mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-11 14:50:02 +00:00
refactor(repo): resolve changed-code audit
This commit is contained in:
@@ -1,8 +1,8 @@
|
||||
import { promises as fs } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { readStore, writeStore } from "../../auth/store.js";
|
||||
import { setupTempAuthEnv, type EnvFixture } from "../../auth/_test-utils.js";
|
||||
import { CliRuntimeError } from "../../utils/commandResult.js";
|
||||
|
||||
// Mock only AuthClient — keep the real store/resolver so the test
|
||||
@@ -43,19 +43,13 @@ const telemetry = vi.hoisted(() => ({
|
||||
}));
|
||||
vi.mock("../../telemetry/index.js", () => telemetry);
|
||||
|
||||
const ENV_KEYS = ["HEYGEN_API_KEY", "HYPERFRAMES_API_KEY", "HEYGEN_CONFIG_DIR"] as const;
|
||||
|
||||
describe("auth login --api-key rollback", () => {
|
||||
let dir: string;
|
||||
const saved: Partial<Record<(typeof ENV_KEYS)[number], string | undefined>> = {};
|
||||
let envFixture: EnvFixture;
|
||||
|
||||
beforeEach(async () => {
|
||||
dir = await fs.mkdtemp(join(tmpdir(), "hf-login-"));
|
||||
for (const k of ENV_KEYS) {
|
||||
saved[k] = process.env[k];
|
||||
delete process.env[k];
|
||||
}
|
||||
process.env["HEYGEN_CONFIG_DIR"] = dir;
|
||||
envFixture = await setupTempAuthEnv("hf-login-");
|
||||
dir = envFixture.dir;
|
||||
verifyState.reject = false;
|
||||
verifyState.user = { email: "alice@example.com" };
|
||||
for (const fn of Object.values(telemetry)) fn.mockClear();
|
||||
@@ -65,12 +59,7 @@ describe("auth login --api-key rollback", () => {
|
||||
|
||||
afterEach(async () => {
|
||||
vi.restoreAllMocks();
|
||||
for (const k of ENV_KEYS) {
|
||||
const v = saved[k];
|
||||
if (v === undefined) delete process.env[k];
|
||||
else process.env[k] = v;
|
||||
}
|
||||
await fs.rm(dir, { recursive: true, force: true });
|
||||
await envFixture.restore();
|
||||
});
|
||||
|
||||
async function runLogin(apiKey: string): Promise<void> {
|
||||
|
||||
@@ -1,9 +1,6 @@
|
||||
// fallow-ignore-file code-duplication
|
||||
import { promises as fs } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
|
||||
import { writeStore } from "../../auth/store.js";
|
||||
import { setupTempAuthEnv, type EnvFixture } from "../../auth/_test-utils.js";
|
||||
import { consumeCommandResult } from "../../utils/commandResult.js";
|
||||
|
||||
// Mock only AuthClient so the live /v3/users/me probe is controllable;
|
||||
@@ -33,20 +30,12 @@ vi.mock("../../auth/index.js", async (orig) => {
|
||||
return { ...actual, AuthClient: MockAuthClient };
|
||||
});
|
||||
|
||||
const ENV_KEYS = ["HEYGEN_API_KEY", "HYPERFRAMES_API_KEY", "HEYGEN_CONFIG_DIR"] as const;
|
||||
|
||||
describe("auth status — persisted user block surface", () => {
|
||||
let dir: string;
|
||||
const saved: Partial<Record<(typeof ENV_KEYS)[number], string | undefined>> = {};
|
||||
let envFixture: EnvFixture;
|
||||
let stdout: string[];
|
||||
|
||||
beforeEach(async () => {
|
||||
dir = await fs.mkdtemp(join(tmpdir(), "hf-status-"));
|
||||
for (const k of ENV_KEYS) {
|
||||
saved[k] = process.env[k];
|
||||
delete process.env[k];
|
||||
}
|
||||
process.env["HEYGEN_CONFIG_DIR"] = dir;
|
||||
envFixture = await setupTempAuthEnv("hf-status-");
|
||||
probeState.apiReject = false;
|
||||
probeState.user = { email: "live@example.com" };
|
||||
stdout = [];
|
||||
@@ -60,12 +49,7 @@ describe("auth status — persisted user block surface", () => {
|
||||
afterEach(async () => {
|
||||
consumeCommandResult();
|
||||
vi.restoreAllMocks();
|
||||
for (const k of ENV_KEYS) {
|
||||
const v = saved[k];
|
||||
if (v === undefined) delete process.env[k];
|
||||
else process.env[k] = v;
|
||||
}
|
||||
await fs.rm(dir, { recursive: true, force: true });
|
||||
await envFixture.restore();
|
||||
});
|
||||
|
||||
async function runStatus(asJson: boolean): Promise<number> {
|
||||
|
||||
@@ -525,6 +525,18 @@ async function runSites(args: Record<string, unknown>): Promise<void> {
|
||||
|
||||
// ── render ──────────────────────────────────────────────────────────────────
|
||||
|
||||
function resolveCloudRunFps(
|
||||
args: Record<string, unknown>,
|
||||
projectDir: string,
|
||||
command: "render" | "render-batch",
|
||||
): 24 | 30 | 60 {
|
||||
const fps =
|
||||
parseIntFlag(args.fps) ?? readAllowedCompositionFpsFromDir(projectDir, [24, 30, 60]) ?? 30;
|
||||
if (fps === 24 || fps === 30 || fps === 60) return fps;
|
||||
console.error(`[cloudrun ${command}] --fps must be 24, 30, or 60; got ${fps}.`);
|
||||
failCommand();
|
||||
}
|
||||
|
||||
// fallow-ignore-next-line complexity
|
||||
async function runRender(args: Record<string, unknown>): Promise<void> {
|
||||
const projectDir = args.target as string | undefined;
|
||||
@@ -540,12 +552,7 @@ async function runRender(args: Record<string, unknown>): Promise<void> {
|
||||
console.error("[cloudrun render] --width and --height are required.");
|
||||
failCommand();
|
||||
}
|
||||
const fps =
|
||||
parseIntFlag(args.fps) ?? readAllowedCompositionFpsFromDir(projectDir, [24, 30, 60]) ?? 30;
|
||||
if (fps !== 24 && fps !== 30 && fps !== 60) {
|
||||
console.error(`[cloudrun render] --fps must be 24, 30, or 60; got ${fps}.`);
|
||||
failCommand();
|
||||
}
|
||||
const fps = resolveCloudRunFps(args, projectDir, "render");
|
||||
const state = readState(args);
|
||||
const variables = resolveAndValidateVariables(args, resolve(projectDir));
|
||||
const config = buildRenderConfig(args, fps, width, height, variables);
|
||||
@@ -651,12 +658,7 @@ async function runRenderBatch(args: Record<string, unknown>): Promise<void> {
|
||||
console.error("[cloudrun render-batch] --width and --height are required.");
|
||||
failCommand();
|
||||
}
|
||||
const fps =
|
||||
parseIntFlag(args.fps) ?? readAllowedCompositionFpsFromDir(projectDir, [24, 30, 60]) ?? 30;
|
||||
if (fps !== 24 && fps !== 30 && fps !== 60) {
|
||||
console.error(`[cloudrun render-batch] --fps must be 24, 30, or 60; got ${fps}.`);
|
||||
failCommand();
|
||||
}
|
||||
const fps = resolveCloudRunFps(args, projectDir, "render-batch");
|
||||
if (!existsSync(resolve(batchPath))) {
|
||||
console.error(`[cloudrun render-batch] batch file not found: ${batchPath}`);
|
||||
failCommand();
|
||||
|
||||
@@ -5,6 +5,7 @@ import { mkdirSync, readdirSync, readFileSync, statSync, writeFileSync, rmSync }
|
||||
import { createRenderPlan, resolveBrowserGpuForCli, type RenderFormat } from "./render/plan.js";
|
||||
import { presentRenderPlan } from "./render/present.js";
|
||||
import { executeRenderPlan, renderLintContinuationHint } from "./render/execute.js";
|
||||
// Test-only seams retained at the command boundary for render behavior tests.
|
||||
export { resolveBrowserGpuForCli, renderLintContinuationHint };
|
||||
|
||||
export const examples: Example[] = [
|
||||
|
||||
@@ -33,6 +33,8 @@ export interface RenderExecutionDependencies {
|
||||
checkResolution: ResolutionPreflight;
|
||||
}
|
||||
|
||||
// Exported only through render.ts so command tests can lock the user-facing guidance.
|
||||
// fallow-ignore-next-line unused-export
|
||||
export function renderLintContinuationHint(strictErrors: boolean): string {
|
||||
return strictErrors
|
||||
? " Continuing render despite lint warnings. Use --strict-all to block warnings."
|
||||
@@ -156,6 +158,7 @@ async function ensureRenderBrowser(plan: RenderPlan): Promise<string> {
|
||||
}
|
||||
}
|
||||
|
||||
// fallow-ignore-next-line complexity
|
||||
async function runRenderLint(plan: RenderPlan): Promise<void> {
|
||||
// lintProject's explicit-entry contract is an absolute source path;
|
||||
// entryFile remains project-relative for the producer.
|
||||
|
||||
@@ -454,6 +454,8 @@ export function renderOutputDirectory(plan: RenderPlan): string {
|
||||
}
|
||||
|
||||
/** Resolve browser GPU mode from Docker, CLI, env, then the auto default. */
|
||||
// Re-exported by render.ts to preserve its tested public seam.
|
||||
// fallow-ignore-next-line unused-export
|
||||
export function resolveBrowserGpuForCli(
|
||||
useDocker: boolean,
|
||||
browserGpuArg: boolean | undefined,
|
||||
|
||||
@@ -5,6 +5,8 @@ import { c } from "../../ui/colors.js";
|
||||
import type { RenderPlan } from "./plan.js";
|
||||
|
||||
/** Present warnings and the human render plan. JSON batch output stays silent. */
|
||||
// This phase intentionally owns every mutually exclusive human-output branch.
|
||||
// fallow-ignore-next-line complexity
|
||||
export async function presentRenderPlan(plan: RenderPlan): Promise<void> {
|
||||
await presentRenderWarnings(plan);
|
||||
if (plan.effectiveQuiet || plan.batchPath) return;
|
||||
|
||||
Reference in New Issue
Block a user