summaryrefslogtreecommitdiff
path: root/apps/web/src/services/storage/migrations/v2-to-v3.ts
diff options
context:
space:
mode:
authorMaze <167211895+mazeincoding@users.noreply.github.com>2026-01-31 00:20:04 +0100
committerGitHub <noreply@github.com>2026-01-31 00:20:04 +0100
commit7bf0984698e43b9aa2dd879f65951318ed410390 (patch)
treeccf2cd590a47d550152afc07129cb55c71a9ec35 /apps/web/src/services/storage/migrations/v2-to-v3.ts
parent0173db99448d1c4c6415dcf15272e17551b48b04 (diff)
downloadopencut-7bf0984698e43b9aa2dd879f65951318ed410390.tar.gz
codebase overhaul (#697)
Diffstat (limited to 'apps/web/src/services/storage/migrations/v2-to-v3.ts')
-rw-r--r--apps/web/src/services/storage/migrations/v2-to-v3.ts92
1 files changed, 92 insertions, 0 deletions
diff --git a/apps/web/src/services/storage/migrations/v2-to-v3.ts b/apps/web/src/services/storage/migrations/v2-to-v3.ts
new file mode 100644
index 00000000..eb6db26d
--- /dev/null
+++ b/apps/web/src/services/storage/migrations/v2-to-v3.ts
@@ -0,0 +1,92 @@
+import { getProjectDurationFromScenes } from "@/lib/scenes";
+import { IndexedDBAdapter } from "@/services/storage/indexeddb-adapter";
+import type { TScene } from "@/types/timeline";
+import { StorageMigration } from "./base";
+
+type ProjectRecord = Record<string, unknown>;
+
+export class V2toV3Migration extends StorageMigration {
+ from = 2;
+ to = 3;
+
+ async run(): Promise<void> {
+ const projectsAdapter = new IndexedDBAdapter<unknown>(
+ "video-editor-projects",
+ "projects",
+ 1,
+ );
+ const projects = await projectsAdapter.getAll();
+
+ for (const project of projects) {
+ if (!isRecord(project)) {
+ continue;
+ }
+
+ const projectId = getProjectId({ project });
+ if (!projectId) {
+ continue;
+ }
+
+ if (isV3Project({ project })) {
+ continue;
+ }
+
+ 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,
+ };
+
+ await projectsAdapter.set(projectId, migratedProject);
+ }
+ }
+}
+
+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;
+}