@marsidev/react-turnstile
Version:
Cloudflare Turnstile integration for React.
2 lines • 6.21 kB
JavaScript
'use client';
import{forwardRef as e,useCallback as t,useEffect as n,useImperativeHandle as r,useMemo as i,useRef as a,useState as o}from"react";import{jsx as s}from"react/jsx-runtime";var c=e(({as:e=`div`,...t},n)=>s(e,{...t,ref:n}));const l=`https://challenges.cloudflare.com/turnstile/v0/api.js`,u=`cf-turnstile-script`,d=`cf-turnstile`,f=`onloadTurnstileCallback`,p=e=>!!document.getElementById(e),m=({render:e=`explicit`,onLoadCallbackName:t=f,scriptOptions:{nonce:n=``,defer:r=!0,async:i=!0,id:a=``,appendTo:o,onError:s,crossOrigin:c=``}={}})=>{let u=a||`cf-turnstile-script`;if(p(u))return;let d=document.createElement(`script`);d.id=u,d.src=`${l}?onload=${t}&render=${e}`,!document.querySelector(`script[src="${d.src}"]`)&&(d.defer=!!r,d.async=!!i,n&&(d.nonce=n),c&&(d.crossOrigin=c),s&&(d.onerror=s,delete window[t]),(o===`body`?document.body:document.getElementsByTagName(`head`)[0]).appendChild(d))},h={normal:{width:300,height:65},compact:{width:150,height:140},invisible:{width:0,height:0,overflow:`hidden`},flexible:{minWidth:300,width:`100%`,height:65},interactionOnly:{width:`fit-content`,height:`auto`,display:`flex`}};function g(e){if(e!==`invisible`&&e!==`interactionOnly`)return e}function _(e=u){let[t,r]=o(!1);return n(()=>{let t=()=>{p(e)&&r(!0)},n=new MutationObserver(t);return n.observe(document,{childList:!0,subtree:!0}),t(),()=>{n.disconnect()}},[e]),t}let v=`unloaded`,y;const b=new Promise((e,t)=>{y={resolve:e,reject:t},v===`ready`&&e(void 0)}),x=(e=f)=>(v===`unloaded`&&(v=`loading`,window[e]=()=>{y.resolve(),v=`ready`,delete window[e]}),b),S=e((e,l)=>{let{scriptOptions:u,options:d={},siteKey:f,onWidgetLoad:p,onSuccess:y,onExpire:b,onError:S,onBeforeInteractive:C,onAfterInteractive:w,onUnsupported:T,onTimeout:E,onLoadScript:D,id:O,style:k,as:A=`div`,injectScript:j=!0,rerenderOnCallbackChange:M=!1,...N}=e,P=d.size,F=t(()=>P===void 0?{}:d.execution===`execute`?h.invisible:d.appearance===`interaction-only`?h.interactionOnly:h[P],[d.execution,P,d.appearance]),[I,L]=o(F()),R=a(null),[z,B]=o(!1),V=a(void 0),H=a(!1),U=O||`cf-turnstile`,W=a({onSuccess:y,onError:S,onExpire:b,onBeforeInteractive:C,onAfterInteractive:w,onUnsupported:T,onTimeout:E});n(()=>{M||(W.current={onSuccess:y,onError:S,onExpire:b,onBeforeInteractive:C,onAfterInteractive:w,onUnsupported:T,onTimeout:E})});let G=u?.id||`cf-turnstile-script`,K=_(G),q=u?.onLoadCallbackName||`onloadTurnstileCallback`,J=d.appearance||`always`,Y=i(()=>({sitekey:f,action:d.action,cData:d.cData,theme:d.theme||`auto`,language:d.language||`auto`,tabindex:d.tabIndex,"response-field":d.responseField,"response-field-name":d.responseFieldName,size:g(P),retry:d.retry||`auto`,"retry-interval":d.retryInterval||8e3,"refresh-expired":d.refreshExpired||`auto`,"refresh-timeout":d.refreshTimeout||`auto`,execution:d.execution||`render`,appearance:d.appearance||`always`,"feedback-enabled":d.feedbackEnabled??!0,callback:e=>{H.current=!0,M?y?.(e):W.current.onSuccess?.(e)},"error-callback":M?S:(...e)=>W.current.onError?.(...e),"expired-callback":M?b:(...e)=>W.current.onExpire?.(...e),"before-interactive-callback":M?C:(...e)=>W.current.onBeforeInteractive?.(...e),"after-interactive-callback":M?w:(...e)=>W.current.onAfterInteractive?.(...e),"unsupported-callback":M?T:(...e)=>W.current.onUnsupported?.(...e),"timeout-callback":M?E:(...e)=>W.current.onTimeout?.(...e)}),[d.action,d.appearance,d.cData,d.execution,d.language,d.refreshExpired,d.responseField,d.responseFieldName,d.retry,d.retryInterval,d.tabIndex,d.theme,d.feedbackEnabled,d.refreshTimeout,f,P,M,M?y:null,M?S:null,M?b:null,M?C:null,M?w:null,M?T:null,M?E:null]),X=t(()=>typeof window<`u`&&!!window.turnstile,[]);return n(function(){j&&!z&&(x(q),m({onLoadCallbackName:q,scriptOptions:{...u,id:G}}))},[j,z,u,G,q]),n(function(){v!==`ready`&&x(q).then(()=>B(!0)).catch(console.error)},[q]),n(function(){if(!R.current||!z)return;let e=!1;return(async()=>{e||!R.current||(V.current=window.turnstile.render(R.current,Y),V.current&&p?.(V.current))})(),()=>{e=!0,V.current&&(window.turnstile.remove(V.current),H.current=!1)}},[U,z,Y]),r(l,()=>{let{turnstile:e}=window;return{getResponse(){if(!e?.getResponse||!V.current||!X()){console.warn(`Turnstile has not been loaded`);return}return e.getResponse(V.current)},async getResponsePromise(e=3e4,t=100){return new Promise((n,r)=>{let i,a=async()=>{if(H.current&&window.turnstile&&V.current)try{let e=window.turnstile.getResponse(V.current);return i&&clearTimeout(i),e?n(e):r(Error(`No response received`))}catch(e){return i&&clearTimeout(i),console.warn(`Failed to get response`,e),r(Error(`Failed to get response`))}i||=setTimeout(()=>{i&&clearTimeout(i),r(Error(`Timeout`))},e),await new Promise(e=>setTimeout(e,t)),await a()};a()})},reset(){if(!e?.reset||!V.current||!X()){console.warn(`Turnstile has not been loaded`);return}d.execution===`execute`&&L(h.invisible);try{H.current=!1,e.reset(V.current)}catch(e){console.warn(`Failed to reset Turnstile widget ${V.current}`,e)}},remove(){if(!e?.remove||!V.current||!X()){console.warn(`Turnstile has not been loaded`);return}L(h.invisible),H.current=!1,e.remove(V.current),V.current=null},render(){if(!e?.render||!R.current||!X()||V.current){console.warn(`Turnstile has not been loaded or container not found`);return}let t=e.render(R.current,Y);return V.current=t,V.current&&p?.(V.current),d.execution!==`execute`&&L(P?h[P]:{}),t},execute(){if(d.execution!==`execute`){console.warn(`Execution mode is not set to "execute"`);return}if(!e?.execute||!R.current||!V.current||!X()){console.warn(`Turnstile has not been loaded or container not found`);return}e.execute(R.current,Y),L(P?h[P]:{})},isExpired(){return!e?.isExpired||!V.current||!X()?(console.warn(`Turnstile has not been loaded`),!1):e.isExpired(V.current)}}},[V,d.execution,P,Y,R,X,z,p]),n(()=>{if(z||!K)return;if(window.turnstile){B(!0);return}let e=setInterval(()=>{window.turnstile&&(B(!0),clearInterval(e))},50);return()=>{clearInterval(e)}},[z,K]),n(()=>{L(F())},[d.execution,P,J]),n(()=>{!K||typeof D!=`function`||D()},[K]),s(c,{ref:R,as:A,id:U,style:{...I,...k},...N})});S.displayName=`Turnstile`;export{d as DEFAULT_CONTAINER_ID,f as DEFAULT_ONLOAD_NAME,u as DEFAULT_SCRIPT_ID,l as SCRIPT_URL,S as Turnstile};