@shopify/graphql-client
Version:
Shopify GraphQL Client - A lightweight generic GraphQL JS client to interact with Shopify GraphQL APIs
4 lines (3 loc) • 7.33 kB
JavaScript
/*! shopify/graphql-client@2.0.1 -- Copyright (c) 2023-present, Shopify Inc. -- license (MIT): https://github.com/Shopify/shopify-app-js/blob/main/LICENSE.md */
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).ShopifyGraphQLClient={})}(this,function(e){"use strict";const t="GraphQL Client",r="An error occurred while fetching from the API. Review 'graphQLErrors' for details.",n="Response returned unexpected Content-Type:",s="An unknown error has occurred. The API did not return a data object or any errors in its response.",o="application/json",a="multipart/mixed",i="X-SDK-Variant",c="X-SDK-Version",u="shopify-graphql-client",d="2.0.1",f=[429,503],l=/@(defer)\b/i,h=/boundary="?([^=";]+)"?/i,y="\r\n\r\n";function p(e,r=t){return e.startsWith(`${r}`)?e:`${r}: ${e}`}function m(e){return e instanceof Error?e.message:JSON.stringify(e)}function w(e){return e instanceof Error&&e.cause?e.cause:void 0}function g(e){return e.flatMap(({errors:e})=>e??[])}function b({client:e,retries:t}){if(void 0!==t&&("number"!=typeof t||t<0||t>3))throw new Error(`${e}: The provided "retries" value (${t}) is invalid - it cannot be less than 0 or greater than 3`)}function x(e,t){return t&&("object"!=typeof t||Array.isArray(t)||"object"==typeof t&&Object.keys(t).length>0)?{[e]:t}:{}}function E(e,t){if(0===e.length)return t;const r=e.pop(),n={[r]:t};return 0===e.length?n:E(e,n)}function S(e,t){return Object.keys(t||{}).reduce((r,n)=>("object"==typeof t[n]||Array.isArray(t[n]))&&e[n]?(r[n]=S(e[n],t[n]),r):(r[n]=t[n],r),Array.isArray(e)?[...e]:{...e})}function k([e,...t]){return t.reduce(S,{...e})}const A=new Set(["authorization","cookie","set-cookie","shopify-storefront-private-token","x-shopify-access-token","x-shopify-storefront-access-token"]);function T({clientLogger:e,customFetchApi:r=fetch,client:n=t,defaultRetryWaitTime:s=1e3,retriableCodes:o=f}){const a=async(t,i,c)=>{const u=i+1,d=c+1,f=function(e){const[t,r]=e;if(!r?.headers)return e;return[t,{...r,headers:$(r.headers)}]}(t);let l;try{if(l=await r(...t),e({type:"HTTP-Response",content:{requestParams:f,response:l}}),!l.ok&&o.includes(l.status)&&u<=d)throw new Error;const n=l?.headers.get("X-Shopify-API-Deprecated-Reason")||"";return n&&e({type:"HTTP-Response-GraphQL-Deprecation-Notice",content:{requestParams:f,deprecationNotice:n}}),l}catch(r){if(u<=d){const r=l?.headers.get("Retry-After");return await async function(e){return new Promise(t=>setTimeout(t,e))}(r?parseInt(r,10):s),e({type:"HTTP-Retry",content:{requestParams:f,lastResponse:l,retryAttempt:i,maxRetries:c}}),a(t,u,c)}throw new Error(p(`${c>0?`Attempted maximum number of ${c} network retries. Last message - `:""}${m(r)}`,n))}};return a}function $(e){const t=(e,t)=>A.has(e.toLowerCase())?"****":t;if(Array.isArray(e))return e.map(([e,r])=>[e,t(e,r)]);if("function"==typeof e.forEach){const r={};return e.forEach((e,n)=>{r[n]=t(n,e)}),"undefined"==typeof Headers?r:new Headers(r)}return Object.fromEntries(Object.entries(e).map(([e,r])=>[e,t(e,r)]))}async function j(e){const{errors:t,data:n,extensions:o}=await e.json();return{...x("data",n),...x("extensions",o),headers:e.headers,...t||!n?{errors:{networkStatusCode:e.status,message:p(t?r:s),...x("graphQLErrors",t),response:e}}:{}}}function N(e){return e.map(e=>{try{return JSON.parse(e)}catch(e){throw new Error(`Error in parsing multipart response - ${m(e)}`)}}).map(e=>{const{data:t,incremental:r,hasNext:n,extensions:s,errors:o}=e;if(!r)return{data:t||{},...x("errors",o),...x("extensions",s),hasNext:n};const a=r.map(({data:e,path:t,errors:r})=>({data:e&&t?E(t,e):{},...x("errors",r)}));return{data:1===a.length?a[0].data:k(a.map(({data:e})=>e)),...x("errors",g(a)),hasNext:n}})}function R(e,t){if(e.length>0)throw new Error(r,{cause:{graphQLErrors:e}});if(0===Object.keys(t).length)throw new Error(s)}e.createGraphQLClient=function({headers:e,url:r,customFetchApi:s=fetch,retries:f=0,logger:E}){b({client:t,retries:f});const S={headers:e,url:r,retries:f},A=function(e){return t=>{e&&e(t)}}(E),$=function(e,{url:r,headers:n,retries:s}){return async(o,a={})=>{const{variables:f,headers:l,url:h,retries:y,keepalive:p,signal:m}=a,w=JSON.stringify({query:o,variables:f});b({client:t,retries:y});const g=Object.entries({...n,...l}).reduce((e,[t,r])=>(e[t]=Array.isArray(r)?r.join(", "):r.toString(),e),{});g[i]||g[c]||(g[i]=u,g[c]=d);return e([h??r,{method:"POST",headers:g,body:w,signal:m,keepalive:p}],1,y??s)}}(T({customFetchApi:s,clientLogger:A,defaultRetryWaitTime:1e3}),S),C=function(e){return async(...t)=>{if(l.test(t[0]))throw new Error(p("This operation will result in a streamable response - use requestStream() instead."));let r=null;try{r=await e(...t);const{status:s,statusText:a}=r,i=r.headers.get("content-type")||"";return r.ok?i.includes(o)?await j(r):{errors:{networkStatusCode:s,message:p(`${n} ${i}`),response:r}}:{errors:{networkStatusCode:s,message:p(a),response:r}}}catch(e){return{errors:{message:m(e),...null==r?{}:{networkStatusCode:r.status,response:r}}}}}}($),L=function(e){return async(...t)=>{if(!l.test(t[0]))throw new Error(p("This operation does not result in a streamable response - use request() instead."));try{const r=await e(...t),{statusText:s}=r;if(!r.ok)throw new Error(s,{cause:r});const i=r.headers.get("content-type")||"";switch(!0){case i.includes(o):return function(e){return{async*[Symbol.asyncIterator](){try{const t=await j(e);yield{...t,hasNext:!1}}catch(t){yield{errors:{message:p(m(t)),networkStatusCode:e.status,response:e},hasNext:!1}}}}}(r);case i.includes(a):return function(e,t){const r=(t??"").match(h),n=`--${r?r[1]:"-"}`;if(!e.body?.getReader&&!e.body?.[Symbol.asyncIterator])throw new Error("API multipart response did not return an iterable body",{cause:e});const s=async function*(e){const t=new TextDecoder;if(e.body[Symbol.asyncIterator])for await(const r of e.body)yield t.decode(r);else{const r=e.body.getReader();let n;try{for(;!(n=await r.read()).done;)yield t.decode(n.value)}finally{r.cancel()}}}(e);let o,a={};return{async*[Symbol.asyncIterator](){try{let e=!0;for await(const t of function(e,t){return{async*[Symbol.asyncIterator](){try{let r="";for await(const n of e)if(r+=n,r.indexOf(t)>-1){const e=r.lastIndexOf(t),n=r.slice(0,e).split(t).filter(e=>e.trim().length>0).map(e=>e.slice(e.indexOf(y)+4).trim());n.length>0&&(yield n),r=r.slice(e+t.length),"--"===r.trim()&&(r="")}}catch(e){throw new Error(`Error occured while processing stream payload - ${m(e)}`)}}}}(s,n)){const r=N(t);o=r.find(e=>e.extensions)?.extensions??o;const n=g(r);a=k([a,...r.map(({data:e})=>e)]),e=r.slice(-1)[0].hasNext,R(n,a),yield{...x("data",a),...x("extensions",o),hasNext:e}}if(e)throw new Error("Response stream terminated unexpectedly")}catch(t){const r=w(t);yield{...x("data",a),...x("extensions",o),errors:{message:p(m(t)),networkStatusCode:e.status,...x("graphQLErrors",r?.graphQLErrors),response:e},hasNext:!1}}}}}(r,i);default:throw new Error(`${n} ${i}`,{cause:r})}}catch(e){return{async*[Symbol.asyncIterator](){const t=w(e);yield{errors:{message:p(m(e)),...x("networkStatusCode",t?.status),...x("response",t)},hasNext:!1}}}}}}($);return{config:S,fetch:$,request:C,requestStream:L}}});
//# sourceMappingURL=graphql-client.min.js.map