import axios, { AxiosInstance } from 'axios';
export class QiitaApiClient {
private client: AxiosInstance;
private accessToken?: string;
constructor(accessToken?: string) {
this.accessToken = accessToken;
this.client = axios.create({
baseURL: 'https://qiita.com/api/v2',
headers: {
'Content-Type': 'application/json',
...(accessToken && { Authorization: `Bearer ${accessToken}` }),
},
});
}
async getAuthenticatedUser() {
this.assertAuthenticated();
const response = await this.client.get('/authenticated_user');
return response.data;
}
async getUser(userId: string) {
const response = await this.client.get(`/users/${userId}`);
return response.data;
}
async getUsers(page = 1, perPage = 20) {
const response = await this.client.get('/users', {
params: { page, per_page: perPage },
});
return response.data;
}
async getUserItems(userId: string, page = 1, perPage = 20) {
const response = await this.client.get(`/users/${userId}/items`, {
params: { page, per_page: perPage },
});
return response.data;
}
async getUserStocks(userId: string, page = 1, perPage = 20) {
const response = await this.client.get(`/users/${userId}/stocks`, {
params: { page, per_page: perPage },
});
return response.data;
}
async getUserFollowers(userId: string, page = 1, perPage = 20) {
const response = await this.client.get(`/users/${userId}/followers`, {
params: { page, per_page: perPage },
});
return response.data;
}
async getUserFollowees(userId: string, page = 1, perPage = 20) {
const response = await this.client.get(`/users/${userId}/followees`, {
params: { page, per_page: perPage },
});
return response.data;
}
async getItems(page = 1, perPage = 20, query?: string) {
const response = await this.client.get('/items', {
params: { page, per_page: perPage, ...(query && { query }) },
});
return response.data;
}
async getItem(itemId: string) {
const response = await this.client.get(`/items/${itemId}`);
return response.data;
}
async createItem(item: {
title: string;
body: string;
tags: Array<{ name: string; versions: string[] }>;
private?: boolean;
tweet?: boolean;
}) {
this.assertAuthenticated();
const response = await this.client.post('/items', item);
return response.data;
}
async updateItem(itemId: string, item: {
title: string;
body: string;
tags: Array<{ name: string; versions: string[] }>;
private?: boolean;
}) {
this.assertAuthenticated();
const response = await this.client.patch(`/items/${itemId}`, item);
return response.data;
}
async deleteItem(itemId: string) {
this.assertAuthenticated();
const response = await this.client.delete(`/items/${itemId}`);
return response.data;
}
async stockItem(itemId: string) {
this.assertAuthenticated();
await this.client.put(`/items/${itemId}/stock`);
return { success: true };
}
async unstockItem(itemId: string) {
this.assertAuthenticated();
await this.client.delete(`/items/${itemId}/stock`);
return { success: true };
}
async isItemStocked(itemId: string) {
this.assertAuthenticated();
try {
await this.client.get(`/items/${itemId}/stock`);
return { stocked: true };
} catch (error: any) {
if (error.response?.status === 404) {
return { stocked: false };
}
throw error;
}
}
async getItemStockers(itemId: string, page = 1, perPage = 20) {
const response = await this.client.get(`/items/${itemId}/stockers`, {
params: { page, per_page: perPage },
});
return response.data;
}
async getTags(page = 1, perPage = 20, sort: 'count' | 'name' = 'count') {
const response = await this.client.get('/tags', {
params: { page, per_page: perPage, sort },
});
return response.data;
}
async getTag(tagId: string) {
const response = await this.client.get(`/tags/${tagId}`);
return response.data;
}
async getTagItems(tagId: string, page = 1, perPage = 20) {
const response = await this.client.get(`/tags/${tagId}/items`, {
params: { page, per_page: perPage },
});
return response.data;
}
async followTag(tagId: string) {
this.assertAuthenticated();
await this.client.put(`/tags/${tagId}/following`);
return { success: true };
}
async unfollowTag(tagId: string) {
this.assertAuthenticated();
await this.client.delete(`/tags/${tagId}/following`);
return { success: true };
}
async isTagFollowed(tagId: string) {
this.assertAuthenticated();
try {
await this.client.get(`/tags/${tagId}/following`);
return { following: true };
} catch (error: any) {
if (error.response?.status === 404) {
return { following: false };
}
throw error;
}
}
async isUserFollowed(userId: string) {
this.assertAuthenticated();
try {
await this.client.get(`/users/${userId}/following`);
return { following: true };
} catch (error: any) {
if (error.response?.status === 404) {
return { following: false };
}
throw error;
}
}
async followUser(userId: string) {
this.assertAuthenticated();
await this.client.put(`/users/${userId}/following`);
return { success: true };
}
async unfollowUser(userId: string) {
this.assertAuthenticated();
await this.client.delete(`/users/${userId}/following`);
return { success: true };
}
async getItemComments(itemId: string) {
const response = await this.client.get(`/items/${itemId}/comments`);
return response.data;
}
async createComment(itemId: string, body: string) {
this.assertAuthenticated();
const response = await this.client.post(`/items/${itemId}/comments`, { body });
return response.data;
}
async updateComment(commentId: string, body: string) {
this.assertAuthenticated();
const response = await this.client.patch(`/comments/${commentId}`, { body });
return response.data;
}
async deleteComment(commentId: string) {
this.assertAuthenticated();
await this.client.delete(`/comments/${commentId}`);
return { success: true };
}
async getComment(commentId: string) {
const response = await this.client.get(`/comments/${commentId}`);
return response.data;
}
private assertAuthenticated() {
if (!this.accessToken) {
throw new Error('アクセストークンが必要です');
}
}
}