diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-02-01 12:15:37 +0100 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-02-01 12:15:37 +0100 |
| commit | 2759d7ed31587efa994be20ee3f2df1a90bca0bd (patch) | |
| tree | 1ca72dc05408c507f86ab9e17801a2ea033195a3 /apps/web/src/services/storage/migrations/transformers/v2-to-v3.ts | |
| parent | 03c2b16064833c85ca8ff74bff7510947728f07b (diff) | |
| download | opencut-2759d7ed31587efa994be20ee3f2df1a90bca0bd.tar.gz | |
add tests for storage migrations
Diffstat (limited to 'apps/web/src/services/storage/migrations/transformers/v2-to-v3.ts')
| -rw-r--r-- | apps/web/src/services/storage/migrations/transformers/v2-to-v3.ts | 81 |
1 files changed, 81 insertions, 0 deletions
diff --git a/apps/web/src/services/storage/migrations/transformers/v2-to-v3.ts b/apps/web/src/services/storage/migrations/transformers/v2-to-v3.ts new file mode 100644 index 00000000..33656109 --- /dev/null +++ b/apps/web/src/services/storage/migrations/transformers/v2-to-v3.ts @@ -0,0 +1,81 @@ +import { getProjectDurationFromScenes } from "@/lib/scenes"; +import type { TScene } from "@/types/timeline"; +import type { MigrationResult, ProjectRecord } from "./types"; + +export function transformProjectV2ToV3({ + project, +}: { + project: ProjectRecord; +}): MigrationResult<ProjectRecord> { + const projectId = getProjectId({ project }); + if (!projectId) { + return { project, skipped: true, reason: "no project id" }; + } + + if (isV3Project({ project })) { + return { project, skipped: true, reason: "already v3" }; + } + + const scenes = getScenes({ project }); + const duration = getProjectDurationFromScenes({ scenes }); + + const metadataValue = project.metadata; + const metadata = isRecord(metadataValue) + ? { ...metadataValue, duration } + : { duration }; + + const migratedProject = { + ...project, + metadata, + version: 3, + }; + + return { project: migratedProject, skipped: false }; +} + +export function getProjectId({ + project, +}: { + project: ProjectRecord; +}): string | null { + const idValue = project.id; + if (typeof idValue === "string" && idValue.length > 0) { + return idValue; + } + + const metadataValue = project.metadata; + if (!isRecord(metadataValue)) { + return null; + } + + const metadataId = metadataValue.id; + if (typeof metadataId === "string" && metadataId.length > 0) { + return metadataId; + } + + return null; +} + +function getScenes({ project }: { project: ProjectRecord }): TScene[] { + const scenesValue = project.scenes; + if (!Array.isArray(scenesValue)) { + return []; + } + + return scenesValue.filter(isRecord) as unknown as TScene[]; +} + +function isV3Project({ project }: { project: ProjectRecord }): boolean { + const versionValue = project.version; + if (typeof versionValue === "number" && versionValue >= 3) { + return true; + } + + return ( + isRecord(project.metadata) && typeof project.metadata.duration === "number" + ); +} + +function isRecord(value: unknown): value is ProjectRecord { + return typeof value === "object" && value !== null; +} |
