mirror of
https://github.com/zhou-yusen/Moving-Note.git
synced 2026-07-22 07:45:22 +00:00
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
This commit is contained in:
parent
c4b7150146
commit
3ee1efb4de
4 changed files with 53 additions and 34 deletions
|
|
@ -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)}`,
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
}
|
||||
|
|
|
|||
15
main.ts
15
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);
|
||||
});
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in a new issue