mirror of
https://github.com/hanzoai/frames.git
synced 2026-09-24 00:08:03 +00:00
@hanzo/frame is taken by the hero video primitive — one full-bleed video element — which has held that name on npm since it shipped. This repo is the video toolchain: a CLI, a renderer, a studio, a player. Plural is what it is, so the CLI publishes as @hanzo/frames and the workspace packages follow it (@hanzo/frames-core, @hanzo/frames-engine, and the rest). The binary stays `frames`, and now actually ships. The manifest mapped it to bin/frames.mjs while the file on disk was bin/hyperframes.mjs, so a global install produced no working command. The paths that name a package to fetch were pointing elsewhere. The update check read registry.npmjs.org/frames, a different author's package, and the npm, bun and pnpm installers would have pulled it over the CLI; the render image installed the upstream hyperframes; scaffolded projects and the docs pinned the unscoped name. All of them now name @hanzo/frames.
145 lines
5.0 KiB
JavaScript
145 lines
5.0 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { describe, it } from "node:test";
|
|
import {
|
|
checkDockerfileWorkspaces,
|
|
findRuntimeWorkspaceDirectories,
|
|
listDockerfileWorkspaceIssues,
|
|
readWorkspacePackages,
|
|
} from "./check-dockerfile-workspaces.mjs";
|
|
|
|
const workspaces = [
|
|
workspace("core", "@hanzo/frames-core", {
|
|
"@hanzo/frames-lint": "workspace:*",
|
|
"@hanzo/frames-studio-server": "workspace:*",
|
|
}),
|
|
workspace("engine", "@hanzo/frames-engine", {
|
|
"@hanzo/frames-core": "workspace:*",
|
|
"@hanzo/frames-parsers": "workspace:*",
|
|
}),
|
|
workspace("gcp-cloud-run", "@hanzo/frames-gcp-cloud-run", {
|
|
"@hanzo/frames-producer": "workspace:*",
|
|
}),
|
|
workspace("lint", "@hanzo/frames-lint", { "@hanzo/frames-parsers": "workspace:*" }),
|
|
workspace("parsers", "@hanzo/frames-parsers"),
|
|
workspace("producer", "@hanzo/frames-producer", {
|
|
"@hanzo/frames-core": "workspace:*",
|
|
"@hanzo/frames-engine": "workspace:*",
|
|
}),
|
|
workspace("sdk", "@hanzo/frames-sdk"),
|
|
workspace("studio-server", "@hanzo/frames-studio-server", {
|
|
"@hanzo/frames-core": "workspace:*",
|
|
}),
|
|
];
|
|
const runtimeDirectories = [
|
|
"core",
|
|
"engine",
|
|
"gcp-cloud-run",
|
|
"lint",
|
|
"parsers",
|
|
"producer",
|
|
"studio-server",
|
|
];
|
|
const buildDirectories = [
|
|
"core",
|
|
"engine",
|
|
"lint",
|
|
"parsers",
|
|
"studio-server",
|
|
"producer",
|
|
"gcp-cloud-run",
|
|
];
|
|
|
|
function workspace(directory, name, dependencies = {}) {
|
|
return { directory, manifest: { name, scripts: { build: "build" }, dependencies } };
|
|
}
|
|
|
|
function dockerfile({
|
|
manifests = workspaces.map((candidate) => candidate.directory),
|
|
sources = runtimeDirectories,
|
|
builds = buildDirectories,
|
|
} = {}) {
|
|
return [
|
|
...manifests.map(
|
|
(directory) => `COPY packages/${directory}/package.json packages/${directory}/package.json`,
|
|
),
|
|
...sources.map((directory) => `COPY packages/${directory}/ packages/${directory}/`),
|
|
...builds.map((directory) => `RUN bun run --cwd packages/${directory} build`),
|
|
].join("\n");
|
|
}
|
|
|
|
describe("GCP Cloud Run Dockerfile workspace checker", () => {
|
|
it("accepts the repository Dockerfile", () => {
|
|
assert.equal(checkDockerfileWorkspaces(), readWorkspacePackages().length);
|
|
});
|
|
|
|
it("derives the runtime closure without looping on workspace cycles", () => {
|
|
assert.deepEqual([...findRuntimeWorkspaceDirectories(workspaces)].sort(), runtimeDirectories);
|
|
});
|
|
|
|
it("reports a missing workspace manifest", () => {
|
|
const manifests = workspaces
|
|
.map((candidate) => candidate.directory)
|
|
.filter((directory) => directory !== "sdk");
|
|
assert.deepEqual(listDockerfileWorkspaceIssues(dockerfile({ manifests }), workspaces), [
|
|
"missing workspace manifests: sdk",
|
|
]);
|
|
|
|
const misdirected = dockerfile().replace(
|
|
"COPY packages/sdk/package.json packages/sdk/package.json",
|
|
"COPY packages/sdk/package.json packages/wrong/package.json",
|
|
);
|
|
assert.deepEqual(listDockerfileWorkspaceIssues(misdirected, workspaces), [
|
|
"missing workspace manifests: sdk",
|
|
]);
|
|
});
|
|
|
|
it("reports a missing runtime source copy", () => {
|
|
const sources = runtimeDirectories.filter((directory) => directory !== "parsers");
|
|
assert.deepEqual(listDockerfileWorkspaceIssues(dockerfile({ sources }), workspaces), [
|
|
"missing runtime workspace sources: parsers",
|
|
]);
|
|
|
|
const misdirected = dockerfile().replace(
|
|
"COPY packages/parsers/ packages/parsers/",
|
|
"COPY packages/parsers/ packages/wrong/",
|
|
);
|
|
assert.deepEqual(listDockerfileWorkspaceIssues(misdirected, workspaces), [
|
|
"missing runtime workspace sources: parsers",
|
|
]);
|
|
});
|
|
|
|
it("requires every buildable runtime prerequisite before producer", () => {
|
|
const builds = buildDirectories.filter((directory) => directory !== "lint");
|
|
assert.deepEqual(listDockerfileWorkspaceIssues(dockerfile({ builds }), workspaces), [
|
|
"runtime workspaces must run their full build before producer: lint",
|
|
]);
|
|
|
|
const lateBuilds = buildDirectories.filter((directory) => directory !== "lint");
|
|
lateBuilds.splice(lateBuilds.indexOf("producer") + 1, 0, "lint");
|
|
assert.deepEqual(
|
|
listDockerfileWorkspaceIssues(dockerfile({ builds: lateBuilds }), workspaces),
|
|
["runtime workspaces must run their full build before producer: lint"],
|
|
);
|
|
});
|
|
|
|
it("does not mistake a build subcommand for a full workspace build", () => {
|
|
const input = dockerfile()
|
|
.replace(
|
|
"RUN bun run --cwd packages/core build",
|
|
"RUN bun run --cwd packages/core build:frames-runtime:modular",
|
|
)
|
|
.concat("\n# bun run --cwd packages/core build");
|
|
assert.deepEqual(listDockerfileWorkspaceIssues(input, workspaces), [
|
|
"runtime workspaces must run their full build before producer: core",
|
|
]);
|
|
});
|
|
|
|
it("requires producer to be built before the adapter", () => {
|
|
const builds = buildDirectories.filter((directory) => directory !== "producer");
|
|
builds.push("producer");
|
|
assert.deepEqual(listDockerfileWorkspaceIssues(dockerfile({ builds }), workspaces), [
|
|
"producer must be built before gcp-cloud-run",
|
|
]);
|
|
});
|
|
});
|