@inploi/flows 4.0.1 → 4.0.3
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/interpreter.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { FlowNode } from '@inploi/core/flows';
|
|
2
|
-
import { InploiRpcClient, AnalyticsService, Logger } from '@inploi/sdk';
|
|
2
|
+
import { InploiRpcClient, AnalyticsService, Logger, PlatformClient } from '@inploi/sdk';
|
|
3
3
|
import { F as FlowSubmissions, a as FlowInput, R as Result, V as ValiError } from './result-e69ff761.js';
|
|
4
4
|
import { TFunction } from './i18n.mjs';
|
|
5
5
|
import { LinkedList } from './linked-list.mjs';
|
|
@@ -60,6 +60,7 @@ type FlowInterpreterParams = {
|
|
|
60
60
|
customProperties?: Record<string, unknown>;
|
|
61
61
|
};
|
|
62
62
|
logger: Logger;
|
|
63
|
+
platformClient?: PlatformClient;
|
|
63
64
|
t: TFunction;
|
|
64
65
|
};
|
|
65
66
|
type FlowActions = {
|
package/dist/interpreter.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{A as S,B as V,C as W,D as A,E as X,a as Y,b as P,c as z,d as k,e as K,f as h,g as $,h as C,i as E,j as B,k as q,l as G,m as L,n as w,o as v,p as R,q as T,r as p,s as O,t as f,u as y,v as d,w as c,x as D,z as U}from"./chunk-H5IXVEP2.mjs";import{b as Q}from"./chunk-DKKJHDKM.mjs";var M=Q(Y());var H=({condition:r,context:e,submissions:l,ifBlock:a})=>{let[u,...o]=r.compareKey.split(".");if(!u)return!1;let t=V({context:e,key:u,path:o,submissions:l});if(!t)return!1;switch(t.type){case"address":{let n=(0,M.default)(t.value,o.join("."));switch(r.compare){case"equals":return n===r.compareValue;case"contains":return n?n.includes(r.compareValue):!1;case"notEquals":return n!==r.compareValue;case"notContains":return n?!n.includes(r.compareValue):!0}break}case"integration":{if(typeof t.value!="object"||Array.isArray(t.value))return!1;let n=(0,M.default)(t.value,o.join(".")),s={...a,data:{...a.data,compareKey:"_temp"}};switch(typeof n){case"boolean":return _(s,{submissions:{_temp:{value:n,type:"boolean"}},context:e});case"string":return _(s,{submissions:{_temp:{value:n,type:"string"}},context:e});case"number":return _(s,{submissions:{_temp:{value:n,type:"number"}},context:e});case"object":return Array.isArray(n)&&n.every(i=>typeof i=="string")?_(s,{submissions:{_temp:{value:n,type:"enum"}},context:e}):!1}break}case"boolean":{let n=r.compareValue==="true";switch(r.compare){case"equals":return t.value===n;case"notEquals":return t.value!==n}break}case"phone":case"string":{let n=t.type==="phone"?t.value.countryCode+t.value.phoneNumber:t.value;switch(r.compare){case"equals":return n===r.compareValue;case"contains":return n?n.includes(r.compareValue):!1;case"notEquals":return n!==r.compareValue;case"notContains":return n?!n.includes(r.compareValue):!0}break}case"number":{try{let n=Number(r.compareValue);switch(r.compare){case"equals":return t.value===n;case"notEquals":return t.value!==n;case"greaterThan":return t.value>n;case"greaterThanOrEqualTo":return t.value>=n;case"lessThan":return t.value<n;case"lessThanOrEqualTo":return t.value<=n}}catch{return console.error(`Failed to parse number in if-block ${a.id}`,t.value),!1}break}case"enum":switch(r.compare){case"equals":return t.value.length===1&&t.value[0]===r.compareValue;case"notEquals":return t.value.length===1&&t.value[0]!==r.compareValue;case"contains":return t.value.includes(r.compareValue);case"notContains":return!t.value.includes(r.compareValue)}break;case"file":break;default:break}},_=(r,{context:e,submissions:l})=>{let a="combinator"in r.data?r.data.conditions:[r.data];if(("combinator"in r.data?r.data.combinator:"and")==="or"){for(let o of a)if(H({condition:o,context:e,submissions:l,ifBlock:r}))return!0;return!1}else{for(let o of a)if(!H({condition:o,context:e,submissions:l,ifBlock:r}))return!1;return!0}};var J=Q(Y());var me=/{{\s*([^}]+?)\s*(?:\|\s*([^}]+?)\s*)?}}/g,I=(r,{context:e,submissions:l})=>r.replace(me,(a,u,o="")=>{let[t,...n]=u.trim().split("."),s=V({key:t,path:n,submissions:l,context:e});if(!s)return o;switch(s.type){case"boolean":return s.value===!0?"true":"false";case"file":return s.value.map(i=>`${i.name} (${A(i.sizeKb)})`).join(", ");case"enum":return s.value.join(", ");case"address":return Object.values(s.value).filter(i=>i&&i.trim().length>0).join(", ");case"number":case"string":return s.value?s.value.toString():o;case"phone":return X(s.value);case"integration":{if(typeof s.value!="object"||Array.isArray(s.value))break;let i=(0,J.default)(s.value,n.join("."));switch(typeof i){case"boolean":return i===!0?"true":"false";case"string":return i;case"number":return i.toString();case"object":if(Array.isArray(i)&&i.every(m=>typeof m=="string"))return i.join(", ")}break}default:}return o});async function*Z(r){let{node:e,config:{logger:l,analytics:a,submissions:u,next:o}}=r;return a.service.log({event:"IDENTIFY",properties:{identifier:S({key:e.data.key,submissions:u}).toString(),first_name:e.data.firstName?S({key:e.data.firstName,submissions:u}).toString():void 0,last_name:e.data.lastName?S({key:e.data.lastName,submissions:u}).toString():void 0,email:e.data.email?S({key:e.data.email,submissions:u}).toString():void 0,phone_number:e.data.phoneNumber?S({key:e.data.phoneNumber,submissions:u}).toString():void 0,custom_traits:e.data.customTraits?Object.fromEntries(e.data.customTraits.map(({key:t,value:n})=>[t,u[n]?.value])):void 0}}).catch(l.error),o(e.nextId)}import{endpoint as pe,typed as ce}from"@inploi/sdk";var ee=v({success:G(),integration_response:v({service:R(p()),status:w(),data:O(),error:L(v({message:p(),data:O()}))})}),fe=pe({pathname:"/flow/submit",method:"POST",schema:{response:ee,body:ce()}});async function*te(r){let{node:e,config:{rpcClient:l,submissions:a,actions:u,next:o,analytics:t,logger:n,context:s}}=r;return e.data.skipConfirmation!==!0&&(yield u.input("submit",{config:{key:e.data.key??"_SUBMIT",label:e.data.submitLabel},validate:async()=>{let m=D(t.service.getSessionInfo)();m.err&&n.error(m.val.originalError);try{let g=await l.request(fe,{body:{log_submit:!1,integration_id:e.data.integrationId,anonymous_id:m.ok?m.val.anonymous_id:void 0,session_id:m.ok?m.val.session_id:void 0,job:s.job,submissions:U(a)}}),b=y(ee,g);return b.success===!1?c(b.issues):d(b.output)}catch(g){let b=[{input:g,origin:"value",reason:"unknown",validation:"API error",message:g instanceof Error?g.message:"toString"in g?g.toString():"Unknown error"}];return c(b)}}})),o(e.nextId)}var N=f(L(R(p())),E(r=>r===null?void 0:r)),ye=({node:r})=>{let e=r.data.keys;return v({[e.line1??"line1"]:N,[e.line2??"line2"]:N,[e.line3??"line3"]:N,[e.city??"city"]:N,[e.country??"country"]:N,[e.postcode??"postcode"]:N,[e.state??"state"]:N})};async function*re(r){let{node:e,config:{submissions:l,actions:a,next:u}}=r;return yield a.text({author:"bot",message:e.data.question}),yield a.input("address",{config:{key:e.data.key,keys:e.data.keys,placeholder:e.data.placeholder,optional:e.data.optional},validate:o=>{if(e.data.optional&&o===null)return d(o);let t=ye(r),n=y(t,o);return n.success===!1?c(n.issues):(l[e.data.key]={type:"address",value:n.output},d(o))}}),u(e.nextId)}var ge=["true","false"],ve=T(ge);async function*ne(r){let{node:e,config:{submissions:l,actions:a,next:u}}=r;return yield a.text({author:"bot",message:e.data.question}),yield a.input("boolean",{config:{key:e.data.key,labels:{false:e.data.falseLabel,true:e.data.trueLabel},optional:e.data.optional},validate:o=>{if(e.data.optional&&o===null)return d(o);let t=y(ve,o);return t.success===!1?c(t.issues):(l[e.data.key]={type:"boolean",value:t.output==="true"},d(o))}}),u(e.nextId)}async function*ae(r){let{node:e,config:{submissions:l,actions:a,next:u}}=r;yield a.text({author:"bot",message:e.data.question});let o=q(T(e.data.options.map(t=>t.value)));return yield a.input("multiple-choice",{config:{key:e.data.key,options:e.data.options,maxSelected:e.data.maxSelected,minSelected:e.data.minSelected},validate:t=>{if(e.data.minSelected===0&&t===null)return d(t);let n=y(o,t);return n.success===!1?c(n.issues):(l[e.data.key]={type:"enum",value:n.output},d(t))}}),u(e.nextId)}async function*oe(r){let{node:e,config:{submissions:l,actions:a,next:u,t:o}}=r;return yield a.text({author:"bot",message:e.data.question}),yield a.input("file",{config:{key:e.data.key,allowMultiple:e.data.multiple===!0,extensions:e.data.extensions,fileSizeLimitKib:e.data.maxSizeKb,optional:e.data.optional},validate:t=>{if(e.data.optional&&t===null)return d(t);let n=e.data.optional?0:1,s=e.data.multiple?Number.POSITIVE_INFINITY:1,i=e.data.maxSizeKb??0,m=e.data.extensions.map(F=>F.toLowerCase()),g=f(q(v({name:f(p(o("validation_empty")),P(F=>{let j=W(F);return j.ok===!1?!1:m.includes(j.val.toLowerCase())},o("validation_file_ext",{ext:m.join(", ")}))),data:p(),sizeKb:w()})),h(n,o("validation_file_min",{count:n})),k(s,o("validation_file_max",{count:s})),P(F=>F.reduce((le,de)=>le+de.sizeKb,0)<=i,o("validation_file_size",{size:A(i)}))),b=y(g,t);return b.success===!1?c(b.issues):(l[e.data.key]={type:"file",value:b.output},d(t))}}),u(e.nextId)}var be=({node:r,config:{t:e}})=>{let l=r.data.min??Number.MIN_SAFE_INTEGER,a=r.data.max??Number.MAX_SAFE_INTEGER,u=r.data.decimalCases??0;return f(w(e("validation_number")),$(l,e("validation_number_min",{min:l})),K(a,e("validation_number_max",{max:a})),P(o=>o===Number(o.toFixed(u)),e("validation_number_decimal_cases",{count:u})))};async function*se(r){let{node:e,config:{submissions:l,actions:a,next:u}}=r;yield a.text({author:"bot",message:e.data.question});let o=l[e.data.key];return yield a.input("number",{config:{key:e.data.key,placeholder:e.data.placeholder,optional:e.data.optional,decimalCases:e.data.decimalCases,max:e.data.max,min:e.data.min,defaultValue:o?.type==="number"?o.value.toString():void 0},validate:t=>{if(e.data.optional&&t===null)return d(t);let n=be(r),s=y(n,t);return s.success===!1?c(s.issues):(l[e.data.key]={type:"number",value:s.output},d(t))}}),u(e.nextId)}var he=({node:r,config:{t:e}})=>v({countryCode:f(p(e("validation_country_code")),C(/^\+?[0-9 -]+$/,e("validation_country_code"))),phoneNumber:f(p(e("validation_phone")),C(/^\+?[0-9 -]+$/,e("validation_phone")),h(r.data.minChars,e("validation_min_chars",{count:r.data.minChars})),E(l=>l.replace(/[^0-9]/g,"")))});async function*ie(r){let{node:e,config:{actions:l,next:a,submissions:u}}=r;yield l.text({author:"bot",message:e.data.question});let o=u[e.data.key];return yield l.input("phone",{config:{key:e.data.key,minChars:e.data.minChars,defaultValue:o?.type==="phone"?o.value:{countryCode:e.data.defaultCountryCode},placeholder:e.data.placeholder,submissionFormat:"phone",optional:e.data.optional},validate:t=>{if(e.data.optional&&t===null)return d(t);let n=he(r),s=y(n,t);return s.success===!1?c(s.issues):(u[e.data.key]={type:"address",value:s.output},d(t))}}),a(e.nextId)}var Ie=({node:r,config:{t:e,logger:l}})=>{let a={date:e("validation_date"),email:e("validation_email"),url:e("validation_url"),maxLength:e("validation_max_chars",{count:r.data.maxChars??999}),minLength:e("validation_min_chars",{count:r.data.minChars??1})};switch(r.data.format){case"date":return f(p(a.date),C(/^\d{4}-\d{2}-\d{2}$/,a.date));case"email":return f(p(a.email),z(a.email),h(r.data.minChars??1,a.minLength),k(r.data.maxChars??1/0,a.maxLength));case"text":return f(p(),h(r.data.minChars??1,a.minLength),k(r.data.maxChars??1/0,a.maxLength));case"url":return f(p(),B(a.url),h(r.data.minChars??1,a.minLength),k(r.data.maxChars??1/0,a.maxLength));case"phone":return f(p(),h(r.data.minChars??1,a.minLength),k(r.data.maxChars??1/0,a.maxLength));default:return r.data.format,l.error(`Unsupported question-text format: ${r.data.format}`),null}};async function*ue(r){let{node:e,config:{submissions:l,actions:a,next:u}}=r;yield a.text({author:"bot",message:e.data.question});let o=l[e.data.key];return yield a.input("text",{config:{key:e.data.key,maxChars:e.data.maxChars,minChars:e.data.minChars,placeholder:e.data.placeholder,format:e.data.format,optional:e.data.optional,defaultValue:o?.type==="string"?o.value:void 0},validate:t=>{if(e.data.optional&&t===null)return d(t);let n=Ie(r);if(n===null)return d(t);let s=y(n,t);return s.success===!1?c(s.issues):(l[e.data.key]={type:"string",value:s.output},d(t))}}),u(e.nextId)}var nt=r=>{let e={};return{interpret:async function*({nodes:a,context:u}){let o={error:({message:i})=>({type:"error",message:I(i,{submissions:e,context:u})}),info:({message:i})=>({type:"info",message:I(i,{submissions:e,context:u})}),success:({message:i})=>({type:"success",message:I(i,{submissions:e,context:u})}),text:({message:i,author:m})=>({type:"text",author:m,message:I(i,{submissions:e,context:u})}),image:({url:i,height:m,width:g})=>({type:"image",url:I(i,{submissions:e,context:u}),height:m,width:g}),state:i=>({type:"state",state:i}),link:({href:i,message:m})=>({type:"link",href:I(i,{submissions:e,context:u}),message:I(m,{submissions:e,context:u})}),submissions:i=>({type:"submissions",submissions:i}),input:(i,m)=>({type:"input",input:{type:i,config:m.config,validate:m.validate}})};if(!a.headId)return{type:"error",message:"No head node found"};let t=a.items[a.headId],n=i=>{if(!i)return t=void 0,{type:"next",nodeId:void 0};let m=a.items[i];if(!m)throw new Error(`Next node with id ${i} not found`);return t=m,{type:"next",nodeId:i}},s={...r,context:u,submissions:e,next:n,actions:o};for(;t;){switch(t.type){case"text":yield o.text({author:"bot",message:t.data.text}),n(t.nextId);break;case"image":yield o.image(t.data),n(t.nextId);break;case"link":yield o.link({href:t.data.href,message:t.data.cta}),n(t.nextId);break;case"add-submission":e[t.data.key]={type:"string",value:t.data.value},n(t.nextId);break;case"jump":n(t.data.targetId);break;case"question-text":yield*ue({config:s,node:t});break;case"question-phone":yield*ie({config:s,node:t});break;case"question-boolean":yield*ne({config:s,node:t});break;case"question-number":yield*se({config:s,node:t});break;case"question-address":yield*re({config:s,node:t});break;case"question-enum":yield*ae({config:s,node:t});break;case"question-file":yield*oe({config:s,node:t});break;case"identify":{yield*Z({config:s,node:t});break}case"if-block":{let i=_(t,{context:s.context,submissions:e})?t.branchId:t.nextId;n(i);break}case"integration-application-submit":yield*te({config:s,node:t});break;case"feedback":yield o.error({message:"Not implemented"});break;case"integration-workflow-get":yield o.error({message:"This message should never be reached"});break;case"end-flow":t=void 0;break}yield o.submissions(e)}yield{type:"end"}}}};export{nt as createFlowInterpreter};
|
|
1
|
+
import{A as I,B as V,C as W,D as j,E as X,a as Y,b as C,c as z,d as x,e as D,f as h,g as K,h as P,i as E,j as $,k as q,l as B,m as L,n as S,o as v,p as R,q as T,r as p,s as O,t as f,u as y,v as d,w as c,x as G,z as U}from"./chunk-H5IXVEP2.mjs";import{b as Q}from"./chunk-DKKJHDKM.mjs";var M=Q(Y());var H=({condition:r,context:e,submissions:l,ifBlock:n})=>{let[u,...o]=r.compareKey.split(".");if(!u)return!1;let t=V({context:e,key:u,path:o,submissions:l});if(!t)return!1;switch(t.type){case"address":{let a=(0,M.default)(t.value,o.join("."));switch(r.compare){case"equals":return a===r.compareValue;case"contains":return a?a.includes(r.compareValue):!1;case"notEquals":return a!==r.compareValue;case"notContains":return a?!a.includes(r.compareValue):!0}break}case"integration":{if(typeof t.value!="object"||Array.isArray(t.value))return!1;let a=(0,M.default)(t.value,o.join(".")),s={...n,data:{compareKey:"_temp",compare:r.compare,compareValue:r.compareValue}};switch(typeof a){case"boolean":return _(s,{submissions:{_temp:{value:a,type:"boolean"}},context:e});case"string":return _(s,{submissions:{_temp:{value:a,type:"string"}},context:e});case"number":return _(s,{submissions:{_temp:{value:a,type:"number"}},context:e});case"object":return Array.isArray(a)&&a.every(i=>typeof i=="string")?_(s,{submissions:{_temp:{value:a,type:"enum"}},context:e}):!1}break}case"boolean":{let a=r.compareValue==="true";switch(r.compare){case"equals":return t.value===a;case"notEquals":return t.value!==a}break}case"phone":case"string":{let a=t.type==="phone"?t.value.countryCode+t.value.phoneNumber:t.value;switch(r.compare){case"equals":return a===r.compareValue;case"contains":return a?a.includes(r.compareValue):!1;case"notEquals":return a!==r.compareValue;case"notContains":return a?!a.includes(r.compareValue):!0}break}case"number":{try{let a=Number(r.compareValue);switch(r.compare){case"equals":return t.value===a;case"notEquals":return t.value!==a;case"greaterThan":return t.value>a;case"greaterThanOrEqualTo":return t.value>=a;case"lessThan":return t.value<a;case"lessThanOrEqualTo":return t.value<=a}}catch{return console.error(`Failed to parse number in if-block ${n.id}`,t.value),!1}break}case"enum":switch(r.compare){case"equals":return t.value.length===1&&t.value[0]===r.compareValue;case"notEquals":return t.value.length===1&&t.value[0]!==r.compareValue;case"contains":return t.value.includes(r.compareValue);case"notContains":return!t.value.includes(r.compareValue)}break;case"file":break;default:break}},_=(r,{context:e,submissions:l})=>{let n="combinator"in r.data?r.data.conditions:[r.data];if(("combinator"in r.data?r.data.combinator:"and")==="or"){for(let o of n)if(H({condition:o,context:e,submissions:l,ifBlock:r}))return!0;return!1}else{for(let o of n)if(!H({condition:o,context:e,submissions:l,ifBlock:r}))return!1;return!0}};var J=Q(Y());var pe=/{{\s*([^}]+?)\s*(?:\|\s*([^}]+?)\s*)?}}/g,k=(r,{context:e,submissions:l})=>r.replace(pe,(n,u,o="")=>{let[t,...a]=u.trim().split("."),s=V({key:t,path:a,submissions:l,context:e});if(!s)return o;switch(s.type){case"boolean":return s.value===!0?"true":"false";case"file":return s.value.map(i=>`${i.name} (${j(i.sizeKb)})`).join(", ");case"enum":return s.value.join(", ");case"address":return Object.values(s.value).filter(i=>i&&i.trim().length>0).join(", ");case"number":case"string":return s.value?s.value.toString():o;case"phone":return X(s.value);case"integration":{if(typeof s.value!="object"||Array.isArray(s.value))break;let i=(0,J.default)(s.value,a.join("."));switch(typeof i){case"boolean":return i===!0?"true":"false";case"string":return i;case"number":return i.toString();case"object":if(Array.isArray(i)&&i.every(m=>typeof m=="string"))return i.join(", ")}break}default:}return o});async function*Z(r){let{node:e,config:{logger:l,platformClient:n,submissions:u,context:o,next:t}}=r,a={isDuplicate:!1};if(n){let s=e.data.scope==="job"?o.job_id:void 0;if(e.data.scope==="company"||s!=null)try{a=await n.checkDuplicate({email:I({key:e.data.email,submissions:u}).toString(),jobId:s,scope:e.data.scope})}catch(i){l.error("[check-duplicate]",i)}}return u[e.data.key]={type:"integration",value:a},t(e.nextId)}async function*ee(r){let{node:e,config:{logger:l,analytics:n,submissions:u,next:o}}=r;return n.service.log({event:"IDENTIFY",properties:{identifier:I({key:e.data.key,submissions:u}).toString(),first_name:e.data.firstName?I({key:e.data.firstName,submissions:u}).toString():void 0,last_name:e.data.lastName?I({key:e.data.lastName,submissions:u}).toString():void 0,email:e.data.email?I({key:e.data.email,submissions:u}).toString():void 0,phone_number:e.data.phoneNumber?I({key:e.data.phoneNumber,submissions:u}).toString():void 0,custom_traits:e.data.customTraits?Object.fromEntries(e.data.customTraits.map(({key:t,value:a})=>[t,u[a]?.value])):void 0}}).catch(l.error),o(e.nextId)}import{endpoint as ce,typed as fe}from"@inploi/sdk";var te=v({success:B(),integration_response:v({service:R(p()),status:S(),data:O(),error:L(v({message:p(),data:O()}))})}),ye=ce({pathname:"/flow/submit",method:"POST",schema:{response:te,body:fe()}});async function*re(r){let{node:e,config:{rpcClient:l,submissions:n,actions:u,next:o,analytics:t,logger:a,context:s}}=r;return e.data.skipConfirmation!==!0&&(yield u.input("submit",{config:{key:e.data.key??"_SUBMIT",label:e.data.submitLabel},validate:async()=>{let m=G(t.service.getSessionInfo)();m.err&&a.error(m.val.originalError);try{let g=await l.request(ye,{body:{log_submit:!1,integration_id:e.data.integrationId,anonymous_id:m.ok?m.val.anonymous_id:void 0,session_id:m.ok?m.val.session_id:void 0,job:s.job,submissions:U(n)}}),b=y(te,g);return b.success===!1?c(b.issues):d(b.output)}catch(g){let b=[{input:g,origin:"value",reason:"unknown",validation:"API error",message:g instanceof Error?g.message:"toString"in g?g.toString():"Unknown error"}];return c(b)}}})),o(e.nextId)}var w=f(L(R(p())),E(r=>r===null?void 0:r)),ge=({node:r})=>{let e=r.data.keys;return v({[e.line1??"line1"]:w,[e.line2??"line2"]:w,[e.line3??"line3"]:w,[e.city??"city"]:w,[e.country??"country"]:w,[e.postcode??"postcode"]:w,[e.state??"state"]:w})};async function*ae(r){let{node:e,config:{submissions:l,actions:n,next:u}}=r;return yield n.text({author:"bot",message:e.data.question}),yield n.input("address",{config:{key:e.data.key,keys:e.data.keys,placeholder:e.data.placeholder,optional:e.data.optional},validate:o=>{if(e.data.optional&&o===null)return d(o);let t=ge(r),a=y(t,o);return a.success===!1?c(a.issues):(l[e.data.key]={type:"address",value:a.output},d(o))}}),u(e.nextId)}var ve=["true","false"],be=T(ve);async function*ne(r){let{node:e,config:{submissions:l,actions:n,next:u}}=r;return yield n.text({author:"bot",message:e.data.question}),yield n.input("boolean",{config:{key:e.data.key,labels:{false:e.data.falseLabel,true:e.data.trueLabel},optional:e.data.optional},validate:o=>{if(e.data.optional&&o===null)return d(o);let t=y(be,o);return t.success===!1?c(t.issues):(l[e.data.key]={type:"boolean",value:t.output==="true"},d(o))}}),u(e.nextId)}async function*oe(r){let{node:e,config:{submissions:l,actions:n,next:u}}=r;yield n.text({author:"bot",message:e.data.question});let o=q(T(e.data.options.map(t=>t.value)));return yield n.input("multiple-choice",{config:{key:e.data.key,options:e.data.options,maxSelected:e.data.maxSelected,minSelected:e.data.minSelected},validate:t=>{if(e.data.minSelected===0&&t===null)return d(t);let a=y(o,t);return a.success===!1?c(a.issues):(l[e.data.key]={type:"enum",value:a.output},d(t))}}),u(e.nextId)}async function*se(r){let{node:e,config:{submissions:l,actions:n,next:u,t:o}}=r;return yield n.text({author:"bot",message:e.data.question}),yield n.input("file",{config:{key:e.data.key,allowMultiple:e.data.multiple===!0,extensions:e.data.extensions,fileSizeLimitKib:e.data.maxSizeKb,optional:e.data.optional},validate:t=>{if(e.data.optional&&t===null)return d(t);let a=e.data.optional?0:1,s=e.data.multiple?Number.POSITIVE_INFINITY:1,i=e.data.maxSizeKb??0,m=e.data.extensions.map(F=>F.toLowerCase()),g=f(q(v({name:f(p(o("validation_empty")),C(F=>{let A=W(F);return A.ok===!1?!1:m.includes(A.val.toLowerCase())},o("validation_file_ext",{ext:m.join(", ")}))),data:p(),sizeKb:S()})),h(a,o("validation_file_min",{count:a})),x(s,o("validation_file_max",{count:s})),C(F=>F.reduce((de,me)=>de+me.sizeKb,0)<=i,o("validation_file_size",{size:j(i)}))),b=y(g,t);return b.success===!1?c(b.issues):(l[e.data.key]={type:"file",value:b.output},d(t))}}),u(e.nextId)}var he=({node:r,config:{t:e}})=>{let l=r.data.min??Number.MIN_SAFE_INTEGER,n=r.data.max??Number.MAX_SAFE_INTEGER,u=r.data.decimalCases??0;return f(S(e("validation_number")),K(l,e("validation_number_min",{min:l})),D(n,e("validation_number_max",{max:n})),C(o=>o===Number(o.toFixed(u)),e("validation_number_decimal_cases",{count:u})))};async function*ie(r){let{node:e,config:{submissions:l,actions:n,next:u}}=r;yield n.text({author:"bot",message:e.data.question});let o=l[e.data.key];return yield n.input("number",{config:{key:e.data.key,placeholder:e.data.placeholder,optional:e.data.optional,decimalCases:e.data.decimalCases,max:e.data.max,min:e.data.min,defaultValue:o?.type==="number"?o.value.toString():void 0},validate:t=>{if(e.data.optional&&t===null)return d(t);let a=he(r),s=y(a,t);return s.success===!1?c(s.issues):(l[e.data.key]={type:"number",value:s.output},d(t))}}),u(e.nextId)}var Ie=({node:r,config:{t:e}})=>v({countryCode:f(p(e("validation_country_code")),P(/^\+?[0-9 -]+$/,e("validation_country_code"))),phoneNumber:f(p(e("validation_phone")),P(/^\+?[0-9 -]+$/,e("validation_phone")),h(r.data.minChars,e("validation_min_chars",{count:r.data.minChars})),E(l=>l.replace(/[^0-9]/g,"")))});async function*ue(r){let{node:e,config:{actions:l,next:n,submissions:u}}=r;yield l.text({author:"bot",message:e.data.question});let o=u[e.data.key];return yield l.input("phone",{config:{key:e.data.key,minChars:e.data.minChars,defaultValue:o?.type==="phone"?o.value:{countryCode:e.data.defaultCountryCode},placeholder:e.data.placeholder,submissionFormat:"phone",optional:e.data.optional},validate:t=>{if(e.data.optional&&t===null)return d(t);let a=Ie(r),s=y(a,t);return s.success===!1?c(s.issues):(u[e.data.key]={type:"address",value:s.output},d(t))}}),n(e.nextId)}var ke=({node:r,config:{t:e,logger:l}})=>{let n={date:e("validation_date"),email:e("validation_email"),url:e("validation_url"),maxLength:e("validation_max_chars",{count:r.data.maxChars??999}),minLength:e("validation_min_chars",{count:r.data.minChars??1})};switch(r.data.format){case"date":return f(p(n.date),P(/^\d{4}-\d{2}-\d{2}$/,n.date));case"email":return f(p(n.email),z(n.email),h(r.data.minChars??1,n.minLength),x(r.data.maxChars??1/0,n.maxLength));case"text":return f(p(),h(r.data.minChars??1,n.minLength),x(r.data.maxChars??1/0,n.maxLength));case"url":return f(p(),$(n.url),h(r.data.minChars??1,n.minLength),x(r.data.maxChars??1/0,n.maxLength));case"phone":return f(p(),h(r.data.minChars??1,n.minLength),x(r.data.maxChars??1/0,n.maxLength));default:return r.data.format,l.error(`Unsupported question-text format: ${r.data.format}`),null}};async function*le(r){let{node:e,config:{submissions:l,actions:n,next:u}}=r;yield n.text({author:"bot",message:e.data.question});let o=l[e.data.key];return yield n.input("text",{config:{key:e.data.key,maxChars:e.data.maxChars,minChars:e.data.minChars,placeholder:e.data.placeholder,format:e.data.format,optional:e.data.optional,defaultValue:o?.type==="string"?o.value:void 0},validate:t=>{if(e.data.optional&&t===null)return d(t);let a=ke(r);if(a===null)return d(t);let s=y(a,t);return s.success===!1?c(s.issues):(l[e.data.key]={type:"string",value:s.output},d(t))}}),u(e.nextId)}var it=r=>{let e={};return{interpret:async function*({nodes:n,context:u}){let o={error:({message:i})=>({type:"error",message:k(i,{submissions:e,context:u})}),info:({message:i})=>({type:"info",message:k(i,{submissions:e,context:u})}),success:({message:i})=>({type:"success",message:k(i,{submissions:e,context:u})}),text:({message:i,author:m})=>({type:"text",author:m,message:k(i,{submissions:e,context:u})}),image:({url:i,height:m,width:g})=>({type:"image",url:k(i,{submissions:e,context:u}),height:m,width:g}),state:i=>({type:"state",state:i}),link:({href:i,message:m})=>({type:"link",href:k(i,{submissions:e,context:u}),message:k(m,{submissions:e,context:u})}),submissions:i=>({type:"submissions",submissions:i}),input:(i,m)=>({type:"input",input:{type:i,config:m.config,validate:m.validate}})};if(!n.headId)return{type:"error",message:"No head node found"};let t=n.items[n.headId],a=i=>{if(!i)return t=void 0,{type:"next",nodeId:void 0};let m=n.items[i];if(!m)throw new Error(`Next node with id ${i} not found`);return t=m,{type:"next",nodeId:i}},s={...r,context:u,submissions:e,next:a,actions:o};for(;t;){switch(t.type){case"text":yield o.text({author:"bot",message:t.data.text}),a(t.nextId);break;case"image":yield o.image(t.data),a(t.nextId);break;case"link":yield o.link({href:t.data.href,message:t.data.cta}),a(t.nextId);break;case"add-submission":e[t.data.key]={type:"string",value:t.data.value},a(t.nextId);break;case"jump":a(t.data.targetId);break;case"question-text":yield*le({config:s,node:t});break;case"question-phone":yield*ue({config:s,node:t});break;case"question-boolean":yield*ne({config:s,node:t});break;case"question-number":yield*ie({config:s,node:t});break;case"question-address":yield*ae({config:s,node:t});break;case"question-enum":yield*oe({config:s,node:t});break;case"question-file":yield*se({config:s,node:t});break;case"identify":{yield*ee({config:s,node:t});break}case"check-duplicate":{yield*Z({config:s,node:t});break}case"if-block":{let i=_(t,{context:s.context,submissions:e})?t.branchId:t.nextId;a(i);break}case"integration-application-submit":yield*re({config:s,node:t});break;case"feedback":yield o.error({message:"Not implemented"});break;case"integration-workflow-get":yield o.error({message:"This message should never be reached"});break;case"end-flow":t=void 0;break}yield o.submissions(e)}yield{type:"end"}}}};export{it as createFlowInterpreter};
|
|
2
2
|
//# sourceMappingURL=interpreter.mjs.map
|
package/dist/interpreter.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/conditions.ts","../src/interpolation.ts","../src/interpreter.identify.ts","../src/interpreter.integration-application-submit.ts","../src/interpreter.question-address.ts","../src/interpreter.question-boolean.ts","../src/interpreter.question-enum.ts","../src/interpreter.question-file.ts","../src/interpreter.question-number.ts","../src/interpreter.question-phone.ts","../src/interpreter.question-text.ts","../src/interpreter.ts"],"sourcesContent":["import { IfBlockNode, IfBlockNodeCondition } from '@inploi/core/flows';\nimport get from 'lodash/get';\n\nimport { FlowSubmissions } from './flow.types';\nimport { getSubmissionValueToCheck } from './utils';\n\nconst isConditionMet = ({\n\tcondition,\n\tcontext,\n\tsubmissions,\n\tifBlock,\n}: {\n\tcontext: Record<string, unknown>;\n\tcondition: IfBlockNodeCondition;\n\tsubmissions: FlowSubmissions;\n\tifBlock: IfBlockNode;\n}) => {\n\tconst [firstSegment, ...path] = condition.compareKey.split('.');\n\tif (!firstSegment) return false;\n\n\tconst answer = getSubmissionValueToCheck({ context, key: firstSegment, path, submissions });\n\tif (!answer) return false;\n\n\tswitch (answer.type) {\n\t\tcase 'address': {\n\t\t\tconst value = get(answer.value, path.join('.'));\n\t\t\tswitch (condition.compare) {\n\t\t\t\tcase 'equals':\n\t\t\t\t\treturn value === condition.compareValue;\n\t\t\t\tcase 'contains':\n\t\t\t\t\tif (!value) return false;\n\t\t\t\t\treturn value.includes(condition.compareValue);\n\t\t\t\tcase 'notEquals':\n\t\t\t\t\treturn value !== condition.compareValue;\n\t\t\t\tcase 'notContains':\n\t\t\t\t\tif (!value) return true;\n\t\t\t\t\treturn !value.includes(condition.compareValue);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'integration': {\n\t\t\t/** We only handle objects as integration submissions for now. */\n\t\t\tif (typeof answer.value !== 'object') return false;\n\t\t\tif (Array.isArray(answer.value)) return false;\n\n\t\t\tconst value = get(answer.value, path.join('.'));\n\t\t\tconst newIfBlock = { ...ifBlock, data: { ...ifBlock.data, compareKey: '_temp' } };\n\t\t\tswitch (typeof value) {\n\t\t\t\tcase 'boolean':\n\t\t\t\t\treturn isIfBlockConditionMet(newIfBlock, {\n\t\t\t\t\t\tsubmissions: { ['_temp']: { value: value, type: 'boolean' } },\n\t\t\t\t\t\tcontext,\n\t\t\t\t\t});\n\t\t\t\tcase 'string':\n\t\t\t\t\treturn isIfBlockConditionMet(newIfBlock, {\n\t\t\t\t\t\tsubmissions: { ['_temp']: { value: value, type: 'string' } },\n\t\t\t\t\t\tcontext,\n\t\t\t\t\t});\n\t\t\t\tcase 'number':\n\t\t\t\t\treturn isIfBlockConditionMet(newIfBlock, {\n\t\t\t\t\t\tsubmissions: { ['_temp']: { value: value, type: 'number' } },\n\t\t\t\t\t\tcontext,\n\t\t\t\t\t});\n\t\t\t\tcase 'object':\n\t\t\t\t\t/** We only handle enums if the result is an array of strings */\n\t\t\t\t\tif (Array.isArray(value) && value.every((value): value is string => typeof value === 'string')) {\n\t\t\t\t\t\treturn isIfBlockConditionMet(newIfBlock, {\n\t\t\t\t\t\t\tsubmissions: { ['_temp']: { value: value, type: 'enum' } },\n\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'boolean': {\n\t\t\tconst compareBoolean = condition.compareValue === 'true';\n\t\t\tswitch (condition.compare) {\n\t\t\t\tcase 'equals':\n\t\t\t\t\treturn answer.value === compareBoolean;\n\t\t\t\tcase 'notEquals':\n\t\t\t\t\treturn answer.value !== compareBoolean;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'phone':\n\t\tcase 'string': {\n\t\t\tconst value = answer.type === 'phone' ? answer.value.countryCode + answer.value.phoneNumber : answer.value;\n\t\t\tswitch (condition.compare) {\n\t\t\t\tcase 'equals':\n\t\t\t\t\treturn value === condition.compareValue;\n\t\t\t\tcase 'contains':\n\t\t\t\t\tif (!value) return false;\n\t\t\t\t\treturn value.includes(condition.compareValue);\n\t\t\t\tcase 'notEquals':\n\t\t\t\t\treturn value !== condition.compareValue;\n\t\t\t\tcase 'notContains':\n\t\t\t\t\tif (!value) return true;\n\t\t\t\t\treturn !value.includes(condition.compareValue);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'number': {\n\t\t\ttry {\n\t\t\t\tconst compareNumber = Number(condition.compareValue);\n\t\t\t\tswitch (condition.compare) {\n\t\t\t\t\tcase 'equals':\n\t\t\t\t\t\treturn answer.value === compareNumber;\n\t\t\t\t\tcase 'notEquals':\n\t\t\t\t\t\treturn answer.value !== compareNumber;\n\t\t\t\t\tcase 'greaterThan':\n\t\t\t\t\t\treturn answer.value > compareNumber;\n\t\t\t\t\tcase 'greaterThanOrEqualTo':\n\t\t\t\t\t\treturn answer.value >= compareNumber;\n\t\t\t\t\tcase 'lessThan':\n\t\t\t\t\t\treturn answer.value < compareNumber;\n\t\t\t\t\tcase 'lessThanOrEqualTo':\n\t\t\t\t\t\treturn answer.value <= compareNumber;\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\tconsole.error(`Failed to parse number in if-block ${ifBlock.id}`, answer.value);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'enum':\n\t\t\tswitch (condition.compare) {\n\t\t\t\tcase 'equals':\n\t\t\t\t\treturn answer.value.length === 1 && answer.value[0] === condition.compareValue;\n\t\t\t\tcase 'notEquals':\n\t\t\t\t\treturn answer.value.length === 1 && answer.value[0] !== condition.compareValue;\n\t\t\t\tcase 'contains':\n\t\t\t\t\treturn answer.value.includes(condition.compareValue);\n\t\t\t\tcase 'notContains':\n\t\t\t\t\treturn !answer.value.includes(condition.compareValue);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 'file':\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tanswer satisfies never;\n\t\t\tbreak;\n\t}\n};\n\nexport const isIfBlockConditionMet = (\n\tifBlock: IfBlockNode,\n\t{ context, submissions }: { submissions: FlowSubmissions; context: Record<string, unknown> },\n): boolean => {\n\tconst conditions = 'combinator' in ifBlock.data ? ifBlock.data.conditions : [ifBlock.data];\n\tconst combinator = 'combinator' in ifBlock.data ? ifBlock.data.combinator : 'and';\n\n\tif (combinator === 'or') {\n\t\tfor (const condition of conditions) {\n\t\t\tconst isMet = isConditionMet({ condition, context, submissions, ifBlock });\n\t\t\tif (isMet) return true;\n\t\t}\n\t\treturn false;\n\t} else {\n\t\tfor (const condition of conditions) {\n\t\t\tconst isMet = isConditionMet({ condition, context, submissions, ifBlock });\n\t\t\tif (!isMet) return false;\n\t\t}\n\t\treturn true;\n\t}\n};\n","import get from 'lodash/get';\n\nimport { FlowSubmissions } from './flow.types';\nimport { formatPhoneNumber, getSubmissionValueToCheck, kbToReadableSize } from './utils';\n\nconst HANDLEBARS_REGEXP = /{{\\s*([^}]+?)\\s*(?:\\|\\s*([^}]+?)\\s*)?}}/g;\n\nexport const interpolateWithData = (\n\tstr: string,\n\t{ context, submissions }: { submissions: FlowSubmissions; context: Record<string, unknown> },\n) => {\n\treturn str.replace(HANDLEBARS_REGEXP, (_, key, defaultValue = '') => {\n\t\tconst [firstSegment, ...path] = key.trim().split('.');\n\t\tconst entity = getSubmissionValueToCheck({ key: firstSegment, path, submissions, context });\n\t\tif (!entity) return defaultValue;\n\n\t\tswitch (entity.type) {\n\t\t\tcase 'boolean':\n\t\t\t\treturn entity.value === true ? 'true' : 'false';\n\t\t\tcase 'file':\n\t\t\t\treturn entity.value.map(file => `${file.name} (${kbToReadableSize(file.sizeKb)})`).join(', ');\n\t\t\tcase 'enum':\n\t\t\t\treturn entity.value.join(', ');\n\t\t\tcase 'address':\n\t\t\t\treturn Object.values(entity.value)\n\t\t\t\t\t.filter(line => line && line.trim().length > 0)\n\t\t\t\t\t.join(', ');\n\t\t\tcase 'number':\n\t\t\tcase 'string':\n\t\t\t\tif (!entity.value) return defaultValue;\n\t\t\t\treturn entity.value.toString();\n\t\t\tcase 'phone':\n\t\t\t\treturn formatPhoneNumber(entity.value);\n\t\t\tcase 'integration': {\n\t\t\t\t/** We only handle objects as integration submissions for now. */\n\t\t\t\tif (typeof entity.value !== 'object') break;\n\t\t\t\tif (Array.isArray(entity.value)) break;\n\n\t\t\t\tconst value = get(entity.value, path.join('.'));\n\t\t\t\tswitch (typeof value) {\n\t\t\t\t\tcase 'boolean':\n\t\t\t\t\t\treturn value === true ? 'true' : 'false';\n\t\t\t\t\tcase 'string':\n\t\t\t\t\t\treturn value;\n\t\t\t\t\tcase 'number':\n\t\t\t\t\t\treturn value.toString();\n\t\t\t\t\tcase 'object':\n\t\t\t\t\t\t/** We only handle enums if the result is an array of strings */\n\t\t\t\t\t\tif (Array.isArray(value) && value.every((i): i is string => typeof i === 'string')) {\n\t\t\t\t\t\t\treturn value.join(', ');\n\t\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tentity satisfies never;\n\t\t}\n\t\treturn defaultValue;\n\t});\n};\n","import { InterpretNodeParams } from './interpreter';\nimport { getSubmissionValue } from './utils';\n\nexport async function* interpretIdentifyNode(params: InterpretNodeParams<'identify'>) {\n\tconst {\n\t\tnode,\n\t\tconfig: { logger, analytics, submissions, next },\n\t} = params;\n\n\tanalytics.service\n\t\t.log({\n\t\t\tevent: 'IDENTIFY',\n\t\t\tproperties: {\n\t\t\t\tidentifier: getSubmissionValue({ key: node.data.key, submissions }).toString(),\n\t\t\t\tfirst_name:\n\t\t\t\t\tnode.data.firstName ? getSubmissionValue({ key: node.data.firstName, submissions }).toString() : undefined,\n\t\t\t\tlast_name:\n\t\t\t\t\tnode.data.lastName ? getSubmissionValue({ key: node.data.lastName, submissions }).toString() : undefined,\n\t\t\t\temail: node.data.email ? getSubmissionValue({ key: node.data.email, submissions }).toString() : undefined,\n\t\t\t\tphone_number:\n\t\t\t\t\tnode.data.phoneNumber ?\n\t\t\t\t\t\tgetSubmissionValue({ key: node.data.phoneNumber, submissions }).toString()\n\t\t\t\t\t:\tundefined,\n\t\t\t\tcustom_traits:\n\t\t\t\t\tnode.data.customTraits ?\n\t\t\t\t\t\tObject.fromEntries(node.data.customTraits.map(({ key, value }) => [key, submissions[value]?.value]))\n\t\t\t\t\t:\tundefined,\n\t\t\t},\n\t\t})\n\t\t.catch(logger.error);\n\n\treturn next(node.nextId);\n}\n","import { endpoint, typed } from '@inploi/sdk';\nimport * as v from 'valibot';\n\nimport { InterpretNodeParams, InterpretNodeReturn } from './interpreter';\nimport { Err, Ok, tryCatch } from './result';\nimport { getFlowSubmissionsPayload } from './utils';\n\nconst responseSchema = v.object({\n\t/** Not necessarily true when we receive a positive response because the API considers only 200 as success */\n\tsuccess: v.boolean(),\n\tintegration_response: v.object({\n\t\tservice: v.optional(v.string()),\n\t\tstatus: v.number(),\n\t\tdata: v.unknown(),\n\t\terror: v.nullable(v.object({ message: v.string(), data: v.unknown() })),\n\t}),\n});\nexport type IntegrationResponse = v.InferOutput<typeof responseSchema>;\n\nconst submitEndpoint = endpoint({\n\tpathname: '/flow/submit',\n\tmethod: 'POST',\n\tschema: {\n\t\tresponse: responseSchema,\n\t\tbody: typed<{\n\t\t\tlog_submit: boolean;\n\t\t\tintegration_id: string;\n\t\t\tanonymous_id: string | null | undefined;\n\t\t\tsession_id: string | null | undefined;\n\t\t\tjob: unknown;\n\t\t\tsubmissions: Record<string, unknown>;\n\t\t}>(),\n\t},\n});\n\nexport async function* interpretIntegrationApplicationSubmitNode(\n\tparams: InterpretNodeParams<'integration-application-submit'>,\n): InterpretNodeReturn {\n\tconst {\n\t\tnode,\n\t\tconfig: { rpcClient, submissions, actions, next, analytics, logger, context },\n\t} = params;\n\n\tif (node.data.skipConfirmation !== true) {\n\t\tyield actions.input('submit', {\n\t\t\tconfig: {\n\t\t\t\tkey: node.data.key ?? '_SUBMIT',\n\t\t\t\tlabel: node.data.submitLabel,\n\t\t\t},\n\t\t\t/** for submit node, validating _is_ submitting */\n\t\t\tvalidate: async () => {\n\t\t\t\tconst getSessionInfoSafe = tryCatch(analytics.service.getSessionInfo);\n\t\t\t\tconst sessionInfo = getSessionInfoSafe();\n\t\t\t\tif (sessionInfo.err) logger.error(sessionInfo.val.originalError);\n\n\t\t\t\ttry {\n\t\t\t\t\tconst response = await rpcClient.request(submitEndpoint, {\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\tlog_submit: false,\n\t\t\t\t\t\t\tintegration_id: node.data.integrationId,\n\t\t\t\t\t\t\tanonymous_id: sessionInfo.ok ? sessionInfo.val.anonymous_id : undefined,\n\t\t\t\t\t\t\tsession_id: sessionInfo.ok ? sessionInfo.val.session_id : undefined,\n\t\t\t\t\t\t\tjob: context.job,\n\t\t\t\t\t\t\tsubmissions: getFlowSubmissionsPayload(submissions),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\tconst parsed = v.safeParse(responseSchema, response);\n\t\t\t\t\tif (parsed.success === false) return Err(parsed.issues);\n\t\t\t\t\treturn Ok(parsed.output);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconst issues: v.ValiError<any>['issues'] = [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinput: e,\n\t\t\t\t\t\t\torigin: 'value',\n\t\t\t\t\t\t\treason: 'unknown',\n\t\t\t\t\t\t\tvalidation: 'API error',\n\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\te instanceof Error ? e.message\n\t\t\t\t\t\t\t\t: 'toString' in (e as any) ? (e as any).toString()\n\t\t\t\t\t\t\t\t: 'Unknown error',\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t\t\t\treturn Err(issues);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t}\n\n\treturn next(node.nextId);\n}\n","import * as v from 'valibot';\n\nimport { InterpretNodeParams, InterpretNodeReturn } from './interpreter';\nimport { Err, Ok } from './result';\n\nconst fieldValueSchema = v.pipe(\n\tv.nullable(v.optional(v.string())),\n\tv.transform(i => (i === null ? undefined : i)),\n);\nconst getValidationSchema = ({ node }: InterpretNodeParams<'question-address'>) => {\n\tconst keys = node.data.keys;\n\treturn v.object({\n\t\t[keys.line1 ?? 'line1']: fieldValueSchema,\n\t\t[keys.line2 ?? 'line2']: fieldValueSchema,\n\t\t[keys.line3 ?? 'line3']: fieldValueSchema,\n\t\t[keys.city ?? 'city']: fieldValueSchema,\n\t\t[keys.country ?? 'country']: fieldValueSchema,\n\t\t[keys.postcode ?? 'postcode']: fieldValueSchema,\n\t\t[keys.state ?? 'state']: fieldValueSchema,\n\t});\n};\n\nexport async function* interpretQuestionAddressNode(\n\tparams: InterpretNodeParams<'question-address'>,\n): InterpretNodeReturn {\n\tconst {\n\t\tnode,\n\t\tconfig: { submissions, actions, next },\n\t} = params;\n\tyield actions.text({ author: 'bot', message: node.data.question });\n\n\tyield actions.input('address', {\n\t\tconfig: {\n\t\t\tkey: node.data.key,\n\t\t\tkeys: node.data.keys,\n\t\t\tplaceholder: node.data.placeholder,\n\t\t\toptional: node.data.optional,\n\t\t},\n\t\tvalidate: submission => {\n\t\t\tif (node.data.optional && submission === null) return Ok(submission);\n\t\t\tconst schema = getValidationSchema(params);\n\t\t\tconst parsed = v.safeParse(schema, submission);\n\t\t\tif (parsed.success === false) return Err(parsed.issues);\n\t\t\tsubmissions[node.data.key] = { type: 'address', value: parsed.output };\n\t\t\treturn Ok(submission);\n\t\t},\n\t});\n\n\treturn next(node.nextId);\n}\n","import * as v from 'valibot';\n\nimport { InterpretNodeParams, InterpretNodeReturn } from './interpreter';\nimport { Err, Ok } from './result';\n\nconst options = ['true', 'false'] as const;\nconst schema = v.picklist(options);\n\nexport async function* interpretQuestionBooleanNode(\n\tparams: InterpretNodeParams<'question-boolean'>,\n): InterpretNodeReturn {\n\tconst {\n\t\tnode,\n\t\tconfig: { submissions, actions, next },\n\t} = params;\n\tyield actions.text({ author: 'bot', message: node.data.question });\n\n\tyield actions.input('boolean', {\n\t\tconfig: {\n\t\t\tkey: node.data.key,\n\t\t\tlabels: {\n\t\t\t\tfalse: node.data.falseLabel,\n\t\t\t\ttrue: node.data.trueLabel,\n\t\t\t},\n\t\t\toptional: node.data.optional,\n\t\t},\n\t\tvalidate: submission => {\n\t\t\tif (node.data.optional && submission === null) return Ok(submission);\n\t\t\tconst parsed = v.safeParse(schema, submission);\n\t\t\tif (parsed.success === false) return Err(parsed.issues);\n\t\t\tsubmissions[node.data.key] = { type: 'boolean', value: parsed.output === 'true' };\n\t\t\treturn Ok(submission);\n\t\t},\n\t});\n\n\treturn next(node.nextId);\n}\n","import { NonEmptyArray } from '@inploi/core/common';\nimport * as v from 'valibot';\n\nimport { InterpretNodeParams, InterpretNodeReturn } from './interpreter';\nimport { Err, Ok } from './result';\n\nexport async function* interpretQuestionEnumNode(params: InterpretNodeParams<'question-enum'>): InterpretNodeReturn {\n\tconst {\n\t\tnode,\n\t\tconfig: { submissions, actions, next },\n\t} = params;\n\tyield actions.text({ author: 'bot', message: node.data.question });\n\n\tconst schema = v.array(v.picklist(node.data.options.map(o => o.value) as NonEmptyArray<string>));\n\tyield actions.input('multiple-choice', {\n\t\tconfig: {\n\t\t\tkey: node.data.key,\n\t\t\toptions: node.data.options,\n\t\t\tmaxSelected: node.data.maxSelected,\n\t\t\tminSelected: node.data.minSelected,\n\t\t},\n\t\tvalidate: submission => {\n\t\t\tif (node.data.minSelected === 0 && submission === null) return Ok(submission);\n\t\t\tconst parsed = v.safeParse(schema, submission);\n\t\t\tif (parsed.success === false) return Err(parsed.issues);\n\t\t\tsubmissions[node.data.key] = { type: 'enum', value: parsed.output };\n\t\t\treturn Ok(submission);\n\t\t},\n\t});\n\n\treturn next(node.nextId);\n}\n","import * as v from 'valibot';\n\nimport { InterpretNodeParams, InterpretNodeReturn } from './interpreter';\nimport { Err, Ok } from './result';\nimport { getFileExtension, kbToReadableSize } from './utils';\n\nexport async function* interpretQuestionFileNode(params: InterpretNodeParams<'question-file'>): InterpretNodeReturn {\n\tconst {\n\t\tnode,\n\t\tconfig: { submissions, actions, next, t },\n\t} = params;\n\tyield actions.text({ author: 'bot', message: node.data.question });\n\n\tyield actions.input('file', {\n\t\tconfig: {\n\t\t\tkey: node.data.key,\n\t\t\tallowMultiple: node.data.multiple === true,\n\t\t\textensions: node.data.extensions,\n\t\t\tfileSizeLimitKib: node.data.maxSizeKb,\n\t\t\toptional: node.data.optional,\n\t\t},\n\t\tvalidate: submission => {\n\t\t\tif (node.data.optional && submission === null) return Ok(submission);\n\t\t\tconst minFiles = node.data.optional ? 0 : 1;\n\t\t\tconst maxFiles = node.data.multiple ? Number.POSITIVE_INFINITY : 1;\n\t\t\tconst maxSize = node.data.maxSizeKb ?? 0;\n\t\t\tconst allowedExtensions = node.data.extensions.map(ext => ext.toLowerCase());\n\t\t\tconst schema = v.pipe(\n\t\t\t\tv.array(\n\t\t\t\t\tv.object({\n\t\t\t\t\t\tname: v.pipe(\n\t\t\t\t\t\t\tv.string(t('validation_empty')),\n\t\t\t\t\t\t\tv.check(\n\t\t\t\t\t\t\t\tfilename => {\n\t\t\t\t\t\t\t\t\tconst extension = getFileExtension(filename);\n\t\t\t\t\t\t\t\t\tif (extension.ok === false) return false;\n\t\t\t\t\t\t\t\t\treturn allowedExtensions.includes(extension.val.toLowerCase());\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tt('validation_file_ext', { ext: allowedExtensions.join(', ') }),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tdata: v.string(),\n\t\t\t\t\t\tsizeKb: v.number(),\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tv.minLength(minFiles, t('validation_file_min', { count: minFiles })),\n\t\t\t\tv.maxLength(maxFiles, t('validation_file_max', { count: maxFiles })),\n\t\t\t\tv.check(\n\t\t\t\t\tfiles => {\n\t\t\t\t\t\tconst totalSize = files.reduce((acc, cur) => acc + cur.sizeKb, 0);\n\t\t\t\t\t\treturn totalSize <= maxSize;\n\t\t\t\t\t},\n\t\t\t\t\tt('validation_file_size', { size: kbToReadableSize(maxSize) }),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\tconst parsed = v.safeParse(schema, submission);\n\t\t\tif (parsed.success === false) return Err(parsed.issues);\n\t\t\tsubmissions[node.data.key] = { type: 'file', value: parsed.output };\n\t\t\treturn Ok(submission);\n\t\t},\n\t});\n\n\treturn next(node.nextId);\n}\n","import * as v from 'valibot';\n\nimport { InterpretNodeParams, InterpretNodeReturn } from './interpreter';\nimport { Err, Ok } from './result';\n\nconst getValidationSchema = ({ node, config: { t } }: InterpretNodeParams<'question-number'>) => {\n\tconst min = node.data.min ?? Number.MIN_SAFE_INTEGER;\n\tconst max = node.data.max ?? Number.MAX_SAFE_INTEGER;\n\tconst decimalCases = node.data.decimalCases ?? 0;\n\n\treturn v.pipe(\n\t\tv.number(t('validation_number')),\n\t\tv.minValue(min, t('validation_number_min', { min })),\n\t\tv.maxValue(max, t('validation_number_max', { max })),\n\t\tv.check(\n\t\t\tvalue => {\n\t\t\t\treturn value === Number(value.toFixed(decimalCases));\n\t\t\t},\n\t\t\tt('validation_number_decimal_cases', { count: decimalCases }),\n\t\t),\n\t);\n};\n\nexport async function* interpretQuestionNumberNode(\n\tparams: InterpretNodeParams<'question-number'>,\n): InterpretNodeReturn {\n\tconst {\n\t\tnode,\n\t\tconfig: { submissions, actions, next },\n\t} = params;\n\tyield actions.text({ author: 'bot', message: node.data.question });\n\n\tconst thisSubmission = submissions[node.data.key];\n\tyield actions.input('number', {\n\t\tconfig: {\n\t\t\tkey: node.data.key,\n\t\t\tplaceholder: node.data.placeholder,\n\t\t\toptional: node.data.optional,\n\t\t\tdecimalCases: node.data.decimalCases,\n\t\t\tmax: node.data.max,\n\t\t\tmin: node.data.min,\n\t\t\tdefaultValue: thisSubmission?.type === 'number' ? thisSubmission.value.toString() : undefined,\n\t\t},\n\t\tvalidate: submission => {\n\t\t\tif (node.data.optional && submission === null) return Ok(submission);\n\t\t\tconst schema = getValidationSchema(params);\n\t\t\tconst parsed = v.safeParse(schema, submission);\n\t\t\tif (parsed.success === false) return Err(parsed.issues);\n\t\t\tsubmissions[node.data.key] = { type: 'number', value: parsed.output };\n\t\t\treturn Ok(submission);\n\t\t},\n\t});\n\n\treturn next(node.nextId);\n}\n","import * as v from 'valibot';\n\nimport { InterpretNodeParams, InterpretNodeReturn } from './interpreter';\nimport { Err, Ok } from './result';\n\nconst getValidationSchema = ({ node, config: { t } }: InterpretNodeParams<'question-phone'>) => {\n\treturn v.object({\n\t\tcountryCode: v.pipe(v.string(t('validation_country_code')), v.regex(/^\\+?[0-9 -]+$/, t('validation_country_code'))),\n\t\tphoneNumber: v.pipe(\n\t\t\tv.string(t('validation_phone')),\n\t\t\tv.regex(/^\\+?[0-9 -]+$/, t('validation_phone')),\n\t\t\tv.minLength(node.data.minChars, t('validation_min_chars', { count: node.data.minChars })),\n\t\t\tv.transform(value => value.replace(/[^0-9]/g, '')),\n\t\t),\n\t});\n};\n\nexport async function* interpretQuestionPhoneNode(params: InterpretNodeParams<'question-phone'>): InterpretNodeReturn {\n\tconst {\n\t\tnode,\n\t\tconfig: { actions, next, submissions },\n\t} = params;\n\tyield actions.text({ author: 'bot', message: node.data.question });\n\n\tconst thisSubmission = submissions[node.data.key];\n\tyield actions.input('phone', {\n\t\tconfig: {\n\t\t\tkey: node.data.key,\n\t\t\tminChars: node.data.minChars,\n\t\t\tdefaultValue:\n\t\t\t\tthisSubmission?.type === 'phone' ?\n\t\t\t\t\tthisSubmission.value\n\t\t\t\t:\t{\n\t\t\t\t\t\tcountryCode: node.data.defaultCountryCode,\n\t\t\t\t\t},\n\t\t\tplaceholder: node.data.placeholder,\n\t\t\tsubmissionFormat: 'phone',\n\t\t\toptional: node.data.optional,\n\t\t},\n\t\tvalidate: submission => {\n\t\t\tif (node.data.optional && submission === null) return Ok(submission);\n\t\t\tconst schema = getValidationSchema(params);\n\t\t\tconst parsed = v.safeParse(schema, submission);\n\t\t\tif (parsed.success === false) return Err(parsed.issues);\n\t\t\tsubmissions[node.data.key] = { type: 'address', value: parsed.output };\n\t\t\treturn Ok(submission);\n\t\t},\n\t});\n\n\treturn next(node.nextId);\n}\n","import * as v from 'valibot';\n\nimport { InterpretNodeParams, InterpretNodeReturn } from './interpreter';\nimport { Err, Ok } from './result';\n\nconst getValidationSchema = ({ node, config: { t, logger } }: InterpretNodeParams<'question-text'>) => {\n\tconst errors = {\n\t\tdate: t('validation_date'),\n\t\temail: t('validation_email'),\n\t\turl: t('validation_url'),\n\t\tmaxLength: t('validation_max_chars', { count: node.data.maxChars ?? 999 }),\n\t\tminLength: t('validation_min_chars', { count: node.data.minChars ?? 1 }),\n\t};\n\n\tswitch (node.data.format) {\n\t\tcase 'date':\n\t\t\treturn v.pipe(\n\t\t\t\tv.string(errors.date),\n\t\t\t\tv.regex(/^\\d{4}-\\d{2}-\\d{2}$/, errors.date),\n\t\t\t);\n\t\tcase 'email':\n\t\t\treturn v.pipe(\n\t\t\t\tv.string(errors.email),\n\t\t\t\tv.email(errors.email),\n\t\t\t\tv.minLength(node.data.minChars ?? 1, errors.minLength),\n\t\t\t\tv.maxLength(node.data.maxChars ?? Infinity, errors.maxLength),\n\t\t\t);\n\n\t\tcase 'text':\n\t\t\treturn v.pipe(\n\t\t\t\tv.string(),\n\t\t\t\tv.minLength(node.data.minChars ?? 1, errors.minLength),\n\t\t\t\tv.maxLength(node.data.maxChars ?? Infinity, errors.maxLength),\n\t\t\t);\n\t\tcase 'url':\n\t\t\treturn v.pipe(\n\t\t\t\tv.string(),\n\t\t\t\tv.url(errors.url),\n\t\t\t\tv.minLength(node.data.minChars ?? 1, errors.minLength),\n\t\t\t\tv.maxLength(node.data.maxChars ?? Infinity, errors.maxLength),\n\t\t\t);\n\t\tcase 'phone':\n\t\t\treturn v.pipe(\n\t\t\t\tv.string(),\n\t\t\t\tv.minLength(node.data.minChars ?? 1, errors.minLength),\n\t\t\t\tv.maxLength(node.data.maxChars ?? Infinity, errors.maxLength),\n\t\t\t);\n\t\tdefault:\n\t\t\tnode.data.format satisfies never;\n\t\t\tlogger.error(`Unsupported question-text format: ${node.data.format}`);\n\t\t\treturn null;\n\t}\n};\n\nexport async function* interpretQuestionTextNode(params: InterpretNodeParams<'question-text'>): InterpretNodeReturn {\n\tconst {\n\t\tnode,\n\t\tconfig: { submissions, actions, next },\n\t} = params;\n\tyield actions.text({ author: 'bot', message: node.data.question });\n\n\tconst thisSubmission = submissions[node.data.key];\n\tyield actions.input('text', {\n\t\tconfig: {\n\t\t\tkey: node.data.key,\n\t\t\tmaxChars: node.data.maxChars,\n\t\t\tminChars: node.data.minChars,\n\t\t\tplaceholder: node.data.placeholder,\n\t\t\tformat: node.data.format,\n\t\t\toptional: node.data.optional,\n\t\t\tdefaultValue: thisSubmission?.type === 'string' ? thisSubmission.value : undefined,\n\t\t},\n\t\tvalidate: submission => {\n\t\t\tif (node.data.optional && submission === null) return Ok(submission);\n\t\t\tconst schema = getValidationSchema(params);\n\t\t\tif (schema === null) return Ok(submission);\n\t\t\tconst parsed = v.safeParse(schema, submission);\n\t\t\tif (parsed.success === false) return Err(parsed.issues);\n\t\t\tsubmissions[node.data.key] = { type: 'string', value: parsed.output };\n\t\t\treturn Ok(submission);\n\t\t},\n\t});\n\n\treturn next(node.nextId);\n}\n","import { FlowNode } from '@inploi/core/flows';\nimport { AnalyticsService, InploiRpcClient, Logger } from '@inploi/sdk';\nimport { ValiError } from 'valibot';\n\nimport { isIfBlockConditionMet } from './conditions';\nimport { FlowSubmissions } from './flow.types';\nimport { TFunction } from './i18n';\nimport { FlowInput } from './inputs';\nimport { interpolateWithData } from './interpolation';\nimport { interpretIdentifyNode } from './interpreter.identify';\nimport { interpretIntegrationApplicationSubmitNode } from './interpreter.integration-application-submit';\nimport { interpretQuestionAddressNode } from './interpreter.question-address';\nimport { interpretQuestionBooleanNode } from './interpreter.question-boolean';\nimport { interpretQuestionEnumNode } from './interpreter.question-enum';\nimport { interpretQuestionFileNode } from './interpreter.question-file';\nimport { interpretQuestionNumberNode } from './interpreter.question-number';\nimport { interpretQuestionPhoneNode } from './interpreter.question-phone';\nimport { interpretQuestionTextNode } from './interpreter.question-text';\nimport { LinkedList, LinkedListItem } from './linked-list';\nimport { Result } from './result';\n\ntype MaybePromise<T> = T | Promise<T>;\ntype FlowInterpreterYield =\n\t| { type: 'submissions'; submissions: FlowSubmissions }\n\t| { type: 'state'; state: 'loading' | 'idle' }\n\t| { type: 'error'; message: string }\n\t| { type: 'info'; message: string }\n\t| { type: 'success'; message: string }\n\t| { type: 'text'; author: 'user' | 'bot'; message: string }\n\t| { type: 'image'; url: string; height: number; width: number }\n\t| { type: 'link'; href: string; message: string }\n\t| { type: 'end' }\n\t| {\n\t\t\ttype: 'input';\n\t\t\tinput: {\n\t\t\t\t[I in FlowInput['type']]: {\n\t\t\t\t\ttype: I;\n\t\t\t\t\tconfig: (FlowInput & { type: I })['config'];\n\t\t\t\t\tvalidate: (\n\t\t\t\t\t\tinput: NonNullable<(FlowInput & { type: I })['submission']>['value'] | null,\n\t\t\t\t\t) => MaybePromise<\n\t\t\t\t\t\tResult<NonNullable<(FlowInput & { type: I })['submission']>['value'] | null, ValiError<any>['issues']>\n\t\t\t\t\t>;\n\t\t\t\t};\n\t\t\t}[FlowInput['type']];\n\t };\n\nexport type FlowInterpreterParams = {\n\trpcClient: InploiRpcClient;\n\tanalytics: {\n\t\tservice: AnalyticsService;\n\t\tcustomProperties?: Record<string, unknown>;\n\t};\n\tlogger: Logger;\n\tt: TFunction;\n};\n\nexport type FlowActions = {\n\terror: ({ message }: { message: string }) => FlowInterpreterYield;\n\tinfo: ({ message }: { message: string }) => FlowInterpreterYield;\n\tsuccess: ({ message }: { message: string }) => FlowInterpreterYield;\n\ttext: ({ message, author }: { message: string; author: 'bot' | 'user' }) => FlowInterpreterYield;\n\timage: ({ url, height, width }: { url: string; height: number; width: number }) => FlowInterpreterYield;\n\tlink: ({ href, message }: { href: string; message: string }) => FlowInterpreterYield;\n\tsubmissions: (submissions: FlowSubmissions) => FlowInterpreterYield;\n\tstate: (state: 'loading' | 'idle') => FlowInterpreterYield;\n\tinput: <T extends FlowInput['type'], Input extends FlowInput & { type: T }>(\n\t\ttype: T,\n\t\tparams: {\n\t\t\tconfig: Input['config'];\n\t\t\tvalidate: (\n\t\t\t\tinput: NonNullable<Input['submission']>['value'] | null,\n\t\t\t) => MaybePromise<Result<NonNullable<Input['submission']>['value'] | null, ValiError<any>['issues']>>;\n\t\t},\n\t) => FlowInterpreterYield;\n};\n\nexport const createFlowInterpreter = (params: FlowInterpreterParams) => {\n\tconst submissions: FlowSubmissions = {};\n\n\treturn {\n\t\tinterpret: async function* interpret({\n\t\t\tnodes,\n\t\t\tcontext,\n\t\t}: {\n\t\t\tnodes: LinkedList<FlowNode>;\n\t\t\tcontext: Record<string, unknown>;\n\t\t}): AsyncGenerator<FlowInterpreterYield> {\n\t\t\tconst actions: FlowActions = {\n\t\t\t\terror: ({ message }) => ({ type: 'error', message: interpolateWithData(message, { submissions, context }) }),\n\t\t\t\tinfo: ({ message }) => ({ type: 'info', message: interpolateWithData(message, { submissions, context }) }),\n\t\t\t\tsuccess: ({ message }) => ({\n\t\t\t\t\ttype: 'success',\n\t\t\t\t\tmessage: interpolateWithData(message, { submissions, context }),\n\t\t\t\t}),\n\t\t\t\ttext: ({ message, author }) => ({\n\t\t\t\t\ttype: 'text',\n\t\t\t\t\tauthor,\n\t\t\t\t\tmessage: interpolateWithData(message, { submissions, context }),\n\t\t\t\t}),\n\t\t\t\timage: ({ url, height, width }) => ({\n\t\t\t\t\ttype: 'image',\n\t\t\t\t\turl: interpolateWithData(url, { submissions, context }),\n\t\t\t\t\theight,\n\t\t\t\t\twidth,\n\t\t\t\t}),\n\t\t\t\tstate: state => ({ type: 'state', state }),\n\t\t\t\tlink: ({ href, message }) => ({\n\t\t\t\t\ttype: 'link',\n\t\t\t\t\thref: interpolateWithData(href, { submissions, context }),\n\t\t\t\t\tmessage: interpolateWithData(message, { submissions, context }),\n\t\t\t\t}),\n\t\t\t\tsubmissions: submissions => ({ type: 'submissions', submissions }),\n\t\t\t\tinput: (type, params) => {\n\t\t\t\t\treturn { type: 'input', input: { type, config: params.config, validate: params.validate } as any };\n\t\t\t\t},\n\t\t\t};\n\t\t\tif (!nodes.headId) return { type: 'error', message: 'No head node found' };\n\t\t\tlet node: LinkedListItem<FlowNode> | undefined = nodes.items[nodes.headId];\n\t\t\tconst next = (nextId: string | undefined): { type: 'next'; nodeId: string | undefined } => {\n\t\t\t\tif (!nextId) {\n\t\t\t\t\tnode = undefined;\n\t\t\t\t\treturn { type: 'next', nodeId: undefined };\n\t\t\t\t}\n\t\t\t\tconst nextNode = nodes.items[nextId];\n\t\t\t\tif (!nextNode) throw new Error(`Next node with id ${nextId} not found`);\n\t\t\t\tnode = nextNode;\n\t\t\t\treturn { type: 'next', nodeId: nextId };\n\t\t\t};\n\t\t\tconst config = { ...params, context, submissions, next, actions };\n\n\t\t\twhile (node) {\n\t\t\t\tswitch (node.type) {\n\t\t\t\t\tcase 'text':\n\t\t\t\t\t\tyield actions.text({ author: 'bot', message: node.data.text });\n\t\t\t\t\t\tnext(node.nextId);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'image':\n\t\t\t\t\t\tyield actions.image(node.data);\n\t\t\t\t\t\tnext(node.nextId);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'link':\n\t\t\t\t\t\tyield actions.link({ href: node.data.href, message: node.data.cta });\n\t\t\t\t\t\tnext(node.nextId);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'add-submission':\n\t\t\t\t\t\tsubmissions[node.data.key] = { type: 'string', value: node.data.value };\n\t\t\t\t\t\tnext(node.nextId);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'jump':\n\t\t\t\t\t\tnext(node.data.targetId);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'question-text':\n\t\t\t\t\t\tyield* interpretQuestionTextNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'question-phone':\n\t\t\t\t\t\tyield* interpretQuestionPhoneNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'question-boolean':\n\t\t\t\t\t\tyield* interpretQuestionBooleanNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'question-number':\n\t\t\t\t\t\tyield* interpretQuestionNumberNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'question-address':\n\t\t\t\t\t\tyield* interpretQuestionAddressNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'question-enum':\n\t\t\t\t\t\tyield* interpretQuestionEnumNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'question-file':\n\t\t\t\t\t\tyield* interpretQuestionFileNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'identify': {\n\t\t\t\t\t\tyield* interpretIdentifyNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'if-block': {\n\t\t\t\t\t\tconst nextNodeId =\n\t\t\t\t\t\t\tisIfBlockConditionMet(node, { context: config.context, submissions }) ? node.branchId : node.nextId;\n\t\t\t\t\t\tnext(nextNodeId);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'integration-application-submit':\n\t\t\t\t\t\tyield* interpretIntegrationApplicationSubmitNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'feedback':\n\t\t\t\t\t\tyield actions.error({ message: 'Not implemented' });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'integration-workflow-get':\n\t\t\t\t\t\tyield actions.error({ message: 'This message should never be reached' });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'end-flow':\n\t\t\t\t\t\tnode = undefined;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tyield actions.submissions(submissions);\n\t\t\t}\n\t\t\tyield { type: 'end' };\n\t\t},\n\t};\n};\n\nexport type InterpretNodeParams<TNodeType extends FlowNode['type']> = {\n\tnode: FlowNode & { type: TNodeType };\n\tconfig: FlowInterpreterParams & {\n\t\tsubmissions: FlowSubmissions;\n\t\tcontext: Record<string, unknown>;\n\t\tnext: (nextId: string | undefined) => { type: 'next'; nodeId: string | undefined };\n\t\tactions: FlowActions;\n\t};\n};\n\nexport type InterpretNodeReturn = AsyncGenerator<FlowInterpreterYield, { type: 'next'; nodeId: string | undefined }>;\n"],"mappings":"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","names":["import_get","isConditionMet","condition","context","submissions","ifBlock","firstSegment","path","answer","getSubmissionValueToCheck","value","get","newIfBlock","isIfBlockConditionMet","compareBoolean","compareNumber","conditions","import_get","HANDLEBARS_REGEXP","interpolateWithData","str","context","submissions","_","key","defaultValue","firstSegment","path","entity","getSubmissionValueToCheck","file","kbToReadableSize","line","formatPhoneNumber","value","get","i","interpretIdentifyNode","params","node","logger","analytics","submissions","next","getSubmissionValue","key","value","endpoint","typed","responseSchema","object","boolean","optional","string","number","unknown","nullable","submitEndpoint","endpoint","typed","interpretIntegrationApplicationSubmitNode","params","node","rpcClient","submissions","actions","next","analytics","logger","context","sessionInfo","tryCatch","response","getFlowSubmissionsPayload","parsed","safeParse","Err","Ok","e","issues","fieldValueSchema","pipe","nullable","optional","string","transform","i","getValidationSchema","node","keys","object","interpretQuestionAddressNode","params","submissions","actions","next","submission","Ok","schema","parsed","safeParse","Err","options","schema","picklist","interpretQuestionBooleanNode","params","node","submissions","actions","next","submission","Ok","parsed","safeParse","Err","interpretQuestionEnumNode","params","node","submissions","actions","next","schema","array","picklist","o","submission","Ok","parsed","safeParse","Err","interpretQuestionFileNode","params","node","submissions","actions","next","t","submission","Ok","minFiles","maxFiles","maxSize","allowedExtensions","ext","schema","pipe","array","object","string","check","filename","extension","getFileExtension","number","minLength","maxLength","files","acc","cur","kbToReadableSize","parsed","safeParse","Err","getValidationSchema","node","t","min","max","decimalCases","pipe","number","minValue","maxValue","check","value","interpretQuestionNumberNode","params","submissions","actions","next","thisSubmission","submission","Ok","schema","parsed","safeParse","Err","getValidationSchema","node","t","object","pipe","string","regex","minLength","transform","value","interpretQuestionPhoneNode","params","actions","next","submissions","thisSubmission","submission","Ok","schema","parsed","safeParse","Err","getValidationSchema","node","t","logger","errors","pipe","string","regex","email","minLength","maxLength","url","interpretQuestionTextNode","params","submissions","actions","next","thisSubmission","submission","Ok","schema","parsed","safeParse","Err","createFlowInterpreter","params","submissions","nodes","context","actions","message","interpolateWithData","author","url","height","width","state","href","type","node","next","nextId","nextNode","config","interpretQuestionTextNode","interpretQuestionPhoneNode","interpretQuestionBooleanNode","interpretQuestionNumberNode","interpretQuestionAddressNode","interpretQuestionEnumNode","interpretQuestionFileNode","interpretIdentifyNode","nextNodeId","isIfBlockConditionMet","interpretIntegrationApplicationSubmitNode"]}
|
|
1
|
+
{"version":3,"sources":["../src/conditions.ts","../src/interpolation.ts","../src/interpreter.check-duplicate.ts","../src/interpreter.identify.ts","../src/interpreter.integration-application-submit.ts","../src/interpreter.question-address.ts","../src/interpreter.question-boolean.ts","../src/interpreter.question-enum.ts","../src/interpreter.question-file.ts","../src/interpreter.question-number.ts","../src/interpreter.question-phone.ts","../src/interpreter.question-text.ts","../src/interpreter.ts"],"sourcesContent":["import { IfBlockNode, IfBlockNodeCondition } from '@inploi/core/flows';\nimport get from 'lodash/get';\n\nimport { FlowSubmissions } from './flow.types';\nimport { getSubmissionValueToCheck } from './utils';\n\nconst isConditionMet = ({\n\tcondition,\n\tcontext,\n\tsubmissions,\n\tifBlock,\n}: {\n\tcontext: Record<string, unknown>;\n\tcondition: IfBlockNodeCondition;\n\tsubmissions: FlowSubmissions;\n\tifBlock: IfBlockNode;\n}) => {\n\tconst [firstSegment, ...path] = condition.compareKey.split('.');\n\tif (!firstSegment) return false;\n\n\tconst answer = getSubmissionValueToCheck({ context, key: firstSegment, path, submissions });\n\tif (!answer) return false;\n\n\tswitch (answer.type) {\n\t\tcase 'address': {\n\t\t\tconst value = get(answer.value, path.join('.'));\n\t\t\tswitch (condition.compare) {\n\t\t\t\tcase 'equals':\n\t\t\t\t\treturn value === condition.compareValue;\n\t\t\t\tcase 'contains':\n\t\t\t\t\tif (!value) return false;\n\t\t\t\t\treturn value.includes(condition.compareValue);\n\t\t\t\tcase 'notEquals':\n\t\t\t\t\treturn value !== condition.compareValue;\n\t\t\t\tcase 'notContains':\n\t\t\t\t\tif (!value) return true;\n\t\t\t\t\treturn !value.includes(condition.compareValue);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'integration': {\n\t\t\t/** We only handle objects as integration submissions for now. */\n\t\t\tif (typeof answer.value !== 'object') return false;\n\t\t\tif (Array.isArray(answer.value)) return false;\n\n\t\t\tconst value = get(answer.value, path.join('.'));\n\t\t\tconst newIfBlock = {\n\t\t\t\t...ifBlock,\n\t\t\t\tdata: { compareKey: '_temp', compare: condition.compare, compareValue: condition.compareValue },\n\t\t\t};\n\t\t\tswitch (typeof value) {\n\t\t\t\tcase 'boolean':\n\t\t\t\t\treturn isIfBlockConditionMet(newIfBlock, {\n\t\t\t\t\t\tsubmissions: { ['_temp']: { value: value, type: 'boolean' } },\n\t\t\t\t\t\tcontext,\n\t\t\t\t\t});\n\t\t\t\tcase 'string':\n\t\t\t\t\treturn isIfBlockConditionMet(newIfBlock, {\n\t\t\t\t\t\tsubmissions: { ['_temp']: { value: value, type: 'string' } },\n\t\t\t\t\t\tcontext,\n\t\t\t\t\t});\n\t\t\t\tcase 'number':\n\t\t\t\t\treturn isIfBlockConditionMet(newIfBlock, {\n\t\t\t\t\t\tsubmissions: { ['_temp']: { value: value, type: 'number' } },\n\t\t\t\t\t\tcontext,\n\t\t\t\t\t});\n\t\t\t\tcase 'object':\n\t\t\t\t\t/** We only handle enums if the result is an array of strings */\n\t\t\t\t\tif (Array.isArray(value) && value.every((value): value is string => typeof value === 'string')) {\n\t\t\t\t\t\treturn isIfBlockConditionMet(newIfBlock, {\n\t\t\t\t\t\t\tsubmissions: { ['_temp']: { value: value, type: 'enum' } },\n\t\t\t\t\t\t\tcontext,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn false;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'boolean': {\n\t\t\tconst compareBoolean = condition.compareValue === 'true';\n\t\t\tswitch (condition.compare) {\n\t\t\t\tcase 'equals':\n\t\t\t\t\treturn answer.value === compareBoolean;\n\t\t\t\tcase 'notEquals':\n\t\t\t\t\treturn answer.value !== compareBoolean;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'phone':\n\t\tcase 'string': {\n\t\t\tconst value = answer.type === 'phone' ? answer.value.countryCode + answer.value.phoneNumber : answer.value;\n\t\t\tswitch (condition.compare) {\n\t\t\t\tcase 'equals':\n\t\t\t\t\treturn value === condition.compareValue;\n\t\t\t\tcase 'contains':\n\t\t\t\t\tif (!value) return false;\n\t\t\t\t\treturn value.includes(condition.compareValue);\n\t\t\t\tcase 'notEquals':\n\t\t\t\t\treturn value !== condition.compareValue;\n\t\t\t\tcase 'notContains':\n\t\t\t\t\tif (!value) return true;\n\t\t\t\t\treturn !value.includes(condition.compareValue);\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'number': {\n\t\t\ttry {\n\t\t\t\tconst compareNumber = Number(condition.compareValue);\n\t\t\t\tswitch (condition.compare) {\n\t\t\t\t\tcase 'equals':\n\t\t\t\t\t\treturn answer.value === compareNumber;\n\t\t\t\t\tcase 'notEquals':\n\t\t\t\t\t\treturn answer.value !== compareNumber;\n\t\t\t\t\tcase 'greaterThan':\n\t\t\t\t\t\treturn answer.value > compareNumber;\n\t\t\t\t\tcase 'greaterThanOrEqualTo':\n\t\t\t\t\t\treturn answer.value >= compareNumber;\n\t\t\t\t\tcase 'lessThan':\n\t\t\t\t\t\treturn answer.value < compareNumber;\n\t\t\t\t\tcase 'lessThanOrEqualTo':\n\t\t\t\t\t\treturn answer.value <= compareNumber;\n\t\t\t\t}\n\t\t\t} catch {\n\t\t\t\tconsole.error(`Failed to parse number in if-block ${ifBlock.id}`, answer.value);\n\t\t\t\treturn false;\n\t\t\t}\n\t\t\tbreak;\n\t\t}\n\n\t\tcase 'enum':\n\t\t\tswitch (condition.compare) {\n\t\t\t\tcase 'equals':\n\t\t\t\t\treturn answer.value.length === 1 && answer.value[0] === condition.compareValue;\n\t\t\t\tcase 'notEquals':\n\t\t\t\t\treturn answer.value.length === 1 && answer.value[0] !== condition.compareValue;\n\t\t\t\tcase 'contains':\n\t\t\t\t\treturn answer.value.includes(condition.compareValue);\n\t\t\t\tcase 'notContains':\n\t\t\t\t\treturn !answer.value.includes(condition.compareValue);\n\t\t\t}\n\t\t\tbreak;\n\n\t\tcase 'file':\n\t\t\tbreak;\n\n\t\tdefault:\n\t\t\tanswer satisfies never;\n\t\t\tbreak;\n\t}\n};\n\nexport const isIfBlockConditionMet = (\n\tifBlock: IfBlockNode,\n\t{ context, submissions }: { submissions: FlowSubmissions; context: Record<string, unknown> },\n): boolean => {\n\tconst conditions = 'combinator' in ifBlock.data ? ifBlock.data.conditions : [ifBlock.data];\n\tconst combinator = 'combinator' in ifBlock.data ? ifBlock.data.combinator : 'and';\n\n\tif (combinator === 'or') {\n\t\tfor (const condition of conditions) {\n\t\t\tconst isMet = isConditionMet({ condition, context, submissions, ifBlock });\n\t\t\tif (isMet) return true;\n\t\t}\n\t\treturn false;\n\t} else {\n\t\tfor (const condition of conditions) {\n\t\t\tconst isMet = isConditionMet({ condition, context, submissions, ifBlock });\n\t\t\tif (!isMet) return false;\n\t\t}\n\t\treturn true;\n\t}\n};\n","import get from 'lodash/get';\n\nimport { FlowSubmissions } from './flow.types';\nimport { formatPhoneNumber, getSubmissionValueToCheck, kbToReadableSize } from './utils';\n\nconst HANDLEBARS_REGEXP = /{{\\s*([^}]+?)\\s*(?:\\|\\s*([^}]+?)\\s*)?}}/g;\n\nexport const interpolateWithData = (\n\tstr: string,\n\t{ context, submissions }: { submissions: FlowSubmissions; context: Record<string, unknown> },\n) => {\n\treturn str.replace(HANDLEBARS_REGEXP, (_, key, defaultValue = '') => {\n\t\tconst [firstSegment, ...path] = key.trim().split('.');\n\t\tconst entity = getSubmissionValueToCheck({ key: firstSegment, path, submissions, context });\n\t\tif (!entity) return defaultValue;\n\n\t\tswitch (entity.type) {\n\t\t\tcase 'boolean':\n\t\t\t\treturn entity.value === true ? 'true' : 'false';\n\t\t\tcase 'file':\n\t\t\t\treturn entity.value.map(file => `${file.name} (${kbToReadableSize(file.sizeKb)})`).join(', ');\n\t\t\tcase 'enum':\n\t\t\t\treturn entity.value.join(', ');\n\t\t\tcase 'address':\n\t\t\t\treturn Object.values(entity.value)\n\t\t\t\t\t.filter(line => line && line.trim().length > 0)\n\t\t\t\t\t.join(', ');\n\t\t\tcase 'number':\n\t\t\tcase 'string':\n\t\t\t\tif (!entity.value) return defaultValue;\n\t\t\t\treturn entity.value.toString();\n\t\t\tcase 'phone':\n\t\t\t\treturn formatPhoneNumber(entity.value);\n\t\t\tcase 'integration': {\n\t\t\t\t/** We only handle objects as integration submissions for now. */\n\t\t\t\tif (typeof entity.value !== 'object') break;\n\t\t\t\tif (Array.isArray(entity.value)) break;\n\n\t\t\t\tconst value = get(entity.value, path.join('.'));\n\t\t\t\tswitch (typeof value) {\n\t\t\t\t\tcase 'boolean':\n\t\t\t\t\t\treturn value === true ? 'true' : 'false';\n\t\t\t\t\tcase 'string':\n\t\t\t\t\t\treturn value;\n\t\t\t\t\tcase 'number':\n\t\t\t\t\t\treturn value.toString();\n\t\t\t\t\tcase 'object':\n\t\t\t\t\t\t/** We only handle enums if the result is an array of strings */\n\t\t\t\t\t\tif (Array.isArray(value) && value.every((i): i is string => typeof i === 'string')) {\n\t\t\t\t\t\t\treturn value.join(', ');\n\t\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault:\n\t\t\t\tentity satisfies never;\n\t\t}\n\t\treturn defaultValue;\n\t});\n};\n","import { InterpretNodeParams } from './interpreter';\nimport { getSubmissionValue } from './utils';\n\nexport async function* interpretCheckDuplicateNode(params: InterpretNodeParams<'check-duplicate'>) {\n\tconst {\n\t\tnode,\n\t\tconfig: { logger, platformClient, submissions, context, next },\n\t} = params;\n\n\tlet result: { isDuplicate: boolean } = { isDuplicate: false };\n\n\tif (platformClient) {\n\t\tconst jobId = node.data.scope === 'job' ? (context.job_id as string | number | undefined) : undefined;\n\n\t\tif (node.data.scope === 'company' || jobId != null) {\n\t\t\ttry {\n\t\t\t\tresult = await platformClient.checkDuplicate({\n\t\t\t\t\temail: getSubmissionValue({ key: node.data.email, submissions }).toString(),\n\t\t\t\t\tjobId,\n\t\t\t\t\tscope: node.data.scope,\n\t\t\t\t});\n\t\t\t} catch (e) {\n\t\t\t\tlogger.error('[check-duplicate]', e);\n\t\t\t}\n\t\t}\n\t}\n\n\tsubmissions[node.data.key] = { type: 'integration', value: result };\n\treturn next(node.nextId);\n}\n","import { InterpretNodeParams } from './interpreter';\nimport { getSubmissionValue } from './utils';\n\nexport async function* interpretIdentifyNode(params: InterpretNodeParams<'identify'>) {\n\tconst {\n\t\tnode,\n\t\tconfig: { logger, analytics, submissions, next },\n\t} = params;\n\n\tanalytics.service\n\t\t.log({\n\t\t\tevent: 'IDENTIFY',\n\t\t\tproperties: {\n\t\t\t\tidentifier: getSubmissionValue({ key: node.data.key, submissions }).toString(),\n\t\t\t\tfirst_name:\n\t\t\t\t\tnode.data.firstName ? getSubmissionValue({ key: node.data.firstName, submissions }).toString() : undefined,\n\t\t\t\tlast_name:\n\t\t\t\t\tnode.data.lastName ? getSubmissionValue({ key: node.data.lastName, submissions }).toString() : undefined,\n\t\t\t\temail: node.data.email ? getSubmissionValue({ key: node.data.email, submissions }).toString() : undefined,\n\t\t\t\tphone_number:\n\t\t\t\t\tnode.data.phoneNumber ?\n\t\t\t\t\t\tgetSubmissionValue({ key: node.data.phoneNumber, submissions }).toString()\n\t\t\t\t\t:\tundefined,\n\t\t\t\tcustom_traits:\n\t\t\t\t\tnode.data.customTraits ?\n\t\t\t\t\t\tObject.fromEntries(node.data.customTraits.map(({ key, value }) => [key, submissions[value]?.value]))\n\t\t\t\t\t:\tundefined,\n\t\t\t},\n\t\t})\n\t\t.catch(logger.error);\n\n\treturn next(node.nextId);\n}\n","import { endpoint, typed } from '@inploi/sdk';\nimport * as v from 'valibot';\n\nimport { InterpretNodeParams, InterpretNodeReturn } from './interpreter';\nimport { Err, Ok, tryCatch } from './result';\nimport { getFlowSubmissionsPayload } from './utils';\n\nconst responseSchema = v.object({\n\t/** Not necessarily true when we receive a positive response because the API considers only 200 as success */\n\tsuccess: v.boolean(),\n\tintegration_response: v.object({\n\t\tservice: v.optional(v.string()),\n\t\tstatus: v.number(),\n\t\tdata: v.unknown(),\n\t\terror: v.nullable(v.object({ message: v.string(), data: v.unknown() })),\n\t}),\n});\nexport type IntegrationResponse = v.InferOutput<typeof responseSchema>;\n\nconst submitEndpoint = endpoint({\n\tpathname: '/flow/submit',\n\tmethod: 'POST',\n\tschema: {\n\t\tresponse: responseSchema,\n\t\tbody: typed<{\n\t\t\tlog_submit: boolean;\n\t\t\tintegration_id: string;\n\t\t\tanonymous_id: string | null | undefined;\n\t\t\tsession_id: string | null | undefined;\n\t\t\tjob: unknown;\n\t\t\tsubmissions: Record<string, unknown>;\n\t\t}>(),\n\t},\n});\n\nexport async function* interpretIntegrationApplicationSubmitNode(\n\tparams: InterpretNodeParams<'integration-application-submit'>,\n): InterpretNodeReturn {\n\tconst {\n\t\tnode,\n\t\tconfig: { rpcClient, submissions, actions, next, analytics, logger, context },\n\t} = params;\n\n\tif (node.data.skipConfirmation !== true) {\n\t\tyield actions.input('submit', {\n\t\t\tconfig: {\n\t\t\t\tkey: node.data.key ?? '_SUBMIT',\n\t\t\t\tlabel: node.data.submitLabel,\n\t\t\t},\n\t\t\t/** for submit node, validating _is_ submitting */\n\t\t\tvalidate: async () => {\n\t\t\t\tconst getSessionInfoSafe = tryCatch(analytics.service.getSessionInfo);\n\t\t\t\tconst sessionInfo = getSessionInfoSafe();\n\t\t\t\tif (sessionInfo.err) logger.error(sessionInfo.val.originalError);\n\n\t\t\t\ttry {\n\t\t\t\t\tconst response = await rpcClient.request(submitEndpoint, {\n\t\t\t\t\t\tbody: {\n\t\t\t\t\t\t\tlog_submit: false,\n\t\t\t\t\t\t\tintegration_id: node.data.integrationId,\n\t\t\t\t\t\t\tanonymous_id: sessionInfo.ok ? sessionInfo.val.anonymous_id : undefined,\n\t\t\t\t\t\t\tsession_id: sessionInfo.ok ? sessionInfo.val.session_id : undefined,\n\t\t\t\t\t\t\tjob: context.job,\n\t\t\t\t\t\t\tsubmissions: getFlowSubmissionsPayload(submissions),\n\t\t\t\t\t\t},\n\t\t\t\t\t});\n\n\t\t\t\t\tconst parsed = v.safeParse(responseSchema, response);\n\t\t\t\t\tif (parsed.success === false) return Err(parsed.issues);\n\t\t\t\t\treturn Ok(parsed.output);\n\t\t\t\t} catch (e) {\n\t\t\t\t\tconst issues: v.ValiError<any>['issues'] = [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tinput: e,\n\t\t\t\t\t\t\torigin: 'value',\n\t\t\t\t\t\t\treason: 'unknown',\n\t\t\t\t\t\t\tvalidation: 'API error',\n\t\t\t\t\t\t\tmessage:\n\t\t\t\t\t\t\t\te instanceof Error ? e.message\n\t\t\t\t\t\t\t\t: 'toString' in (e as any) ? (e as any).toString()\n\t\t\t\t\t\t\t\t: 'Unknown error',\n\t\t\t\t\t\t},\n\t\t\t\t\t];\n\t\t\t\t\treturn Err(issues);\n\t\t\t\t}\n\t\t\t},\n\t\t});\n\t}\n\n\treturn next(node.nextId);\n}\n","import * as v from 'valibot';\n\nimport { InterpretNodeParams, InterpretNodeReturn } from './interpreter';\nimport { Err, Ok } from './result';\n\nconst fieldValueSchema = v.pipe(\n\tv.nullable(v.optional(v.string())),\n\tv.transform(i => (i === null ? undefined : i)),\n);\nconst getValidationSchema = ({ node }: InterpretNodeParams<'question-address'>) => {\n\tconst keys = node.data.keys;\n\treturn v.object({\n\t\t[keys.line1 ?? 'line1']: fieldValueSchema,\n\t\t[keys.line2 ?? 'line2']: fieldValueSchema,\n\t\t[keys.line3 ?? 'line3']: fieldValueSchema,\n\t\t[keys.city ?? 'city']: fieldValueSchema,\n\t\t[keys.country ?? 'country']: fieldValueSchema,\n\t\t[keys.postcode ?? 'postcode']: fieldValueSchema,\n\t\t[keys.state ?? 'state']: fieldValueSchema,\n\t});\n};\n\nexport async function* interpretQuestionAddressNode(\n\tparams: InterpretNodeParams<'question-address'>,\n): InterpretNodeReturn {\n\tconst {\n\t\tnode,\n\t\tconfig: { submissions, actions, next },\n\t} = params;\n\tyield actions.text({ author: 'bot', message: node.data.question });\n\n\tyield actions.input('address', {\n\t\tconfig: {\n\t\t\tkey: node.data.key,\n\t\t\tkeys: node.data.keys,\n\t\t\tplaceholder: node.data.placeholder,\n\t\t\toptional: node.data.optional,\n\t\t},\n\t\tvalidate: submission => {\n\t\t\tif (node.data.optional && submission === null) return Ok(submission);\n\t\t\tconst schema = getValidationSchema(params);\n\t\t\tconst parsed = v.safeParse(schema, submission);\n\t\t\tif (parsed.success === false) return Err(parsed.issues);\n\t\t\tsubmissions[node.data.key] = { type: 'address', value: parsed.output };\n\t\t\treturn Ok(submission);\n\t\t},\n\t});\n\n\treturn next(node.nextId);\n}\n","import * as v from 'valibot';\n\nimport { InterpretNodeParams, InterpretNodeReturn } from './interpreter';\nimport { Err, Ok } from './result';\n\nconst options = ['true', 'false'] as const;\nconst schema = v.picklist(options);\n\nexport async function* interpretQuestionBooleanNode(\n\tparams: InterpretNodeParams<'question-boolean'>,\n): InterpretNodeReturn {\n\tconst {\n\t\tnode,\n\t\tconfig: { submissions, actions, next },\n\t} = params;\n\tyield actions.text({ author: 'bot', message: node.data.question });\n\n\tyield actions.input('boolean', {\n\t\tconfig: {\n\t\t\tkey: node.data.key,\n\t\t\tlabels: {\n\t\t\t\tfalse: node.data.falseLabel,\n\t\t\t\ttrue: node.data.trueLabel,\n\t\t\t},\n\t\t\toptional: node.data.optional,\n\t\t},\n\t\tvalidate: submission => {\n\t\t\tif (node.data.optional && submission === null) return Ok(submission);\n\t\t\tconst parsed = v.safeParse(schema, submission);\n\t\t\tif (parsed.success === false) return Err(parsed.issues);\n\t\t\tsubmissions[node.data.key] = { type: 'boolean', value: parsed.output === 'true' };\n\t\t\treturn Ok(submission);\n\t\t},\n\t});\n\n\treturn next(node.nextId);\n}\n","import { NonEmptyArray } from '@inploi/core/common';\nimport * as v from 'valibot';\n\nimport { InterpretNodeParams, InterpretNodeReturn } from './interpreter';\nimport { Err, Ok } from './result';\n\nexport async function* interpretQuestionEnumNode(params: InterpretNodeParams<'question-enum'>): InterpretNodeReturn {\n\tconst {\n\t\tnode,\n\t\tconfig: { submissions, actions, next },\n\t} = params;\n\tyield actions.text({ author: 'bot', message: node.data.question });\n\n\tconst schema = v.array(v.picklist(node.data.options.map(o => o.value) as NonEmptyArray<string>));\n\tyield actions.input('multiple-choice', {\n\t\tconfig: {\n\t\t\tkey: node.data.key,\n\t\t\toptions: node.data.options,\n\t\t\tmaxSelected: node.data.maxSelected,\n\t\t\tminSelected: node.data.minSelected,\n\t\t},\n\t\tvalidate: submission => {\n\t\t\tif (node.data.minSelected === 0 && submission === null) return Ok(submission);\n\t\t\tconst parsed = v.safeParse(schema, submission);\n\t\t\tif (parsed.success === false) return Err(parsed.issues);\n\t\t\tsubmissions[node.data.key] = { type: 'enum', value: parsed.output };\n\t\t\treturn Ok(submission);\n\t\t},\n\t});\n\n\treturn next(node.nextId);\n}\n","import * as v from 'valibot';\n\nimport { InterpretNodeParams, InterpretNodeReturn } from './interpreter';\nimport { Err, Ok } from './result';\nimport { getFileExtension, kbToReadableSize } from './utils';\n\nexport async function* interpretQuestionFileNode(params: InterpretNodeParams<'question-file'>): InterpretNodeReturn {\n\tconst {\n\t\tnode,\n\t\tconfig: { submissions, actions, next, t },\n\t} = params;\n\tyield actions.text({ author: 'bot', message: node.data.question });\n\n\tyield actions.input('file', {\n\t\tconfig: {\n\t\t\tkey: node.data.key,\n\t\t\tallowMultiple: node.data.multiple === true,\n\t\t\textensions: node.data.extensions,\n\t\t\tfileSizeLimitKib: node.data.maxSizeKb,\n\t\t\toptional: node.data.optional,\n\t\t},\n\t\tvalidate: submission => {\n\t\t\tif (node.data.optional && submission === null) return Ok(submission);\n\t\t\tconst minFiles = node.data.optional ? 0 : 1;\n\t\t\tconst maxFiles = node.data.multiple ? Number.POSITIVE_INFINITY : 1;\n\t\t\tconst maxSize = node.data.maxSizeKb ?? 0;\n\t\t\tconst allowedExtensions = node.data.extensions.map(ext => ext.toLowerCase());\n\t\t\tconst schema = v.pipe(\n\t\t\t\tv.array(\n\t\t\t\t\tv.object({\n\t\t\t\t\t\tname: v.pipe(\n\t\t\t\t\t\t\tv.string(t('validation_empty')),\n\t\t\t\t\t\t\tv.check(\n\t\t\t\t\t\t\t\tfilename => {\n\t\t\t\t\t\t\t\t\tconst extension = getFileExtension(filename);\n\t\t\t\t\t\t\t\t\tif (extension.ok === false) return false;\n\t\t\t\t\t\t\t\t\treturn allowedExtensions.includes(extension.val.toLowerCase());\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tt('validation_file_ext', { ext: allowedExtensions.join(', ') }),\n\t\t\t\t\t\t\t),\n\t\t\t\t\t\t),\n\t\t\t\t\t\tdata: v.string(),\n\t\t\t\t\t\tsizeKb: v.number(),\n\t\t\t\t\t}),\n\t\t\t\t),\n\t\t\t\tv.minLength(minFiles, t('validation_file_min', { count: minFiles })),\n\t\t\t\tv.maxLength(maxFiles, t('validation_file_max', { count: maxFiles })),\n\t\t\t\tv.check(\n\t\t\t\t\tfiles => {\n\t\t\t\t\t\tconst totalSize = files.reduce((acc, cur) => acc + cur.sizeKb, 0);\n\t\t\t\t\t\treturn totalSize <= maxSize;\n\t\t\t\t\t},\n\t\t\t\t\tt('validation_file_size', { size: kbToReadableSize(maxSize) }),\n\t\t\t\t),\n\t\t\t);\n\n\t\t\tconst parsed = v.safeParse(schema, submission);\n\t\t\tif (parsed.success === false) return Err(parsed.issues);\n\t\t\tsubmissions[node.data.key] = { type: 'file', value: parsed.output };\n\t\t\treturn Ok(submission);\n\t\t},\n\t});\n\n\treturn next(node.nextId);\n}\n","import * as v from 'valibot';\n\nimport { InterpretNodeParams, InterpretNodeReturn } from './interpreter';\nimport { Err, Ok } from './result';\n\nconst getValidationSchema = ({ node, config: { t } }: InterpretNodeParams<'question-number'>) => {\n\tconst min = node.data.min ?? Number.MIN_SAFE_INTEGER;\n\tconst max = node.data.max ?? Number.MAX_SAFE_INTEGER;\n\tconst decimalCases = node.data.decimalCases ?? 0;\n\n\treturn v.pipe(\n\t\tv.number(t('validation_number')),\n\t\tv.minValue(min, t('validation_number_min', { min })),\n\t\tv.maxValue(max, t('validation_number_max', { max })),\n\t\tv.check(\n\t\t\tvalue => {\n\t\t\t\treturn value === Number(value.toFixed(decimalCases));\n\t\t\t},\n\t\t\tt('validation_number_decimal_cases', { count: decimalCases }),\n\t\t),\n\t);\n};\n\nexport async function* interpretQuestionNumberNode(\n\tparams: InterpretNodeParams<'question-number'>,\n): InterpretNodeReturn {\n\tconst {\n\t\tnode,\n\t\tconfig: { submissions, actions, next },\n\t} = params;\n\tyield actions.text({ author: 'bot', message: node.data.question });\n\n\tconst thisSubmission = submissions[node.data.key];\n\tyield actions.input('number', {\n\t\tconfig: {\n\t\t\tkey: node.data.key,\n\t\t\tplaceholder: node.data.placeholder,\n\t\t\toptional: node.data.optional,\n\t\t\tdecimalCases: node.data.decimalCases,\n\t\t\tmax: node.data.max,\n\t\t\tmin: node.data.min,\n\t\t\tdefaultValue: thisSubmission?.type === 'number' ? thisSubmission.value.toString() : undefined,\n\t\t},\n\t\tvalidate: submission => {\n\t\t\tif (node.data.optional && submission === null) return Ok(submission);\n\t\t\tconst schema = getValidationSchema(params);\n\t\t\tconst parsed = v.safeParse(schema, submission);\n\t\t\tif (parsed.success === false) return Err(parsed.issues);\n\t\t\tsubmissions[node.data.key] = { type: 'number', value: parsed.output };\n\t\t\treturn Ok(submission);\n\t\t},\n\t});\n\n\treturn next(node.nextId);\n}\n","import * as v from 'valibot';\n\nimport { InterpretNodeParams, InterpretNodeReturn } from './interpreter';\nimport { Err, Ok } from './result';\n\nconst getValidationSchema = ({ node, config: { t } }: InterpretNodeParams<'question-phone'>) => {\n\treturn v.object({\n\t\tcountryCode: v.pipe(v.string(t('validation_country_code')), v.regex(/^\\+?[0-9 -]+$/, t('validation_country_code'))),\n\t\tphoneNumber: v.pipe(\n\t\t\tv.string(t('validation_phone')),\n\t\t\tv.regex(/^\\+?[0-9 -]+$/, t('validation_phone')),\n\t\t\tv.minLength(node.data.minChars, t('validation_min_chars', { count: node.data.minChars })),\n\t\t\tv.transform(value => value.replace(/[^0-9]/g, '')),\n\t\t),\n\t});\n};\n\nexport async function* interpretQuestionPhoneNode(params: InterpretNodeParams<'question-phone'>): InterpretNodeReturn {\n\tconst {\n\t\tnode,\n\t\tconfig: { actions, next, submissions },\n\t} = params;\n\tyield actions.text({ author: 'bot', message: node.data.question });\n\n\tconst thisSubmission = submissions[node.data.key];\n\tyield actions.input('phone', {\n\t\tconfig: {\n\t\t\tkey: node.data.key,\n\t\t\tminChars: node.data.minChars,\n\t\t\tdefaultValue:\n\t\t\t\tthisSubmission?.type === 'phone' ?\n\t\t\t\t\tthisSubmission.value\n\t\t\t\t:\t{\n\t\t\t\t\t\tcountryCode: node.data.defaultCountryCode,\n\t\t\t\t\t},\n\t\t\tplaceholder: node.data.placeholder,\n\t\t\tsubmissionFormat: 'phone',\n\t\t\toptional: node.data.optional,\n\t\t},\n\t\tvalidate: submission => {\n\t\t\tif (node.data.optional && submission === null) return Ok(submission);\n\t\t\tconst schema = getValidationSchema(params);\n\t\t\tconst parsed = v.safeParse(schema, submission);\n\t\t\tif (parsed.success === false) return Err(parsed.issues);\n\t\t\tsubmissions[node.data.key] = { type: 'address', value: parsed.output };\n\t\t\treturn Ok(submission);\n\t\t},\n\t});\n\n\treturn next(node.nextId);\n}\n","import * as v from 'valibot';\n\nimport { InterpretNodeParams, InterpretNodeReturn } from './interpreter';\nimport { Err, Ok } from './result';\n\nconst getValidationSchema = ({ node, config: { t, logger } }: InterpretNodeParams<'question-text'>) => {\n\tconst errors = {\n\t\tdate: t('validation_date'),\n\t\temail: t('validation_email'),\n\t\turl: t('validation_url'),\n\t\tmaxLength: t('validation_max_chars', { count: node.data.maxChars ?? 999 }),\n\t\tminLength: t('validation_min_chars', { count: node.data.minChars ?? 1 }),\n\t};\n\n\tswitch (node.data.format) {\n\t\tcase 'date':\n\t\t\treturn v.pipe(\n\t\t\t\tv.string(errors.date),\n\t\t\t\tv.regex(/^\\d{4}-\\d{2}-\\d{2}$/, errors.date),\n\t\t\t);\n\t\tcase 'email':\n\t\t\treturn v.pipe(\n\t\t\t\tv.string(errors.email),\n\t\t\t\tv.email(errors.email),\n\t\t\t\tv.minLength(node.data.minChars ?? 1, errors.minLength),\n\t\t\t\tv.maxLength(node.data.maxChars ?? Infinity, errors.maxLength),\n\t\t\t);\n\n\t\tcase 'text':\n\t\t\treturn v.pipe(\n\t\t\t\tv.string(),\n\t\t\t\tv.minLength(node.data.minChars ?? 1, errors.minLength),\n\t\t\t\tv.maxLength(node.data.maxChars ?? Infinity, errors.maxLength),\n\t\t\t);\n\t\tcase 'url':\n\t\t\treturn v.pipe(\n\t\t\t\tv.string(),\n\t\t\t\tv.url(errors.url),\n\t\t\t\tv.minLength(node.data.minChars ?? 1, errors.minLength),\n\t\t\t\tv.maxLength(node.data.maxChars ?? Infinity, errors.maxLength),\n\t\t\t);\n\t\tcase 'phone':\n\t\t\treturn v.pipe(\n\t\t\t\tv.string(),\n\t\t\t\tv.minLength(node.data.minChars ?? 1, errors.minLength),\n\t\t\t\tv.maxLength(node.data.maxChars ?? Infinity, errors.maxLength),\n\t\t\t);\n\t\tdefault:\n\t\t\tnode.data.format satisfies never;\n\t\t\tlogger.error(`Unsupported question-text format: ${node.data.format}`);\n\t\t\treturn null;\n\t}\n};\n\nexport async function* interpretQuestionTextNode(params: InterpretNodeParams<'question-text'>): InterpretNodeReturn {\n\tconst {\n\t\tnode,\n\t\tconfig: { submissions, actions, next },\n\t} = params;\n\tyield actions.text({ author: 'bot', message: node.data.question });\n\n\tconst thisSubmission = submissions[node.data.key];\n\tyield actions.input('text', {\n\t\tconfig: {\n\t\t\tkey: node.data.key,\n\t\t\tmaxChars: node.data.maxChars,\n\t\t\tminChars: node.data.minChars,\n\t\t\tplaceholder: node.data.placeholder,\n\t\t\tformat: node.data.format,\n\t\t\toptional: node.data.optional,\n\t\t\tdefaultValue: thisSubmission?.type === 'string' ? thisSubmission.value : undefined,\n\t\t},\n\t\tvalidate: submission => {\n\t\t\tif (node.data.optional && submission === null) return Ok(submission);\n\t\t\tconst schema = getValidationSchema(params);\n\t\t\tif (schema === null) return Ok(submission);\n\t\t\tconst parsed = v.safeParse(schema, submission);\n\t\t\tif (parsed.success === false) return Err(parsed.issues);\n\t\t\tsubmissions[node.data.key] = { type: 'string', value: parsed.output };\n\t\t\treturn Ok(submission);\n\t\t},\n\t});\n\n\treturn next(node.nextId);\n}\n","import { FlowNode } from '@inploi/core/flows';\nimport { AnalyticsService, InploiRpcClient, Logger } from '@inploi/sdk';\nimport type { PlatformClient } from '@inploi/sdk';\nimport { ValiError } from 'valibot';\n\nimport { isIfBlockConditionMet } from './conditions';\nimport { FlowSubmissions } from './flow.types';\nimport { TFunction } from './i18n';\nimport { FlowInput } from './inputs';\nimport { interpolateWithData } from './interpolation';\nimport { interpretCheckDuplicateNode } from './interpreter.check-duplicate';\nimport { interpretIdentifyNode } from './interpreter.identify';\nimport { interpretIntegrationApplicationSubmitNode } from './interpreter.integration-application-submit';\nimport { interpretQuestionAddressNode } from './interpreter.question-address';\nimport { interpretQuestionBooleanNode } from './interpreter.question-boolean';\nimport { interpretQuestionEnumNode } from './interpreter.question-enum';\nimport { interpretQuestionFileNode } from './interpreter.question-file';\nimport { interpretQuestionNumberNode } from './interpreter.question-number';\nimport { interpretQuestionPhoneNode } from './interpreter.question-phone';\nimport { interpretQuestionTextNode } from './interpreter.question-text';\nimport { LinkedList, LinkedListItem } from './linked-list';\nimport { Result } from './result';\n\ntype MaybePromise<T> = T | Promise<T>;\ntype FlowInterpreterYield =\n\t| { type: 'submissions'; submissions: FlowSubmissions }\n\t| { type: 'state'; state: 'loading' | 'idle' }\n\t| { type: 'error'; message: string }\n\t| { type: 'info'; message: string }\n\t| { type: 'success'; message: string }\n\t| { type: 'text'; author: 'user' | 'bot'; message: string }\n\t| { type: 'image'; url: string; height: number; width: number }\n\t| { type: 'link'; href: string; message: string }\n\t| { type: 'end' }\n\t| {\n\t\t\ttype: 'input';\n\t\t\tinput: {\n\t\t\t\t[I in FlowInput['type']]: {\n\t\t\t\t\ttype: I;\n\t\t\t\t\tconfig: (FlowInput & { type: I })['config'];\n\t\t\t\t\tvalidate: (\n\t\t\t\t\t\tinput: NonNullable<(FlowInput & { type: I })['submission']>['value'] | null,\n\t\t\t\t\t) => MaybePromise<\n\t\t\t\t\t\tResult<NonNullable<(FlowInput & { type: I })['submission']>['value'] | null, ValiError<any>['issues']>\n\t\t\t\t\t>;\n\t\t\t\t};\n\t\t\t}[FlowInput['type']];\n\t };\n\nexport type FlowInterpreterParams = {\n\trpcClient: InploiRpcClient;\n\tanalytics: {\n\t\tservice: AnalyticsService;\n\t\tcustomProperties?: Record<string, unknown>;\n\t};\n\tlogger: Logger;\n\tplatformClient?: PlatformClient;\n\tt: TFunction;\n};\n\nexport type FlowActions = {\n\terror: ({ message }: { message: string }) => FlowInterpreterYield;\n\tinfo: ({ message }: { message: string }) => FlowInterpreterYield;\n\tsuccess: ({ message }: { message: string }) => FlowInterpreterYield;\n\ttext: ({ message, author }: { message: string; author: 'bot' | 'user' }) => FlowInterpreterYield;\n\timage: ({ url, height, width }: { url: string; height: number; width: number }) => FlowInterpreterYield;\n\tlink: ({ href, message }: { href: string; message: string }) => FlowInterpreterYield;\n\tsubmissions: (submissions: FlowSubmissions) => FlowInterpreterYield;\n\tstate: (state: 'loading' | 'idle') => FlowInterpreterYield;\n\tinput: <T extends FlowInput['type'], Input extends FlowInput & { type: T }>(\n\t\ttype: T,\n\t\tparams: {\n\t\t\tconfig: Input['config'];\n\t\t\tvalidate: (\n\t\t\t\tinput: NonNullable<Input['submission']>['value'] | null,\n\t\t\t) => MaybePromise<Result<NonNullable<Input['submission']>['value'] | null, ValiError<any>['issues']>>;\n\t\t},\n\t) => FlowInterpreterYield;\n};\n\nexport const createFlowInterpreter = (params: FlowInterpreterParams) => {\n\tconst submissions: FlowSubmissions = {};\n\n\treturn {\n\t\tinterpret: async function* interpret({\n\t\t\tnodes,\n\t\t\tcontext,\n\t\t}: {\n\t\t\tnodes: LinkedList<FlowNode>;\n\t\t\tcontext: Record<string, unknown>;\n\t\t}): AsyncGenerator<FlowInterpreterYield> {\n\t\t\tconst actions: FlowActions = {\n\t\t\t\terror: ({ message }) => ({ type: 'error', message: interpolateWithData(message, { submissions, context }) }),\n\t\t\t\tinfo: ({ message }) => ({ type: 'info', message: interpolateWithData(message, { submissions, context }) }),\n\t\t\t\tsuccess: ({ message }) => ({\n\t\t\t\t\ttype: 'success',\n\t\t\t\t\tmessage: interpolateWithData(message, { submissions, context }),\n\t\t\t\t}),\n\t\t\t\ttext: ({ message, author }) => ({\n\t\t\t\t\ttype: 'text',\n\t\t\t\t\tauthor,\n\t\t\t\t\tmessage: interpolateWithData(message, { submissions, context }),\n\t\t\t\t}),\n\t\t\t\timage: ({ url, height, width }) => ({\n\t\t\t\t\ttype: 'image',\n\t\t\t\t\turl: interpolateWithData(url, { submissions, context }),\n\t\t\t\t\theight,\n\t\t\t\t\twidth,\n\t\t\t\t}),\n\t\t\t\tstate: state => ({ type: 'state', state }),\n\t\t\t\tlink: ({ href, message }) => ({\n\t\t\t\t\ttype: 'link',\n\t\t\t\t\thref: interpolateWithData(href, { submissions, context }),\n\t\t\t\t\tmessage: interpolateWithData(message, { submissions, context }),\n\t\t\t\t}),\n\t\t\t\tsubmissions: submissions => ({ type: 'submissions', submissions }),\n\t\t\t\tinput: (type, params) => {\n\t\t\t\t\treturn { type: 'input', input: { type, config: params.config, validate: params.validate } as any };\n\t\t\t\t},\n\t\t\t};\n\t\t\tif (!nodes.headId) return { type: 'error', message: 'No head node found' };\n\t\t\tlet node: LinkedListItem<FlowNode> | undefined = nodes.items[nodes.headId];\n\t\t\tconst next = (nextId: string | undefined): { type: 'next'; nodeId: string | undefined } => {\n\t\t\t\tif (!nextId) {\n\t\t\t\t\tnode = undefined;\n\t\t\t\t\treturn { type: 'next', nodeId: undefined };\n\t\t\t\t}\n\t\t\t\tconst nextNode = nodes.items[nextId];\n\t\t\t\tif (!nextNode) throw new Error(`Next node with id ${nextId} not found`);\n\t\t\t\tnode = nextNode;\n\t\t\t\treturn { type: 'next', nodeId: nextId };\n\t\t\t};\n\t\t\tconst config = { ...params, context, submissions, next, actions };\n\n\t\t\twhile (node) {\n\t\t\t\tswitch (node.type) {\n\t\t\t\t\tcase 'text':\n\t\t\t\t\t\tyield actions.text({ author: 'bot', message: node.data.text });\n\t\t\t\t\t\tnext(node.nextId);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'image':\n\t\t\t\t\t\tyield actions.image(node.data);\n\t\t\t\t\t\tnext(node.nextId);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'link':\n\t\t\t\t\t\tyield actions.link({ href: node.data.href, message: node.data.cta });\n\t\t\t\t\t\tnext(node.nextId);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'add-submission':\n\t\t\t\t\t\tsubmissions[node.data.key] = { type: 'string', value: node.data.value };\n\t\t\t\t\t\tnext(node.nextId);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'jump':\n\t\t\t\t\t\tnext(node.data.targetId);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'question-text':\n\t\t\t\t\t\tyield* interpretQuestionTextNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'question-phone':\n\t\t\t\t\t\tyield* interpretQuestionPhoneNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'question-boolean':\n\t\t\t\t\t\tyield* interpretQuestionBooleanNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'question-number':\n\t\t\t\t\t\tyield* interpretQuestionNumberNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'question-address':\n\t\t\t\t\t\tyield* interpretQuestionAddressNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'question-enum':\n\t\t\t\t\t\tyield* interpretQuestionEnumNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'question-file':\n\t\t\t\t\t\tyield* interpretQuestionFileNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'identify': {\n\t\t\t\t\t\tyield* interpretIdentifyNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'check-duplicate': {\n\t\t\t\t\t\tyield* interpretCheckDuplicateNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'if-block': {\n\t\t\t\t\t\tconst nextNodeId =\n\t\t\t\t\t\t\tisIfBlockConditionMet(node, { context: config.context, submissions }) ? node.branchId : node.nextId;\n\t\t\t\t\t\tnext(nextNodeId);\n\t\t\t\t\t\tbreak;\n\t\t\t\t\t}\n\t\t\t\t\tcase 'integration-application-submit':\n\t\t\t\t\t\tyield* interpretIntegrationApplicationSubmitNode({ config, node });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'feedback':\n\t\t\t\t\t\tyield actions.error({ message: 'Not implemented' });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'integration-workflow-get':\n\t\t\t\t\t\tyield actions.error({ message: 'This message should never be reached' });\n\t\t\t\t\t\tbreak;\n\t\t\t\t\tcase 'end-flow':\n\t\t\t\t\t\tnode = undefined;\n\t\t\t\t\t\tbreak;\n\t\t\t\t}\n\t\t\t\tyield actions.submissions(submissions);\n\t\t\t}\n\t\t\tyield { type: 'end' };\n\t\t},\n\t};\n};\n\nexport type InterpretNodeParams<TNodeType extends FlowNode['type']> = {\n\tnode: FlowNode & { type: TNodeType };\n\tconfig: FlowInterpreterParams & {\n\t\tsubmissions: FlowSubmissions;\n\t\tcontext: Record<string, unknown>;\n\t\tnext: (nextId: string | undefined) => { type: 'next'; nodeId: string | undefined };\n\t\tactions: FlowActions;\n\t};\n};\n\nexport type InterpretNodeReturn = AsyncGenerator<FlowInterpreterYield, { type: 'next'; nodeId: string | undefined }>;\n"],"mappings":"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","names":["import_get","isConditionMet","condition","context","submissions","ifBlock","firstSegment","path","answer","getSubmissionValueToCheck","value","get","newIfBlock","isIfBlockConditionMet","compareBoolean","compareNumber","conditions","import_get","HANDLEBARS_REGEXP","interpolateWithData","str","context","submissions","_","key","defaultValue","firstSegment","path","entity","getSubmissionValueToCheck","file","kbToReadableSize","line","formatPhoneNumber","value","get","i","interpretCheckDuplicateNode","params","node","logger","platformClient","submissions","context","next","result","jobId","getSubmissionValue","e","interpretIdentifyNode","params","node","logger","analytics","submissions","next","getSubmissionValue","key","value","endpoint","typed","responseSchema","object","boolean","optional","string","number","unknown","nullable","submitEndpoint","endpoint","typed","interpretIntegrationApplicationSubmitNode","params","node","rpcClient","submissions","actions","next","analytics","logger","context","sessionInfo","tryCatch","response","getFlowSubmissionsPayload","parsed","safeParse","Err","Ok","e","issues","fieldValueSchema","pipe","nullable","optional","string","transform","i","getValidationSchema","node","keys","object","interpretQuestionAddressNode","params","submissions","actions","next","submission","Ok","schema","parsed","safeParse","Err","options","schema","picklist","interpretQuestionBooleanNode","params","node","submissions","actions","next","submission","Ok","parsed","safeParse","Err","interpretQuestionEnumNode","params","node","submissions","actions","next","schema","array","picklist","o","submission","Ok","parsed","safeParse","Err","interpretQuestionFileNode","params","node","submissions","actions","next","t","submission","Ok","minFiles","maxFiles","maxSize","allowedExtensions","ext","schema","pipe","array","object","string","check","filename","extension","getFileExtension","number","minLength","maxLength","files","acc","cur","kbToReadableSize","parsed","safeParse","Err","getValidationSchema","node","t","min","max","decimalCases","pipe","number","minValue","maxValue","check","value","interpretQuestionNumberNode","params","submissions","actions","next","thisSubmission","submission","Ok","schema","parsed","safeParse","Err","getValidationSchema","node","t","object","pipe","string","regex","minLength","transform","value","interpretQuestionPhoneNode","params","actions","next","submissions","thisSubmission","submission","Ok","schema","parsed","safeParse","Err","getValidationSchema","node","t","logger","errors","pipe","string","regex","email","minLength","maxLength","url","interpretQuestionTextNode","params","submissions","actions","next","thisSubmission","submission","Ok","schema","parsed","safeParse","Err","createFlowInterpreter","params","submissions","nodes","context","actions","message","interpolateWithData","author","url","height","width","state","href","type","node","next","nextId","nextNode","config","interpretQuestionTextNode","interpretQuestionPhoneNode","interpretQuestionBooleanNode","interpretQuestionNumberNode","interpretQuestionAddressNode","interpretQuestionEnumNode","interpretQuestionFileNode","interpretIdentifyNode","interpretCheckDuplicateNode","nextNodeId","isIfBlockConditionMet","interpretIntegrationApplicationSubmitNode"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@inploi/flows",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.3",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"exports": {
|
|
6
6
|
"./interpreter": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
],
|
|
30
30
|
"peerDependencies": {
|
|
31
31
|
"@inploi/core": "*",
|
|
32
|
-
"@inploi/sdk": ">=1.17.
|
|
32
|
+
"@inploi/sdk": ">=1.17.3",
|
|
33
33
|
"@inploi/i18n": "*"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
@@ -41,9 +41,9 @@
|
|
|
41
41
|
"tsup": "^7.2.0",
|
|
42
42
|
"valibot": "1.1.0",
|
|
43
43
|
"nanoid": "^5.1.5",
|
|
44
|
+
"@inploi/core": "1.16.3",
|
|
44
45
|
"@inploi/i18n": "0.1.5",
|
|
45
|
-
"@inploi/
|
|
46
|
-
"@inploi/sdk": "1.17.0",
|
|
46
|
+
"@inploi/sdk": "1.17.3",
|
|
47
47
|
"eslint-config-custom": "0.1.0",
|
|
48
48
|
"tsconfig": "0.1.0"
|
|
49
49
|
},
|