mirror of
https://github.com/hanzoai/frames.git
synced 2026-09-24 00:08:03 +00:00
scripts: serve catalog previews from the docs site
Three scripts still reached upstream infrastructure, and running any of them put its URLs back into the tree. generate-catalog-pages emitted an absolute vendor CDN host into every catalog page. The pages already checked in use root-relative /images/ paths, so a regenerate reverted 306 of them; the base now matches what ships, and the docs site serves the previews its own generator produces. backfill-block-previews wrote a preview field into registry manifests from that same CDN pattern. It is a one-shot migration nothing calls, and no manifest carries the field it wrote. Gone. upload-docs-images synced docs/images to an S3 bucket under an upstream AWS profile. Its source directory does not exist, and the contributing guides already say previews are served from the docs site and nothing is uploaded. Gone, with the script entry and the comments that pointed at it.
This commit is contained in:
+3
-3
@@ -17,9 +17,9 @@ lefthook-local.yml
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Docs media — served from CDN, not committed.
|
||||
# Regenerate with scripts/generate-{catalog,template}-previews.ts then upload
|
||||
# with `bun run upload:docs-images`. Add explicit negations below for any
|
||||
# Docs media — built at deploy time, not committed. Regenerate with
|
||||
# scripts/generate-{catalog,template}-previews.ts; the docs site serves them
|
||||
# from its own /images/ path. Add explicit negations below for any
|
||||
# non-generated assets (logos, svgs) that should stay in the repo.
|
||||
docs/images/
|
||||
|
||||
|
||||
@@ -52,7 +52,6 @@
|
||||
"generate:previews": "tsx scripts/generate-template-previews.ts",
|
||||
"generate:catalog-previews": "tsx scripts/generate-catalog-previews.ts",
|
||||
"package:codex-plugin": "node scripts/package-codex-plugin.mjs",
|
||||
"upload:docs-images": "bash scripts/upload-docs-images.sh",
|
||||
"prepare": "test -d .git && lefthook install || true"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -1,120 +0,0 @@
|
||||
#!/usr/bin/env tsx
|
||||
/**
|
||||
* Backfill preview URLs in registry block + component manifests.
|
||||
*
|
||||
* - Blocks: adds `preview: { video, poster }` using the deterministic CDN pattern
|
||||
* - Components: normalizes bare-string `preview` to `{ video }` object format
|
||||
*
|
||||
* Usage:
|
||||
* npx tsx scripts/backfill-block-previews.ts # all items
|
||||
* npx tsx scripts/backfill-block-previews.ts --dry-run # preview changes only
|
||||
*/
|
||||
|
||||
import { readdirSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { join, resolve, dirname } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const scriptDir = dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = resolve(scriptDir, "..");
|
||||
const registryDir = resolve(repoRoot, "registry");
|
||||
|
||||
const CDN_BASE = "https://static.heygen.ai/frames-oss/docs/images/catalog";
|
||||
|
||||
const dryRun = process.argv.includes("--dry-run");
|
||||
|
||||
interface Preview {
|
||||
video?: string;
|
||||
poster?: string;
|
||||
}
|
||||
|
||||
let updated = 0;
|
||||
let skipped = 0;
|
||||
|
||||
function tryReadManifest(manifestPath: string): Record<string, unknown> | null {
|
||||
try {
|
||||
return JSON.parse(readFileSync(manifestPath, "utf-8"));
|
||||
} catch {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
function writeManifest(manifestPath: string, manifest: Record<string, unknown>): void {
|
||||
writeFileSync(manifestPath, JSON.stringify(manifest, null, 2) + "\n", "utf-8");
|
||||
}
|
||||
|
||||
function backfillBlocks() {
|
||||
const blocksDir = join(registryDir, "blocks");
|
||||
let entries: ReturnType<typeof readdirSync<string>>;
|
||||
try {
|
||||
entries = readdirSync(blocksDir, { withFileTypes: true });
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const entry of entries) {
|
||||
if (!entry.isDirectory()) continue;
|
||||
const manifestPath = join(blocksDir, entry.name, "registry-item.json");
|
||||
const manifest = tryReadManifest(manifestPath);
|
||||
if (!manifest) continue;
|
||||
|
||||
const preview: Preview = {
|
||||
video: `${CDN_BASE}/blocks/${entry.name}.mp4`,
|
||||
poster: `${CDN_BASE}/blocks/${entry.name}.png`,
|
||||
};
|
||||
|
||||
const existing = manifest.preview as Preview | undefined;
|
||||
if (existing?.video === preview.video && existing?.poster === preview.poster) {
|
||||
skipped++;
|
||||
continue;
|
||||
}
|
||||
|
||||
manifest.preview = preview;
|
||||
|
||||
if (dryRun) {
|
||||
console.log(`[dry-run] ${entry.name}: would set preview →`, preview);
|
||||
} else {
|
||||
writeManifest(manifestPath, manifest);
|
||||
}
|
||||
updated++;
|
||||
}
|
||||
}
|
||||
|
||||
function normalizeComponents() {
|
||||
const componentsDir = join(registryDir, "components");
|
||||
let entries: ReturnType<typeof readdirSync<string>>;
|
||||
try {
|
||||
entries = readdirSync(componentsDir, { withFileTypes: true });
|
||||
} catch {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const entry of entries) {
|
||||
if (!entry.isDirectory()) continue;
|
||||
const manifestPath = join(componentsDir, entry.name, "registry-item.json");
|
||||
const manifest = tryReadManifest(manifestPath);
|
||||
if (!manifest) continue;
|
||||
if (!manifest.preview) continue;
|
||||
|
||||
if (typeof manifest.preview === "string") {
|
||||
manifest.preview = { video: manifest.preview };
|
||||
|
||||
if (dryRun) {
|
||||
console.log(
|
||||
`[dry-run] ${entry.name}: normalize string → { video: "${(manifest.preview as Preview).video}" }`,
|
||||
);
|
||||
} else {
|
||||
writeManifest(manifestPath, manifest);
|
||||
}
|
||||
updated++;
|
||||
} else {
|
||||
skipped++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
backfillBlocks();
|
||||
normalizeComponents();
|
||||
|
||||
console.log(
|
||||
`\n${dryRun ? "[dry-run] " : ""}Done: ${updated} updated, ${skipped} already up-to-date`,
|
||||
);
|
||||
@@ -27,7 +27,10 @@ const scriptDir = dirname(fileURLToPath(import.meta.url));
|
||||
const repoRoot = resolve(scriptDir, "..");
|
||||
const registryDir = resolve(repoRoot, "registry");
|
||||
const docsDir = resolve(repoRoot, "docs");
|
||||
const catalogImageBase = "https://static.heygen.ai/frames-oss/docs/images/catalog";
|
||||
// Previews resolve from the docs site's own /images/ path, produced by
|
||||
// `bun run generate:catalog-previews` at deploy time. Root-relative, so the
|
||||
// emitted pages carry no host and match what is already checked in.
|
||||
const catalogImageBase = "/images/catalog";
|
||||
|
||||
// ── Types ──────────────────────────────────────────────────────────────────
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@
|
||||
* - Components: renders the component's demo.html via a wrapper index.html
|
||||
*
|
||||
* Output: docs/images/catalog/<type>/<name>.png + <name>.mp4
|
||||
* (docs/images/ is gitignored — files are served from the CDN. After running
|
||||
* this script, run `bun run upload:docs-images` to publish.)
|
||||
* (docs/images/ is gitignored — the docs site serves them from its own
|
||||
* /images/ path, so a deploy runs this script rather than uploading.)
|
||||
*
|
||||
* Usage:
|
||||
* npx tsx scripts/generate-catalog-previews.ts # all items
|
||||
|
||||
@@ -6,8 +6,8 @@
|
||||
* videos of each built-in template.
|
||||
*
|
||||
* Output: docs/images/templates/<id>.png + <id>.mp4
|
||||
* (docs/images/ is gitignored — files are served from the CDN. After running
|
||||
* this script, run `bun run upload:docs-images` to publish.)
|
||||
* (docs/images/ is gitignored — the docs site serves them from its own
|
||||
* /images/ path, so a deploy runs this script rather than uploading.)
|
||||
*
|
||||
* Usage:
|
||||
* bun run generate:previews # all templates (PNG + MP4)
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# Upload docs/images/ to the HeyGen public CDN.
|
||||
#
|
||||
# Docs previews (mp4/png/gif) are served from https://static.heygen.ai/frames-oss/docs/images/
|
||||
# rather than committed to the repo. After regenerating previews with
|
||||
# `scripts/generate-catalog-previews.ts` or `scripts/generate-template-previews.ts`,
|
||||
# run this script to publish the new files.
|
||||
#
|
||||
# Requires AWS credentials for the heygen engineering account (profile: engineering-767398024897).
|
||||
# Contributors without AWS access: open a PR with the HTML/MDX changes and a
|
||||
# maintainer will run the generators + this upload before merging.
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
REPO_ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
SRC="$REPO_ROOT/docs/images/"
|
||||
DEST="s3://heygen-public/frames-oss/docs/images/"
|
||||
PROFILE="${AWS_PROFILE:-engineering-767398024897}"
|
||||
|
||||
if [ ! -d "$SRC" ]; then
|
||||
echo "No docs/images/ directory to upload — nothing to do."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo "Uploading $SRC → $DEST (profile: $PROFILE)"
|
||||
aws --profile "$PROFILE" s3 sync "$SRC" "$DEST" \
|
||||
--cache-control "public, max-age=31536000, immutable" \
|
||||
--metadata-directive REPLACE
|
||||
|
||||
echo "Done. Files are live at https://static.heygen.ai/frames-oss/docs/images/"
|
||||
@@ -117,7 +117,7 @@ npx @hanzo/frames publish
|
||||
**Catalog preview image** — The catalog card uses a PNG at `docs/images/catalog/{kind}/{name}.png` (where `{kind}` is `blocks` or `components`). Generate it from a snapshot, then:
|
||||
|
||||
- **Maintainers:** regenerate previews with `bun run generate:catalog-previews`; they are served from the docs site's own `/images/` path, so nothing is uploaded anywhere
|
||||
- **External contributors:** attach the preview MP4 to your PR description. A maintainer will generate and upload the catalog image before merging.
|
||||
- **External contributors:** attach the preview MP4 to your PR description. A maintainer will generate the catalog image before merging.
|
||||
|
||||
### Step 6: Ship
|
||||
|
||||
|
||||
Reference in New Issue
Block a user