mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-10-30 09:16:55 +00:00
* feat(catalog): shelve 3D objects and cursors in their own catalog sections Carries the generator grouping rules from #4310 and #4308. * feat(registry): add a starfield ambient overlay From #4313. * feat(registry): add a falling snow ambient overlay From #4331. * feat(registry): add a torn-paper-rip transition From #4321. * feat(registry): add a paper-collage-reveal transition From #4322. * feat(registry): add a curtain-reveal transition From #4323. * feat(registry): add 3D objects: product turntable, glass hero, exploded stack, extruded logo From #4310. * feat(registry): add eight cursor animations and the dart cursor From #4308. * fix(catalog): find items by everyday editor words and accept a bare search word From #4311. * chore(registry): remove the simulated-cursor component The Cursors section's new pointer animations replace it (from #4308). * fix(registry): take cursor-zoom-follow's screenshot from runtime variables only The declared default is empty, so page markup never becomes an image URL. Clears the code-scanning alert raised on #4308. * docs(cli): show a catalog search example that finds items "smoke" matches nothing in the catalog; "crossfade" finds fade-through. * chore(ci): allow the simulated-cursor removal in the deletion guard * fix(ci): skip tracked files missing from disk in the player CDN pin check Catalog regeneration removes a deleted item's pages before the publish PR untracks them, so the check crashed on every catalog deletion PR. * chore(cli): drop comments that narrate catalog search history * fix(registry): drag-drop keeps the family arrow and shows the drop slot only while hovering * fix(registry): agent cursor labels its steps in an accent tag, no glow or sparkles, in 4.8 s * fix(registry): annotate cursor draws a tapered marker stroke and clears the circled value * fix(registry): show real file thumbnails and end the context menu demo sooner * fix(registry): give marquee select real photos, a Finder-blue marquee and a tighter loop * fix(registry): centre the text-select toolbar on the selection and tighten its timing * fix(registry): selection cursors default to the macOS system blue * style(registry): format the agent and annotate cursor sources * fix(registry): dart-cursor stops covering the choice it makes and shows the export finishing * fix(registry): frame the product turntable fully and light it with two studio softboxes * fix(registry): touch-indicator taps like a real phone and the post it taps gets liked * fix(registry): press-ripple confirms with a check and small click rings at the cursor * fix(registry): exploded stack separates at once and marks each layer in blue as it is labelled * fix(registry): extruded logo settles facing the camera, set in Geist Bold with a neutral rim * fix(registry): magnetic cursor docks its toolbar on the selection and ends after the press * style(registry): format the exploded stack source * fix(registry): glyph trail becomes a tutorial cursor path with numbered steps on a settings screen * fix(registry): make glass-hero a clear lens that shows the headline through it * fix(registry): snow reads as real snowfall with bokeh flakes over a winter title card * fix(registry): oversized cursor is a 3.5x arrow that clicks a real editor toggle on * fix(registry): starfield reads as a drifting night sky over a real title card * style(registry): format the glass hero source * fix(registry): make the paper tear show a white fibrous edge and lift the torn sheet away * fix(registry): curtain reveal draws velvet folds that gather onto a title card * fix(registry): make every zoom-follow click change the screen and read at zoom * fix(registry): paper collage pieces stay opaque, tear with deckled grain and lift away on an arc * refactor(registry): drop dead code and correct stale comments in reworked items * fix(registry): agent cursor scrubs cleanly, docs match press-ripple, fictional demo names * docs(registry): catalog notes say oversized-cursor exits and how it differs from press-ripple * docs(registry): plain lowercase comments in oversized-cursor and touch-indicator * docs(registry): oversized-cursor names CLICK_AT as the click cue
88 lines
3.3 KiB
TypeScript
88 lines
3.3 KiB
TypeScript
import { test } from "node:test";
|
|
import assert from "node:assert/strict";
|
|
import { execFileSync } from "node:child_process";
|
|
import { existsSync, mkdirSync, mkdtempSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { join, resolve } from "node:path";
|
|
|
|
/**
|
|
* Every CDN reference to the player must ask for `latest`.
|
|
*
|
|
* A pinned line here fails silently and indefinitely. The catalog page still
|
|
* renders on the build the pin names, so nothing looks broken: the only symptom
|
|
* is that a fix published to npm never appears on the docs, which surfaces as
|
|
* "that bug is still there" weeks later rather than as a red check. That is
|
|
* exactly how the pin sat one minor line behind after a release, across 175
|
|
* generated pages and three hand-written files nobody thought to grep.
|
|
*
|
|
* The reference lives in the two catalog snippets that build a preview
|
|
* `srcDoc`; this asserts on the whole tree rather than on the sources a reader
|
|
* would think to check.
|
|
*/
|
|
const ROOT = resolve(import.meta.dirname, "..");
|
|
const PLAYER_CDN = /cdn\.jsdelivr\.net\/npm\/@hyperframes\/player@([^/"'`\s]+)/g;
|
|
const TEXT_FILE = /\.(mdx?|[jt]sx?|html|json)$/;
|
|
|
|
/**
|
|
* Tracked files only, via git rather than a directory walk: it is one call, and
|
|
* it skips `node_modules` and build output for free because they are ignored.
|
|
*/
|
|
function trackedTextFiles(root = ROOT): string[] {
|
|
const listing = execFileSync(
|
|
"git",
|
|
["ls-files", "-z", "docs", "scripts", "packages", "registry"],
|
|
{
|
|
cwd: root,
|
|
encoding: "utf-8",
|
|
maxBuffer: 64 * 1024 * 1024,
|
|
},
|
|
);
|
|
// A tracked file can be gone from disk: catalog regeneration removes a deleted
|
|
// item's pages before the publish PR untracks them.
|
|
return listing.split("\0").filter((file) => TEXT_FILE.test(file) && existsSync(join(root, file)));
|
|
}
|
|
|
|
function pinnedReferences(root = ROOT): { file: string; version: string }[] {
|
|
const found: { file: string; version: string }[] = [];
|
|
for (const file of trackedTextFiles(root)) {
|
|
const text = readFileSync(join(root, file), "utf-8");
|
|
for (const match of text.matchAll(PLAYER_CDN)) {
|
|
found.push({ file, version: match[1] as string });
|
|
}
|
|
}
|
|
return found;
|
|
}
|
|
|
|
test("every player CDN reference asks for latest", () => {
|
|
const references = pinnedReferences();
|
|
|
|
// A guard that passes because it matched nothing is worse than no guard.
|
|
assert.ok(
|
|
references.length >= 2,
|
|
`expected the catalog snippets to reference the player CDN, found ${references.length}`,
|
|
);
|
|
|
|
const pinned = references.filter((r) => r.version !== "latest");
|
|
assert.deepEqual(
|
|
pinned,
|
|
[],
|
|
`pinned player versions found. Use @latest instead:\n${pinned
|
|
.map((r) => ` ${r.file}: @${r.version}`)
|
|
.join("\n")}`,
|
|
);
|
|
});
|
|
|
|
test("a tracked file missing from disk is skipped, not read", () => {
|
|
const dir = mkdtempSync(join(tmpdir(), "player-cdn-pin-"));
|
|
try {
|
|
execFileSync("git", ["init", "-q"], { cwd: dir });
|
|
mkdirSync(join(dir, "docs"));
|
|
writeFileSync(join(dir, "docs", "gone.mdx"), "removed page");
|
|
execFileSync("git", ["add", "docs"], { cwd: dir });
|
|
rmSync(join(dir, "docs", "gone.mdx"));
|
|
assert.deepEqual(pinnedReferences(dir), []);
|
|
} finally {
|
|
rmSync(dir, { recursive: true, force: true });
|
|
}
|
|
});
|