jasonkuhrt / graphql-request

Minimal GraphQL client

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Support passing relative path for URL

frederikhors opened this issue · comments

I just found out another quirk this time with 7.0.0-next.33.

But this time only when I build my bundle for production:

TypeError: Failed to construct 'URL': Invalid URL
    at index.pxZNWVDZ.js:51:1995
    at ce (index.pxZNWVDZ.js:51:823)
    at Zi.request (index.pxZNWVDZ.js:51:4018)
    at utils.CoYeZH7t.js:1:932
    at Object.persister (helpers.Bc0QlLkm.js:1:25762)

An extract of index.pxZNWVDZ.js:51:1995 (let l=new URL(n.url) is the stack trace indication):

}`)}function S(e,n,i=""){return n!=null&&n!==""?e+n+i:""}function z(e){return S("  ",e.replace(/\n/g,`
  `))}function je(e){var n;return(n=e==null?void 0:e.some(i=>i.includes(`
`)))!==null&&n!==void 0?n:!1}const $i=e=>{var t;let n;const i=e.definitions.filter(Je);return i.length===1&&(n=(t=i[0].name)==null?void 0:t.value),n},Qi=e=>{let n=!1;const i=e.definitions.filter(Je);return i.length===1&&(n=i[0].operation===fe.MUTATION),n},ue=(e,n)=>{const i=typeof e=="string"?e:wi(e);let t=!1,a;if(n)return{expression:i,isMutation:t,operationName:a};const d=En(()=>typeof e=="string"?hi(e):e);return d instanceof Error?{expression:i,isMutation:t,operationName:a}:(a=$i(d),t=Qi(d),{expression:i,operationName:a,isMutation:t})},Oe=JSON,ce=async e=>{const n={...e,method:e.request._tag==="Single"?e.request.document.isMutation?"POST":Re(e.method??"post"):e.request.hasMutations?"POST":Re(e.method??"post"),fetchOptions:{...e.fetchOptions,errorPolicy:e.fetchOptions.errorPolicy??"none"}},t=await Ji(n.method)(n);if(!t.ok)return new M({status:t.status,headers:t.headers},{query:e.request._tag==="Single"?e.request.document.expression:e.request.query,variables:e.request.variables});const a=await Wi(t,e.fetchOptions.jsonSerializer??Oe);if(a instanceof Error)throw a;const d={status:t.status,headers:t.headers};if(_n(a)&&n.fetchOptions.errorPolicy==="none"){const l=a._tag==="Batch"?{...a.executionResults,...d}:{...a.executionResult,...d};return new M(l,{query:e.request._tag==="Single"?e.request.document.expression:e.request.query,variables:e.request.variables})}if(a._tag==="Single")return{...d,...Ge(n)(a.executionResult)};if(a._tag==="Batch")return{...d,data:a.executionResults.map(Ge(n))}},Ge=e=>n=>({extensions:n.extensions,data:n.data,errors:e.fetchOptions.errorPolicy==="all"?n.errors:void 0}),Wi=async(e,n)=>{const i=e.headers.get(ve),t=await e.text();return i&&On(i)?Me(n.parse(t)):Me(t)},Ji=e=>async n=>{const i=new Headers(n.headers);let t=null,a;i.has(Ye)||i.set(Ye,[We,pe].join(", ")),e==="POST"?(a=(n.fetchOptions.jsonSerializer??Oe).stringify(Xi(n)),typeof a=="string"&&!i.has(ve)&&i.set(ve,pe)):t=zi(n);const d={method:e,headers:i,body:a,...n.fetchOptions};let l=new URL(n.url),k=d;if(n.middleware){const r=await Promise.resolve(n.middleware({...d,url:n.url,operationName:n.request._tag==="Single"?n.request.document.operationName:void 0,variables:n.request.variables})),{url:u,...c}=r;l=new URL(u),k=c}return t&&t.forEach((r,u)=>{l.searchParams.append(u,r)}),await(n.fetch??fetch)(l,k)},Xi=e=>{if(e.request._tag==="Single"){const{variables:n,document:{expression:i,operationName:t}}=e.request;return{query:i,variables:n,operationName:t}}else{if(e.request._tag==="Batch")return $e(e.request.query,e.request.variables??[]).map(([n,i])=>({query:n,variables:i}));throw Qe(e.request)}},zi=e=>{var t;const n=e.fetchOptions.jsonSerializer??Oe,i=new URLSearchParams;if(e.request._tag==="Single")return i.append("query",xe(e.request.document.expression)),e.request.variables&&i.append("variables",n.stringify(e.request.variables)),e.request.document.operationName&&i.append("operationName",e.request.document.operationName),i;if(e.request._tag==="Batch"){const a=((t=e.request.variables)==null?void 0:t.map(k=>n.stringify(k)))??[],d=e.request.query.map(xe),l=$e(d,a).map(([k,s])=>({query:k,variables:s}));i.append("query",n.stringify(l))}else throw Qe(e.request);return i};class Zi{constructor(n,i={}){this.url=n,this.requestConfig=i,this.rawRequest=async(...t)=>{const[a,d,l]=t,k=gn(a,d,l),{headers:s,fetch:r=globalThis.fetch,method:u="POST",requestMiddleware:c,responseMiddleware:N,excludeOperationName:A,...F}=this.requestConfig,{url:y}=this;k.signal!==void 0&&(F.signal=k.signal);const K=ue(k.query,A),f=await ce({url:y,request:{_tag:"Single",document:K,variables:k.variables},headers:{...Y(oe(s)),...Y(k.requestHeaders)},fetch:r,method:u,fetchOptions:F,middleware:c});if(N&&N(f),f instanceof Error)throw f;return f}}async request(n,...i){const[t,a]=i,d=ea(n,t,a),{headers:l,fetch:k=globalThis.fetch,method:s="POST",requestMiddleware:r,

If it only happens after you bundle then I think it's an issue in your project. What is the value of n.url? And, what is supplying the global URL?

Is the same URL I use with version v7.0.0-next.12.

graphql-request version is the only thing I change.

It might be a breaking change in graphql-request rather than a bug.

Does your target runtime (browser?) have a global URL class? What is the URL value? Have you manually run that value through the global URL class constructor?

browser?

Yes

Does your target runtime have a global URL class?

Nope, all default.

I'm using it like this with both versions:

export const client = new GraphQLClient("/graphql", {
	fetch: createPersistedQueryFetch(fetch) // from from https://github.com/jasonkuhrt/graphql-request/issues/269
});

Interesting, /graphql is not a valid URL. You are relying on the browser supplying the current host URL prefix. This approach is only valid in browsers. I'm not sure this feature should be supported, but I'll consider it. Let me know what you think for your use-case.

It works if I use window.location.origin since I'm using it in browser only.

I think being explicit here is less confusing and makes for a better API, because we can validate that a valid URL is passed catching more user errors.

Upon release, I'll try to remember to mention this breaking change!