diff --git a/src/cli/exportProject.test.ts b/src/cli/exportProject.test.ts index 174308011..9b2001333 100644 --- a/src/cli/exportProject.test.ts +++ b/src/cli/exportProject.test.ts @@ -2,11 +2,13 @@ import { describe, expect, it, vi } from "vitest"; import { normalizeProjectEditor, PROJECT_VERSION, + type ProjectEditorState, validateProjectData, } from "@/components/video-editor/projectPersistence"; import { migrateProjectDataToAxcutDocument } from "@/lib/ai-edition/document/migrate"; import { isAxcutDocumentFile } from "@/lib/ai-edition/schema"; -import { loadDocumentProject, type VideoProbe } from "./exportProject"; +import { getEditorSettings } from "@/lib/ai-edition/store/editorSettings"; +import { legacyProjectEditor, loadDocumentProject, type VideoProbe } from "./exportProject"; const SCREEN = "/recordings/screen.mp4"; @@ -52,6 +54,36 @@ describe("the project file shapes the CLI export reads", () => { }); }); +describe("legacyProjectEditor", () => { + it("keeps the render settings the normalizer does not know", () => { + const editor = { + cursorModel3d: true, + cursorClickSound: true, + cursorShow: false, + webcamBackgroundMode: "blur", + webcamBlurIntensity: 0.8, + audioGainDb: 6, + }; + const document = migrateProjectDataToAxcutDocument({ + ...v2Project(), + editor: legacyProjectEditor(editor as Partial), + }); + const settings = getEditorSettings(document); + expect(settings.cursor.model3d).toBe(true); + expect(settings.cursor.clickSound).toBe(true); + expect(settings.cursorShow).toBe(false); + expect(settings.webcamBackgroundMode).toBe("blur"); + expect(settings.audioGainDb).toBe(6); + expect(document.legacyEditor).toMatchObject(editor); + }); + + it("still normalizes the keys it knows", () => { + expect(legacyProjectEditor({ aspectRatio: "nope" as never }).aspectRatio).toBe( + normalizeProjectEditor({}).aspectRatio, + ); + }); +}); + describe("loadDocumentProject", () => { it("reads the media, length and size off the document without probing", async () => { const project = await loadDocumentProject(savedDocument(), noProbe); diff --git a/src/cli/exportProject.ts b/src/cli/exportProject.ts index ad762becf..06c2d9327 100644 --- a/src/cli/exportProject.ts +++ b/src/cli/exportProject.ts @@ -27,6 +27,17 @@ export interface ExportProject { sourceDims: Dims; } +/** + * A v2 project's editor as its migrated document keeps it: normalized, plus every key the + * normalizer does not know. The migration copies it into `legacyEditor`, where the export reads + * the render settings, so a key dropped here exported as its default. + */ +export function legacyProjectEditor( + editor: Partial | undefined, +): ProjectEditorState { + return { ...editor, ...normalizeProjectEditor(editor ?? {}) }; +} + /** * A project the editor saved: the AxcutDocument itself, at any `schemaVersion`, upgraded and * validated as the editor's "Browse files…" does. The main process has already relinked moved diff --git a/src/cli/loadCliProject.ts b/src/cli/loadCliProject.ts index 395514348..459bae06e 100644 --- a/src/cli/loadCliProject.ts +++ b/src/cli/loadCliProject.ts @@ -4,7 +4,6 @@ import { type EditorProjectData, - normalizeProjectEditor, resolveProjectMedia, toFileUrl, validateProjectData, @@ -13,7 +12,7 @@ import { migrateProjectDataToAxcutDocument } from "@/lib/ai-edition/document/mig import { applyProbedDuration } from "@/lib/ai-edition/document/timeline"; import { isAxcutDocumentFile } from "@/lib/ai-edition/schema"; import { nativeBridgeClient } from "@/native"; -import { type ExportProject, loadDocumentProject } from "./exportProject"; +import { type ExportProject, legacyProjectEditor, loadDocumentProject } from "./exportProject"; export function probeVideoDimensions( url: string, @@ -70,7 +69,7 @@ async function loadLegacyProject(project: EditorProjectData): Promise