1- import nodeFetch from 'node-fetch ' ;
1+ import axios , { AxiosRequestConfig , AxiosResponse } from 'axios ' ;
22import * as querystring from 'querystring' ;
33
44import { QiitaError } from '../errors/QiitaError' ;
@@ -95,7 +95,7 @@ export abstract class Gateway {
9595 * @param options Fetch APIの第二引数に渡されるオプションです
9696 * @return パースされたJSONオブジェクトを解決するPromiseです
9797 */
98- protected async request < T > ( url : string , options : { [ key : string ] : any } = { } ) : Promise < T > {
98+ protected async request < T > ( options : AxiosRequestConfig ) : Promise < AxiosResponse < T > > {
9999 if ( ! options . headers ) {
100100 options . headers = { } ;
101101 }
@@ -112,38 +112,30 @@ export abstract class Gateway {
112112 options . headers . Authorization = `Bearer ${ this . token } ` ;
113113 }
114114
115- const response = typeof window === 'undefined'
116- ? await nodeFetch ( url , options )
117- : await fetch ( url , options ) ;
118-
119- let data ;
115+ options . transformResponse = [ ( data ) => {
116+ try {
117+ return JSON . parse ( data ) ;
118+ } catch {
119+ return data ;
120+ }
121+ } ] ;
120122
121123 try {
122- data = await response . json ( ) ;
123- } catch {
124- // JSONでパースできないレスポンスボディのときはundefinedを返す
125- data = undefined ;
126- }
127-
128- if ( response . ok ) {
129- return data as T ;
130- } else {
131- // Qiitaがエラーの際に返すステータスコードが明記されていなかったので
132- // ありそうなものをハンドルしています。
133- // ref: https://qiita.com/api/v2/docs#%E3%82%B9%E3%83%86%E3%83%BC%E3%82%BF%E3%82%B9%E3%82%B3%E3%83%BC%E3%83%89
134- switch ( response . status ) {
124+ return await axios . request < T > ( options ) ;
125+ } catch ( error ) {
126+ switch ( error . status ) {
135127 case 401 :
136- throw new QiitaUnauthorizedError ( data . message || 'リクエストに必要な権限が不足しています。' ) ;
128+ throw new QiitaUnauthorizedError ( error . data . message || 'リクエストに必要な権限が不足しています。' ) ;
137129 case 403 :
138- throw new QiitaForbiddenError ( data . message || 'このリクエストは禁止されています。' ) ;
130+ throw new QiitaForbiddenError ( error . data . message || 'このリクエストは禁止されています。' ) ;
139131 case 404 :
140- throw new QiitaNotFoundError ( data . message || '指定したエンドポイントが見つかりませんでした' ) ;
132+ throw new QiitaNotFoundError ( error . data . message || '指定したエンドポイントが見つかりませんでした' ) ;
141133 case 429 :
142- throw new QiitaRateLimitError ( data . message || 'APIのレートリミットに到達しました。時間をおいてもう一度お試しください。' ) ;
134+ throw new QiitaRateLimitError ( error . data . message || 'APIのレートリミットに到達しました。時間をおいてもう一度お試しください。' ) ;
143135 case 500 :
144- throw new QiitaInternalServerError ( data . message || 'Qiitaのサーバーが internal server error を返しました。ホストが混雑している可能性がありますので、時間をおいてもう一度お試しください。' ) ;
136+ throw new QiitaInternalServerError ( error . data . message || 'Qiitaのサーバーが internal server error を返しました。ホストが混雑している可能性がありますので、時間をおいてもう一度お試しください。' ) ;
145137 default :
146- throw new QiitaError ( 'QiitaError' , data . message || 'Qiita APIのリクエスト中に予期せぬエラーが発生しました' ) ;
138+ throw new QiitaError ( 'QiitaError' , error . data . message || 'Qiita APIのリクエスト中に予期せぬエラーが発生しました' ) ;
147139 }
148140 }
149141 }
@@ -154,8 +146,12 @@ export abstract class Gateway {
154146 * @param params クエリ文字列
155147 * @param options Fetch APIの第二引数になるオブジェクト
156148 */
157- protected get < T > ( url : string , params = { } , options = { } ) : Promise < T > {
158- return this . request ( url + ( Object . keys ( params ) . length ? '?' + querystring . stringify ( params ) : '' ) , { method : 'GET' , ...options } ) ;
149+ protected get < T > ( url : string , params = { } , options = { } ) {
150+ return this . request < T > ( {
151+ method : 'GET' ,
152+ url : url + ( Object . keys ( params ) . length ? '?' + querystring . stringify ( params ) : '' ) ,
153+ ...options ,
154+ } ) ;
159155 }
160156
161157 /**
@@ -164,8 +160,13 @@ export abstract class Gateway {
164160 * @param body リクエストボディ
165161 * @param options Fetch APIの第二引数になるオブジェクト
166162 */
167- protected post < T > ( url : string , body = { } , options = { } ) : Promise < T > {
168- return this . request ( url , { method : 'POST' , body : JSON . stringify ( body ) , ...options } ) ;
163+ protected post < T > ( url : string , body = { } , options = { } ) {
164+ return this . request < T > ( {
165+ method : 'POST' ,
166+ url,
167+ data : JSON . stringify ( body ) ,
168+ ...options ,
169+ } ) ;
169170 }
170171
171172 /**
@@ -174,8 +175,13 @@ export abstract class Gateway {
174175 * @param body リクエストボディ
175176 * @param options Fetch APIの第二引数になるオブジェクト
176177 */
177- protected put < T > ( url : string , body = { } , options = { } ) : Promise < T > {
178- return this . request ( url , { method : 'PUT' , body : JSON . stringify ( body ) , ...options } ) ;
178+ protected put < T > ( url : string , body = { } , options = { } ) {
179+ return this . request < T > ( {
180+ method : 'PUT' ,
181+ url,
182+ data : JSON . stringify ( body ) ,
183+ ...options ,
184+ } ) ;
179185 }
180186
181187 /**
@@ -184,8 +190,13 @@ export abstract class Gateway {
184190 * @param body リクエストボディ
185191 * @param options Fetch APIの第二引数になるオブジェクト
186192 */
187- protected delete < T > ( url : string , body = { } , options = { } ) : Promise < T > {
188- return this . request ( url , { method : 'DELETE' , body : JSON . stringify ( body ) , ...options } ) ;
193+ protected delete < T > ( url : string , body = { } , options = { } ) {
194+ return this . request < T > ( {
195+ method : 'DELETE' ,
196+ url,
197+ data : JSON . stringify ( body ) ,
198+ ...options ,
199+ } ) ;
189200 }
190201
191202 /**
@@ -194,7 +205,12 @@ export abstract class Gateway {
194205 * @param body リクエストボディ
195206 * @param options Fetch APIの第二引数になるオブジェクト
196207 */
197- protected patch < T > ( url : string , body = { } , options = { } ) : Promise < T > {
198- return this . request ( url , { method : 'PATCH' , body : JSON . stringify ( body ) , ...options } ) ;
208+ protected patch < T > ( url : string , body = { } , options = { } ) {
209+ return this . request < T > ( {
210+ method : 'PATCH' ,
211+ url,
212+ data : JSON . stringify ( body ) ,
213+ ...options ,
214+ } ) ;
199215 }
200216}
0 commit comments