@rilaykit/workflow 2.0.0 → 2.0.1
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.
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var core=require('@rilaykit/core'),forms=require('@rilaykit/forms'),q=require('@noble/ed25519'),react=require('react'),jsxRuntime=require('react/jsx-runtime');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var q__namespace=/*#__PURE__*/_interopNamespace(q);var j=1751361139160,ee="8fdb6a454550326d331c3b3d1d1f8c707a371bdb6c7ea72a0a1e4ea6f1822620",f=class f{static async setLicenseKey(e){f.licenseKey=e||"",f.licenseKey?f.licenseResult=await f.validateLicense():f.licenseResult={valid:false,error:"MISSING"},f.isInitialized=true;}static async validateLicense(){if(!f.licenseKey)return {valid:false,error:"MISSING"};try{if(!f.licenseKey.startsWith("ril_"))return {valid:!1,error:"FORMAT_INVALID"};let e=f.licenseKey.slice(4),t=f.base64ToString(e).split(".");if(t.length!==3)return {valid:!1,error:"FORMAT_INVALID"};let[r,i,l]=t,n=`${r}.${i}`,d=new TextEncoder().encode(n),u=l.match(/.{2}/g);if(!u)return {valid:!1,error:"INVALID"};let S=new Uint8Array(u.map(g=>Number.parseInt(g,16))),y=f.hexToBytes(ee);if(!await q__namespace.verify(S,d,y))return {valid:!1,error:"SIGNATURE_INVALID"};let w=f.base64ToString(i.replace(/-/g,"+").replace(/_/g,"/")),h=JSON.parse(w),k=Math.floor(Date.now()/1e3);return h.e<k?{valid:!1,error:"EXPIRED",data:f.decompressPayload(h)}:j>h.e*1e3?{valid:!1,error:"EXPIRED",data:f.decompressPayload(h)}:h.p===void 0||!h.c||!h.i||!h.e||!h.t?{valid:!1,error:"INVALID"}:{valid:!0,data:f.decompressPayload(h)}}catch{return {valid:false,error:"INVALID"}}}static decompressPayload(e){return {plan:{0:"ARCHITECT",1:"FOUNDRY"}[e.p]||"ARCHITECT",company:e.c,customerId:e.i.toString(),expiry:e.e*1e3,iat:e.t*1e3}}static hexToBytes(e){let o=new Uint8Array(e.length/2);for(let t=0;t<e.length;t+=2)o[t/2]=Number.parseInt(e.substring(t,t+2),16);return o}static base64ToString(e){if(typeof atob<"u")return atob(e);if(typeof Buffer<"u")return Buffer.from(e,"base64").toString();let o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t="",r=0,i=e.replace(/[^A-Za-z0-9+/]/g,"");for(;r<i.length;){let l=o.indexOf(i.charAt(r++)),n=o.indexOf(i.charAt(r++)),d=o.indexOf(i.charAt(r++)),u=o.indexOf(i.charAt(r++)),S=l<<18|n<<12|d<<6|u;t+=String.fromCharCode(S>>16&255),d!==64&&(t+=String.fromCharCode(S>>8&255)),u!==64&&(t+=String.fromCharCode(S&255));}return t}static getLicenseResult(){return f.isInitialized?f.licenseResult?f.licenseResult:{valid:false,error:"MISSING"}:{valid:false,error:"MISSING"}}static shouldDisplayWatermark(){return typeof window>"u"?false:!f.getLicenseResult().valid}static getWatermarkMessage(){let e=f.getLicenseResult();return {MISSING:"Rilay Workflow - For Trial Use Only",EXPIRED:"Rilay Workflow - License Expired",INVALID:"Rilay Workflow - Invalid License",FORMAT_INVALID:"Rilay Workflow - Invalid License Format",SIGNATURE_INVALID:"Rilay Workflow - Invalid License Signature"}[e.error||"MISSING"]||""}static logLicenseStatus(){let e=f.getLicenseResult();if(e.valid)return;let t={MISSING:"\u{1F527} Rilay Workflow - Trial Mode. Purchase a license at https://rilay.io/pricing",EXPIRED:"\u26A0\uFE0F Rilay Workflow - License Expired. Please renew your license.",INVALID:"\u274C Rilay Workflow - Invalid License. Please check your license key.",FORMAT_INVALID:"\u274C Rilay Workflow - Invalid License Format. Please check your license key.",SIGNATURE_INVALID:"\u274C Rilay Workflow - Invalid License Signature. Please check your license key."}[e.error||"MISSING"];console.warn(`%c${t}`,"color: #f59e0b; font-weight: bold;");}static async getLicenseInfo(){let e=f.getLicenseResult();return !e.valid||!e.data?{}:{plan:e.data.plan,company:e.data.company,expiryDate:new Date(e.data.expiry).toLocaleDateString()}}};f.licenseKey="",f.licenseResult=null,f.isInitialized=false;var x=f;var D=class a{constructor(e,o,t,r){this.steps=[];this.navigation={allowBackNavigation:true};this.plugins=[];this.config=e,this.workflowId=o,this.workflowName=t,this.workflowDescription=r,x.logLicenseStatus();}static create(e,o,t,r){return new a(e,o,t,r)}createStepFromDefinition(e){return {id:e.id,title:e.title,description:e.description,formConfig:e.formConfig instanceof forms.form?e.formConfig.build():e.formConfig,allowSkip:e.allowSkip||false,requiredToComplete:e.requiredToComplete!==false,hooks:e.hooks,permissions:e.permissions,isDynamic:!!e.dynamicConfig,dynamicConfig:e.dynamicConfig,renderer:e.renderer}}addStep(e){let o=this.createStepFromDefinition(e);return this.steps.push(o),this}addDynamicStep(e){return this.addStep(e)}addSteps(e){for(let o of e)this.addStep(o);return this}setNavigation(e){return this.navigation={...this.navigation,...e},this}enableBackNavigation(e=true){return this.navigation={...this.navigation,allowBackNavigation:e},this}enableStepSkipping(e=true){return this.navigation={...this.navigation,allowStepSkipping:e},this}setPersistence(e){return this.persistence=e,this}setAnalytics(e){return this.analytics=e,this}setCompletion(e){return this.completion=e,this}use(e){this.validatePluginDependencies(e),this.plugins.push(e);try{e.install(this);}catch(o){throw new Error(`Failed to install plugin "${e.name}": ${o instanceof Error?o.message:String(o)}`)}return this}validatePluginDependencies(e){if(!e.dependencies)return;let o=e.dependencies.filter(t=>!this.plugins.some(r=>r.name===t));if(o.length>0)throw new Error(`Plugin "${e.name}" requires missing dependencies: ${o.join(", ")}`)}removePlugin(e){return this.plugins=this.plugins.filter(o=>o.name!==e),this}updateStep(e,o){let t=this.steps.findIndex(r=>r.id===e);if(t===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[t]={...this.steps[t],...o},this}removeStep(e){return this.steps=this.steps.filter(o=>o.id!==e),this}getStep(e){return this.steps.find(o=>o.id===e)}getSteps(){return [...this.steps]}clearSteps(){return this.steps=[],this}clone(e,o){let t=new a(this.config,e||`${this.workflowId}-clone`,o||`${this.workflowName} (Copy)`,this.workflowDescription);return t.steps=this.steps.map(r=>({...r})),t.navigation={...this.navigation},t.persistence=this.persistence?{...this.persistence}:void 0,t.completion=this.completion?{...this.completion}:void 0,t.analytics=this.analytics?{...this.analytics}:void 0,t.plugins=[...this.plugins],t}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let o=this.steps.map(r=>r.id),t=o.filter((r,i)=>o.indexOf(r)!==i);t.length>0&&e.push(`Duplicate step IDs: ${t.join(", ")}`);for(let r of this.plugins)if(r.dependencies){let i=r.dependencies.filter(l=>!this.plugins.some(n=>n.name===l));i.length>0&&e.push(`Plugin "${r.name}" requires missing dependencies: ${i.join(", ")}`);}return e}getStats(){return {totalSteps:this.steps.length,dynamicSteps:this.steps.filter(e=>e.isDynamic).length,pluginsInstalled:this.plugins.length,estimatedFields:this.steps.reduce((e,o)=>e+o.formConfig.allFields.length,0),hasPersistence:!!this.persistence,hasAnalytics:!!this.analytics,allowBackNavigation:this.navigation.allowBackNavigation!==false}}build(){let e=this.validate();if(e.length>0)throw new Error(`Workflow validation failed: ${e.join(", ")}`);return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:[...this.steps],navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,plugins:[...this.plugins],renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,plugins:this.plugins.map(e=>({name:e.name,version:e.version,dependencies:e.dependencies}))}}fromJSON(e){return e.id&&(this.workflowId=e.id),e.name&&(this.workflowName=e.name),e.description&&(this.workflowDescription=e.description),e.steps&&(this.steps=e.steps),e.navigation&&(this.navigation=e.navigation),e.persistence&&(this.persistence=e.persistence),e.completion&&(this.completion=e.completion),e.analytics&&(this.analytics=e.analytics),this}};function oe(a,e,o,t){return D.create(a,e,o,t)}core.ril.prototype.createFlow=function(a,e,o){return D.create(this,a,e,o)};function le(a,e){switch(e.type){case "SET_CURRENT_STEP":return {...a,currentStepIndex:e.stepIndex,stepData:a.allData[a.resolvedSteps[e.stepIndex]?.id]||{}};case "SET_STEP_DATA":{let o=a.resolvedSteps[a.currentStepIndex]?.id;return {...a,stepData:e.data,allData:{...a.allData,[o]:e.data}}}case "SET_ALL_DATA":return {...a,allData:e.data};case "SET_FIELD_VALUE":{let o=a.resolvedSteps[a.currentStepIndex]?.id,t={...a.stepData,[e.fieldId]:e.value};return {...a,stepData:t,allData:{...a.allData,[o]:t}}}case "SET_ERROR":return {...a,errors:{...a.errors,[e.fieldId]:e.errors}};case "CLEAR_ERROR":{let o={...a.errors};return delete o[e.fieldId],{...a,errors:o}}case "MARK_TOUCHED":return {...a,touched:new Set([...a.touched,e.fieldId])};case "SET_VALIDATING":{let o=new Set(a.isValidating);return e.isValidating?o.add(e.fieldId):o.delete(e.fieldId),{...a,isValidating:o}}case "SET_SUBMITTING":return {...a,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...a,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...a,visitedSteps:new Set([...a.visitedSteps,a.resolvedSteps[e.stepIndex]?.id])};case "SET_PERSISTED_DATA":return {...a,persistedData:e.data};case "SET_RESOLVED_STEPS":return {...a,resolvedSteps:e.steps};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},errors:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:a.resolvedSteps};default:return a}}var Y=react.createContext(null);function L({children:a,workflowConfig:e,defaultValues:o={},onStepChange:t,onWorkflowComplete:r,className:i,user:l}){let[n,d]=react.useReducer(le,{currentStepIndex:0,allData:o,stepData:{},errors:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:e.steps}),u=react.useRef(null),S=react.useRef(Date.now()),y=react.useRef(new Map),C=react.useRef(false),w=react.useRef(null),h=react.useRef(t),k=react.useRef(r);h.current=t,k.current=r;let s=react.useMemo(()=>e,[e]),g=react.useMemo(()=>({workflowId:s.id,currentStepIndex:n.currentStepIndex,totalSteps:n.resolvedSteps.length,allData:n.allData,stepData:n.stepData,isFirstStep:n.currentStepIndex===0,isLastStep:n.currentStepIndex===n.resolvedSteps.length-1,visitedSteps:n.visitedSteps,user:l}),[s.id,n.currentStepIndex,n.resolvedSteps.length,n.allData,n.stepData,n.visitedSteps,l]);react.useEffect(()=>{(async()=>{let p=[];for(let m of s.steps)if(m.isDynamic&&m.dynamicConfig)try{let V=await m.dynamicConfig.resolver(n.allData,g);p.push(...V);}catch(V){console.error(`Failed to resolve dynamic step "${m.id}":`,V),p.push({...m,isDynamic:false});}else p.push(m);d({type:"SET_RESOLVED_STEPS",steps:p});})();},[s.steps,n.allData,g]),react.useEffect(()=>{s.analytics?.onWorkflowStart&&!C.current&&(C.current=true,s.analytics.onWorkflowStart(s.id,g));},[s.id,s.analytics,g]),react.useEffect(()=>{let c=n.resolvedSteps[n.currentStepIndex];if(c&&w.current!==c.id){if(w.current&&s.analytics?.onStepComplete){let p=y.current.get(w.current);p&&s.analytics.onStepComplete(w.current,Date.now()-p,n.stepData,g);}w.current=c.id,y.current.set(c.id,Date.now()),s.analytics?.onStepStart&&s.analytics.onStepStart(c.id,Date.now(),g);}},[n.currentStepIndex,n.resolvedSteps,s.analytics,g]);let E=react.useCallback(async()=>{if(s.persistence)try{let c={workflowId:s.id,currentStepIndex:n.currentStepIndex,allData:n.allData,metadata:{timestamp:Date.now(),version:"1.0.0",userId:l?.id,sessionId:crypto.randomUUID()}},p=s.persistence.key||`workflow-${s.id}`;await s.persistence.adapter.save(p,c),s.persistence.onSave&&await s.persistence.onSave(c);}catch(c){console.error("Failed to save workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"save");}},[s,n.currentStepIndex,n.allData,l]),O=react.useCallback(async()=>{if(s.persistence)try{let c=s.persistence.key||`workflow-${s.id}`,p=await s.persistence.adapter.load(c);p&&p.workflowId===s.id&&(d({type:"SET_ALL_DATA",data:p.allData}),d({type:"SET_CURRENT_STEP",stepIndex:p.currentStepIndex}),d({type:"SET_PERSISTED_DATA",data:p}),s.persistence.onLoad&&await s.persistence.onLoad(p));}catch(c){console.error("Failed to load workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"load");}},[s]),A=react.useCallback(async()=>{if(s.persistence)try{let c=s.persistence.key||`workflow-${s.id}`;await s.persistence.adapter.remove(c);}catch(c){console.error("Failed to clear workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"remove");}},[s]);react.useEffect(()=>{s.persistence&&(async()=>{try{let p=s.persistence.key||`workflow-${s.id}`,m=await s.persistence.adapter.load(p);m&&m.workflowId===s.id&&(d({type:"SET_ALL_DATA",data:m.allData}),d({type:"SET_CURRENT_STEP",stepIndex:m.currentStepIndex}),d({type:"SET_PERSISTED_DATA",data:m}),s.persistence.onLoad&&await s.persistence.onLoad(m),console.log("Workflow data loaded from persistence:",m));}catch(p){console.error("Failed to load workflow draft on mount:",p),s.persistence.onError&&await s.persistence.onError(p,"load");}})();},[s.id]),react.useEffect(()=>{if(s.persistence?.saveOnStepChange)return u.current&&clearTimeout(u.current),u.current=setTimeout(()=>{E();},s.persistence.debounceMs||1e3),()=>{u.current&&clearTimeout(u.current);}},[n.allData,E,s.persistence]);let R=react.useMemo(()=>n.resolvedSteps[n.currentStepIndex],[n.resolvedSteps,n.currentStepIndex]),M=react.useMemo(()=>R?.formConfig,[R]),P=react.useCallback(async c=>{if(c<0||c>=n.resolvedSteps.length)return false;let p=n.resolvedSteps[c];if(p.permissions)try{if(!(p.permissions.customGuard?await p.permissions.customGuard(l,g):!0))return console.warn(`Access denied to step "${p.id}"`),!1}catch(m){return console.error(`Permission check failed for step "${p.id}":`,m),false}if(p.hooks?.onBeforeEnter)try{await p.hooks.onBeforeEnter(n.stepData,n.allData,g);}catch(m){return console.error(`onBeforeEnter hook failed for step "${p.id}":`,m),s.analytics?.onError&&s.analytics.onError(m,g),false}d({type:"SET_TRANSITIONING",isTransitioning:true});try{return h.current&&h.current(n.currentStepIndex,c,g),d({type:"SET_CURRENT_STEP",stepIndex:c}),d({type:"MARK_STEP_VISITED",stepIndex:c}),!0}catch(m){return console.error("Step transition failed:",m),s.analytics?.onError&&s.analytics.onError(m,g),false}finally{d({type:"SET_TRANSITIONING",isTransitioning:false});}},[n.resolvedSteps,n.currentStepIndex,n.stepData,n.allData,l,g,s.analytics]),N=react.useCallback((c,p)=>{d({type:"SET_FIELD_VALUE",fieldId:c,value:p});},[]),$=react.useCallback(c=>{d({type:"SET_STEP_DATA",data:c});},[]),U=react.useCallback(async()=>R?{isValid:true,errors:[]}:{isValid:true,errors:[]},[R]),_=react.useCallback(async()=>P(n.currentStepIndex+1),[P,n.currentStepIndex]),G=react.useCallback(async()=>s.navigation?.allowBackNavigation?P(n.currentStepIndex-1):false,[s.navigation,n.currentStepIndex,P]),K=react.useCallback(async()=>!R?.allowSkip||!s.navigation?.allowStepSkipping?false:(s.analytics?.onStepSkip&&s.analytics.onStepSkip(R.id,"user_skip",g),P(n.currentStepIndex+1)),[R,s.navigation,s.analytics,g,P,n.currentStepIndex]),H=react.useCallback(async()=>{d({type:"SET_SUBMITTING",isSubmitting:true});try{if(k.current&&await k.current(n.allData),await A(),s.analytics?.onWorkflowComplete){let c=Date.now()-S.current;s.analytics.onWorkflowComplete(s.id,c,n.allData);}}catch(c){throw console.error("Workflow submission failed:",c),s.analytics?.onError&&s.analytics.onError(c,g),c}finally{d({type:"SET_SUBMITTING",isSubmitting:false});}},[n.allData,k,A,s.analytics,g]),z=react.useCallback(()=>{d({type:"RESET_WORKFLOW"});},[]),Z=react.useMemo(()=>({workflowState:n,workflowConfig:s,currentStep:R,context:g,formConfig:M,goToStep:P,goNext:_,goPrevious:G,skipStep:K,setValue:N,setStepData:$,validateCurrentStep:U,submitWorkflow:H,resetWorkflow:z,saveDraft:E,loadDraft:O,clearDraft:A}),[n,s,R,g,M,P,_,G,K,N,$,U,H,z,E,O,A]),Q=react.useCallback(async()=>{await _();},[_]);return jsxRuntime.jsx(Y.Provider,{value:Z,children:jsxRuntime.jsx(forms.FormProvider,{formConfig:R?.formConfig,defaultValues:n?.allData[R?.id]||{},onFieldChange:N,"data-workflow-id":s.id,className:i,onSubmit:Q,children:a},R?.id)})}function I(){let a=react.useContext(Y);if(!a)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return a}function pe({children:a,workflowConfig:e,...o}){let[t,r]=react.useState(false),i=x.shouldDisplayWatermark(),l=x.getWatermarkMessage(),n=e instanceof D?e.build():e;return react.useEffect(()=>{r(true);},[]),jsxRuntime.jsxs("div",{style:{position:"relative"},children:[jsxRuntime.jsx(L,{...o,workflowConfig:n,children:a}),t&&i&&jsxRuntime.jsx("div",{style:{position:"absolute",top:"10px",right:"10px",background:"rgba(0, 0, 0, 0.8)",color:"white",padding:"4px 8px",borderRadius:"4px",fontSize:"12px",fontFamily:"monospace",zIndex:1e3,pointerEvents:"none",opacity:.7},children:l})]})}function ge(){let{currentStep:a}=I();if(!a)return null;let{formConfig:e,renderer:o}=a;return e?o?o(a):jsxRuntime.jsx(forms.FormBody,{}):null}function Se({className:a,children:e,renderAs:o}){let{context:t,submitWorkflow:r,workflowState:i,workflowConfig:l,currentStep:n}=I(),{submit:d,formState:u}=forms.useFormContext(),S=!i.isTransitioning&&!i.isSubmitting,y=async E=>{E?.preventDefault(),S&&await d(E);},C=async E=>{E?.preventDefault(),S&&await r();},w={isLastStep:t.isLastStep,canGoNext:S,isSubmitting:i.isSubmitting,onNext:y,onSubmit:C,className:a,currentStep:n,stepData:u.values||{},allData:t.allData,context:t};if(o==="children"||o===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(w)}let k=l.renderConfig?.nextButtonRenderer;if(!k)throw new Error(`No nextButtonRenderer configured for workflow "${l.id}". Please configure a nextButtonRenderer using config.setWorkflowNextButtonRenderer() or config.setWorkflowRenderConfig().`);let s=core.resolveRendererChildren(e,w),g={...w,children:s};return k(g)}function ve({className:a,children:e,renderAs:o}){let{context:t,goPrevious:r,workflowState:i,workflowConfig:l,currentStep:n}=I(),{formState:d}=forms.useFormContext(),u=t.currentStepIndex>0&&l.navigation?.allowBackNavigation!==false&&!i.isTransitioning&&!i.isSubmitting;if(l.navigation?.allowBackNavigation===false)throw new Error(`WorkflowPreviousButton is rendered but allowBackNavigation is disabled in workflow "${l.id}". Either enable back navigation or remove the WorkflowPreviousButton component.`);let y={canGoPrevious:u,onPrevious:async s=>{s?.preventDefault(),u&&await r();},className:a,currentStep:n,stepData:d.values||{},allData:t.allData,context:t};if(o==="children"||o===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(y)}let w=l.renderConfig?.previousButtonRenderer;if(!w)throw new Error(`No previousButtonRenderer configured for workflow "${l.id}". Please configure a previousButtonRenderer using config.setWorkflowPreviousButtonRenderer() or config.setWorkflowRenderConfig().`);let h=core.resolveRendererChildren(e,y),k={...y,children:h};return w(k)}function Ie({className:a,children:e,renderAs:o}){let{currentStep:t,skipStep:r,workflowState:i,workflowConfig:l,context:n}=I(),{formState:d}=forms.useFormContext(),u=!!t?.allowSkip&&l.navigation?.allowStepSkipping!==false&&!i.isTransitioning&&!i.isSubmitting,y={canSkip:u,onSkip:async s=>{s?.preventDefault(),u&&await r();},className:a,currentStep:t,stepData:d.values||{},allData:n.allData,context:n};if(o==="children"||o===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(y)}let w=l.renderConfig?.skipButtonRenderer;if(!w)throw new Error(`No skipButtonRenderer configured for workflow "${l.id}". Please configure a skipButtonRenderer using config.setWorkflowSkipButtonRenderer() or config.setWorkflowRenderConfig().`);let h=core.resolveRendererChildren(e,y),k={...y,children:h};return w(k)}function Ee({onStepClick:a,className:e,children:o,renderAs:t}){let{workflowConfig:r,workflowState:i,goToStep:l}=I(),n=C=>{a?a(C):l(C);},d={steps:i.resolvedSteps,currentStepIndex:i.currentStepIndex,visitedSteps:i.visitedSteps,onStepClick:n,className:e};if(t==="children"||t===true){if(typeof o!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return o(d)}let S=r.renderConfig?.stepperRenderer;if(!S)throw new Error(`No stepperRenderer configured for workflow "${r.id}". Please configure a stepperRenderer using config.setStepperRenderer() or config.setWorkflowRenderConfig().`);return S(d)}var B=class{constructor(e){this.name="analytics";this.version="1.0.0";this.performanceData=new Map;this.config=e;}install(e){let o={onWorkflowStart:(t,r)=>{this.track("workflow_start",{workflow_id:t,total_steps:r.totalSteps,...this.getContextData(r)}),this.config.enablePerformanceTracking&&this.performanceData.set(`workflow_${t}`,Date.now());},onWorkflowComplete:(t,r,i)=>{this.track("workflow_complete",{workflow_id:t,duration_ms:r,form_data_keys:this.config.includeFormData?Object.keys(i):void 0,...this.config.includeFormData?{form_data:i}:{}});},onWorkflowAbandon:(t,r,i)=>{this.track("workflow_abandon",{workflow_id:t,abandoned_at_step:r,completion_percentage:this.calculateCompletionPercentage(i)});},onStepStart:(t,r,i)=>{this.track("step_start",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,...this.getContextData(i)}),this.config.enablePerformanceTracking&&this.performanceData.set(`step_${t}`,r);},onStepComplete:(t,r,i,l)=>{this.track("step_complete",{step_id:t,step_index:l.currentStepIndex,workflow_id:l.workflowId,duration_ms:r,field_count:Object.keys(i).length,...this.getContextData(l)});},onStepSkip:(t,r,i)=>{this.track("step_skip",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,skip_reason:r,...this.getContextData(i)});},onValidationError:(t,r,i)=>{this.track("validation_error",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,error_count:r.length,error_codes:r.map(l=>l.code),...this.getContextData(i)});},onError:(t,r)=>{this.track("workflow_error",{workflow_id:r.workflowId,step_id:r.currentStepIndex,error_message:t.message,error_name:t.name,...this.getContextData(r)});}};e.setAnalytics(o);}track(e,o){let t=this.config.eventMapping?.[e]||e,r={...o,timestamp:Date.now(),plugin_version:this.version};for(let[i,l]of Object.entries(this.config.providers))switch(i){case "googleAnalytics":this.trackGoogleAnalytics(t,r,l);break;case "mixpanel":this.trackMixpanel(t,r);break;case "amplitude":this.trackAmplitude(t,r);break;case "custom":this.trackCustom(t,r,l);break}}trackGoogleAnalytics(e,o,t){typeof window<"u"&&window.gtag&&window.gtag("event",e,{...o,custom_map:t.customDimensions});}trackMixpanel(e,o){typeof window<"u"&&window.mixpanel&&window.mixpanel.track(e,o);}trackAmplitude(e,o){typeof window<"u"&&window.amplitude&&window.amplitude.getInstance().logEvent(e,o);}async trackCustom(e,o,t){try{await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify({event:e,properties:o})});}catch(r){console.error("Custom analytics tracking failed:",r);}}getContextData(e){return this.config.includeUserContext?{user_id:e.user?.id,is_first_step:e.isFirstStep,is_last_step:e.isLastStep,visited_steps_count:e.visitedSteps.size,browser_info:typeof window<"u"?{user_agent:navigator.userAgent,language:navigator.language,platform:navigator.platform}:void 0}:{}}calculateCompletionPercentage(e){let o=Object.keys(e).length,t=Object.values(e).filter(r=>r!=null&&r!=="").length;return o>0?t/o*100:0}};var F=class{constructor(e){this.name="validation";this.version="1.0.0";this.dependencies=[];this.debounceTimers=new Map;this.config=e;}install(e){let o=e.getSteps();for(let t of o){let r=t.hooks||{};e.updateStep(t.id,{hooks:{...r,onValidate:async(i,l)=>{let n=await this.validateStep(i,l);return this.config.onValidationComplete&&this.config.onValidationComplete(n,l),n}}});}}async validateStep(e,o){let t=[];try{if(this.config.schema){let i=await this.validateWithSchema(e,o);t.push(...i.errors);}let r=await this.validateWithRules(e,o);if(t.push(...r.errors),this.config.crossFieldValidation){let i=await this.validateCrossField(o.allData,o);t.push(...i.errors);}if(this.config.asyncRules){let i=await this.validateAsync(e,o);t.push(...i.errors);}return {isValid:t.length===0,errors:t}}catch(r){return {isValid:false,errors:[{code:"VALIDATION_ERROR",message:`Validation failed: ${r instanceof Error?r.message:String(r)}`}]}}}async validateWithSchema(e,o){if(!this.config.schema?.schema)return {isValid:true,errors:[]};try{switch(this.config.schema.type){case "zod":{let t=this.config.schema.schema.safeParse(e);if(!t.success)return {isValid:!1,errors:t.error.errors.map(r=>({code:r.code,message:r.message,path:r.path}))};break}case "yup":try{await this.config.schema.schema.validate(e,{abortEarly:!1});}catch(t){return {isValid:!1,errors:t.inner?.map(r=>({code:"YUP_VALIDATION_ERROR",message:r.message,path:r.path?[r.path]:void 0}))||[{code:"YUP_VALIDATION_ERROR",message:t.message}]}}break;case "custom":{let t=await this.config.schema.schema(e,o);if(!t.isValid)return t;break}}return {isValid:!0,errors:[]}}catch(t){return {isValid:false,errors:[{code:"SCHEMA_VALIDATION_ERROR",message:`Schema validation failed: ${t instanceof Error?t.message:String(t)}`}]}}}async validateWithRules(e,o){let t=[];if(this.config.rules.required)for(let r of this.config.rules.required)(!e[r]||typeof e[r]=="string"&&e[r].trim()==="")&&t.push({code:"REQUIRED",message:`${r} is required`,path:[r]});if(this.config.rules.email){let r=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;for(let i of this.config.rules.email)e[i]&&!r.test(e[i])&&t.push({code:"INVALID_EMAIL",message:`${i} must be a valid email address`,path:[i]});}if(this.config.rules.phone){let r=/^[\+]?[1-9][\d]{0,15}$/;for(let i of this.config.rules.phone)e[i]&&!r.test(e[i].replace(/\s/g,""))&&t.push({code:"INVALID_PHONE",message:`${i} must be a valid phone number`,path:[i]});}if(this.config.rules.minLength)for(let[r,i]of Object.entries(this.config.rules.minLength))e[r]&&e[r].length<i&&t.push({code:"MIN_LENGTH",message:`${r} must be at least ${i} characters long`,path:[r]});if(this.config.rules.maxLength)for(let[r,i]of Object.entries(this.config.rules.maxLength))e[r]&&e[r].length>i&&t.push({code:"MAX_LENGTH",message:`${r} must be no more than ${i} characters long`,path:[r]});if(this.config.rules.pattern)for(let[r,i]of Object.entries(this.config.rules.pattern))e[r]&&!i.test(e[r])&&t.push({code:"PATTERN_MISMATCH",message:`${r} format is invalid`,path:[r]});if(this.config.rules.custom){for(let[r,i]of Object.entries(this.config.rules.custom))if(e[r]){let l=await i(e[r],o);l.isValid||t.push(...l.errors.map(n=>({...n,path:[r]})));}}return {isValid:t.length===0,errors:t}}async validateCrossField(e,o){let t=[];if(!this.config.crossFieldValidation)return {isValid:true,errors:[]};for(let r of this.config.crossFieldValidation){let i={},l=true;for(let n of r.fields)if(e[n]!==void 0)i[n]=e[n];else {l=false;break}l&&((await r.validator(i,o)).isValid||t.push({code:"CROSS_FIELD_VALIDATION",message:r.message,path:r.fields}));}return {isValid:t.length===0,errors:t}}async validateAsync(e,o){let t=[];if(!this.config.asyncRules)return {isValid:true,errors:[]};let r=Object.entries(this.config.asyncRules).map(async([l,n])=>{if(!e[l])return null;let d=`${l}_${o.workflowId}`;return this.debounceTimers.has(d)&&clearTimeout(this.debounceTimers.get(d)),new Promise(u=>{let S=setTimeout(async()=>{try{let y=n.method==="GET"?`${n.url}?value=${encodeURIComponent(e[l])}`:n.url,w=await(await fetch(y,{method:n.method||"POST",headers:{"Content-Type":"application/json",...n.headers},body:n.method!=="GET"?JSON.stringify({value:e[l]}):void 0})).json();w.isValid?u(null):u({code:"ASYNC_VALIDATION_ERROR",message:w.message||`${l} validation failed`,path:[l]});}catch{u({code:"ASYNC_VALIDATION_ERROR",message:`Async validation failed for ${l}`,path:[l]});}},n.debounceMs||500);this.debounceTimers.set(d,S);})}),i=await Promise.all(r);return t.push(...i.filter(l=>l!==null)),{isValid:t.length===0,errors:t}}};
|
|
1
|
+
'use strict';var core=require('@rilaykit/core'),forms=require('@rilaykit/forms'),q=require('@noble/ed25519'),react=require('react'),jsxRuntime=require('react/jsx-runtime');function _interopNamespace(e){if(e&&e.__esModule)return e;var n=Object.create(null);if(e){Object.keys(e).forEach(function(k){if(k!=='default'){var d=Object.getOwnPropertyDescriptor(e,k);Object.defineProperty(n,k,d.get?d:{enumerable:true,get:function(){return e[k]}});}})}n.default=e;return Object.freeze(n)}var q__namespace=/*#__PURE__*/_interopNamespace(q);var j=1751361139160,ee="8fdb6a454550326d331c3b3d1d1f8c707a371bdb6c7ea72a0a1e4ea6f1822620",f=class f{static async setLicenseKey(e){f.licenseKey=e||"",f.licenseKey?f.licenseResult=await f.validateLicense():f.licenseResult={valid:false,error:"MISSING"},f.isInitialized=true;}static async validateLicense(){if(!f.licenseKey)return {valid:false,error:"MISSING"};try{if(!f.licenseKey.startsWith("ril_"))return {valid:!1,error:"FORMAT_INVALID"};let e=f.licenseKey.slice(4),t=f.base64ToString(e).split(".");if(t.length!==3)return {valid:!1,error:"FORMAT_INVALID"};let[r,i,l]=t,n=`${r}.${i}`,d=new TextEncoder().encode(n),u=l.match(/.{2}/g);if(!u)return {valid:!1,error:"INVALID"};let S=new Uint8Array(u.map(g=>Number.parseInt(g,16))),y=f.hexToBytes(ee);if(!await q__namespace.verify(S,d,y))return {valid:!1,error:"SIGNATURE_INVALID"};let w=f.base64ToString(i.replace(/-/g,"+").replace(/_/g,"/")),h=JSON.parse(w),k=Math.floor(Date.now()/1e3);return h.e<k?{valid:!1,error:"EXPIRED",data:f.decompressPayload(h)}:j>h.e*1e3?{valid:!1,error:"EXPIRED",data:f.decompressPayload(h)}:h.p===void 0||!h.c||!h.i||!h.e||!h.t?{valid:!1,error:"INVALID"}:{valid:!0,data:f.decompressPayload(h)}}catch{return {valid:false,error:"INVALID"}}}static decompressPayload(e){return {plan:{0:"ARCHITECT",1:"FOUNDRY"}[e.p]||"ARCHITECT",company:e.c,customerId:e.i.toString(),expiry:e.e*1e3,iat:e.t*1e3}}static hexToBytes(e){let o=new Uint8Array(e.length/2);for(let t=0;t<e.length;t+=2)o[t/2]=Number.parseInt(e.substring(t,t+2),16);return o}static base64ToString(e){if(typeof atob<"u")return atob(e);if(typeof Buffer<"u")return Buffer.from(e,"base64").toString();let o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t="",r=0,i=e.replace(/[^A-Za-z0-9+/]/g,"");for(;r<i.length;){let l=o.indexOf(i.charAt(r++)),n=o.indexOf(i.charAt(r++)),d=o.indexOf(i.charAt(r++)),u=o.indexOf(i.charAt(r++)),S=l<<18|n<<12|d<<6|u;t+=String.fromCharCode(S>>16&255),d!==64&&(t+=String.fromCharCode(S>>8&255)),u!==64&&(t+=String.fromCharCode(S&255));}return t}static getLicenseResult(){return f.isInitialized?f.licenseResult?f.licenseResult:{valid:false,error:"MISSING"}:{valid:false,error:"MISSING"}}static shouldDisplayWatermark(){return typeof window>"u"?false:!f.getLicenseResult().valid}static getWatermarkMessage(){let e=f.getLicenseResult();return {MISSING:"Rilay Workflow - For Trial Use Only",EXPIRED:"Rilay Workflow - License Expired",INVALID:"Rilay Workflow - Invalid License",FORMAT_INVALID:"Rilay Workflow - Invalid License Format",SIGNATURE_INVALID:"Rilay Workflow - Invalid License Signature"}[e.error||"MISSING"]||""}static logLicenseStatus(){let e=f.getLicenseResult();if(e.valid)return;let t={MISSING:"\u{1F527} Rilay Workflow - Trial Mode. Purchase a license at https://rilay.io/pricing",EXPIRED:"\u26A0\uFE0F Rilay Workflow - License Expired. Please renew your license.",INVALID:"\u274C Rilay Workflow - Invalid License. Please check your license key.",FORMAT_INVALID:"\u274C Rilay Workflow - Invalid License Format. Please check your license key.",SIGNATURE_INVALID:"\u274C Rilay Workflow - Invalid License Signature. Please check your license key."}[e.error||"MISSING"];console.warn(`%c${t}`,"color: #f59e0b; font-weight: bold;");}static async getLicenseInfo(){let e=f.getLicenseResult();return !e.valid||!e.data?{}:{plan:e.data.plan,company:e.data.company,expiryDate:new Date(e.data.expiry).toLocaleDateString()}}};f.licenseKey="",f.licenseResult=null,f.isInitialized=false;var x=f;var D=class a{constructor(e,o,t,r){this.steps=[];this.navigation={allowBackNavigation:true};this.plugins=[];this.config=e,this.workflowId=o,this.workflowName=t,this.workflowDescription=r,x.logLicenseStatus();}static create(e,o,t,r){return new a(e,o,t,r)}createStepFromDefinition(e){return {id:e.id,title:e.title,description:e.description,formConfig:e.formConfig instanceof forms.form?e.formConfig.build():e.formConfig,allowSkip:e.allowSkip||false,requiredToComplete:e.requiredToComplete!==false,hooks:e.hooks,permissions:e.permissions,isDynamic:!!e.dynamicConfig,dynamicConfig:e.dynamicConfig,renderer:e.renderer}}addStep(e){let o=this.createStepFromDefinition(e);return this.steps.push(o),this}addDynamicStep(e){return this.addStep(e)}addSteps(e){for(let o of e)this.addStep(o);return this}setNavigation(e){return this.navigation={...this.navigation,...e},this}enableBackNavigation(e=true){return this.navigation={...this.navigation,allowBackNavigation:e},this}enableStepSkipping(e=true){return this.navigation={...this.navigation,allowStepSkipping:e},this}setPersistence(e){return this.persistence=e,this}setAnalytics(e){return this.analytics=e,this}setCompletion(e){return this.completion=e,this}use(e){this.validatePluginDependencies(e),this.plugins.push(e);try{e.install(this);}catch(o){throw new Error(`Failed to install plugin "${e.name}": ${o instanceof Error?o.message:String(o)}`)}return this}validatePluginDependencies(e){if(!e.dependencies)return;let o=e.dependencies.filter(t=>!this.plugins.some(r=>r.name===t));if(o.length>0)throw new Error(`Plugin "${e.name}" requires missing dependencies: ${o.join(", ")}`)}removePlugin(e){return this.plugins=this.plugins.filter(o=>o.name!==e),this}updateStep(e,o){let t=this.steps.findIndex(r=>r.id===e);if(t===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[t]={...this.steps[t],...o},this}removeStep(e){return this.steps=this.steps.filter(o=>o.id!==e),this}getStep(e){return this.steps.find(o=>o.id===e)}getSteps(){return [...this.steps]}clearSteps(){return this.steps=[],this}clone(e,o){let t=new a(this.config,e||`${this.workflowId}-clone`,o||`${this.workflowName} (Copy)`,this.workflowDescription);return t.steps=this.steps.map(r=>({...r})),t.navigation={...this.navigation},t.persistence=this.persistence?{...this.persistence}:void 0,t.completion=this.completion?{...this.completion}:void 0,t.analytics=this.analytics?{...this.analytics}:void 0,t.plugins=[...this.plugins],t}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let o=this.steps.map(r=>r.id),t=o.filter((r,i)=>o.indexOf(r)!==i);t.length>0&&e.push(`Duplicate step IDs: ${t.join(", ")}`);for(let r of this.plugins)if(r.dependencies){let i=r.dependencies.filter(l=>!this.plugins.some(n=>n.name===l));i.length>0&&e.push(`Plugin "${r.name}" requires missing dependencies: ${i.join(", ")}`);}return e}getStats(){return {totalSteps:this.steps.length,dynamicSteps:this.steps.filter(e=>e.isDynamic).length,pluginsInstalled:this.plugins.length,estimatedFields:this.steps.reduce((e,o)=>e+o.formConfig.allFields.length,0),hasPersistence:!!this.persistence,hasAnalytics:!!this.analytics,allowBackNavigation:this.navigation.allowBackNavigation!==false}}build(){let e=this.validate();if(e.length>0)throw new Error(`Workflow validation failed: ${e.join(", ")}`);return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:[...this.steps],navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,plugins:[...this.plugins],renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,plugins:this.plugins.map(e=>({name:e.name,version:e.version,dependencies:e.dependencies}))}}fromJSON(e){return e.id&&(this.workflowId=e.id),e.name&&(this.workflowName=e.name),e.description&&(this.workflowDescription=e.description),e.steps&&(this.steps=e.steps),e.navigation&&(this.navigation=e.navigation),e.persistence&&(this.persistence=e.persistence),e.completion&&(this.completion=e.completion),e.analytics&&(this.analytics=e.analytics),this}};function oe(a,e,o,t){return D.create(a,e,o,t)}core.ril.prototype.createFlow=function(a,e,o){return D.create(this,a,e,o)};function le(a,e){switch(e.type){case "SET_CURRENT_STEP":return {...a,currentStepIndex:e.stepIndex,stepData:a.allData[a.resolvedSteps[e.stepIndex]?.id]||{}};case "SET_STEP_DATA":{let o=a.resolvedSteps[a.currentStepIndex]?.id;return {...a,stepData:e.data,allData:{...a.allData,[o]:e.data}}}case "SET_ALL_DATA":return {...a,allData:e.data};case "SET_FIELD_VALUE":{let o=a.resolvedSteps[a.currentStepIndex]?.id,t={...a.stepData,[e.fieldId]:e.value};return {...a,stepData:t,allData:{...a.allData,[o]:t}}}case "SET_ERROR":return {...a,errors:{...a.errors,[e.fieldId]:e.errors}};case "CLEAR_ERROR":{let o={...a.errors};return delete o[e.fieldId],{...a,errors:o}}case "MARK_TOUCHED":return {...a,touched:new Set([...a.touched,e.fieldId])};case "SET_VALIDATING":{let o=new Set(a.isValidating);return e.isValidating?o.add(e.fieldId):o.delete(e.fieldId),{...a,isValidating:o}}case "SET_SUBMITTING":return {...a,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...a,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...a,visitedSteps:new Set([...a.visitedSteps,a.resolvedSteps[e.stepIndex]?.id])};case "SET_PERSISTED_DATA":return {...a,persistedData:e.data};case "SET_RESOLVED_STEPS":return {...a,resolvedSteps:e.steps};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},errors:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:a.resolvedSteps};default:return a}}var Y=react.createContext(null);function L({children:a,workflowConfig:e,defaultValues:o={},onStepChange:t,onWorkflowComplete:r,className:i,user:l}){let[n,d]=react.useReducer(le,{currentStepIndex:0,allData:o,stepData:{},errors:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:e.steps}),u=react.useRef(null),S=react.useRef(Date.now()),y=react.useRef(new Map),R=react.useRef(false),w=react.useRef(null),h=react.useRef(t),k=react.useRef(r);h.current=t,k.current=r;let s=react.useMemo(()=>e,[e]),g=react.useMemo(()=>({workflowId:s.id,currentStepIndex:n.currentStepIndex,totalSteps:n.resolvedSteps.length,allData:n.allData,stepData:n.stepData,isFirstStep:n.currentStepIndex===0,isLastStep:n.currentStepIndex===n.resolvedSteps.length-1,visitedSteps:n.visitedSteps,user:l}),[s.id,n.currentStepIndex,n.resolvedSteps.length,n.allData,n.stepData,n.visitedSteps,l]);react.useEffect(()=>{(async()=>{let p=[];for(let m of s.steps)if(m.isDynamic&&m.dynamicConfig)try{let V=await m.dynamicConfig.resolver(n.allData,g);p.push(...V);}catch(V){console.error(`Failed to resolve dynamic step "${m.id}":`,V),p.push({...m,isDynamic:false});}else p.push(m);d({type:"SET_RESOLVED_STEPS",steps:p});})();},[s.steps,n.allData,g]),react.useEffect(()=>{s.analytics?.onWorkflowStart&&!R.current&&(R.current=true,s.analytics.onWorkflowStart(s.id,g));},[s.id,s.analytics,g]),react.useEffect(()=>{let c=n.resolvedSteps[n.currentStepIndex];if(c&&w.current!==c.id){if(w.current&&s.analytics?.onStepComplete){let p=y.current.get(w.current);p&&s.analytics.onStepComplete(w.current,Date.now()-p,n.stepData,g);}w.current=c.id,y.current.set(c.id,Date.now()),s.analytics?.onStepStart&&s.analytics.onStepStart(c.id,Date.now(),g);}},[n.currentStepIndex,n.resolvedSteps,s.analytics,g]);let E=react.useCallback(async()=>{if(s.persistence)try{let c={workflowId:s.id,currentStepIndex:n.currentStepIndex,allData:n.allData,metadata:{timestamp:Date.now(),version:"1.0.0",userId:l?.id,sessionId:crypto.randomUUID()}},p=s.persistence.key||`workflow-${s.id}`;await s.persistence.adapter.save(p,c),s.persistence.onSave&&await s.persistence.onSave(c);}catch(c){console.error("Failed to save workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"save");}},[s,n.currentStepIndex,n.allData,l]),O=react.useCallback(async()=>{if(s.persistence)try{let c=s.persistence.key||`workflow-${s.id}`,p=await s.persistence.adapter.load(c);p&&p.workflowId===s.id&&(d({type:"SET_ALL_DATA",data:p.allData}),d({type:"SET_CURRENT_STEP",stepIndex:p.currentStepIndex}),d({type:"SET_PERSISTED_DATA",data:p}),s.persistence.onLoad&&await s.persistence.onLoad(p));}catch(c){console.error("Failed to load workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"load");}},[s]),A=react.useCallback(async()=>{if(s.persistence)try{let c=s.persistence.key||`workflow-${s.id}`;await s.persistence.adapter.remove(c);}catch(c){console.error("Failed to clear workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"remove");}},[s]);react.useEffect(()=>{s.persistence&&(async()=>{try{let p=s.persistence.key||`workflow-${s.id}`,m=await s.persistence.adapter.load(p);m&&m.workflowId===s.id&&(d({type:"SET_ALL_DATA",data:m.allData}),d({type:"SET_CURRENT_STEP",stepIndex:m.currentStepIndex}),d({type:"SET_PERSISTED_DATA",data:m}),s.persistence.onLoad&&await s.persistence.onLoad(m),console.log("Workflow data loaded from persistence:",m));}catch(p){console.error("Failed to load workflow draft on mount:",p),s.persistence.onError&&await s.persistence.onError(p,"load");}})();},[s.id]),react.useEffect(()=>{if(s.persistence?.saveOnStepChange)return u.current&&clearTimeout(u.current),u.current=setTimeout(()=>{E();},s.persistence.debounceMs||1e3),()=>{u.current&&clearTimeout(u.current);}},[n.allData,E,s.persistence]);let C=react.useMemo(()=>n.resolvedSteps[n.currentStepIndex],[n.resolvedSteps,n.currentStepIndex]),M=react.useMemo(()=>C?.formConfig,[C]),P=react.useCallback(async c=>{if(c<0||c>=n.resolvedSteps.length)return false;let p=n.resolvedSteps[c];if(p.permissions)try{if(!(p.permissions.customGuard?await p.permissions.customGuard(l,g):!0))return console.warn(`Access denied to step "${p.id}"`),!1}catch(m){return console.error(`Permission check failed for step "${p.id}":`,m),false}if(p.hooks?.onBeforeEnter)try{await p.hooks.onBeforeEnter(n.stepData,n.allData,g);}catch(m){return console.error(`onBeforeEnter hook failed for step "${p.id}":`,m),s.analytics?.onError&&s.analytics.onError(m,g),false}d({type:"SET_TRANSITIONING",isTransitioning:true});try{return h.current&&h.current(n.currentStepIndex,c,g),d({type:"SET_CURRENT_STEP",stepIndex:c}),d({type:"MARK_STEP_VISITED",stepIndex:c}),!0}catch(m){return console.error("Step transition failed:",m),s.analytics?.onError&&s.analytics.onError(m,g),false}finally{d({type:"SET_TRANSITIONING",isTransitioning:false});}},[n.resolvedSteps,n.currentStepIndex,n.stepData,n.allData,l,g,s.analytics]),N=react.useCallback((c,p)=>{d({type:"SET_FIELD_VALUE",fieldId:c,value:p});},[]),$=react.useCallback(c=>{d({type:"SET_STEP_DATA",data:c});},[]),U=react.useCallback(async()=>C?{isValid:true,errors:[]}:{isValid:true,errors:[]},[C]),_=react.useCallback(async()=>P(n.currentStepIndex+1),[P,n.currentStepIndex]),G=react.useCallback(async()=>s.navigation?.allowBackNavigation?P(n.currentStepIndex-1):false,[s.navigation,n.currentStepIndex,P]),K=react.useCallback(async()=>!C?.allowSkip||!s.navigation?.allowStepSkipping?false:(s.analytics?.onStepSkip&&s.analytics.onStepSkip(C.id,"user_skip",g),P(n.currentStepIndex+1)),[C,s.navigation,s.analytics,g,P,n.currentStepIndex]),H=react.useCallback(async()=>{d({type:"SET_SUBMITTING",isSubmitting:true});try{if(k.current&&await k.current(n.allData),await A(),s.analytics?.onWorkflowComplete){let c=Date.now()-S.current;s.analytics.onWorkflowComplete(s.id,c,n.allData);}}catch(c){throw console.error("Workflow submission failed:",c),s.analytics?.onError&&s.analytics.onError(c,g),c}finally{d({type:"SET_SUBMITTING",isSubmitting:false});}},[n.allData,k,A,s.analytics,g]),z=react.useCallback(()=>{d({type:"RESET_WORKFLOW"});},[]),Z=react.useMemo(()=>({workflowState:n,workflowConfig:s,currentStep:C,context:g,formConfig:M,goToStep:P,goNext:_,goPrevious:G,skipStep:K,setValue:N,setStepData:$,validateCurrentStep:U,submitWorkflow:H,resetWorkflow:z,saveDraft:E,loadDraft:O,clearDraft:A}),[n,s,C,g,M,P,_,G,K,N,$,U,H,z,E,O,A]),Q=react.useCallback(async()=>{await _();},[_]);return jsxRuntime.jsx(Y.Provider,{value:Z,children:jsxRuntime.jsx(forms.FormProvider,{formConfig:C?.formConfig,defaultValues:n?.allData[C?.id]||{},onFieldChange:N,"data-workflow-id":s.id,className:i,onSubmit:Q,children:a})})}function I(){let a=react.useContext(Y);if(!a)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return a}function pe({children:a,workflowConfig:e,...o}){let[t,r]=react.useState(false),i=x.shouldDisplayWatermark(),l=x.getWatermarkMessage(),n=e instanceof D?e.build():e;return react.useEffect(()=>{r(true);},[]),jsxRuntime.jsxs("div",{style:{position:"relative"},children:[jsxRuntime.jsx(L,{...o,workflowConfig:n,children:a}),t&&i&&jsxRuntime.jsx("div",{style:{position:"absolute",top:"10px",right:"10px",background:"rgba(0, 0, 0, 0.8)",color:"white",padding:"4px 8px",borderRadius:"4px",fontSize:"12px",fontFamily:"monospace",zIndex:1e3,pointerEvents:"none",opacity:.7},children:l})]})}function ge(){let{currentStep:a}=I();if(!a)return null;let{formConfig:e,renderer:o}=a;return e?o?o(a):jsxRuntime.jsx(forms.FormBody,{}):null}function Se({className:a,children:e,renderAs:o}){let{context:t,submitWorkflow:r,workflowState:i,workflowConfig:l,currentStep:n}=I(),{submit:d,formState:u}=forms.useFormContext(),S=!i.isTransitioning&&!i.isSubmitting,y=async E=>{E?.preventDefault(),S&&await d(E);},R=async E=>{E?.preventDefault(),S&&await r();},w={isLastStep:t.isLastStep,canGoNext:S,isSubmitting:i.isSubmitting,onNext:y,onSubmit:R,className:a,currentStep:n,stepData:u.values||{},allData:t.allData,context:t};if(o==="children"||o===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(w)}let k=l.renderConfig?.nextButtonRenderer;if(!k)throw new Error(`No nextButtonRenderer configured for workflow "${l.id}". Please configure a nextButtonRenderer using config.setWorkflowNextButtonRenderer() or config.setWorkflowRenderConfig().`);let s=core.resolveRendererChildren(e,w),g={...w,children:s};return k(g)}function ve({className:a,children:e,renderAs:o}){let{context:t,goPrevious:r,workflowState:i,workflowConfig:l,currentStep:n}=I(),{formState:d}=forms.useFormContext(),u=t.currentStepIndex>0&&l.navigation?.allowBackNavigation!==false&&!i.isTransitioning&&!i.isSubmitting;if(l.navigation?.allowBackNavigation===false)throw new Error(`WorkflowPreviousButton is rendered but allowBackNavigation is disabled in workflow "${l.id}". Either enable back navigation or remove the WorkflowPreviousButton component.`);let y={canGoPrevious:u,onPrevious:async s=>{s?.preventDefault(),u&&await r();},className:a,currentStep:n,stepData:d.values||{},allData:t.allData,context:t};if(o==="children"||o===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(y)}let w=l.renderConfig?.previousButtonRenderer;if(!w)throw new Error(`No previousButtonRenderer configured for workflow "${l.id}". Please configure a previousButtonRenderer using config.setWorkflowPreviousButtonRenderer() or config.setWorkflowRenderConfig().`);let h=core.resolveRendererChildren(e,y),k={...y,children:h};return w(k)}function Ie({className:a,children:e,renderAs:o}){let{currentStep:t,skipStep:r,workflowState:i,workflowConfig:l,context:n}=I(),{formState:d}=forms.useFormContext(),u=!!t?.allowSkip&&l.navigation?.allowStepSkipping!==false&&!i.isTransitioning&&!i.isSubmitting,y={canSkip:u,onSkip:async s=>{s?.preventDefault(),u&&await r();},className:a,currentStep:t,stepData:d.values||{},allData:n.allData,context:n};if(o==="children"||o===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(y)}let w=l.renderConfig?.skipButtonRenderer;if(!w)throw new Error(`No skipButtonRenderer configured for workflow "${l.id}". Please configure a skipButtonRenderer using config.setWorkflowSkipButtonRenderer() or config.setWorkflowRenderConfig().`);let h=core.resolveRendererChildren(e,y),k={...y,children:h};return w(k)}function Ee({onStepClick:a,className:e,children:o,renderAs:t}){let{workflowConfig:r,workflowState:i,goToStep:l}=I(),n=R=>{a?a(R):l(R);},d={steps:i.resolvedSteps,currentStepIndex:i.currentStepIndex,visitedSteps:i.visitedSteps,onStepClick:n,className:e};if(t==="children"||t===true){if(typeof o!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return o(d)}let S=r.renderConfig?.stepperRenderer;if(!S)throw new Error(`No stepperRenderer configured for workflow "${r.id}". Please configure a stepperRenderer using config.setStepperRenderer() or config.setWorkflowRenderConfig().`);return S(d)}var B=class{constructor(e){this.name="analytics";this.version="1.0.0";this.performanceData=new Map;this.config=e;}install(e){let o={onWorkflowStart:(t,r)=>{this.track("workflow_start",{workflow_id:t,total_steps:r.totalSteps,...this.getContextData(r)}),this.config.enablePerformanceTracking&&this.performanceData.set(`workflow_${t}`,Date.now());},onWorkflowComplete:(t,r,i)=>{this.track("workflow_complete",{workflow_id:t,duration_ms:r,form_data_keys:this.config.includeFormData?Object.keys(i):void 0,...this.config.includeFormData?{form_data:i}:{}});},onWorkflowAbandon:(t,r,i)=>{this.track("workflow_abandon",{workflow_id:t,abandoned_at_step:r,completion_percentage:this.calculateCompletionPercentage(i)});},onStepStart:(t,r,i)=>{this.track("step_start",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,...this.getContextData(i)}),this.config.enablePerformanceTracking&&this.performanceData.set(`step_${t}`,r);},onStepComplete:(t,r,i,l)=>{this.track("step_complete",{step_id:t,step_index:l.currentStepIndex,workflow_id:l.workflowId,duration_ms:r,field_count:Object.keys(i).length,...this.getContextData(l)});},onStepSkip:(t,r,i)=>{this.track("step_skip",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,skip_reason:r,...this.getContextData(i)});},onValidationError:(t,r,i)=>{this.track("validation_error",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,error_count:r.length,error_codes:r.map(l=>l.code),...this.getContextData(i)});},onError:(t,r)=>{this.track("workflow_error",{workflow_id:r.workflowId,step_id:r.currentStepIndex,error_message:t.message,error_name:t.name,...this.getContextData(r)});}};e.setAnalytics(o);}track(e,o){let t=this.config.eventMapping?.[e]||e,r={...o,timestamp:Date.now(),plugin_version:this.version};for(let[i,l]of Object.entries(this.config.providers))switch(i){case "googleAnalytics":this.trackGoogleAnalytics(t,r,l);break;case "mixpanel":this.trackMixpanel(t,r);break;case "amplitude":this.trackAmplitude(t,r);break;case "custom":this.trackCustom(t,r,l);break}}trackGoogleAnalytics(e,o,t){typeof window<"u"&&window.gtag&&window.gtag("event",e,{...o,custom_map:t.customDimensions});}trackMixpanel(e,o){typeof window<"u"&&window.mixpanel&&window.mixpanel.track(e,o);}trackAmplitude(e,o){typeof window<"u"&&window.amplitude&&window.amplitude.getInstance().logEvent(e,o);}async trackCustom(e,o,t){try{await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify({event:e,properties:o})});}catch(r){console.error("Custom analytics tracking failed:",r);}}getContextData(e){return this.config.includeUserContext?{user_id:e.user?.id,is_first_step:e.isFirstStep,is_last_step:e.isLastStep,visited_steps_count:e.visitedSteps.size,browser_info:typeof window<"u"?{user_agent:navigator.userAgent,language:navigator.language,platform:navigator.platform}:void 0}:{}}calculateCompletionPercentage(e){let o=Object.keys(e).length,t=Object.values(e).filter(r=>r!=null&&r!=="").length;return o>0?t/o*100:0}};var F=class{constructor(e){this.name="validation";this.version="1.0.0";this.dependencies=[];this.debounceTimers=new Map;this.config=e;}install(e){let o=e.getSteps();for(let t of o){let r=t.hooks||{};e.updateStep(t.id,{hooks:{...r,onValidate:async(i,l)=>{let n=await this.validateStep(i,l);return this.config.onValidationComplete&&this.config.onValidationComplete(n,l),n}}});}}async validateStep(e,o){let t=[];try{if(this.config.schema){let i=await this.validateWithSchema(e,o);t.push(...i.errors);}let r=await this.validateWithRules(e,o);if(t.push(...r.errors),this.config.crossFieldValidation){let i=await this.validateCrossField(o.allData,o);t.push(...i.errors);}if(this.config.asyncRules){let i=await this.validateAsync(e,o);t.push(...i.errors);}return {isValid:t.length===0,errors:t}}catch(r){return {isValid:false,errors:[{code:"VALIDATION_ERROR",message:`Validation failed: ${r instanceof Error?r.message:String(r)}`}]}}}async validateWithSchema(e,o){if(!this.config.schema?.schema)return {isValid:true,errors:[]};try{switch(this.config.schema.type){case "zod":{let t=this.config.schema.schema.safeParse(e);if(!t.success)return {isValid:!1,errors:t.error.errors.map(r=>({code:r.code,message:r.message,path:r.path}))};break}case "yup":try{await this.config.schema.schema.validate(e,{abortEarly:!1});}catch(t){return {isValid:!1,errors:t.inner?.map(r=>({code:"YUP_VALIDATION_ERROR",message:r.message,path:r.path?[r.path]:void 0}))||[{code:"YUP_VALIDATION_ERROR",message:t.message}]}}break;case "custom":{let t=await this.config.schema.schema(e,o);if(!t.isValid)return t;break}}return {isValid:!0,errors:[]}}catch(t){return {isValid:false,errors:[{code:"SCHEMA_VALIDATION_ERROR",message:`Schema validation failed: ${t instanceof Error?t.message:String(t)}`}]}}}async validateWithRules(e,o){let t=[];if(this.config.rules.required)for(let r of this.config.rules.required)(!e[r]||typeof e[r]=="string"&&e[r].trim()==="")&&t.push({code:"REQUIRED",message:`${r} is required`,path:[r]});if(this.config.rules.email){let r=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;for(let i of this.config.rules.email)e[i]&&!r.test(e[i])&&t.push({code:"INVALID_EMAIL",message:`${i} must be a valid email address`,path:[i]});}if(this.config.rules.phone){let r=/^[\+]?[1-9][\d]{0,15}$/;for(let i of this.config.rules.phone)e[i]&&!r.test(e[i].replace(/\s/g,""))&&t.push({code:"INVALID_PHONE",message:`${i} must be a valid phone number`,path:[i]});}if(this.config.rules.minLength)for(let[r,i]of Object.entries(this.config.rules.minLength))e[r]&&e[r].length<i&&t.push({code:"MIN_LENGTH",message:`${r} must be at least ${i} characters long`,path:[r]});if(this.config.rules.maxLength)for(let[r,i]of Object.entries(this.config.rules.maxLength))e[r]&&e[r].length>i&&t.push({code:"MAX_LENGTH",message:`${r} must be no more than ${i} characters long`,path:[r]});if(this.config.rules.pattern)for(let[r,i]of Object.entries(this.config.rules.pattern))e[r]&&!i.test(e[r])&&t.push({code:"PATTERN_MISMATCH",message:`${r} format is invalid`,path:[r]});if(this.config.rules.custom){for(let[r,i]of Object.entries(this.config.rules.custom))if(e[r]){let l=await i(e[r],o);l.isValid||t.push(...l.errors.map(n=>({...n,path:[r]})));}}return {isValid:t.length===0,errors:t}}async validateCrossField(e,o){let t=[];if(!this.config.crossFieldValidation)return {isValid:true,errors:[]};for(let r of this.config.crossFieldValidation){let i={},l=true;for(let n of r.fields)if(e[n]!==void 0)i[n]=e[n];else {l=false;break}l&&((await r.validator(i,o)).isValid||t.push({code:"CROSS_FIELD_VALIDATION",message:r.message,path:r.fields}));}return {isValid:t.length===0,errors:t}}async validateAsync(e,o){let t=[];if(!this.config.asyncRules)return {isValid:true,errors:[]};let r=Object.entries(this.config.asyncRules).map(async([l,n])=>{if(!e[l])return null;let d=`${l}_${o.workflowId}`;return this.debounceTimers.has(d)&&clearTimeout(this.debounceTimers.get(d)),new Promise(u=>{let S=setTimeout(async()=>{try{let y=n.method==="GET"?`${n.url}?value=${encodeURIComponent(e[l])}`:n.url,w=await(await fetch(y,{method:n.method||"POST",headers:{"Content-Type":"application/json",...n.headers},body:n.method!=="GET"?JSON.stringify({value:e[l]}):void 0})).json();w.isValid?u(null):u({code:"ASYNC_VALIDATION_ERROR",message:w.message||`${l} validation failed`,path:[l]});}catch{u({code:"ASYNC_VALIDATION_ERROR",message:`Async validation failed for ${l}`,path:[l]});}},n.debounceMs||500);this.debounceTimers.set(d,S);})}),i=await Promise.all(r);return t.push(...i.filter(l=>l!==null)),{isValid:t.length===0,errors:t}}};
|
|
2
2
|
Object.defineProperty(exports,"createZodValidator",{enumerable:true,get:function(){return core.createZodValidator}});Object.defineProperty(exports,"ril",{enumerable:true,get:function(){return core.ril}});Object.defineProperty(exports,"form",{enumerable:true,get:function(){return forms.form}});exports.AnalyticsPlugin=B;exports.RilayLicenseManager=x;exports.ValidationPlugin=F;exports.Workflow=pe;exports.WorkflowBody=ge;exports.WorkflowNextButton=Se;exports.WorkflowPreviousButton=ve;exports.WorkflowProvider=L;exports.WorkflowSkipButton=Ie;exports.WorkflowStepper=Ee;exports.createFlow=oe;exports.flow=D;exports.useWorkflowContext=I;
|
package/dist/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import {ril,resolveRendererChildren}from'@rilaykit/core';export{createZodValidator,ril}from'@rilaykit/core';import {form,FormProvider,FormBody,useFormContext}from'@rilaykit/forms';export{form}from'@rilaykit/forms';import*as q from'@noble/ed25519';import {createContext,useReducer,useRef,useMemo,useEffect,useCallback,useContext,useState}from'react';import {jsx,jsxs}from'react/jsx-runtime';var j=1751361139160,ee="8fdb6a454550326d331c3b3d1d1f8c707a371bdb6c7ea72a0a1e4ea6f1822620",f=class f{static async setLicenseKey(e){f.licenseKey=e||"",f.licenseKey?f.licenseResult=await f.validateLicense():f.licenseResult={valid:false,error:"MISSING"},f.isInitialized=true;}static async validateLicense(){if(!f.licenseKey)return {valid:false,error:"MISSING"};try{if(!f.licenseKey.startsWith("ril_"))return {valid:!1,error:"FORMAT_INVALID"};let e=f.licenseKey.slice(4),t=f.base64ToString(e).split(".");if(t.length!==3)return {valid:!1,error:"FORMAT_INVALID"};let[r,i,l]=t,n=`${r}.${i}`,d=new TextEncoder().encode(n),u=l.match(/.{2}/g);if(!u)return {valid:!1,error:"INVALID"};let S=new Uint8Array(u.map(g=>Number.parseInt(g,16))),y=f.hexToBytes(ee);if(!await q.verify(S,d,y))return {valid:!1,error:"SIGNATURE_INVALID"};let w=f.base64ToString(i.replace(/-/g,"+").replace(/_/g,"/")),h=JSON.parse(w),k=Math.floor(Date.now()/1e3);return h.e<k?{valid:!1,error:"EXPIRED",data:f.decompressPayload(h)}:j>h.e*1e3?{valid:!1,error:"EXPIRED",data:f.decompressPayload(h)}:h.p===void 0||!h.c||!h.i||!h.e||!h.t?{valid:!1,error:"INVALID"}:{valid:!0,data:f.decompressPayload(h)}}catch{return {valid:false,error:"INVALID"}}}static decompressPayload(e){return {plan:{0:"ARCHITECT",1:"FOUNDRY"}[e.p]||"ARCHITECT",company:e.c,customerId:e.i.toString(),expiry:e.e*1e3,iat:e.t*1e3}}static hexToBytes(e){let o=new Uint8Array(e.length/2);for(let t=0;t<e.length;t+=2)o[t/2]=Number.parseInt(e.substring(t,t+2),16);return o}static base64ToString(e){if(typeof atob<"u")return atob(e);if(typeof Buffer<"u")return Buffer.from(e,"base64").toString();let o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t="",r=0,i=e.replace(/[^A-Za-z0-9+/]/g,"");for(;r<i.length;){let l=o.indexOf(i.charAt(r++)),n=o.indexOf(i.charAt(r++)),d=o.indexOf(i.charAt(r++)),u=o.indexOf(i.charAt(r++)),S=l<<18|n<<12|d<<6|u;t+=String.fromCharCode(S>>16&255),d!==64&&(t+=String.fromCharCode(S>>8&255)),u!==64&&(t+=String.fromCharCode(S&255));}return t}static getLicenseResult(){return f.isInitialized?f.licenseResult?f.licenseResult:{valid:false,error:"MISSING"}:{valid:false,error:"MISSING"}}static shouldDisplayWatermark(){return typeof window>"u"?false:!f.getLicenseResult().valid}static getWatermarkMessage(){let e=f.getLicenseResult();return {MISSING:"Rilay Workflow - For Trial Use Only",EXPIRED:"Rilay Workflow - License Expired",INVALID:"Rilay Workflow - Invalid License",FORMAT_INVALID:"Rilay Workflow - Invalid License Format",SIGNATURE_INVALID:"Rilay Workflow - Invalid License Signature"}[e.error||"MISSING"]||""}static logLicenseStatus(){let e=f.getLicenseResult();if(e.valid)return;let t={MISSING:"\u{1F527} Rilay Workflow - Trial Mode. Purchase a license at https://rilay.io/pricing",EXPIRED:"\u26A0\uFE0F Rilay Workflow - License Expired. Please renew your license.",INVALID:"\u274C Rilay Workflow - Invalid License. Please check your license key.",FORMAT_INVALID:"\u274C Rilay Workflow - Invalid License Format. Please check your license key.",SIGNATURE_INVALID:"\u274C Rilay Workflow - Invalid License Signature. Please check your license key."}[e.error||"MISSING"];console.warn(`%c${t}`,"color: #f59e0b; font-weight: bold;");}static async getLicenseInfo(){let e=f.getLicenseResult();return !e.valid||!e.data?{}:{plan:e.data.plan,company:e.data.company,expiryDate:new Date(e.data.expiry).toLocaleDateString()}}};f.licenseKey="",f.licenseResult=null,f.isInitialized=false;var x=f;var D=class a{constructor(e,o,t,r){this.steps=[];this.navigation={allowBackNavigation:true};this.plugins=[];this.config=e,this.workflowId=o,this.workflowName=t,this.workflowDescription=r,x.logLicenseStatus();}static create(e,o,t,r){return new a(e,o,t,r)}createStepFromDefinition(e){return {id:e.id,title:e.title,description:e.description,formConfig:e.formConfig instanceof form?e.formConfig.build():e.formConfig,allowSkip:e.allowSkip||false,requiredToComplete:e.requiredToComplete!==false,hooks:e.hooks,permissions:e.permissions,isDynamic:!!e.dynamicConfig,dynamicConfig:e.dynamicConfig,renderer:e.renderer}}addStep(e){let o=this.createStepFromDefinition(e);return this.steps.push(o),this}addDynamicStep(e){return this.addStep(e)}addSteps(e){for(let o of e)this.addStep(o);return this}setNavigation(e){return this.navigation={...this.navigation,...e},this}enableBackNavigation(e=true){return this.navigation={...this.navigation,allowBackNavigation:e},this}enableStepSkipping(e=true){return this.navigation={...this.navigation,allowStepSkipping:e},this}setPersistence(e){return this.persistence=e,this}setAnalytics(e){return this.analytics=e,this}setCompletion(e){return this.completion=e,this}use(e){this.validatePluginDependencies(e),this.plugins.push(e);try{e.install(this);}catch(o){throw new Error(`Failed to install plugin "${e.name}": ${o instanceof Error?o.message:String(o)}`)}return this}validatePluginDependencies(e){if(!e.dependencies)return;let o=e.dependencies.filter(t=>!this.plugins.some(r=>r.name===t));if(o.length>0)throw new Error(`Plugin "${e.name}" requires missing dependencies: ${o.join(", ")}`)}removePlugin(e){return this.plugins=this.plugins.filter(o=>o.name!==e),this}updateStep(e,o){let t=this.steps.findIndex(r=>r.id===e);if(t===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[t]={...this.steps[t],...o},this}removeStep(e){return this.steps=this.steps.filter(o=>o.id!==e),this}getStep(e){return this.steps.find(o=>o.id===e)}getSteps(){return [...this.steps]}clearSteps(){return this.steps=[],this}clone(e,o){let t=new a(this.config,e||`${this.workflowId}-clone`,o||`${this.workflowName} (Copy)`,this.workflowDescription);return t.steps=this.steps.map(r=>({...r})),t.navigation={...this.navigation},t.persistence=this.persistence?{...this.persistence}:void 0,t.completion=this.completion?{...this.completion}:void 0,t.analytics=this.analytics?{...this.analytics}:void 0,t.plugins=[...this.plugins],t}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let o=this.steps.map(r=>r.id),t=o.filter((r,i)=>o.indexOf(r)!==i);t.length>0&&e.push(`Duplicate step IDs: ${t.join(", ")}`);for(let r of this.plugins)if(r.dependencies){let i=r.dependencies.filter(l=>!this.plugins.some(n=>n.name===l));i.length>0&&e.push(`Plugin "${r.name}" requires missing dependencies: ${i.join(", ")}`);}return e}getStats(){return {totalSteps:this.steps.length,dynamicSteps:this.steps.filter(e=>e.isDynamic).length,pluginsInstalled:this.plugins.length,estimatedFields:this.steps.reduce((e,o)=>e+o.formConfig.allFields.length,0),hasPersistence:!!this.persistence,hasAnalytics:!!this.analytics,allowBackNavigation:this.navigation.allowBackNavigation!==false}}build(){let e=this.validate();if(e.length>0)throw new Error(`Workflow validation failed: ${e.join(", ")}`);return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:[...this.steps],navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,plugins:[...this.plugins],renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,plugins:this.plugins.map(e=>({name:e.name,version:e.version,dependencies:e.dependencies}))}}fromJSON(e){return e.id&&(this.workflowId=e.id),e.name&&(this.workflowName=e.name),e.description&&(this.workflowDescription=e.description),e.steps&&(this.steps=e.steps),e.navigation&&(this.navigation=e.navigation),e.persistence&&(this.persistence=e.persistence),e.completion&&(this.completion=e.completion),e.analytics&&(this.analytics=e.analytics),this}};function oe(a,e,o,t){return D.create(a,e,o,t)}ril.prototype.createFlow=function(a,e,o){return D.create(this,a,e,o)};function le(a,e){switch(e.type){case "SET_CURRENT_STEP":return {...a,currentStepIndex:e.stepIndex,stepData:a.allData[a.resolvedSteps[e.stepIndex]?.id]||{}};case "SET_STEP_DATA":{let o=a.resolvedSteps[a.currentStepIndex]?.id;return {...a,stepData:e.data,allData:{...a.allData,[o]:e.data}}}case "SET_ALL_DATA":return {...a,allData:e.data};case "SET_FIELD_VALUE":{let o=a.resolvedSteps[a.currentStepIndex]?.id,t={...a.stepData,[e.fieldId]:e.value};return {...a,stepData:t,allData:{...a.allData,[o]:t}}}case "SET_ERROR":return {...a,errors:{...a.errors,[e.fieldId]:e.errors}};case "CLEAR_ERROR":{let o={...a.errors};return delete o[e.fieldId],{...a,errors:o}}case "MARK_TOUCHED":return {...a,touched:new Set([...a.touched,e.fieldId])};case "SET_VALIDATING":{let o=new Set(a.isValidating);return e.isValidating?o.add(e.fieldId):o.delete(e.fieldId),{...a,isValidating:o}}case "SET_SUBMITTING":return {...a,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...a,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...a,visitedSteps:new Set([...a.visitedSteps,a.resolvedSteps[e.stepIndex]?.id])};case "SET_PERSISTED_DATA":return {...a,persistedData:e.data};case "SET_RESOLVED_STEPS":return {...a,resolvedSteps:e.steps};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},errors:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:a.resolvedSteps};default:return a}}var Y=createContext(null);function L({children:a,workflowConfig:e,defaultValues:o={},onStepChange:t,onWorkflowComplete:r,className:i,user:l}){let[n,d]=useReducer(le,{currentStepIndex:0,allData:o,stepData:{},errors:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:e.steps}),u=useRef(null),S=useRef(Date.now()),y=useRef(new Map),C=useRef(false),w=useRef(null),h=useRef(t),k=useRef(r);h.current=t,k.current=r;let s=useMemo(()=>e,[e]),g=useMemo(()=>({workflowId:s.id,currentStepIndex:n.currentStepIndex,totalSteps:n.resolvedSteps.length,allData:n.allData,stepData:n.stepData,isFirstStep:n.currentStepIndex===0,isLastStep:n.currentStepIndex===n.resolvedSteps.length-1,visitedSteps:n.visitedSteps,user:l}),[s.id,n.currentStepIndex,n.resolvedSteps.length,n.allData,n.stepData,n.visitedSteps,l]);useEffect(()=>{(async()=>{let p=[];for(let m of s.steps)if(m.isDynamic&&m.dynamicConfig)try{let V=await m.dynamicConfig.resolver(n.allData,g);p.push(...V);}catch(V){console.error(`Failed to resolve dynamic step "${m.id}":`,V),p.push({...m,isDynamic:false});}else p.push(m);d({type:"SET_RESOLVED_STEPS",steps:p});})();},[s.steps,n.allData,g]),useEffect(()=>{s.analytics?.onWorkflowStart&&!C.current&&(C.current=true,s.analytics.onWorkflowStart(s.id,g));},[s.id,s.analytics,g]),useEffect(()=>{let c=n.resolvedSteps[n.currentStepIndex];if(c&&w.current!==c.id){if(w.current&&s.analytics?.onStepComplete){let p=y.current.get(w.current);p&&s.analytics.onStepComplete(w.current,Date.now()-p,n.stepData,g);}w.current=c.id,y.current.set(c.id,Date.now()),s.analytics?.onStepStart&&s.analytics.onStepStart(c.id,Date.now(),g);}},[n.currentStepIndex,n.resolvedSteps,s.analytics,g]);let E=useCallback(async()=>{if(s.persistence)try{let c={workflowId:s.id,currentStepIndex:n.currentStepIndex,allData:n.allData,metadata:{timestamp:Date.now(),version:"1.0.0",userId:l?.id,sessionId:crypto.randomUUID()}},p=s.persistence.key||`workflow-${s.id}`;await s.persistence.adapter.save(p,c),s.persistence.onSave&&await s.persistence.onSave(c);}catch(c){console.error("Failed to save workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"save");}},[s,n.currentStepIndex,n.allData,l]),O=useCallback(async()=>{if(s.persistence)try{let c=s.persistence.key||`workflow-${s.id}`,p=await s.persistence.adapter.load(c);p&&p.workflowId===s.id&&(d({type:"SET_ALL_DATA",data:p.allData}),d({type:"SET_CURRENT_STEP",stepIndex:p.currentStepIndex}),d({type:"SET_PERSISTED_DATA",data:p}),s.persistence.onLoad&&await s.persistence.onLoad(p));}catch(c){console.error("Failed to load workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"load");}},[s]),A=useCallback(async()=>{if(s.persistence)try{let c=s.persistence.key||`workflow-${s.id}`;await s.persistence.adapter.remove(c);}catch(c){console.error("Failed to clear workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"remove");}},[s]);useEffect(()=>{s.persistence&&(async()=>{try{let p=s.persistence.key||`workflow-${s.id}`,m=await s.persistence.adapter.load(p);m&&m.workflowId===s.id&&(d({type:"SET_ALL_DATA",data:m.allData}),d({type:"SET_CURRENT_STEP",stepIndex:m.currentStepIndex}),d({type:"SET_PERSISTED_DATA",data:m}),s.persistence.onLoad&&await s.persistence.onLoad(m),console.log("Workflow data loaded from persistence:",m));}catch(p){console.error("Failed to load workflow draft on mount:",p),s.persistence.onError&&await s.persistence.onError(p,"load");}})();},[s.id]),useEffect(()=>{if(s.persistence?.saveOnStepChange)return u.current&&clearTimeout(u.current),u.current=setTimeout(()=>{E();},s.persistence.debounceMs||1e3),()=>{u.current&&clearTimeout(u.current);}},[n.allData,E,s.persistence]);let R=useMemo(()=>n.resolvedSteps[n.currentStepIndex],[n.resolvedSteps,n.currentStepIndex]),M=useMemo(()=>R?.formConfig,[R]),P=useCallback(async c=>{if(c<0||c>=n.resolvedSteps.length)return false;let p=n.resolvedSteps[c];if(p.permissions)try{if(!(p.permissions.customGuard?await p.permissions.customGuard(l,g):!0))return console.warn(`Access denied to step "${p.id}"`),!1}catch(m){return console.error(`Permission check failed for step "${p.id}":`,m),false}if(p.hooks?.onBeforeEnter)try{await p.hooks.onBeforeEnter(n.stepData,n.allData,g);}catch(m){return console.error(`onBeforeEnter hook failed for step "${p.id}":`,m),s.analytics?.onError&&s.analytics.onError(m,g),false}d({type:"SET_TRANSITIONING",isTransitioning:true});try{return h.current&&h.current(n.currentStepIndex,c,g),d({type:"SET_CURRENT_STEP",stepIndex:c}),d({type:"MARK_STEP_VISITED",stepIndex:c}),!0}catch(m){return console.error("Step transition failed:",m),s.analytics?.onError&&s.analytics.onError(m,g),false}finally{d({type:"SET_TRANSITIONING",isTransitioning:false});}},[n.resolvedSteps,n.currentStepIndex,n.stepData,n.allData,l,g,s.analytics]),N=useCallback((c,p)=>{d({type:"SET_FIELD_VALUE",fieldId:c,value:p});},[]),$=useCallback(c=>{d({type:"SET_STEP_DATA",data:c});},[]),U=useCallback(async()=>R?{isValid:true,errors:[]}:{isValid:true,errors:[]},[R]),_=useCallback(async()=>P(n.currentStepIndex+1),[P,n.currentStepIndex]),G=useCallback(async()=>s.navigation?.allowBackNavigation?P(n.currentStepIndex-1):false,[s.navigation,n.currentStepIndex,P]),K=useCallback(async()=>!R?.allowSkip||!s.navigation?.allowStepSkipping?false:(s.analytics?.onStepSkip&&s.analytics.onStepSkip(R.id,"user_skip",g),P(n.currentStepIndex+1)),[R,s.navigation,s.analytics,g,P,n.currentStepIndex]),H=useCallback(async()=>{d({type:"SET_SUBMITTING",isSubmitting:true});try{if(k.current&&await k.current(n.allData),await A(),s.analytics?.onWorkflowComplete){let c=Date.now()-S.current;s.analytics.onWorkflowComplete(s.id,c,n.allData);}}catch(c){throw console.error("Workflow submission failed:",c),s.analytics?.onError&&s.analytics.onError(c,g),c}finally{d({type:"SET_SUBMITTING",isSubmitting:false});}},[n.allData,k,A,s.analytics,g]),z=useCallback(()=>{d({type:"RESET_WORKFLOW"});},[]),Z=useMemo(()=>({workflowState:n,workflowConfig:s,currentStep:R,context:g,formConfig:M,goToStep:P,goNext:_,goPrevious:G,skipStep:K,setValue:N,setStepData:$,validateCurrentStep:U,submitWorkflow:H,resetWorkflow:z,saveDraft:E,loadDraft:O,clearDraft:A}),[n,s,R,g,M,P,_,G,K,N,$,U,H,z,E,O,A]),Q=useCallback(async()=>{await _();},[_]);return jsx(Y.Provider,{value:Z,children:jsx(FormProvider,{formConfig:R?.formConfig,defaultValues:n?.allData[R?.id]||{},onFieldChange:N,"data-workflow-id":s.id,className:i,onSubmit:Q,children:a},R?.id)})}function I(){let a=useContext(Y);if(!a)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return a}function pe({children:a,workflowConfig:e,...o}){let[t,r]=useState(false),i=x.shouldDisplayWatermark(),l=x.getWatermarkMessage(),n=e instanceof D?e.build():e;return useEffect(()=>{r(true);},[]),jsxs("div",{style:{position:"relative"},children:[jsx(L,{...o,workflowConfig:n,children:a}),t&&i&&jsx("div",{style:{position:"absolute",top:"10px",right:"10px",background:"rgba(0, 0, 0, 0.8)",color:"white",padding:"4px 8px",borderRadius:"4px",fontSize:"12px",fontFamily:"monospace",zIndex:1e3,pointerEvents:"none",opacity:.7},children:l})]})}function ge(){let{currentStep:a}=I();if(!a)return null;let{formConfig:e,renderer:o}=a;return e?o?o(a):jsx(FormBody,{}):null}function Se({className:a,children:e,renderAs:o}){let{context:t,submitWorkflow:r,workflowState:i,workflowConfig:l,currentStep:n}=I(),{submit:d,formState:u}=useFormContext(),S=!i.isTransitioning&&!i.isSubmitting,y=async E=>{E?.preventDefault(),S&&await d(E);},C=async E=>{E?.preventDefault(),S&&await r();},w={isLastStep:t.isLastStep,canGoNext:S,isSubmitting:i.isSubmitting,onNext:y,onSubmit:C,className:a,currentStep:n,stepData:u.values||{},allData:t.allData,context:t};if(o==="children"||o===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(w)}let k=l.renderConfig?.nextButtonRenderer;if(!k)throw new Error(`No nextButtonRenderer configured for workflow "${l.id}". Please configure a nextButtonRenderer using config.setWorkflowNextButtonRenderer() or config.setWorkflowRenderConfig().`);let s=resolveRendererChildren(e,w),g={...w,children:s};return k(g)}function ve({className:a,children:e,renderAs:o}){let{context:t,goPrevious:r,workflowState:i,workflowConfig:l,currentStep:n}=I(),{formState:d}=useFormContext(),u=t.currentStepIndex>0&&l.navigation?.allowBackNavigation!==false&&!i.isTransitioning&&!i.isSubmitting;if(l.navigation?.allowBackNavigation===false)throw new Error(`WorkflowPreviousButton is rendered but allowBackNavigation is disabled in workflow "${l.id}". Either enable back navigation or remove the WorkflowPreviousButton component.`);let y={canGoPrevious:u,onPrevious:async s=>{s?.preventDefault(),u&&await r();},className:a,currentStep:n,stepData:d.values||{},allData:t.allData,context:t};if(o==="children"||o===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(y)}let w=l.renderConfig?.previousButtonRenderer;if(!w)throw new Error(`No previousButtonRenderer configured for workflow "${l.id}". Please configure a previousButtonRenderer using config.setWorkflowPreviousButtonRenderer() or config.setWorkflowRenderConfig().`);let h=resolveRendererChildren(e,y),k={...y,children:h};return w(k)}function Ie({className:a,children:e,renderAs:o}){let{currentStep:t,skipStep:r,workflowState:i,workflowConfig:l,context:n}=I(),{formState:d}=useFormContext(),u=!!t?.allowSkip&&l.navigation?.allowStepSkipping!==false&&!i.isTransitioning&&!i.isSubmitting,y={canSkip:u,onSkip:async s=>{s?.preventDefault(),u&&await r();},className:a,currentStep:t,stepData:d.values||{},allData:n.allData,context:n};if(o==="children"||o===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(y)}let w=l.renderConfig?.skipButtonRenderer;if(!w)throw new Error(`No skipButtonRenderer configured for workflow "${l.id}". Please configure a skipButtonRenderer using config.setWorkflowSkipButtonRenderer() or config.setWorkflowRenderConfig().`);let h=resolveRendererChildren(e,y),k={...y,children:h};return w(k)}function Ee({onStepClick:a,className:e,children:o,renderAs:t}){let{workflowConfig:r,workflowState:i,goToStep:l}=I(),n=C=>{a?a(C):l(C);},d={steps:i.resolvedSteps,currentStepIndex:i.currentStepIndex,visitedSteps:i.visitedSteps,onStepClick:n,className:e};if(t==="children"||t===true){if(typeof o!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return o(d)}let S=r.renderConfig?.stepperRenderer;if(!S)throw new Error(`No stepperRenderer configured for workflow "${r.id}". Please configure a stepperRenderer using config.setStepperRenderer() or config.setWorkflowRenderConfig().`);return S(d)}var B=class{constructor(e){this.name="analytics";this.version="1.0.0";this.performanceData=new Map;this.config=e;}install(e){let o={onWorkflowStart:(t,r)=>{this.track("workflow_start",{workflow_id:t,total_steps:r.totalSteps,...this.getContextData(r)}),this.config.enablePerformanceTracking&&this.performanceData.set(`workflow_${t}`,Date.now());},onWorkflowComplete:(t,r,i)=>{this.track("workflow_complete",{workflow_id:t,duration_ms:r,form_data_keys:this.config.includeFormData?Object.keys(i):void 0,...this.config.includeFormData?{form_data:i}:{}});},onWorkflowAbandon:(t,r,i)=>{this.track("workflow_abandon",{workflow_id:t,abandoned_at_step:r,completion_percentage:this.calculateCompletionPercentage(i)});},onStepStart:(t,r,i)=>{this.track("step_start",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,...this.getContextData(i)}),this.config.enablePerformanceTracking&&this.performanceData.set(`step_${t}`,r);},onStepComplete:(t,r,i,l)=>{this.track("step_complete",{step_id:t,step_index:l.currentStepIndex,workflow_id:l.workflowId,duration_ms:r,field_count:Object.keys(i).length,...this.getContextData(l)});},onStepSkip:(t,r,i)=>{this.track("step_skip",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,skip_reason:r,...this.getContextData(i)});},onValidationError:(t,r,i)=>{this.track("validation_error",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,error_count:r.length,error_codes:r.map(l=>l.code),...this.getContextData(i)});},onError:(t,r)=>{this.track("workflow_error",{workflow_id:r.workflowId,step_id:r.currentStepIndex,error_message:t.message,error_name:t.name,...this.getContextData(r)});}};e.setAnalytics(o);}track(e,o){let t=this.config.eventMapping?.[e]||e,r={...o,timestamp:Date.now(),plugin_version:this.version};for(let[i,l]of Object.entries(this.config.providers))switch(i){case "googleAnalytics":this.trackGoogleAnalytics(t,r,l);break;case "mixpanel":this.trackMixpanel(t,r);break;case "amplitude":this.trackAmplitude(t,r);break;case "custom":this.trackCustom(t,r,l);break}}trackGoogleAnalytics(e,o,t){typeof window<"u"&&window.gtag&&window.gtag("event",e,{...o,custom_map:t.customDimensions});}trackMixpanel(e,o){typeof window<"u"&&window.mixpanel&&window.mixpanel.track(e,o);}trackAmplitude(e,o){typeof window<"u"&&window.amplitude&&window.amplitude.getInstance().logEvent(e,o);}async trackCustom(e,o,t){try{await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify({event:e,properties:o})});}catch(r){console.error("Custom analytics tracking failed:",r);}}getContextData(e){return this.config.includeUserContext?{user_id:e.user?.id,is_first_step:e.isFirstStep,is_last_step:e.isLastStep,visited_steps_count:e.visitedSteps.size,browser_info:typeof window<"u"?{user_agent:navigator.userAgent,language:navigator.language,platform:navigator.platform}:void 0}:{}}calculateCompletionPercentage(e){let o=Object.keys(e).length,t=Object.values(e).filter(r=>r!=null&&r!=="").length;return o>0?t/o*100:0}};var F=class{constructor(e){this.name="validation";this.version="1.0.0";this.dependencies=[];this.debounceTimers=new Map;this.config=e;}install(e){let o=e.getSteps();for(let t of o){let r=t.hooks||{};e.updateStep(t.id,{hooks:{...r,onValidate:async(i,l)=>{let n=await this.validateStep(i,l);return this.config.onValidationComplete&&this.config.onValidationComplete(n,l),n}}});}}async validateStep(e,o){let t=[];try{if(this.config.schema){let i=await this.validateWithSchema(e,o);t.push(...i.errors);}let r=await this.validateWithRules(e,o);if(t.push(...r.errors),this.config.crossFieldValidation){let i=await this.validateCrossField(o.allData,o);t.push(...i.errors);}if(this.config.asyncRules){let i=await this.validateAsync(e,o);t.push(...i.errors);}return {isValid:t.length===0,errors:t}}catch(r){return {isValid:false,errors:[{code:"VALIDATION_ERROR",message:`Validation failed: ${r instanceof Error?r.message:String(r)}`}]}}}async validateWithSchema(e,o){if(!this.config.schema?.schema)return {isValid:true,errors:[]};try{switch(this.config.schema.type){case "zod":{let t=this.config.schema.schema.safeParse(e);if(!t.success)return {isValid:!1,errors:t.error.errors.map(r=>({code:r.code,message:r.message,path:r.path}))};break}case "yup":try{await this.config.schema.schema.validate(e,{abortEarly:!1});}catch(t){return {isValid:!1,errors:t.inner?.map(r=>({code:"YUP_VALIDATION_ERROR",message:r.message,path:r.path?[r.path]:void 0}))||[{code:"YUP_VALIDATION_ERROR",message:t.message}]}}break;case "custom":{let t=await this.config.schema.schema(e,o);if(!t.isValid)return t;break}}return {isValid:!0,errors:[]}}catch(t){return {isValid:false,errors:[{code:"SCHEMA_VALIDATION_ERROR",message:`Schema validation failed: ${t instanceof Error?t.message:String(t)}`}]}}}async validateWithRules(e,o){let t=[];if(this.config.rules.required)for(let r of this.config.rules.required)(!e[r]||typeof e[r]=="string"&&e[r].trim()==="")&&t.push({code:"REQUIRED",message:`${r} is required`,path:[r]});if(this.config.rules.email){let r=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;for(let i of this.config.rules.email)e[i]&&!r.test(e[i])&&t.push({code:"INVALID_EMAIL",message:`${i} must be a valid email address`,path:[i]});}if(this.config.rules.phone){let r=/^[\+]?[1-9][\d]{0,15}$/;for(let i of this.config.rules.phone)e[i]&&!r.test(e[i].replace(/\s/g,""))&&t.push({code:"INVALID_PHONE",message:`${i} must be a valid phone number`,path:[i]});}if(this.config.rules.minLength)for(let[r,i]of Object.entries(this.config.rules.minLength))e[r]&&e[r].length<i&&t.push({code:"MIN_LENGTH",message:`${r} must be at least ${i} characters long`,path:[r]});if(this.config.rules.maxLength)for(let[r,i]of Object.entries(this.config.rules.maxLength))e[r]&&e[r].length>i&&t.push({code:"MAX_LENGTH",message:`${r} must be no more than ${i} characters long`,path:[r]});if(this.config.rules.pattern)for(let[r,i]of Object.entries(this.config.rules.pattern))e[r]&&!i.test(e[r])&&t.push({code:"PATTERN_MISMATCH",message:`${r} format is invalid`,path:[r]});if(this.config.rules.custom){for(let[r,i]of Object.entries(this.config.rules.custom))if(e[r]){let l=await i(e[r],o);l.isValid||t.push(...l.errors.map(n=>({...n,path:[r]})));}}return {isValid:t.length===0,errors:t}}async validateCrossField(e,o){let t=[];if(!this.config.crossFieldValidation)return {isValid:true,errors:[]};for(let r of this.config.crossFieldValidation){let i={},l=true;for(let n of r.fields)if(e[n]!==void 0)i[n]=e[n];else {l=false;break}l&&((await r.validator(i,o)).isValid||t.push({code:"CROSS_FIELD_VALIDATION",message:r.message,path:r.fields}));}return {isValid:t.length===0,errors:t}}async validateAsync(e,o){let t=[];if(!this.config.asyncRules)return {isValid:true,errors:[]};let r=Object.entries(this.config.asyncRules).map(async([l,n])=>{if(!e[l])return null;let d=`${l}_${o.workflowId}`;return this.debounceTimers.has(d)&&clearTimeout(this.debounceTimers.get(d)),new Promise(u=>{let S=setTimeout(async()=>{try{let y=n.method==="GET"?`${n.url}?value=${encodeURIComponent(e[l])}`:n.url,w=await(await fetch(y,{method:n.method||"POST",headers:{"Content-Type":"application/json",...n.headers},body:n.method!=="GET"?JSON.stringify({value:e[l]}):void 0})).json();w.isValid?u(null):u({code:"ASYNC_VALIDATION_ERROR",message:w.message||`${l} validation failed`,path:[l]});}catch{u({code:"ASYNC_VALIDATION_ERROR",message:`Async validation failed for ${l}`,path:[l]});}},n.debounceMs||500);this.debounceTimers.set(d,S);})}),i=await Promise.all(r);return t.push(...i.filter(l=>l!==null)),{isValid:t.length===0,errors:t}}};
|
|
1
|
+
import {ril,resolveRendererChildren}from'@rilaykit/core';export{createZodValidator,ril}from'@rilaykit/core';import {form,FormProvider,FormBody,useFormContext}from'@rilaykit/forms';export{form}from'@rilaykit/forms';import*as q from'@noble/ed25519';import {createContext,useReducer,useRef,useMemo,useEffect,useCallback,useContext,useState}from'react';import {jsx,jsxs}from'react/jsx-runtime';var j=1751361139160,ee="8fdb6a454550326d331c3b3d1d1f8c707a371bdb6c7ea72a0a1e4ea6f1822620",f=class f{static async setLicenseKey(e){f.licenseKey=e||"",f.licenseKey?f.licenseResult=await f.validateLicense():f.licenseResult={valid:false,error:"MISSING"},f.isInitialized=true;}static async validateLicense(){if(!f.licenseKey)return {valid:false,error:"MISSING"};try{if(!f.licenseKey.startsWith("ril_"))return {valid:!1,error:"FORMAT_INVALID"};let e=f.licenseKey.slice(4),t=f.base64ToString(e).split(".");if(t.length!==3)return {valid:!1,error:"FORMAT_INVALID"};let[r,i,l]=t,n=`${r}.${i}`,d=new TextEncoder().encode(n),u=l.match(/.{2}/g);if(!u)return {valid:!1,error:"INVALID"};let S=new Uint8Array(u.map(g=>Number.parseInt(g,16))),y=f.hexToBytes(ee);if(!await q.verify(S,d,y))return {valid:!1,error:"SIGNATURE_INVALID"};let w=f.base64ToString(i.replace(/-/g,"+").replace(/_/g,"/")),h=JSON.parse(w),k=Math.floor(Date.now()/1e3);return h.e<k?{valid:!1,error:"EXPIRED",data:f.decompressPayload(h)}:j>h.e*1e3?{valid:!1,error:"EXPIRED",data:f.decompressPayload(h)}:h.p===void 0||!h.c||!h.i||!h.e||!h.t?{valid:!1,error:"INVALID"}:{valid:!0,data:f.decompressPayload(h)}}catch{return {valid:false,error:"INVALID"}}}static decompressPayload(e){return {plan:{0:"ARCHITECT",1:"FOUNDRY"}[e.p]||"ARCHITECT",company:e.c,customerId:e.i.toString(),expiry:e.e*1e3,iat:e.t*1e3}}static hexToBytes(e){let o=new Uint8Array(e.length/2);for(let t=0;t<e.length;t+=2)o[t/2]=Number.parseInt(e.substring(t,t+2),16);return o}static base64ToString(e){if(typeof atob<"u")return atob(e);if(typeof Buffer<"u")return Buffer.from(e,"base64").toString();let o="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",t="",r=0,i=e.replace(/[^A-Za-z0-9+/]/g,"");for(;r<i.length;){let l=o.indexOf(i.charAt(r++)),n=o.indexOf(i.charAt(r++)),d=o.indexOf(i.charAt(r++)),u=o.indexOf(i.charAt(r++)),S=l<<18|n<<12|d<<6|u;t+=String.fromCharCode(S>>16&255),d!==64&&(t+=String.fromCharCode(S>>8&255)),u!==64&&(t+=String.fromCharCode(S&255));}return t}static getLicenseResult(){return f.isInitialized?f.licenseResult?f.licenseResult:{valid:false,error:"MISSING"}:{valid:false,error:"MISSING"}}static shouldDisplayWatermark(){return typeof window>"u"?false:!f.getLicenseResult().valid}static getWatermarkMessage(){let e=f.getLicenseResult();return {MISSING:"Rilay Workflow - For Trial Use Only",EXPIRED:"Rilay Workflow - License Expired",INVALID:"Rilay Workflow - Invalid License",FORMAT_INVALID:"Rilay Workflow - Invalid License Format",SIGNATURE_INVALID:"Rilay Workflow - Invalid License Signature"}[e.error||"MISSING"]||""}static logLicenseStatus(){let e=f.getLicenseResult();if(e.valid)return;let t={MISSING:"\u{1F527} Rilay Workflow - Trial Mode. Purchase a license at https://rilay.io/pricing",EXPIRED:"\u26A0\uFE0F Rilay Workflow - License Expired. Please renew your license.",INVALID:"\u274C Rilay Workflow - Invalid License. Please check your license key.",FORMAT_INVALID:"\u274C Rilay Workflow - Invalid License Format. Please check your license key.",SIGNATURE_INVALID:"\u274C Rilay Workflow - Invalid License Signature. Please check your license key."}[e.error||"MISSING"];console.warn(`%c${t}`,"color: #f59e0b; font-weight: bold;");}static async getLicenseInfo(){let e=f.getLicenseResult();return !e.valid||!e.data?{}:{plan:e.data.plan,company:e.data.company,expiryDate:new Date(e.data.expiry).toLocaleDateString()}}};f.licenseKey="",f.licenseResult=null,f.isInitialized=false;var x=f;var D=class a{constructor(e,o,t,r){this.steps=[];this.navigation={allowBackNavigation:true};this.plugins=[];this.config=e,this.workflowId=o,this.workflowName=t,this.workflowDescription=r,x.logLicenseStatus();}static create(e,o,t,r){return new a(e,o,t,r)}createStepFromDefinition(e){return {id:e.id,title:e.title,description:e.description,formConfig:e.formConfig instanceof form?e.formConfig.build():e.formConfig,allowSkip:e.allowSkip||false,requiredToComplete:e.requiredToComplete!==false,hooks:e.hooks,permissions:e.permissions,isDynamic:!!e.dynamicConfig,dynamicConfig:e.dynamicConfig,renderer:e.renderer}}addStep(e){let o=this.createStepFromDefinition(e);return this.steps.push(o),this}addDynamicStep(e){return this.addStep(e)}addSteps(e){for(let o of e)this.addStep(o);return this}setNavigation(e){return this.navigation={...this.navigation,...e},this}enableBackNavigation(e=true){return this.navigation={...this.navigation,allowBackNavigation:e},this}enableStepSkipping(e=true){return this.navigation={...this.navigation,allowStepSkipping:e},this}setPersistence(e){return this.persistence=e,this}setAnalytics(e){return this.analytics=e,this}setCompletion(e){return this.completion=e,this}use(e){this.validatePluginDependencies(e),this.plugins.push(e);try{e.install(this);}catch(o){throw new Error(`Failed to install plugin "${e.name}": ${o instanceof Error?o.message:String(o)}`)}return this}validatePluginDependencies(e){if(!e.dependencies)return;let o=e.dependencies.filter(t=>!this.plugins.some(r=>r.name===t));if(o.length>0)throw new Error(`Plugin "${e.name}" requires missing dependencies: ${o.join(", ")}`)}removePlugin(e){return this.plugins=this.plugins.filter(o=>o.name!==e),this}updateStep(e,o){let t=this.steps.findIndex(r=>r.id===e);if(t===-1)throw new Error(`Step with ID "${e}" not found`);return this.steps[t]={...this.steps[t],...o},this}removeStep(e){return this.steps=this.steps.filter(o=>o.id!==e),this}getStep(e){return this.steps.find(o=>o.id===e)}getSteps(){return [...this.steps]}clearSteps(){return this.steps=[],this}clone(e,o){let t=new a(this.config,e||`${this.workflowId}-clone`,o||`${this.workflowName} (Copy)`,this.workflowDescription);return t.steps=this.steps.map(r=>({...r})),t.navigation={...this.navigation},t.persistence=this.persistence?{...this.persistence}:void 0,t.completion=this.completion?{...this.completion}:void 0,t.analytics=this.analytics?{...this.analytics}:void 0,t.plugins=[...this.plugins],t}validate(){let e=[];this.steps.length===0&&e.push("Workflow must have at least one step");let o=this.steps.map(r=>r.id),t=o.filter((r,i)=>o.indexOf(r)!==i);t.length>0&&e.push(`Duplicate step IDs: ${t.join(", ")}`);for(let r of this.plugins)if(r.dependencies){let i=r.dependencies.filter(l=>!this.plugins.some(n=>n.name===l));i.length>0&&e.push(`Plugin "${r.name}" requires missing dependencies: ${i.join(", ")}`);}return e}getStats(){return {totalSteps:this.steps.length,dynamicSteps:this.steps.filter(e=>e.isDynamic).length,pluginsInstalled:this.plugins.length,estimatedFields:this.steps.reduce((e,o)=>e+o.formConfig.allFields.length,0),hasPersistence:!!this.persistence,hasAnalytics:!!this.analytics,allowBackNavigation:this.navigation.allowBackNavigation!==false}}build(){let e=this.validate();if(e.length>0)throw new Error(`Workflow validation failed: ${e.join(", ")}`);return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:[...this.steps],navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,plugins:[...this.plugins],renderConfig:this.config.getWorkflowRenderConfig()}}toJSON(){return {id:this.workflowId,name:this.workflowName,description:this.workflowDescription,steps:this.steps,navigation:this.navigation,persistence:this.persistence,completion:this.completion,analytics:this.analytics,plugins:this.plugins.map(e=>({name:e.name,version:e.version,dependencies:e.dependencies}))}}fromJSON(e){return e.id&&(this.workflowId=e.id),e.name&&(this.workflowName=e.name),e.description&&(this.workflowDescription=e.description),e.steps&&(this.steps=e.steps),e.navigation&&(this.navigation=e.navigation),e.persistence&&(this.persistence=e.persistence),e.completion&&(this.completion=e.completion),e.analytics&&(this.analytics=e.analytics),this}};function oe(a,e,o,t){return D.create(a,e,o,t)}ril.prototype.createFlow=function(a,e,o){return D.create(this,a,e,o)};function le(a,e){switch(e.type){case "SET_CURRENT_STEP":return {...a,currentStepIndex:e.stepIndex,stepData:a.allData[a.resolvedSteps[e.stepIndex]?.id]||{}};case "SET_STEP_DATA":{let o=a.resolvedSteps[a.currentStepIndex]?.id;return {...a,stepData:e.data,allData:{...a.allData,[o]:e.data}}}case "SET_ALL_DATA":return {...a,allData:e.data};case "SET_FIELD_VALUE":{let o=a.resolvedSteps[a.currentStepIndex]?.id,t={...a.stepData,[e.fieldId]:e.value};return {...a,stepData:t,allData:{...a.allData,[o]:t}}}case "SET_ERROR":return {...a,errors:{...a.errors,[e.fieldId]:e.errors}};case "CLEAR_ERROR":{let o={...a.errors};return delete o[e.fieldId],{...a,errors:o}}case "MARK_TOUCHED":return {...a,touched:new Set([...a.touched,e.fieldId])};case "SET_VALIDATING":{let o=new Set(a.isValidating);return e.isValidating?o.add(e.fieldId):o.delete(e.fieldId),{...a,isValidating:o}}case "SET_SUBMITTING":return {...a,isSubmitting:e.isSubmitting};case "SET_TRANSITIONING":return {...a,isTransitioning:e.isTransitioning};case "MARK_STEP_VISITED":return {...a,visitedSteps:new Set([...a.visitedSteps,a.resolvedSteps[e.stepIndex]?.id])};case "SET_PERSISTED_DATA":return {...a,persistedData:e.data};case "SET_RESOLVED_STEPS":return {...a,resolvedSteps:e.steps};case "RESET_WORKFLOW":return {currentStepIndex:0,allData:{},stepData:{},errors:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:a.resolvedSteps};default:return a}}var Y=createContext(null);function L({children:a,workflowConfig:e,defaultValues:o={},onStepChange:t,onWorkflowComplete:r,className:i,user:l}){let[n,d]=useReducer(le,{currentStepIndex:0,allData:o,stepData:{},errors:{},touched:new Set,isValidating:new Set,visitedSteps:new Set,isSubmitting:false,isTransitioning:false,resolvedSteps:e.steps}),u=useRef(null),S=useRef(Date.now()),y=useRef(new Map),R=useRef(false),w=useRef(null),h=useRef(t),k=useRef(r);h.current=t,k.current=r;let s=useMemo(()=>e,[e]),g=useMemo(()=>({workflowId:s.id,currentStepIndex:n.currentStepIndex,totalSteps:n.resolvedSteps.length,allData:n.allData,stepData:n.stepData,isFirstStep:n.currentStepIndex===0,isLastStep:n.currentStepIndex===n.resolvedSteps.length-1,visitedSteps:n.visitedSteps,user:l}),[s.id,n.currentStepIndex,n.resolvedSteps.length,n.allData,n.stepData,n.visitedSteps,l]);useEffect(()=>{(async()=>{let p=[];for(let m of s.steps)if(m.isDynamic&&m.dynamicConfig)try{let V=await m.dynamicConfig.resolver(n.allData,g);p.push(...V);}catch(V){console.error(`Failed to resolve dynamic step "${m.id}":`,V),p.push({...m,isDynamic:false});}else p.push(m);d({type:"SET_RESOLVED_STEPS",steps:p});})();},[s.steps,n.allData,g]),useEffect(()=>{s.analytics?.onWorkflowStart&&!R.current&&(R.current=true,s.analytics.onWorkflowStart(s.id,g));},[s.id,s.analytics,g]),useEffect(()=>{let c=n.resolvedSteps[n.currentStepIndex];if(c&&w.current!==c.id){if(w.current&&s.analytics?.onStepComplete){let p=y.current.get(w.current);p&&s.analytics.onStepComplete(w.current,Date.now()-p,n.stepData,g);}w.current=c.id,y.current.set(c.id,Date.now()),s.analytics?.onStepStart&&s.analytics.onStepStart(c.id,Date.now(),g);}},[n.currentStepIndex,n.resolvedSteps,s.analytics,g]);let E=useCallback(async()=>{if(s.persistence)try{let c={workflowId:s.id,currentStepIndex:n.currentStepIndex,allData:n.allData,metadata:{timestamp:Date.now(),version:"1.0.0",userId:l?.id,sessionId:crypto.randomUUID()}},p=s.persistence.key||`workflow-${s.id}`;await s.persistence.adapter.save(p,c),s.persistence.onSave&&await s.persistence.onSave(c);}catch(c){console.error("Failed to save workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"save");}},[s,n.currentStepIndex,n.allData,l]),O=useCallback(async()=>{if(s.persistence)try{let c=s.persistence.key||`workflow-${s.id}`,p=await s.persistence.adapter.load(c);p&&p.workflowId===s.id&&(d({type:"SET_ALL_DATA",data:p.allData}),d({type:"SET_CURRENT_STEP",stepIndex:p.currentStepIndex}),d({type:"SET_PERSISTED_DATA",data:p}),s.persistence.onLoad&&await s.persistence.onLoad(p));}catch(c){console.error("Failed to load workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"load");}},[s]),A=useCallback(async()=>{if(s.persistence)try{let c=s.persistence.key||`workflow-${s.id}`;await s.persistence.adapter.remove(c);}catch(c){console.error("Failed to clear workflow draft:",c),s.persistence.onError&&await s.persistence.onError(c,"remove");}},[s]);useEffect(()=>{s.persistence&&(async()=>{try{let p=s.persistence.key||`workflow-${s.id}`,m=await s.persistence.adapter.load(p);m&&m.workflowId===s.id&&(d({type:"SET_ALL_DATA",data:m.allData}),d({type:"SET_CURRENT_STEP",stepIndex:m.currentStepIndex}),d({type:"SET_PERSISTED_DATA",data:m}),s.persistence.onLoad&&await s.persistence.onLoad(m),console.log("Workflow data loaded from persistence:",m));}catch(p){console.error("Failed to load workflow draft on mount:",p),s.persistence.onError&&await s.persistence.onError(p,"load");}})();},[s.id]),useEffect(()=>{if(s.persistence?.saveOnStepChange)return u.current&&clearTimeout(u.current),u.current=setTimeout(()=>{E();},s.persistence.debounceMs||1e3),()=>{u.current&&clearTimeout(u.current);}},[n.allData,E,s.persistence]);let C=useMemo(()=>n.resolvedSteps[n.currentStepIndex],[n.resolvedSteps,n.currentStepIndex]),M=useMemo(()=>C?.formConfig,[C]),P=useCallback(async c=>{if(c<0||c>=n.resolvedSteps.length)return false;let p=n.resolvedSteps[c];if(p.permissions)try{if(!(p.permissions.customGuard?await p.permissions.customGuard(l,g):!0))return console.warn(`Access denied to step "${p.id}"`),!1}catch(m){return console.error(`Permission check failed for step "${p.id}":`,m),false}if(p.hooks?.onBeforeEnter)try{await p.hooks.onBeforeEnter(n.stepData,n.allData,g);}catch(m){return console.error(`onBeforeEnter hook failed for step "${p.id}":`,m),s.analytics?.onError&&s.analytics.onError(m,g),false}d({type:"SET_TRANSITIONING",isTransitioning:true});try{return h.current&&h.current(n.currentStepIndex,c,g),d({type:"SET_CURRENT_STEP",stepIndex:c}),d({type:"MARK_STEP_VISITED",stepIndex:c}),!0}catch(m){return console.error("Step transition failed:",m),s.analytics?.onError&&s.analytics.onError(m,g),false}finally{d({type:"SET_TRANSITIONING",isTransitioning:false});}},[n.resolvedSteps,n.currentStepIndex,n.stepData,n.allData,l,g,s.analytics]),N=useCallback((c,p)=>{d({type:"SET_FIELD_VALUE",fieldId:c,value:p});},[]),$=useCallback(c=>{d({type:"SET_STEP_DATA",data:c});},[]),U=useCallback(async()=>C?{isValid:true,errors:[]}:{isValid:true,errors:[]},[C]),_=useCallback(async()=>P(n.currentStepIndex+1),[P,n.currentStepIndex]),G=useCallback(async()=>s.navigation?.allowBackNavigation?P(n.currentStepIndex-1):false,[s.navigation,n.currentStepIndex,P]),K=useCallback(async()=>!C?.allowSkip||!s.navigation?.allowStepSkipping?false:(s.analytics?.onStepSkip&&s.analytics.onStepSkip(C.id,"user_skip",g),P(n.currentStepIndex+1)),[C,s.navigation,s.analytics,g,P,n.currentStepIndex]),H=useCallback(async()=>{d({type:"SET_SUBMITTING",isSubmitting:true});try{if(k.current&&await k.current(n.allData),await A(),s.analytics?.onWorkflowComplete){let c=Date.now()-S.current;s.analytics.onWorkflowComplete(s.id,c,n.allData);}}catch(c){throw console.error("Workflow submission failed:",c),s.analytics?.onError&&s.analytics.onError(c,g),c}finally{d({type:"SET_SUBMITTING",isSubmitting:false});}},[n.allData,k,A,s.analytics,g]),z=useCallback(()=>{d({type:"RESET_WORKFLOW"});},[]),Z=useMemo(()=>({workflowState:n,workflowConfig:s,currentStep:C,context:g,formConfig:M,goToStep:P,goNext:_,goPrevious:G,skipStep:K,setValue:N,setStepData:$,validateCurrentStep:U,submitWorkflow:H,resetWorkflow:z,saveDraft:E,loadDraft:O,clearDraft:A}),[n,s,C,g,M,P,_,G,K,N,$,U,H,z,E,O,A]),Q=useCallback(async()=>{await _();},[_]);return jsx(Y.Provider,{value:Z,children:jsx(FormProvider,{formConfig:C?.formConfig,defaultValues:n?.allData[C?.id]||{},onFieldChange:N,"data-workflow-id":s.id,className:i,onSubmit:Q,children:a})})}function I(){let a=useContext(Y);if(!a)throw new Error("useWorkflowContext must be used within a WorkflowProvider");return a}function pe({children:a,workflowConfig:e,...o}){let[t,r]=useState(false),i=x.shouldDisplayWatermark(),l=x.getWatermarkMessage(),n=e instanceof D?e.build():e;return useEffect(()=>{r(true);},[]),jsxs("div",{style:{position:"relative"},children:[jsx(L,{...o,workflowConfig:n,children:a}),t&&i&&jsx("div",{style:{position:"absolute",top:"10px",right:"10px",background:"rgba(0, 0, 0, 0.8)",color:"white",padding:"4px 8px",borderRadius:"4px",fontSize:"12px",fontFamily:"monospace",zIndex:1e3,pointerEvents:"none",opacity:.7},children:l})]})}function ge(){let{currentStep:a}=I();if(!a)return null;let{formConfig:e,renderer:o}=a;return e?o?o(a):jsx(FormBody,{}):null}function Se({className:a,children:e,renderAs:o}){let{context:t,submitWorkflow:r,workflowState:i,workflowConfig:l,currentStep:n}=I(),{submit:d,formState:u}=useFormContext(),S=!i.isTransitioning&&!i.isSubmitting,y=async E=>{E?.preventDefault(),S&&await d(E);},R=async E=>{E?.preventDefault(),S&&await r();},w={isLastStep:t.isLastStep,canGoNext:S,isSubmitting:i.isSubmitting,onNext:y,onSubmit:R,className:a,currentStep:n,stepData:u.values||{},allData:t.allData,context:t};if(o==="children"||o===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(w)}let k=l.renderConfig?.nextButtonRenderer;if(!k)throw new Error(`No nextButtonRenderer configured for workflow "${l.id}". Please configure a nextButtonRenderer using config.setWorkflowNextButtonRenderer() or config.setWorkflowRenderConfig().`);let s=resolveRendererChildren(e,w),g={...w,children:s};return k(g)}function ve({className:a,children:e,renderAs:o}){let{context:t,goPrevious:r,workflowState:i,workflowConfig:l,currentStep:n}=I(),{formState:d}=useFormContext(),u=t.currentStepIndex>0&&l.navigation?.allowBackNavigation!==false&&!i.isTransitioning&&!i.isSubmitting;if(l.navigation?.allowBackNavigation===false)throw new Error(`WorkflowPreviousButton is rendered but allowBackNavigation is disabled in workflow "${l.id}". Either enable back navigation or remove the WorkflowPreviousButton component.`);let y={canGoPrevious:u,onPrevious:async s=>{s?.preventDefault(),u&&await r();},className:a,currentStep:n,stepData:d.values||{},allData:t.allData,context:t};if(o==="children"||o===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(y)}let w=l.renderConfig?.previousButtonRenderer;if(!w)throw new Error(`No previousButtonRenderer configured for workflow "${l.id}". Please configure a previousButtonRenderer using config.setWorkflowPreviousButtonRenderer() or config.setWorkflowRenderConfig().`);let h=resolveRendererChildren(e,y),k={...y,children:h};return w(k)}function Ie({className:a,children:e,renderAs:o}){let{currentStep:t,skipStep:r,workflowState:i,workflowConfig:l,context:n}=I(),{formState:d}=useFormContext(),u=!!t?.allowSkip&&l.navigation?.allowStepSkipping!==false&&!i.isTransitioning&&!i.isSubmitting,y={canSkip:u,onSkip:async s=>{s?.preventDefault(),u&&await r();},className:a,currentStep:t,stepData:d.values||{},allData:n.allData,context:n};if(o==="children"||o===true){if(typeof e!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return e(y)}let w=l.renderConfig?.skipButtonRenderer;if(!w)throw new Error(`No skipButtonRenderer configured for workflow "${l.id}". Please configure a skipButtonRenderer using config.setWorkflowSkipButtonRenderer() or config.setWorkflowRenderConfig().`);let h=resolveRendererChildren(e,y),k={...y,children:h};return w(k)}function Ee({onStepClick:a,className:e,children:o,renderAs:t}){let{workflowConfig:r,workflowState:i,goToStep:l}=I(),n=R=>{a?a(R):l(R);},d={steps:i.resolvedSteps,currentStepIndex:i.currentStepIndex,visitedSteps:i.visitedSteps,onStepClick:n,className:e};if(t==="children"||t===true){if(typeof o!="function")throw new Error('When renderAs="children" is used, children must be a function that returns React elements');return o(d)}let S=r.renderConfig?.stepperRenderer;if(!S)throw new Error(`No stepperRenderer configured for workflow "${r.id}". Please configure a stepperRenderer using config.setStepperRenderer() or config.setWorkflowRenderConfig().`);return S(d)}var B=class{constructor(e){this.name="analytics";this.version="1.0.0";this.performanceData=new Map;this.config=e;}install(e){let o={onWorkflowStart:(t,r)=>{this.track("workflow_start",{workflow_id:t,total_steps:r.totalSteps,...this.getContextData(r)}),this.config.enablePerformanceTracking&&this.performanceData.set(`workflow_${t}`,Date.now());},onWorkflowComplete:(t,r,i)=>{this.track("workflow_complete",{workflow_id:t,duration_ms:r,form_data_keys:this.config.includeFormData?Object.keys(i):void 0,...this.config.includeFormData?{form_data:i}:{}});},onWorkflowAbandon:(t,r,i)=>{this.track("workflow_abandon",{workflow_id:t,abandoned_at_step:r,completion_percentage:this.calculateCompletionPercentage(i)});},onStepStart:(t,r,i)=>{this.track("step_start",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,...this.getContextData(i)}),this.config.enablePerformanceTracking&&this.performanceData.set(`step_${t}`,r);},onStepComplete:(t,r,i,l)=>{this.track("step_complete",{step_id:t,step_index:l.currentStepIndex,workflow_id:l.workflowId,duration_ms:r,field_count:Object.keys(i).length,...this.getContextData(l)});},onStepSkip:(t,r,i)=>{this.track("step_skip",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,skip_reason:r,...this.getContextData(i)});},onValidationError:(t,r,i)=>{this.track("validation_error",{step_id:t,step_index:i.currentStepIndex,workflow_id:i.workflowId,error_count:r.length,error_codes:r.map(l=>l.code),...this.getContextData(i)});},onError:(t,r)=>{this.track("workflow_error",{workflow_id:r.workflowId,step_id:r.currentStepIndex,error_message:t.message,error_name:t.name,...this.getContextData(r)});}};e.setAnalytics(o);}track(e,o){let t=this.config.eventMapping?.[e]||e,r={...o,timestamp:Date.now(),plugin_version:this.version};for(let[i,l]of Object.entries(this.config.providers))switch(i){case "googleAnalytics":this.trackGoogleAnalytics(t,r,l);break;case "mixpanel":this.trackMixpanel(t,r);break;case "amplitude":this.trackAmplitude(t,r);break;case "custom":this.trackCustom(t,r,l);break}}trackGoogleAnalytics(e,o,t){typeof window<"u"&&window.gtag&&window.gtag("event",e,{...o,custom_map:t.customDimensions});}trackMixpanel(e,o){typeof window<"u"&&window.mixpanel&&window.mixpanel.track(e,o);}trackAmplitude(e,o){typeof window<"u"&&window.amplitude&&window.amplitude.getInstance().logEvent(e,o);}async trackCustom(e,o,t){try{await fetch(t.endpoint,{method:"POST",headers:{"Content-Type":"application/json",...t.headers},body:JSON.stringify({event:e,properties:o})});}catch(r){console.error("Custom analytics tracking failed:",r);}}getContextData(e){return this.config.includeUserContext?{user_id:e.user?.id,is_first_step:e.isFirstStep,is_last_step:e.isLastStep,visited_steps_count:e.visitedSteps.size,browser_info:typeof window<"u"?{user_agent:navigator.userAgent,language:navigator.language,platform:navigator.platform}:void 0}:{}}calculateCompletionPercentage(e){let o=Object.keys(e).length,t=Object.values(e).filter(r=>r!=null&&r!=="").length;return o>0?t/o*100:0}};var F=class{constructor(e){this.name="validation";this.version="1.0.0";this.dependencies=[];this.debounceTimers=new Map;this.config=e;}install(e){let o=e.getSteps();for(let t of o){let r=t.hooks||{};e.updateStep(t.id,{hooks:{...r,onValidate:async(i,l)=>{let n=await this.validateStep(i,l);return this.config.onValidationComplete&&this.config.onValidationComplete(n,l),n}}});}}async validateStep(e,o){let t=[];try{if(this.config.schema){let i=await this.validateWithSchema(e,o);t.push(...i.errors);}let r=await this.validateWithRules(e,o);if(t.push(...r.errors),this.config.crossFieldValidation){let i=await this.validateCrossField(o.allData,o);t.push(...i.errors);}if(this.config.asyncRules){let i=await this.validateAsync(e,o);t.push(...i.errors);}return {isValid:t.length===0,errors:t}}catch(r){return {isValid:false,errors:[{code:"VALIDATION_ERROR",message:`Validation failed: ${r instanceof Error?r.message:String(r)}`}]}}}async validateWithSchema(e,o){if(!this.config.schema?.schema)return {isValid:true,errors:[]};try{switch(this.config.schema.type){case "zod":{let t=this.config.schema.schema.safeParse(e);if(!t.success)return {isValid:!1,errors:t.error.errors.map(r=>({code:r.code,message:r.message,path:r.path}))};break}case "yup":try{await this.config.schema.schema.validate(e,{abortEarly:!1});}catch(t){return {isValid:!1,errors:t.inner?.map(r=>({code:"YUP_VALIDATION_ERROR",message:r.message,path:r.path?[r.path]:void 0}))||[{code:"YUP_VALIDATION_ERROR",message:t.message}]}}break;case "custom":{let t=await this.config.schema.schema(e,o);if(!t.isValid)return t;break}}return {isValid:!0,errors:[]}}catch(t){return {isValid:false,errors:[{code:"SCHEMA_VALIDATION_ERROR",message:`Schema validation failed: ${t instanceof Error?t.message:String(t)}`}]}}}async validateWithRules(e,o){let t=[];if(this.config.rules.required)for(let r of this.config.rules.required)(!e[r]||typeof e[r]=="string"&&e[r].trim()==="")&&t.push({code:"REQUIRED",message:`${r} is required`,path:[r]});if(this.config.rules.email){let r=/^[^\s@]+@[^\s@]+\.[^\s@]+$/;for(let i of this.config.rules.email)e[i]&&!r.test(e[i])&&t.push({code:"INVALID_EMAIL",message:`${i} must be a valid email address`,path:[i]});}if(this.config.rules.phone){let r=/^[\+]?[1-9][\d]{0,15}$/;for(let i of this.config.rules.phone)e[i]&&!r.test(e[i].replace(/\s/g,""))&&t.push({code:"INVALID_PHONE",message:`${i} must be a valid phone number`,path:[i]});}if(this.config.rules.minLength)for(let[r,i]of Object.entries(this.config.rules.minLength))e[r]&&e[r].length<i&&t.push({code:"MIN_LENGTH",message:`${r} must be at least ${i} characters long`,path:[r]});if(this.config.rules.maxLength)for(let[r,i]of Object.entries(this.config.rules.maxLength))e[r]&&e[r].length>i&&t.push({code:"MAX_LENGTH",message:`${r} must be no more than ${i} characters long`,path:[r]});if(this.config.rules.pattern)for(let[r,i]of Object.entries(this.config.rules.pattern))e[r]&&!i.test(e[r])&&t.push({code:"PATTERN_MISMATCH",message:`${r} format is invalid`,path:[r]});if(this.config.rules.custom){for(let[r,i]of Object.entries(this.config.rules.custom))if(e[r]){let l=await i(e[r],o);l.isValid||t.push(...l.errors.map(n=>({...n,path:[r]})));}}return {isValid:t.length===0,errors:t}}async validateCrossField(e,o){let t=[];if(!this.config.crossFieldValidation)return {isValid:true,errors:[]};for(let r of this.config.crossFieldValidation){let i={},l=true;for(let n of r.fields)if(e[n]!==void 0)i[n]=e[n];else {l=false;break}l&&((await r.validator(i,o)).isValid||t.push({code:"CROSS_FIELD_VALIDATION",message:r.message,path:r.fields}));}return {isValid:t.length===0,errors:t}}async validateAsync(e,o){let t=[];if(!this.config.asyncRules)return {isValid:true,errors:[]};let r=Object.entries(this.config.asyncRules).map(async([l,n])=>{if(!e[l])return null;let d=`${l}_${o.workflowId}`;return this.debounceTimers.has(d)&&clearTimeout(this.debounceTimers.get(d)),new Promise(u=>{let S=setTimeout(async()=>{try{let y=n.method==="GET"?`${n.url}?value=${encodeURIComponent(e[l])}`:n.url,w=await(await fetch(y,{method:n.method||"POST",headers:{"Content-Type":"application/json",...n.headers},body:n.method!=="GET"?JSON.stringify({value:e[l]}):void 0})).json();w.isValid?u(null):u({code:"ASYNC_VALIDATION_ERROR",message:w.message||`${l} validation failed`,path:[l]});}catch{u({code:"ASYNC_VALIDATION_ERROR",message:`Async validation failed for ${l}`,path:[l]});}},n.debounceMs||500);this.debounceTimers.set(d,S);})}),i=await Promise.all(r);return t.push(...i.filter(l=>l!==null)),{isValid:t.length===0,errors:t}}};
|
|
2
2
|
export{B as AnalyticsPlugin,x as RilayLicenseManager,F as ValidationPlugin,pe as Workflow,ge as WorkflowBody,Se as WorkflowNextButton,ve as WorkflowPreviousButton,L as WorkflowProvider,Ie as WorkflowSkipButton,Ee as WorkflowStepper,oe as createFlow,D as flow,I as useWorkflowContext};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rilaykit/workflow",
|
|
3
|
-
"version": "2.0.
|
|
3
|
+
"version": "2.0.1",
|
|
4
4
|
"description": "Commercial workflow and multi-step form utilities for RilayKit - License required for all use",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"types": "dist/index.d.ts",
|
|
@@ -26,8 +26,8 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"@noble/ed25519": "^1.7.1",
|
|
29
|
-
"@rilaykit/
|
|
30
|
-
"@rilaykit/
|
|
29
|
+
"@rilaykit/forms": "2.0.1",
|
|
30
|
+
"@rilaykit/core": "2.0.1"
|
|
31
31
|
},
|
|
32
32
|
"peerDependencies": {
|
|
33
33
|
"react": ">=18.0.0",
|