// src/main/services/update-ports.ts // UpdateService 가 의존하는 포트(인터페이스). 서비스는 이 계약에만 의존하고, // electron-updater · fetch · electron dialog 구현은 update-adapters.ts 에 있다 (테스트는 가짜 포트 주입). import type { UpdateChannel } from '../update-feed' import type { UpdatePolicy } from '../update-policy' export interface UpdateProgressPayload { percent: number bytesPerSecond: number transferred: number total: number } export type ReleaseNotes = string | ReadonlyArray<{ version: string; note: string | null }> | null | undefined export interface UpdateInfoLike { version: string releaseNotes?: ReleaseNotes } /** 업데이터(electron-updater) 이벤트를 서비스로 넘기는 콜백 */ export interface UpdaterEventHandlers { onChecking(): void onAvailable(info: UpdateInfoLike): void onNotAvailable(version: string): void onProgress(progress: UpdateProgressPayload): void onDownloaded(version: string): void onError(message: string): void } export interface UpdaterPort { checkForUpdates(): Promise /** 인자 없이 업데이터가 마지막으로 알린(update-available) 버전을 받는다. */ downloadUpdate(): Promise quitAndInstall(isSilent: boolean, isForceRunAfter: boolean): void setChannel(channel: UpdateChannel, allowPrerelease: boolean): void setDifferentialDisabled(disabled: boolean): void /** * 받아 둔 설치 파일을 앱 종료 시 설치할지. 킬 스위치·rollout 중단으로 설치 파일이 더 이상 * 허용되지 않으면 false 로 내려 종료 시 조용히 설치되는 것을 막는다. */ setAutoInstallOnQuit(enabled: boolean): void } /** 원격 정책 공급원. 실패하면 마지막으로 성공한 정책(없으면 기본값)을 돌려준다(fail-open). */ export interface PolicySource { load(): Promise } export type ConsentAnswer = 'download' | 'later' | 'skip' export type RestartAnswer = 'restart' | 'later' export interface UpdatePrompter { askConsent(input: { version: string; releaseNotes: ReleaseNotes; mandatory: boolean }): Promise /** mandatory 면 미루기('종료 시 설치') 선택지 없이 재시작만 안내한다. */ askRestart(version: string, options: { mandatory: boolean }): Promise }