@@ -105,7 +105,6 @@ export const ConversationContainer = (props: Props) => {
|
||||
})
|
||||
|
||||
const streamMessage = (content: string) => {
|
||||
console.log('STREAM', content)
|
||||
setIsSending(false)
|
||||
const lastChunk = [...chatChunks()].pop()
|
||||
if (!lastChunk) return
|
||||
|
||||
63
packages/lib/migrations/migrateTypebotFromV3ToV4.ts
Normal file
63
packages/lib/migrations/migrateTypebotFromV3ToV4.ts
Normal file
@@ -0,0 +1,63 @@
|
||||
import { PrismaClient, Webhook as WebhookFromDb } from '@typebot.io/prisma'
|
||||
import {
|
||||
Block,
|
||||
Typebot,
|
||||
Webhook,
|
||||
defaultWebhookAttributes,
|
||||
} from '@typebot.io/schemas'
|
||||
import { isWebhookBlock } from '../utils'
|
||||
import { HttpMethod } from '@typebot.io/schemas/features/blocks/integrations/webhook/enums'
|
||||
|
||||
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),
|
||||
},
|
||||
},
|
||||
})
|
||||
return {
|
||||
...typebot,
|
||||
version: '4',
|
||||
groups: typebot.groups.map((group) => ({
|
||||
...group,
|
||||
blocks: group.blocks.map(migrateWebhookBlock(webhooks)),
|
||||
})),
|
||||
}
|
||||
}
|
||||
|
||||
const migrateWebhookBlock =
|
||||
(webhooks: WebhookFromDb[]) =>
|
||||
(block: Block): Block => {
|
||||
if (!isWebhookBlock(block)) return block
|
||||
const webhook = webhooks.find((webhook) => webhook.id === block.webhookId)
|
||||
return {
|
||||
...block,
|
||||
webhookId: undefined,
|
||||
options: {
|
||||
...block.options,
|
||||
webhook: webhook
|
||||
? {
|
||||
id: webhook.id,
|
||||
url: webhook.url ?? undefined,
|
||||
method: (webhook.method as Webhook['method']) ?? HttpMethod.POST,
|
||||
headers: (webhook.headers as Webhook['headers']) ?? [],
|
||||
queryParams: (webhook.queryParams as Webhook['headers']) ?? [],
|
||||
body: webhook.body ?? undefined,
|
||||
}
|
||||
: {
|
||||
...defaultWebhookAttributes,
|
||||
id: block.webhookId ?? '',
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -125,16 +125,6 @@ export const blockTypeHasOption = (
|
||||
.concat(Object.values(IntegrationBlockType))
|
||||
.includes(type)
|
||||
|
||||
export const blockTypeHasWebhook = (
|
||||
type: BlockType
|
||||
): type is IntegrationBlockType.WEBHOOK =>
|
||||
Object.values([
|
||||
IntegrationBlockType.WEBHOOK,
|
||||
IntegrationBlockType.ZAPIER,
|
||||
IntegrationBlockType.MAKE_COM,
|
||||
IntegrationBlockType.PABBLY_CONNECT,
|
||||
] as string[]).includes(type)
|
||||
|
||||
export const blockTypeHasItems = (
|
||||
type: BlockType
|
||||
): type is
|
||||
|
||||
@@ -5,7 +5,7 @@ export * from './googleSheets'
|
||||
export * from './makeCom'
|
||||
export * from './pabblyConnect'
|
||||
export * from './sendEmail'
|
||||
export * from './webhook'
|
||||
export * from './webhook/schemas'
|
||||
export * from './zapier'
|
||||
export * from './pixel/schemas'
|
||||
export * from './pixel/constants'
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { IntegrationBlockType } from './enums'
|
||||
import { webhookOptionsSchema } from './webhook'
|
||||
import { webhookOptionsSchema } from './webhook/schemas'
|
||||
|
||||
export const makeComBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([IntegrationBlockType.MAKE_COM]),
|
||||
options: webhookOptionsSchema,
|
||||
webhookId: z.string(),
|
||||
webhookId: z
|
||||
.string()
|
||||
.describe('Deprecated, use webhook.id instead')
|
||||
.optional(),
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { IntegrationBlockType } from './enums'
|
||||
import { webhookOptionsSchema } from './webhook'
|
||||
import { webhookOptionsSchema } from './webhook/schemas'
|
||||
|
||||
export const pabblyConnectBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([IntegrationBlockType.PABBLY_CONNECT]),
|
||||
options: webhookOptionsSchema,
|
||||
webhookId: z.string(),
|
||||
webhookId: z
|
||||
.string()
|
||||
.describe('Deprecated, use webhook.id instead')
|
||||
.optional(),
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { IntegrationBlockType } from './enums'
|
||||
|
||||
const variableForTestSchema = z.object({
|
||||
id: z.string(),
|
||||
variableId: z.string().optional(),
|
||||
value: z.string().optional(),
|
||||
})
|
||||
|
||||
const responseVariableMappingSchema = z.object({
|
||||
id: z.string(),
|
||||
variableId: z.string().optional(),
|
||||
bodyPath: z.string().optional(),
|
||||
})
|
||||
|
||||
export const webhookOptionsSchema = z.object({
|
||||
variablesForTest: z.array(variableForTestSchema),
|
||||
responseVariableMapping: z.array(responseVariableMappingSchema),
|
||||
isAdvancedConfig: z.boolean().optional(),
|
||||
isCustomBody: z.boolean().optional(),
|
||||
isExecutedOnClient: z.boolean().optional(),
|
||||
})
|
||||
|
||||
export const webhookBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([IntegrationBlockType.WEBHOOK]),
|
||||
options: webhookOptionsSchema,
|
||||
webhookId: z.string(),
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultWebhookOptions: Omit<WebhookOptions, 'webhookId'> = {
|
||||
responseVariableMapping: [],
|
||||
variablesForTest: [],
|
||||
isAdvancedConfig: false,
|
||||
isCustomBody: false,
|
||||
}
|
||||
|
||||
export type WebhookBlock = z.infer<typeof webhookBlockSchema>
|
||||
export type WebhookOptions = z.infer<typeof webhookOptionsSchema>
|
||||
export type ResponseVariableMapping = z.infer<
|
||||
typeof responseVariableMappingSchema
|
||||
>
|
||||
export type VariableForTest = z.infer<typeof variableForTestSchema>
|
||||
@@ -0,0 +1,11 @@
|
||||
export enum HttpMethod {
|
||||
POST = 'POST',
|
||||
GET = 'GET',
|
||||
PUT = 'PUT',
|
||||
DELETE = 'DELETE',
|
||||
PATCH = 'PATCH',
|
||||
HEAD = 'HEAD',
|
||||
CONNECT = 'CONNECT',
|
||||
OPTIONS = 'OPTIONS',
|
||||
TRACE = 'TRACE',
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
export * from './enums'
|
||||
export * from './schemas'
|
||||
@@ -0,0 +1,95 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../../baseSchemas'
|
||||
import { IntegrationBlockType } from '../enums'
|
||||
import { HttpMethod } from './enums'
|
||||
|
||||
const variableForTestSchema = z.object({
|
||||
id: z.string(),
|
||||
variableId: z.string().optional(),
|
||||
value: z.string().optional(),
|
||||
})
|
||||
|
||||
const responseVariableMappingSchema = z.object({
|
||||
id: z.string(),
|
||||
variableId: z.string().optional(),
|
||||
bodyPath: z.string().optional(),
|
||||
})
|
||||
|
||||
const keyValueSchema = z.object({
|
||||
id: z.string(),
|
||||
key: z.string().optional(),
|
||||
value: z.string().optional(),
|
||||
})
|
||||
|
||||
export const webhookSchema = z.object({
|
||||
id: z.string(),
|
||||
queryParams: keyValueSchema.array(),
|
||||
headers: keyValueSchema.array(),
|
||||
method: z.nativeEnum(HttpMethod),
|
||||
url: z.string().optional(),
|
||||
body: z.string().optional(),
|
||||
})
|
||||
|
||||
export const webhookOptionsSchema = z.object({
|
||||
variablesForTest: z.array(variableForTestSchema),
|
||||
responseVariableMapping: z.array(responseVariableMappingSchema),
|
||||
isAdvancedConfig: z.boolean().optional(),
|
||||
isCustomBody: z.boolean().optional(),
|
||||
isExecutedOnClient: z.boolean().optional(),
|
||||
webhook: webhookSchema.optional(),
|
||||
})
|
||||
|
||||
export const webhookBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([IntegrationBlockType.WEBHOOK]),
|
||||
options: webhookOptionsSchema,
|
||||
webhookId: z
|
||||
.string()
|
||||
.describe('Deprecated, now integrated in webhook block options')
|
||||
.optional(),
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultWebhookAttributes: Omit<
|
||||
Webhook,
|
||||
'id' | 'body' | 'url' | 'typebotId' | 'createdAt' | 'updatedAt'
|
||||
> = {
|
||||
method: HttpMethod.POST,
|
||||
headers: [],
|
||||
queryParams: [],
|
||||
}
|
||||
|
||||
export const defaultWebhookOptions = (webhookId: string): WebhookOptions => ({
|
||||
responseVariableMapping: [],
|
||||
variablesForTest: [],
|
||||
isAdvancedConfig: false,
|
||||
isCustomBody: false,
|
||||
webhook: {
|
||||
id: webhookId,
|
||||
...defaultWebhookAttributes,
|
||||
},
|
||||
})
|
||||
|
||||
export const executableWebhookSchema = z.object({
|
||||
url: z.string(),
|
||||
headers: z.record(z.string()).optional(),
|
||||
body: z.unknown().optional(),
|
||||
method: z.nativeEnum(HttpMethod).optional(),
|
||||
})
|
||||
|
||||
export type KeyValue = { id: string; key?: string; value?: string }
|
||||
|
||||
export type WebhookResponse = {
|
||||
statusCode: number
|
||||
data?: unknown
|
||||
}
|
||||
|
||||
export type ExecutableWebhook = z.infer<typeof executableWebhookSchema>
|
||||
|
||||
export type Webhook = z.infer<typeof webhookSchema>
|
||||
export type WebhookBlock = z.infer<typeof webhookBlockSchema>
|
||||
export type WebhookOptions = z.infer<typeof webhookOptionsSchema>
|
||||
export type ResponseVariableMapping = z.infer<
|
||||
typeof responseVariableMappingSchema
|
||||
>
|
||||
export type VariableForTest = z.infer<typeof variableForTestSchema>
|
||||
@@ -1,13 +1,16 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { IntegrationBlockType } from './enums'
|
||||
import { webhookOptionsSchema } from './webhook'
|
||||
import { webhookOptionsSchema } from './webhook/schemas'
|
||||
|
||||
export const zapierBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([IntegrationBlockType.ZAPIER]),
|
||||
options: webhookOptionsSchema,
|
||||
webhookId: z.string(),
|
||||
webhookId: z
|
||||
.string()
|
||||
.describe('Deprecated, use webhook.id instead')
|
||||
.optional(),
|
||||
})
|
||||
)
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { z } from 'zod'
|
||||
import {
|
||||
executableWebhookSchema,
|
||||
googleAnalyticsOptionsSchema,
|
||||
paymentInputRuntimeOptionsSchema,
|
||||
pixelOptionsSchema,
|
||||
@@ -19,7 +20,6 @@ import { answerSchema } from './answer'
|
||||
import { BubbleBlockType } from './blocks/bubbles/enums'
|
||||
import { inputBlockSchemas } from './blocks/schemas'
|
||||
import { chatCompletionMessageSchema } from './blocks/integrations/openai'
|
||||
import { executableWebhookSchema } from './webhooks'
|
||||
|
||||
const typebotInSessionStateSchema = publicTypebotSchema.pick({
|
||||
id: true,
|
||||
|
||||
@@ -11,7 +11,7 @@ import { z } from 'zod'
|
||||
|
||||
export const publicTypebotSchema = z.object({
|
||||
id: z.string(),
|
||||
version: z.enum(['3']).nullable(),
|
||||
version: z.enum(['3', '4']).nullable(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
typebotId: z.string(),
|
||||
|
||||
@@ -39,7 +39,7 @@ const resultsTablePreferencesSchema = z.object({
|
||||
})
|
||||
|
||||
export const typebotSchema = z.object({
|
||||
version: z.enum(['3']).nullable(),
|
||||
version: z.enum(['3', '4']).nullable(),
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
groups: z.array(groupSchema),
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
import { Webhook as WebhookFromPrisma } from '@typebot.io/prisma'
|
||||
import { z } from 'zod'
|
||||
|
||||
export enum HttpMethod {
|
||||
POST = 'POST',
|
||||
GET = 'GET',
|
||||
PUT = 'PUT',
|
||||
DELETE = 'DELETE',
|
||||
PATCH = 'PATCH',
|
||||
HEAD = 'HEAD',
|
||||
CONNECT = 'CONNECT',
|
||||
OPTIONS = 'OPTIONS',
|
||||
TRACE = 'TRACE',
|
||||
}
|
||||
|
||||
export type KeyValue = { id: string; key?: string; value?: string }
|
||||
|
||||
export type Webhook = Omit<
|
||||
WebhookFromPrisma,
|
||||
'queryParams' | 'headers' | 'method' | 'createdAt' | 'updatedAt'
|
||||
> & {
|
||||
queryParams: KeyValue[]
|
||||
headers: KeyValue[]
|
||||
method: HttpMethod
|
||||
}
|
||||
|
||||
export type WebhookResponse = {
|
||||
statusCode: number
|
||||
data?: unknown
|
||||
}
|
||||
|
||||
export const defaultWebhookAttributes: Omit<
|
||||
Webhook,
|
||||
'id' | 'body' | 'url' | 'typebotId' | 'createdAt' | 'updatedAt'
|
||||
> = {
|
||||
method: HttpMethod.POST,
|
||||
headers: [],
|
||||
queryParams: [],
|
||||
}
|
||||
|
||||
export const executableWebhookSchema = z.object({
|
||||
url: z.string(),
|
||||
headers: z.record(z.string()).optional(),
|
||||
body: z.unknown().optional(),
|
||||
method: z.nativeEnum(HttpMethod).optional(),
|
||||
})
|
||||
|
||||
export type ExecutableWebhook = z.infer<typeof executableWebhookSchema>
|
||||
@@ -5,7 +5,6 @@ export * from './features/result'
|
||||
export * from './features/answer'
|
||||
export * from './features/utils'
|
||||
export * from './features/credentials'
|
||||
export * from './features/webhooks'
|
||||
export * from './features/chat'
|
||||
export * from './features/workspace'
|
||||
export * from './features/items'
|
||||
|
||||
Reference in New Issue
Block a user