hapi-recaptcha-html 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ (()=>{function j(e,t){return function(){return e.apply(t,arguments)}}var{toString:ut}=Object.prototype,{getPrototypeOf:fe}=Object,G=(e=>t=>{let r=ut.call(t);return e[r]||(e[r]=r.slice(8,-1).toLowerCase())})(Object.create(null)),R=e=>(e=e.toLowerCase(),t=>G(t)===e),X=e=>t=>typeof t===e,{isArray:U}=Array,k=X("undefined");function ft(e){return e!==null&&!k(e)&&e.constructor!==null&&!k(e.constructor)&&x(e.constructor.isBuffer)&&e.constructor.isBuffer(e)}var Pe=R("ArrayBuffer");function dt(e){let t;return typeof ArrayBuffer<"u"&&ArrayBuffer.isView?t=ArrayBuffer.isView(e):t=e&&e.buffer&&Pe(e.buffer),t}var pt=X("string"),x=X("function"),Fe=X("number"),Y=e=>e!==null&&typeof e=="object",mt=e=>e===!0||e===!1,K=e=>{if(G(e)!=="object")return!1;let t=fe(e);return(t===null||t===Object.prototype||Object.getPrototypeOf(t)===null)&&!(Symbol.toStringTag in e)&&!(Symbol.iterator in e)},ht=R("Date"),yt=R("File"),wt=R("Blob"),Et=R("FileList"),bt=e=>Y(e)&&x(e.pipe),St=e=>{let t;return e&&(typeof FormData=="function"&&e instanceof FormData||x(e.append)&&((t=G(e))==="formdata"||t==="object"&&x(e.toString)&&e.toString()==="[object FormData]"))},xt=R("URLSearchParams"),At=e=>e.trim?e.trim():e.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g,"");function I(e,t,{allOwnKeys:r=!1}={}){if(e===null||typeof e>"u")return;let n,o;if(typeof e!="object"&&(e=[e]),U(e))for(n=0,o=e.length;n<o;n++)t.call(null,e[n],n,e);else{let i=r?Object.getOwnPropertyNames(e):Object.keys(e),s=i.length,c;for(n=0;n<s;n++)c=i[n],t.call(null,e[c],c,e)}}function Ue(e,t){t=t.toLowerCase();let r=Object.keys(e),n=r.length,o;for(;n-- >0;)if(o=r[n],t===o.toLowerCase())return o;return null}var _e=(()=>typeof globalThis<"u"?globalThis:typeof self<"u"?self:typeof window<"u"?window:global)(),De=e=>!k(e)&&e!==_e;function ue(){let{caseless:e}=De(this)&&this||{},t={},r=(n,o)=>{let i=e&&Ue(t,o)||o;K(t[i])&&K(n)?t[i]=ue(t[i],n):K(n)?t[i]=ue({},n):U(n)?t[i]=n.slice():t[i]=n};for(let n=0,o=arguments.length;n<o;n++)arguments[n]&&I(arguments[n],r);return t}var Rt=(e,t,r,{allOwnKeys:n}={})=>(I(t,(o,i)=>{r&&x(o)?e[i]=j(o,r):e[i]=o},{allOwnKeys:n}),e),Ot=e=>(e.charCodeAt(0)===65279&&(e=e.slice(1)),e),gt=(e,t,r,n)=>{e.prototype=Object.create(t.prototype,n),e.prototype.constructor=e,Object.defineProperty(e,"super",{value:t.prototype}),r&&Object.assign(e.prototype,r)},Tt=(e,t,r,n)=>{let o,i,s,c={};if(t=t||{},e==null)return t;do{for(o=Object.getOwnPropertyNames(e),i=o.length;i-- >0;)s=o[i],(!n||n(s,e,t))&&!c[s]&&(t[s]=e[s],c[s]=!0);e=r!==!1&&fe(e)}while(e&&(!r||r(e,t))&&e!==Object.prototype);return t},Ct=(e,t,r)=>{e=String(e),(r===void 0||r>e.length)&&(r=e.length),r-=t.length;let n=e.indexOf(t,r);return n!==-1&&n===r},Nt=e=>{if(!e)return null;if(U(e))return e;let t=e.length;if(!Fe(t))return null;let r=new Array(t);for(;t-- >0;)r[t]=e[t];return r},Pt=(e=>t=>e&&t instanceof e)(typeof Uint8Array<"u"&&fe(Uint8Array)),Ft=(e,t)=>{let n=(e&&e[Symbol.iterator]).call(e),o;for(;(o=n.next())&&!o.done;){let i=o.value;t.call(e,i[0],i[1])}},Ut=(e,t)=>{let r,n=[];for(;(r=e.exec(t))!==null;)n.push(r);return n},_t=R("HTMLFormElement"),Dt=e=>e.toLowerCase().replace(/[-_\s]([a-z\d])(\w*)/g,function(r,n,o){return n.toUpperCase()+o}),Ce=(({hasOwnProperty:e})=>(t,r)=>e.call(t,r))(Object.prototype),Lt=R("RegExp"),Le=(e,t)=>{let r=Object.getOwnPropertyDescriptors(e),n={};I(r,(o,i)=>{t(o,i,e)!==!1&&(n[i]=o)}),Object.defineProperties(e,n)},Bt=e=>{Le(e,(t,r)=>{if(x(e)&&["arguments","caller","callee"].indexOf(r)!==-1)return!1;let n=e[r];if(x(n)){if(t.enumerable=!1,"writable"in t){t.writable=!1;return}t.set||(t.set=()=>{throw Error("Can not rewrite read-only method '"+r+"'")})}})},jt=(e,t)=>{let r={},n=o=>{o.forEach(i=>{r[i]=!0})};return U(e)?n(e):n(String(e).split(t)),r},kt=()=>{},It=(e,t)=>(e=+e,Number.isFinite(e)?e:t),le="abcdefghijklmnopqrstuvwxyz",Ne="0123456789",Be={DIGIT:Ne,ALPHA:le,ALPHA_DIGIT:le+le.toUpperCase()+Ne},Ht=(e=16,t=Be.ALPHA_DIGIT)=>{let r="",{length:n}=t;for(;e--;)r+=t[Math.random()*n|0];return r};function qt(e){return!!(e&&x(e.append)&&e[Symbol.toStringTag]==="FormData"&&e[Symbol.iterator])}var Mt=e=>{let t=new Array(10),r=(n,o)=>{if(Y(n)){if(t.indexOf(n)>=0)return;if(!("toJSON"in n)){t[o]=n;let i=U(n)?[]:{};return I(n,(s,c)=>{let f=r(s,o+1);!k(f)&&(i[c]=f)}),t[o]=void 0,i}}return n};return r(e,0)},Jt=R("AsyncFunction"),zt=e=>e&&(Y(e)||x(e))&&x(e.then)&&x(e.catch),a={isArray:U,isArrayBuffer:Pe,isBuffer:ft,isFormData:St,isArrayBufferView:dt,isString:pt,isNumber:Fe,isBoolean:mt,isObject:Y,isPlainObject:K,isUndefined:k,isDate:ht,isFile:yt,isBlob:wt,isRegExp:Lt,isFunction:x,isStream:bt,isURLSearchParams:xt,isTypedArray:Pt,isFileList:Et,forEach:I,merge:ue,extend:Rt,trim:At,stripBOM:Ot,inherits:gt,toFlatObject:Tt,kindOf:G,kindOfTest:R,endsWith:Ct,toArray:Nt,forEachEntry:Ft,matchAll:Ut,isHTMLForm:_t,hasOwnProperty:Ce,hasOwnProp:Ce,reduceDescriptors:Le,freezeMethods:Bt,toObjectSet:jt,toCamelCase:Dt,noop:kt,toFiniteNumber:It,findKey:Ue,global:_e,isContextDefined:De,ALPHABET:Be,generateString:Ht,isSpecCompliantForm:qt,toJSONObject:Mt,isAsyncFn:Jt,isThenable:zt};function _(e,t,r,n,o){Error.call(this),Error.captureStackTrace?Error.captureStackTrace(this,this.constructor):this.stack=new Error().stack,this.message=e,this.name="AxiosError",t&&(this.code=t),r&&(this.config=r),n&&(this.request=n),o&&(this.response=o)}a.inherits(_,Error,{toJSON:function(){return{message:this.message,name:this.name,description:this.description,number:this.number,fileName:this.fileName,lineNumber:this.lineNumber,columnNumber:this.columnNumber,stack:this.stack,config:a.toJSONObject(this.config),code:this.code,status:this.response&&this.response.status?this.response.status:null}}});var je=_.prototype,ke={};["ERR_BAD_OPTION_VALUE","ERR_BAD_OPTION","ECONNABORTED","ETIMEDOUT","ERR_NETWORK","ERR_FR_TOO_MANY_REDIRECTS","ERR_DEPRECATED","ERR_BAD_RESPONSE","ERR_BAD_REQUEST","ERR_CANCELED","ERR_NOT_SUPPORT","ERR_INVALID_URL"].forEach(e=>{ke[e]={value:e}});Object.defineProperties(_,ke);Object.defineProperty(je,"isAxiosError",{value:!0});_.from=(e,t,r,n,o,i)=>{let s=Object.create(je);return a.toFlatObject(e,s,function(f){return f!==Error.prototype},c=>c!=="isAxiosError"),_.call(s,e.message,t,r,n,o),s.cause=e,s.name=e.name,i&&Object.assign(s,i),s};var m=_;var Q=null;function de(e){return a.isPlainObject(e)||a.isArray(e)}function He(e){return a.endsWith(e,"[]")?e.slice(0,-2):e}function Ie(e,t,r){return e?e.concat(t).map(function(o,i){return o=He(o),!r&&i?"["+o+"]":o}).join(r?".":""):t}function vt(e){return a.isArray(e)&&!e.some(de)}var Vt=a.toFlatObject(a,{},null,function(t){return/^is[A-Z]/.test(t)});function $t(e,t,r){if(!a.isObject(e))throw new TypeError("target must be an object");t=t||new(Q||FormData),r=a.toFlatObject(r,{metaTokens:!0,dots:!1,indexes:!1},!1,function(h,g){return!a.isUndefined(g[h])});let n=r.metaTokens,o=r.visitor||u,i=r.dots,s=r.indexes,f=(r.Blob||typeof Blob<"u"&&Blob)&&a.isSpecCompliantForm(t);if(!a.isFunction(o))throw new TypeError("visitor must be a function");function l(d){if(d===null)return"";if(a.isDate(d))return d.toISOString();if(!f&&a.isBlob(d))throw new m("Blob is not supported. Use a Buffer instead.");return a.isArrayBuffer(d)||a.isTypedArray(d)?f&&typeof Blob=="function"?new Blob([d]):Buffer.from(d):d}function u(d,h,g){let A=d;if(d&&!g&&typeof d=="object"){if(a.endsWith(h,"{}"))h=n?h:h.slice(0,-2),d=JSON.stringify(d);else if(a.isArray(d)&&vt(d)||(a.isFileList(d)||a.endsWith(h,"[]"))&&(A=a.toArray(d)))return h=He(h),A.forEach(function(W,lt){!(a.isUndefined(W)||W===null)&&t.append(s===!0?Ie([h],lt,i):s===null?h:h+"[]",l(W))}),!1}return de(d)?!0:(t.append(Ie(g,h,i),l(d)),!1)}let p=[],E=Object.assign(Vt,{defaultVisitor:u,convertValue:l,isVisitable:de});function y(d,h){if(!a.isUndefined(d)){if(p.indexOf(d)!==-1)throw Error("Circular reference detected in "+h.join("."));p.push(d),a.forEach(d,function(A,F){(!(a.isUndefined(A)||A===null)&&o.call(t,A,a.isString(F)?F.trim():F,h,E))===!0&&y(A,h?h.concat(F):[F])}),p.pop()}}if(!a.isObject(e))throw new TypeError("data must be an object");return y(e),t}var C=$t;function qe(e){let t={"!":"%21","'":"%27","(":"%28",")":"%29","~":"%7E","%20":"+","%00":"\0"};return encodeURIComponent(e).replace(/[!'()~]|%20|%00/g,function(n){return t[n]})}function Me(e,t){this._pairs=[],e&&C(e,this,t)}var Je=Me.prototype;Je.append=function(t,r){this._pairs.push([t,r])};Je.toString=function(t){let r=t?function(n){return t.call(this,n,qe)}:qe;return this._pairs.map(function(o){return r(o[0])+"="+r(o[1])},"").join("&")};var Z=Me;function Wt(e){return encodeURIComponent(e).replace(/%3A/gi,":").replace(/%24/g,"$").replace(/%2C/gi,",").replace(/%20/g,"+").replace(/%5B/gi,"[").replace(/%5D/gi,"]")}function H(e,t,r){if(!t)return e;let n=r&&r.encode||Wt,o=r&&r.serialize,i;if(o?i=o(t,r):i=a.isURLSearchParams(t)?t.toString():new Z(t,r).toString(n),i){let s=e.indexOf("#");s!==-1&&(e=e.slice(0,s)),e+=(e.indexOf("?")===-1?"?":"&")+i}return e}var pe=class{constructor(){this.handlers=[]}use(t,r,n){return this.handlers.push({fulfilled:t,rejected:r,synchronous:n?n.synchronous:!1,runWhen:n?n.runWhen:null}),this.handlers.length-1}eject(t){this.handlers[t]&&(this.handlers[t]=null)}clear(){this.handlers&&(this.handlers=[])}forEach(t){a.forEach(this.handlers,function(n){n!==null&&t(n)})}},me=pe;var ee={silentJSONParsing:!0,forcedJSONParsing:!0,clarifyTimeoutError:!1};var ze=typeof URLSearchParams<"u"?URLSearchParams:Z;var ve=typeof FormData<"u"?FormData:null;var Ve=typeof Blob<"u"?Blob:null;var Kt=(()=>{let e;return typeof navigator<"u"&&((e=navigator.product)==="ReactNative"||e==="NativeScript"||e==="NS")?!1:typeof window<"u"&&typeof document<"u"})(),Gt=(()=>typeof WorkerGlobalScope<"u"&&self instanceof WorkerGlobalScope&&typeof self.importScripts=="function")(),b={isBrowser:!0,classes:{URLSearchParams:ze,FormData:ve,Blob:Ve},isStandardBrowserEnv:Kt,isStandardBrowserWebWorkerEnv:Gt,protocols:["http","https","file","blob","url","data"]};function he(e,t){return C(e,new b.classes.URLSearchParams,Object.assign({visitor:function(r,n,o,i){return b.isNode&&a.isBuffer(r)?(this.append(n,r.toString("base64")),!1):i.defaultVisitor.apply(this,arguments)}},t))}function Xt(e){return a.matchAll(/\w+|\[(\w*)]/g,e).map(t=>t[0]==="[]"?"":t[1]||t[0])}function Yt(e){let t={},r=Object.keys(e),n,o=r.length,i;for(n=0;n<o;n++)i=r[n],t[i]=e[i];return t}function Qt(e){function t(r,n,o,i){let s=r[i++],c=Number.isFinite(+s),f=i>=r.length;return s=!s&&a.isArray(o)?o.length:s,f?(a.hasOwnProp(o,s)?o[s]=[o[s],n]:o[s]=n,!c):((!o[s]||!a.isObject(o[s]))&&(o[s]=[]),t(r,n,o[s],i)&&a.isArray(o[s])&&(o[s]=Yt(o[s])),!c)}if(a.isFormData(e)&&a.isFunction(e.entries)){let r={};return a.forEachEntry(e,(n,o)=>{t(Xt(n),o,r,0)}),r}return null}var te=Qt;var Zt={"Content-Type":void 0};function er(e,t,r){if(a.isString(e))try{return(t||JSON.parse)(e),a.trim(e)}catch(n){if(n.name!=="SyntaxError")throw n}return(r||JSON.stringify)(e)}var re={transitional:ee,adapter:["xhr","http"],transformRequest:[function(t,r){let n=r.getContentType()||"",o=n.indexOf("application/json")>-1,i=a.isObject(t);if(i&&a.isHTMLForm(t)&&(t=new FormData(t)),a.isFormData(t))return o&&o?JSON.stringify(te(t)):t;if(a.isArrayBuffer(t)||a.isBuffer(t)||a.isStream(t)||a.isFile(t)||a.isBlob(t))return t;if(a.isArrayBufferView(t))return t.buffer;if(a.isURLSearchParams(t))return r.setContentType("application/x-www-form-urlencoded;charset=utf-8",!1),t.toString();let c;if(i){if(n.indexOf("application/x-www-form-urlencoded")>-1)return he(t,this.formSerializer).toString();if((c=a.isFileList(t))||n.indexOf("multipart/form-data")>-1){let f=this.env&&this.env.FormData;return C(c?{"files[]":t}:t,f&&new f,this.formSerializer)}}return i||o?(r.setContentType("application/json",!1),er(t)):t}],transformResponse:[function(t){let r=this.transitional||re.transitional,n=r&&r.forcedJSONParsing,o=this.responseType==="json";if(t&&a.isString(t)&&(n&&!this.responseType||o)){let s=!(r&&r.silentJSONParsing)&&o;try{return JSON.parse(t)}catch(c){if(s)throw c.name==="SyntaxError"?m.from(c,m.ERR_BAD_RESPONSE,this,null,this.response):c}}return t}],timeout:0,xsrfCookieName:"XSRF-TOKEN",xsrfHeaderName:"X-XSRF-TOKEN",maxContentLength:-1,maxBodyLength:-1,env:{FormData:b.classes.FormData,Blob:b.classes.Blob},validateStatus:function(t){return t>=200&&t<300},headers:{common:{Accept:"application/json, text/plain, */*"}}};a.forEach(["delete","get","head"],function(t){re.headers[t]={}});a.forEach(["post","put","patch"],function(t){re.headers[t]=a.merge(Zt)});var D=re;var tr=a.toObjectSet(["age","authorization","content-length","content-type","etag","expires","from","host","if-modified-since","if-unmodified-since","last-modified","location","max-forwards","proxy-authorization","referer","retry-after","user-agent"]),$e=e=>{let t={},r,n,o;return e&&e.split(`
2
+ `).forEach(function(s){o=s.indexOf(":"),r=s.substring(0,o).trim().toLowerCase(),n=s.substring(o+1).trim(),!(!r||t[r]&&tr[r])&&(r==="set-cookie"?t[r]?t[r].push(n):t[r]=[n]:t[r]=t[r]?t[r]+", "+n:n)}),t};var We=Symbol("internals");function q(e){return e&&String(e).trim().toLowerCase()}function ne(e){return e===!1||e==null?e:a.isArray(e)?e.map(ne):String(e)}function rr(e){let t=Object.create(null),r=/([^\s,;=]+)\s*(?:=\s*([^,;]+))?/g,n;for(;n=r.exec(e);)t[n[1]]=n[2];return t}var nr=e=>/^[-_a-zA-Z0-9^`|~,!#$%&'*+.]+$/.test(e.trim());function ye(e,t,r,n,o){if(a.isFunction(n))return n.call(this,t,r);if(o&&(t=r),!!a.isString(t)){if(a.isString(n))return t.indexOf(n)!==-1;if(a.isRegExp(n))return n.test(t)}}function or(e){return e.trim().toLowerCase().replace(/([a-z\d])(\w*)/g,(t,r,n)=>r.toUpperCase()+n)}function sr(e,t){let r=a.toCamelCase(" "+t);["get","set","has"].forEach(n=>{Object.defineProperty(e,n+r,{value:function(o,i,s){return this[n].call(this,t,o,i,s)},configurable:!0})})}var L=class{constructor(t){t&&this.set(t)}set(t,r,n){let o=this;function i(c,f,l){let u=q(f);if(!u)throw new Error("header name must be a non-empty string");let p=a.findKey(o,u);(!p||o[p]===void 0||l===!0||l===void 0&&o[p]!==!1)&&(o[p||f]=ne(c))}let s=(c,f)=>a.forEach(c,(l,u)=>i(l,u,f));return a.isPlainObject(t)||t instanceof this.constructor?s(t,r):a.isString(t)&&(t=t.trim())&&!nr(t)?s($e(t),r):t!=null&&i(r,t,n),this}get(t,r){if(t=q(t),t){let n=a.findKey(this,t);if(n){let o=this[n];if(!r)return o;if(r===!0)return rr(o);if(a.isFunction(r))return r.call(this,o,n);if(a.isRegExp(r))return r.exec(o);throw new TypeError("parser must be boolean|regexp|function")}}}has(t,r){if(t=q(t),t){let n=a.findKey(this,t);return!!(n&&this[n]!==void 0&&(!r||ye(this,this[n],n,r)))}return!1}delete(t,r){let n=this,o=!1;function i(s){if(s=q(s),s){let c=a.findKey(n,s);c&&(!r||ye(n,n[c],c,r))&&(delete n[c],o=!0)}}return a.isArray(t)?t.forEach(i):i(t),o}clear(t){let r=Object.keys(this),n=r.length,o=!1;for(;n--;){let i=r[n];(!t||ye(this,this[i],i,t,!0))&&(delete this[i],o=!0)}return o}normalize(t){let r=this,n={};return a.forEach(this,(o,i)=>{let s=a.findKey(n,i);if(s){r[s]=ne(o),delete r[i];return}let c=t?or(i):String(i).trim();c!==i&&delete r[i],r[c]=ne(o),n[c]=!0}),this}concat(...t){return this.constructor.concat(this,...t)}toJSON(t){let r=Object.create(null);return a.forEach(this,(n,o)=>{n!=null&&n!==!1&&(r[o]=t&&a.isArray(n)?n.join(", "):n)}),r}[Symbol.iterator](){return Object.entries(this.toJSON())[Symbol.iterator]()}toString(){return Object.entries(this.toJSON()).map(([t,r])=>t+": "+r).join(`
3
+ `)}get[Symbol.toStringTag](){return"AxiosHeaders"}static from(t){return t instanceof this?t:new this(t)}static concat(t,...r){let n=new this(t);return r.forEach(o=>n.set(o)),n}static accessor(t){let n=(this[We]=this[We]={accessors:{}}).accessors,o=this.prototype;function i(s){let c=q(s);n[c]||(sr(o,s),n[c]=!0)}return a.isArray(t)?t.forEach(i):i(t),this}};L.accessor(["Content-Type","Content-Length","Accept","Accept-Encoding","User-Agent","Authorization"]);a.freezeMethods(L.prototype);a.freezeMethods(L);var S=L;function M(e,t){let r=this||D,n=t||r,o=S.from(n.headers),i=n.data;return a.forEach(e,function(c){i=c.call(r,i,o.normalize(),t?t.status:void 0)}),o.normalize(),i}function J(e){return!!(e&&e.__CANCEL__)}function Ke(e,t,r){m.call(this,e??"canceled",m.ERR_CANCELED,t,r),this.name="CanceledError"}a.inherits(Ke,m,{__CANCEL__:!0});var N=Ke;function we(e,t,r){let n=r.config.validateStatus;!r.status||!n||n(r.status)?e(r):t(new m("Request failed with status code "+r.status,[m.ERR_BAD_REQUEST,m.ERR_BAD_RESPONSE][Math.floor(r.status/100)-4],r.config,r.request,r))}var Ge=b.isStandardBrowserEnv?function(){return{write:function(r,n,o,i,s,c){let f=[];f.push(r+"="+encodeURIComponent(n)),a.isNumber(o)&&f.push("expires="+new Date(o).toGMTString()),a.isString(i)&&f.push("path="+i),a.isString(s)&&f.push("domain="+s),c===!0&&f.push("secure"),document.cookie=f.join("; ")},read:function(r){let n=document.cookie.match(new RegExp("(^|;\\s*)("+r+")=([^;]*)"));return n?decodeURIComponent(n[3]):null},remove:function(r){this.write(r,"",Date.now()-864e5)}}}():function(){return{write:function(){},read:function(){return null},remove:function(){}}}();function Ee(e){return/^([a-z][a-z\d+\-.]*:)?\/\//i.test(e)}function be(e,t){return t?e.replace(/\/+$/,"")+"/"+t.replace(/^\/+/,""):e}function z(e,t){return e&&!Ee(t)?be(e,t):t}var Xe=b.isStandardBrowserEnv?function(){let t=/(msie|trident)/i.test(navigator.userAgent),r=document.createElement("a"),n;function o(i){let s=i;return t&&(r.setAttribute("href",s),s=r.href),r.setAttribute("href",s),{href:r.href,protocol:r.protocol?r.protocol.replace(/:$/,""):"",host:r.host,search:r.search?r.search.replace(/^\?/,""):"",hash:r.hash?r.hash.replace(/^#/,""):"",hostname:r.hostname,port:r.port,pathname:r.pathname.charAt(0)==="/"?r.pathname:"/"+r.pathname}}return n=o(window.location.href),function(s){let c=a.isString(s)?o(s):s;return c.protocol===n.protocol&&c.host===n.host}}():function(){return function(){return!0}}();function Se(e){let t=/^([-+\w]{1,25})(:?\/\/|:)/.exec(e);return t&&t[1]||""}function ir(e,t){e=e||10;let r=new Array(e),n=new Array(e),o=0,i=0,s;return t=t!==void 0?t:1e3,function(f){let l=Date.now(),u=n[i];s||(s=l),r[o]=f,n[o]=l;let p=i,E=0;for(;p!==o;)E+=r[p++],p=p%e;if(o=(o+1)%e,o===i&&(i=(i+1)%e),l-s<t)return;let y=u&&l-u;return y?Math.round(E*1e3/y):void 0}}var Ye=ir;function Qe(e,t){let r=0,n=Ye(50,250);return o=>{let i=o.loaded,s=o.lengthComputable?o.total:void 0,c=i-r,f=n(c),l=i<=s;r=i;let u={loaded:i,total:s,progress:s?i/s:void 0,bytes:c,rate:f||void 0,estimated:f&&s&&l?(s-i)/f:void 0,event:o};u[t?"download":"upload"]=!0,e(u)}}var ar=typeof XMLHttpRequest<"u",Ze=ar&&function(e){return new Promise(function(r,n){let o=e.data,i=S.from(e.headers).normalize(),s=e.responseType,c;function f(){e.cancelToken&&e.cancelToken.unsubscribe(c),e.signal&&e.signal.removeEventListener("abort",c)}a.isFormData(o)&&(b.isStandardBrowserEnv||b.isStandardBrowserWebWorkerEnv?i.setContentType(!1):i.setContentType("multipart/form-data;",!1));let l=new XMLHttpRequest;if(e.auth){let y=e.auth.username||"",d=e.auth.password?unescape(encodeURIComponent(e.auth.password)):"";i.set("Authorization","Basic "+btoa(y+":"+d))}let u=z(e.baseURL,e.url);l.open(e.method.toUpperCase(),H(u,e.params,e.paramsSerializer),!0),l.timeout=e.timeout;function p(){if(!l)return;let y=S.from("getAllResponseHeaders"in l&&l.getAllResponseHeaders()),h={data:!s||s==="text"||s==="json"?l.responseText:l.response,status:l.status,statusText:l.statusText,headers:y,config:e,request:l};we(function(A){r(A),f()},function(A){n(A),f()},h),l=null}if("onloadend"in l?l.onloadend=p:l.onreadystatechange=function(){!l||l.readyState!==4||l.status===0&&!(l.responseURL&&l.responseURL.indexOf("file:")===0)||setTimeout(p)},l.onabort=function(){l&&(n(new m("Request aborted",m.ECONNABORTED,e,l)),l=null)},l.onerror=function(){n(new m("Network Error",m.ERR_NETWORK,e,l)),l=null},l.ontimeout=function(){let d=e.timeout?"timeout of "+e.timeout+"ms exceeded":"timeout exceeded",h=e.transitional||ee;e.timeoutErrorMessage&&(d=e.timeoutErrorMessage),n(new m(d,h.clarifyTimeoutError?m.ETIMEDOUT:m.ECONNABORTED,e,l)),l=null},b.isStandardBrowserEnv){let y=(e.withCredentials||Xe(u))&&e.xsrfCookieName&&Ge.read(e.xsrfCookieName);y&&i.set(e.xsrfHeaderName,y)}o===void 0&&i.setContentType(null),"setRequestHeader"in l&&a.forEach(i.toJSON(),function(d,h){l.setRequestHeader(h,d)}),a.isUndefined(e.withCredentials)||(l.withCredentials=!!e.withCredentials),s&&s!=="json"&&(l.responseType=e.responseType),typeof e.onDownloadProgress=="function"&&l.addEventListener("progress",Qe(e.onDownloadProgress,!0)),typeof e.onUploadProgress=="function"&&l.upload&&l.upload.addEventListener("progress",Qe(e.onUploadProgress)),(e.cancelToken||e.signal)&&(c=y=>{l&&(n(!y||y.type?new N(null,e,l):y),l.abort(),l=null)},e.cancelToken&&e.cancelToken.subscribe(c),e.signal&&(e.signal.aborted?c():e.signal.addEventListener("abort",c)));let E=Se(u);if(E&&b.protocols.indexOf(E)===-1){n(new m("Unsupported protocol "+E+":",m.ERR_BAD_REQUEST,e));return}l.send(o||null)})};var oe={http:Q,xhr:Ze};a.forEach(oe,(e,t)=>{if(e){try{Object.defineProperty(e,"name",{value:t})}catch{}Object.defineProperty(e,"adapterName",{value:t})}});var et={getAdapter:e=>{e=a.isArray(e)?e:[e];let{length:t}=e,r,n;for(let o=0;o<t&&(r=e[o],!(n=a.isString(r)?oe[r.toLowerCase()]:r));o++);if(!n)throw n===!1?new m(`Adapter ${r} is not supported by the environment`,"ERR_NOT_SUPPORT"):new Error(a.hasOwnProp(oe,r)?`Adapter '${r}' is not available in the build`:`Unknown adapter '${r}'`);if(!a.isFunction(n))throw new TypeError("adapter is not a function");return n},adapters:oe};function xe(e){if(e.cancelToken&&e.cancelToken.throwIfRequested(),e.signal&&e.signal.aborted)throw new N(null,e)}function se(e){return xe(e),e.headers=S.from(e.headers),e.data=M.call(e,e.transformRequest),["post","put","patch"].indexOf(e.method)!==-1&&e.headers.setContentType("application/x-www-form-urlencoded",!1),et.getAdapter(e.adapter||D.adapter)(e).then(function(n){return xe(e),n.data=M.call(e,e.transformResponse,n),n.headers=S.from(n.headers),n},function(n){return J(n)||(xe(e),n&&n.response&&(n.response.data=M.call(e,e.transformResponse,n.response),n.response.headers=S.from(n.response.headers))),Promise.reject(n)})}var tt=e=>e instanceof S?e.toJSON():e;function T(e,t){t=t||{};let r={};function n(l,u,p){return a.isPlainObject(l)&&a.isPlainObject(u)?a.merge.call({caseless:p},l,u):a.isPlainObject(u)?a.merge({},u):a.isArray(u)?u.slice():u}function o(l,u,p){if(a.isUndefined(u)){if(!a.isUndefined(l))return n(void 0,l,p)}else return n(l,u,p)}function i(l,u){if(!a.isUndefined(u))return n(void 0,u)}function s(l,u){if(a.isUndefined(u)){if(!a.isUndefined(l))return n(void 0,l)}else return n(void 0,u)}function c(l,u,p){if(p in t)return n(l,u);if(p in e)return n(void 0,l)}let f={url:i,method:i,data:i,baseURL:s,transformRequest:s,transformResponse:s,paramsSerializer:s,timeout:s,timeoutMessage:s,withCredentials:s,adapter:s,responseType:s,xsrfCookieName:s,xsrfHeaderName:s,onUploadProgress:s,onDownloadProgress:s,decompress:s,maxContentLength:s,maxBodyLength:s,beforeRedirect:s,transport:s,httpAgent:s,httpsAgent:s,cancelToken:s,socketPath:s,responseEncoding:s,validateStatus:c,headers:(l,u)=>o(tt(l),tt(u),!0)};return a.forEach(Object.keys(Object.assign({},e,t)),function(u){let p=f[u]||o,E=p(e[u],t[u],u);a.isUndefined(E)&&p!==c||(r[u]=E)}),r}var ie="1.4.0";var Ae={};["object","boolean","number","function","string","symbol"].forEach((e,t)=>{Ae[e]=function(n){return typeof n===e||"a"+(t<1?"n ":" ")+e}});var rt={};Ae.transitional=function(t,r,n){function o(i,s){return"[Axios v"+ie+"] Transitional option '"+i+"'"+s+(n?". "+n:"")}return(i,s,c)=>{if(t===!1)throw new m(o(s," has been removed"+(r?" in "+r:"")),m.ERR_DEPRECATED);return r&&!rt[s]&&(rt[s]=!0,console.warn(o(s," has been deprecated since v"+r+" and will be removed in the near future"))),t?t(i,s,c):!0}};function cr(e,t,r){if(typeof e!="object")throw new m("options must be an object",m.ERR_BAD_OPTION_VALUE);let n=Object.keys(e),o=n.length;for(;o-- >0;){let i=n[o],s=t[i];if(s){let c=e[i],f=c===void 0||s(c,i,e);if(f!==!0)throw new m("option "+i+" must be "+f,m.ERR_BAD_OPTION_VALUE);continue}if(r!==!0)throw new m("Unknown option "+i,m.ERR_BAD_OPTION)}}var ae={assertOptions:cr,validators:Ae};var P=ae.validators,B=class{constructor(t){this.defaults=t,this.interceptors={request:new me,response:new me}}request(t,r){typeof t=="string"?(r=r||{},r.url=t):r=t||{},r=T(this.defaults,r);let{transitional:n,paramsSerializer:o,headers:i}=r;n!==void 0&&ae.assertOptions(n,{silentJSONParsing:P.transitional(P.boolean),forcedJSONParsing:P.transitional(P.boolean),clarifyTimeoutError:P.transitional(P.boolean)},!1),o!=null&&(a.isFunction(o)?r.paramsSerializer={serialize:o}:ae.assertOptions(o,{encode:P.function,serialize:P.function},!0)),r.method=(r.method||this.defaults.method||"get").toLowerCase();let s;s=i&&a.merge(i.common,i[r.method]),s&&a.forEach(["delete","get","head","post","put","patch","common"],d=>{delete i[d]}),r.headers=S.concat(s,i);let c=[],f=!0;this.interceptors.request.forEach(function(h){typeof h.runWhen=="function"&&h.runWhen(r)===!1||(f=f&&h.synchronous,c.unshift(h.fulfilled,h.rejected))});let l=[];this.interceptors.response.forEach(function(h){l.push(h.fulfilled,h.rejected)});let u,p=0,E;if(!f){let d=[se.bind(this),void 0];for(d.unshift.apply(d,c),d.push.apply(d,l),E=d.length,u=Promise.resolve(r);p<E;)u=u.then(d[p++],d[p++]);return u}E=c.length;let y=r;for(p=0;p<E;){let d=c[p++],h=c[p++];try{y=d(y)}catch(g){h.call(this,g);break}}try{u=se.call(this,y)}catch(d){return Promise.reject(d)}for(p=0,E=l.length;p<E;)u=u.then(l[p++],l[p++]);return u}getUri(t){t=T(this.defaults,t);let r=z(t.baseURL,t.url);return H(r,t.params,t.paramsSerializer)}};a.forEach(["delete","get","head","options"],function(t){B.prototype[t]=function(r,n){return this.request(T(n||{},{method:t,url:r,data:(n||{}).data}))}});a.forEach(["post","put","patch"],function(t){function r(n){return function(i,s,c){return this.request(T(c||{},{method:t,headers:n?{"Content-Type":"multipart/form-data"}:{},url:i,data:s}))}}B.prototype[t]=r(),B.prototype[t+"Form"]=r(!0)});var v=B;var V=class{constructor(t){if(typeof t!="function")throw new TypeError("executor must be a function.");let r;this.promise=new Promise(function(i){r=i});let n=this;this.promise.then(o=>{if(!n._listeners)return;let i=n._listeners.length;for(;i-- >0;)n._listeners[i](o);n._listeners=null}),this.promise.then=o=>{let i,s=new Promise(c=>{n.subscribe(c),i=c}).then(o);return s.cancel=function(){n.unsubscribe(i)},s},t(function(i,s,c){n.reason||(n.reason=new N(i,s,c),r(n.reason))})}throwIfRequested(){if(this.reason)throw this.reason}subscribe(t){if(this.reason){t(this.reason);return}this._listeners?this._listeners.push(t):this._listeners=[t]}unsubscribe(t){if(!this._listeners)return;let r=this._listeners.indexOf(t);r!==-1&&this._listeners.splice(r,1)}static source(){let t;return{token:new V(function(o){t=o}),cancel:t}}},nt=V;function Re(e){return function(r){return e.apply(null,r)}}function Oe(e){return a.isObject(e)&&e.isAxiosError===!0}var ge={Continue:100,SwitchingProtocols:101,Processing:102,EarlyHints:103,Ok:200,Created:201,Accepted:202,NonAuthoritativeInformation:203,NoContent:204,ResetContent:205,PartialContent:206,MultiStatus:207,AlreadyReported:208,ImUsed:226,MultipleChoices:300,MovedPermanently:301,Found:302,SeeOther:303,NotModified:304,UseProxy:305,Unused:306,TemporaryRedirect:307,PermanentRedirect:308,BadRequest:400,Unauthorized:401,PaymentRequired:402,Forbidden:403,NotFound:404,MethodNotAllowed:405,NotAcceptable:406,ProxyAuthenticationRequired:407,RequestTimeout:408,Conflict:409,Gone:410,LengthRequired:411,PreconditionFailed:412,PayloadTooLarge:413,UriTooLong:414,UnsupportedMediaType:415,RangeNotSatisfiable:416,ExpectationFailed:417,ImATeapot:418,MisdirectedRequest:421,UnprocessableEntity:422,Locked:423,FailedDependency:424,TooEarly:425,UpgradeRequired:426,PreconditionRequired:428,TooManyRequests:429,RequestHeaderFieldsTooLarge:431,UnavailableForLegalReasons:451,InternalServerError:500,NotImplemented:501,BadGateway:502,ServiceUnavailable:503,GatewayTimeout:504,HttpVersionNotSupported:505,VariantAlsoNegotiates:506,InsufficientStorage:507,LoopDetected:508,NotExtended:510,NetworkAuthenticationRequired:511};Object.entries(ge).forEach(([e,t])=>{ge[t]=e});var ot=ge;function st(e){let t=new v(e),r=j(v.prototype.request,t);return a.extend(r,v.prototype,t,{allOwnKeys:!0}),a.extend(r,t,null,{allOwnKeys:!0}),r.create=function(o){return st(T(e,o))},r}var w=st(D);w.Axios=v;w.CanceledError=N;w.CancelToken=nt;w.isCancel=J;w.VERSION=ie;w.toFormData=C;w.AxiosError=m;w.Cancel=w.CanceledError;w.all=function(t){return Promise.all(t)};w.spread=Re;w.isAxiosError=Oe;w.mergeConfig=T;w.AxiosHeaders=S;w.formToJSON=e=>te(a.isHTMLForm(e)?new FormData(e):e);w.HttpStatusCode=ot;w.default=w;var ce=w;var{Axios:Wo,AxiosError:Ko,CanceledError:Go,isCancel:Xo,CancelToken:Yo,VERSION:Qo,all:Zo,Cancel:es,isAxiosError:ts,spread:rs,toFormData:ns,AxiosHeaders:os,HttpStatusCode:ss,formToJSON:is,mergeConfig:as}=ce;var $=class{constructor({theme:t="light",render_element_or_id:r="recaptcha-el"}){this.gl_api_url="https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit",this.captcha_sitekey="6LeRUzsjAAAAANUHNEY6VkUXmMo_wlrDK5SUoFUV",this.verify_url="https://internalapi.activamedia.com.sg/v1/recaptcha/verify",this.theme=t,this.render_element_or_id=r,this.defineOnloadCallBack(),this.loadJsFile()}defineOnloadCallBack(){window.onloadCallback=()=>{console.log("api loaded")}}loadJsFile(){if(document.querySelectorAll(`script[src="${this.gl_api_url}"]`).length===0){var t=document.createElement("script");t.setAttribute("src",this.gl_api_url),t.setAttribute("type","text/javascript"),t.setAttribute("async",!0),t.setAttribute("defer",!0),document.body.appendChild(t)}}sleep(t){return new Promise(r=>setTimeout(r,t))}async render(){let t="";for(;;){if(await this.sleep(200),typeof grecaptcha<"u"&&grecaptcha!==void 0&&typeof grecaptcha.render=="function"){t=grecaptcha.render(this.render_element_or_id,{sitekey:this.captcha_sitekey,theme:this.theme});break}console.info("checking grecaptcha undefined")}return t}reset(t){grecaptcha.reset(t)}fetchResponse(t){try{return grecaptcha.getResponse(t)}catch(r){console.error(r)}}async verifyRecaptcha(t){return await fetch(this.verify_url,{method:"post",body:JSON.stringify({token:t}),headers:{Accept:"application/json","Content-Type":"application/json"}}).then(r=>r.json())}};var O={config:{},fields:{},name:null,endpoint:null,redirectTo:null,fileUpload:{filepond:null,el:null},onSuccess(e){},onFailed(e){},amCaptcha:Object,captchaId:null,recaptchaTheme:"light",widgetId:null};async function it(e){let t=Object.assign({},O,e);await lr(t)}async function lr(e){document.addEventListener("alpine:init",()=>{if(Alpine.data(e.name,()=>({...e,errors:{},busy:!1,async init(){if(this.$watch("busy",t=>{let r=document.querySelectorAll('form button, form input[type="submit"], form input[type="button"]');t?r.forEach(n=>{n.disabled=!0}):r.forEach(n=>{n.disabled=!1})}),this.$init&&this.$init(),this.captchaId){let t=document.getElementById(this.captchaId);if(t)this.amCaptcha=new $({theme:this.recaptchaTheme,render_element_or_id:t}),this.widgetId=await this.amCaptcha.render();else throw"Can't find recaptcha rendering element."}},submit(){this.busy=!0,this.errors={};let t=new FormData;if(Object.keys(this.fields).forEach((s,c)=>{typeof this.fields[s]=="object"?this.fields[s].forEach((f,l)=>{t.append(`${s}[${l}]`,f)}):t.append(s,this.fields[s])}),e.fileUpload.filepond)e.fileUpload.filepond.getFiles().forEach((s,c)=>{t.append(`files[${c}]`,s.file,s.name)});else if(e.fileUpload.el){let c=document.querySelector(e.fileUpload.el).files;for(let f=0;f<c.length;f++)t.append(`files[${f}]`,c[f],c[f].name)}let n=new URL(window.top.location.href);t.append("x_origin",n.origin+n.pathname);let o={method:"POST",url:yr(e.endpoint),data:t},i=Object.assign({},o,e.config);this.captchaId&&ur(this.amCaptcha).then(()=>{ce(i).then(s=>{e.redirectTo&&(window.location.href=e.redirectTo),e.fileUpload.filepond&&e.fileUpload.filepond.removeFiles(),fr(),this.resetFields(),e.onSuccess(s),mr()}).catch(s=>{this.errors=s.response.data.errors,this.busy=!1,e.onFailed(s.response),hr(),this.captchaId&&this.amCaptcha.reset(this.widgetId)})}).catch(s=>{this.errors=s,e.onFailed(s),this.busy=!1}).finally(()=>{this.amCaptcha.reset(this.widgetId)})},resetFields(){this.errors={},this.fields=e.fields,this.busy=!1,this.captchaId&&this.amCaptcha.reset(this.widgetId)}})),O.redirectTo&&O.endpoint&&new URL(O.endpoint).host==="hapiform.sg"&&console.log("\u{1F680} "+window.location.origin+O.redirectTo),O.endpoint){let t=new URL(O.endpoint),r=O.endpoint.match(/[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/);t.host==="hapiform.sg"&&console.log(`\u{1F680} ${t.origin}/${r}`)}})}async function ur(e){let t=e.fetchResponse(this.widgetId);if(t.length===0)throw{recaptchaError:"You can't leave Captcha Code empty"};return await e.verifyRecaptcha(t).then(r=>{if(r.success===!1)throw{recaptchaError:"captcha invalid: timeout or duplicate."}})}function fr(){dr(),pr()}function dr(){try{O.fileUpload.filepond.removeFiles()}catch{}}function pr(){try{let e=document.querySelector(O.fileUpload.el);e.value=""}catch{}}function mr(){at("hapi:success")}function hr(){at("hapi:error")}function at(e){let t=new Event(e);document.dispatchEvent(t)}function yr(e){let t=new URL(e);return(window.location.hostname==="localhost"||window.location.hostname==="127.0.0.1")&&(t.searchParams.set("test","1"),console.log("testing mode!")),t.href}function Te(){if(document.querySelectorAll('script[src="//unpkg.com/alpinejs"]').length===0){var e=document.createElement("script");e.setAttribute("src","//unpkg.com/alpinejs"),e.setAttribute("type","text/javascript"),e.setAttribute("defer",!0),document.body.appendChild(e)}}var ct={form:it},hs=ct;window.Hapi=ct;Te();})();
@@ -0,0 +1,6 @@
1
+ Hapi.form({
2
+ name: 'contactForm',
3
+ endpoint: 'https://hapiform.sg/api/a198d598-b594-4ba1-acbe-0d1795b43576',
4
+ redirectTo: '/contactus-success.html',
5
+ captchaId: 'captcha-01'
6
+ });
package/index.html ADDED
@@ -0,0 +1,127 @@
1
+ <!doctype html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport"
6
+ content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
7
+ <meta http-equiv="X-UA-Compatible" content="ie=edge">
8
+ <link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.3/dist/css/bootstrap.min.css"
9
+ integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
10
+ <title>Document</title>
11
+ <style>
12
+ form {
13
+ width: 500px;
14
+ margin: 10px auto;
15
+ }
16
+ </style>
17
+ </head>
18
+ <body>
19
+ <h1>Test</h1>
20
+ <form x-on:submit.prevent="submit" x-data="contactForm">
21
+ <div>
22
+ <div class="mb-3">
23
+ <div class="form-field">
24
+ <label for="form01-name" class="form-label">Name</label>
25
+ <input type="text" id="form01-name" x-model="fields.name"
26
+ placeholder="Name" class="form-control">
27
+ </div>
28
+ <template x-if="errors && errors.name">
29
+ <div x-text="errors.name" class="text-danger"></div>
30
+ </template>
31
+ </div>
32
+ <div class="mb-3">
33
+ <div class="form-field">
34
+ <label for="form01-contact_number" class="form-label">Contact Number</label>
35
+ <input type="tel" id="form01-contact_number" x-model="fields.contact_number"
36
+ placeholder="Contact Number" class="form-control">
37
+
38
+ </div>
39
+ <template x-if="errors && errors.contact_number">
40
+ <div x-text="errors.contact_number" class="text-danger"></div>
41
+ </template>
42
+ </div>
43
+ <div class="mb-3">
44
+ <div class="form-field">
45
+ <label for="form01-email" class="form-label">Email</label>
46
+ <input type="email" id="form01-email" x-model="fields.email"
47
+ placeholder="Email" class="form-control">
48
+ </div>
49
+ <template x-if="errors && errors.email">
50
+ <div x-text="errors.email" class="text-danger"></div>
51
+ </template>
52
+ </div>
53
+ <div class="mb-3">
54
+ <div class="form-field">
55
+ <select class="form-select" id="form01-specialist" x-model="fields.specialist">
56
+ <option value="" selected>Preferred Specialist</option>
57
+ <option value="Dr Dennis Koh">Dr Dennis Koh</option>
58
+ <option value="Dr Sharon Koh">Dr Sharon Koh</option>
59
+ <option value="Dr Pauleon Tan">Dr Pauleon Tan</option>
60
+ <option value="No Preference">No Preference</option>
61
+ </select>
62
+ </div>
63
+ <template x-if="errors && errors.specialist">
64
+ <div x-text="errors.specialist" class="text-danger"></div>
65
+ </template>
66
+ </div>
67
+ <div class="mb-3">
68
+ <div class="form-field">
69
+ <label for="form01-message" class="form-label">Message</label>
70
+ <textarea id="form01-message" x-model="fields.message" rows="4"
71
+ placeholder="Message" class="form-control form-textarea"></textarea>
72
+
73
+ </div>
74
+ <template x-if="errors && errors.message">
75
+ <div x-text="errors.message" class="text-danger"></div>
76
+ </template>
77
+ </div>
78
+ <div class="mb-3">
79
+ <div id="captcha-01"></div>
80
+ <template x-if="errors && errors.recaptchaError">
81
+ <div x-text="errors.recaptchaError" class="text-danger"></div>
82
+ </template>
83
+ </div>
84
+ <div class="mb-3">
85
+ <button type="submit" class="btn btn-primary">
86
+ Submit
87
+ <svg x-show="busy" class="form-loading" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg">
88
+ <defs>
89
+ <linearGradient x1="8.042%" y1="0%" x2="65.682%" y2="23.865%" id="a">
90
+ <stop stop-color="#fff" stop-opacity="0" offset="0%"/>
91
+ <stop stop-color="#fff" stop-opacity=".631" offset="63.146%"/>
92
+ <stop stop-color="#fff" offset="100%"/>
93
+ </linearGradient>
94
+ </defs>
95
+ <g fill="none" fill-rule="evenodd">
96
+ <g transform="translate(1 1)">
97
+ <path d="M36 18c0-9.94-8.06-18-18-18" id="Oval-2" stroke="url(#a)" stroke-width="2">
98
+ <animateTransform
99
+ attributeName="transform"
100
+ type="rotate"
101
+ from="0 18 18"
102
+ to="360 18 18"
103
+ dur="0.9s"
104
+ repeatCount="indefinite"/>
105
+ </path>
106
+ <circle fill="#fff" cx="36" cy="18" r="1">
107
+ <animateTransform
108
+ attributeName="transform"
109
+ type="rotate"
110
+ from="0 18 18"
111
+ to="360 18 18"
112
+ dur="0.9s"
113
+ repeatCount="indefinite"/>
114
+ </circle>
115
+ </g>
116
+ </g>
117
+ </svg>
118
+ </button>
119
+ </div>
120
+ </div>
121
+ </form>
122
+
123
+ <script src="dist/hapi.min.js" defer></script>
124
+ <script src="enquiry-form.js" defer></script>
125
+
126
+ </body>
127
+ </html>
package/index.js ADDED
@@ -0,0 +1,15 @@
1
+ import { form } from "./src/hapi";
2
+
3
+ let Hapi = {
4
+ form,
5
+ };
6
+
7
+ export default Hapi;
8
+ window.Hapi = Hapi;
9
+
10
+ import loadAlpineJsFile from "./src/alpineloader";
11
+ loadAlpineJsFile();
12
+
13
+
14
+
15
+
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "hapi-recaptcha-html",
3
+ "version": "1.0.0",
4
+ "description": "hapiform html js library with google recaptcha",
5
+ "main": "index.js",
6
+ "keywords": [
7
+ "hapiform"
8
+ ],
9
+ "author": "chenghuichao",
10
+ "license": "MIT",
11
+ "dependencies": {
12
+ "axios": "^1.4.0",
13
+ "esbuild": "^0.17.19"
14
+ },
15
+ "bundleDependencies": false,
16
+ "scripts": {
17
+ "build": "esbuild index.js --bundle --minify --outfile=./dist/hapi.min.js",
18
+ "watch": "esbuild index.js --watch --bundle --minify --outfile=./dist/hapi.min.js"
19
+ }
20
+ }
package/readme.md ADDED
@@ -0,0 +1,68 @@
1
+ # HAPI Form Plugin
2
+ Wrapper of Alpine JS plugin for HAPI Form, works on Laravel API endpoint.
3
+ ## CDN
4
+ ```html
5
+ <script src="https://unpkg.com/chenghuichao/hapi-recaptcha-html@latest/dist/hapi.min.js"></script>
6
+ ```
7
+
8
+ ## Usage
9
+ ```html
10
+
11
+ <script>
12
+ Hapi.form({
13
+ name: "",
14
+ endpoint: "",
15
+ redirectTo: "",
16
+ fileUpload: {
17
+ filepond: filepondObject,
18
+ el: '#files'
19
+ },
20
+ captchaId: null,
21
+ recaptchaTheme: 'light',
22
+ onSuccess(res) {
23
+ },
24
+ onFailed(err) {
25
+ }
26
+ });
27
+ </script>
28
+ ```
29
+
30
+ - name – The name of the instance, to be matched with `x-data="name"`.
31
+ - endpoint – The form endpoint URL generated from the backend.
32
+ - redirectTo – Location to be redirected after success. Eg: "/thank-you" or "https://example.com". (Optional)
33
+ - fileUpload
34
+ - filepond – Filepond object. (Filepond plugin required)
35
+ - el – Select `input` element if you're using normal upload.
36
+ - captchaId - Id of div element to render the google recaptcha, `null` means recaptcha is disabled.
37
+ - recaptchaTheme - `light` or `dark`.
38
+ - onSuccess() – On success event.
39
+ - onFailed() – On failed event.
40
+ - errors.recaptchaError - to display captcha verification errors.
41
+
42
+ ## Array data
43
+ ```js
44
+ Hapi.form({
45
+ fields: {
46
+ colors; [] // Example an empty array of colors
47
+ },
48
+ name: "",
49
+ endpoint: "",
50
+ });
51
+ ```
52
+
53
+ ## Alpine.js data
54
+ Sometimes you might need to set data for Alpine.js, I got your back.
55
+ ```js
56
+ Hapi.form({
57
+ ...
58
+ open: false,
59
+ });
60
+ ```
61
+ ## Events
62
+
63
+ ### Success Event
64
+ When submission is success, Hapi will emit `hapi:success` event.
65
+
66
+
67
+ ### Error Event
68
+ When submission has error, Hapi will emit `hapi:error` event.
@@ -0,0 +1,10 @@
1
+ export default function loadAlpineJsFile() {
2
+ // global js file, load one time
3
+ if (document.querySelectorAll(`script[src="//unpkg.com/alpinejs"]`).length === 0) {
4
+ var scriptEl = document.createElement('script');
5
+ scriptEl.setAttribute("src", "//unpkg.com/alpinejs");
6
+ scriptEl.setAttribute("type", "text/javascript");
7
+ scriptEl.setAttribute("defer", true);
8
+ document.body.appendChild(scriptEl);
9
+ }
10
+ }
package/src/hapi.js ADDED
@@ -0,0 +1,280 @@
1
+ "use strict";
2
+
3
+ import axios from "axios";
4
+ import AMCaptcha from './recaptcha';
5
+
6
+
7
+ let hapiOptions = {
8
+ config: {},
9
+ fields: {},
10
+ name: null,
11
+ endpoint: null,
12
+ redirectTo: null,
13
+ fileUpload: {
14
+ filepond: null,
15
+ el: null,
16
+ },
17
+ onSuccess(res) {
18
+ res;
19
+ },
20
+ onFailed(res) {
21
+ res;
22
+ },
23
+ amCaptcha: Object,
24
+ captchaId: null,
25
+ recaptchaTheme: 'light', // light, dark
26
+ widgetId: null,
27
+ };
28
+
29
+ async function form(options) {
30
+ let mergedOptions = Object.assign({}, hapiOptions, options);
31
+
32
+ await alpine(mergedOptions);
33
+ }
34
+
35
+ async function alpine(options) {
36
+ document.addEventListener("alpine:init", () => {
37
+ Alpine.data(options.name, () => ({
38
+ ...options,
39
+ errors: {},
40
+ busy: false,
41
+ async init() {
42
+ this.$watch("busy", (value) => {
43
+ let buttons = document.querySelectorAll('form button, form input[type="submit"], form input[type="button"]');
44
+
45
+ if (value) {
46
+ buttons.forEach((button) => {
47
+ button.disabled = true;
48
+ });
49
+ } else {
50
+ buttons.forEach((button) => {
51
+ button.disabled = false;
52
+ });
53
+ }
54
+ });
55
+
56
+ this.$init ? this.$init() : null;
57
+
58
+ if (this.captchaId) {
59
+ // find the rending element
60
+ let recaptcha_el = document.getElementById(this.captchaId);
61
+ if (recaptcha_el) {
62
+ this.amCaptcha = new AMCaptcha({
63
+ theme: this.recaptchaTheme,
64
+ render_element_or_id: recaptcha_el
65
+ });
66
+ this.widgetId = await this.amCaptcha.render();
67
+
68
+ } else {
69
+ throw "Can't find recaptcha rendering element.";
70
+ }
71
+ }
72
+ },
73
+ submit() {
74
+ // Set busy to true and reset error validations
75
+ this.busy = true;
76
+ this.errors = {};
77
+
78
+ // Get all form fields
79
+ let formData = new FormData();
80
+
81
+ let fieldNames = Object.keys(this.fields);
82
+
83
+ // Append all fields to formData
84
+ fieldNames.forEach((field, i) => {
85
+ if (typeof this.fields[field] === "object") {
86
+ this.fields[field].forEach((item, index) => {
87
+ formData.append(`${field}[${index}]`, item);
88
+ });
89
+ } else {
90
+ formData.append(field, this.fields[field]);
91
+ }
92
+ });
93
+
94
+ // Check if filepond is enabled
95
+ if (options.fileUpload.filepond) {
96
+ options.fileUpload.filepond.getFiles().forEach((file, i) => {
97
+ formData.append(`files[${i}]`, file.file, file.name);
98
+ });
99
+ }
100
+ // Check if normal file upload is enabled
101
+ else if (options.fileUpload.el) {
102
+ let inputElement = document.querySelector(options.fileUpload.el);
103
+
104
+ let fileList = inputElement.files;
105
+
106
+ for (let i = 0; i < fileList.length; i++) {
107
+ formData.append(`files[${i}]`, fileList[i], fileList[i].name);
108
+ }
109
+ }
110
+
111
+ // Append x_origin to formData
112
+ let currentUrl = new URL(window.top.location.href);
113
+
114
+ formData.append("x_origin", currentUrl.origin + currentUrl.pathname);
115
+
116
+ const defaultConfig = {
117
+ method: "POST",
118
+ url: getEndpoint(options.endpoint),
119
+ data: formData,
120
+ };
121
+
122
+ const config = Object.assign({}, defaultConfig, options.config);
123
+
124
+ if (this.captchaId) {
125
+
126
+ verifyRecaptcha(this.amCaptcha)
127
+ .then(() => {
128
+ // do submission
129
+ axios(config)
130
+ .then((res) => {
131
+ if (options.redirectTo) {
132
+ window.location.href = options.redirectTo;
133
+ }
134
+
135
+ // Remove files from filepond
136
+ if (options.fileUpload.filepond) {
137
+ options.fileUpload.filepond.removeFiles();
138
+ }
139
+
140
+ clearFiles();
141
+ this.resetFields();
142
+ options.onSuccess(res);
143
+ successEvent();
144
+ })
145
+ .catch((err) => {
146
+ this.errors = err.response.data.errors;
147
+ this.busy = false;
148
+ options.onFailed(err.response);
149
+ errorEvent();
150
+ if (this.captchaId) this.amCaptcha.reset(this.widgetId);
151
+ });
152
+
153
+ })
154
+ .catch((error) => {
155
+ this.errors = error;
156
+ // failed method
157
+ options.onFailed(error);
158
+ this.busy = false;
159
+ })
160
+ .finally(() => {
161
+ this.amCaptcha.reset(this.widgetId);
162
+ });
163
+ }
164
+ },
165
+ resetFields() {
166
+ this.errors = {};
167
+ this.fields = options.fields;
168
+ this.busy = false;
169
+ if (this.captchaId) this.amCaptcha.reset(this.widgetId);
170
+ },
171
+ }));
172
+
173
+ // Display redirect path
174
+ if (hapiOptions.redirectTo && hapiOptions.endpoint) {
175
+ let endpoint = new URL(hapiOptions.endpoint);
176
+
177
+ if (endpoint.host === "hapiform.sg") {
178
+ console.log("🚀 " + window.location.origin + hapiOptions.redirectTo);
179
+ }
180
+ }
181
+
182
+ // Display the endpoint
183
+ if (hapiOptions.endpoint) {
184
+ let endpoint = new URL(hapiOptions.endpoint);
185
+ let uuid = hapiOptions.endpoint.match(/[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/);
186
+
187
+ if (endpoint.host === "hapiform.sg") {
188
+ console.log(`🚀 ${endpoint.origin}/${uuid}`);
189
+ }
190
+ }
191
+ });
192
+ }
193
+
194
+ async function verifyRecaptcha(captcha) {
195
+ // 1. get response of recaptcha
196
+ const token = captcha.fetchResponse(this.widgetId);
197
+ if (token.length === 0) {
198
+ throw {recaptchaError:"You can't leave Captcha Code empty"};
199
+ }
200
+ // 2. verify recaptcha
201
+ return await captcha.verifyRecaptcha(token)
202
+ .then((data) => {
203
+ if (data.success === false) {
204
+ throw {recaptchaError:"captcha invalid: timeout or duplicate."};
205
+ }
206
+ });
207
+ }
208
+
209
+ // function onSubmission(config, options) {
210
+ // axios(config)
211
+ // .then((res) => {
212
+ // if (options.redirectTo) {
213
+ // window.location.href = options.redirectTo;
214
+ // }
215
+ //
216
+ // // Remove files from filepond
217
+ // if (options.fileUpload.filepond) {
218
+ // options.fileUpload.filepond.removeFiles();
219
+ // }
220
+ //
221
+ // clearFiles();
222
+ // this.resetFields();
223
+ // options.onSuccess(res);
224
+ // successEvent();
225
+ // })
226
+ // .catch((err) => {
227
+ // this.errors = err.response.data.errors;
228
+ // this.busy = false;
229
+ // options.onFailed(err.response);
230
+ // errorEvent();
231
+ // if (this.captchaId) this.amCaptcha.reset(this.widgetId);
232
+ // });
233
+ // }
234
+
235
+ function clearFiles() {
236
+ clearFilepondFiles();
237
+ clearUploads();
238
+ }
239
+
240
+ function clearFilepondFiles() {
241
+ try {
242
+ hapiOptions.fileUpload.filepond.removeFiles();
243
+ } catch (e) {
244
+ }
245
+ }
246
+
247
+ function clearUploads() {
248
+ try {
249
+ let inputElement = document.querySelector(hapiOptions.fileUpload.el);
250
+ inputElement.value = "";
251
+ } catch (e) {
252
+ }
253
+ }
254
+
255
+ function successEvent() {
256
+ dispatchEvent("hapi:success");
257
+ }
258
+
259
+ function errorEvent() {
260
+ dispatchEvent("hapi:error");
261
+ }
262
+
263
+ function dispatchEvent(eventName) {
264
+ const event = new Event(eventName);
265
+
266
+ document.dispatchEvent(event);
267
+ }
268
+
269
+ function getEndpoint(endpoint) {
270
+ let url = new URL(endpoint);
271
+
272
+ if (window.location.hostname === "localhost" || window.location.hostname === "127.0.0.1") {
273
+ url.searchParams.set("test", '1');
274
+ console.log('testing mode!')
275
+ }
276
+
277
+ return url.href;
278
+ }
279
+
280
+ export {form};
@@ -0,0 +1,84 @@
1
+ export default class AMCaptcha {
2
+ constructor({theme = 'light', render_element_or_id = 'recaptcha-el'}) {
3
+ //
4
+ this.gl_api_url = "https://www.google.com/recaptcha/api.js?onload=onloadCallback&render=explicit";
5
+ this.captcha_sitekey = "6LeRUzsjAAAAANUHNEY6VkUXmMo_wlrDK5SUoFUV";
6
+ this.verify_url = "https://internalapi.activamedia.com.sg/v1/recaptcha/verify";
7
+ this.theme = theme;
8
+ this.render_element_or_id = render_element_or_id;
9
+
10
+ this.defineOnloadCallBack();
11
+ this.loadJsFile();
12
+ }
13
+
14
+ defineOnloadCallBack() {
15
+ window.onloadCallback = () => {
16
+ console.log('api loaded');
17
+ }
18
+ }
19
+
20
+ /**
21
+ * insert and load the google api js file
22
+ */
23
+ loadJsFile() {
24
+ // global js file, load one time
25
+ if (document.querySelectorAll(`script[src="${this.gl_api_url}"]`).length === 0) {
26
+ var scriptEl = document.createElement('script');
27
+ scriptEl.setAttribute("src", this.gl_api_url);
28
+ scriptEl.setAttribute("type", "text/javascript");
29
+ scriptEl.setAttribute("async", true);
30
+ scriptEl.setAttribute("defer", true);
31
+ document.body.appendChild(scriptEl);
32
+ }
33
+ }
34
+
35
+ sleep(ms) {
36
+ return new Promise(resolve => setTimeout(resolve, ms));
37
+ };
38
+
39
+ /**
40
+ * rendering google captcha
41
+ */
42
+ async render() {
43
+ let widgetId = '';
44
+ while (true) {
45
+ await this.sleep(200);
46
+ if (typeof grecaptcha !== 'undefined' && grecaptcha !== undefined
47
+ && typeof grecaptcha.render === "function") {
48
+ widgetId = grecaptcha.render(
49
+ this.render_element_or_id,
50
+ {
51
+ sitekey: this.captcha_sitekey,
52
+ theme: this.theme
53
+ });
54
+ break;
55
+ }
56
+ console.info("checking grecaptcha undefined");
57
+ }
58
+
59
+ return widgetId
60
+ }
61
+
62
+ /**
63
+ * reset google captcha
64
+ */
65
+ reset(widgetId) {
66
+ grecaptcha.reset(widgetId);
67
+ }
68
+
69
+ fetchResponse(widgetId) {
70
+ try {
71
+ return grecaptcha.getResponse(widgetId);
72
+ } catch (e) {console.error(e);}
73
+ }
74
+
75
+ async verifyRecaptcha(token) {
76
+ return await fetch(this.verify_url, {
77
+ method: 'post', body: JSON.stringify({"token": token}),
78
+ headers: {'Accept': 'application/json', 'Content-Type': 'application/json'},
79
+ }).then((response) => response.json());
80
+ }
81
+ }
82
+
83
+
84
+