getta 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,3 +1,9 @@
1
+ #### 0.4.1 (2022-10-24)
2
+
3
+ ##### Refactors
4
+
5
+ * update logging ([addf14cc](https://github.com/badbatch/getta/commit/addf14cc344ed31aa409ea564cae15bb3f5d2b08))
6
+
1
7
  ### 0.4.0 (2022-10-23)
2
8
 
3
9
  ##### New Features
@@ -1,2 +1,2 @@
1
- import e from"@babel/runtime/helpers/defineProperty";import t from"lodash/merge";import r from"lodash/castArray";import"core-js/modules/es.promise.js";import a from"md5";import i from"query-string";const s="arrayBuffer",h="blob",o="formData",c="json",n="text",u={ARRAY_BUFFER_FORMAT:"arrayBuffer",BLOB_FORMAT:"blob",FORM_DATA_FORMAT:"formData",JSON_FORMAT:c,TEXT_FORMAT:"text"},d=e=>e,l=5e3,m={"content-type":"application/json"},_=5,p=3,T=/({type})|({id})|({id,\+})|({brief\|standard})/g,f=/({[a-zA-Z0-9_]+\?})/g,R=50,y=100,g="Getta expected to receive 'basePath' in the constructor options,\n but recevied undefined.",v="The request exceeded the maximum number of redirects, which is",q="The request exceeded the maximum number of retries, which is",E="Getta expected to receive 'get', 'post', 'put' or 'delete', but received",P="The requested resource could not been found.",b="The request timed out. Getta did not get a response within",x="get",w="post",C="put",L="delete",k=["get","post","put","delete"],D="information",$="successful",A="redirection",O="clientError",j="serverError",S=304,H=404,M="Cookie",Q="ETag",F="Location",G="If-None-Match",W="Cache-Control",B="request_sent",N="response_received";function I(e,t,r){const a=Object.keys(t);return e.replace(r,e=>a.reduce((r,a)=>e.includes(a)?t[a]:r,""))}function U(e,t,{optionalPathTemplateRegExp:r,pathTemplateCallback:a,pathTemplateData:s,pathTemplateRegExp:h,queryParams:o}){const c=e.endsWith("/")||t.startsWith("/")?"":"/";let n=`${e}${c}${t}`;if(s&&(n=a(n,s,h)),n=n.replace(r,""),n.endsWith("/")&&(n=n.substring(0,n.length-1)),o&&Object.keys(o).length){n=`${n}${i.extract(n)?"&":"?"}${i.stringify(o)}`}return n}class z{constructor(t){e(this,"_basePath",void 0),e(this,"_bodyParser",void 0),e(this,"_cache",void 0),e(this,"_conditionalRequestsEnabled",void 0),e(this,"_fetchTimeout",void 0),e(this,"_headers",void 0),e(this,"_log",void 0),e(this,"_maxRedirects",void 0),e(this,"_maxRetries",void 0),e(this,"_optionalPathTemplateRegExp",void 0),e(this,"_pathTemplateCallback",void 0),e(this,"_pathTemplateRegExp",void 0),e(this,"_performance",void 0),e(this,"_queryParams",void 0),e(this,"_rateLimitCount",0),e(this,"_rateLimitedRequestQueue",[]),e(this,"_rateLimitPerSecond",void 0),e(this,"_rateLimitTimer",null),e(this,"_requestRetryWait",void 0),e(this,"_requestTracker",{active:[],pending:new Map}),e(this,"_streamReader",void 0);const{basePath:r,bodyParser:a=d,cache:i,enableConditionalRequests:s=!0,fetchTimeout:h=l,headers:o,log:n,maxRedirects:u=_,maxRetries:v=p,optionalPathTemplateRegExp:q=f,pathTemplateCallback:E=I,pathTemplateRegExp:P=T,performance:b,queryParams:x={},rateLimitPerSecond:w=R,requestRetryWait:C=y,streamReader:L=c}=t;if(!r)throw new Error(g);this._basePath=r,this._bodyParser=a,this._cache=i,this._conditionalRequestsEnabled=s,this._fetchTimeout=h,this._headers={...m,...o||{}},this._log=n,this._maxRedirects=u,this._maxRetries=v,this._optionalPathTemplateRegExp=q,this._pathTemplateCallback=E,this._pathTemplateRegExp=P,this._performance=b,this._queryParams=x,this._rateLimitPerSecond=w,this._requestRetryWait=C,this._streamReader=L}get cache(){return this._cache}createShortcut(e,r,{method:a,...i}){if(!k.includes(a))throw new Error("Getta expected to receive 'get', 'post', 'put' or 'delete', but received "+a);this[e]=async({method:e,...s}={})=>this[null!=e?e:a](r,t({},i,s))}async delete(e,t={},r){return this._delete(e,t,r)}async get(e,t={},r){return this._get(e,t,r)}async post(e,t,r){return this._request(e,{...t,method:"post"},r)}async put(e,t,r){return this._request(e,{...t,method:"put"},r)}_addRequestToRateLimitedQueue(e,t){return new Promise(r=>{this._rateLimitedRequestQueue.push([r,e,t])})}async _cacheEntryDelete(e){if(!this._cache)return!1;try{return await this._cache.delete(e)}catch(e){return Promise.reject(e)}}async _cacheEntryGet(e){if(this._cache)try{return await this._cache.get(e)}catch(e){return Promise.reject(e)}}async _cacheEntryHas(e){if(!this._cache)return!1;try{return await this._cache.has(e)}catch(e){return!1}}async _cacheEntrySet(e,t,r){if(this._cache)try{return await this._cache.set(e,t,{cacheHeaders:r})}catch(e){return Promise.reject(e)}}async _delete(e,{headers:t={},pathTemplateData:r,queryParams:i={},...s},h){const o=U(this._basePath,e,{optionalPathTemplateRegExp:this._optionalPathTemplateRegExp,pathTemplateCallback:this._pathTemplateCallback,pathTemplateData:r,pathTemplateRegExp:this._pathTemplateRegExp,queryParams:{...this._queryParams,...i}}),c=a(o);return await this._cacheEntryHas(c)&&this._cacheEntryDelete(c),this._fetch(o,{headers:{...this._headers,...t},method:"delete",...s},h)}async _fetch(e,{redirects:t,retries:a,...i},s={}){try{return new Promise(async(r,h)=>{var o,c;const n=setTimeout(()=>{h(new Error(`${b} ${this._fetchTimeout}ms.`))},this._fetchTimeout);if(this._rateLimit(),!(this._rateLimitCount<this._rateLimitPerSecond))return void r(await this._addRequestToRateLimitedQueue(e,{redirects:t,retries:a,...i}));const u=this._performance.now();null===(o=this._log)||void 0===o||o.call(this,"request_sent",{context:{redirects:t,retries:a,url:e,...i,...s},stats:{startTime:u}});const d=await fetch(e,i),l=this._performance.now(),m=l-u;null===(c=this._log)||void 0===c||c.call(this,"response_received",{context:{redirects:t,retries:a,url:e,...i,...s},stats:{duration:m,endTime:l,startTime:u}}),clearTimeout(n);const{headers:_,status:p}=d,T=function(e){switch(!0){case e<200:return"information";case e<300:return"successful";case e<400:return"redirection";case e<500:return"clientError";default:return"serverError"}}(p);if("redirection"===T&&_.get("Location"))return void r(await this._fetchRedirectHandler(_.get("Location"),{redirects:t,status:p,...i}));if("serverError"===T)return void r(await this._fetchRetryHandler(e,{retries:a,...i}));const f=d;try{f.data=d.body?this._bodyParser(await d[this._streamReader]()):void 0,r(f)}catch(t){h([t,new Error(`Unable to ${i.method} ${e} due to previous error`)])}})}catch(e){return{errors:r(e)}}}async _fetchRedirectHandler(e,{method:t,redirects:r=1,status:a,...i}){if(r===this._maxRedirects){return{errors:[new Error(`The request exceeded the maximum number of redirects, which is ${this._maxRedirects}.`)]}}r+=1;const s=303===a?"get":t;return this._fetch(e,{method:s,redirects:r,...i})}async _fetchRetryHandler(e,{retries:t=1,...r}){return t===this._maxRetries?{errors:[new Error(`The request exceeded the maximum number of retries, which is ${this._maxRetries}.`)]}:(t+=1,await(a=this._requestRetryWait,new Promise(e=>setTimeout(e,a))),this._fetch(e,{retries:t,...r}));var a}async _get(e,{headers:t={},pathTemplateData:r,queryParams:i={}},s){const h=U(this._basePath,e,{optionalPathTemplateRegExp:this._optionalPathTemplateRegExp,pathTemplateCallback:this._pathTemplateCallback,pathTemplateData:r,pathTemplateRegExp:this._pathTemplateRegExp,queryParams:{...this._queryParams,...i}}),o=a(h),c=await this._cacheEntryHas(o);if(c){if(function(e){var t,r,a;return!(null!==(t=null==e||null===(r=e.metadata)||void 0===r||null===(a=r.cacheControl)||void 0===a?void 0:a.noCache)&&void 0!==t&&t)&&e.checkTTL()}(c))return{data:await this._cacheEntryGet(o),headers:new Headers({"cache-control":c.printCacheControl()})};if(this._conditionalRequestsEnabled){var n,u;const e=null!==(n=null==c||null===(u=c.metadata)||void 0===u?void 0:u.etag)&&void 0!==n?n:null;e&&(t["If-None-Match"]=e)}}const d=this._trackRequest(o);return d||this._getResolve(o,await this._fetch(h,{headers:{...this._headers,...t},method:"get"},s))}async _getResolve(e,t){const{data:r,headers:a,status:i}=t;if(404===i)this._cacheEntryDelete(e),t.errors||(t.errors=[]),t.errors.push(new Error("The requested resource could not been found."));else if(304===i&&a){const r=await this._cacheEntryGet(e);r&&(this._cacheEntrySet(e,r,{cacheControl:a.get("Cache-Control")||void 0,etag:a.get("ETag")||void 0}),t.data=r)}else r&&a&&this._cacheEntrySet(e,r,{cacheControl:a.get("Cache-Control")||void 0,etag:a.get("ETag")||void 0});return this._resolvePendingRequests(e,t),this._requestTracker.active=this._requestTracker.active.filter(t=>t!==e),t}_rateLimit(){this._rateLimitTimer||(this._rateLimitTimer=setTimeout(()=>{this._rateLimitTimer=null,this._rateLimitCount=0,this._rateLimitedRequestQueue.length&&this._releaseRateLimitedRequestQueue()},1e3)),this._rateLimitCount+=1}_releaseRateLimitedRequestQueue(){this._rateLimitedRequestQueue.forEach(async([e,t,r])=>{e(await this._fetch(t,r))}),this._rateLimitedRequestQueue=[]}async _request(e,{body:t,headers:r,method:a,pathTemplateData:i,queryParams:s,...h},o){const c=U(this._basePath,e,{optionalPathTemplateRegExp:this._optionalPathTemplateRegExp,pathTemplateCallback:this._pathTemplateCallback,pathTemplateData:i,pathTemplateRegExp:this._pathTemplateRegExp,queryParams:{...this._queryParams,...s}});return this._fetch(c,{body:t,headers:{...this._headers,...r},method:a,...h},o)}_resolvePendingRequests(e,t){const r=this._requestTracker.pending.get(e);r&&(r.forEach(({resolve:e})=>{e(t)}),this._requestTracker.pending.delete(e))}_setPendingRequest(e,t){let r=this._requestTracker.pending.get(e);r||(r=[]),r.push(t),this._requestTracker.pending.set(e,r)}_trackRequest(e){if(this._requestTracker.active.includes(e))return new Promise(t=>{this._setPendingRequest(e,{resolve:t})});this._requestTracker.active.push(e)}}export default function(e,t){const r=new z(e);return t?(Object.keys(t).forEach(e=>{r.createShortcut(e,...t[e])}),r):r}export{s as ARRAY_BUFFER_FORMAT,h as BLOB_FORMAT,W as CACHE_CONTROL_HEADER,O as CLIENT_ERROR_REPSONSE,M as COOKIE_HEADER,d as DEFAULT_BODY_PARSER,l as DEFAULT_FETCH_TIMEOUT,m as DEFAULT_HEADERS,_ as DEFAULT_MAX_REDIRECTS,p as DEFAULT_MAX_RETRIES,T as DEFAULT_PATH_TEMPLATE_REGEX,R as DEFAULT_RATE_LIMIT,y as DEFAULT_REQUEST_RETRY_WAIT,L as DELETE_METHOD,Q as ETAG_HEADER,k as FETCH_METHODS,b as FETCH_TIMEOUT_ERROR,o as FORM_DATA_FORMAT,x as GET_METHOD,z as Getta,G as IF_NONE_MATCH_HEADER,D as INFORMATION_REPSONSE,E as INVALID_FETCH_METHOD_ERROR,c as JSON_FORMAT,F as LOCATION_HEADER,v as MAX_REDIRECTS_EXCEEDED_ERROR,q as MAX_RETRIES_EXCEEDED_ERROR,g as MISSING_BASE_PATH_ERROR,H as NOT_FOUND_STATUS_CODE,S as NOT_MODIFIED_STATUS_CODE,f as OPTIONAL_PATH_TEMPLATE_REGEX,w as POST_METHOD,C as PUT_METHOD,A as REDIRECTION_REPSONSE,B as REQUEST_SENT,P as RESOURCE_NOT_FOUND_ERROR,N as RESPONSE_RECEIVED,j as SERVER_ERROR_REPSONSE,u as STREAM_READERS,$ as SUCCESSFUL_REPSONSE,n as TEXT_FORMAT,I as defaultPathTemplateCallback};
1
+ import e from"@babel/runtime/helpers/defineProperty";import t from"lodash/merge";import r from"lodash/castArray";import"core-js/modules/es.promise.js";import a from"md5";import s from"query-string";const i="arrayBuffer",h="blob",o="formData",c="json",n="text",u={ARRAY_BUFFER_FORMAT:"arrayBuffer",BLOB_FORMAT:"blob",FORM_DATA_FORMAT:"formData",JSON_FORMAT:c,TEXT_FORMAT:"text"},d=e=>e,l=5e3,m={"content-type":"application/json"},_=5,p=3,T=/({type})|({id})|({id,\+})|({brief\|standard})/g,R=/({[a-zA-Z0-9_]+\?})/g,f=50,g=100,y="Getta expected to receive 'basePath' in the constructor options,\n but recevied undefined.",v="The request exceeded the maximum number of redirects, which is",q="The request exceeded the maximum number of retries, which is",E="Getta expected to receive 'get', 'post', 'put' or 'delete', but received",b="The requested resource could not been found.",P="The request timed out. Getta did not get a response within",x="get",w="post",C="put",L="delete",k=["get","post","put","delete"],D="information",$="successful",A="redirection",O="clientError",j="serverError",S=304,H=404,M="Cookie",Q="ETag",F="Location",G="If-None-Match",W="Cache-Control",B="request_sent",N="response_received";function I(e,t,r){const a=Object.keys(t);return e.replace(r,e=>a.reduce((r,a)=>e.includes(a)?t[a]:r,""))}function U(e,t,{optionalPathTemplateRegExp:r,pathTemplateCallback:a,pathTemplateData:i,pathTemplateRegExp:h,queryParams:o}){const c=e.endsWith("/")||t.startsWith("/")?"":"/";let n=`${e}${c}${t}`;if(i&&(n=a(n,i,h)),n=n.replace(r,""),n.endsWith("/")&&(n=n.substring(0,n.length-1)),o&&Object.keys(o).length){n=`${n}${s.extract(n)?"&":"?"}${s.stringify(o)}`}return n}class z{constructor(t){e(this,"_basePath",void 0),e(this,"_bodyParser",void 0),e(this,"_cache",void 0),e(this,"_conditionalRequestsEnabled",void 0),e(this,"_fetchTimeout",void 0),e(this,"_headers",void 0),e(this,"_log",void 0),e(this,"_maxRedirects",void 0),e(this,"_maxRetries",void 0),e(this,"_optionalPathTemplateRegExp",void 0),e(this,"_pathTemplateCallback",void 0),e(this,"_pathTemplateRegExp",void 0),e(this,"_performance",void 0),e(this,"_queryParams",void 0),e(this,"_rateLimitCount",0),e(this,"_rateLimitedRequestQueue",[]),e(this,"_rateLimitPerSecond",void 0),e(this,"_rateLimitTimer",null),e(this,"_requestRetryWait",void 0),e(this,"_requestTracker",{active:[],pending:new Map}),e(this,"_streamReader",void 0);const{basePath:r,bodyParser:a=d,cache:s,enableConditionalRequests:i=!0,fetchTimeout:h=l,headers:o,log:n,maxRedirects:u=_,maxRetries:v=p,optionalPathTemplateRegExp:q=R,pathTemplateCallback:E=I,pathTemplateRegExp:b=T,performance:P,queryParams:x={},rateLimitPerSecond:w=f,requestRetryWait:C=g,streamReader:L=c}=t;if(!r)throw new Error(y);this._basePath=r,this._bodyParser=a,this._cache=s,this._conditionalRequestsEnabled=i,this._fetchTimeout=h,this._headers={...m,...o||{}},this._log=n,this._maxRedirects=u,this._maxRetries=v,this._optionalPathTemplateRegExp=q,this._pathTemplateCallback=E,this._pathTemplateRegExp=b,this._performance=P,this._queryParams=x,this._rateLimitPerSecond=w,this._requestRetryWait=C,this._streamReader=L}get cache(){return this._cache}createShortcut(e,r,{method:a,...s}){if(!k.includes(a))throw new Error("Getta expected to receive 'get', 'post', 'put' or 'delete', but received "+a);this[e]=async({method:e,...i}={})=>this[null!=e?e:a](r,t({},s,i))}async delete(e,t={},r){return this._delete(e,t,r)}async get(e,t={},r){return this._get(e,t,r)}async post(e,t,r){return this._request(e,{...t,method:"post"},r)}async put(e,t,r){return this._request(e,{...t,method:"put"},r)}_addRequestToRateLimitedQueue(e,t,r){return new Promise(a=>{this._rateLimitedRequestQueue.push([a,e,t,r])})}async _cacheEntryDelete(e){if(!this._cache)return!1;try{return await this._cache.delete(e)}catch(e){return Promise.reject(e)}}async _cacheEntryGet(e){if(this._cache)try{return await this._cache.get(e)}catch(e){return Promise.reject(e)}}async _cacheEntryHas(e){if(!this._cache)return!1;try{return await this._cache.has(e)}catch(e){return!1}}async _cacheEntrySet(e,t,r){if(this._cache)try{return await this._cache.set(e,t,{cacheHeaders:r})}catch(e){return Promise.reject(e)}}async _delete(e,{headers:t={},pathTemplateData:r,queryParams:s={},...i},h){const o=U(this._basePath,e,{optionalPathTemplateRegExp:this._optionalPathTemplateRegExp,pathTemplateCallback:this._pathTemplateCallback,pathTemplateData:r,pathTemplateRegExp:this._pathTemplateRegExp,queryParams:{...this._queryParams,...s}}),c=a(o);return await this._cacheEntryHas(c)&&this._cacheEntryDelete(c),this._fetch(o,{headers:{...this._headers,...t},method:"delete",...i},h)}async _fetch(e,t,a={}){a.startTime=this._performance.now();try{const{redirects:r,retries:s,...i}=t;return new Promise(async(h,o)=>{const c=setTimeout(()=>{o(new Error(`${P} ${this._fetchTimeout}ms.`))},this._fetchTimeout);if(this._rateLimit(),!(this._rateLimitCount<this._rateLimitPerSecond))return void h(await this._addRequestToRateLimitedQueue(e,t,a));var n;r||s||(null===(n=this._log)||void 0===n||n.call(this,"request_sent",{context:{redirects:r,retries:s,url:e,...i,...a},stats:{startTime:a.startTime}}));const u=await fetch(e,i);clearTimeout(c);const{headers:d,status:l}=u,m=function(e){switch(!0){case e<200:return"information";case e<300:return"successful";case e<400:return"redirection";case e<500:return"clientError";default:return"serverError"}}(l);if("redirection"===m&&d.get("Location"))return void h(await this._fetchRedirectHandler(u,d.get("Location"),{redirects:r,status:l,...i},a));if("serverError"===m)return void h(await this._fetchRetryHandler(u,e,{retries:s,...i},a));const _=u;try{_.data=u.body?this._bodyParser(await u[this._streamReader]()):void 0,this._logResponse(_,e,t,a),h(_)}catch(t){o([t,new Error(`Unable to ${i.method} ${e} due to previous error`)])}})}catch(s){const i={errors:r(s)};return this._logResponse(i,e,t,a),i}}async _fetchRedirectHandler(e,t,r,a){const{method:s,redirects:i=1,status:h,...o}=r;if(i===this._maxRedirects){const s=e;return s.errors=[new Error(`The request exceeded the maximum number of redirects, which is ${this._maxRedirects}.`)],this._logResponse(s,t,r,a),s}const c=303===h?"get":s;return this._fetch(t,{method:c,redirects:i+1,...o})}async _fetchRetryHandler(e,t,r,a){const{retries:s=1,...i}=r;if(s===this._maxRetries){const s=e;return s.errors=[new Error(`The request exceeded the maximum number of retries, which is ${this._maxRetries}.`)],this._logResponse(s,t,r,a),s}var h;return await(h=this._requestRetryWait,new Promise(e=>setTimeout(e,h))),this._fetch(t,{retries:s+1,...i})}async _get(e,{headers:t={},pathTemplateData:r,queryParams:s={}},i){const h=U(this._basePath,e,{optionalPathTemplateRegExp:this._optionalPathTemplateRegExp,pathTemplateCallback:this._pathTemplateCallback,pathTemplateData:r,pathTemplateRegExp:this._pathTemplateRegExp,queryParams:{...this._queryParams,...s}}),o=a(h),c=await this._cacheEntryHas(o);if(c){if(function(e){var t,r,a;return!(null!==(t=null==e||null===(r=e.metadata)||void 0===r||null===(a=r.cacheControl)||void 0===a?void 0:a.noCache)&&void 0!==t&&t)&&e.checkTTL()}(c))return{data:await this._cacheEntryGet(o),headers:new Headers({"cache-control":c.printCacheControl()})};if(this._conditionalRequestsEnabled){var n,u;const e=null!==(n=null==c||null===(u=c.metadata)||void 0===u?void 0:u.etag)&&void 0!==n?n:null;e&&(t["If-None-Match"]=e)}}const d=this._trackRequest(o);return d||this._getResolve(o,await this._fetch(h,{headers:{...this._headers,...t},method:"get"},i))}async _getResolve(e,t){const{data:r,headers:a,status:s}=t;if(404===s)this._cacheEntryDelete(e),t.errors||(t.errors=[]),t.errors.push(new Error("The requested resource could not been found."));else if(304===s&&a){const r=await this._cacheEntryGet(e);r&&(this._cacheEntrySet(e,r,{cacheControl:a.get("Cache-Control")||void 0,etag:a.get("ETag")||void 0}),t.data=r)}else r&&a&&this._cacheEntrySet(e,r,{cacheControl:a.get("Cache-Control")||void 0,etag:a.get("ETag")||void 0});return this._resolvePendingRequests(e,t),this._requestTracker.active=this._requestTracker.active.filter(t=>t!==e),t}_logResponse(e,t,r,a){var s;const{data:i,errors:h,headers:o,status:c}=e,{redirects:n,retries:u}=r,{startTime:d,...l}=a,m=this._performance.now(),_=m-d;null===(s=this._log)||void 0===s||s.call(this,"response_received",{context:{body:i?{data:i}:{errors:null!=h?h:[]},headers:o,method:r.method,redirects:n,retries:u,status:c,url:t,...l},stats:{duration:_,endTime:m,startTime:d}})}_rateLimit(){this._rateLimitTimer||(this._rateLimitTimer=setTimeout(()=>{this._rateLimitTimer=null,this._rateLimitCount=0,this._rateLimitedRequestQueue.length&&this._releaseRateLimitedRequestQueue()},1e3)),this._rateLimitCount+=1}_releaseRateLimitedRequestQueue(){this._rateLimitedRequestQueue.forEach(async([e,t,r,a])=>{e(await this._fetch(t,r,a))}),this._rateLimitedRequestQueue=[]}async _request(e,{body:t,headers:r,method:a,pathTemplateData:s,queryParams:i,...h},o){const c=U(this._basePath,e,{optionalPathTemplateRegExp:this._optionalPathTemplateRegExp,pathTemplateCallback:this._pathTemplateCallback,pathTemplateData:s,pathTemplateRegExp:this._pathTemplateRegExp,queryParams:{...this._queryParams,...i}});return this._fetch(c,{body:t,headers:{...this._headers,...r},method:a,...h},o)}_resolvePendingRequests(e,t){const r=this._requestTracker.pending.get(e);r&&(r.forEach(({resolve:e})=>{e(t)}),this._requestTracker.pending.delete(e))}_setPendingRequest(e,t){let r=this._requestTracker.pending.get(e);r||(r=[]),r.push(t),this._requestTracker.pending.set(e,r)}_trackRequest(e){if(this._requestTracker.active.includes(e))return new Promise(t=>{this._setPendingRequest(e,{resolve:t})});this._requestTracker.active.push(e)}}export default function(e,t){const r=new z(e);return t?(Object.keys(t).forEach(e=>{r.createShortcut(e,...t[e])}),r):r}export{i as ARRAY_BUFFER_FORMAT,h as BLOB_FORMAT,W as CACHE_CONTROL_HEADER,O as CLIENT_ERROR_REPSONSE,M as COOKIE_HEADER,d as DEFAULT_BODY_PARSER,l as DEFAULT_FETCH_TIMEOUT,m as DEFAULT_HEADERS,_ as DEFAULT_MAX_REDIRECTS,p as DEFAULT_MAX_RETRIES,T as DEFAULT_PATH_TEMPLATE_REGEX,f as DEFAULT_RATE_LIMIT,g as DEFAULT_REQUEST_RETRY_WAIT,L as DELETE_METHOD,Q as ETAG_HEADER,k as FETCH_METHODS,P as FETCH_TIMEOUT_ERROR,o as FORM_DATA_FORMAT,x as GET_METHOD,z as Getta,G as IF_NONE_MATCH_HEADER,D as INFORMATION_REPSONSE,E as INVALID_FETCH_METHOD_ERROR,c as JSON_FORMAT,F as LOCATION_HEADER,v as MAX_REDIRECTS_EXCEEDED_ERROR,q as MAX_RETRIES_EXCEEDED_ERROR,y as MISSING_BASE_PATH_ERROR,H as NOT_FOUND_STATUS_CODE,S as NOT_MODIFIED_STATUS_CODE,R as OPTIONAL_PATH_TEMPLATE_REGEX,w as POST_METHOD,C as PUT_METHOD,A as REDIRECTION_REPSONSE,B as REQUEST_SENT,b as RESOURCE_NOT_FOUND_ERROR,N as RESPONSE_RECEIVED,j as SERVER_ERROR_REPSONSE,u as STREAM_READERS,$ as SUCCESSFUL_REPSONSE,n as TEXT_FORMAT,I as defaultPathTemplateCallback};
2
2
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../getta/src/constants.ts","../getta/src/helpers/default-path-template-callback/index.ts","../getta/src/helpers/build-endpoint/index.ts","../getta/src/main.ts","../getta/src/helpers/get-response-group/index.ts","../getta/src/helpers/delay/index.ts","../getta/src/helpers/is-cacheability-valid/index.ts"],"sourcesContent":["import { PlainObject } from \"@repodog/types\";\n\nexport const ARRAY_BUFFER_FORMAT = \"arrayBuffer\" as const;\nexport const BLOB_FORMAT = \"blob\" as const;\nexport const FORM_DATA_FORMAT = \"formData\" as const;\nexport const JSON_FORMAT = \"json\" as const;\nexport const TEXT_FORMAT = \"text\" as const;\n\nexport const STREAM_READERS = {\n ARRAY_BUFFER_FORMAT,\n BLOB_FORMAT,\n FORM_DATA_FORMAT,\n JSON_FORMAT,\n TEXT_FORMAT,\n};\n\nexport const DEFAULT_BODY_PARSER = (body: PlainObject) => body;\nexport const DEFAULT_FETCH_TIMEOUT = 5000 as const;\nexport const DEFAULT_HEADERS = { \"content-type\": \"application/json\" };\nexport const DEFAULT_MAX_REDIRECTS = 5 as const;\nexport const DEFAULT_MAX_RETRIES = 3 as const;\nexport const DEFAULT_PATH_TEMPLATE_REGEX = /({type})|({id})|({id,\\+})|({brief\\|standard})/g;\nexport const OPTIONAL_PATH_TEMPLATE_REGEX = /({[a-zA-Z0-9_]+\\?})/g;\nexport const DEFAULT_RATE_LIMIT = 50;\nexport const DEFAULT_REQUEST_RETRY_WAIT = 100;\n\nexport const MISSING_BASE_PATH_ERROR = `Getta expected to receive 'basePath' in the constructor options,\n but recevied undefined.`;\n\nexport const MAX_REDIRECTS_EXCEEDED_ERROR = \"The request exceeded the maximum number of redirects, which is\";\n\nexport const MAX_RETRIES_EXCEEDED_ERROR = \"The request exceeded the maximum number of retries, which is\";\n\nexport const INVALID_FETCH_METHOD_ERROR = \"Getta expected to receive 'get', 'post', 'put' or 'delete', but received\";\n\nexport const RESOURCE_NOT_FOUND_ERROR = \"The requested resource could not been found.\";\n\nexport const FETCH_TIMEOUT_ERROR = \"The request timed out. Getta did not get a response within\";\n\nexport const GET_METHOD = \"get\" as const;\nexport const POST_METHOD = \"post\" as const;\nexport const PUT_METHOD = \"put\" as const;\nexport const DELETE_METHOD = \"delete\" as const;\n\nexport const FETCH_METHODS = [GET_METHOD, POST_METHOD, PUT_METHOD, DELETE_METHOD];\n\nexport const INFORMATION_REPSONSE = \"information\" as const;\nexport const SUCCESSFUL_REPSONSE = \"successful\" as const;\nexport const REDIRECTION_REPSONSE = \"redirection\" as const;\nexport const CLIENT_ERROR_REPSONSE = \"clientError\" as const;\nexport const SERVER_ERROR_REPSONSE = \"serverError\" as const;\n\nexport const NOT_MODIFIED_STATUS_CODE = 304 as const;\nexport const NOT_FOUND_STATUS_CODE = 404 as const;\n\nexport const COOKIE_HEADER = \"Cookie\" as const;\nexport const ETAG_HEADER = \"ETag\" as const;\nexport const LOCATION_HEADER = \"Location\" as const;\nexport const IF_NONE_MATCH_HEADER = \"If-None-Match\" as const;\nexport const CACHE_CONTROL_HEADER = \"Cache-Control\" as const;\n\nexport const REQUEST_SENT = \"request_sent\" as const;\nexport const RESPONSE_RECEIVED = \"response_received\" as const;\n","import { StringObject } from \"@repodog/types\";\n\nexport default function defaultPathTemplateCallback(\n pathTemplate: string,\n data: StringObject,\n pathTemplateRegExp: RegExp,\n) {\n const dataKeys = Object.keys(data);\n\n return pathTemplate.replace(pathTemplateRegExp, match => {\n return dataKeys.reduce((value, key) => {\n if (match.includes(key)) return data[key];\n return value;\n }, \"\");\n });\n}\n","import queryString from \"query-string\";\nimport { BuildEndpointOptions } from \"./types\";\n\nexport default function buildEndpoint(\n basePath: string,\n path: string,\n {\n optionalPathTemplateRegExp,\n pathTemplateCallback,\n pathTemplateData,\n pathTemplateRegExp,\n queryParams,\n }: BuildEndpointOptions,\n) {\n const pathJoiner = basePath.endsWith(\"/\") || path.startsWith(\"/\") ? \"\" : \"/\";\n let endpoint = `${basePath}${pathJoiner}${path}`;\n\n if (pathTemplateData) {\n endpoint = pathTemplateCallback(endpoint, pathTemplateData, pathTemplateRegExp);\n }\n\n endpoint = endpoint.replace(optionalPathTemplateRegExp, \"\");\n\n if (endpoint.endsWith(\"/\")) {\n endpoint = endpoint.substring(0, endpoint.length - 1);\n }\n\n if (queryParams && Object.keys(queryParams).length) {\n const queryJoin = queryString.extract(endpoint) ? \"&\" : \"?\";\n endpoint = `${endpoint}${queryJoin}${queryString.stringify(queryParams)}`;\n }\n\n return endpoint;\n}\n","import Cachemap, { CacheHeaders } from \"@cachemap/core\";\nimport { Func, PlainObject, StringObject } from \"@repodog/types\";\nimport Cacheability from \"cacheability\";\nimport { castArray, merge } from \"lodash\";\nimport md5 from \"md5\";\nimport { Required } from \"utility-types\";\nimport {\n CACHE_CONTROL_HEADER,\n DEFAULT_BODY_PARSER,\n DEFAULT_FETCH_TIMEOUT,\n DEFAULT_HEADERS,\n DEFAULT_MAX_REDIRECTS,\n DEFAULT_MAX_RETRIES,\n DEFAULT_PATH_TEMPLATE_REGEX,\n DEFAULT_RATE_LIMIT,\n DEFAULT_REQUEST_RETRY_WAIT,\n DELETE_METHOD,\n ETAG_HEADER,\n FETCH_METHODS,\n FETCH_TIMEOUT_ERROR,\n GET_METHOD,\n IF_NONE_MATCH_HEADER,\n INVALID_FETCH_METHOD_ERROR,\n JSON_FORMAT,\n LOCATION_HEADER,\n MAX_REDIRECTS_EXCEEDED_ERROR,\n MAX_RETRIES_EXCEEDED_ERROR,\n MISSING_BASE_PATH_ERROR,\n NOT_FOUND_STATUS_CODE,\n NOT_MODIFIED_STATUS_CODE,\n OPTIONAL_PATH_TEMPLATE_REGEX,\n POST_METHOD,\n PUT_METHOD,\n REDIRECTION_REPSONSE,\n REQUEST_SENT,\n RESOURCE_NOT_FOUND_ERROR,\n RESPONSE_RECEIVED,\n SERVER_ERROR_REPSONSE,\n} from \"./constants\";\nimport buildEndpoint from \"./helpers/build-endpoint\";\nimport defaultPathTemplateCallback from \"./helpers/default-path-template-callback\";\nimport delay from \"./helpers/delay\";\nimport getResponseGroup from \"./helpers/get-response-group\";\nimport isCacheabilityValid from \"./helpers/is-cacheability-valid\";\nimport {\n ConstructorOptions,\n FetchOptions,\n FetchRedirectHandlerOptions,\n FetchResponse,\n Log,\n PathTemplateCallback,\n PendingRequestResolver,\n PendingRequestResolvers,\n Performance,\n RequestOptions,\n RequestQueue,\n RequestTracker,\n ShortcutProperties,\n Shortcuts,\n StreamReader,\n} from \"./types\";\n\nexport class Getta {\n private _basePath: string;\n private _bodyParser: Func;\n private _cache?: Cachemap;\n private _conditionalRequestsEnabled: boolean;\n private _fetchTimeout: number;\n private _headers: StringObject;\n private _log: Log | undefined;\n private _maxRedirects: number;\n private _maxRetries: number;\n private _optionalPathTemplateRegExp: RegExp;\n private _pathTemplateCallback: PathTemplateCallback;\n private _pathTemplateRegExp: RegExp;\n private _performance: Performance;\n private _queryParams: PlainObject;\n private _rateLimitCount: number = 0;\n private _rateLimitedRequestQueue: RequestQueue = [];\n private _rateLimitPerSecond: number;\n private _rateLimitTimer: NodeJS.Timer | null = null;\n private _requestRetryWait: number;\n private _requestTracker: RequestTracker = { active: [], pending: new Map() };\n private _streamReader: StreamReader;\n\n constructor(options: ConstructorOptions) {\n const {\n basePath,\n bodyParser = DEFAULT_BODY_PARSER,\n cache,\n enableConditionalRequests = true,\n fetchTimeout = DEFAULT_FETCH_TIMEOUT,\n headers,\n log,\n maxRedirects = DEFAULT_MAX_REDIRECTS,\n maxRetries = DEFAULT_MAX_RETRIES,\n optionalPathTemplateRegExp = OPTIONAL_PATH_TEMPLATE_REGEX,\n pathTemplateCallback = defaultPathTemplateCallback,\n pathTemplateRegExp = DEFAULT_PATH_TEMPLATE_REGEX,\n performance,\n queryParams = {},\n rateLimitPerSecond = DEFAULT_RATE_LIMIT,\n requestRetryWait = DEFAULT_REQUEST_RETRY_WAIT,\n streamReader = JSON_FORMAT,\n } = options;\n\n if (!basePath) {\n throw new Error(MISSING_BASE_PATH_ERROR);\n }\n\n this._basePath = basePath;\n this._bodyParser = bodyParser;\n this._cache = cache;\n this._conditionalRequestsEnabled = enableConditionalRequests;\n this._fetchTimeout = fetchTimeout;\n this._headers = { ...DEFAULT_HEADERS, ...(headers || {}) };\n this._log = log;\n this._maxRedirects = maxRedirects;\n this._maxRetries = maxRetries;\n this._optionalPathTemplateRegExp = optionalPathTemplateRegExp;\n this._pathTemplateCallback = pathTemplateCallback;\n this._pathTemplateRegExp = pathTemplateRegExp;\n this._performance = performance;\n this._queryParams = queryParams;\n this._rateLimitPerSecond = rateLimitPerSecond;\n this._requestRetryWait = requestRetryWait;\n this._streamReader = streamReader;\n }\n\n get cache(): Cachemap | undefined {\n return this._cache;\n }\n\n public createShortcut(name: string, path: string, { method, ...rest }: Required<RequestOptions, \"method\">) {\n if (!FETCH_METHODS.includes(method)) {\n throw new Error(`${INVALID_FETCH_METHOD_ERROR} ${method}`);\n }\n\n // @ts-ignore\n this[name] = async <Resource extends PlainObject>({ method: requestMethod, ...requestRest }: RequestOptions = {}) =>\n // @ts-ignore\n this[requestMethod ?? method](path, merge({}, rest, requestRest)) as Promise<FetchResponse<Resource>>;\n }\n\n public async delete(path: string, options: Omit<RequestOptions, \"method\"> = {}, context?: PlainObject) {\n return this._delete(path, options, context);\n }\n\n public async get(path: string, options: Omit<RequestOptions, \"method\"> = {}, context?: PlainObject) {\n return this._get(path, options, context);\n }\n\n public async post(path: string, options: Omit<Required<RequestOptions, \"body\">, \"method\">, context?: PlainObject) {\n return this._request(path, { ...options, method: POST_METHOD }, context);\n }\n\n public async put(path: string, options: Omit<Required<RequestOptions, \"body\">, \"methood\">, context?: PlainObject) {\n return this._request(path, { ...options, method: PUT_METHOD }, context);\n }\n\n private _addRequestToRateLimitedQueue(endpoint: string, options: FetchOptions) {\n return new Promise((resolve: (value: FetchResponse) => void) => {\n this._rateLimitedRequestQueue.push([resolve, endpoint, options]);\n });\n }\n\n private async _cacheEntryDelete(requestHash: string): Promise<boolean> {\n if (!this._cache) return false;\n\n try {\n return await this._cache.delete(requestHash);\n } catch (errors) {\n return Promise.reject(errors);\n }\n }\n\n private async _cacheEntryGet(requestHash: string): Promise<PlainObject | undefined> {\n if (!this._cache) return undefined;\n\n try {\n return await this._cache.get(requestHash);\n } catch (errors) {\n return Promise.reject(errors);\n }\n }\n\n private async _cacheEntryHas(requestHash: string): Promise<Cacheability | false> {\n if (!this._cache) return false;\n\n try {\n return await this._cache.has(requestHash);\n } catch (error) {\n return false;\n }\n }\n\n private async _cacheEntrySet(requestHash: string, data: PlainObject, cacheHeaders: CacheHeaders): Promise<void> {\n if (!this._cache) return undefined;\n\n try {\n return await this._cache.set(requestHash, data, { cacheHeaders });\n } catch (error) {\n return Promise.reject(error);\n }\n }\n\n private async _delete(\n path: string,\n { headers = {}, pathTemplateData, queryParams = {}, ...rest }: Omit<RequestOptions, \"method\">,\n context?: PlainObject,\n ) {\n const endpoint = buildEndpoint(this._basePath, path, {\n optionalPathTemplateRegExp: this._optionalPathTemplateRegExp,\n pathTemplateCallback: this._pathTemplateCallback,\n pathTemplateData,\n pathTemplateRegExp: this._pathTemplateRegExp,\n queryParams: { ...this._queryParams, ...queryParams },\n });\n\n const requestHash = md5(endpoint);\n const cacheability = await this._cacheEntryHas(requestHash);\n\n if (cacheability) {\n this._cacheEntryDelete(requestHash);\n }\n\n return this._fetch(\n endpoint,\n {\n headers: { ...this._headers, ...headers },\n method: DELETE_METHOD,\n ...rest,\n },\n context,\n );\n }\n\n private async _fetch(\n endpoint: string,\n { redirects, retries, ...rest }: FetchOptions,\n context: PlainObject = {},\n ): Promise<FetchResponse> {\n try {\n return new Promise(async (resolve: (value: FetchResponse) => void, reject) => {\n const fetchTimer = setTimeout(() => {\n reject(new Error(`${FETCH_TIMEOUT_ERROR} ${this._fetchTimeout}ms.`));\n }, this._fetchTimeout);\n\n this._rateLimit();\n\n if (!(this._rateLimitCount < this._rateLimitPerSecond)) {\n resolve(await this._addRequestToRateLimitedQueue(endpoint, { redirects, retries, ...rest }));\n return;\n }\n\n const startTime = this._performance.now();\n\n this._log?.(REQUEST_SENT, {\n context: { redirects, retries, url: endpoint, ...rest, ...context },\n stats: { startTime },\n });\n\n const res = await fetch(endpoint, rest);\n\n const endTime = this._performance.now();\n const duration = endTime - startTime;\n\n this._log?.(RESPONSE_RECEIVED, {\n context: { redirects, retries, url: endpoint, ...rest, ...context },\n stats: { duration, endTime, startTime },\n });\n\n clearTimeout(fetchTimer);\n\n const { headers, status } = res;\n const responseGroup = getResponseGroup(status);\n\n if (responseGroup === REDIRECTION_REPSONSE && headers.get(LOCATION_HEADER)) {\n resolve(\n await this._fetchRedirectHandler(headers.get(LOCATION_HEADER) as string, {\n redirects,\n status,\n ...rest,\n }),\n );\n\n return;\n }\n\n if (responseGroup === SERVER_ERROR_REPSONSE) {\n resolve(\n (await this._fetchRetryHandler(endpoint, {\n retries,\n ...rest,\n })) as FetchResponse,\n );\n\n return;\n }\n\n const fetchRes = res as FetchResponse;\n\n try {\n fetchRes.data = res.body ? this._bodyParser(await res[this._streamReader]()) : undefined;\n resolve(fetchRes);\n } catch (e) {\n reject([e, new Error(`Unable to ${rest.method} ${endpoint} due to previous error`)]);\n }\n });\n } catch (error) {\n const errorRes = { errors: castArray(error) };\n return errorRes as FetchResponse;\n }\n }\n\n private async _fetchRedirectHandler(\n endpoint: string,\n { method, redirects = 1, status, ...rest }: FetchRedirectHandlerOptions,\n ): Promise<FetchResponse> {\n if (redirects === this._maxRedirects) {\n const errorRes = {\n errors: [new Error(`${MAX_REDIRECTS_EXCEEDED_ERROR} ${this._maxRedirects}.`)],\n };\n\n return errorRes as FetchResponse;\n }\n\n redirects += 1;\n const redirectMethod = status === 303 ? GET_METHOD : method;\n return this._fetch(endpoint, { method: redirectMethod, redirects, ...rest });\n }\n\n private async _fetchRetryHandler(endpoint: string, { retries = 1, ...rest }: FetchOptions) {\n if (retries === this._maxRetries) {\n return {\n errors: [new Error(`${MAX_RETRIES_EXCEEDED_ERROR} ${this._maxRetries}.`)],\n };\n }\n\n retries += 1;\n await delay(this._requestRetryWait);\n return this._fetch(endpoint, { retries, ...rest });\n }\n\n private async _get(\n path: string,\n { headers = {}, pathTemplateData, queryParams = {} }: Omit<RequestOptions, \"method\">,\n context?: PlainObject,\n ) {\n const endpoint = buildEndpoint(this._basePath, path, {\n optionalPathTemplateRegExp: this._optionalPathTemplateRegExp,\n pathTemplateCallback: this._pathTemplateCallback,\n pathTemplateData,\n pathTemplateRegExp: this._pathTemplateRegExp,\n queryParams: { ...this._queryParams, ...queryParams },\n });\n\n const requestHash = md5(endpoint);\n const cacheability = await this._cacheEntryHas(requestHash);\n\n if (cacheability) {\n if (isCacheabilityValid(cacheability)) {\n return {\n data: await this._cacheEntryGet(requestHash),\n headers: new Headers({ \"cache-control\": cacheability.printCacheControl() }),\n };\n }\n\n if (this._conditionalRequestsEnabled) {\n const etag = cacheability?.metadata?.etag ?? null;\n if (etag) headers[IF_NONE_MATCH_HEADER] = etag;\n }\n }\n\n const pendingRequest = this._trackRequest(requestHash);\n if (pendingRequest) return pendingRequest;\n\n return this._getResolve(\n requestHash,\n await this._fetch(endpoint, { headers: { ...this._headers, ...headers }, method: GET_METHOD }, context),\n );\n }\n\n private async _getResolve(requestHash: string, res: FetchResponse) {\n const { data, headers, status } = res;\n\n if (status === NOT_FOUND_STATUS_CODE) {\n this._cacheEntryDelete(requestHash);\n\n if (!res.errors) {\n res.errors = [];\n }\n\n res.errors.push(new Error(RESOURCE_NOT_FOUND_ERROR));\n } else if (status === NOT_MODIFIED_STATUS_CODE && headers) {\n const cachedData = await this._cacheEntryGet(requestHash);\n\n if (cachedData) {\n this._cacheEntrySet(requestHash, cachedData, {\n cacheControl: headers.get(CACHE_CONTROL_HEADER) || undefined,\n etag: headers.get(ETAG_HEADER) || undefined,\n });\n\n res.data = cachedData;\n }\n } else if (data && headers) {\n this._cacheEntrySet(requestHash, data, {\n cacheControl: headers.get(CACHE_CONTROL_HEADER) || undefined,\n etag: headers.get(ETAG_HEADER) || undefined,\n });\n }\n\n this._resolvePendingRequests(requestHash, res);\n this._requestTracker.active = this._requestTracker.active.filter(value => value !== requestHash);\n return res;\n }\n\n private _rateLimit() {\n if (!this._rateLimitTimer) {\n this._rateLimitTimer = setTimeout(() => {\n this._rateLimitTimer = null;\n this._rateLimitCount = 0;\n\n if (this._rateLimitedRequestQueue.length) {\n this._releaseRateLimitedRequestQueue();\n }\n }, 1000);\n }\n\n this._rateLimitCount += 1;\n }\n\n private _releaseRateLimitedRequestQueue() {\n this._rateLimitedRequestQueue.forEach(async ([resolve, endpoint, options]) => {\n // @ts-ignore\n resolve(await this._fetch(endpoint, options));\n });\n\n this._rateLimitedRequestQueue = [];\n }\n\n private async _request(\n path: string,\n { body, headers, method, pathTemplateData, queryParams, ...rest }: Required<RequestOptions, \"method\">,\n context?: PlainObject,\n ) {\n const endpoint = buildEndpoint(this._basePath, path, {\n optionalPathTemplateRegExp: this._optionalPathTemplateRegExp,\n pathTemplateCallback: this._pathTemplateCallback,\n pathTemplateData,\n pathTemplateRegExp: this._pathTemplateRegExp,\n queryParams: { ...this._queryParams, ...queryParams },\n });\n\n return this._fetch(\n endpoint,\n {\n body,\n headers: { ...this._headers, ...headers },\n method,\n ...rest,\n },\n context,\n );\n }\n\n private _resolvePendingRequests(requestHash: string, responseData: FetchResponse) {\n const pendingRequests = this._requestTracker.pending.get(requestHash);\n if (!pendingRequests) return;\n\n pendingRequests.forEach(({ resolve }) => {\n resolve(responseData);\n });\n\n this._requestTracker.pending.delete(requestHash);\n }\n\n private _setPendingRequest(requestHash: string, resolver: PendingRequestResolvers) {\n let pending = this._requestTracker.pending.get(requestHash);\n if (!pending) pending = [];\n pending.push(resolver);\n this._requestTracker.pending.set(requestHash, pending);\n }\n\n private _trackRequest(requestHash: string): Promise<FetchResponse> | void {\n if (this._requestTracker.active.includes(requestHash)) {\n return new Promise((resolve: PendingRequestResolver) => {\n this._setPendingRequest(requestHash, { resolve });\n });\n }\n\n this._requestTracker.active.push(requestHash);\n }\n}\n\nexport default function createRestClient<N extends string>(options: ConstructorOptions, shortcuts?: Shortcuts) {\n const getta = new Getta(options) as Getta & ShortcutProperties<N>;\n if (!shortcuts) return getta;\n\n Object.keys(shortcuts).forEach(key => {\n getta.createShortcut(key, ...shortcuts[key]);\n });\n\n return getta;\n}\n","import {\n CLIENT_ERROR_REPSONSE,\n INFORMATION_REPSONSE,\n REDIRECTION_REPSONSE,\n SERVER_ERROR_REPSONSE,\n SUCCESSFUL_REPSONSE,\n} from \"../../constants\";\n\nexport default function getResponseGroup(status: number) {\n switch (true) {\n case status < 200:\n return INFORMATION_REPSONSE;\n case status < 300:\n return SUCCESSFUL_REPSONSE;\n case status < 400:\n return REDIRECTION_REPSONSE;\n case status < 500:\n return CLIENT_ERROR_REPSONSE;\n default:\n return SERVER_ERROR_REPSONSE;\n }\n}\n","export default function delay(ms: number) {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n","import Cacheability from \"cacheability\";\n\nexport default function isCacheabilityValid(cacheability: Cacheability) {\n const noCache = cacheability?.metadata?.cacheControl?.noCache ?? false;\n return !noCache && cacheability.checkTTL();\n}\n"],"names":["ARRAY_BUFFER_FORMAT","BLOB_FORMAT","FORM_DATA_FORMAT","JSON_FORMAT","TEXT_FORMAT","STREAM_READERS","DEFAULT_BODY_PARSER","body","DEFAULT_FETCH_TIMEOUT","DEFAULT_HEADERS","DEFAULT_MAX_REDIRECTS","DEFAULT_MAX_RETRIES","DEFAULT_PATH_TEMPLATE_REGEX","OPTIONAL_PATH_TEMPLATE_REGEX","DEFAULT_RATE_LIMIT","DEFAULT_REQUEST_RETRY_WAIT","MISSING_BASE_PATH_ERROR","MAX_REDIRECTS_EXCEEDED_ERROR","MAX_RETRIES_EXCEEDED_ERROR","INVALID_FETCH_METHOD_ERROR","RESOURCE_NOT_FOUND_ERROR","FETCH_TIMEOUT_ERROR","GET_METHOD","POST_METHOD","PUT_METHOD","DELETE_METHOD","FETCH_METHODS","INFORMATION_REPSONSE","SUCCESSFUL_REPSONSE","REDIRECTION_REPSONSE","CLIENT_ERROR_REPSONSE","SERVER_ERROR_REPSONSE","NOT_MODIFIED_STATUS_CODE","NOT_FOUND_STATUS_CODE","COOKIE_HEADER","ETAG_HEADER","LOCATION_HEADER","IF_NONE_MATCH_HEADER","CACHE_CONTROL_HEADER","REQUEST_SENT","RESPONSE_RECEIVED","defaultPathTemplateCallback","pathTemplate","data","pathTemplateRegExp","dataKeys","Object","keys","replace","match","reduce","value","key","includes","buildEndpoint","basePath","path","optionalPathTemplateRegExp","pathTemplateCallback","pathTemplateData","queryParams","pathJoiner","endsWith","startsWith","endpoint","substring","length","queryString","extract","stringify","Getta","constructor","options","active","pending","Map","bodyParser","cache","enableConditionalRequests","fetchTimeout","headers","log","maxRedirects","maxRetries","performance","rateLimitPerSecond","requestRetryWait","streamReader","Error","_basePath","_bodyParser","_cache","_conditionalRequestsEnabled","_fetchTimeout","_headers","_log","_maxRedirects","_maxRetries","_optionalPathTemplateRegExp","_pathTemplateCallback","_pathTemplateRegExp","_performance","_queryParams","_rateLimitPerSecond","_requestRetryWait","_streamReader","this","createShortcut","name","method","rest","async","requestMethod","requestRest","_merge","context","_delete","_get","_request","_addRequestToRateLimitedQueue","Promise","resolve","_rateLimitedRequestQueue","push","requestHash","delete","errors","reject","get","has","error","cacheHeaders","set","md5","_cacheEntryHas","_cacheEntryDelete","_fetch","redirects","retries","fetchTimer","setTimeout","_rateLimit","_rateLimitCount","startTime","now","url","stats","res","fetch","endTime","duration","clearTimeout","status","responseGroup","getResponseGroup","_fetchRedirectHandler","_fetchRetryHandler","fetchRes","undefined","e","_castArray","redirectMethod","ms","cacheability","metadata","_cacheability$metadat2","cacheControl","_cacheability$metadat3","noCache","checkTTL","isCacheabilityValid","_cacheEntryGet","Headers","printCacheControl","etag","pendingRequest","_trackRequest","_getResolve","cachedData","_cacheEntrySet","_resolvePendingRequests","_requestTracker","filter","_rateLimitTimer","_releaseRateLimitedRequestQueue","forEach","responseData","pendingRequests","_setPendingRequest","resolver","shortcuts","getta"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../getta/src/constants.ts","../getta/src/helpers/default-path-template-callback/index.ts","../getta/src/helpers/build-endpoint/index.ts","../getta/src/main.ts","../getta/src/helpers/get-response-group/index.ts","../getta/src/helpers/delay/index.ts","../getta/src/helpers/is-cacheability-valid/index.ts"],"sourcesContent":["import { PlainObject } from \"@repodog/types\";\n\nexport const ARRAY_BUFFER_FORMAT = \"arrayBuffer\" as const;\nexport const BLOB_FORMAT = \"blob\" as const;\nexport const FORM_DATA_FORMAT = \"formData\" as const;\nexport const JSON_FORMAT = \"json\" as const;\nexport const TEXT_FORMAT = \"text\" as const;\n\nexport const STREAM_READERS = {\n ARRAY_BUFFER_FORMAT,\n BLOB_FORMAT,\n FORM_DATA_FORMAT,\n JSON_FORMAT,\n TEXT_FORMAT,\n};\n\nexport const DEFAULT_BODY_PARSER = (body: PlainObject) => body;\nexport const DEFAULT_FETCH_TIMEOUT = 5000 as const;\nexport const DEFAULT_HEADERS = { \"content-type\": \"application/json\" };\nexport const DEFAULT_MAX_REDIRECTS = 5 as const;\nexport const DEFAULT_MAX_RETRIES = 3 as const;\nexport const DEFAULT_PATH_TEMPLATE_REGEX = /({type})|({id})|({id,\\+})|({brief\\|standard})/g;\nexport const OPTIONAL_PATH_TEMPLATE_REGEX = /({[a-zA-Z0-9_]+\\?})/g;\nexport const DEFAULT_RATE_LIMIT = 50;\nexport const DEFAULT_REQUEST_RETRY_WAIT = 100;\n\nexport const MISSING_BASE_PATH_ERROR = `Getta expected to receive 'basePath' in the constructor options,\n but recevied undefined.`;\n\nexport const MAX_REDIRECTS_EXCEEDED_ERROR = \"The request exceeded the maximum number of redirects, which is\";\n\nexport const MAX_RETRIES_EXCEEDED_ERROR = \"The request exceeded the maximum number of retries, which is\";\n\nexport const INVALID_FETCH_METHOD_ERROR = \"Getta expected to receive 'get', 'post', 'put' or 'delete', but received\";\n\nexport const RESOURCE_NOT_FOUND_ERROR = \"The requested resource could not been found.\";\n\nexport const FETCH_TIMEOUT_ERROR = \"The request timed out. Getta did not get a response within\";\n\nexport const GET_METHOD = \"get\" as const;\nexport const POST_METHOD = \"post\" as const;\nexport const PUT_METHOD = \"put\" as const;\nexport const DELETE_METHOD = \"delete\" as const;\n\nexport const FETCH_METHODS = [GET_METHOD, POST_METHOD, PUT_METHOD, DELETE_METHOD];\n\nexport const INFORMATION_REPSONSE = \"information\" as const;\nexport const SUCCESSFUL_REPSONSE = \"successful\" as const;\nexport const REDIRECTION_REPSONSE = \"redirection\" as const;\nexport const CLIENT_ERROR_REPSONSE = \"clientError\" as const;\nexport const SERVER_ERROR_REPSONSE = \"serverError\" as const;\n\nexport const NOT_MODIFIED_STATUS_CODE = 304 as const;\nexport const NOT_FOUND_STATUS_CODE = 404 as const;\n\nexport const COOKIE_HEADER = \"Cookie\" as const;\nexport const ETAG_HEADER = \"ETag\" as const;\nexport const LOCATION_HEADER = \"Location\" as const;\nexport const IF_NONE_MATCH_HEADER = \"If-None-Match\" as const;\nexport const CACHE_CONTROL_HEADER = \"Cache-Control\" as const;\n\nexport const REQUEST_SENT = \"request_sent\" as const;\nexport const RESPONSE_RECEIVED = \"response_received\" as const;\n","import { StringObject } from \"@repodog/types\";\n\nexport default function defaultPathTemplateCallback(\n pathTemplate: string,\n data: StringObject,\n pathTemplateRegExp: RegExp,\n) {\n const dataKeys = Object.keys(data);\n\n return pathTemplate.replace(pathTemplateRegExp, match => {\n return dataKeys.reduce((value, key) => {\n if (match.includes(key)) return data[key];\n return value;\n }, \"\");\n });\n}\n","import queryString from \"query-string\";\nimport { BuildEndpointOptions } from \"./types\";\n\nexport default function buildEndpoint(\n basePath: string,\n path: string,\n {\n optionalPathTemplateRegExp,\n pathTemplateCallback,\n pathTemplateData,\n pathTemplateRegExp,\n queryParams,\n }: BuildEndpointOptions,\n) {\n const pathJoiner = basePath.endsWith(\"/\") || path.startsWith(\"/\") ? \"\" : \"/\";\n let endpoint = `${basePath}${pathJoiner}${path}`;\n\n if (pathTemplateData) {\n endpoint = pathTemplateCallback(endpoint, pathTemplateData, pathTemplateRegExp);\n }\n\n endpoint = endpoint.replace(optionalPathTemplateRegExp, \"\");\n\n if (endpoint.endsWith(\"/\")) {\n endpoint = endpoint.substring(0, endpoint.length - 1);\n }\n\n if (queryParams && Object.keys(queryParams).length) {\n const queryJoin = queryString.extract(endpoint) ? \"&\" : \"?\";\n endpoint = `${endpoint}${queryJoin}${queryString.stringify(queryParams)}`;\n }\n\n return endpoint;\n}\n","import Cachemap, { CacheHeaders } from \"@cachemap/core\";\nimport { Func, PlainObject, StringObject } from \"@repodog/types\";\nimport Cacheability from \"cacheability\";\nimport { castArray, merge } from \"lodash\";\nimport md5 from \"md5\";\nimport { Required } from \"utility-types\";\nimport {\n CACHE_CONTROL_HEADER,\n DEFAULT_BODY_PARSER,\n DEFAULT_FETCH_TIMEOUT,\n DEFAULT_HEADERS,\n DEFAULT_MAX_REDIRECTS,\n DEFAULT_MAX_RETRIES,\n DEFAULT_PATH_TEMPLATE_REGEX,\n DEFAULT_RATE_LIMIT,\n DEFAULT_REQUEST_RETRY_WAIT,\n DELETE_METHOD,\n ETAG_HEADER,\n FETCH_METHODS,\n FETCH_TIMEOUT_ERROR,\n GET_METHOD,\n IF_NONE_MATCH_HEADER,\n INVALID_FETCH_METHOD_ERROR,\n JSON_FORMAT,\n LOCATION_HEADER,\n MAX_REDIRECTS_EXCEEDED_ERROR,\n MAX_RETRIES_EXCEEDED_ERROR,\n MISSING_BASE_PATH_ERROR,\n NOT_FOUND_STATUS_CODE,\n NOT_MODIFIED_STATUS_CODE,\n OPTIONAL_PATH_TEMPLATE_REGEX,\n POST_METHOD,\n PUT_METHOD,\n REDIRECTION_REPSONSE,\n REQUEST_SENT,\n RESOURCE_NOT_FOUND_ERROR,\n RESPONSE_RECEIVED,\n SERVER_ERROR_REPSONSE,\n} from \"./constants\";\nimport buildEndpoint from \"./helpers/build-endpoint\";\nimport defaultPathTemplateCallback from \"./helpers/default-path-template-callback\";\nimport delay from \"./helpers/delay\";\nimport getResponseGroup from \"./helpers/get-response-group\";\nimport isCacheabilityValid from \"./helpers/is-cacheability-valid\";\nimport {\n ConstructorOptions,\n FetchOptions,\n FetchRedirectHandlerOptions,\n FetchResponse,\n Log,\n PathTemplateCallback,\n PendingRequestResolver,\n PendingRequestResolvers,\n Performance,\n RequestOptions,\n RequestQueue,\n RequestTracker,\n ShortcutProperties,\n Shortcuts,\n StreamReader,\n} from \"./types\";\n\nexport class Getta {\n private _basePath: string;\n private _bodyParser: Func;\n private _cache?: Cachemap;\n private _conditionalRequestsEnabled: boolean;\n private _fetchTimeout: number;\n private _headers: StringObject;\n private _log: Log | undefined;\n private _maxRedirects: number;\n private _maxRetries: number;\n private _optionalPathTemplateRegExp: RegExp;\n private _pathTemplateCallback: PathTemplateCallback;\n private _pathTemplateRegExp: RegExp;\n private _performance: Performance;\n private _queryParams: PlainObject;\n private _rateLimitCount: number = 0;\n private _rateLimitedRequestQueue: RequestQueue = [];\n private _rateLimitPerSecond: number;\n private _rateLimitTimer: NodeJS.Timer | null = null;\n private _requestRetryWait: number;\n private _requestTracker: RequestTracker = { active: [], pending: new Map() };\n private _streamReader: StreamReader;\n\n constructor(options: ConstructorOptions) {\n const {\n basePath,\n bodyParser = DEFAULT_BODY_PARSER,\n cache,\n enableConditionalRequests = true,\n fetchTimeout = DEFAULT_FETCH_TIMEOUT,\n headers,\n log,\n maxRedirects = DEFAULT_MAX_REDIRECTS,\n maxRetries = DEFAULT_MAX_RETRIES,\n optionalPathTemplateRegExp = OPTIONAL_PATH_TEMPLATE_REGEX,\n pathTemplateCallback = defaultPathTemplateCallback,\n pathTemplateRegExp = DEFAULT_PATH_TEMPLATE_REGEX,\n performance,\n queryParams = {},\n rateLimitPerSecond = DEFAULT_RATE_LIMIT,\n requestRetryWait = DEFAULT_REQUEST_RETRY_WAIT,\n streamReader = JSON_FORMAT,\n } = options;\n\n if (!basePath) {\n throw new Error(MISSING_BASE_PATH_ERROR);\n }\n\n this._basePath = basePath;\n this._bodyParser = bodyParser;\n this._cache = cache;\n this._conditionalRequestsEnabled = enableConditionalRequests;\n this._fetchTimeout = fetchTimeout;\n this._headers = { ...DEFAULT_HEADERS, ...(headers || {}) };\n this._log = log;\n this._maxRedirects = maxRedirects;\n this._maxRetries = maxRetries;\n this._optionalPathTemplateRegExp = optionalPathTemplateRegExp;\n this._pathTemplateCallback = pathTemplateCallback;\n this._pathTemplateRegExp = pathTemplateRegExp;\n this._performance = performance;\n this._queryParams = queryParams;\n this._rateLimitPerSecond = rateLimitPerSecond;\n this._requestRetryWait = requestRetryWait;\n this._streamReader = streamReader;\n }\n\n get cache(): Cachemap | undefined {\n return this._cache;\n }\n\n public createShortcut(name: string, path: string, { method, ...rest }: Required<RequestOptions, \"method\">) {\n if (!FETCH_METHODS.includes(method)) {\n throw new Error(`${INVALID_FETCH_METHOD_ERROR} ${method}`);\n }\n\n // @ts-ignore\n this[name] = async <Resource extends PlainObject>({ method: requestMethod, ...requestRest }: RequestOptions = {}) =>\n // @ts-ignore\n this[requestMethod ?? method](path, merge({}, rest, requestRest)) as Promise<FetchResponse<Resource>>;\n }\n\n public async delete(path: string, options: Omit<RequestOptions, \"method\"> = {}, context?: PlainObject) {\n return this._delete(path, options, context);\n }\n\n public async get(path: string, options: Omit<RequestOptions, \"method\"> = {}, context?: PlainObject) {\n return this._get(path, options, context);\n }\n\n public async post(path: string, options: Omit<Required<RequestOptions, \"body\">, \"method\">, context?: PlainObject) {\n return this._request(path, { ...options, method: POST_METHOD }, context);\n }\n\n public async put(path: string, options: Omit<Required<RequestOptions, \"body\">, \"methood\">, context?: PlainObject) {\n return this._request(path, { ...options, method: PUT_METHOD }, context);\n }\n\n private _addRequestToRateLimitedQueue(endpoint: string, options: FetchOptions, context: PlainObject) {\n return new Promise((resolve: (value: FetchResponse) => void) => {\n this._rateLimitedRequestQueue.push([resolve, endpoint, options, context]);\n });\n }\n\n private async _cacheEntryDelete(requestHash: string): Promise<boolean> {\n if (!this._cache) return false;\n\n try {\n return await this._cache.delete(requestHash);\n } catch (errors) {\n return Promise.reject(errors);\n }\n }\n\n private async _cacheEntryGet(requestHash: string): Promise<PlainObject | undefined> {\n if (!this._cache) return undefined;\n\n try {\n return await this._cache.get(requestHash);\n } catch (errors) {\n return Promise.reject(errors);\n }\n }\n\n private async _cacheEntryHas(requestHash: string): Promise<Cacheability | false> {\n if (!this._cache) return false;\n\n try {\n return await this._cache.has(requestHash);\n } catch (error) {\n return false;\n }\n }\n\n private async _cacheEntrySet(requestHash: string, data: PlainObject, cacheHeaders: CacheHeaders): Promise<void> {\n if (!this._cache) return undefined;\n\n try {\n return await this._cache.set(requestHash, data, { cacheHeaders });\n } catch (error) {\n return Promise.reject(error);\n }\n }\n\n private async _delete(\n path: string,\n { headers = {}, pathTemplateData, queryParams = {}, ...rest }: Omit<RequestOptions, \"method\">,\n context?: PlainObject,\n ) {\n const endpoint = buildEndpoint(this._basePath, path, {\n optionalPathTemplateRegExp: this._optionalPathTemplateRegExp,\n pathTemplateCallback: this._pathTemplateCallback,\n pathTemplateData,\n pathTemplateRegExp: this._pathTemplateRegExp,\n queryParams: { ...this._queryParams, ...queryParams },\n });\n\n const requestHash = md5(endpoint);\n const cacheability = await this._cacheEntryHas(requestHash);\n\n if (cacheability) {\n this._cacheEntryDelete(requestHash);\n }\n\n return this._fetch(\n endpoint,\n {\n headers: { ...this._headers, ...headers },\n method: DELETE_METHOD,\n ...rest,\n },\n context,\n );\n }\n\n private async _fetch(endpoint: string, options: FetchOptions, context: PlainObject = {}): Promise<FetchResponse> {\n context.startTime = this._performance.now();\n\n try {\n const { redirects, retries, ...rest } = options;\n return new Promise(async (resolve: (value: FetchResponse) => void, reject) => {\n const fetchTimer = setTimeout(() => {\n reject(new Error(`${FETCH_TIMEOUT_ERROR} ${this._fetchTimeout}ms.`));\n }, this._fetchTimeout);\n\n this._rateLimit();\n\n if (!(this._rateLimitCount < this._rateLimitPerSecond)) {\n resolve(await this._addRequestToRateLimitedQueue(endpoint, options, context));\n return;\n }\n\n if (!redirects && !retries) {\n this._log?.(REQUEST_SENT, {\n context: { redirects, retries, url: endpoint, ...rest, ...context },\n stats: { startTime: context.startTime },\n });\n }\n\n const res = await fetch(endpoint, rest);\n\n clearTimeout(fetchTimer);\n\n const { headers, status } = res;\n const responseGroup = getResponseGroup(status);\n\n if (responseGroup === REDIRECTION_REPSONSE && headers.get(LOCATION_HEADER)) {\n resolve(\n await this._fetchRedirectHandler(\n res,\n headers.get(LOCATION_HEADER) as string,\n {\n redirects,\n status,\n ...rest,\n },\n context,\n ),\n );\n\n return;\n }\n\n if (responseGroup === SERVER_ERROR_REPSONSE) {\n resolve(\n (await this._fetchRetryHandler(\n res,\n endpoint,\n {\n retries,\n ...rest,\n },\n context,\n )) as FetchResponse,\n );\n\n return;\n }\n\n const fetchRes = res as FetchResponse;\n\n try {\n fetchRes.data = res.body ? this._bodyParser(await res[this._streamReader]()) : undefined;\n this._logResponse(fetchRes, endpoint, options, context);\n resolve(fetchRes);\n } catch (e) {\n reject([e, new Error(`Unable to ${rest.method} ${endpoint} due to previous error`)]);\n }\n });\n } catch (error) {\n const fetchRes = { errors: castArray(error) };\n this._logResponse(fetchRes as FetchResponse, endpoint, options, context);\n return fetchRes as FetchResponse;\n }\n }\n\n private async _fetchRedirectHandler(\n res: Response,\n endpoint: string,\n options: FetchRedirectHandlerOptions,\n context: PlainObject,\n ): Promise<FetchResponse> {\n const { method, redirects = 1, status, ...rest } = options;\n\n if (redirects === this._maxRedirects) {\n const fetchRes = res as FetchResponse;\n fetchRes.errors = [new Error(`${MAX_REDIRECTS_EXCEEDED_ERROR} ${this._maxRedirects}.`)];\n this._logResponse(fetchRes, endpoint, options, context);\n return fetchRes;\n }\n\n const redirectMethod = status === 303 ? GET_METHOD : method;\n return this._fetch(endpoint, { method: redirectMethod, redirects: redirects + 1, ...rest });\n }\n\n private async _fetchRetryHandler(res: Response, endpoint: string, options: FetchOptions, context: PlainObject) {\n const { retries = 1, ...rest } = options;\n\n if (retries === this._maxRetries) {\n const fetchRes = res as FetchResponse;\n fetchRes.errors = [new Error(`${MAX_RETRIES_EXCEEDED_ERROR} ${this._maxRetries}.`)];\n this._logResponse(fetchRes, endpoint, options, context);\n return fetchRes;\n }\n\n await delay(this._requestRetryWait);\n return this._fetch(endpoint, { retries: retries + 1, ...rest });\n }\n\n private async _get(\n path: string,\n { headers = {}, pathTemplateData, queryParams = {} }: Omit<RequestOptions, \"method\">,\n context?: PlainObject,\n ) {\n const endpoint = buildEndpoint(this._basePath, path, {\n optionalPathTemplateRegExp: this._optionalPathTemplateRegExp,\n pathTemplateCallback: this._pathTemplateCallback,\n pathTemplateData,\n pathTemplateRegExp: this._pathTemplateRegExp,\n queryParams: { ...this._queryParams, ...queryParams },\n });\n\n const requestHash = md5(endpoint);\n const cacheability = await this._cacheEntryHas(requestHash);\n\n if (cacheability) {\n if (isCacheabilityValid(cacheability)) {\n return {\n data: await this._cacheEntryGet(requestHash),\n headers: new Headers({ \"cache-control\": cacheability.printCacheControl() }),\n };\n }\n\n if (this._conditionalRequestsEnabled) {\n const etag = cacheability?.metadata?.etag ?? null;\n if (etag) headers[IF_NONE_MATCH_HEADER] = etag;\n }\n }\n\n const pendingRequest = this._trackRequest(requestHash);\n if (pendingRequest) return pendingRequest;\n\n return this._getResolve(\n requestHash,\n await this._fetch(endpoint, { headers: { ...this._headers, ...headers }, method: GET_METHOD }, context),\n );\n }\n\n private async _getResolve(requestHash: string, res: FetchResponse) {\n const { data, headers, status } = res;\n\n if (status === NOT_FOUND_STATUS_CODE) {\n this._cacheEntryDelete(requestHash);\n\n if (!res.errors) {\n res.errors = [];\n }\n\n res.errors.push(new Error(RESOURCE_NOT_FOUND_ERROR));\n } else if (status === NOT_MODIFIED_STATUS_CODE && headers) {\n const cachedData = await this._cacheEntryGet(requestHash);\n\n if (cachedData) {\n this._cacheEntrySet(requestHash, cachedData, {\n cacheControl: headers.get(CACHE_CONTROL_HEADER) || undefined,\n etag: headers.get(ETAG_HEADER) || undefined,\n });\n\n res.data = cachedData;\n }\n } else if (data && headers) {\n this._cacheEntrySet(requestHash, data, {\n cacheControl: headers.get(CACHE_CONTROL_HEADER) || undefined,\n etag: headers.get(ETAG_HEADER) || undefined,\n });\n }\n\n this._resolvePendingRequests(requestHash, res);\n this._requestTracker.active = this._requestTracker.active.filter(value => value !== requestHash);\n return res;\n }\n\n private _logResponse(res: FetchResponse, endpoint: string, options: FetchOptions, context: PlainObject) {\n const { data, errors, headers, status } = res;\n const { redirects, retries } = options;\n const { startTime, ...otherContext } = context;\n\n const endTime = this._performance.now();\n const duration = endTime - startTime;\n\n this._log?.(RESPONSE_RECEIVED, {\n context: {\n body: data ? { data } : { errors: errors ?? [] },\n headers,\n method: options.method,\n redirects,\n retries,\n status,\n url: endpoint,\n ...otherContext,\n },\n stats: { duration, endTime, startTime },\n });\n }\n\n private _rateLimit() {\n if (!this._rateLimitTimer) {\n this._rateLimitTimer = setTimeout(() => {\n this._rateLimitTimer = null;\n this._rateLimitCount = 0;\n\n if (this._rateLimitedRequestQueue.length) {\n this._releaseRateLimitedRequestQueue();\n }\n }, 1000);\n }\n\n this._rateLimitCount += 1;\n }\n\n private _releaseRateLimitedRequestQueue() {\n this._rateLimitedRequestQueue.forEach(async ([resolve, endpoint, options, context]) => {\n // @ts-ignore\n resolve(await this._fetch(endpoint, options, context));\n });\n\n this._rateLimitedRequestQueue = [];\n }\n\n private async _request(\n path: string,\n { body, headers, method, pathTemplateData, queryParams, ...rest }: Required<RequestOptions, \"method\">,\n context?: PlainObject,\n ) {\n const endpoint = buildEndpoint(this._basePath, path, {\n optionalPathTemplateRegExp: this._optionalPathTemplateRegExp,\n pathTemplateCallback: this._pathTemplateCallback,\n pathTemplateData,\n pathTemplateRegExp: this._pathTemplateRegExp,\n queryParams: { ...this._queryParams, ...queryParams },\n });\n\n return this._fetch(\n endpoint,\n {\n body,\n headers: { ...this._headers, ...headers },\n method,\n ...rest,\n },\n context,\n );\n }\n\n private _resolvePendingRequests(requestHash: string, responseData: FetchResponse) {\n const pendingRequests = this._requestTracker.pending.get(requestHash);\n if (!pendingRequests) return;\n\n pendingRequests.forEach(({ resolve }) => {\n resolve(responseData);\n });\n\n this._requestTracker.pending.delete(requestHash);\n }\n\n private _setPendingRequest(requestHash: string, resolver: PendingRequestResolvers) {\n let pending = this._requestTracker.pending.get(requestHash);\n if (!pending) pending = [];\n pending.push(resolver);\n this._requestTracker.pending.set(requestHash, pending);\n }\n\n private _trackRequest(requestHash: string): Promise<FetchResponse> | void {\n if (this._requestTracker.active.includes(requestHash)) {\n return new Promise((resolve: PendingRequestResolver) => {\n this._setPendingRequest(requestHash, { resolve });\n });\n }\n\n this._requestTracker.active.push(requestHash);\n }\n}\n\nexport default function createRestClient<N extends string>(options: ConstructorOptions, shortcuts?: Shortcuts) {\n const getta = new Getta(options) as Getta & ShortcutProperties<N>;\n if (!shortcuts) return getta;\n\n Object.keys(shortcuts).forEach(key => {\n getta.createShortcut(key, ...shortcuts[key]);\n });\n\n return getta;\n}\n","import {\n CLIENT_ERROR_REPSONSE,\n INFORMATION_REPSONSE,\n REDIRECTION_REPSONSE,\n SERVER_ERROR_REPSONSE,\n SUCCESSFUL_REPSONSE,\n} from \"../../constants\";\n\nexport default function getResponseGroup(status: number) {\n switch (true) {\n case status < 200:\n return INFORMATION_REPSONSE;\n case status < 300:\n return SUCCESSFUL_REPSONSE;\n case status < 400:\n return REDIRECTION_REPSONSE;\n case status < 500:\n return CLIENT_ERROR_REPSONSE;\n default:\n return SERVER_ERROR_REPSONSE;\n }\n}\n","export default function delay(ms: number) {\n return new Promise(resolve => setTimeout(resolve, ms));\n}\n","import Cacheability from \"cacheability\";\n\nexport default function isCacheabilityValid(cacheability: Cacheability) {\n const noCache = cacheability?.metadata?.cacheControl?.noCache ?? false;\n return !noCache && cacheability.checkTTL();\n}\n"],"names":["ARRAY_BUFFER_FORMAT","BLOB_FORMAT","FORM_DATA_FORMAT","JSON_FORMAT","TEXT_FORMAT","STREAM_READERS","DEFAULT_BODY_PARSER","body","DEFAULT_FETCH_TIMEOUT","DEFAULT_HEADERS","DEFAULT_MAX_REDIRECTS","DEFAULT_MAX_RETRIES","DEFAULT_PATH_TEMPLATE_REGEX","OPTIONAL_PATH_TEMPLATE_REGEX","DEFAULT_RATE_LIMIT","DEFAULT_REQUEST_RETRY_WAIT","MISSING_BASE_PATH_ERROR","MAX_REDIRECTS_EXCEEDED_ERROR","MAX_RETRIES_EXCEEDED_ERROR","INVALID_FETCH_METHOD_ERROR","RESOURCE_NOT_FOUND_ERROR","FETCH_TIMEOUT_ERROR","GET_METHOD","POST_METHOD","PUT_METHOD","DELETE_METHOD","FETCH_METHODS","INFORMATION_REPSONSE","SUCCESSFUL_REPSONSE","REDIRECTION_REPSONSE","CLIENT_ERROR_REPSONSE","SERVER_ERROR_REPSONSE","NOT_MODIFIED_STATUS_CODE","NOT_FOUND_STATUS_CODE","COOKIE_HEADER","ETAG_HEADER","LOCATION_HEADER","IF_NONE_MATCH_HEADER","CACHE_CONTROL_HEADER","REQUEST_SENT","RESPONSE_RECEIVED","defaultPathTemplateCallback","pathTemplate","data","pathTemplateRegExp","dataKeys","Object","keys","replace","match","reduce","value","key","includes","buildEndpoint","basePath","path","optionalPathTemplateRegExp","pathTemplateCallback","pathTemplateData","queryParams","pathJoiner","endsWith","startsWith","endpoint","substring","length","queryString","extract","stringify","Getta","constructor","options","active","pending","Map","bodyParser","cache","enableConditionalRequests","fetchTimeout","headers","log","maxRedirects","maxRetries","performance","rateLimitPerSecond","requestRetryWait","streamReader","Error","_basePath","_bodyParser","_cache","_conditionalRequestsEnabled","_fetchTimeout","_headers","_log","_maxRedirects","_maxRetries","_optionalPathTemplateRegExp","_pathTemplateCallback","_pathTemplateRegExp","_performance","_queryParams","_rateLimitPerSecond","_requestRetryWait","_streamReader","this","createShortcut","name","method","rest","async","requestMethod","requestRest","_merge","context","_delete","_get","_request","_addRequestToRateLimitedQueue","Promise","resolve","_rateLimitedRequestQueue","push","requestHash","delete","errors","reject","get","has","error","cacheHeaders","set","md5","_cacheEntryHas","_cacheEntryDelete","_fetch","startTime","now","redirects","retries","fetchTimer","setTimeout","_rateLimit","_rateLimitCount","url","stats","res","fetch","clearTimeout","status","responseGroup","getResponseGroup","_fetchRedirectHandler","_fetchRetryHandler","fetchRes","undefined","_logResponse","e","_castArray","redirectMethod","ms","cacheability","metadata","_cacheability$metadat2","cacheControl","_cacheability$metadat3","noCache","checkTTL","isCacheabilityValid","_cacheEntryGet","Headers","printCacheControl","etag","pendingRequest","_trackRequest","_getResolve","cachedData","_cacheEntrySet","_resolvePendingRequests","_requestTracker","filter","otherContext","endTime","duration","_rateLimitTimer","_releaseRateLimitedRequestQueue","forEach","responseData","pendingRequests","_setPendingRequest","resolver","shortcuts","getta"],"mappings":"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"}
@@ -1,23 +1,23 @@
1
1
  -----------------------------
2
2
  Rollup File Analysis
3
3
  -----------------------------
4
- bundle size: 18.065 KB
5
- original size: 23.189 KB
6
- code reduction: 22.1 %
4
+ bundle size: 18.996 KB
5
+ original size: 24.359 KB
6
+ code reduction: 22.02 %
7
7
  module count: 9
8
8
 
9
9
  ██████████████████████████████████████░░░░░░░░░░░░
10
10
  file: /src/main.ts
11
- bundle space: 76.75 %
12
- rendered size: 13.864 KB
13
- original size: 15.726 KB
14
- code reduction: 11.84 %
11
+ bundle space: 77.88 %
12
+ rendered size: 14.795 KB
13
+ original size: 16.883 KB
14
+ code reduction: 12.37 %
15
15
  dependents: 1
16
16
  - /src/index.ts
17
17
 
18
18
  █████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
19
19
  file: /src/constants.ts
20
- bundle space: 11.44 %
20
+ bundle space: 10.88 %
21
21
  rendered size: 2.067 KB
22
22
  original size: 2.657 KB
23
23
  code reduction: 22.21 %
@@ -28,7 +28,7 @@ dependents: 3
28
28
 
29
29
  ██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
30
30
  file: /src/helpers/build-endpoint/index.ts
31
- bundle space: 4.37 %
31
+ bundle space: 4.16 %
32
32
  rendered size: 790 Bytes
33
33
  original size: 955 Bytes
34
34
  code reduction: 17.28 %
@@ -37,7 +37,7 @@ dependents: 1
37
37
 
38
38
  █░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
39
39
  file: /src/helpers/is-cacheability-valid/index.ts
40
- bundle space: 3.37 %
40
+ bundle space: 3.21 %
41
41
  rendered size: 609 Bytes
42
42
  original size: 238 Bytes
43
43
  code reduction: 0 %
@@ -46,7 +46,7 @@ dependents: 1
46
46
 
47
47
  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
48
48
  file: /src/helpers/get-response-group/index.ts
49
- bundle space: 1.9 %
49
+ bundle space: 1.81 %
50
50
  rendered size: 344 Bytes
51
51
  original size: 521 Bytes
52
52
  code reduction: 33.97 %
@@ -55,7 +55,7 @@ dependents: 1
55
55
 
56
56
  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
57
57
  file: /src/helpers/default-path-template-callback/index.ts
58
- bundle space: 1.72 %
58
+ bundle space: 1.64 %
59
59
  rendered size: 311 Bytes
60
60
  original size: 415 Bytes
61
61
  code reduction: 25.06 %
@@ -65,7 +65,7 @@ dependents: 2
65
65
 
66
66
  ░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░
67
67
  file: /src/helpers/delay/index.ts
68
- bundle space: 0.44 %
68
+ bundle space: 0.42 %
69
69
  rendered size: 80 Bytes
70
70
  original size: 104 Bytes
71
71
  code reduction: 23.08 %
@@ -76,7 +76,7 @@ dependents: 1
76
76
  file: /src/types.ts
77
77
  bundle space: 0 %
78
78
  rendered size: 0 Byte
79
- original size: 2.379 KB
79
+ original size: 2.392 KB
80
80
  code reduction: 100 %
81
81
  dependents: 1
82
82
  - /src/index.ts
package/lib/main/main.js CHANGED
@@ -139,9 +139,9 @@ class Getta {
139
139
  }, context);
140
140
  }
141
141
 
142
- _addRequestToRateLimitedQueue(endpoint, options) {
142
+ _addRequestToRateLimitedQueue(endpoint, options, context) {
143
143
  return new Promise(resolve => {
144
- this._rateLimitedRequestQueue.push([resolve, endpoint, options]);
144
+ this._rateLimitedRequestQueue.push([resolve, endpoint, options, context]);
145
145
  });
146
146
  }
147
147
 
@@ -218,15 +218,16 @@ class Getta {
218
218
  }, context);
219
219
  }
220
220
 
221
- async _fetch(endpoint, {
222
- redirects,
223
- retries,
224
- ...rest
225
- }, context = {}) {
221
+ async _fetch(endpoint, options, context = {}) {
222
+ context.startTime = this._performance.now();
223
+
226
224
  try {
225
+ const {
226
+ redirects,
227
+ retries,
228
+ ...rest
229
+ } = options;
227
230
  return new Promise(async (resolve, reject) => {
228
- var _this$_log, _this$_log2;
229
-
230
231
  const fetchTimer = setTimeout(() => {
231
232
  reject(new Error(`${_constants.FETCH_TIMEOUT_ERROR} ${this._fetchTimeout}ms.`));
232
233
  }, this._fetchTimeout);
@@ -234,47 +235,28 @@ class Getta {
234
235
  this._rateLimit();
235
236
 
236
237
  if (!(this._rateLimitCount < this._rateLimitPerSecond)) {
237
- resolve(await this._addRequestToRateLimitedQueue(endpoint, {
238
- redirects,
239
- retries,
240
- ...rest
241
- }));
238
+ resolve(await this._addRequestToRateLimitedQueue(endpoint, options, context));
242
239
  return;
243
240
  }
244
241
 
245
- const startTime = this._performance.now();
242
+ if (!redirects && !retries) {
243
+ var _this$_log;
244
+
245
+ (_this$_log = this._log) === null || _this$_log === void 0 ? void 0 : _this$_log.call(this, _constants.REQUEST_SENT, {
246
+ context: {
247
+ redirects,
248
+ retries,
249
+ url: endpoint,
250
+ ...rest,
251
+ ...context
252
+ },
253
+ stats: {
254
+ startTime: context.startTime
255
+ }
256
+ });
257
+ }
246
258
 
247
- (_this$_log = this._log) === null || _this$_log === void 0 ? void 0 : _this$_log.call(this, _constants.REQUEST_SENT, {
248
- context: {
249
- redirects,
250
- retries,
251
- url: endpoint,
252
- ...rest,
253
- ...context
254
- },
255
- stats: {
256
- startTime
257
- }
258
- });
259
259
  const res = await fetch(endpoint, rest);
260
-
261
- const endTime = this._performance.now();
262
-
263
- const duration = endTime - startTime;
264
- (_this$_log2 = this._log) === null || _this$_log2 === void 0 ? void 0 : _this$_log2.call(this, _constants.RESPONSE_RECEIVED, {
265
- context: {
266
- redirects,
267
- retries,
268
- url: endpoint,
269
- ...rest,
270
- ...context
271
- },
272
- stats: {
273
- duration,
274
- endTime,
275
- startTime
276
- }
277
- });
278
260
  clearTimeout(fetchTimer);
279
261
  const {
280
262
  headers,
@@ -283,19 +265,19 @@ class Getta {
283
265
  const responseGroup = (0, _getResponseGroup.default)(status);
284
266
 
285
267
  if (responseGroup === _constants.REDIRECTION_REPSONSE && headers.get(_constants.LOCATION_HEADER)) {
286
- resolve(await this._fetchRedirectHandler(headers.get(_constants.LOCATION_HEADER), {
268
+ resolve(await this._fetchRedirectHandler(res, headers.get(_constants.LOCATION_HEADER), {
287
269
  redirects,
288
270
  status,
289
271
  ...rest
290
- }));
272
+ }, context));
291
273
  return;
292
274
  }
293
275
 
294
276
  if (responseGroup === _constants.SERVER_ERROR_REPSONSE) {
295
- resolve(await this._fetchRetryHandler(endpoint, {
277
+ resolve(await this._fetchRetryHandler(res, endpoint, {
296
278
  retries,
297
279
  ...rest
298
- }));
280
+ }, context));
299
281
  return;
300
282
  }
301
283
 
@@ -303,55 +285,68 @@ class Getta {
303
285
 
304
286
  try {
305
287
  fetchRes.data = res.body ? this._bodyParser(await res[this._streamReader]()) : undefined;
288
+
289
+ this._logResponse(fetchRes, endpoint, options, context);
290
+
306
291
  resolve(fetchRes);
307
292
  } catch (e) {
308
293
  reject([e, new Error(`Unable to ${rest.method} ${endpoint} due to previous error`)]);
309
294
  }
310
295
  });
311
296
  } catch (error) {
312
- const errorRes = {
297
+ const fetchRes = {
313
298
  errors: (0, _castArray2.default)(error)
314
299
  };
315
- return errorRes;
300
+
301
+ this._logResponse(fetchRes, endpoint, options, context);
302
+
303
+ return fetchRes;
316
304
  }
317
305
  }
318
306
 
319
- async _fetchRedirectHandler(endpoint, {
320
- method,
321
- redirects = 1,
322
- status,
323
- ...rest
324
- }) {
307
+ async _fetchRedirectHandler(res, endpoint, options, context) {
308
+ const {
309
+ method,
310
+ redirects = 1,
311
+ status,
312
+ ...rest
313
+ } = options;
314
+
325
315
  if (redirects === this._maxRedirects) {
326
- const errorRes = {
327
- errors: [new Error(`${_constants.MAX_REDIRECTS_EXCEEDED_ERROR} ${this._maxRedirects}.`)]
328
- };
329
- return errorRes;
316
+ const fetchRes = res;
317
+ fetchRes.errors = [new Error(`${_constants.MAX_REDIRECTS_EXCEEDED_ERROR} ${this._maxRedirects}.`)];
318
+
319
+ this._logResponse(fetchRes, endpoint, options, context);
320
+
321
+ return fetchRes;
330
322
  }
331
323
 
332
- redirects += 1;
333
324
  const redirectMethod = status === 303 ? _constants.GET_METHOD : method;
334
325
  return this._fetch(endpoint, {
335
326
  method: redirectMethod,
336
- redirects,
327
+ redirects: redirects + 1,
337
328
  ...rest
338
329
  });
339
330
  }
340
331
 
341
- async _fetchRetryHandler(endpoint, {
342
- retries = 1,
343
- ...rest
344
- }) {
332
+ async _fetchRetryHandler(res, endpoint, options, context) {
333
+ const {
334
+ retries = 1,
335
+ ...rest
336
+ } = options;
337
+
345
338
  if (retries === this._maxRetries) {
346
- return {
347
- errors: [new Error(`${_constants.MAX_RETRIES_EXCEEDED_ERROR} ${this._maxRetries}.`)]
348
- };
339
+ const fetchRes = res;
340
+ fetchRes.errors = [new Error(`${_constants.MAX_RETRIES_EXCEEDED_ERROR} ${this._maxRetries}.`)];
341
+
342
+ this._logResponse(fetchRes, endpoint, options, context);
343
+
344
+ return fetchRes;
349
345
  }
350
346
 
351
- retries += 1;
352
347
  await (0, _delay.default)(this._requestRetryWait);
353
348
  return this._fetch(endpoint, {
354
- retries,
349
+ retries: retries + 1,
355
350
  ...rest
356
351
  });
357
352
  }
@@ -441,6 +436,50 @@ class Getta {
441
436
  return res;
442
437
  }
443
438
 
439
+ _logResponse(res, endpoint, options, context) {
440
+ var _this$_log2;
441
+
442
+ const {
443
+ data,
444
+ errors,
445
+ headers,
446
+ status
447
+ } = res;
448
+ const {
449
+ redirects,
450
+ retries
451
+ } = options;
452
+ const {
453
+ startTime,
454
+ ...otherContext
455
+ } = context;
456
+
457
+ const endTime = this._performance.now();
458
+
459
+ const duration = endTime - startTime;
460
+ (_this$_log2 = this._log) === null || _this$_log2 === void 0 ? void 0 : _this$_log2.call(this, _constants.RESPONSE_RECEIVED, {
461
+ context: {
462
+ body: data ? {
463
+ data
464
+ } : {
465
+ errors: errors !== null && errors !== void 0 ? errors : []
466
+ },
467
+ headers,
468
+ method: options.method,
469
+ redirects,
470
+ retries,
471
+ status,
472
+ url: endpoint,
473
+ ...otherContext
474
+ },
475
+ stats: {
476
+ duration,
477
+ endTime,
478
+ startTime
479
+ }
480
+ });
481
+ }
482
+
444
483
  _rateLimit() {
445
484
  if (!this._rateLimitTimer) {
446
485
  this._rateLimitTimer = setTimeout(() => {
@@ -457,8 +496,8 @@ class Getta {
457
496
  }
458
497
 
459
498
  _releaseRateLimitedRequestQueue() {
460
- this._rateLimitedRequestQueue.forEach(async ([resolve, endpoint, options]) => {
461
- resolve(await this._fetch(endpoint, options));
499
+ this._rateLimitedRequestQueue.forEach(async ([resolve, endpoint, options, context]) => {
500
+ resolve(await this._fetch(endpoint, options, context));
462
501
  });
463
502
 
464
503
  this._rateLimitedRequestQueue = [];
@@ -139,9 +139,9 @@ export class Getta {
139
139
  }, context);
140
140
  }
141
141
 
142
- _addRequestToRateLimitedQueue(endpoint, options) {
142
+ _addRequestToRateLimitedQueue(endpoint, options, context) {
143
143
  return new Promise(resolve => {
144
- this._rateLimitedRequestQueue.push([resolve, endpoint, options]);
144
+ this._rateLimitedRequestQueue.push([resolve, endpoint, options, context]);
145
145
  });
146
146
  }
147
147
 
@@ -218,15 +218,16 @@ export class Getta {
218
218
  }, context);
219
219
  }
220
220
 
221
- async _fetch(endpoint, {
222
- redirects,
223
- retries,
224
- ...rest
225
- }, context = {}) {
221
+ async _fetch(endpoint, options, context = {}) {
222
+ context.startTime = this._performance.now();
223
+
226
224
  try {
225
+ const {
226
+ redirects,
227
+ retries,
228
+ ...rest
229
+ } = options;
227
230
  return new Promise(async (resolve, reject) => {
228
- var _this$_log, _this$_log2;
229
-
230
231
  const fetchTimer = setTimeout(() => {
231
232
  reject(new Error(`${FETCH_TIMEOUT_ERROR} ${this._fetchTimeout}ms.`));
232
233
  }, this._fetchTimeout);
@@ -234,47 +235,28 @@ export class Getta {
234
235
  this._rateLimit();
235
236
 
236
237
  if (!(this._rateLimitCount < this._rateLimitPerSecond)) {
237
- resolve(await this._addRequestToRateLimitedQueue(endpoint, {
238
- redirects,
239
- retries,
240
- ...rest
241
- }));
238
+ resolve(await this._addRequestToRateLimitedQueue(endpoint, options, context));
242
239
  return;
243
240
  }
244
241
 
245
- const startTime = this._performance.now();
242
+ if (!redirects && !retries) {
243
+ var _this$_log;
244
+
245
+ (_this$_log = this._log) === null || _this$_log === void 0 ? void 0 : _this$_log.call(this, REQUEST_SENT, {
246
+ context: {
247
+ redirects,
248
+ retries,
249
+ url: endpoint,
250
+ ...rest,
251
+ ...context
252
+ },
253
+ stats: {
254
+ startTime: context.startTime
255
+ }
256
+ });
257
+ }
246
258
 
247
- (_this$_log = this._log) === null || _this$_log === void 0 ? void 0 : _this$_log.call(this, REQUEST_SENT, {
248
- context: {
249
- redirects,
250
- retries,
251
- url: endpoint,
252
- ...rest,
253
- ...context
254
- },
255
- stats: {
256
- startTime
257
- }
258
- });
259
259
  const res = await fetch(endpoint, rest);
260
-
261
- const endTime = this._performance.now();
262
-
263
- const duration = endTime - startTime;
264
- (_this$_log2 = this._log) === null || _this$_log2 === void 0 ? void 0 : _this$_log2.call(this, RESPONSE_RECEIVED, {
265
- context: {
266
- redirects,
267
- retries,
268
- url: endpoint,
269
- ...rest,
270
- ...context
271
- },
272
- stats: {
273
- duration,
274
- endTime,
275
- startTime
276
- }
277
- });
278
260
  clearTimeout(fetchTimer);
279
261
  const {
280
262
  headers,
@@ -283,19 +265,19 @@ export class Getta {
283
265
  const responseGroup = getResponseGroup(status);
284
266
 
285
267
  if (responseGroup === REDIRECTION_REPSONSE && headers.get(LOCATION_HEADER)) {
286
- resolve(await this._fetchRedirectHandler(headers.get(LOCATION_HEADER), {
268
+ resolve(await this._fetchRedirectHandler(res, headers.get(LOCATION_HEADER), {
287
269
  redirects,
288
270
  status,
289
271
  ...rest
290
- }));
272
+ }, context));
291
273
  return;
292
274
  }
293
275
 
294
276
  if (responseGroup === SERVER_ERROR_REPSONSE) {
295
- resolve(await this._fetchRetryHandler(endpoint, {
277
+ resolve(await this._fetchRetryHandler(res, endpoint, {
296
278
  retries,
297
279
  ...rest
298
- }));
280
+ }, context));
299
281
  return;
300
282
  }
301
283
 
@@ -303,55 +285,68 @@ export class Getta {
303
285
 
304
286
  try {
305
287
  fetchRes.data = res.body ? this._bodyParser(await res[this._streamReader]()) : undefined;
288
+
289
+ this._logResponse(fetchRes, endpoint, options, context);
290
+
306
291
  resolve(fetchRes);
307
292
  } catch (e) {
308
293
  reject([e, new Error(`Unable to ${rest.method} ${endpoint} due to previous error`)]);
309
294
  }
310
295
  });
311
296
  } catch (error) {
312
- const errorRes = {
297
+ const fetchRes = {
313
298
  errors: _castArray(error)
314
299
  };
315
- return errorRes;
300
+
301
+ this._logResponse(fetchRes, endpoint, options, context);
302
+
303
+ return fetchRes;
316
304
  }
317
305
  }
318
306
 
319
- async _fetchRedirectHandler(endpoint, {
320
- method,
321
- redirects = 1,
322
- status,
323
- ...rest
324
- }) {
307
+ async _fetchRedirectHandler(res, endpoint, options, context) {
308
+ const {
309
+ method,
310
+ redirects = 1,
311
+ status,
312
+ ...rest
313
+ } = options;
314
+
325
315
  if (redirects === this._maxRedirects) {
326
- const errorRes = {
327
- errors: [new Error(`${MAX_REDIRECTS_EXCEEDED_ERROR} ${this._maxRedirects}.`)]
328
- };
329
- return errorRes;
316
+ const fetchRes = res;
317
+ fetchRes.errors = [new Error(`${MAX_REDIRECTS_EXCEEDED_ERROR} ${this._maxRedirects}.`)];
318
+
319
+ this._logResponse(fetchRes, endpoint, options, context);
320
+
321
+ return fetchRes;
330
322
  }
331
323
 
332
- redirects += 1;
333
324
  const redirectMethod = status === 303 ? GET_METHOD : method;
334
325
  return this._fetch(endpoint, {
335
326
  method: redirectMethod,
336
- redirects,
327
+ redirects: redirects + 1,
337
328
  ...rest
338
329
  });
339
330
  }
340
331
 
341
- async _fetchRetryHandler(endpoint, {
342
- retries = 1,
343
- ...rest
344
- }) {
332
+ async _fetchRetryHandler(res, endpoint, options, context) {
333
+ const {
334
+ retries = 1,
335
+ ...rest
336
+ } = options;
337
+
345
338
  if (retries === this._maxRetries) {
346
- return {
347
- errors: [new Error(`${MAX_RETRIES_EXCEEDED_ERROR} ${this._maxRetries}.`)]
348
- };
339
+ const fetchRes = res;
340
+ fetchRes.errors = [new Error(`${MAX_RETRIES_EXCEEDED_ERROR} ${this._maxRetries}.`)];
341
+
342
+ this._logResponse(fetchRes, endpoint, options, context);
343
+
344
+ return fetchRes;
349
345
  }
350
346
 
351
- retries += 1;
352
347
  await delay(this._requestRetryWait);
353
348
  return this._fetch(endpoint, {
354
- retries,
349
+ retries: retries + 1,
355
350
  ...rest
356
351
  });
357
352
  }
@@ -441,6 +436,50 @@ export class Getta {
441
436
  return res;
442
437
  }
443
438
 
439
+ _logResponse(res, endpoint, options, context) {
440
+ var _this$_log2;
441
+
442
+ const {
443
+ data,
444
+ errors,
445
+ headers,
446
+ status
447
+ } = res;
448
+ const {
449
+ redirects,
450
+ retries
451
+ } = options;
452
+ const {
453
+ startTime,
454
+ ...otherContext
455
+ } = context;
456
+
457
+ const endTime = this._performance.now();
458
+
459
+ const duration = endTime - startTime;
460
+ (_this$_log2 = this._log) === null || _this$_log2 === void 0 ? void 0 : _this$_log2.call(this, RESPONSE_RECEIVED, {
461
+ context: {
462
+ body: data ? {
463
+ data
464
+ } : {
465
+ errors: errors !== null && errors !== void 0 ? errors : []
466
+ },
467
+ headers,
468
+ method: options.method,
469
+ redirects,
470
+ retries,
471
+ status,
472
+ url: endpoint,
473
+ ...otherContext
474
+ },
475
+ stats: {
476
+ duration,
477
+ endTime,
478
+ startTime
479
+ }
480
+ });
481
+ }
482
+
444
483
  _rateLimit() {
445
484
  if (!this._rateLimitTimer) {
446
485
  this._rateLimitTimer = setTimeout(() => {
@@ -457,8 +496,8 @@ export class Getta {
457
496
  }
458
497
 
459
498
  _releaseRateLimitedRequestQueue() {
460
- this._rateLimitedRequestQueue.forEach(async ([resolve, endpoint, options]) => {
461
- resolve(await this._fetch(endpoint, options));
499
+ this._rateLimitedRequestQueue.forEach(async ([resolve, endpoint, options, context]) => {
500
+ resolve(await this._fetch(endpoint, options, context));
462
501
  });
463
502
 
464
503
  this._rateLimitedRequestQueue = [];
@@ -45,6 +45,7 @@ export declare class Getta {
45
45
  private _fetchRetryHandler;
46
46
  private _get;
47
47
  private _getResolve;
48
+ private _logResponse;
48
49
  private _rateLimit;
49
50
  private _releaseRateLimitedRequestQueue;
50
51
  private _request;
@@ -1 +1 @@
1
- {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,QAA0B,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAQ,WAAW,EAAgB,MAAM,gBAAgB,CAAC;AAIjE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAuCzC,OAAO,EACL,kBAAkB,EAGlB,aAAa,EAMb,cAAc,EAGd,kBAAkB,EAClB,SAAS,EAEV,MAAM,SAAS,CAAC;AAEjB,qBAAa,KAAK;IAChB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAO;IAC1B,OAAO,CAAC,MAAM,CAAC,CAAW;IAC1B,OAAO,CAAC,2BAA2B,CAAU;IAC7C,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,2BAA2B,CAAS;IAC5C,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,wBAAwB,CAAoB;IACpD,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,eAAe,CAAsD;IAC7E,OAAO,CAAC,aAAa,CAAe;gBAExB,OAAO,EAAE,kBAAkB;IA4CvC,IAAI,KAAK,IAAI,QAAQ,GAAG,SAAS,CAEhC;IAEM,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC;IAW5F,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,EAAE,OAAO,CAAC,EAAE,WAAW;IAIxF,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,EAAE,OAAO,CAAC,EAAE,WAAW;;;;IAIrF,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,EAAE,WAAW;IAInG,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,EAAE,WAAW;IAIhH,OAAO,CAAC,6BAA6B;YAMvB,iBAAiB;YAUjB,cAAc;YAUd,cAAc;YAUd,cAAc;YAUd,OAAO;YA+BP,MAAM;YA8EN,qBAAqB;YAiBrB,kBAAkB;YAYlB,IAAI;YAuCJ,WAAW;IAkCzB,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,+BAA+B;YASzB,QAAQ;IAyBtB,OAAO,CAAC,uBAAuB;IAW/B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,aAAa;CAStB;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,SAAS,CAAC,EAAE,SAAS,iCAS5G"}
1
+ {"version":3,"file":"main.d.ts","sourceRoot":"","sources":["../../src/main.ts"],"names":[],"mappings":"AAAA,OAAO,QAA0B,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAQ,WAAW,EAAgB,MAAM,gBAAgB,CAAC;AAIjE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAuCzC,OAAO,EACL,kBAAkB,EAGlB,aAAa,EAMb,cAAc,EAGd,kBAAkB,EAClB,SAAS,EAEV,MAAM,SAAS,CAAC;AAEjB,qBAAa,KAAK;IAChB,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,WAAW,CAAO;IAC1B,OAAO,CAAC,MAAM,CAAC,CAAW;IAC1B,OAAO,CAAC,2BAA2B,CAAU;IAC7C,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,QAAQ,CAAe;IAC/B,OAAO,CAAC,IAAI,CAAkB;IAC9B,OAAO,CAAC,aAAa,CAAS;IAC9B,OAAO,CAAC,WAAW,CAAS;IAC5B,OAAO,CAAC,2BAA2B,CAAS;IAC5C,OAAO,CAAC,qBAAqB,CAAuB;IACpD,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,YAAY,CAAc;IAClC,OAAO,CAAC,eAAe,CAAa;IACpC,OAAO,CAAC,wBAAwB,CAAoB;IACpD,OAAO,CAAC,mBAAmB,CAAS;IACpC,OAAO,CAAC,eAAe,CAA6B;IACpD,OAAO,CAAC,iBAAiB,CAAS;IAClC,OAAO,CAAC,eAAe,CAAsD;IAC7E,OAAO,CAAC,aAAa,CAAe;gBAExB,OAAO,EAAE,kBAAkB;IA4CvC,IAAI,KAAK,IAAI,QAAQ,GAAG,SAAS,CAEhC;IAEM,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,GAAG,IAAI,EAAE,EAAE,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC;IAW5F,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,EAAE,OAAO,CAAC,EAAE,WAAW;IAIxF,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE,IAAI,CAAC,cAAc,EAAE,QAAQ,CAAM,EAAE,OAAO,CAAC,EAAE,WAAW;;;;IAIrF,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,EAAE,WAAW;IAInG,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,IAAI,CAAC,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,EAAE,WAAW;IAIhH,OAAO,CAAC,6BAA6B;YAMvB,iBAAiB;YAUjB,cAAc;YAUd,cAAc;YAUd,cAAc;YAUd,OAAO;YA+BP,MAAM;YAiFN,qBAAqB;YAmBrB,kBAAkB;YAclB,IAAI;YAuCJ,WAAW;IAkCzB,OAAO,CAAC,YAAY;IAuBpB,OAAO,CAAC,UAAU;IAelB,OAAO,CAAC,+BAA+B;YASzB,QAAQ;IAyBtB,OAAO,CAAC,uBAAuB;IAW/B,OAAO,CAAC,kBAAkB;IAO1B,OAAO,CAAC,aAAa;CAStB;AAED,MAAM,CAAC,OAAO,UAAU,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,OAAO,EAAE,kBAAkB,EAAE,SAAS,CAAC,EAAE,SAAS,iCAS5G"}
@@ -49,7 +49,7 @@ export interface RequestOptions {
49
49
  pathTemplateData?: StringObject;
50
50
  queryParams?: PlainObject;
51
51
  }
52
- export declare type RequestQueue = [(value: FetchResponse) => void, string, FetchOptions][];
52
+ export declare type RequestQueue = [(value: FetchResponse) => void, string, FetchOptions, PlainObject][];
53
53
  export interface ResponseDataWithErrors<Resource = PlainObject> {
54
54
  data?: Resource;
55
55
  errors?: Error[];
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,QAAQ,MAAM,gBAAgB,CAAC;AACtC,OAAO,EAAE,IAAI,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AACjE,OAAO,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAEzC,oBAAY,WAAW,GAAG,KAAK,GAAG,MAAM,GAAG,KAAK,GAAG,QAAQ,CAAC;AAE5D,oBAAY,YAAY,GAAG,aAAa,GAAG,MAAM,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjF,oBAAY,kBAAkB,CAAC,CAAC,SAAS,MAAM,GAAG,MAAM,IAAI;KACzD,CAAC,IAAI,CAAC,GAAG,CAAC,QAAQ,GAAG,WAAW,EAAE,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;CACvF,CAAC;AAEF,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,IAAI,CAAC;IAClB,KAAK,CAAC,EAAE,QAAQ,CAAC;IACjB,yBAAyB,CAAC,EAAE,OAAO,CAAC;IACpC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,GAAG,CAAC,EAAE,GAAG,CAAC;IACV,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,oBAAoB,CAAC,EAAE,oBAAoB,CAAC;IAC5C,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,WAAW,EAAE,WAAW,CAAC;IACzB,WAAW,CAAC,EAAE,WAAW,CAAC;IAC1B,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,YAAY,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,OAAO,EAAE,YAAY,CAAC;IACtB,MAAM,EAAE,WAAW,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,aAAa,CAAC,QAAQ,GAAG,WAAW,CAAE,SAAQ,sBAAsB,CAAC,QAAQ,CAAC,EAAE,QAAQ;CAAG;AAE5G,MAAM,WAAW,2BAA4B,SAAQ,YAAY;IAC/D,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,oBAAY,GAAG,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,QAAQ,CAAC,EAAE,QAAQ,KAAK,IAAI,CAAC;AAEpF,oBAAY,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,GAAG,OAAO,CAAC;AAE1F,MAAM,WAAW,WAAW;IAC1B,GAAG,IAAI,MAAM,CAAC;CACf;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,OAAO,CAAC,EAAE,YAAY,CAAC;IACvB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,gBAAgB,CAAC,EAAE,YAAY,CAAC;IAChC,WAAW,CAAC,EAAE,WAAW,CAAC;CAC3B;AAED,oBAAY,YAAY,GAAG,CAAC,CAAC,KAAK,EAAE,aAAa,KAAK,IAAI,EAAE,MAAM,EAAE,YAAY,CAAC,EAAE,CAAC;AAEpF,MAAM,WAAW,sBAAsB,CAAC,QAAQ,GAAG,WAAW;IAC5D,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,MAAM,CAAC,EAAE,KAAK,EAAE,CAAC;CAClB;AAED,oBAAY,oBAAoB,GAAG,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,EAAE,kBAAkB,EAAE,MAAM,KAAK,MAAM,CAAC;AAE5G,oBAAY,sBAAsB,GAAG,CAAC,KAAK,EAAE,aAAa,CAAC,WAAW,CAAC,KAAK,IAAI,CAAC;AAEjF,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,sBAAsB,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,uBAAuB,EAAE,CAAC,CAAC;CACjD;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,cAAc,EAAE,QAAQ,CAAC,CAAC,CAAC;CAC7D"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "getta",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "description": "An isomorphic rest client based on the Fetch API.",
5
5
  "keywords": [
6
6
  "api-client",
package/src/main.ts CHANGED
@@ -158,9 +158,9 @@ export class Getta {
158
158
  return this._request(path, { ...options, method: PUT_METHOD }, context);
159
159
  }
160
160
 
161
- private _addRequestToRateLimitedQueue(endpoint: string, options: FetchOptions) {
161
+ private _addRequestToRateLimitedQueue(endpoint: string, options: FetchOptions, context: PlainObject) {
162
162
  return new Promise((resolve: (value: FetchResponse) => void) => {
163
- this._rateLimitedRequestQueue.push([resolve, endpoint, options]);
163
+ this._rateLimitedRequestQueue.push([resolve, endpoint, options, context]);
164
164
  });
165
165
  }
166
166
 
@@ -235,12 +235,11 @@ export class Getta {
235
235
  );
236
236
  }
237
237
 
238
- private async _fetch(
239
- endpoint: string,
240
- { redirects, retries, ...rest }: FetchOptions,
241
- context: PlainObject = {},
242
- ): Promise<FetchResponse> {
238
+ private async _fetch(endpoint: string, options: FetchOptions, context: PlainObject = {}): Promise<FetchResponse> {
239
+ context.startTime = this._performance.now();
240
+
243
241
  try {
242
+ const { redirects, retries, ...rest } = options;
244
243
  return new Promise(async (resolve: (value: FetchResponse) => void, reject) => {
245
244
  const fetchTimer = setTimeout(() => {
246
245
  reject(new Error(`${FETCH_TIMEOUT_ERROR} ${this._fetchTimeout}ms.`));
@@ -249,27 +248,19 @@ export class Getta {
249
248
  this._rateLimit();
250
249
 
251
250
  if (!(this._rateLimitCount < this._rateLimitPerSecond)) {
252
- resolve(await this._addRequestToRateLimitedQueue(endpoint, { redirects, retries, ...rest }));
251
+ resolve(await this._addRequestToRateLimitedQueue(endpoint, options, context));
253
252
  return;
254
253
  }
255
254
 
256
- const startTime = this._performance.now();
257
-
258
- this._log?.(REQUEST_SENT, {
259
- context: { redirects, retries, url: endpoint, ...rest, ...context },
260
- stats: { startTime },
261
- });
255
+ if (!redirects && !retries) {
256
+ this._log?.(REQUEST_SENT, {
257
+ context: { redirects, retries, url: endpoint, ...rest, ...context },
258
+ stats: { startTime: context.startTime },
259
+ });
260
+ }
262
261
 
263
262
  const res = await fetch(endpoint, rest);
264
263
 
265
- const endTime = this._performance.now();
266
- const duration = endTime - startTime;
267
-
268
- this._log?.(RESPONSE_RECEIVED, {
269
- context: { redirects, retries, url: endpoint, ...rest, ...context },
270
- stats: { duration, endTime, startTime },
271
- });
272
-
273
264
  clearTimeout(fetchTimer);
274
265
 
275
266
  const { headers, status } = res;
@@ -277,11 +268,16 @@ export class Getta {
277
268
 
278
269
  if (responseGroup === REDIRECTION_REPSONSE && headers.get(LOCATION_HEADER)) {
279
270
  resolve(
280
- await this._fetchRedirectHandler(headers.get(LOCATION_HEADER) as string, {
281
- redirects,
282
- status,
283
- ...rest,
284
- }),
271
+ await this._fetchRedirectHandler(
272
+ res,
273
+ headers.get(LOCATION_HEADER) as string,
274
+ {
275
+ redirects,
276
+ status,
277
+ ...rest,
278
+ },
279
+ context,
280
+ ),
285
281
  );
286
282
 
287
283
  return;
@@ -289,10 +285,15 @@ export class Getta {
289
285
 
290
286
  if (responseGroup === SERVER_ERROR_REPSONSE) {
291
287
  resolve(
292
- (await this._fetchRetryHandler(endpoint, {
293
- retries,
294
- ...rest,
295
- })) as FetchResponse,
288
+ (await this._fetchRetryHandler(
289
+ res,
290
+ endpoint,
291
+ {
292
+ retries,
293
+ ...rest,
294
+ },
295
+ context,
296
+ )) as FetchResponse,
296
297
  );
297
298
 
298
299
  return;
@@ -302,44 +303,50 @@ export class Getta {
302
303
 
303
304
  try {
304
305
  fetchRes.data = res.body ? this._bodyParser(await res[this._streamReader]()) : undefined;
306
+ this._logResponse(fetchRes, endpoint, options, context);
305
307
  resolve(fetchRes);
306
308
  } catch (e) {
307
309
  reject([e, new Error(`Unable to ${rest.method} ${endpoint} due to previous error`)]);
308
310
  }
309
311
  });
310
312
  } catch (error) {
311
- const errorRes = { errors: castArray(error) };
312
- return errorRes as FetchResponse;
313
+ const fetchRes = { errors: castArray(error) };
314
+ this._logResponse(fetchRes as FetchResponse, endpoint, options, context);
315
+ return fetchRes as FetchResponse;
313
316
  }
314
317
  }
315
318
 
316
319
  private async _fetchRedirectHandler(
320
+ res: Response,
317
321
  endpoint: string,
318
- { method, redirects = 1, status, ...rest }: FetchRedirectHandlerOptions,
322
+ options: FetchRedirectHandlerOptions,
323
+ context: PlainObject,
319
324
  ): Promise<FetchResponse> {
320
- if (redirects === this._maxRedirects) {
321
- const errorRes = {
322
- errors: [new Error(`${MAX_REDIRECTS_EXCEEDED_ERROR} ${this._maxRedirects}.`)],
323
- };
325
+ const { method, redirects = 1, status, ...rest } = options;
324
326
 
325
- return errorRes as FetchResponse;
327
+ if (redirects === this._maxRedirects) {
328
+ const fetchRes = res as FetchResponse;
329
+ fetchRes.errors = [new Error(`${MAX_REDIRECTS_EXCEEDED_ERROR} ${this._maxRedirects}.`)];
330
+ this._logResponse(fetchRes, endpoint, options, context);
331
+ return fetchRes;
326
332
  }
327
333
 
328
- redirects += 1;
329
334
  const redirectMethod = status === 303 ? GET_METHOD : method;
330
- return this._fetch(endpoint, { method: redirectMethod, redirects, ...rest });
335
+ return this._fetch(endpoint, { method: redirectMethod, redirects: redirects + 1, ...rest });
331
336
  }
332
337
 
333
- private async _fetchRetryHandler(endpoint: string, { retries = 1, ...rest }: FetchOptions) {
338
+ private async _fetchRetryHandler(res: Response, endpoint: string, options: FetchOptions, context: PlainObject) {
339
+ const { retries = 1, ...rest } = options;
340
+
334
341
  if (retries === this._maxRetries) {
335
- return {
336
- errors: [new Error(`${MAX_RETRIES_EXCEEDED_ERROR} ${this._maxRetries}.`)],
337
- };
342
+ const fetchRes = res as FetchResponse;
343
+ fetchRes.errors = [new Error(`${MAX_RETRIES_EXCEEDED_ERROR} ${this._maxRetries}.`)];
344
+ this._logResponse(fetchRes, endpoint, options, context);
345
+ return fetchRes;
338
346
  }
339
347
 
340
- retries += 1;
341
348
  await delay(this._requestRetryWait);
342
- return this._fetch(endpoint, { retries, ...rest });
349
+ return this._fetch(endpoint, { retries: retries + 1, ...rest });
343
350
  }
344
351
 
345
352
  private async _get(
@@ -415,6 +422,29 @@ export class Getta {
415
422
  return res;
416
423
  }
417
424
 
425
+ private _logResponse(res: FetchResponse, endpoint: string, options: FetchOptions, context: PlainObject) {
426
+ const { data, errors, headers, status } = res;
427
+ const { redirects, retries } = options;
428
+ const { startTime, ...otherContext } = context;
429
+
430
+ const endTime = this._performance.now();
431
+ const duration = endTime - startTime;
432
+
433
+ this._log?.(RESPONSE_RECEIVED, {
434
+ context: {
435
+ body: data ? { data } : { errors: errors ?? [] },
436
+ headers,
437
+ method: options.method,
438
+ redirects,
439
+ retries,
440
+ status,
441
+ url: endpoint,
442
+ ...otherContext,
443
+ },
444
+ stats: { duration, endTime, startTime },
445
+ });
446
+ }
447
+
418
448
  private _rateLimit() {
419
449
  if (!this._rateLimitTimer) {
420
450
  this._rateLimitTimer = setTimeout(() => {
@@ -431,9 +461,9 @@ export class Getta {
431
461
  }
432
462
 
433
463
  private _releaseRateLimitedRequestQueue() {
434
- this._rateLimitedRequestQueue.forEach(async ([resolve, endpoint, options]) => {
464
+ this._rateLimitedRequestQueue.forEach(async ([resolve, endpoint, options, context]) => {
435
465
  // @ts-ignore
436
- resolve(await this._fetch(endpoint, options));
466
+ resolve(await this._fetch(endpoint, options, context));
437
467
  });
438
468
 
439
469
  this._rateLimitedRequestQueue = [];
package/src/types.ts CHANGED
@@ -60,7 +60,7 @@ export interface RequestOptions {
60
60
  queryParams?: PlainObject;
61
61
  }
62
62
 
63
- export type RequestQueue = [(value: FetchResponse) => void, string, FetchOptions][];
63
+ export type RequestQueue = [(value: FetchResponse) => void, string, FetchOptions, PlainObject][];
64
64
 
65
65
  export interface ResponseDataWithErrors<Resource = PlainObject> {
66
66
  data?: Resource;