import { parseProjectStateSnapshot, type ProjectStateSnapshot, } from "./project-state-snapshot.model.js"; import type { SerializedProjectCommand } from "./project-command.model.js"; export const projectStateRestoreCommandType = "project.restore-state"; export const projectStateRestoreCommandSchemaVersion = 1 as const; export interface ProjectStateRestoreCommandPayload { expectedStateSha256: string; targetState: ProjectStateSnapshot; } export type ProjectStateRestoreCommand = SerializedProjectCommand< ProjectStateRestoreCommandPayload > & { schemaVersion: typeof projectStateRestoreCommandSchemaVersion; type: typeof projectStateRestoreCommandType; }; export function createProjectStateRestoreCommand( expectedStateSha256: string, targetState: ProjectStateSnapshot ): ProjectStateRestoreCommand { const command: ProjectStateRestoreCommand = { schemaVersion: projectStateRestoreCommandSchemaVersion, type: projectStateRestoreCommandType, payload: { expectedStateSha256, targetState: parseProjectStateSnapshot(targetState), }, }; assertProjectStateRestoreCommand(command); return command; } export function assertProjectStateRestoreCommand( value: unknown ): asserts value is ProjectStateRestoreCommand { if (!value || typeof value !== "object") { throw new Error("Project state restore command must be an object."); } const command = value as Partial; if ( command.type !== projectStateRestoreCommandType || command.schemaVersion !== projectStateRestoreCommandSchemaVersion ) { throw new Error("Unsupported project state restore command."); } if (!command.payload || typeof command.payload !== "object") { throw new Error("Project state restore payload is required."); } const payload = command.payload as Partial; if ( typeof payload.expectedStateSha256 !== "string" || !/^[a-f0-9]{64}$/.test(payload.expectedStateSha256) ) { throw new Error("Expected project state checksum is invalid."); } parseProjectStateSnapshot(payload.targetState); }