2
0

📝 Migrate from Docusaurus to Mintlify (#1115)

Closes #868
This commit is contained in:
Baptiste Arnaud
2023-12-22 09:13:53 +01:00
committed by GitHub
parent 512bb09282
commit 1e5fa5a575
450 changed files with 49522 additions and 104787 deletions

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../zod'
export const totalAnswersSchema = z.object({
blockId: z.string(),

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../zod'
import { Answer as AnswerPrisma, Prisma } from '@typebot.io/prisma'
export const answerSchema = z.object({

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../zod'
export const invoiceSchema = z.object({
id: z.string(),

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../zod'
export const subscriptionSchema = z.object({
currentBillingPeriod: z.object({

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { blockBaseSchema } from '../../shared'
import { BubbleBlockType } from '../constants'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { variableStringSchema } from '../../../utils'
import { blockBaseSchema } from '../../shared'
import { BubbleBlockType } from '../constants'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { BubbleBlockType } from '../constants'
import { blockBaseSchema } from '../../shared'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../zod'
import { audioBubbleBlockSchema } from './audio'
import { embedBubbleBlockSchema } from './embed'
import { imageBubbleBlockSchema } from './image'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import type { TElement } from '@udecode/plate-common'
import { blockBaseSchema } from '../../shared'
import { BubbleBlockType } from '../constants'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { blockBaseSchema } from '../../shared'
import { VideoBubbleContentType } from './constants'
import { variableStringSchema } from '../../../utils'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { InputBlockType } from '../constants'
import { itemBaseSchemas } from '../../../items/shared'
import { optionBaseSchema, blockBaseSchema } from '../../shared'
@ -49,10 +49,18 @@ export const buttonsInputV5Schema = blockBaseSchema.merge(
)
export const buttonsInputSchemas = {
v5: buttonsInputV5Schema,
v6: buttonsInputV5Schema.extend({
items: z.array(buttonItemSchemas.v6),
v5: buttonsInputV5Schema.openapi({
title: 'Buttons v5',
ref: 'buttonsInputV5',
}),
v6: buttonsInputV5Schema
.extend({
items: z.array(buttonItemSchemas.v6),
})
.openapi({
title: 'Buttons',
ref: 'buttonsInput',
}),
} as const
export const buttonsInputSchema = z.union([

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { optionBaseSchema, blockBaseSchema } from '../../shared'
import { InputBlockType } from '../constants'
@ -19,11 +19,16 @@ export const dateInputOptionsSchema = optionBaseSchema.merge(
})
)
export const dateInputSchema = blockBaseSchema.merge(
z.object({
type: z.enum([InputBlockType.DATE]),
options: dateInputOptionsSchema.optional(),
export const dateInputSchema = blockBaseSchema
.merge(
z.object({
type: z.enum([InputBlockType.DATE]),
options: dateInputOptionsSchema.optional(),
})
)
.openapi({
title: 'Date',
ref: 'dateInput',
})
)
export type DateInputBlock = z.infer<typeof dateInputSchema>

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { optionBaseSchema, blockBaseSchema } from '../../shared'
import { InputBlockType } from '../constants'
import { textInputOptionsBaseSchema } from '../text'
@ -11,12 +11,17 @@ export const emailInputOptionsSchema = optionBaseSchema
})
)
export const emailInputSchema = blockBaseSchema.merge(
z.object({
type: z.enum([InputBlockType.EMAIL]),
options: emailInputOptionsSchema.optional(),
export const emailInputSchema = blockBaseSchema
.merge(
z.object({
type: z.enum([InputBlockType.EMAIL]),
options: emailInputOptionsSchema.optional(),
})
)
.openapi({
title: 'Email',
ref: 'email',
})
)
export type EmailInputBlock = z.infer<typeof emailInputSchema>
export type EmailInputOptions = z.infer<typeof emailInputOptionsSchema>

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { optionBaseSchema, blockBaseSchema } from '../../shared'
import { InputBlockType } from '../constants'
@ -33,12 +33,20 @@ const fileInputBlockV5Schema = blockBaseSchema.merge(
)
export const fileInputBlockSchemas = {
v5: fileInputBlockV5Schema,
v6: fileInputBlockV5Schema.merge(
z.object({
options: fileInputOptionsSchemas.v6.optional(),
})
),
v5: fileInputBlockV5Schema.openapi({
title: 'File input v5',
ref: 'fileInputV5',
}),
v6: fileInputBlockV5Schema
.merge(
z.object({
options: fileInputOptionsSchemas.v6.optional(),
})
)
.openapi({
title: 'File',
ref: 'fileInput',
}),
}
const fileInputBlockSchema = z.union([

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { variableStringSchema } from '../../../utils'
import { optionBaseSchema, blockBaseSchema } from '../../shared'
import { InputBlockType } from '../constants'
@ -14,11 +14,16 @@ export const numberInputOptionsSchema = optionBaseSchema
})
)
export const numberInputSchema = blockBaseSchema.merge(
z.object({
type: z.enum([InputBlockType.NUMBER]),
options: numberInputOptionsSchema.optional(),
export const numberInputSchema = blockBaseSchema
.merge(
z.object({
type: z.enum([InputBlockType.NUMBER]),
options: numberInputOptionsSchema.optional(),
})
)
.openapi({
title: 'Number',
ref: 'numberInput',
})
)
export type NumberInputBlock = z.infer<typeof numberInputSchema>

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import {
optionBaseSchema,
blockBaseSchema,
@ -54,12 +54,17 @@ export const paymentInputRuntimeOptionsSchema = z.object({
publicKey: z.string(),
})
export const paymentInputSchema = blockBaseSchema.merge(
z.object({
type: z.enum([InputBlockType.PAYMENT]),
options: paymentInputOptionsSchema.optional(),
export const paymentInputSchema = blockBaseSchema
.merge(
z.object({
type: z.enum([InputBlockType.PAYMENT]),
options: paymentInputOptionsSchema.optional(),
})
)
.openapi({
title: 'Payment',
ref: 'paymentInput',
})
)
export const stripeCredentialsSchema = z
.object({

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { optionBaseSchema, blockBaseSchema } from '../../shared'
import { InputBlockType } from '../constants'
import { textInputOptionsBaseSchema } from '../text'
@ -12,11 +12,16 @@ export const phoneNumberInputOptionsSchema = optionBaseSchema
})
)
export const phoneNumberInputBlockSchema = blockBaseSchema.merge(
z.object({
type: z.enum([InputBlockType.PHONE]),
options: phoneNumberInputOptionsSchema.optional(),
export const phoneNumberInputBlockSchema = blockBaseSchema
.merge(
z.object({
type: z.enum([InputBlockType.PHONE]),
options: phoneNumberInputOptionsSchema.optional(),
})
)
.openapi({
title: 'Phone number',
ref: 'phoneNumberInput',
})
)
export type PhoneNumberInputBlock = z.infer<typeof phoneNumberInputBlockSchema>

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { optionBaseSchema, blockBaseSchema } from '../../shared'
import { conditionSchema } from '../../logic'
import { InputBlockType } from '../constants'
@ -60,10 +60,18 @@ export const pictureChoiceBlockV5Schema = blockBaseSchema.merge(
)
export const pictureChoiceBlockSchemas = {
v5: pictureChoiceBlockV5Schema,
v6: pictureChoiceBlockV5Schema.extend({
items: z.array(pictureChoiceItemSchemas.v6),
v5: pictureChoiceBlockV5Schema.openapi({
title: 'Picture choice v5',
ref: 'pictureChoiceV5',
}),
v6: pictureChoiceBlockV5Schema
.extend({
items: z.array(pictureChoiceItemSchemas.v6),
})
.openapi({
title: 'Picture choice',
ref: 'pictureChoice',
}),
} as const
export const pictureChoiceBlockSchema = z.union([

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { optionBaseSchema, blockBaseSchema } from '../../shared'
import { InputBlockType } from '../constants'
@ -23,11 +23,16 @@ export const ratingInputOptionsSchema = optionBaseSchema.merge(
})
)
export const ratingInputBlockSchema = blockBaseSchema.merge(
z.object({
type: z.literal(InputBlockType.RATING),
options: ratingInputOptionsSchema.optional(),
export const ratingInputBlockSchema = blockBaseSchema
.merge(
z.object({
type: z.literal(InputBlockType.RATING),
options: ratingInputOptionsSchema.optional(),
})
)
.openapi({
title: 'Rating',
ref: 'rating',
})
)
export type RatingInputBlock = z.infer<typeof ratingInputBlockSchema>

View File

@ -1,14 +1,11 @@
import { z } from 'zod'
import { z } from '../../../zod'
import { buttonsInputSchemas } from './choice'
import { dateInputSchema } from './date'
import { emailInputSchema } from './email'
import { numberInputSchema } from './number'
import { paymentInputSchema } from './payment'
import { phoneNumberInputBlockSchema } from './phone'
import {
pictureChoiceBlockSchema,
pictureChoiceBlockSchemas,
} from './pictureChoice'
import { pictureChoiceBlockSchemas } from './pictureChoice'
import { ratingInputBlockSchema } from './rating'
import { textInputSchema } from './text'
import { urlInputSchema } from './url'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { optionBaseSchema, blockBaseSchema } from '../../shared'
import { InputBlockType } from '../constants'
@ -19,11 +19,16 @@ export const textInputOptionsSchema = textInputOptionsBaseSchema
})
)
export const textInputSchema = blockBaseSchema.merge(
z.object({
type: z.enum([InputBlockType.TEXT]),
options: textInputOptionsSchema.optional(),
export const textInputSchema = blockBaseSchema
.merge(
z.object({
type: z.enum([InputBlockType.TEXT]),
options: textInputOptionsSchema.optional(),
})
)
.openapi({
title: 'Text',
ref: 'textInput',
})
)
export type TextInputBlock = z.infer<typeof textInputSchema>

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { optionBaseSchema, blockBaseSchema } from '../../shared'
import { InputBlockType } from '../constants'
import { textInputOptionsBaseSchema } from '../text'
@ -11,11 +11,16 @@ export const urlInputOptionsSchema = optionBaseSchema
})
)
export const urlInputSchema = blockBaseSchema.merge(
z.object({
type: z.enum([InputBlockType.URL]),
options: urlInputOptionsSchema.optional(),
export const urlInputSchema = blockBaseSchema
.merge(
z.object({
type: z.enum([InputBlockType.URL]),
options: urlInputOptionsSchema.optional(),
})
)
.openapi({
title: 'URL',
ref: 'url',
})
)
export type UrlInputBlock = z.infer<typeof urlInputSchema>

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { chatwootTasks } from './constants'
import { blockBaseSchema } from '../../shared'
import { IntegrationBlockType } from '../constants'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { variableStringSchema } from '../../../utils'
import { blockBaseSchema } from '../../shared'
import { IntegrationBlockType } from '../constants'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { IntegrationBlockType } from '../constants'
import { GoogleSheetsAction, totalRowsToExtractOptions } from './constants'
import { blockBaseSchema, credentialsBaseSchema } from '../../shared'
@ -34,7 +34,9 @@ const rowsFilterComparisonSchema = z.object({
const initialGoogleSheetsOptionsSchema = googleSheetsOptionsBaseSchema.merge(
z.object({
action: z.undefined(),
action: z.undefined().openapi({
type: 'string',
}),
})
)

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { IntegrationBlockType } from '../constants'
import { webhookBlockSchemas } from '../webhook'

View File

@ -1,6 +1,5 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import {
chatCompletionMessageCustomRoles,
chatCompletionMessageRoles,
chatCompletionResponseValues,
openAITasks,
@ -18,7 +17,9 @@ const openAIBaseOptionsSchema = z.object({
const initialOptionsSchema = z
.object({
task: z.undefined(),
task: z.undefined().openapi({
type: 'string',
}),
})
.merge(openAIBaseOptionsSchema)

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { IntegrationBlockType } from '../constants'
import { webhookBlockSchemas } from '../webhook'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { pixelEventTypes } from './constants'
import { blockBaseSchema } from '../../shared'
import { IntegrationBlockType } from '../constants'
@ -19,7 +19,9 @@ const basePixelOptionSchema = z.object({
const initialPixelOptionSchema = basePixelOptionSchema.merge(
z.object({
eventType: z.undefined(),
eventType: z.undefined().openapi({
type: 'string',
}),
})
)

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../zod'
import { chatwootBlockSchema } from './chatwoot'
import { googleAnalyticsBlockSchema } from './googleAnalytics'
import { googleSheetsBlockSchemas } from './googleSheets'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { blockBaseSchema, credentialsBaseSchema } from '../../shared'
import { IntegrationBlockType } from '../constants'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { blockBaseSchema } from '../../shared'
import { IntegrationBlockType } from '../constants'
import { HttpMethod } from './constants'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { IntegrationBlockType } from '../constants'
import { webhookBlockSchemas } from '../webhook'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { blockBaseSchema, credentialsBaseSchema } from '../../shared'
import { IntegrationBlockType } from '../constants'
import { searchResponseValues } from './constants'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { blockBaseSchema } from '../../shared'
import { LogicBlockType } from '../constants'
import { itemBaseSchemas } from '../../../items/shared'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { blockBaseSchema } from '../../shared'
import { LogicBlockType } from '../constants'
import { ComparisonOperators, LogicalOperator } from './constants'
@ -39,14 +39,18 @@ export const conditionBlockSchemas = {
z.object({
type: z.enum([LogicBlockType.CONDITION]),
items: z.array(conditionItemSchemas.v5),
options: z.undefined(),
options: z.undefined().openapi({
type: 'object',
}),
})
),
v6: blockBaseSchema.merge(
z.object({
type: z.enum([LogicBlockType.CONDITION]),
items: z.array(conditionItemSchemas.v6),
options: z.undefined(),
options: z.undefined().openapi({
type: 'object',
}),
})
),
}

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { blockBaseSchema } from '../../shared'
import { LogicBlockType } from '../constants'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { blockBaseSchema } from '../../shared'
import { LogicBlockType } from '../constants'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../zod'
import { conditionBlockSchemas } from './condition'
import { jumpBlockSchema } from './jump'
import { redirectBlockSchema } from './redirect'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { blockBaseSchema } from '../../shared'
import { LogicBlockType } from '../constants'

View File

@ -1,6 +1,9 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { blockBaseSchema } from '../../shared'
import { LogicBlockType } from '../constants'
import { extendZodWithOpenApi } from 'zod-openapi'
extendZodWithOpenApi(z)
const baseOptions = z.object({
variableId: z.string().optional(),
@ -24,7 +27,7 @@ const basicSetVariableOptionsSchema = baseOptions.extend({
})
const initialSetVariableOptionsSchema = baseOptions.extend({
type: z.undefined(),
type: z.undefined().openapi({ type: 'string' }),
expressionToEvaluate: z.string().optional(),
isCode: z.boolean().optional(),
})

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { blockBaseSchema } from '../../shared'
import { LogicBlockType } from '../constants'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../../zod'
import { blockBaseSchema } from '../../shared'
import { LogicBlockType } from '../constants'

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../zod'
import { blockBaseSchema } from './shared'
import { startBlockSchema } from './start/schemas'
import { ItemV6 } from '../items/schema'
@ -43,6 +43,10 @@ export const blockSchemaV6 = z
})
)
)
.openapi({
title: 'Block',
ref: 'block',
})
export type BlockV6 = z.infer<typeof blockSchemaV6>
const blockSchema = blockSchemaV5.or(blockSchemaV6)

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../zod'
import { Credentials as CredentialsFromPrisma } from '@typebot.io/prisma'
export const blockBaseSchema = z.object({

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../zod'
import { blockBaseSchema } from '../shared'
export const startBlockSchema = blockBaseSchema.merge(

View File

@ -0,0 +1,173 @@
import { z } from '../../zod'
import { extendZodWithOpenApi } from 'zod-openapi'
import { listVariableValue } from '../typebot/variable'
import {
googleAnalyticsOptionsSchema,
executableWebhookSchema,
pixelOptionsSchema,
redirectOptionsSchema,
} from '../blocks'
import { nativeMessageSchema } from '../blocks/integrations/openai'
extendZodWithOpenApi(z)
const startPropsToInjectSchema = z.object({
googleAnalyticsId: z.string().optional(),
pixelIds: z.array(z.string()).optional(),
gtmId: z.string().optional(),
customHeadCode: z.string().optional(),
})
export type StartPropsToInject = z.infer<typeof startPropsToInjectSchema>
const scriptToExecuteSchema = z.object({
content: z.string(),
args: z.array(
z.object({
id: z.string(),
value: z
.string()
.or(z.number())
.or(z.boolean())
.or(listVariableValue)
.nullish(),
})
),
})
export type ScriptToExecute = z.infer<typeof scriptToExecuteSchema>
const clientSideActionBaseSchema = z.object({
lastBubbleBlockId: z.string().optional(),
expectsDedicatedReply: z.boolean().optional(),
})
export const clientSideActionSchema = z.discriminatedUnion('type', [
z
.object({
type: z.literal('scriptToExecute'),
scriptToExecute: scriptToExecuteSchema,
})
.merge(clientSideActionBaseSchema)
.openapi({
ref: 'csaScriptToExecute',
title: 'Script to execute',
}),
z
.object({
type: z.literal('redirect'),
redirect: redirectOptionsSchema,
})
.merge(clientSideActionBaseSchema)
.openapi({
ref: 'csaRedirect',
title: 'Redirect',
}),
z
.object({
type: z.literal('chatwoot'),
chatwoot: z.object({ scriptToExecute: scriptToExecuteSchema }),
})
.merge(clientSideActionBaseSchema)
.openapi({
ref: 'csaChatwoot',
title: 'Chatwoot',
}),
z
.object({
type: z.literal('googleAnalytics'),
googleAnalytics: googleAnalyticsOptionsSchema,
})
.merge(clientSideActionBaseSchema)
.openapi({
ref: 'csaGa',
title: 'Google Analytics',
}),
z
.object({
type: z.literal('wait'),
wait: z.object({
secondsToWaitFor: z.number(),
}),
})
.merge(clientSideActionBaseSchema)
.openapi({
ref: 'csaWait',
title: 'Wait',
}),
z
.object({
type: z.literal('setVariable'),
setVariable: z.object({ scriptToExecute: scriptToExecuteSchema }),
})
.merge(clientSideActionBaseSchema)
.openapi({
ref: 'csaSetVariable',
title: 'Set variable',
}),
z
.object({
type: z.literal('streamOpenAiChatCompletion'),
streamOpenAiChatCompletion: z.object({
messages: z.array(
nativeMessageSchema.pick({ content: true, role: true })
),
}),
})
.merge(clientSideActionBaseSchema)
.openapi({
ref: 'csaStreamOpenAiChatCompletion',
title: 'Stream OpenAI',
}),
z
.object({
type: z.literal('webhookToExecute'),
webhookToExecute: executableWebhookSchema,
})
.merge(clientSideActionBaseSchema)
.openapi({
ref: 'csaExecWebhook',
title: 'Execute webhook',
}),
z
.object({
type: z.literal('startPropsToInject'),
startPropsToInject: startPropsToInjectSchema,
})
.merge(clientSideActionBaseSchema)
.openapi({
ref: 'csaInjectStartProps',
title: 'Inject start props',
}),
z
.object({
type: z.literal('pixel'),
pixel: pixelOptionsSchema,
})
.merge(clientSideActionBaseSchema)
.openapi({
ref: 'csaPixel',
title: 'Init Pixel',
}),
z
.object({
type: z.literal('stream'),
stream: z.literal(true),
})
.merge(clientSideActionBaseSchema)
.openapi({
ref: 'csaStream',
title: 'Exec stream',
}),
z
.object({
type: z.literal('codeToExecute'),
codeToExecute: z.object({
args: z.record(z.string(), z.unknown()),
content: z.string(),
}),
})
.merge(clientSideActionBaseSchema)
.openapi({
ref: 'csaCodeToExecute',
title: 'Execute code',
}),
])

View File

@ -1,23 +1,30 @@
import { z } from 'zod'
import { z } from '../../../zod'
import {
chatLogSchema,
chatMessageSchema,
clientSideActionSchema,
runtimeOptionsSchema,
startTypebotSchema,
} from '../schema'
import { typebotV5Schema, typebotV6Schema } from '../../typebot'
import { dynamicThemeSchema } from '../shared'
import { inputBlockSchemas } from '../../blocks'
import { extendZodWithOpenApi } from 'zod-openapi'
import { clientSideActionSchema } from '../clientSideAction'
extendZodWithOpenApi(z)
export const startElementIdSchema = z.union([
z.object({
startGroupId: z.string().describe('Start chat from a specific group.'),
startEventId: z.never().optional(),
startEventId: z.never().optional().openapi({
type: 'string',
}),
}),
z.object({
startEventId: z.string().describe('Start chat from a specific event.'),
startGroupId: z.never().optional(),
startGroupId: z.never().optional().openapi({
type: 'string',
}),
}),
z.object({}),
])
@ -28,7 +35,7 @@ const startParamsSchema = z
typebot: startTypebotSchema
.or(z.string())
.describe(
'Either a Typebot ID or a Typebot object. If you provide a Typebot object, it will be executed in preview mode. ([How can I find my typebot ID?](https://docs.typebot.io/api#how-to-find-my-typebotid)).'
'Either a Typebot ID or a Typebot object. If you provide a Typebot object, it will be executed in preview mode. ([How can I find my typebot ID?](https://docs.typebot.io/api-reference#how-to-find-my-typebotid)).'
),
isPreview: z
.boolean()

View File

@ -1,13 +1,20 @@
import { z } from 'zod'
import { z } from '../../zod'
import {
executableWebhookSchema,
googleAnalyticsOptionsSchema,
buttonsInputSchemas,
dateInputSchema,
emailInputSchema,
fileInputBlockSchemas,
numberInputSchema,
paymentInputRuntimeOptionsSchema,
pixelOptionsSchema,
redirectOptionsSchema,
paymentInputSchema,
phoneNumberInputBlockSchema,
pictureChoiceBlockSchemas,
ratingInputBlockSchema,
textInputSchema,
urlInputSchema,
} from '../blocks'
import { logSchema } from '../result'
import { listVariableValue } from '../typebot'
import { settingsSchema, themeSchema } from '../typebot'
import {
textBubbleContentSchema,
imageBubbleContentSchema,
@ -15,13 +22,12 @@ import {
audioBubbleContentSchema,
embedBubbleContentSchema,
} from '../blocks/bubbles'
import { nativeMessageSchema } from '../blocks/integrations/openai'
import { sessionStateSchema } from './sessionState'
import { dynamicThemeSchema } from './shared'
import { preprocessTypebot } from '../typebot/helpers/preprocessTypebot'
import { typebotV5Schema, typebotV6Schema } from '../typebot/typebot'
import { inputBlockSchemas } from '../blocks/inputs/schema'
import { BubbleBlockType } from '../blocks/bubbles/constants'
import { clientSideActionSchema } from './clientSideAction'
const chatSessionSchema = z.object({
id: z.string(),
@ -31,34 +37,59 @@ const chatSessionSchema = z.object({
})
export type ChatSession = z.infer<typeof chatSessionSchema>
const textMessageSchema = z.object({
type: z.literal(BubbleBlockType.TEXT),
content: textBubbleContentSchema,
})
const textMessageSchema = z
.object({
type: z.literal(BubbleBlockType.TEXT),
content: textBubbleContentSchema,
})
.openapi({
title: 'Text',
ref: 'textMessage',
})
const imageMessageSchema = z.object({
type: z.enum([BubbleBlockType.IMAGE]),
content: imageBubbleContentSchema,
})
const imageMessageSchema = z
.object({
type: z.enum([BubbleBlockType.IMAGE]),
content: imageBubbleContentSchema,
})
.openapi({
title: 'Image',
ref: 'imageMessage',
})
const videoMessageSchema = z.object({
type: z.enum([BubbleBlockType.VIDEO]),
content: videoBubbleContentSchema,
})
const videoMessageSchema = z
.object({
type: z.enum([BubbleBlockType.VIDEO]),
content: videoBubbleContentSchema,
})
.openapi({
title: 'Video',
ref: 'videoMessage',
})
const audioMessageSchema = z.object({
type: z.enum([BubbleBlockType.AUDIO]),
content: audioBubbleContentSchema,
})
const audioMessageSchema = z
.object({
type: z.enum([BubbleBlockType.AUDIO]),
content: audioBubbleContentSchema,
})
.openapi({
title: 'Audio',
ref: 'audioMessage',
})
const embedMessageSchema = z.object({
type: z.enum([BubbleBlockType.EMBED]),
content: embedBubbleContentSchema
.omit({
height: true,
})
.merge(z.object({ height: z.number().optional() })),
})
const embedMessageSchema = z
.object({
type: z.enum([BubbleBlockType.EMBED]),
content: embedBubbleContentSchema
.omit({
height: true,
})
.merge(z.object({ height: z.number().optional() })),
})
.openapi({
title: 'Embed',
ref: 'embedMessage',
})
const displayEmbedBubbleSchema = z.object({
waitForEventFunction: z
@ -72,10 +103,15 @@ const displayEmbedBubbleSchema = z.object({
content: z.string(),
}),
})
const customEmbedSchema = z.object({
type: z.literal('custom-embed'),
content: displayEmbedBubbleSchema,
})
const customEmbedSchema = z
.object({
type: z.literal('custom-embed'),
content: displayEmbedBubbleSchema,
})
.openapi({
title: 'Custom embed',
ref: 'customEmbedMessage',
})
export type CustomEmbedBubble = z.infer<typeof customEmbedSchema>
export const chatMessageSchema = z
@ -92,22 +128,6 @@ export const chatMessageSchema = z
)
export type ChatMessage = z.infer<typeof chatMessageSchema>
const scriptToExecuteSchema = z.object({
content: z.string(),
args: z.array(
z.object({
id: z.string(),
value: z
.string()
.or(z.number())
.or(z.boolean())
.or(listVariableValue)
.nullish(),
})
),
})
export type ScriptToExecute = z.infer<typeof scriptToExecuteSchema>
const startTypebotPick = {
version: true,
id: true,
@ -121,8 +141,14 @@ const startTypebotPick = {
export const startTypebotSchema = z.preprocess(
preprocessTypebot,
z.discriminatedUnion('version', [
typebotV5Schema._def.schema.pick(startTypebotPick),
typebotV6Schema.pick(startTypebotPick),
typebotV5Schema._def.schema.pick(startTypebotPick).openapi({
title: 'Typebot V5',
ref: 'typebotV5',
}),
typebotV6Schema.pick(startTypebotPick).openapi({
title: 'Typebot V6',
ref: 'typebotV6',
}),
])
)
export type StartTypebot = z.infer<typeof startTypebotSchema>
@ -136,9 +162,24 @@ export const chatLogSchema = logSchema
export type ChatLog = z.infer<typeof chatLogSchema>
export const startChatInputSchema = z.object({
publicId: z.string(),
isStreamEnabled: z.boolean().optional(),
message: z.string().optional(),
publicId: z
.string()
.describe(
"[Where to find my bot's public ID?](../how-to#how-to-find-my-publicid)"
),
message: z
.string()
.optional()
.describe(
"Only provide it if your flow starts with an input block and you'd like to directly provide an answer to it."
),
isStreamEnabled: z
.boolean()
.optional()
.default(false)
.describe(
'If enabled, you will be required to stream OpenAI completions on a client and send the generated response back to the API.'
),
resultId: z
.string()
.optional()
@ -146,6 +187,7 @@ export const startChatInputSchema = z.object({
isOnlyRegistering: z
.boolean()
.optional()
.default(false)
.describe(
'If set to `true`, it will only register the session and not start the bot. This is used for 3rd party chat platforms as it can require a session to be registered before sending the first message.'
),
@ -153,8 +195,14 @@ export const startChatInputSchema = z.object({
.record(z.unknown())
.optional()
.describe(
'[More info about prefilled variables.](https://docs.typebot.io/editor/variables#prefilled-variables)'
),
'[More info about prefilled variables.](../../editor/variables#prefilled-variables)'
)
.openapi({
example: {
'First name': 'John',
Email: 'john@gmail.com',
},
}),
})
export type StartChatInput = z.infer<typeof startChatInputSchema>
@ -171,7 +219,11 @@ export const startFromSchema = z.discriminatedUnion('type', [
export type StartFrom = z.infer<typeof startFromSchema>
export const startPreviewChatInputSchema = z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
isStreamEnabled: z.boolean().optional(),
message: z.string().optional(),
isOnlyRegistering: z
@ -192,90 +244,6 @@ export type StartPreviewChatInput = z.infer<typeof startPreviewChatInputSchema>
export const runtimeOptionsSchema = paymentInputRuntimeOptionsSchema.optional()
export type RuntimeOptions = z.infer<typeof runtimeOptionsSchema>
const startPropsToInjectSchema = z.object({
googleAnalyticsId: z.string().optional(),
pixelIds: z.array(z.string()).optional(),
gtmId: z.string().optional(),
customHeadCode: z.string().optional(),
})
export type StartPropsToInject = z.infer<typeof startPropsToInjectSchema>
export const clientSideActionSchema = z
.object({
lastBubbleBlockId: z.string().optional(),
expectsDedicatedReply: z.boolean().optional(),
})
.and(
z
.object({
scriptToExecute: scriptToExecuteSchema,
})
.or(
z.object({
redirect: redirectOptionsSchema,
})
)
.or(
z.object({
chatwoot: z.object({ scriptToExecute: scriptToExecuteSchema }),
})
)
.or(
z.object({
googleAnalytics: googleAnalyticsOptionsSchema,
})
)
.or(
z.object({
wait: z.object({
secondsToWaitFor: z.number(),
}),
})
)
.or(
z.object({
setVariable: z.object({ scriptToExecute: scriptToExecuteSchema }),
})
)
.or(
z.object({
streamOpenAiChatCompletion: z.object({
messages: z.array(
nativeMessageSchema.pick({ content: true, role: true })
),
}),
})
)
.or(
z.object({
webhookToExecute: executableWebhookSchema,
})
)
.or(
z.object({
startPropsToInject: startPropsToInjectSchema,
})
)
.or(
z.object({
pixel: pixelOptionsSchema,
})
)
.or(
z.object({
stream: z.literal(true),
})
)
.or(
z.object({
codeToExecute: z.object({
args: z.record(z.string(), z.unknown()),
content: z.string(),
}),
})
)
)
const typebotInChatReplyPick = {
version: true,
id: true,
@ -298,41 +266,59 @@ const chatResponseBaseSchema = z.object({
.string()
.optional()
.describe(
'The sent message is validated and formatted on the backend. This is set only if the message differs from the formatted version.'
'The sent message is validated and formatted on the backend. For example, if for a date input you replied something like `tomorrow`, the backend will convert it to a date string. This field returns the formatted message.'
),
messages: z.array(chatMessageSchema),
input: z
.union([
z.discriminatedUnion('type', [...inputBlockSchemas.v5]),
z.discriminatedUnion('type', [...inputBlockSchemas.v6]),
z.discriminatedUnion('type', [
textInputSchema,
buttonsInputSchemas.v6,
emailInputSchema,
numberInputSchema,
urlInputSchema,
phoneNumberInputBlockSchema,
dateInputSchema,
paymentInputSchema,
ratingInputBlockSchema,
fileInputBlockSchemas.v6,
pictureChoiceBlockSchemas.v6,
]),
z.discriminatedUnion('type', [
buttonsInputSchemas.v5,
fileInputBlockSchemas.v5,
pictureChoiceBlockSchemas.v5,
]),
])
.and(
z.object({
prefilledValue: z.string().optional(),
runtimeOptions: runtimeOptionsSchema.optional(),
})
)
.optional(),
clientSideActions: z.array(clientSideActionSchema).optional(),
logs: z.array(chatLogSchema).optional(),
dynamicTheme: dynamicThemeSchema.optional(),
clientSideActions: z
.array(clientSideActionSchema)
.optional()
.describe('Actions to execute on the client side'),
logs: z
.array(chatLogSchema)
.optional()
.describe('Logs that were saved during the last execution'),
dynamicTheme: dynamicThemeSchema
.optional()
.describe(
'If the typebot contains dynamic avatars, dynamicTheme returns the new avatar URLs whenever their variables are updated.'
),
})
export const startChatResponseSchema = chatResponseBaseSchema.extend({
sessionId: z.string().optional(),
typebot: z.object({
id: z.string(),
theme: z.union([
typebotV5Schema._def.schema.shape.theme,
typebotV6Schema.shape.theme,
]),
settings: z.union([
typebotV5Schema._def.schema.shape.settings,
typebotV6Schema.shape.settings,
]),
}),
resultId: z.string().optional(),
})
export const startChatResponseSchema = z
.object({
sessionId: z
.string()
.describe('To save and use for /continueChat requests.'),
resultId: z.string(),
typebot: z.object({
id: z.string(),
theme: themeSchema,
settings: settingsSchema,
}),
})
.merge(chatResponseBaseSchema)
export type StartChatResponse = z.infer<typeof startChatResponseSchema>
export const startPreviewChatResponseSchema = startChatResponseSchema.omit({

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../zod'
import { answerSchema } from '../answer'
import { resultSchema } from '../result'
import { typebotInSessionStateSchema, dynamicThemeSchema } from './shared'
@ -29,7 +29,9 @@ const resultInSessionStateSchema = resultSchema
)
const sessionStateSchemaV1 = z.object({
version: z.undefined(),
version: z.undefined().openapi({
type: 'string',
}),
typebot: typebotInSessionStateSchema,
dynamicTheme: dynamicThemeSchema.optional(),
linkedTypebots: z.object({

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../zod'
import { publicTypebotSchemaV5, publicTypebotSchemaV6 } from '../publicTypebot'
import { preprocessTypebot } from '../typebot/helpers/preprocessTypebot'

View File

@ -1,5 +1,5 @@
import { CollaborationType, CollaboratorsOnTypebots } from '@typebot.io/prisma'
import { z } from 'zod'
import { z } from '../zod'
export const collaboratorSchema = z.object({
type: z.nativeEnum(CollaborationType),

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../zod'
import { stripeCredentialsSchema } from './blocks/inputs/payment/schema'
import { googleSheetsCredentialsSchema } from './blocks/integrations/googleSheets/schema'
import { smtpCredentialsSchema } from './blocks/integrations/sendEmail'

View File

@ -1,5 +1,8 @@
import { CustomDomain as CustomDomainInDb } from '@typebot.io/prisma'
import { z } from 'zod'
import { z } from '../zod'
import { extendZodWithOpenApi } from 'zod-openapi'
extendZodWithOpenApi(z)
export const domainVerificationStatusSchema = z.enum([
'Valid Configuration',
@ -41,6 +44,9 @@ export const customDomainSchema = z.object({
name: z
.string()
.transform((name) => name.toLowerCase())
.openapi({
effectType: 'input',
})
.refine((name) => domainNameRegex.test(name)),
workspaceId: z.string(),
createdAt: z.date(),

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../zod'
export const eventBaseSchema = z.object({
id: z.string(),

View File

@ -1,7 +1,12 @@
import { z } from 'zod'
import { z } from '../../../zod'
import { eventBaseSchema } from '../shared'
import { EventType } from '../constants'
export const startEventSchema = eventBaseSchema.extend({
type: z.literal(EventType.START),
})
export const startEventSchema = eventBaseSchema
.extend({
type: z.literal(EventType.START),
})
.openapi({
description: 'Event',
ref: 'event',
})

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../zod'
import {
buttonItemSchemas,
conditionItemSchemas,

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../zod'
const itemBaseV5Schema = z.object({
id: z.string(),

View File

@ -6,7 +6,7 @@ import {
groupV5Schema,
groupV6Schema,
} from './typebot'
import { z } from 'zod'
import { z } from '../zod'
import { preprocessTypebot } from './typebot/helpers/preprocessTypebot'
import { edgeSchema } from './typebot/edge'
import { startEventSchema } from './events'
@ -20,7 +20,9 @@ export const publicTypebotSchemaV5 = z.preprocess(
updatedAt: z.date(),
typebotId: z.string(),
groups: z.array(groupV5Schema),
events: z.null(),
events: z.null().openapi({
type: 'array',
}),
edges: z.array(edgeSchema),
variables: z.array(variableSchema),
theme: themeSchema,
@ -39,8 +41,14 @@ export type PublicTypebotV6 = z.infer<typeof publicTypebotSchemaV6>
export const publicTypebotSchema = z.preprocess(
preprocessTypebot,
z.discriminatedUnion('version', [
publicTypebotSchemaV5._def.schema,
publicTypebotSchemaV6,
publicTypebotSchemaV6.openapi({
ref: 'publicTypebotV6',
title: 'Public Typebot V6',
}),
publicTypebotSchemaV5._def.schema.openapi({
ref: 'publicTypebotV5',
title: 'Public Typebot V5',
}),
])
)
export type PublicTypebot = z.infer<typeof publicTypebotSchema>

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../zod'
import { answerInputSchema, answerSchema } from './answer'
import { variableWithValueSchema } from './typebot/variable'
import {

View File

@ -1,5 +1,5 @@
import { Plan } from '@typebot.io/prisma'
import { z } from 'zod'
import { z } from '../zod'
const userEvent = z.object({
userId: z.string(),

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../zod'
const blockSourceSchema = z.object({
blockId: z.string(),

View File

@ -1,5 +1,5 @@
import { blockSchemaV5, blockSchemaV6 } from '../blocks'
import { z } from 'zod'
import { z } from '../../zod'
export const groupV5Schema = z.object({
id: z.string(),
@ -12,9 +12,14 @@ export const groupV5Schema = z.object({
})
type GroupV5 = z.infer<typeof groupV5Schema>
export const groupV6Schema = groupV5Schema.extend({
blocks: z.array(blockSchemaV6),
})
export const groupV6Schema = groupV5Schema
.extend({
blocks: z.array(blockSchemaV6),
})
.openapi({
title: 'Group V6',
ref: 'groupV6',
})
export type GroupV6 = z.infer<typeof groupV6Schema>
export const parseGroups = <T extends string | null>(

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../../zod'
import { rememberUserStorages } from './constants'
import { whatsAppSettingsSchema } from '../../whatsapp'
@ -31,16 +31,21 @@ const metadataSchema = z.object({
googleTagManagerId: z.string().optional(),
})
export const settingsSchema = z.object({
general: generalSettings.optional(),
typingEmulation: typingEmulation.optional(),
metadata: metadataSchema.optional(),
whatsApp: whatsAppSettingsSchema.optional(),
publicShare: z
.object({
isEnabled: z.boolean().optional(),
})
.optional(),
})
export const settingsSchema = z
.object({
general: generalSettings.optional(),
typingEmulation: typingEmulation.optional(),
metadata: metadataSchema.optional(),
whatsApp: whatsAppSettingsSchema.optional(),
publicShare: z
.object({
isEnabled: z.boolean().optional(),
})
.optional(),
})
.openapi({
title: 'Settings',
ref: 'settings',
})
export type Settings = z.infer<typeof settingsSchema>

View File

@ -1,5 +1,5 @@
import { ThemeTemplate as ThemeTemplatePrisma } from '@typebot.io/prisma'
import { z } from 'zod'
import { z } from '../../../zod'
import { BackgroundType } from './constants'
const avatarPropsSchema = z.object({
@ -38,11 +38,16 @@ const generalThemeSchema = z.object({
background: backgroundSchema.optional(),
})
export const themeSchema = z.object({
general: generalThemeSchema.optional(),
chat: chatThemeSchema.optional(),
customCss: z.string().optional(),
})
export const themeSchema = z
.object({
general: generalThemeSchema.optional(),
chat: chatThemeSchema.optional(),
customCss: z.string().optional(),
})
.openapi({
title: 'Theme',
ref: 'theme',
})
export const themeTemplateSchema = z.object({
id: z.string(),

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../zod'
import { settingsSchema } from './settings'
import { themeSchema } from './theme'
import { variableSchema } from './variable'
@ -31,7 +31,9 @@ export const typebotV5Schema = z.preprocess(
version: z.enum(['3', '4', '5']),
id: z.string(),
name: z.string(),
events: z.preprocess((val) => (val === undefined ? null : val), z.null()),
events: z
.preprocess((val) => (val === undefined ? null : val), z.null())
.openapi({ type: 'array' }),
groups: z.array(groupV5Schema),
edges: z.array(edgeSchema),
variables: z.array(variableSchema),
@ -58,20 +60,29 @@ export const typebotV5Schema = z.preprocess(
riskLevel: z.number().nullable(),
}) satisfies z.ZodType<TypebotPrisma, z.ZodTypeDef, unknown>
)
export type TypebotV5 = z.infer<typeof typebotV5Schema>
export const typebotV6Schema = typebotV5Schema._def.schema.extend({
version: z.literal('6'),
groups: z.array(groupV6Schema),
events: z.tuple([startEventSchema]),
})
export const typebotV6Schema = typebotV5Schema._def.schema
.extend({
version: z.literal('6'),
groups: z.array(groupV6Schema),
events: z.tuple([startEventSchema]),
})
.openapi({
title: 'Typebot V6',
ref: 'typebotV6',
})
export type TypebotV6 = z.infer<typeof typebotV6Schema>
export const typebotSchema = z.preprocess(
preprocessTypebot,
z.discriminatedUnion('version', [
typebotV5Schema._def.schema,
typebotV6Schema,
typebotV5Schema._def.schema.openapi({
title: 'Typebot V5',
ref: 'typebotV5',
}),
])
)
export type Typebot = z.infer<typeof typebotSchema>

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../../zod'
export const listVariableValue = z.array(z.string().nullable())

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../zod'
export type IdMap<T> = { [id: string]: T }

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../zod'
import { credentialsBaseSchema } from './blocks/shared'
import {
ComparisonOperators,

View File

@ -1,4 +1,4 @@
import { z } from 'zod'
import { z } from '../zod'
import {
Workspace as WorkspacePrisma,
Plan,