From 3ee1efb4de58e19959b455f37551b43f4e6e4ef1 Mon Sep 17 00:00:00 2001 From: Yusen <1274899438@qq.com> Date: Sat, 13 Jun 2026 21:25:47 +0800 Subject: [PATCH] Fix remaining warnings: add API response types, fix unsafe access - github-api.ts: Add ShaResponse, TreeResponse, CompareResponse, UserResponse, GitCommitResponse interfaces; cast all resp.json - github-auth.ts: Add DeviceCodeResponse, TokenResponse, UserResponse interfaces; cast all resp.json - sync-engine.ts: Remove unnecessary TFile cast, fix repoOwner -> githubUsername - main.ts: Wrap async setTimeout callback to avoid void return warning --- github-api.ts | 44 ++++++++++++++++++++++++-------------------- github-auth.ts | 22 ++++++++++++++++++---- main.ts | 15 ++++++++------- sync-engine.ts | 6 +++--- 4 files changed, 53 insertions(+), 34 deletions(-) diff --git a/github-api.ts b/github-api.ts index c752054..148c2b8 100644 --- a/github-api.ts +++ b/github-api.ts @@ -4,6 +4,16 @@ import type { GitHubFile, CompareResult, LocalFileInfo, TreeItem } from "./types const API_BASE = "https://api.github.com"; const RAW_BASE = "https://raw.githubusercontent.com"; +/** GitHub API response types */ +interface ShaResponse { sha: string } +interface TreeResponse { sha: string; tree: GitHubFile[]; truncated: boolean } +interface CompareResponse { + files: { filename: string; status: string; previous_filename?: string }[]; + commits: { sha: string }[]; +} +interface UserResponse { login: string } +interface GitCommitResponse { sha: string; tree: { sha: string } } + export class GitHubApiClient { private token: string; private owner: string; @@ -34,7 +44,7 @@ export class GitHubApiClient { url: `${API_BASE}/repos/${this.owner}/${this.repo}/commits/${this.branch}`, headers: this.headers, }); - return resp.json.sha; + return (resp.json as ShaResponse).sha; } /** @@ -45,7 +55,7 @@ export class GitHubApiClient { url: `${API_BASE}/repos/${this.owner}/${this.repo}/git/trees/${this.branch}?recursive=1`, headers: this.headers, }); - const data = resp.json; + const data = resp.json as TreeResponse; if (data.truncated) { console.warn("[moving-note] File tree truncated, some files may be missing"); } @@ -60,19 +70,13 @@ export class GitHubApiClient { url: `${API_BASE}/repos/${this.owner}/${this.repo}/compare/${oldSha}...${this.branch}`, headers: this.headers, }); - const data = resp.json; + const data = resp.json as CompareResponse; return { - files: data.files.map( - (f: { - filename: string; - status: string; - previous_filename?: string; - }) => ({ - filename: f.filename, - status: f.status, - previous_filename: f.previous_filename, - }) - ), + files: data.files.map((f) => ({ + filename: f.filename, + status: f.status, + previous_filename: f.previous_filename, + })), newSha: data.commits[data.commits.length - 1]?.sha ?? oldSha, }; } @@ -229,7 +233,7 @@ export class GitHubApiClient { url: `${API_BASE}/user`, headers: this.headers, }); - return { valid: true, username: resp.json.login }; + return { valid: true, username: (resp.json as UserResponse).login }; } catch { return { valid: false }; } @@ -246,7 +250,7 @@ export class GitHubApiClient { url: `${API_BASE}/repos/${this.owner}/${this.repo}/git/commits/${commitSha}`, headers: this.headers, }); - return resp.json.tree.sha; + return (resp.json as GitCommitResponse).tree.sha; } /** @@ -259,7 +263,7 @@ export class GitHubApiClient { headers: this.headers, body: JSON.stringify({ content, encoding }), }); - return resp.json.sha; + return (resp.json as ShaResponse).sha; } /** @@ -272,7 +276,7 @@ export class GitHubApiClient { headers: this.headers, body: JSON.stringify({ base_tree: baseTreeSha, tree: treeItems }), }); - return resp.json.sha; + return (resp.json as ShaResponse).sha; } /** @@ -285,7 +289,7 @@ export class GitHubApiClient { headers: this.headers, body: JSON.stringify({ message, tree: treeSha, parents: [parentSha] }), }); - return resp.json.sha; + return (resp.json as ShaResponse).sha; } /** @@ -353,7 +357,7 @@ export class GitHubApiClient { url: `${API_BASE}/repos/${this.owner}/${this.repo}/contents/${encodeURI(path)}?ref=${this.branch}`, headers: this.headers, }); - const fileSha = resp.json.sha; + const fileSha = (resp.json as ShaResponse).sha; await requestUrl({ url: `${API_BASE}/repos/${this.owner}/${this.repo}/contents/${encodeURI(path)}`, diff --git a/github-auth.ts b/github-auth.ts index c476803..6138f8e 100644 --- a/github-auth.ts +++ b/github-auth.ts @@ -1,5 +1,19 @@ import { requestUrl } from "obsidian"; +/** GitHub OAuth response types */ +interface DeviceCodeResponse { + device_code: string; + user_code: string; + verification_uri: string; + expires_in: number; + interval: number; +} +interface TokenResponse { + access_token?: string; + error?: string; +} +interface UserResponse { login: string } + /** * GitHub OAuth Device Flow * 无需手动创建 Token,用户只需在浏览器中输入验证码即可登录 @@ -54,7 +68,7 @@ export async function startDeviceFlow( }); const { device_code, user_code, verification_uri, expires_in, interval } = - codeResp.json; + codeResp.json as DeviceCodeResponse; // Step 2: 通知 UI 显示验证码 onCodeReady(user_code, verification_uri); @@ -83,7 +97,7 @@ export async function startDeviceFlow( }), }); - const data = tokenResp.json; + const data = tokenResp.json as TokenResponse; if (data.access_token) { // 登录成功!获取用户名 @@ -98,7 +112,7 @@ export async function startDeviceFlow( return { success: true, token: data.access_token, - username: userResp.json.login, + username: (userResp.json as UserResponse).login, }; } @@ -146,7 +160,7 @@ export async function validateToken( Accept: "application/vnd.github.v3+json", }, }); - return { valid: true, username: resp.json.login }; + return { valid: true, username: (resp.json as UserResponse).login }; } catch { return { valid: false }; } diff --git a/main.ts b/main.ts index a704707..c35801d 100644 --- a/main.ts +++ b/main.ts @@ -39,14 +39,15 @@ export default class MovingNotePlugin extends Plugin { // Sync on startup if (this.settings.syncOnStartup) { this.app.workspace.onLayoutReady(() => { - // Delay 2 seconds before syncing, wait for Obsidian to fully load - window.setTimeout(async () => { - if (this.isConfigured()) { - const result = await this.syncNow(); - if (result.filesChanged > 0) { - new Notice(result.message); + window.setTimeout(() => { + void (async () => { + if (this.isConfigured()) { + const result = await this.syncNow(); + if (result.filesChanged > 0) { + new Notice(result.message); + } } - } + })(); }, 2000); }); } diff --git a/sync-engine.ts b/sync-engine.ts index 70e9c4a..ff806af 100644 --- a/sync-engine.ts +++ b/sync-engine.ts @@ -276,7 +276,7 @@ export class SyncEngine { if (file.path.startsWith(this.app.vault.configDir + "/")) continue; try { - const buffer = await this.app.vault.readBinary(file as import("obsidian").TFile); + const buffer = await this.app.vault.readBinary(file); const sha = await this.computeGitSha1(buffer); files[file.path] = sha; } catch { @@ -351,7 +351,7 @@ export class SyncEngine { const content = await this.app.vault.read(file as import("obsidian").TFile); files.push({ path, content, encoding: "utf-8", mode: "100644" }); } else { - const buffer = await this.app.vault.readBinary(file as import("obsidian").TFile); + const buffer = await this.app.vault.readBinary(file); const base64 = this.arrayBufferToBase64(buffer); files.push({ path, content: base64, encoding: "base64", mode: "100644" }); } @@ -524,7 +524,7 @@ export class SyncEngine { private formatCommitMessage(): string { const now = new Date(); const date = now.toISOString().replace("T", " ").substring(0, 19); - const hostname = this.settings.repoOwner; + const hostname = this.settings.githubUsername || "unknown"; return this.settings.commitMessage .replace("{{date}}", date) .replace("{{hostname}}", hostname);