2
0

♻️ Introduce typebot v6 with events (#1013)

Closes #885
This commit is contained in:
Baptiste Arnaud
2023-11-08 15:34:16 +01:00
committed by GitHub
parent 68e4fc71fb
commit 35300eaf34
634 changed files with 58971 additions and 31449 deletions

View File

@@ -0,0 +1,15 @@
import { PublicTypebot, PublicTypebotV6 } from '@typebot.io/schemas'
import { migrateTypebotFromV3ToV4 } from './migrateTypebotFromV3ToV4'
import { migrateTypebotFromV5ToV6 } from './migrateTypebotFromV5ToV6'
export const migrateTypebot = async (
typebot: PublicTypebot
): Promise<PublicTypebotV6> => {
if (typebot.version === '6') return typebot
let migratedTypebot: any = typebot
if (migratedTypebot.version === '3')
migratedTypebot = await migrateTypebotFromV3ToV4(typebot)
if (migratedTypebot.version === '4' || migratedTypebot.version === '5')
migratedTypebot = migrateTypebotFromV5ToV6(migratedTypebot)
return migratedTypebot
}

View File

@@ -0,0 +1,30 @@
import {
PublicTypebot,
PublicTypebotV6,
Typebot,
TypebotV6,
} from '@typebot.io/schemas'
import { migrateTypebotFromV3ToV4 } from './migrateTypebotFromV3ToV4'
import { migrateTypebotFromV5ToV6 } from './migrateTypebotFromV5ToV6'
export const migrateTypebot = async (typebot: Typebot): Promise<TypebotV6> => {
if (typebot.version === '6') return typebot
let migratedTypebot: any = typebot
if (migratedTypebot.version === '3')
migratedTypebot = await migrateTypebotFromV3ToV4(typebot)
if (migratedTypebot.version === '4' || migratedTypebot.version === '5')
migratedTypebot = migrateTypebotFromV5ToV6(migratedTypebot)
return migratedTypebot
}
export const migratePublicTypebot = async (
typebot: PublicTypebot
): Promise<PublicTypebotV6> => {
if (typebot.version === '6') return typebot
let migratedTypebot: any = typebot
if (migratedTypebot.version === '3')
migratedTypebot = await migrateTypebotFromV3ToV4(typebot)
if (migratedTypebot.version === '4' || migratedTypebot.version === '5')
migratedTypebot = migrateTypebotFromV5ToV6(migratedTypebot)
return migratedTypebot
}

View File

@@ -1,43 +1,48 @@
import { PrismaClient, Webhook as WebhookFromDb } from '@typebot.io/prisma'
import { Webhook as WebhookFromDb } from '@typebot.io/prisma'
import {
Block,
Typebot,
BlockV5,
PublicTypebotV5,
TypebotV5,
Webhook,
defaultWebhookAttributes,
} from '@typebot.io/schemas'
import { isWebhookBlock } from '../utils'
import { HttpMethod } from '@typebot.io/schemas/features/blocks/integrations/webhook/enums'
import { isWebhookBlock, isDefined } from '../utils'
import prisma from '../prisma'
import {
HttpMethod,
defaultWebhookAttributes,
} from '@typebot.io/schemas/features/blocks/integrations/webhook/constants'
export const migrateTypebotFromV3ToV4 =
(prisma: PrismaClient) =>
async (
typebot: Typebot
): Promise<Omit<Typebot, 'version'> & { version: '4' }> => {
if (typebot.version === '4')
return typebot as Omit<Typebot, 'version'> & { version: '4' }
const webhookBlocks = typebot.groups
.flatMap((group) => group.blocks)
.filter(isWebhookBlock)
const webhooks = await prisma.webhook.findMany({
where: {
id: {
in: webhookBlocks.map((block) => block.webhookId as string),
},
export const migrateTypebotFromV3ToV4 = async (
typebot: TypebotV5 | PublicTypebotV5
): Promise<Omit<TypebotV5 | PublicTypebotV5, 'version'> & { version: '4' }> => {
if (typebot.version === '4')
return typebot as Omit<TypebotV5, 'version'> & { version: '4' }
const webhookBlocks = typebot.groups
.flatMap((group) => group.blocks)
.filter(isWebhookBlock)
const webhooks = await prisma.webhook.findMany({
where: {
id: {
in: webhookBlocks
.map((block) => ('webhookId' in block ? block.webhookId : undefined))
.filter(isDefined),
},
})
return {
...typebot,
version: '4',
groups: typebot.groups.map((group) => ({
...group,
blocks: group.blocks.map(migrateWebhookBlock(webhooks)),
})),
}
},
})
return {
...typebot,
version: '4',
groups: typebot.groups.map((group) => ({
...group,
blocks: group.blocks.map(migrateWebhookBlock(webhooks)),
})),
}
}
const migrateWebhookBlock =
(webhooks: WebhookFromDb[]) =>
(block: Block): Block => {
(block: BlockV5): BlockV5 => {
if (!isWebhookBlock(block)) return block
const webhook = webhooks.find((webhook) => webhook.id === block.webhookId)
return {
@@ -56,7 +61,7 @@ const migrateWebhookBlock =
}
: {
...defaultWebhookAttributes,
id: block.webhookId ?? '',
id: 'webhookId' in block ? block.webhookId ?? '' : '',
},
},
}

View File

@@ -0,0 +1,125 @@
import {
BlockV5,
BlockV6,
GoogleSheetsBlockV5,
GoogleSheetsBlockV6,
PublicTypebotV5,
PublicTypebotV6,
TypebotV5,
TypebotV6,
} from '@typebot.io/schemas'
import { IntegrationBlockType } from '@typebot.io/schemas/features/blocks/integrations/constants'
import { GoogleSheetsAction } from '@typebot.io/schemas/features/blocks/integrations/googleSheets/constants'
import { ComparisonOperators } from '@typebot.io/schemas/features/blocks/logic/condition/constants'
import { createId } from '@paralleldrive/cuid2'
import { EventType } from '@typebot.io/schemas/features/events/constants'
import { byId } from '../utils'
export const migrateTypebotFromV5ToV6 = async (
typebot: TypebotV5 | PublicTypebotV5
): Promise<TypebotV6 | PublicTypebotV6> => {
const startGroup = typebot.groups.find((group) =>
group.blocks.some((b) => b.type === 'start')
)
if (!startGroup) throw new Error('Start group not found')
const startBlock = startGroup?.blocks.find((b) => b.type === 'start')
if (!startBlock) throw new Error('Start block not found')
const startOutgoingEdge = typebot.edges.find(byId(startBlock.outgoingEdgeId))
return {
...typebot,
groups: migrateGroups(
typebot.groups.filter((g) => g.blocks.some((b) => b.type !== 'start'))
),
version: '6',
events: [
{
id: startGroup.id,
type: EventType.START,
graphCoordinates: startGroup.graphCoordinates,
outgoingEdgeId: startBlock.outgoingEdgeId,
},
],
edges: startOutgoingEdge
? [
{
...startOutgoingEdge,
from: {
eventId: startGroup.id,
},
},
...typebot.edges.filter((e) => e.id !== startOutgoingEdge.id),
]
: typebot.edges,
}
}
const migrateGroups = (groups: TypebotV5['groups']): TypebotV6['groups'] =>
groups.map((group) => ({
...group,
blocks: migrateBlocksFromV1ToV2(group.blocks),
}))
const migrateBlocksFromV1ToV2 = (
blocks: TypebotV5['groups'][0]['blocks']
): BlockV6[] =>
(
blocks.filter((block) => block.type !== 'start') as Exclude<
BlockV5,
{ type: 'start' }
>[]
).map((block) => {
if (block.type === IntegrationBlockType.GOOGLE_SHEETS) {
return {
...block,
options: migrateGoogleSheetsOptions(block.options),
}
}
return block
})
const migrateGoogleSheetsOptions = (
options: GoogleSheetsBlockV5['options']
): GoogleSheetsBlockV6['options'] => {
if (!options) return
if (options.action === GoogleSheetsAction.GET) {
if (options.filter || !options.referenceCell) return options
return {
...options,
filter: {
comparisons: [
{
id: createId(),
column: options.referenceCell?.column,
comparisonOperator: ComparisonOperators.EQUAL,
value: options.referenceCell?.value,
},
],
},
}
}
if (options.action === GoogleSheetsAction.INSERT_ROW) {
return options
}
if (options.action === GoogleSheetsAction.UPDATE_ROW) {
if (options.filter || !options.referenceCell) return options
return {
...options,
filter: {
comparisons: [
{
id: createId(),
column: options.referenceCell?.column,
comparisonOperator: ComparisonOperators.EQUAL,
value: options.referenceCell?.value,
},
],
},
}
}
return options
}