1. Axios 方式
import axios, { AxiosInstance, AxiosResponse } from 'axios';
export class YuqueAPI {
private readonly http: AxiosInstance;
constructor(private readonly accessToken: string) {
this.http = axios.create({
baseURL: 'https://www.yuque.com/api/v2',
headers: {
'User-Agent': 'lyzhong-yuque-blog',
'X-Auth-Token': accessToken,
},
});
}
async getUser(login?: string): Promise<AxiosResponse<any>> {
return this.http.get(`/user${login ? `s/${login}` : ''}`);
}
async getRepos(login: string, offset?: number): Promise<AxiosResponse<any>> {
return this.http.get(`/users/${login}/repos`);
}
async getDocs(login: string, blogNames: string): Promise<AxiosResponse<any>> {
return this.http.get(`/repos/${login}/${blogNames}/docs`);
}
async getDoc(
login: string,
blogNames: string,
slug: string,
): Promise<AxiosResponse<any>> {
return this.http.get(`/repos/${login}/${blogNames}/docs/${slug}`);
}
}
2. 原生Fetch 方式
export class YuqueAPI {
private readonly baseUrl = 'https://www.yuque.com/api/v2';
private readonly headers = {
'User-Agent': 'lyzhong-yuque-blog',
};
constructor(private readonly accessToken: string) {
this.headers['X-Auth-Token'] = accessToken;
}
async getUser(login?: string): Promise<Response> {
const url = `${this.baseUrl}/user${login ? `s/${login}` : ''}`;
const response = await fetch(url, { headers: this.headers });
return response.json();
}
async getRepos(login: string, offset?: number): Promise<Response> {
const url = `${this.baseUrl}/users/${login}/repos`;
const response = await fetch(url, { headers: this.headers });
return response.json();
}
async getDocs(login: string, blogNames: string): Promise<Response> {
const url = `${this.baseUrl}/repos/${login}/${blogNames}/docs`;
const response = await fetch(url, { headers: this.headers });
return response.json();
}
async getDoc(
login: string,
blogNames: string,
slug: string,
): Promise<Response> {
const url = `${this.baseUrl}/repos/${login}/${blogNames}/docs/${slug}`;
const response = await fetch(url, { headers: this.headers });
return response.json();
}
}
3. 添加类型定义个 getResult 方法
const API_ROOT = 'https://www.yuque.com/api/v2';
export interface YuquePayload<T> {
data: T;
}
export interface HelloMessage {
message: string;
}
export interface User {
id: number;
type: string;
login: string;
name: string;
description: string | null;
avatar_url: string;
created_at: string;
updated_at: string;
}
export interface Repo {
id: number;
type: string;
slug: string;
name: string;
namespace: string;
user_id: string;
user: User;
description: string;
creator_id: string;
public: number;
likes_count: number;
watches_count: number;
created_at: string;
updated_at: string;
}
export interface Doc {
cover: string;
description: string;
id: number;
slug: string;
title: string;
book_id: number;
book: Repo;
user_id: number;
user: User;
format: string;
body: string;
body_draft: string;
body_html: string;
body_lake: string;
creator_id: number;
public: number;
status: number;
likes_count: number;
comments_count: number;
content_updated_at: string;
deleted_at: string;
created_at: string;
updated_at: string;
}
export class YuqueApi {
private token: string;
private headers: { [key: string]: string };
constructor(token: string) {
this.token = token;
this.headers = {
'Content-Type': 'application/json',
'User-Agent': 'lyzhong-yuque-blog',
'X-Auth-Token': this.token,
};
}
public async hello(): Promise<YuquePayload<HelloMessage>> {
const { data } = await this.getResult<HelloMessage>('/hello');
return {
data,
};
}
public async getUser(login?: string): Promise<YuquePayload<User>> {
const { data } = await this.getResult<User>(
`/user${login ? `s/${login}` : ''}`,
);
return {
data,
};
}
public async getRepos(
login: string,
offset?: number,
): Promise<YuquePayload<Repo[]>> {
const { data } = await this.getResult<Repo[]>(`/users/${login}/repos`);
return {
data,
};
}
public async getDocs(
namespace: string,
offset?: number,
): Promise<YuquePayload<Doc[]>> {
const { data } = await this.getResult<Doc[]>(`/repos/${namespace}/docs`);
return {
data,
};
}
public async getDoc(
namespace: string,
slug: string,
): Promise<YuquePayload<Doc>> {
const { data } = await this.getResult<Doc>(
`/repos/${namespace}/docs/${slug}`,
);
return {
data,
};
}
private async getResult<T>(
path: string,
options: RequestInit = {},
): Promise<YuquePayload<T>> {
const response = await fetch(`${API_ROOT}${path}`, {
method: 'GET',
headers: this.headers,
...options,
});
if (!response.ok) {
throw new Error(
`Failed to fetch ${path}, status code: ${response.status}`,
);
}
const json = await response.json();
return {
data: json,
};
}
}