import { HttpFetcher, HttpFetcherConfig, HttpFetcherRequest, HttpFetcherTarget, HttpResponseError, RequestInitType } from './HttpFetcher'; import { FetcherRequest } from './Fetcher'; export type HttpJsonFetcherConfig = HttpFetcherConfig & { responseTransform?: 'text' | 'response' | ((response: Response) => Promise); }; export type RequestJsonInit = Omit & { body?: any | null }; // type RequestJsonInit = Omit; export type HttpAnyBodyFetcherConfig = Omit, 'fetch'> & { fetch?: RequestJsonInit }; // export class HttpJsonResponseError extends HttpResponseError { // } // // export const isHttpJsonResponseError = (data: any): data is HttpJsonResponseError => { // return data instanceof HttpJsonResponseError; // } // export type HttpJsonFetcherRequest = HttpFetcherRequest>; export type HttpJsonFetcherRequest = FetcherRequest< HttpFetcherTarget, RESPONSE, HttpJsonFetcherConfig, T >; export type HttpJsonFetcherBodyAnyRequest = FetcherRequest< HttpFetcherTarget, RESPONSE, HttpAnyBodyFetcherConfig, T >; export class HttpJsonFetcher extends HttpFetcher { private updateJsonFetchConfigAndData( config: HttpJsonFetcherRequest ) { const headers = { 'Content-Type': 'application/json', Accept: 'application/json, text/plain, */*' }; config.config ??= {}; config.config.fetch ??= {}; config.config.fetch.headers ??= {}; config.config!.fetch!.headers = {...headers, ...config.config!.fetch?.headers}; if (config.config?.fetch?.body && typeof config.config?.fetch?.body !== 'string') { config.config.fetch.body = JSON.stringify(config.config.fetch.body); } return config; } get(config: HttpJsonFetcherRequest & { config: { responseTransform: 'response' } }): Promise; get(config: HttpJsonFetcherRequest & { config: { responseTransform: 'text' } }): Promise; get(config: HttpJsonFetcherRequest): Promise; get(config: HttpJsonFetcherRequest): Promise { return super.get(config); } delete(config: HttpJsonFetcherRequest & { config: { responseTransform: 'response' } }): Promise; delete(config: HttpJsonFetcherRequest & { config: { responseTransform: 'text' } }): Promise; delete(config: HttpJsonFetcherRequest): Promise; delete(config: HttpJsonFetcherRequest): Promise { return super.delete(config); } post(config: HttpJsonFetcherRequest & { config: { responseTransform: 'response' } }): Promise; post(config: HttpJsonFetcherRequest & { config: { responseTransform: 'text' } }): Promise; post(config: HttpJsonFetcherRequest): Promise; post(config: HttpJsonFetcherRequest): Promise { return super.post(config); } patch(config: HttpJsonFetcherRequest & { config: { responseTransform: 'response' } }): Promise; patch(config: HttpJsonFetcherRequest & { config: { responseTransform: 'text' } }): Promise; patch(config: HttpJsonFetcherRequest): Promise; patch(config: HttpJsonFetcherRequest): Promise { return super.patch(config); } put(config: HttpJsonFetcherRequest & { config: { responseTransform: 'response' } }): Promise; put(config: HttpJsonFetcherRequest & { config: { responseTransform: 'text' } }): Promise; put(config: HttpJsonFetcherRequest): Promise; put(config: HttpJsonFetcherRequest): Promise { return super.put(config); } head(config: HttpJsonFetcherRequest & { config: { responseTransform: 'response' } }): Promise; head(config: HttpJsonFetcherRequest & { config: { responseTransform: 'text' } }): Promise; head(config: HttpJsonFetcherRequest): Promise; head(config: HttpJsonFetcherRequest): Promise { return super.head(config); } postJson(config: HttpJsonFetcherBodyAnyRequest & { config: { responseTransform: 'response' } }): Promise; postJson(config: HttpJsonFetcherBodyAnyRequest & { config: { responseTransform: 'text' } }): Promise; postJson(config: HttpJsonFetcherBodyAnyRequest): Promise; postJson(config: HttpJsonFetcherBodyAnyRequest): Promise { return super.post(this.updateJsonFetchConfigAndData(config)); } patchJson(config: HttpJsonFetcherBodyAnyRequest & { config: { responseTransform: 'response' } }): Promise; patchJson(config: HttpJsonFetcherBodyAnyRequest & { config: { responseTransform: 'text' } }): Promise; patchJson(config: HttpJsonFetcherBodyAnyRequest): Promise; patchJson(config: HttpJsonFetcherBodyAnyRequest): Promise { return super.patch(this.updateJsonFetchConfigAndData(config)); } putJson(config: HttpJsonFetcherBodyAnyRequest & { config: { responseTransform: 'response' } }): Promise; putJson(config: HttpJsonFetcherBodyAnyRequest & { config: { responseTransform: 'text' } }): Promise; putJson(config: HttpJsonFetcherBodyAnyRequest): Promise; putJson(config: HttpJsonFetcherBodyAnyRequest): Promise { return super.put(this.updateJsonFetchConfigAndData(config)); } protected async errorTransform(e: any): Promise { const httpResponseError = new HttpResponseError(); httpResponseError.error = e; if (e instanceof Response) { httpResponseError.response = e; try { httpResponseError.body = await e.clone().json(); httpResponseError.message = e.statusText; } catch (parseError: any) { httpResponseError.body = parseError; // Store the parsing error httpResponseError.message = parseError.message; // Use parsing error message } } else { httpResponseError.body = e; httpResponseError.message = e.message; } return httpResponseError; } // protected execute(target: HttpFetcherTarget, config?: HttpJsonFetcherConfig): Promise { protected execute(fetcherRequest: FetcherRequest>): Promise { return super.execute(fetcherRequest).then((response: Response) => { // fetch에 있는 content-length는 서버에서 보낸값이 0 이여도 자체적으로 따로 판단해서 0이상이 나오는경우가 있다. 그리고 서버에서주는 header값도 믿긴 어렵다. // const contentLength = response.headers.get('Content-Length'); // const hasBody = contentLength && parseInt(contentLength, 10) > 0; // console.log('hgasbody', hasBody) const config = fetcherRequest.config as any; const transform = config?.responseTransform ?? (config?.bypassTransform ? 'response' : (config?.transformText ? 'text' : undefined)); if (transform === 'response') { return response; } else if (transform === 'text') { return response?.text(); } else if (typeof transform === 'function') { return transform(response); } else { return response?.text().then(it => { if ((it ?? '').length > 0) { return JSON.parse(it); } }) } }); } }