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