UNPKG

@arcgis/core

Version:

ArcGIS Maps SDK for JavaScript: A complete 2D and 3D mapping and data visualization API

6 lines (5 loc) • 11.5 kB
/* All material copyright ESRI, All Rights Reserved, unless otherwise specified. See https://js.arcgis.com/4.32/esri/copyright.txt for details. */ import e from"./config.js";import{id as r}from"./kernel.js";import t from"./core/Error.js";import has from"./core/has.js";import{clone as s}from"./core/lang.js";import{getOrCreateMapValue as o}from"./core/MapUtils.js";import{onAbort as n,isAbortError as a,createAbortError as i,isAborted as l}from"./core/promiseUtils.js";import{queryToObject as u,isDataProtocol as c,isBlobProtocol as d,normalize as p,getInterceptor as m,isTrustedServer as h,getOrigin as f,toHTTPS as y,objectToQuery as w,getProxyRule as g,getProxyUrl as q,addQueryParameters as b,hasSameOrigin as S,getAppUrl as T,addProxyRule as k}from"./core/urlUtils.js";import{isHostedAgolService as O}from"./layers/support/arcgisLayerUrl.js";import{isSecureProxyService as v}from"./portal/support/urlUtils.js";import{isApiKeyApplicable as C}from"./support/apiKeyUtils.js";import{registerNoCorsDomains as x,isNoCorsRequestRequired as L,sendNoCorsRequest as E,createTimeoutError as U,loadImageAsync as j}from"./support/requestUtils.js";async function P(e,r){e instanceof URL&&(e=e.toString()),r?.query instanceof URLSearchParams&&(r.query=u(r.query.toString().replaceAll("+"," ")));const t=c(e),s=d(e);s||t||(e=p(e));const o={url:e,requestOptions:{...r}},a=e=>({data:e,getAllHeaders:I,getHeader:I,httpStatus:200,requestOptions:o.requestOptions,url:o.url}),i=m(e,H.internalInterceptors);if(i){const e=await K(i,o);if(null!=e)return a(e)}let l=m(e);if(l){const e=await K(l,o);if(null!=e)return a(e);l.after||l.error||(l=null)}if(e=o.url,"image"===(r=o.requestOptions).responseType&&(has("host-webworker")||has("host-node")))throw $("request:invalid-parameters",new Error("responseType 'image' is not supported in Web Workers or Node environment"),o);if("head"===r.method){if(r.body)throw $("request:invalid-parameters",new Error("body parameter cannot be set when method is 'head'"),o);if(t||s)throw $("request:invalid-parameters",new Error("data and blob URLs are not supported for method 'head'"),o)}if(await z(),A)return A.execute(e,r);const h=new AbortController,f=n(r,(()=>h.abort())),y={controller:h,credential:void 0,credentialToken:void 0,fetchOptions:void 0,hasToken:!1,interceptor:l,params:o,redoRequest:!1,useIdentity:H.useIdentity,useProxy:!1,useSSL:!1,withCredentials:!1},w=r.useRequestQueue?Z(y):ee(y),g=await w.finally((()=>f?.remove()));return l?.after?.(g),g}let A;const H=e.request,R="FormData"in globalThis,_=new Set([499,498,403,401]),D=new Set(["COM_0056","COM_0057","SB_0008"]),F=[/\/arcgis\/tokens/i,/\/sharing(\/rest)?\/generatetoken/i,/\/rest\/info/i],I=()=>null,M=Symbol();function N(e){const r=f(e);r&&!P._corsServers.includes(r)&&P._corsServers.push(r)}function B(e){const r=f(e);return!r||r.endsWith(".arcgis.com")||P._corsServers.includes(r)||h(r)}function $(e,r,o,n){let l="Error";const u={url:o.url,requestOptions:o.requestOptions,getAllHeaders:I,getHeader:I,ssl:!1};if(r instanceof t)return r.details?(r.details=s(r.details),r.details.url=o.url,r.details.requestOptions=o.requestOptions):r.details=u,r;if(r){const e=n&&(()=>Array.from(n.headers)),t=n&&(e=>n.headers.get(e)),s=n?.status,o=r.message;o&&(l=o),e&&t&&(u.getAllHeaders=e,u.getHeader=t),u.httpStatus=(null!=r.httpCode?r.httpCode:r.code)||s||0,u.subCode=r.subcode,u.messageCode=r.messageCode,"string"==typeof r.details?u.messages=[r.details]:u.messages=r.details,u.raw=M in r?r[M]:r}return a(r)?i():new t(e,l,u)}async function z(){has("host-webworker")&&!A&&(A=await import("./core/workers/request.js"))}async function Q(){r||await import("./identity/IdentityManager.js")}async function W(t){const s=t.params.url,o=t.params.requestOptions,n=t.controller.signal,a=o.body;let i=null,u=null;if(R&&"HTMLFormElement"in globalThis&&(a instanceof FormData?i=a:a instanceof HTMLFormElement&&(i=new FormData(a))),"string"==typeof a&&(u=a),t.fetchOptions={cache:o.cacheBust?"no-cache":"default",credentials:"same-origin",headers:o.headers||{},method:"head"===o.method?"HEAD":"GET",mode:"cors",priority:H.priority,redirect:"follow",signal:n},(i||u)&&(t.fetchOptions.body=i||u),"anonymous"===o.authMode&&(t.useIdentity=!1),t.hasToken=!!(/token=/i.test(s)||o.query?.token||i?.get("token")),!t.hasToken&&C(s)&&(o.query||(o.query={}),o.query.token=e.apiKey,t.hasToken=!0),t.useIdentity&&!t.hasToken&&!t.credentialToken&&!G(s)&&!l(n)){let e;"immediate"===o.authMode?(await Q(),e=await r.getCredential(s,{signal:n}),t.credential=e):"no-prompt"===o.authMode?(await Q(),e=await r.getCredential(s,{prompt:!1,signal:n}).catch((()=>{})),t.credential=e):r&&(e=r.findCredential(s)),e&&(t.credentialToken=e.token,t.useSSL=!!e.ssl)}}function G(e){return F.some((r=>r.test(e)))}async function J(e){let t=e.params.url;const s=e.params.requestOptions,o=e.fetchOptions??{},n=d(t)||c(t),a=s.responseType||"json",l=n?0:null!=s.timeout?s.timeout:H.timeout;let u=!1;if(!n){e.useSSL&&(t=y(t));let n={...s.query};e.credentialToken&&(n.token=e.credentialToken);let a=w(n);has("esri-url-encodes-apostrophe")&&(a=a.replaceAll("'","%27"));const i=t.length+1+a.length;let l;u="delete"===s.method||"post"===s.method||"put"===s.method||!!s.body||i>H.maxUrlLength;const c=s.useProxy||!!g(t);if(c){const e=q(t);l=e.path,!u&&l.length+1+i>H.maxUrlLength&&(u=!0),e.query&&(n={...e.query,...n})}if("HEAD"===o.method&&(u||c)){if(u){if(i>H.maxUrlLength)throw $("request:invalid-parameters",new Error("URL exceeds maximum length"),e.params);throw $("request:invalid-parameters",new Error("cannot use POST request when method is 'head'"),e.params)}if(c)throw $("request:invalid-parameters",new Error("cannot use proxy when method is 'head'"),e.params)}if(u?(o.method="delete"===s.method?"DELETE":"put"===s.method?"PUT":"POST",s.body?t=b(t,n):(o.body=w(n),o.headers||(o.headers={}),o.headers["Content-Type"]="application/x-www-form-urlencoded")):t=b(t,n),c&&(e.useProxy=!0,t=`${l}?${t}`),n.token&&R&&o.body instanceof FormData&&!v(t)&&o.body.set("token",n.token),s.hasOwnProperty("withCredentials"))e.withCredentials=s.withCredentials;else if(!S(t,T()))if(h(t))e.withCredentials=!0;else if(r){const s=r.findServerInfo(t);s?.webTierAuth&&(e.withCredentials=!0)}e.withCredentials&&(o.credentials="include",L(t)&&await E(u?b(t,n):t))}let p,m,O=0,C=!1;l>0&&(O=setTimeout((()=>{C=!0,e.controller.abort()}),l));try{if("native-request-init"===s.responseType)m=o,m.url=t,s.signal?m.signal=s.signal:delete m.signal;else if("image"!==s.responseType||"default"!==o.cache||"GET"!==o.method||u||X(s.headers)||!n&&!e.useProxy&&H.proxyUrl&&!B(t)){if(P._beforeFetch&&await P._beforeFetch(t,o),p=await fetch(t,o),P._afterFetch&&await P._afterFetch(p),e.useProxy||N(t),"native"===s.responseType)m=p;else if("HEAD"!==o.method)if(p.ok){switch(a){case"array-buffer":m=await p.arrayBuffer();break;case"blob":case"image":m=await p.blob();break;default:m=await p.text()}if(O&&(clearTimeout(O),O=0),"json"===a||"xml"===a||"document"===a)if(m)switch(a){case"json":m=JSON.parse(m);break;case"xml":m=V(m,"application/xml");break;case"document":m=V(m,"text/html")}else m=null;if(m){if("array-buffer"===a||"blob"===a){const e=p.headers.get("Content-Type");if(e&&/application\/json|text\/plain/i.test(e)&&m["blob"===a?"size":"byteLength"]<=750)try{const e=await new Response(m).json();e.error&&(m=e)}catch{}}"image"===a&&m instanceof Blob&&(m=await te(URL.createObjectURL(m),e,!0))}}else{m=await p.text();try{m=JSON.parse(m)}catch{}}}else m=await te(t,e)}catch(x){if("AbortError"===x.name){if(C)throw U();throw i("Request canceled")}if(!(!p&&x instanceof TypeError&&H.proxyUrl)||s.body||"delete"===s.method||"head"===s.method||"post"===s.method||"put"===s.method||e.useProxy||B(t))throw x;e.redoRequest=!0,k({proxyUrl:H.proxyUrl,urlPrefix:f(t)??""})}finally{O&&clearTimeout(O)}return[p,m]}async function K(e,r){if(null!=e.responseData)return e.responseData;if(e.headers&&(r.requestOptions.headers={...r.requestOptions.headers,...e.headers}),e.query&&(r.requestOptions.query={...r.requestOptions.query,...e.query}),e.before){let o,n;try{n=await e.before(r)}catch(s){o=$("request:interceptor",s,r)}if((n instanceof Error||n instanceof t)&&(o=$("request:interceptor",n,r)),o)throw e.error&&e.error(o),o;return n}}function X(e){if(e)for(const r of Object.getOwnPropertyNames(e))if(e[r])return!0;return!1}function V(e,r){let t;try{t=(new DOMParser).parseFromString(e,r)}catch{}if(!t||t.getElementsByTagName("parsererror").length)throw new SyntaxError("XML Parse error");return t}P._corsServers=["https://server.arcgisonline.com","https://services.arcgisonline.com"],P._beforeFetch=void 0,P._afterFetch=void 0;const Y=new Map;async function Z(e){const r=se(e.params.url);if(!r)return ee(e);const{QueueProcessor:t}=await import("./core/QueueProcessor.js"),s=o(Y,r.origin,(()=>{const e=r.isHosted?has("request-queue-concurrency-hosted"):has("request-queue-concurrency-non-hosted");return new t({concurrency:e,process:e=>{if(l(e.params.requestOptions))throw $("",i("Request canceled"),e.params);return ee(e)}})}));return s.push(e)}async function ee(e){let t,s;await W(e);try{do{[t,s]=await J(e)}while(!await re(e,t,s))}catch(a){const r=$("request:server",a,e.params,t);throw r.details.ssl=e.useSSL,e.interceptor?.error&&e.interceptor.error(r),r}const o=e.params.url;if(s&&/\/sharing\/rest\/(accounts|portals)\/self/i.test(o)){if(!e.hasToken&&!e.credentialToken&&s.user?.username&&!h(o)){const e=f(o,!0);e&&H.trustedServers.push(e)}Array.isArray(s.authorizedCrossOriginNoCorsDomains)&&x(s.authorizedCrossOriginNoCorsDomains)}const n=e.credential;if(n&&r){const e=r.findServerInfo(n.server);let t=e?.owningSystemUrl;if(t){t=t.replace(/\/?$/,"/sharing");const e=r.findCredential(t,n.userId);e&&-1===r._getIdenticalSvcIdx(t,e)&&e.resources.unshift(t)}}return{data:s,getAllHeaders:t?()=>Array.from(t.headers):I,getHeader:t?e=>t.headers.get(e):I,httpStatus:t?.status??200,requestOptions:e.params.requestOptions,ssl:e.useSSL,url:e.params.url}}async function re(e,t,s){if(e.redoRequest)return e.redoRequest=!1,!1;const o=e.params.requestOptions;if(!t||"native"===o.responseType||"native-request-init"===o.responseType)return!0;let n,a;if(s&&(s.error&&"object"==typeof s.error?n=s.error:"error"===s.status&&Array.isArray(s.messages)&&(n={...s},n[M]=s,n.details=s.messages)),!n&&!t.ok)throw n=new Error(`Unable to load ${t.url} status: ${t.status}`),n[M]=s,n;let i,l=null;n&&(a=Number(n.code),l=n.hasOwnProperty("subcode")?Number(n.subcode):null,i=n.messageCode,i=i?.toUpperCase());const u=o.authMode;if(403===a&&(4===l||n.message?.toLowerCase().includes("ssl")&&!n.message.toLowerCase().includes("permission"))){if(!e.useSSL)return e.useSSL=!0,!1}else if(!e.hasToken&&e.useIdentity&&("no-prompt"!==u||498===a)&&void 0!==a&&_.has(a)&&!G(e.params.url)&&(403!==a||(!i||!D.has(i))&&(null==l||2===l&&e.credentialToken))){await Q();try{const t=await r.getCredential(e.params.url,{error:$("request:server",n,e.params),prompt:"no-prompt"!==u,signal:e.controller.signal,token:e.credentialToken});return e.credential=t,e.credentialToken=t.token,e.useSSL=e.useSSL||t.ssl,!1}catch(c){if("no-prompt"===u)return e.credential=void 0,e.credentialToken=void 0,!1;n=c}}if(n)throw n;return!0}function te(e,r,t=!1){const s=r.controller.signal,o=new Image;return r.withCredentials?o.crossOrigin="use-credentials":o.crossOrigin="anonymous",o.alt="",o.fetchPriority=H.priority,o.src=e,j(o,e,t,s)}function se(e){let r,t;return"string"==typeof e?(r=f(e,!0),t=O(e)):(r=e.origin,t=O(e.toString())),null==r?null:{origin:r,isHosted:t}}export{P as default};