♻️ Re-organize workspace folders

This commit is contained in:
Baptiste Arnaud
2023-03-15 08:35:16 +01:00
parent 25c367901f
commit cbc8194f19
987 changed files with 2716 additions and 2770 deletions

View File

@@ -0,0 +1,32 @@
import {
BubbleBlock,
BubbleBlockType,
InputBlock,
InputBlockType,
Block,
} from '@typebot.io/schemas'
import { isBubbleBlock, isInputBlock } from '@typebot.io/lib'
import type { TypebotPostMessageData } from 'typebot-js'
export const getLastChatBlockType = (
blocks: Block[]
): BubbleBlockType | InputBlockType | undefined => {
const displayedBlocks = blocks.filter(
(s) => isBubbleBlock(s) || isInputBlock(s)
) as (BubbleBlock | InputBlock)[]
return displayedBlocks.pop()?.type
}
export const sendEventToParent = (data: TypebotPostMessageData) => {
try {
window.top?.postMessage(
{
from: 'typebot',
...data,
},
'*'
)
} catch (error) {
console.error(error)
}
}

View File

@@ -0,0 +1,33 @@
import { executeChatwootBlock } from '@/features/blocks/integrations/chatwoot'
import { executeGoogleAnalyticsBlock } from '@/features/blocks/integrations/googleAnalytics'
import { executeGoogleSheetBlock } from '@/features/blocks/integrations/googleSheets'
import { executeSendEmailBlock } from '@/features/blocks/integrations/sendEmail'
import { executeWebhook } from '@/features/blocks/integrations/webhook'
import { IntegrationState } from '@/types'
import { IntegrationBlock, IntegrationBlockType } from '@typebot.io/schemas'
export const executeIntegration = ({
block,
context,
}: {
block: IntegrationBlock
context: IntegrationState
}): Promise<string | undefined> | string | undefined => {
switch (block.type) {
case IntegrationBlockType.GOOGLE_SHEETS:
return executeGoogleSheetBlock(block, context)
case IntegrationBlockType.GOOGLE_ANALYTICS:
return executeGoogleAnalyticsBlock(block, context)
case IntegrationBlockType.ZAPIER:
case IntegrationBlockType.MAKE_COM:
case IntegrationBlockType.PABBLY_CONNECT:
case IntegrationBlockType.WEBHOOK:
return executeWebhook(block, context)
case IntegrationBlockType.EMAIL:
return executeSendEmailBlock(block, context)
case IntegrationBlockType.CHATWOOT:
return executeChatwootBlock(block, context)
default:
return
}
}

View File

@@ -0,0 +1,36 @@
import { TypebotViewerProps } from '@/components/TypebotViewer'
import { executeCondition } from '@/features/blocks/logic/condition'
import { executeRedirect } from '@/features/blocks/logic/redirect'
import { executeSetVariable } from '@/features/blocks/logic/setVariable'
import { executeTypebotLink } from '@/features/blocks/logic/typebotLink'
import { executeWait } from '@/features/blocks/logic/wait'
import { LinkedTypebot } from '@/providers/TypebotProvider'
import { EdgeId, LogicState } from '@/types'
import { LogicBlock, LogicBlockType } from '@typebot.io/schemas'
import { executeScript } from '@/features/blocks/logic/script/executeScript'
export const executeLogic = async (
block: LogicBlock,
context: LogicState
): Promise<{
nextEdgeId?: EdgeId
linkedTypebot?: TypebotViewerProps['typebot'] | LinkedTypebot
blockedPopupUrl?: string
}> => {
switch (block.type) {
case LogicBlockType.SET_VARIABLE:
return { nextEdgeId: executeSetVariable(block, context) }
case LogicBlockType.CONDITION:
return { nextEdgeId: executeCondition(block, context) }
case LogicBlockType.REDIRECT:
return executeRedirect(block, context)
case LogicBlockType.SCRIPT:
return { nextEdgeId: await executeScript(block, context) }
case LogicBlockType.TYPEBOT_LINK:
return executeTypebotLink(block, context)
case LogicBlockType.WAIT:
return { nextEdgeId: await executeWait(block, context) }
default:
return {}
}
}

View File

@@ -0,0 +1,28 @@
import { Log } from '@typebot.io/prisma'
export const sanitizeUrl = (url: string): string =>
url.startsWith('http') ||
url.startsWith('mailto:') ||
url.startsWith('tel:') ||
url.startsWith('sms:')
? url
: `https://${url}`
export const isMobile =
typeof window !== 'undefined' &&
window.matchMedia('only screen and (max-width: 760px)').matches
export const isEmbedded =
typeof window !== 'undefined' &&
window.parent &&
window.location !== window.top?.location
export const parseLog = (
error: Error | undefined,
successMessage: string,
errorMessage: string
): Omit<Log, 'id' | 'createdAt' | 'resultId'> => ({
status: error ? 'error' : 'success',
description: error ? errorMessage : successMessage,
details: (error && JSON.stringify(error, null, 2).substring(0, 1000)) ?? null,
})

View File

@@ -0,0 +1,62 @@
import { validateEmail } from '@/features/blocks/inputs/email'
import { validatePhoneNumber } from '@/features/blocks/inputs/phone'
import { validateUrl } from '@/features/blocks/inputs/url'
import { parseVariables } from '@/features/variables'
import {
BubbleBlock,
BubbleBlockType,
Edge,
EmailInputBlock,
InputBlockType,
PhoneNumberInputBlock,
Block,
UrlInputBlock,
Variable,
} from '@typebot.io/schemas'
import { isInputBlock } from '@typebot.io/lib'
export const isInputValid = (
inputValue: string,
type: InputBlockType
): boolean => {
switch (type) {
case InputBlockType.EMAIL:
return validateEmail(inputValue)
case InputBlockType.PHONE:
return validatePhoneNumber(inputValue)
case InputBlockType.URL:
return validateUrl(inputValue)
}
return true
}
export const blockCanBeRetried = (
block: Block
): block is EmailInputBlock | UrlInputBlock | PhoneNumberInputBlock =>
isInputBlock(block) && 'retryMessageContent' in block.options
export const parseRetryBlock = (
block: EmailInputBlock | UrlInputBlock | PhoneNumberInputBlock,
variables: Variable[],
createEdge: (edge: Edge) => void
): BubbleBlock => {
const content = parseVariables(variables)(block.options.retryMessageContent)
const newBlockId = block.id + Math.random() * 1000
const newEdge: Edge = {
id: (Math.random() * 1000).toString(),
from: { blockId: newBlockId, groupId: block.groupId },
to: { groupId: block.groupId, blockId: block.id },
}
createEdge(newEdge)
return {
groupId: block.groupId,
id: newBlockId,
type: BubbleBlockType.TEXT,
content: {
html: `<div>${content}</div>`,
richText: [],
plainText: content,
},
outgoingEdgeId: newEdge.id,
}
}