fork of hey-api/openapi-ts because I need some additional things
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at main 184 lines 4.4 kB view raw
1import type { Client, Config, RequestOptions } from './types'; 2import { 3 buildUrl, 4 createConfig, 5 createInterceptors, 6 getParseAs, 7 mergeConfigs, 8 mergeHeaders, 9 setAuthParams, 10} from './utils'; 11 12type ReqInit = Omit<RequestInit, 'body' | 'headers'> & { 13 body?: any; 14 headers: ReturnType<typeof mergeHeaders>; 15}; 16 17export const createClient = (config: Config = {}): Client => { 18 let _config = mergeConfigs(createConfig(), config); 19 20 const getConfig = (): Config => ({ ..._config }); 21 22 const setConfig = (config: Config): Config => { 23 _config = mergeConfigs(_config, config); 24 return getConfig(); 25 }; 26 27 const interceptors = createInterceptors< 28 Request, 29 Response, 30 unknown, 31 RequestOptions 32 >(); 33 34 // @ts-expect-error 35 const request: Client['request'] = async (options) => { 36 const opts = { 37 ..._config, 38 ...options, 39 fetch: options.fetch ?? _config.fetch ?? globalThis.fetch, 40 headers: mergeHeaders(_config.headers, options.headers), 41 }; 42 43 if (opts.security) { 44 await setAuthParams({ 45 ...opts, 46 security: opts.security, 47 }); 48 } 49 50 if (opts.requestValidator) { 51 await opts.requestValidator(opts); 52 } 53 54 if (opts.body && opts.bodySerializer) { 55 opts.body = opts.bodySerializer(opts.body); 56 } 57 58 // remove Content-Type header if body is empty to avoid sending invalid requests 59 if (opts.body === undefined || opts.body === '') { 60 opts.headers.delete('Content-Type'); 61 } 62 63 const url = buildUrl(opts); 64 const requestInit: ReqInit = { 65 redirect: 'follow', 66 ...opts, 67 }; 68 69 let request = new Request(url, requestInit); 70 71 for (const fn of interceptors.request.fns) { 72 if (fn) { 73 request = await fn(request, opts); 74 } 75 } 76 77 // fetch must be assigned here, otherwise it would throw the error: 78 // TypeError: Failed to execute 'fetch' on 'Window': Illegal invocation 79 const _fetch = opts.fetch!; 80 let response = await _fetch(request); 81 82 for (const fn of interceptors.response.fns) { 83 if (fn) { 84 response = await fn(response, request, opts); 85 } 86 } 87 88 const result = { 89 request, 90 response, 91 }; 92 93 if (response.ok) { 94 if ( 95 response.status === 204 || 96 response.headers.get('Content-Length') === '0' 97 ) { 98 return { 99 data: {}, 100 ...result, 101 }; 102 } 103 104 const parseAs = 105 (opts.parseAs === 'auto' 106 ? getParseAs(response.headers.get('Content-Type')) 107 : opts.parseAs) ?? 'json'; 108 109 let data: any; 110 switch (parseAs) { 111 case 'arrayBuffer': 112 case 'blob': 113 case 'formData': 114 case 'json': 115 case 'text': 116 data = await response[parseAs](); 117 break; 118 case 'stream': 119 return { 120 data: response.body, 121 ...result, 122 }; 123 } 124 if (parseAs === 'json') { 125 if (opts.responseValidator) { 126 await opts.responseValidator(data); 127 } 128 129 if (opts.responseTransformer) { 130 data = await opts.responseTransformer(data); 131 } 132 } 133 134 return { 135 data, 136 ...result, 137 }; 138 } 139 140 let error = await response.text(); 141 142 try { 143 error = JSON.parse(error); 144 } catch { 145 // noop 146 } 147 148 let finalError = error; 149 150 for (const fn of interceptors.error.fns) { 151 if (fn) { 152 finalError = (await fn(error, response, request, opts)) as string; 153 } 154 } 155 156 finalError = finalError || ({} as string); 157 158 if (opts.throwOnError) { 159 throw finalError; 160 } 161 162 return { 163 error: finalError, 164 ...result, 165 }; 166 }; 167 168 return { 169 buildUrl, 170 connect: (options) => request({ ...options, method: 'CONNECT' }), 171 delete: (options) => request({ ...options, method: 'DELETE' }), 172 get: (options) => request({ ...options, method: 'GET' }), 173 getConfig, 174 head: (options) => request({ ...options, method: 'HEAD' }), 175 interceptors, 176 options: (options) => request({ ...options, method: 'OPTIONS' }), 177 patch: (options) => request({ ...options, method: 'PATCH' }), 178 post: (options) => request({ ...options, method: 'POST' }), 179 put: (options) => request({ ...options, method: 'PUT' }), 180 request, 181 setConfig, 182 trace: (options) => request({ ...options, method: 'TRACE' }), 183 }; 184};