@hcaptcha/loader
Version:
This is a JavaScript library to easily configure the loading of the hCaptcha JS client SDK with built-in error handling.
5 lines (4 loc) • 13 kB
JavaScript
var G=Object.defineProperty,K=Object.defineProperties;var V=Object.getOwnPropertyDescriptors;var w=Object.getOwnPropertySymbols;var P=Object.prototype.hasOwnProperty,D=Object.prototype.propertyIsEnumerable;var I=(t,e,r)=>e in t?G(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,d=(t,e)=>{for(var r in e||(e={}))P.call(e,r)&&I(t,r,e[r]);if(w)for(var r of w(e))D.call(e,r)&&I(t,r,e[r]);return t},R=(t,e)=>K(t,V(e));var M=(t,e)=>{var r={};for(var n in t)P.call(t,n)&&e.indexOf(n)<0&&(r[n]=t[n]);if(t!=null&&w)for(var n of w(t))e.indexOf(n)<0&&D.call(t,n)&&(r[n]=t[n]);return r};var l=(t,e,r)=>(I(t,typeof e!="symbol"?e+"":e,r),r);var x=(t,e,r)=>new Promise((n,s)=>{var a=c=>{try{o(r.next(c))}catch(i){s(i)}},u=c=>{try{o(r.throw(c))}catch(i){s(i)}},o=c=>c.done?n(c.value):Promise.resolve(c.value).then(a,u);o((r=r.apply(t,e)).next())});var L="hCaptcha-script",b="hCaptchaOnLoad",T="script-error";var g="@hCaptcha/loader";function U(t){return Object.entries(t).filter(([,e])=>e||e===!1).map(([e,r])=>`${encodeURIComponent(e)}=${encodeURIComponent(String(r))}`).join("&")}function O(t){let e=t&&t.ownerDocument||document,r=e.defaultView||e.parentWindow||window;return{document:e,window:r}}function S(t){return t||document.head}function B(t){var e;t.setTag("source",g),t.setTag("url",document.URL),t.setContext("os",{UA:navigator.userAgent}),t.setContext("browser",d({},z())),t.setContext("device",R(d({},J()),{screen_width_pixels:screen.width,screen_height_pixels:screen.height,language:navigator.language,orientation:((e=screen.orientation)==null?void 0:e.type)||"Unknown",processor_count:navigator.hardwareConcurrency,platform:navigator.platform}))}function z(){var n,s,a,u,o,c;let t=navigator.userAgent,e,r;return t.indexOf("Firefox")!==-1?(e="Firefox",r=(n=t.match(/Firefox\/([\d.]+)/))==null?void 0:n[1]):t.indexOf("Edg")!==-1?(e="Microsoft Edge",r=(s=t.match(/Edg\/([\d.]+)/))==null?void 0:s[1]):t.indexOf("Chrome")!==-1&&t.indexOf("Safari")!==-1?(e="Chrome",r=(a=t.match(/Chrome\/([\d.]+)/))==null?void 0:a[1]):t.indexOf("Safari")!==-1&&t.indexOf("Chrome")===-1?(e="Safari",r=(u=t.match(/Version\/([\d.]+)/))==null?void 0:u[1]):t.indexOf("Opera")!==-1||t.indexOf("OPR")!==-1?(e="Opera",r=(o=t.match(/(Opera|OPR)\/([\d.]+)/))==null?void 0:o[2]):t.indexOf("MSIE")!==-1||t.indexOf("Trident")!==-1?(e="Internet Explorer",r=(c=t.match(/(MSIE |rv:)([\d.]+)/))==null?void 0:c[2]):(e="Unknown",r="Unknown"),{name:e,version:r}}function F(t){return new Promise(e=>setTimeout(e,t))}function J(){let t=navigator.userAgent,e;t.indexOf("Win")!==-1?e="Windows":t.indexOf("Mac")!==-1?e="Mac":t.indexOf("Linux")!==-1?e="Linux":t.indexOf("Android")!==-1?e="Android":t.indexOf("like Mac")!==-1||t.indexOf("iPhone")!==-1||t.indexOf("iPad")!==-1?e="iOS":e="Unknown";let r;return/Mobile|iPhone|iPod|Android/i.test(t)?r="Mobile":/Tablet|iPad/i.test(t)?r="Tablet":r="Desktop",{model:e,family:e,device:r}}var Q=class k{constructor(e){l(this,"_parent");l(this,"breadcrumbs",[]);l(this,"context",{});l(this,"extra",{});l(this,"tags",{});l(this,"request");l(this,"user");this._parent=e}get parent(){return this._parent}child(){return new k(this)}setRequest(e){return this.request=e,this}removeRequest(){return this.request=void 0,this}addBreadcrumb(e){return typeof e.timestamp>"u"&&(e.timestamp=new Date().toISOString()),this.breadcrumbs.push(e),this}setExtra(e,r){return this.extra[e]=r,this}removeExtra(e){return delete this.extra[e],this}setContext(e,r){return typeof r.type>"u"&&(r.type=e),this.context[e]=r,this}removeContext(e){return delete this.context[e],this}setTags(e){return this.tags=d(d({},this.tags),e),this}setTag(e,r){return this.tags[e]=r,this}removeTag(e){return delete this.tags[e],this}setUser(e){return this.user=e,this}removeUser(){return this.user=void 0,this}toBody(){let e=[],r=this;for(;r;)e.push(r),r=r.parent;return e.reverse().reduce((n,s)=>{var a;return n.breadcrumbs=[...(a=n.breadcrumbs)!=null?a:[],...s.breadcrumbs],n.extra=d(d({},n.extra),s.extra),n.contexts=d(d({},n.contexts),s.context),n.tags=d(d({},n.tags),s.tags),s.user&&(n.user=s.user),s.request&&(n.request=s.request),n},{breadcrumbs:[],extra:{},contexts:{},tags:{},request:void 0,user:void 0})}clear(){this.breadcrumbs=[],this.context={},this.tags={},this.user=void 0}},Z=/^\s*at (?:(.*?) ?\()?((?:file|https?|blob|chrome-extension|address|native|eval|webpack|<anonymous>|[-a-z]+:|.*bundle|\/).*?)(?::(\d+))?(?::(\d+))?\)?\s*$/i,ee=/^\s*(.*?)(?:\((.*?)\))?(?:^|@)?((?:file|https?|blob|chrome|webpack|resource|moz-extension).*?:\/.*?|\[native code\]|[^@]*(?:bundle|\d+\.js))(?::(\d+))?(?::(\d+))?\s*$/i,te=/^\s*at (?:((?:\[object object\])?.+) )?\(?((?:file|ms-appx|https?|webpack|blob):.*?):(\d+)(?::(\d+))?\)?\s*$/i,re=/^(?:(\w+):)\/\/(?:(\w+)(?::(\w+))?@)([\w.-]+)(?::(\d+))?\/(.+)/,A="?",j="An unknown error occurred",ne="0.0.4";function se(t){for(let e=0;e<t.length;e++)t[e]=Math.floor(Math.random()*256);return t}function p(t){return(t+256).toString(16).substring(1)}function oe(){let t=se(new Array(16));return t[6]=t[6]&15|64,t[8]=t[8]&63|128,p(t[0])+p(t[1])+p(t[2])+p(t[3])+"-"+p(t[4])+p(t[5])+"-"+p(t[6])+p(t[7])+"-"+p(t[8])+p(t[9])+"-"+p(t[10])+p(t[11])+p(t[12])+p(t[13])+p(t[14])+p(t[15])}var ie=[[Z,"chrome"],[te,"winjs"],[ee,"gecko"]];function ae(t){var n,s,a,u;if(!t.stack)return null;let e=[],r=(a=(s=(n=t.stack).split)==null?void 0:s.call(n,`
`))!=null?a:[];for(let o=0;o<r.length;++o){let c=null,i=null,h=null;for(let[y,E]of ie)if(i=y.exec(r[o]),i){h=E;break}if(!(!i||!h)){if(h==="chrome")c={filename:(u=i[2])!=null&&u.startsWith("address at ")?i[2].substring(11):i[2],function:i[1]||A,lineno:i[3]?+i[3]:null,colno:i[4]?+i[4]:null};else if(h==="winjs")c={filename:i[2],function:i[1]||A,lineno:+i[3],colno:i[4]?+i[4]:null};else if(h==="gecko")o===0&&!i[5]&&t.columnNumber!==void 0&&e.length>0&&(e[0].column=t.columnNumber+1),c={filename:i[3],function:i[1]||A,lineno:i[4]?+i[4]:null,colno:i[5]?+i[5]:null};else continue;!c.function&&c.lineno&&(c.function=A),e.push(c)}}return e.length?e.reverse():null}function ce(t){let e=ae(t);return{type:t.name,value:t.message,stacktrace:{frames:e!=null?e:[]}}}function ue(t){let e=re.exec(t),r=e?e.slice(1):[];if(r.length!==6)throw new Error("Invalid DSN");let n=r[5].split("/"),s=n.slice(0,-1).join("/");return r[0]+"://"+r[3]+(r[4]?":"+r[4]:"")+(s?"/"+s:"")+"/api/"+n.pop()+"/envelope/?sentry_version=7&sentry_key="+r[1]+(r[2]?"&sentry_secret="+r[2]:"")}function le(t,e,r){var s,a;let n=d({event_id:oe().replaceAll("-",""),platform:"javascript",sdk:{name:"@hcaptcha/sentry",version:ne},environment:e,release:r,timestamp:Date.now()/1e3},t.scope.toBody());if(t.type==="exception"){n.message=(a=(s=t.error)==null?void 0:s.message)!=null?a:"Unknown error",n.fingerprint=[n.message];let u=[],o=t.error;for(let c=0;c<5&&o&&(u.push(ce(o)),!(!o.cause||!(o.cause instanceof Error)));c++)o=o.cause;n.exception={values:u.reverse()}}return t.type==="message"&&(n.message=t.message,n.level=t.level),n}function de(t){if(t instanceof Error)return t;if(typeof t=="string")return new Error(t);if(typeof t=="object"&&t!==null&&!Array.isArray(t)){let r=t,{message:n}=r,s=M(r,["message"]),a=new Error(typeof n=="string"?n:j);return Object.assign(a,s)}let e=new Error(j);return Object.assign(e,{cause:t})}function pe(t,e,r){return x(this,null,function*(){var n,s;try{if(typeof fetch<"u"&&typeof AbortSignal<"u"){let a;if(r){let c=new AbortController;a=c.signal,setTimeout(()=>c.abort(),r)}let u=yield fetch(t,R(d({},e),{signal:a})),o=yield u.text();return{status:u.status,body:o}}return yield new Promise((a,u)=>{var c,i;let o=new XMLHttpRequest;if(o.open((c=e==null?void 0:e.method)!=null?c:"GET",t),o.onload=()=>a({status:o.status,body:o.responseText}),o.onerror=()=>u(new Error("XHR Network Error")),e==null?void 0:e.headers)for(let[h,y]of Object.entries(e.headers))o.setRequestHeader(h,y);if(r){let h=setTimeout(()=>{o.abort(),u(new Error("Request timed out"))},r);o.onloadend=()=>{clearTimeout(h)}}o.send((i=e==null?void 0:e.body)==null?void 0:i.toString())})}catch(a){return{status:0,body:(s=(n=a==null?void 0:a.toString)==null?void 0:n.call(a))!=null?s:"Unknown error"}}})}var f,N=(f=class{constructor(e){l(this,"apiURL");l(this,"dsn");l(this,"environment");l(this,"release");l(this,"sampleRate");l(this,"debug");l(this,"_scope");l(this,"shouldBuffer",!1);l(this,"bufferlimit",20);l(this,"buffer",[]);var r,n,s,a,u;this.environment=e.environment,this.release=e.release,this.sampleRate=(r=e.sampleRate)!=null?r:1,this.debug=(n=e.debug)!=null?n:!1,this._scope=(s=e.scope)!=null?s:new Q,this.apiURL=ue(e.dsn),this.dsn=e.dsn,this.shouldBuffer=(a=e.buffer)!=null?a:!1,this.bufferlimit=(u=e.bufferLimit)!=null?u:20}static init(e){f._instance||(f._instance=new f(e))}static get instance(){if(!f._instance)throw new Error("Sentry has not been initialized");return f._instance}log(...e){this.debug&&console.log(...e)}get scope(){return this._scope}static get scope(){return f.instance.scope}withScope(e){let r=this._scope.child();e(r)}static withScope(e){f.instance.withScope(e)}captureException(e,r){this.captureEvent({type:"exception",level:"error",error:de(e),scope:r!=null?r:this._scope})}static captureException(e,r){f.instance.captureException(e,r)}captureMessage(e,r="info",n){this.captureEvent({type:"message",level:r,message:e,scope:n!=null?n:this._scope})}static captureMessage(e,r="info",n){f.instance.captureMessage(e,r,n)}captureEvent(e){if(Math.random()>=this.sampleRate){this.log("Dropped event due to sample rate");return}if(this.shouldBuffer){if(this.buffer.length>=this.bufferlimit)return;this.buffer.push(e)}else this.sendEvent(e)}sendEvent(e,r=5e3){return x(this,null,function*(){try{this.log("Sending sentry event",e);let n=le(e,this.environment,this.release),s={event_id:n.event_id,dsn:this.dsn},a={type:"event"},u=JSON.stringify(s)+`
`+JSON.stringify(a)+`
`+JSON.stringify(n),o=yield pe(this.apiURL,{method:"POST",headers:{"Content-Type":"application/x-sentry-envelope"},body:u},r);this.log("Sentry response",o.status),o.status!==200&&(console.log(o.body),console.error("Failed to send event to Sentry",o))}catch(n){console.error("Failed to send event",n)}})}flush(e=5e3){return x(this,null,function*(){try{this.log("Flushing sentry events",this.buffer.length);let r=this.buffer.splice(0,this.buffer.length).map(n=>this.sendEvent(n,e));yield Promise.all(r),this.log("Flushed all events")}catch(r){console.error("Failed to flush events",r)}})}static flush(e=5e3){return f.instance.flush(e)}static reset(){f._instance=void 0}},l(f,"_instance"),f);var fe="https://d233059272824702afc8c43834c4912d@sentry.hcaptcha.com/6",he="2.3.0",me="production";function H(t=!0){if(!t)return q();N.init({dsn:fe,release:he,environment:me});let e=N.scope;return B(e),q(e)}function q(t=null){return{addBreadcrumb:e=>{t&&t.addBreadcrumb(e)},captureRequest:e=>{t&&t.setRequest(e)},captureException:e=>{t&&N.captureException(e,t)}}}function W({scriptLocation:t,query:e,loadAsync:r=!0,crossOrigin:n="anonymous",apihost:s="https://js.hcaptcha.com",cleanup:a=!1,secureApi:u=!1,scriptSource:o=""}={},c){let i=S(t),h=O(i);return new Promise((y,E)=>{let m=h.document.createElement("script");m.id=L,o?m.src=`${o}?onload=${b}`:u?m.src=`${s}/1/secure-api.js?onload=${b}`:m.src=`${s}/1/api.js?onload=${b}`,m.crossOrigin=n,m.async=r;let _=(v,X)=>{try{!u&&a&&i.removeChild(m),X(v)}catch(Y){E(Y)}};m.onload=v=>_(v,y),m.onerror=v=>{c&&c(m.src),_(v,E)},m.src+=e!==""?`&${e}`:"",i.appendChild(m)})}var C=[];function be(t={cleanup:!1},e){try{e.addBreadcrumb({category:g,message:"hCaptcha loader params",data:t});let r=S(t.scriptLocation),n=O(r),s=C.find(({scope:u})=>u===n.window);if(s)return e.addBreadcrumb({category:g,message:"hCaptcha already loaded"}),s.promise;let a=new Promise((u,o)=>x(this,null,function*(){try{n.window[b]=()=>{e.addBreadcrumb({category:g,message:"hCaptcha script called onload function"}),u(n.window.hcaptcha)};let c=U({custom:t.custom,render:t.render,sentry:t.sentry,assethost:t.assethost,imghost:t.imghost,reportapi:t.reportapi,endpoint:t.endpoint,host:t.host,recaptchacompat:t.recaptchacompat,hl:t.hl,uj:t.uj});yield W(d({query:c},t),i=>{e.captureRequest({url:i,method:"GET"})}),e.addBreadcrumb({category:g,message:"hCaptcha loaded",data:s})}catch(c){e.addBreadcrumb({category:g,message:"hCaptcha failed to load"});let i=C.findIndex(h=>h.scope===n.window);i!==-1&&C.splice(i,1),o(new Error(T))}}));return C.push({promise:a,scope:n.window}),a}catch(r){return e.captureException(r),Promise.reject(new Error(T))}}function $(t,e,r=0){return x(this,null,function*(){var u,o;let n=(u=t.maxRetries)!=null?u:2,s=(o=t.retryDelay)!=null?o:1e3,a=r<n?"Retry loading hCaptcha Api":"Exceeded maximum retries";try{return yield be(t,e)}catch(c){return e.addBreadcrumb({category:g,message:a}),r>=n?(e.captureException(c),Promise.reject(c)):(e.addBreadcrumb({category:g,message:`Waiting ${s}ms before retry attempt ${r+1}`}),yield F(s),r+=1,$(t,e,r))}})}function ye(){return x(this,arguments,function*(t={}){let e=H(t.sentry);return yield $(t,e)})}export{ye as hCaptchaLoader};