2
0

(typebotLink) Better typebot link with merge option

Closes #675
This commit is contained in:
Baptiste Arnaud
2023-08-24 07:48:30 +02:00
parent 0acede92ef
commit ee3b94c35d
59 changed files with 1147 additions and 696 deletions

View File

@@ -5,6 +5,7 @@ import { LogicBlockType } from './enums'
export const typebotLinkOptionsSchema = z.object({
typebotId: z.string().optional(),
groupId: z.string().optional(),
mergeResults: z.boolean().optional(),
})
export const typebotLinkBlockSchema = blockBaseSchema.merge(
@@ -14,7 +15,9 @@ export const typebotLinkBlockSchema = blockBaseSchema.merge(
})
)
export const defaultTypebotLinkOptions: TypebotLinkOptions = {}
export const defaultTypebotLinkOptions: TypebotLinkOptions = {
mergeResults: false,
}
export type TypebotLinkBlock = z.infer<typeof typebotLinkBlockSchema>
export type TypebotLinkOptions = z.infer<typeof typebotLinkOptionsSchema>

View File

@@ -5,68 +5,21 @@ import {
paymentInputRuntimeOptionsSchema,
pixelOptionsSchema,
redirectOptionsSchema,
} from './blocks'
import { publicTypebotSchema } from './publicTypebot'
import { logSchema, resultSchema } from './result'
import { listVariableValue, typebotSchema } from './typebot'
} from '../blocks'
import { logSchema } from '../result'
import { listVariableValue, typebotSchema } from '../typebot'
import {
textBubbleContentSchema,
imageBubbleContentSchema,
videoBubbleContentSchema,
audioBubbleContentSchema,
embedBubbleContentSchema,
} from './blocks/bubbles'
import { answerSchema } from './answer'
import { BubbleBlockType } from './blocks/bubbles/enums'
import { inputBlockSchemas } from './blocks/schemas'
import { chatCompletionMessageSchema } from './blocks/integrations/openai'
const typebotInSessionStateSchema = publicTypebotSchema._def.schema.pick({
id: true,
groups: true,
edges: true,
variables: true,
})
const dynamicThemeSchema = z.object({
hostAvatarUrl: z.string().optional(),
guestAvatarUrl: z.string().optional(),
})
const answerInSessionStateSchema = answerSchema.pick({
content: true,
blockId: true,
variableId: true,
})
const resultInSessionStateSchema = resultSchema
.pick({
variables: true,
})
.merge(
z.object({
answers: z.array(answerInSessionStateSchema),
id: z.string().optional(),
})
)
export const sessionStateSchema = z.object({
typebot: typebotInSessionStateSchema,
dynamicTheme: dynamicThemeSchema.optional(),
linkedTypebots: z.object({
typebots: z.array(typebotInSessionStateSchema),
queue: z.array(z.object({ edgeId: z.string(), typebotId: z.string() })),
}),
currentTypebotId: z.string(),
result: resultInSessionStateSchema,
currentBlock: z
.object({
blockId: z.string(),
groupId: z.string(),
})
.optional(),
isStreamEnabled: z.boolean().optional(),
})
} from '../blocks/bubbles'
import { BubbleBlockType } from '../blocks/bubbles/enums'
import { inputBlockSchemas } from '../blocks/schemas'
import { chatCompletionMessageSchema } from '../blocks/integrations/openai'
import { sessionStateSchema } from './sessionState'
import { dynamicThemeSchema } from './shared'
const chatSessionSchema = z.object({
id: z.string(),
@@ -301,9 +254,7 @@ export const chatReplySchema = z.object({
})
export type ChatSession = z.infer<typeof chatSessionSchema>
export type SessionState = z.infer<typeof sessionStateSchema>
export type TypebotInSession = z.infer<typeof typebotInSessionStateSchema>
export type ResultInSession = z.infer<typeof resultInSessionStateSchema>
export type ChatReply = z.infer<typeof chatReplySchema>
export type ChatMessage = z.infer<typeof chatMessageSchema>
export type SendMessageInput = z.infer<typeof sendMessageInputSchema>

View File

@@ -0,0 +1,125 @@
import { z } from 'zod'
import { answerSchema } from '../answer'
import { resultSchema } from '../result'
import { typebotInSessionStateSchema, dynamicThemeSchema } from './shared'
const answerInSessionStateSchema = answerSchema.pick({
content: true,
blockId: true,
variableId: true,
})
const answerInSessionStateSchemaV2 = z.object({
key: z.string(),
value: z.string(),
})
export type AnswerInSessionState = z.infer<typeof answerInSessionStateSchemaV2>
const resultInSessionStateSchema = resultSchema
.pick({
variables: true,
})
.merge(
z.object({
answers: z.array(answerInSessionStateSchema),
id: z.string().optional(),
})
)
const sessionStateSchemaV1 = z.object({
typebot: typebotInSessionStateSchema,
dynamicTheme: dynamicThemeSchema.optional(),
linkedTypebots: z.object({
typebots: z.array(typebotInSessionStateSchema),
queue: z.array(z.object({ edgeId: z.string(), typebotId: z.string() })),
}),
currentTypebotId: z.string(),
result: resultInSessionStateSchema,
currentBlock: z
.object({
blockId: z.string(),
groupId: z.string(),
})
.optional(),
isStreamEnabled: z.boolean().optional(),
})
const sessionStateSchemaV2 = z.object({
version: z.literal('2'),
typebotsQueue: z.array(
z.object({
edgeIdToTriggerWhenDone: z.string().optional(),
isMergingWithParent: z.boolean().optional(),
resultId: z.string().optional(),
answers: z.array(answerInSessionStateSchemaV2),
typebot: typebotInSessionStateSchema,
})
),
dynamicTheme: dynamicThemeSchema.optional(),
currentBlock: z
.object({
blockId: z.string(),
groupId: z.string(),
})
.optional(),
isStreamEnabled: z.boolean().optional(),
})
export type SessionState = z.infer<typeof sessionStateSchemaV2>
export const sessionStateSchema = sessionStateSchemaV1
.or(sessionStateSchemaV2)
.transform((state): SessionState => {
if ('version' in state) return state
return {
version: '2',
typebotsQueue: [
{
typebot: state.typebot,
resultId: state.result.id,
answers: state.result.answers.map((answer) => ({
key:
(answer.variableId
? state.typebot.variables.find(
(variable) => variable.id === answer.variableId
)?.name
: state.typebot.groups.find((group) =>
group.blocks.find((block) => block.id === answer.blockId)
)?.title) ?? '',
value: answer.content,
})),
isMergingWithParent: true,
edgeIdToTriggerWhenDone:
state.linkedTypebots.queue.length > 0
? state.linkedTypebots.queue[0].edgeId
: undefined,
},
...state.linkedTypebots.typebots.map(
(typebot, index) =>
({
typebot,
resultId: state.result.id,
answers: state.result.answers.map((answer) => ({
key:
(answer.variableId
? state.typebot.variables.find(
(variable) => variable.id === answer.variableId
)?.name
: state.typebot.groups.find((group) =>
group.blocks.find(
(block) => block.id === answer.blockId
)
)?.title) ?? '',
value: answer.content,
})),
edgeIdToTriggerWhenDone: state.linkedTypebots.queue.at(index + 1)
?.edgeId,
} satisfies SessionState['typebotsQueue'][number])
),
],
dynamicTheme: state.dynamicTheme,
currentBlock: state.currentBlock,
isStreamEnabled: state.isStreamEnabled,
}
})

View File

@@ -0,0 +1,17 @@
import { z } from 'zod'
import { publicTypebotSchema } from '../publicTypebot'
export const typebotInSessionStateSchema = publicTypebotSchema._def.schema.pick(
{
id: true,
groups: true,
edges: true,
variables: true,
}
)
export type TypebotInSession = z.infer<typeof typebotInSessionStateSchema>
export const dynamicThemeSchema = z.object({
hostAvatarUrl: z.string().optional(),
guestAvatarUrl: z.string().optional(),
})

View File

@@ -5,6 +5,8 @@ export * from './features/result'
export * from './features/answer'
export * from './features/utils'
export * from './features/credentials'
export * from './features/chat'
export * from './features/chat/schema'
export * from './features/chat/sessionState'
export * from './features/chat/shared'
export * from './features/workspace'
export * from './features/items'