♻️ Re-organize workspace folders
This commit is contained in:
36
packages/schemas/features/answer.ts
Normal file
36
packages/schemas/features/answer.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { z } from 'zod'
|
||||
import { Answer as AnswerPrisma, Prisma } from '@typebot.io/prisma'
|
||||
|
||||
export const answerSchema = z.object({
|
||||
createdAt: z.date(),
|
||||
resultId: z.string(),
|
||||
blockId: z.string(),
|
||||
groupId: z.string(),
|
||||
variableId: z.string().nullable(),
|
||||
content: z.string(),
|
||||
storageUsed: z.number().nullable(),
|
||||
}) satisfies z.ZodType<AnswerPrisma>
|
||||
|
||||
export const answerInputSchema = answerSchema
|
||||
.omit({
|
||||
createdAt: true,
|
||||
resultId: true,
|
||||
variableId: true,
|
||||
storageUsed: true,
|
||||
})
|
||||
.merge(
|
||||
z.object({
|
||||
variableId: z.string().nullish(),
|
||||
storageUsed: z.number().nullish(),
|
||||
})
|
||||
) satisfies z.ZodType<Prisma.AnswerUncheckedUpdateInput>
|
||||
|
||||
export type Stats = {
|
||||
totalViews: number
|
||||
totalStarts: number
|
||||
totalCompleted: number
|
||||
}
|
||||
|
||||
export type Answer = z.infer<typeof answerSchema>
|
||||
|
||||
export type AnswerInput = z.infer<typeof answerInputSchema>
|
11
packages/schemas/features/billing/invoice.ts
Normal file
11
packages/schemas/features/billing/invoice.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { z } from 'zod'
|
||||
|
||||
export const invoiceSchema = z.object({
|
||||
id: z.string(),
|
||||
url: z.string(),
|
||||
amount: z.number(),
|
||||
currency: z.string(),
|
||||
date: z.number().nullable(),
|
||||
})
|
||||
|
||||
export type Invoice = z.infer<typeof invoiceSchema>
|
9
packages/schemas/features/billing/subscription.ts
Normal file
9
packages/schemas/features/billing/subscription.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { z } from 'zod'
|
||||
|
||||
export const subscriptionSchema = z.object({
|
||||
additionalChatsIndex: z.number(),
|
||||
additionalStorageIndex: z.number(),
|
||||
currency: z.enum(['eur', 'usd']),
|
||||
})
|
||||
|
||||
export type Subscription = z.infer<typeof subscriptionSchema>
|
20
packages/schemas/features/blocks/baseSchemas.ts
Normal file
20
packages/schemas/features/blocks/baseSchemas.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { z } from 'zod'
|
||||
import { Credentials as CredentialsFromPrisma } from '@typebot.io/prisma'
|
||||
|
||||
export const blockBaseSchema = z.object({
|
||||
id: z.string(),
|
||||
groupId: z.string(),
|
||||
outgoingEdgeId: z.string().optional(),
|
||||
})
|
||||
|
||||
export const optionBaseSchema = z.object({
|
||||
variableId: z.string().optional(),
|
||||
})
|
||||
|
||||
export const credentialsBaseSchema = z.object({
|
||||
id: z.string(),
|
||||
createdAt: z.date(),
|
||||
workspaceId: z.string(),
|
||||
name: z.string(),
|
||||
iv: z.string(),
|
||||
}) satisfies z.ZodType<Omit<CredentialsFromPrisma, 'data' | 'type'>>
|
19
packages/schemas/features/blocks/bubbles/audio.ts
Normal file
19
packages/schemas/features/blocks/bubbles/audio.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { BubbleBlockType } from './enums'
|
||||
|
||||
export const audioBubbleContentSchema = z.object({
|
||||
url: z.string().optional(),
|
||||
})
|
||||
|
||||
export const audioBubbleBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([BubbleBlockType.AUDIO]),
|
||||
content: audioBubbleContentSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultAudioBubbleContent = {}
|
||||
|
||||
export type AudioBubbleBlock = z.infer<typeof audioBubbleBlockSchema>
|
||||
export type AudioBubbleContent = z.infer<typeof audioBubbleContentSchema>
|
21
packages/schemas/features/blocks/bubbles/embed.ts
Normal file
21
packages/schemas/features/blocks/bubbles/embed.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { z } from 'zod'
|
||||
import { variableStringSchema } from '../../utils'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { BubbleBlockType } from './enums'
|
||||
|
||||
export const embedBubbleContentSchema = z.object({
|
||||
url: z.string().optional(),
|
||||
height: z.number().or(variableStringSchema),
|
||||
})
|
||||
|
||||
export const embedBubbleBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([BubbleBlockType.EMBED]),
|
||||
content: embedBubbleContentSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultEmbedBubbleContent: EmbedBubbleContent = { height: 400 }
|
||||
|
||||
export type EmbedBubbleBlock = z.infer<typeof embedBubbleBlockSchema>
|
||||
export type EmbedBubbleContent = z.infer<typeof embedBubbleContentSchema>
|
7
packages/schemas/features/blocks/bubbles/enums.ts
Normal file
7
packages/schemas/features/blocks/bubbles/enums.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export enum BubbleBlockType {
|
||||
TEXT = 'text',
|
||||
IMAGE = 'image',
|
||||
VIDEO = 'video',
|
||||
EMBED = 'embed',
|
||||
AUDIO = 'audio',
|
||||
}
|
19
packages/schemas/features/blocks/bubbles/image.ts
Normal file
19
packages/schemas/features/blocks/bubbles/image.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { BubbleBlockType } from './enums'
|
||||
|
||||
export const imageBubbleContentSchema = z.object({
|
||||
url: z.string().optional(),
|
||||
})
|
||||
|
||||
export const imageBubbleBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([BubbleBlockType.IMAGE]),
|
||||
content: imageBubbleContentSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultImageBubbleContent: ImageBubbleContent = {}
|
||||
|
||||
export type ImageBubbleBlock = z.infer<typeof imageBubbleBlockSchema>
|
||||
export type ImageBubbleContent = z.infer<typeof imageBubbleContentSchema>
|
6
packages/schemas/features/blocks/bubbles/index.ts
Normal file
6
packages/schemas/features/blocks/bubbles/index.ts
Normal file
@ -0,0 +1,6 @@
|
||||
export * from './audio'
|
||||
export * from './embed'
|
||||
export * from './image'
|
||||
export * from './text'
|
||||
export * from './video'
|
||||
export * from './enums'
|
26
packages/schemas/features/blocks/bubbles/text.ts
Normal file
26
packages/schemas/features/blocks/bubbles/text.ts
Normal file
@ -0,0 +1,26 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { BubbleBlockType } from './enums'
|
||||
|
||||
export const defaultTextBubbleContent: TextBubbleContent = {
|
||||
html: '',
|
||||
richText: [],
|
||||
plainText: '',
|
||||
}
|
||||
|
||||
export const textBubbleContentSchema = z.object({
|
||||
html: z.string(),
|
||||
richText: z.array(z.any()),
|
||||
plainText: z.string(),
|
||||
})
|
||||
|
||||
export type TextBubbleContent = z.infer<typeof textBubbleContentSchema>
|
||||
|
||||
export const textBubbleBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([BubbleBlockType.TEXT]),
|
||||
content: textBubbleContentSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export type TextBubbleBlock = z.infer<typeof textBubbleBlockSchema>
|
5
packages/schemas/features/blocks/bubbles/video/enums.ts
Normal file
5
packages/schemas/features/blocks/bubbles/video/enums.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export enum VideoBubbleContentType {
|
||||
URL = 'url',
|
||||
YOUTUBE = 'youtube',
|
||||
VIMEO = 'vimeo',
|
||||
}
|
2
packages/schemas/features/blocks/bubbles/video/index.ts
Normal file
2
packages/schemas/features/blocks/bubbles/video/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './enums'
|
||||
export * from './schemas'
|
22
packages/schemas/features/blocks/bubbles/video/schemas.ts
Normal file
22
packages/schemas/features/blocks/bubbles/video/schemas.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../../baseSchemas'
|
||||
import { BubbleBlockType } from '../enums'
|
||||
import { VideoBubbleContentType } from './enums'
|
||||
|
||||
export const videoBubbleContentSchema = z.object({
|
||||
url: z.string().optional(),
|
||||
id: z.string().optional(),
|
||||
type: z.nativeEnum(VideoBubbleContentType).optional(),
|
||||
})
|
||||
|
||||
export const videoBubbleBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([BubbleBlockType.VIDEO]),
|
||||
content: videoBubbleContentSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultVideoBubbleContent: VideoBubbleContent = {}
|
||||
|
||||
export type VideoBubbleBlock = z.infer<typeof videoBubbleBlockSchema>
|
||||
export type VideoBubbleContent = z.infer<typeof videoBubbleContentSchema>
|
7
packages/schemas/features/blocks/index.ts
Normal file
7
packages/schemas/features/blocks/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export * from './baseSchemas'
|
||||
export * from './bubbles'
|
||||
export * from './inputs'
|
||||
export * from './integrations'
|
||||
export * from './logic'
|
||||
export * from './start'
|
||||
export * from './schemas'
|
38
packages/schemas/features/blocks/inputs/choice.ts
Normal file
38
packages/schemas/features/blocks/inputs/choice.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { z } from 'zod'
|
||||
import { ItemType } from '../../items/enums'
|
||||
import { itemBaseSchema } from '../../items/baseSchemas'
|
||||
import { optionBaseSchema, blockBaseSchema } from '../baseSchemas'
|
||||
import { defaultButtonLabel } from './constants'
|
||||
import { InputBlockType } from './enums'
|
||||
|
||||
export const choiceInputOptionsSchema = optionBaseSchema.merge(
|
||||
z.object({
|
||||
isMultipleChoice: z.boolean(),
|
||||
buttonLabel: z.string(),
|
||||
dynamicVariableId: z.string().optional(),
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultChoiceInputOptions: ChoiceInputOptions = {
|
||||
buttonLabel: defaultButtonLabel,
|
||||
isMultipleChoice: false,
|
||||
}
|
||||
|
||||
export const buttonItemSchema = itemBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.literal(ItemType.BUTTON),
|
||||
content: z.string().optional(),
|
||||
})
|
||||
)
|
||||
|
||||
export const choiceInputSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([InputBlockType.CHOICE]),
|
||||
items: z.array(buttonItemSchema),
|
||||
options: choiceInputOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export type ButtonItem = z.infer<typeof buttonItemSchema>
|
||||
export type ChoiceInputBlock = z.infer<typeof choiceInputSchema>
|
||||
export type ChoiceInputOptions = z.infer<typeof choiceInputOptionsSchema>
|
1
packages/schemas/features/blocks/inputs/constants.ts
Normal file
1
packages/schemas/features/blocks/inputs/constants.ts
Normal file
@ -0,0 +1 @@
|
||||
export const defaultButtonLabel = 'Send'
|
32
packages/schemas/features/blocks/inputs/date.ts
Normal file
32
packages/schemas/features/blocks/inputs/date.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { z } from 'zod'
|
||||
import { optionBaseSchema, blockBaseSchema } from '../baseSchemas'
|
||||
import { defaultButtonLabel } from './constants'
|
||||
import { InputBlockType } from './enums'
|
||||
|
||||
export const dateInputOptionsSchema = optionBaseSchema.merge(
|
||||
z.object({
|
||||
labels: z.object({
|
||||
button: z.string(),
|
||||
from: z.string(),
|
||||
to: z.string(),
|
||||
}),
|
||||
hasTime: z.boolean(),
|
||||
isRange: z.boolean(),
|
||||
})
|
||||
)
|
||||
|
||||
export const dateInputSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([InputBlockType.DATE]),
|
||||
options: dateInputOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultDateInputOptions: DateInputOptions = {
|
||||
hasTime: false,
|
||||
isRange: false,
|
||||
labels: { button: defaultButtonLabel, from: 'From:', to: 'To:' },
|
||||
}
|
||||
|
||||
export type DateInputBlock = z.infer<typeof dateInputSchema>
|
||||
export type DateInputOptions = z.infer<typeof dateInputOptionsSchema>
|
32
packages/schemas/features/blocks/inputs/email.ts
Normal file
32
packages/schemas/features/blocks/inputs/email.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { z } from 'zod'
|
||||
import { optionBaseSchema, blockBaseSchema } from '../baseSchemas'
|
||||
import { defaultButtonLabel } from './constants'
|
||||
import { InputBlockType } from './enums'
|
||||
import { textInputOptionsBaseSchema } from './text'
|
||||
|
||||
export const emailInputOptionsSchema = optionBaseSchema
|
||||
.merge(textInputOptionsBaseSchema)
|
||||
.merge(
|
||||
z.object({
|
||||
retryMessageContent: z.string(),
|
||||
})
|
||||
)
|
||||
|
||||
export const emailInputSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([InputBlockType.EMAIL]),
|
||||
options: emailInputOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultEmailInputOptions: EmailInputOptions = {
|
||||
labels: {
|
||||
button: defaultButtonLabel,
|
||||
placeholder: 'Type your email...',
|
||||
},
|
||||
retryMessageContent:
|
||||
"This email doesn't seem to be valid. Can you type it again?",
|
||||
}
|
||||
|
||||
export type EmailInputBlock = z.infer<typeof emailInputSchema>
|
||||
export type EmailInputOptions = z.infer<typeof emailInputOptionsSchema>
|
12
packages/schemas/features/blocks/inputs/enums.ts
Normal file
12
packages/schemas/features/blocks/inputs/enums.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export enum InputBlockType {
|
||||
TEXT = 'text input',
|
||||
NUMBER = 'number input',
|
||||
EMAIL = 'email input',
|
||||
URL = 'url input',
|
||||
DATE = 'date input',
|
||||
PHONE = 'phone number input',
|
||||
CHOICE = 'choice input',
|
||||
PAYMENT = 'payment input',
|
||||
RATING = 'rating input',
|
||||
FILE = 'file input',
|
||||
}
|
41
packages/schemas/features/blocks/inputs/file.ts
Normal file
41
packages/schemas/features/blocks/inputs/file.ts
Normal file
@ -0,0 +1,41 @@
|
||||
import { z } from 'zod'
|
||||
import { optionBaseSchema, blockBaseSchema } from '../baseSchemas'
|
||||
import { InputBlockType } from './enums'
|
||||
|
||||
export const fileInputOptionsSchema = optionBaseSchema.merge(
|
||||
z.object({
|
||||
isRequired: z.boolean().optional(),
|
||||
isMultipleAllowed: z.boolean(),
|
||||
labels: z.object({
|
||||
placeholder: z.string(),
|
||||
button: z.string(),
|
||||
clear: z.string().optional(),
|
||||
skip: z.string().optional(),
|
||||
}),
|
||||
sizeLimit: z.number().optional(),
|
||||
})
|
||||
)
|
||||
|
||||
export const fileInputStepSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.literal(InputBlockType.FILE),
|
||||
options: fileInputOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultFileInputOptions = {
|
||||
isRequired: true,
|
||||
isMultipleAllowed: false,
|
||||
labels: {
|
||||
placeholder: `<strong>
|
||||
Click to upload
|
||||
</strong> or drag and drop<br>
|
||||
(size limit: 10MB)`,
|
||||
button: 'Upload',
|
||||
clear: 'Clear',
|
||||
skip: 'Skip',
|
||||
},
|
||||
} satisfies FileInputOptions
|
||||
|
||||
export type FileInputBlock = z.infer<typeof fileInputStepSchema>
|
||||
export type FileInputOptions = z.infer<typeof fileInputOptionsSchema>
|
12
packages/schemas/features/blocks/inputs/index.ts
Normal file
12
packages/schemas/features/blocks/inputs/index.ts
Normal file
@ -0,0 +1,12 @@
|
||||
export * from './choice'
|
||||
export * from './constants'
|
||||
export * from './date'
|
||||
export * from './email'
|
||||
export * from './enums'
|
||||
export * from './file'
|
||||
export * from './number'
|
||||
export * from './payment'
|
||||
export * from './phone'
|
||||
export * from './rating'
|
||||
export * from './text'
|
||||
export * from './url'
|
29
packages/schemas/features/blocks/inputs/number.ts
Normal file
29
packages/schemas/features/blocks/inputs/number.ts
Normal file
@ -0,0 +1,29 @@
|
||||
import { z } from 'zod'
|
||||
import { optionBaseSchema, blockBaseSchema } from '../baseSchemas'
|
||||
import { defaultButtonLabel } from './constants'
|
||||
import { InputBlockType } from './enums'
|
||||
import { textInputOptionsBaseSchema } from './text'
|
||||
|
||||
export const numberInputOptionsSchema = optionBaseSchema
|
||||
.merge(textInputOptionsBaseSchema)
|
||||
.merge(
|
||||
z.object({
|
||||
min: z.number().optional(),
|
||||
max: z.number().optional(),
|
||||
step: z.number().optional(),
|
||||
})
|
||||
)
|
||||
|
||||
export const numberInputSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([InputBlockType.NUMBER]),
|
||||
options: numberInputOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultNumberInputOptions: NumberInputOptions = {
|
||||
labels: { button: defaultButtonLabel, placeholder: 'Type a number...' },
|
||||
}
|
||||
|
||||
export type NumberInputBlock = z.infer<typeof numberInputSchema>
|
||||
export type NumberInputOptions = z.infer<typeof numberInputOptionsSchema>
|
3
packages/schemas/features/blocks/inputs/payment/enums.ts
Normal file
3
packages/schemas/features/blocks/inputs/payment/enums.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export enum PaymentProvider {
|
||||
STRIPE = 'Stripe',
|
||||
}
|
2
packages/schemas/features/blocks/inputs/payment/index.ts
Normal file
2
packages/schemas/features/blocks/inputs/payment/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './enums'
|
||||
export * from './schemas'
|
77
packages/schemas/features/blocks/inputs/payment/schemas.ts
Normal file
77
packages/schemas/features/blocks/inputs/payment/schemas.ts
Normal file
@ -0,0 +1,77 @@
|
||||
import { z } from 'zod'
|
||||
import {
|
||||
optionBaseSchema,
|
||||
blockBaseSchema,
|
||||
credentialsBaseSchema,
|
||||
} from '../../baseSchemas'
|
||||
import { InputBlockType } from '../enums'
|
||||
import { PaymentProvider } from './enums'
|
||||
|
||||
export type CreditCardDetails = {
|
||||
number: string
|
||||
exp_month: string
|
||||
exp_year: string
|
||||
cvc: string
|
||||
}
|
||||
|
||||
export const paymentInputOptionsSchema = optionBaseSchema.merge(
|
||||
z.object({
|
||||
provider: z.nativeEnum(PaymentProvider),
|
||||
labels: z.object({
|
||||
button: z.string(),
|
||||
success: z.string().optional(),
|
||||
}),
|
||||
additionalInformation: z
|
||||
.object({
|
||||
name: z.string().optional(),
|
||||
email: z.string().optional(),
|
||||
phoneNumber: z.string().optional(),
|
||||
})
|
||||
.optional(),
|
||||
credentialsId: z.string().optional(),
|
||||
currency: z.string(),
|
||||
amount: z.string().optional(),
|
||||
})
|
||||
)
|
||||
|
||||
export const paymentInputRuntimeOptionsSchema = z.object({
|
||||
paymentIntentSecret: z.string(),
|
||||
amountLabel: z.string(),
|
||||
publicKey: z.string(),
|
||||
})
|
||||
|
||||
export const paymentInputSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([InputBlockType.PAYMENT]),
|
||||
options: paymentInputOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const stripeCredentialsSchema = z
|
||||
.object({
|
||||
type: z.literal('stripe'),
|
||||
data: z.object({
|
||||
live: z.object({
|
||||
secretKey: z.string(),
|
||||
publicKey: z.string(),
|
||||
}),
|
||||
test: z.object({
|
||||
secretKey: z.string().optional(),
|
||||
publicKey: z.string().optional(),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.merge(credentialsBaseSchema)
|
||||
|
||||
export const defaultPaymentInputOptions: PaymentInputOptions = {
|
||||
provider: PaymentProvider.STRIPE,
|
||||
labels: { button: 'Pay', success: 'Success' },
|
||||
currency: 'USD',
|
||||
}
|
||||
|
||||
export type PaymentInputBlock = z.infer<typeof paymentInputSchema>
|
||||
export type PaymentInputOptions = z.infer<typeof paymentInputOptionsSchema>
|
||||
export type PaymentInputRuntimeOptions = z.infer<
|
||||
typeof paymentInputRuntimeOptionsSchema
|
||||
>
|
||||
export type StripeCredentials = z.infer<typeof stripeCredentialsSchema>
|
35
packages/schemas/features/blocks/inputs/phone.ts
Normal file
35
packages/schemas/features/blocks/inputs/phone.ts
Normal file
@ -0,0 +1,35 @@
|
||||
import { z } from 'zod'
|
||||
import { optionBaseSchema, blockBaseSchema } from '../baseSchemas'
|
||||
import { defaultButtonLabel } from './constants'
|
||||
import { InputBlockType } from './enums'
|
||||
import { textInputOptionsBaseSchema } from './text'
|
||||
|
||||
export const phoneNumberInputOptionsSchema = optionBaseSchema
|
||||
.merge(textInputOptionsBaseSchema)
|
||||
.merge(
|
||||
z.object({
|
||||
retryMessageContent: z.string(),
|
||||
defaultCountryCode: z.string().optional(),
|
||||
})
|
||||
)
|
||||
|
||||
export const phoneNumberInputBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([InputBlockType.PHONE]),
|
||||
options: phoneNumberInputOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultPhoneInputOptions: PhoneNumberInputOptions = {
|
||||
labels: {
|
||||
button: defaultButtonLabel,
|
||||
placeholder: 'Type your phone number...',
|
||||
},
|
||||
retryMessageContent:
|
||||
"This phone number doesn't seem to be valid. Can you type it again?",
|
||||
}
|
||||
|
||||
export type PhoneNumberInputBlock = z.infer<typeof phoneNumberInputBlockSchema>
|
||||
export type PhoneNumberInputOptions = z.infer<
|
||||
typeof phoneNumberInputOptionsSchema
|
||||
>
|
38
packages/schemas/features/blocks/inputs/rating.ts
Normal file
38
packages/schemas/features/blocks/inputs/rating.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { z } from 'zod'
|
||||
import { optionBaseSchema, blockBaseSchema } from '../baseSchemas'
|
||||
import { defaultButtonLabel } from './constants'
|
||||
import { InputBlockType } from './enums'
|
||||
|
||||
export const defaultRatingInputOptions: RatingInputOptions = {
|
||||
buttonType: 'Numbers',
|
||||
length: 10,
|
||||
labels: { button: defaultButtonLabel },
|
||||
customIcon: { isEnabled: false },
|
||||
}
|
||||
|
||||
export const ratingInputOptionsSchema = optionBaseSchema.merge(
|
||||
z.object({
|
||||
buttonType: z.literal('Icons').or(z.literal('Numbers')),
|
||||
length: z.number(),
|
||||
labels: z.object({
|
||||
left: z.string().optional(),
|
||||
right: z.string().optional(),
|
||||
button: z.string(),
|
||||
}),
|
||||
customIcon: z.object({
|
||||
isEnabled: z.boolean(),
|
||||
svg: z.string().optional(),
|
||||
}),
|
||||
isOneClickSubmitEnabled: z.boolean().optional(),
|
||||
})
|
||||
)
|
||||
|
||||
export const ratingInputBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.literal(InputBlockType.RATING),
|
||||
options: ratingInputOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export type RatingInputBlock = z.infer<typeof ratingInputBlockSchema>
|
||||
export type RatingInputOptions = z.infer<typeof ratingInputOptionsSchema>
|
34
packages/schemas/features/blocks/inputs/text.ts
Normal file
34
packages/schemas/features/blocks/inputs/text.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema, optionBaseSchema } from '../baseSchemas'
|
||||
import { defaultButtonLabel } from './constants'
|
||||
import { InputBlockType } from './enums'
|
||||
|
||||
export const textInputOptionsBaseSchema = z.object({
|
||||
labels: z.object({
|
||||
placeholder: z.string(),
|
||||
button: z.string(),
|
||||
}),
|
||||
})
|
||||
|
||||
export const textInputOptionsSchema = textInputOptionsBaseSchema
|
||||
.merge(optionBaseSchema)
|
||||
.merge(
|
||||
z.object({
|
||||
isLong: z.boolean(),
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultTextInputOptions: TextInputOptions = {
|
||||
isLong: false,
|
||||
labels: { button: defaultButtonLabel, placeholder: 'Type your answer...' },
|
||||
}
|
||||
|
||||
export const textInputSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([InputBlockType.TEXT]),
|
||||
options: textInputOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export type TextInputBlock = z.infer<typeof textInputSchema>
|
||||
export type TextInputOptions = z.infer<typeof textInputOptionsSchema>
|
32
packages/schemas/features/blocks/inputs/url.ts
Normal file
32
packages/schemas/features/blocks/inputs/url.ts
Normal file
@ -0,0 +1,32 @@
|
||||
import { z } from 'zod'
|
||||
import { optionBaseSchema, blockBaseSchema } from '../baseSchemas'
|
||||
import { defaultButtonLabel } from './constants'
|
||||
import { InputBlockType } from './enums'
|
||||
import { textInputOptionsBaseSchema } from './text'
|
||||
|
||||
export const urlInputOptionsSchema = optionBaseSchema
|
||||
.merge(textInputOptionsBaseSchema)
|
||||
.merge(
|
||||
z.object({
|
||||
retryMessageContent: z.string(),
|
||||
})
|
||||
)
|
||||
|
||||
export const urlInputSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([InputBlockType.URL]),
|
||||
options: urlInputOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultUrlInputOptions: UrlInputOptions = {
|
||||
labels: {
|
||||
button: defaultButtonLabel,
|
||||
placeholder: 'Type a URL...',
|
||||
},
|
||||
retryMessageContent:
|
||||
"This URL doesn't seem to be valid. Can you type it again?",
|
||||
}
|
||||
|
||||
export type UrlInputBlock = z.infer<typeof urlInputSchema>
|
||||
export type UrlInputOptions = z.infer<typeof urlInputOptionsSchema>
|
36
packages/schemas/features/blocks/integrations/chatwoot.ts
Normal file
36
packages/schemas/features/blocks/integrations/chatwoot.ts
Normal file
@ -0,0 +1,36 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { IntegrationBlockType } from './enums'
|
||||
|
||||
export const chatwootTasks = ['Show widget', 'Close widget'] as const
|
||||
|
||||
export const chatwootOptionsSchema = z.object({
|
||||
task: z.enum(chatwootTasks).optional(),
|
||||
baseUrl: z.string(),
|
||||
websiteToken: z.string(),
|
||||
user: z
|
||||
.object({
|
||||
id: z.string().optional(),
|
||||
email: z.string().optional(),
|
||||
name: z.string().optional(),
|
||||
avatarUrl: z.string().optional(),
|
||||
phoneNumber: z.string().optional(),
|
||||
})
|
||||
.optional(),
|
||||
})
|
||||
|
||||
export const chatwootBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([IntegrationBlockType.CHATWOOT]),
|
||||
options: chatwootOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultChatwootOptions: ChatwootOptions = {
|
||||
task: 'Show widget',
|
||||
baseUrl: 'https://app.chatwoot.com',
|
||||
websiteToken: '',
|
||||
}
|
||||
|
||||
export type ChatwootBlock = z.infer<typeof chatwootBlockSchema>
|
||||
export type ChatwootOptions = z.infer<typeof chatwootOptionsSchema>
|
11
packages/schemas/features/blocks/integrations/enums.ts
Normal file
11
packages/schemas/features/blocks/integrations/enums.ts
Normal file
@ -0,0 +1,11 @@
|
||||
export enum IntegrationBlockType {
|
||||
GOOGLE_SHEETS = 'Google Sheets',
|
||||
OPEN_AI = 'OpenAI',
|
||||
GOOGLE_ANALYTICS = 'Google Analytics',
|
||||
WEBHOOK = 'Webhook',
|
||||
EMAIL = 'Email',
|
||||
ZAPIER = 'Zapier',
|
||||
MAKE_COM = 'Make.com',
|
||||
PABBLY_CONNECT = 'Pabbly',
|
||||
CHATWOOT = 'Chatwoot',
|
||||
}
|
@ -0,0 +1,25 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { IntegrationBlockType } from './enums'
|
||||
|
||||
export const googleAnalyticsOptionsSchema = z.object({
|
||||
trackingId: z.string().optional(),
|
||||
category: z.string().optional(),
|
||||
action: z.string().optional(),
|
||||
label: z.string().optional(),
|
||||
value: z.number().optional(),
|
||||
})
|
||||
|
||||
export const googleAnalyticsBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([IntegrationBlockType.GOOGLE_ANALYTICS]),
|
||||
options: googleAnalyticsOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultGoogleAnalyticsOptions: GoogleAnalyticsOptions = {}
|
||||
|
||||
export type GoogleAnalyticsBlock = z.infer<typeof googleAnalyticsBlockSchema>
|
||||
export type GoogleAnalyticsOptions = z.infer<
|
||||
typeof googleAnalyticsOptionsSchema
|
||||
>
|
@ -0,0 +1,5 @@
|
||||
export enum GoogleSheetsAction {
|
||||
GET = 'Get data from sheet',
|
||||
INSERT_ROW = 'Insert a row',
|
||||
UPDATE_ROW = 'Update a row',
|
||||
}
|
@ -0,0 +1,2 @@
|
||||
export * from './enums'
|
||||
export * from './schemas'
|
@ -0,0 +1,156 @@
|
||||
import { z } from 'zod'
|
||||
import { ComparisonOperators, LogicalOperator } from '../../logic/condition'
|
||||
import { IntegrationBlockType } from '../enums'
|
||||
import { GoogleSheetsAction } from './enums'
|
||||
import { blockBaseSchema, credentialsBaseSchema } from '../../baseSchemas'
|
||||
|
||||
const cellSchema = z.object({
|
||||
column: z.string().optional(),
|
||||
value: z.string().optional(),
|
||||
id: z.string(),
|
||||
})
|
||||
|
||||
const extractingCellSchema = z.object({
|
||||
column: z.string().optional(),
|
||||
id: z.string(),
|
||||
variableId: z.string().optional(),
|
||||
})
|
||||
|
||||
const googleSheetsOptionsBaseSchema = z.object({
|
||||
credentialsId: z.string().optional(),
|
||||
sheetId: z.string().optional(),
|
||||
spreadsheetId: z.string().optional(),
|
||||
})
|
||||
|
||||
const rowsFilterComparisonSchema = z.object({
|
||||
id: z.string(),
|
||||
column: z.string().optional(),
|
||||
comparisonOperator: z.nativeEnum(ComparisonOperators).optional(),
|
||||
value: z.string().optional(),
|
||||
})
|
||||
|
||||
const initialGoogleSheetsOptionsSchema = googleSheetsOptionsBaseSchema.merge(
|
||||
z.object({
|
||||
action: z.undefined(),
|
||||
})
|
||||
)
|
||||
|
||||
const googleSheetsGetOptionsSchema = googleSheetsOptionsBaseSchema.merge(
|
||||
z.object({
|
||||
action: z.enum([GoogleSheetsAction.GET]),
|
||||
// TODO: remove referenceCell once migrated to filtering
|
||||
referenceCell: cellSchema.optional(),
|
||||
filter: z.object({
|
||||
comparisons: z.array(rowsFilterComparisonSchema),
|
||||
logicalOperator: z.nativeEnum(LogicalOperator),
|
||||
}),
|
||||
cellsToExtract: z.array(extractingCellSchema),
|
||||
})
|
||||
)
|
||||
|
||||
const googleSheetsInsertRowOptionsSchema = googleSheetsOptionsBaseSchema.merge(
|
||||
z.object({
|
||||
action: z.enum([GoogleSheetsAction.INSERT_ROW]),
|
||||
cellsToInsert: z.array(cellSchema),
|
||||
})
|
||||
)
|
||||
|
||||
const googleSheetsUpdateRowOptionsSchema = googleSheetsOptionsBaseSchema.merge(
|
||||
z.object({
|
||||
action: z.enum([GoogleSheetsAction.UPDATE_ROW]),
|
||||
cellsToUpsert: z.array(cellSchema),
|
||||
referenceCell: cellSchema.optional(),
|
||||
})
|
||||
)
|
||||
|
||||
export const googleSheetsOptionsSchema = z.discriminatedUnion('action', [
|
||||
googleSheetsGetOptionsSchema,
|
||||
googleSheetsInsertRowOptionsSchema,
|
||||
googleSheetsUpdateRowOptionsSchema,
|
||||
initialGoogleSheetsOptionsSchema,
|
||||
])
|
||||
|
||||
export const googleSheetsBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([IntegrationBlockType.GOOGLE_SHEETS]),
|
||||
options: googleSheetsOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const googleSheetsCredentialsSchema = z
|
||||
.object({
|
||||
type: z.literal('google sheets'),
|
||||
data: z.object({
|
||||
refresh_token: z.string().nullish(),
|
||||
expiry_date: z.number().nullish(),
|
||||
access_token: z.string().nullish(),
|
||||
token_type: z.string().nullish(),
|
||||
id_token: z.string().nullish(),
|
||||
scope: z.string().optional(),
|
||||
}),
|
||||
})
|
||||
.merge(credentialsBaseSchema)
|
||||
|
||||
export const defaultGoogleSheetsOptions: GoogleSheetsOptions = {}
|
||||
|
||||
export const defaultGoogleSheetsGetOptions = (
|
||||
createId: () => string
|
||||
): GoogleSheetsGetOptions => ({
|
||||
action: GoogleSheetsAction.GET,
|
||||
cellsToExtract: [
|
||||
{
|
||||
id: createId(),
|
||||
},
|
||||
],
|
||||
filter: {
|
||||
comparisons: [
|
||||
{
|
||||
id: createId(),
|
||||
},
|
||||
],
|
||||
logicalOperator: LogicalOperator.AND,
|
||||
},
|
||||
})
|
||||
|
||||
export const defaultGoogleSheetsInsertOptions = (
|
||||
createId: () => string
|
||||
): GoogleSheetsInsertRowOptions => ({
|
||||
action: GoogleSheetsAction.INSERT_ROW,
|
||||
cellsToInsert: [
|
||||
{
|
||||
id: createId(),
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
export const defaultGoogleSheetsUpdateOptions = (
|
||||
createId: () => string
|
||||
): GoogleSheetsUpdateRowOptions => ({
|
||||
action: GoogleSheetsAction.UPDATE_ROW,
|
||||
cellsToUpsert: [
|
||||
{
|
||||
id: createId(),
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
export type GoogleSheetsBlock = z.infer<typeof googleSheetsBlockSchema>
|
||||
export type GoogleSheetsOptions = z.infer<typeof googleSheetsOptionsSchema>
|
||||
export type GoogleSheetsOptionsBase = z.infer<
|
||||
typeof googleSheetsOptionsBaseSchema
|
||||
>
|
||||
export type GoogleSheetsGetOptions = z.infer<
|
||||
typeof googleSheetsGetOptionsSchema
|
||||
>
|
||||
export type GoogleSheetsInsertRowOptions = z.infer<
|
||||
typeof googleSheetsInsertRowOptionsSchema
|
||||
>
|
||||
export type GoogleSheetsUpdateRowOptions = z.infer<
|
||||
typeof googleSheetsUpdateRowOptionsSchema
|
||||
>
|
||||
export type Cell = z.infer<typeof cellSchema>
|
||||
export type ExtractingCell = z.infer<typeof extractingCellSchema>
|
||||
export type RowsFilterComparison = z.infer<typeof rowsFilterComparisonSchema>
|
||||
export type GoogleSheetsCredentials = z.infer<
|
||||
typeof googleSheetsCredentialsSchema
|
||||
>
|
9
packages/schemas/features/blocks/integrations/index.ts
Normal file
9
packages/schemas/features/blocks/integrations/index.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export * from './chatwoot'
|
||||
export * from './enums'
|
||||
export * from './googleAnalytics'
|
||||
export * from './googleSheets'
|
||||
export * from './makeCom'
|
||||
export * from './pabblyConnect'
|
||||
export * from './sendEmail'
|
||||
export * from './webhook'
|
||||
export * from './zapier'
|
14
packages/schemas/features/blocks/integrations/makeCom.ts
Normal file
14
packages/schemas/features/blocks/integrations/makeCom.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { IntegrationBlockType } from './enums'
|
||||
import { webhookOptionsSchema } from './webhook'
|
||||
|
||||
export const makeComBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([IntegrationBlockType.MAKE_COM]),
|
||||
options: webhookOptionsSchema,
|
||||
webhookId: z.string(),
|
||||
})
|
||||
)
|
||||
|
||||
export type MakeComBlock = z.infer<typeof makeComBlockSchema>
|
131
packages/schemas/features/blocks/integrations/openai.ts
Normal file
131
packages/schemas/features/blocks/integrations/openai.ts
Normal file
@ -0,0 +1,131 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema, credentialsBaseSchema } from '../baseSchemas'
|
||||
import { IntegrationBlockType } from './enums'
|
||||
|
||||
export const openAITasks = ['Create chat completion', 'Create image'] as const
|
||||
|
||||
export const chatCompletionModels = [
|
||||
'gpt-3.5-turbo',
|
||||
'gpt-3.5-turbo-0301',
|
||||
] as const
|
||||
|
||||
export const chatCompletionMessageRoles = [
|
||||
'system',
|
||||
'user',
|
||||
'assistant',
|
||||
] as const
|
||||
|
||||
export const chatCompletionMessageCustomRoles = [
|
||||
'Messages sequence ✨',
|
||||
] as const
|
||||
|
||||
export const chatCompletionResponseValues = [
|
||||
'Message content',
|
||||
'Total tokens',
|
||||
] as const
|
||||
|
||||
const openAIBaseOptionsSchema = z.object({
|
||||
credentialsId: z.string().optional(),
|
||||
})
|
||||
|
||||
const initialOptionsSchema = z
|
||||
.object({
|
||||
task: z.undefined(),
|
||||
})
|
||||
.merge(openAIBaseOptionsSchema)
|
||||
|
||||
const chatCompletionMessageSchema = z.object({
|
||||
id: z.string(),
|
||||
role: z.enum(chatCompletionMessageRoles).optional(),
|
||||
content: z.string().optional(),
|
||||
})
|
||||
|
||||
const chatCompletionCustomMessageSchema = z.object({
|
||||
id: z.string(),
|
||||
role: z.enum(chatCompletionMessageCustomRoles),
|
||||
content: z
|
||||
.object({
|
||||
assistantMessagesVariableId: z.string().optional(),
|
||||
userMessagesVariableId: z.string().optional(),
|
||||
})
|
||||
.optional(),
|
||||
})
|
||||
|
||||
const chatCompletionOptionsSchema = z
|
||||
.object({
|
||||
task: z.literal(openAITasks[0]),
|
||||
model: z.enum(chatCompletionModels),
|
||||
messages: z.array(
|
||||
z.union([chatCompletionMessageSchema, chatCompletionCustomMessageSchema])
|
||||
),
|
||||
responseMapping: z.array(
|
||||
z.object({
|
||||
id: z.string(),
|
||||
valueToExtract: z.enum(chatCompletionResponseValues),
|
||||
variableId: z.string().optional(),
|
||||
})
|
||||
),
|
||||
})
|
||||
.merge(openAIBaseOptionsSchema)
|
||||
|
||||
const createImageOptionsSchema = z
|
||||
.object({
|
||||
task: z.literal(openAITasks[1]),
|
||||
prompt: z.string().optional(),
|
||||
advancedOptions: z.object({
|
||||
size: z.enum(['256x256', '512x512', '1024x1024']).optional(),
|
||||
}),
|
||||
responseMapping: z.array(
|
||||
z.object({
|
||||
id: z.string(),
|
||||
valueToExtract: z.enum(['Image URL']),
|
||||
variableId: z.string().optional(),
|
||||
})
|
||||
),
|
||||
})
|
||||
.merge(openAIBaseOptionsSchema)
|
||||
|
||||
export const openAIBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([IntegrationBlockType.OPEN_AI]),
|
||||
options: z.discriminatedUnion('task', [
|
||||
initialOptionsSchema,
|
||||
chatCompletionOptionsSchema,
|
||||
createImageOptionsSchema,
|
||||
]),
|
||||
})
|
||||
)
|
||||
|
||||
export const openAICredentialsSchema = z
|
||||
.object({
|
||||
type: z.literal('openai'),
|
||||
data: z.object({
|
||||
apiKey: z.string(),
|
||||
}),
|
||||
})
|
||||
.merge(credentialsBaseSchema)
|
||||
|
||||
export const defaultChatCompletionOptions = (
|
||||
createId: () => string
|
||||
): ChatCompletionOpenAIOptions => ({
|
||||
task: 'Create chat completion',
|
||||
messages: [
|
||||
{
|
||||
id: createId(),
|
||||
},
|
||||
],
|
||||
responseMapping: [
|
||||
{
|
||||
id: createId(),
|
||||
valueToExtract: 'Message content',
|
||||
},
|
||||
],
|
||||
model: 'gpt-3.5-turbo',
|
||||
})
|
||||
|
||||
export type OpenAICredentials = z.infer<typeof openAICredentialsSchema>
|
||||
export type OpenAIBlock = z.infer<typeof openAIBlockSchema>
|
||||
export type ChatCompletionOpenAIOptions = z.infer<
|
||||
typeof chatCompletionOptionsSchema
|
||||
>
|
||||
export type CreateImageOpenAIOptions = z.infer<typeof createImageOptionsSchema>
|
@ -0,0 +1,14 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { IntegrationBlockType } from './enums'
|
||||
import { webhookOptionsSchema } from './webhook'
|
||||
|
||||
export const pabblyConnectBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([IntegrationBlockType.PABBLY_CONNECT]),
|
||||
options: webhookOptionsSchema,
|
||||
webhookId: z.string(),
|
||||
})
|
||||
)
|
||||
|
||||
export type PabblyConnectBlock = z.infer<typeof pabblyConnectBlockSchema>
|
50
packages/schemas/features/blocks/integrations/sendEmail.ts
Normal file
50
packages/schemas/features/blocks/integrations/sendEmail.ts
Normal file
@ -0,0 +1,50 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema, credentialsBaseSchema } from '../baseSchemas'
|
||||
import { IntegrationBlockType } from './enums'
|
||||
|
||||
export const sendEmailOptionsSchema = z.object({
|
||||
credentialsId: z.string(),
|
||||
isCustomBody: z.boolean().optional(),
|
||||
isBodyCode: z.boolean().optional(),
|
||||
recipients: z.array(z.string()),
|
||||
subject: z.string().optional(),
|
||||
body: z.string().optional(),
|
||||
replyTo: z.string().optional(),
|
||||
cc: z.array(z.string()).optional(),
|
||||
bcc: z.array(z.string()).optional(),
|
||||
attachmentsVariableId: z.string().optional(),
|
||||
})
|
||||
|
||||
export const sendEmailBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([IntegrationBlockType.EMAIL]),
|
||||
options: sendEmailOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const smtpCredentialsSchema = z
|
||||
.object({
|
||||
type: z.literal('smtp'),
|
||||
data: z.object({
|
||||
host: z.string().optional(),
|
||||
username: z.string().optional(),
|
||||
password: z.string().optional(),
|
||||
isTlsEnabled: z.boolean().optional(),
|
||||
port: z.number(),
|
||||
from: z.object({
|
||||
email: z.string().optional(),
|
||||
name: z.string().optional(),
|
||||
}),
|
||||
}),
|
||||
})
|
||||
.merge(credentialsBaseSchema)
|
||||
|
||||
export const defaultSendEmailOptions: SendEmailOptions = {
|
||||
credentialsId: 'default',
|
||||
isCustomBody: false,
|
||||
recipients: [],
|
||||
}
|
||||
|
||||
export type SendEmailBlock = z.infer<typeof sendEmailBlockSchema>
|
||||
export type SendEmailOptions = z.infer<typeof sendEmailOptionsSchema>
|
||||
export type SmtpCredentials = z.infer<typeof smtpCredentialsSchema>
|
44
packages/schemas/features/blocks/integrations/webhook.ts
Normal file
44
packages/schemas/features/blocks/integrations/webhook.ts
Normal file
@ -0,0 +1,44 @@
|
||||
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(),
|
||||
})
|
||||
|
||||
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>
|
14
packages/schemas/features/blocks/integrations/zapier.ts
Normal file
14
packages/schemas/features/blocks/integrations/zapier.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { IntegrationBlockType } from './enums'
|
||||
import { webhookOptionsSchema } from './webhook'
|
||||
|
||||
export const zapierBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([IntegrationBlockType.ZAPIER]),
|
||||
options: webhookOptionsSchema,
|
||||
webhookId: z.string(),
|
||||
})
|
||||
)
|
||||
|
||||
export type ZapierBlock = z.infer<typeof zapierBlockSchema>
|
55
packages/schemas/features/blocks/logic/condition.ts
Normal file
55
packages/schemas/features/blocks/logic/condition.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { z } from 'zod'
|
||||
import { ItemType } from '../../items/enums'
|
||||
import { itemBaseSchema } from '../../items/baseSchemas'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { LogicBlockType } from './enums'
|
||||
|
||||
export enum LogicalOperator {
|
||||
OR = 'OR',
|
||||
AND = 'AND',
|
||||
}
|
||||
|
||||
export enum ComparisonOperators {
|
||||
EQUAL = 'Equal to',
|
||||
NOT_EQUAL = 'Not equal',
|
||||
CONTAINS = 'Contains',
|
||||
GREATER = 'Greater than',
|
||||
LESS = 'Less than',
|
||||
IS_SET = 'Is set',
|
||||
}
|
||||
|
||||
const comparisonSchema = z.object({
|
||||
id: z.string(),
|
||||
variableId: z.string().optional(),
|
||||
comparisonOperator: z.nativeEnum(ComparisonOperators).optional(),
|
||||
value: z.string().optional(),
|
||||
})
|
||||
|
||||
const conditionContentSchema = z.object({
|
||||
logicalOperator: z.nativeEnum(LogicalOperator),
|
||||
comparisons: z.array(comparisonSchema),
|
||||
})
|
||||
|
||||
export const conditionItemSchema = itemBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.literal(ItemType.CONDITION),
|
||||
content: conditionContentSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const conditionBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([LogicBlockType.CONDITION]),
|
||||
items: z.array(conditionItemSchema),
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultConditionContent: ConditionContent = {
|
||||
comparisons: [],
|
||||
logicalOperator: LogicalOperator.AND,
|
||||
}
|
||||
|
||||
export type ConditionItem = z.infer<typeof conditionItemSchema>
|
||||
export type Comparison = z.infer<typeof comparisonSchema>
|
||||
export type ConditionBlock = z.infer<typeof conditionBlockSchema>
|
||||
export type ConditionContent = z.infer<typeof conditionContentSchema>
|
9
packages/schemas/features/blocks/logic/enums.ts
Normal file
9
packages/schemas/features/blocks/logic/enums.ts
Normal file
@ -0,0 +1,9 @@
|
||||
export enum LogicBlockType {
|
||||
SET_VARIABLE = 'Set variable',
|
||||
CONDITION = 'Condition',
|
||||
REDIRECT = 'Redirect',
|
||||
SCRIPT = 'Code',
|
||||
TYPEBOT_LINK = 'Typebot link',
|
||||
WAIT = 'Wait',
|
||||
JUMP = 'Jump',
|
||||
}
|
7
packages/schemas/features/blocks/logic/index.ts
Normal file
7
packages/schemas/features/blocks/logic/index.ts
Normal file
@ -0,0 +1,7 @@
|
||||
export * from './script'
|
||||
export * from './condition'
|
||||
export * from './enums'
|
||||
export * from './redirect'
|
||||
export * from './setVariable'
|
||||
export * from './typebotLink'
|
||||
export * from './wait'
|
17
packages/schemas/features/blocks/logic/jump.ts
Normal file
17
packages/schemas/features/blocks/logic/jump.ts
Normal file
@ -0,0 +1,17 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { LogicBlockType } from './enums'
|
||||
|
||||
export const jumpOptionsSchema = z.object({
|
||||
groupId: z.string().optional(),
|
||||
blockId: z.string().optional(),
|
||||
})
|
||||
|
||||
export const jumpBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([LogicBlockType.JUMP]),
|
||||
options: jumpOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export type JumpBlock = z.infer<typeof jumpBlockSchema>
|
20
packages/schemas/features/blocks/logic/redirect.ts
Normal file
20
packages/schemas/features/blocks/logic/redirect.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { LogicBlockType } from './enums'
|
||||
|
||||
export const redirectOptionsSchema = z.object({
|
||||
url: z.string().optional(),
|
||||
isNewTab: z.boolean(),
|
||||
})
|
||||
|
||||
export const redirectBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([LogicBlockType.REDIRECT]),
|
||||
options: redirectOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultRedirectOptions: RedirectOptions = { isNewTab: false }
|
||||
|
||||
export type RedirectBlock = z.infer<typeof redirectBlockSchema>
|
||||
export type RedirectOptions = z.infer<typeof redirectOptionsSchema>
|
21
packages/schemas/features/blocks/logic/script.ts
Normal file
21
packages/schemas/features/blocks/logic/script.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { LogicBlockType } from './enums'
|
||||
|
||||
export const scriptOptionsSchema = z.object({
|
||||
name: z.string(),
|
||||
content: z.string().optional(),
|
||||
shouldExecuteInParentContext: z.boolean().optional(),
|
||||
})
|
||||
|
||||
export const scriptBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([LogicBlockType.SCRIPT]),
|
||||
options: scriptOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultScriptOptions: ScriptOptions = { name: 'Script' }
|
||||
|
||||
export type ScriptBlock = z.infer<typeof scriptBlockSchema>
|
||||
export type ScriptOptions = z.infer<typeof scriptOptionsSchema>
|
21
packages/schemas/features/blocks/logic/setVariable.ts
Normal file
21
packages/schemas/features/blocks/logic/setVariable.ts
Normal file
@ -0,0 +1,21 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { LogicBlockType } from './enums'
|
||||
|
||||
export const setVariableOptionsSchema = z.object({
|
||||
variableId: z.string().optional(),
|
||||
expressionToEvaluate: z.string().optional(),
|
||||
isCode: z.boolean().optional(),
|
||||
})
|
||||
|
||||
export const setVariableBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([LogicBlockType.SET_VARIABLE]),
|
||||
options: setVariableOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultSetVariablesOptions: SetVariableOptions = {}
|
||||
|
||||
export type SetVariableBlock = z.infer<typeof setVariableBlockSchema>
|
||||
export type SetVariableOptions = z.infer<typeof setVariableOptionsSchema>
|
20
packages/schemas/features/blocks/logic/typebotLink.ts
Normal file
20
packages/schemas/features/blocks/logic/typebotLink.ts
Normal file
@ -0,0 +1,20 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { LogicBlockType } from './enums'
|
||||
|
||||
export const typebotLinkOptionsSchema = z.object({
|
||||
typebotId: z.string().optional(),
|
||||
groupId: z.string().optional(),
|
||||
})
|
||||
|
||||
export const typebotLinkBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([LogicBlockType.TYPEBOT_LINK]),
|
||||
options: typebotLinkOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultTypebotLinkOptions: TypebotLinkOptions = {}
|
||||
|
||||
export type TypebotLinkBlock = z.infer<typeof typebotLinkBlockSchema>
|
||||
export type TypebotLinkOptions = z.infer<typeof typebotLinkOptionsSchema>
|
19
packages/schemas/features/blocks/logic/wait.ts
Normal file
19
packages/schemas/features/blocks/logic/wait.ts
Normal file
@ -0,0 +1,19 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
import { LogicBlockType } from './enums'
|
||||
|
||||
export const waitOptionsSchema = z.object({
|
||||
secondsToWaitFor: z.string().optional(),
|
||||
})
|
||||
|
||||
export const waitBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.enum([LogicBlockType.WAIT]),
|
||||
options: waitOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultWaitOptions: WaitOptions = {}
|
||||
|
||||
export type WaitBlock = z.infer<typeof waitBlockSchema>
|
||||
export type WaitOptions = z.infer<typeof waitOptionsSchema>
|
161
packages/schemas/features/blocks/schemas.ts
Normal file
161
packages/schemas/features/blocks/schemas.ts
Normal file
@ -0,0 +1,161 @@
|
||||
import { z } from 'zod'
|
||||
import { BubbleBlockType } from './bubbles/enums'
|
||||
import { ChoiceInputBlock, choiceInputSchema } from './inputs/choice'
|
||||
import { InputBlockType } from './inputs/enums'
|
||||
import { IntegrationBlockType } from './integrations/enums'
|
||||
import { ConditionBlock, conditionBlockSchema } from './logic/condition'
|
||||
import { LogicBlockType } from './logic/enums'
|
||||
import { blockBaseSchema } from './baseSchemas'
|
||||
import { startBlockSchema } from './start/schemas'
|
||||
import {
|
||||
textBubbleBlockSchema,
|
||||
imageBubbleBlockSchema,
|
||||
videoBubbleBlockSchema,
|
||||
embedBubbleBlockSchema,
|
||||
audioBubbleBlockSchema,
|
||||
} from './bubbles'
|
||||
import {
|
||||
textInputSchema,
|
||||
emailInputSchema,
|
||||
numberInputSchema,
|
||||
urlInputSchema,
|
||||
phoneNumberInputBlockSchema,
|
||||
dateInputSchema,
|
||||
paymentInputSchema,
|
||||
ratingInputBlockSchema,
|
||||
fileInputStepSchema,
|
||||
} from './inputs'
|
||||
import {
|
||||
chatwootBlockSchema,
|
||||
googleAnalyticsBlockSchema,
|
||||
googleSheetsBlockSchema,
|
||||
makeComBlockSchema,
|
||||
pabblyConnectBlockSchema,
|
||||
sendEmailBlockSchema,
|
||||
webhookBlockSchema,
|
||||
zapierBlockSchema,
|
||||
} from './integrations'
|
||||
import { openAIBlockSchema } from './integrations/openai'
|
||||
import {
|
||||
scriptBlockSchema,
|
||||
redirectBlockSchema,
|
||||
setVariableBlockSchema,
|
||||
typebotLinkBlockSchema,
|
||||
waitBlockSchema,
|
||||
} from './logic'
|
||||
import { jumpBlockSchema } from './logic/jump'
|
||||
|
||||
export type DraggableBlock =
|
||||
| BubbleBlock
|
||||
| InputBlock
|
||||
| LogicBlock
|
||||
| IntegrationBlock
|
||||
|
||||
export type BlockType =
|
||||
| 'start'
|
||||
| BubbleBlockType
|
||||
| InputBlockType
|
||||
| LogicBlockType
|
||||
| IntegrationBlockType
|
||||
|
||||
export type DraggableBlockType =
|
||||
| BubbleBlockType
|
||||
| InputBlockType
|
||||
| LogicBlockType
|
||||
| IntegrationBlockType
|
||||
|
||||
export type BlockWithOptions =
|
||||
| InputBlock
|
||||
| Exclude<LogicBlock, ConditionBlock>
|
||||
| IntegrationBlock
|
||||
|
||||
export type BlockWithOptionsType =
|
||||
| InputBlockType
|
||||
| Exclude<LogicBlockType, LogicBlockType.CONDITION>
|
||||
| IntegrationBlockType
|
||||
|
||||
export type BlockOptions =
|
||||
| InputBlockOptions
|
||||
| LogicBlockOptions
|
||||
| IntegrationBlockOptions
|
||||
|
||||
export type BlockWithItems = ConditionBlock | ChoiceInputBlock
|
||||
|
||||
export type BlockBase = z.infer<typeof blockBaseSchema>
|
||||
|
||||
export type BlockIndices = {
|
||||
groupIndex: number
|
||||
blockIndex: number
|
||||
}
|
||||
|
||||
const bubbleBlockSchema = z.discriminatedUnion('type', [
|
||||
textBubbleBlockSchema,
|
||||
imageBubbleBlockSchema,
|
||||
videoBubbleBlockSchema,
|
||||
embedBubbleBlockSchema,
|
||||
audioBubbleBlockSchema,
|
||||
])
|
||||
|
||||
export type BubbleBlock = z.infer<typeof bubbleBlockSchema>
|
||||
export type BubbleBlockContent = BubbleBlock['content']
|
||||
|
||||
export const inputBlockSchema = z.discriminatedUnion('type', [
|
||||
textInputSchema,
|
||||
choiceInputSchema,
|
||||
emailInputSchema,
|
||||
numberInputSchema,
|
||||
urlInputSchema,
|
||||
phoneNumberInputBlockSchema,
|
||||
dateInputSchema,
|
||||
paymentInputSchema,
|
||||
ratingInputBlockSchema,
|
||||
fileInputStepSchema,
|
||||
])
|
||||
|
||||
export type InputBlock = z.infer<typeof inputBlockSchema>
|
||||
export type InputBlockOptions = InputBlock['options']
|
||||
|
||||
export const logicBlockSchema = z.discriminatedUnion('type', [
|
||||
scriptBlockSchema,
|
||||
conditionBlockSchema,
|
||||
redirectBlockSchema,
|
||||
setVariableBlockSchema,
|
||||
typebotLinkBlockSchema,
|
||||
waitBlockSchema,
|
||||
jumpBlockSchema,
|
||||
])
|
||||
|
||||
export type LogicBlock = z.infer<typeof logicBlockSchema>
|
||||
|
||||
export type LogicBlockOptions = LogicBlock extends
|
||||
| {
|
||||
options?: infer Options
|
||||
}
|
||||
| {}
|
||||
? Options
|
||||
: never
|
||||
|
||||
export const integrationBlockSchema = z.discriminatedUnion('type', [
|
||||
chatwootBlockSchema,
|
||||
googleAnalyticsBlockSchema,
|
||||
googleSheetsBlockSchema,
|
||||
makeComBlockSchema,
|
||||
openAIBlockSchema,
|
||||
pabblyConnectBlockSchema,
|
||||
sendEmailBlockSchema,
|
||||
webhookBlockSchema,
|
||||
zapierBlockSchema,
|
||||
])
|
||||
|
||||
export type IntegrationBlock = z.infer<typeof integrationBlockSchema>
|
||||
export type IntegrationBlockOptions = IntegrationBlock['options']
|
||||
|
||||
export const blockSchema = z.union([
|
||||
startBlockSchema,
|
||||
bubbleBlockSchema,
|
||||
inputBlockSchema,
|
||||
logicBlockSchema,
|
||||
integrationBlockSchema,
|
||||
])
|
||||
|
||||
export type Block = z.infer<typeof blockSchema>
|
1
packages/schemas/features/blocks/start/index.ts
Normal file
1
packages/schemas/features/blocks/start/index.ts
Normal file
@ -0,0 +1 @@
|
||||
export * from './schemas'
|
11
packages/schemas/features/blocks/start/schemas.ts
Normal file
11
packages/schemas/features/blocks/start/schemas.ts
Normal file
@ -0,0 +1,11 @@
|
||||
import { z } from 'zod'
|
||||
import { blockBaseSchema } from '../baseSchemas'
|
||||
|
||||
export const startBlockSchema = blockBaseSchema.merge(
|
||||
z.object({
|
||||
type: z.literal('start'),
|
||||
label: z.string(),
|
||||
})
|
||||
)
|
||||
|
||||
export type StartBlock = z.infer<typeof startBlockSchema>
|
258
packages/schemas/features/chat.ts
Normal file
258
packages/schemas/features/chat.ts
Normal file
@ -0,0 +1,258 @@
|
||||
import { z } from 'zod'
|
||||
import {
|
||||
googleAnalyticsOptionsSchema,
|
||||
paymentInputRuntimeOptionsSchema,
|
||||
redirectOptionsSchema,
|
||||
} from './blocks'
|
||||
import { publicTypebotSchema } from './publicTypebot'
|
||||
import { logSchema, resultSchema } from './result'
|
||||
import { typebotSchema } from './typebot'
|
||||
import {
|
||||
textBubbleContentSchema,
|
||||
imageBubbleContentSchema,
|
||||
videoBubbleContentSchema,
|
||||
audioBubbleContentSchema,
|
||||
embedBubbleContentSchema,
|
||||
} from './blocks/bubbles'
|
||||
import { answerSchema } from './answer'
|
||||
import { BubbleBlockType } from './blocks/bubbles/enums'
|
||||
import { inputBlockSchema } from './blocks/schemas'
|
||||
|
||||
const typebotInSessionStateSchema = publicTypebotSchema.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(),
|
||||
})
|
||||
|
||||
const chatSessionSchema = z.object({
|
||||
id: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
state: sessionStateSchema,
|
||||
})
|
||||
|
||||
const textMessageSchema = z.object({
|
||||
type: z.literal(BubbleBlockType.TEXT),
|
||||
content: textBubbleContentSchema.omit({
|
||||
richText: true,
|
||||
}),
|
||||
})
|
||||
|
||||
const imageMessageSchema = z.object({
|
||||
type: z.enum([BubbleBlockType.IMAGE]),
|
||||
content: imageBubbleContentSchema,
|
||||
})
|
||||
|
||||
const videoMessageSchema = z.object({
|
||||
type: z.enum([BubbleBlockType.VIDEO]),
|
||||
content: videoBubbleContentSchema,
|
||||
})
|
||||
|
||||
const audioMessageSchema = z.object({
|
||||
type: z.enum([BubbleBlockType.AUDIO]),
|
||||
content: audioBubbleContentSchema,
|
||||
})
|
||||
|
||||
const embedMessageSchema = z.object({
|
||||
type: z.enum([BubbleBlockType.EMBED]),
|
||||
content: embedBubbleContentSchema
|
||||
.omit({
|
||||
height: true,
|
||||
})
|
||||
.merge(z.object({ height: z.number().optional() })),
|
||||
})
|
||||
|
||||
const chatMessageSchema = z
|
||||
.object({ id: z.string() })
|
||||
.and(
|
||||
z.discriminatedUnion('type', [
|
||||
textMessageSchema,
|
||||
imageMessageSchema,
|
||||
videoMessageSchema,
|
||||
audioMessageSchema,
|
||||
embedMessageSchema,
|
||||
])
|
||||
)
|
||||
|
||||
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(z.array(z.string()))
|
||||
.nullish(),
|
||||
})
|
||||
),
|
||||
})
|
||||
|
||||
const startTypebotSchema = typebotSchema.pick({
|
||||
id: true,
|
||||
groups: true,
|
||||
edges: true,
|
||||
variables: true,
|
||||
settings: true,
|
||||
theme: true,
|
||||
})
|
||||
|
||||
const startParamsSchema = z.object({
|
||||
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)).'
|
||||
),
|
||||
isPreview: z
|
||||
.boolean()
|
||||
.optional()
|
||||
.describe(
|
||||
"If set to `true`, it will start a Preview session with the unpublished bot and it won't be saved in the Results tab. You need to be authenticated for this to work."
|
||||
),
|
||||
resultId: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe("Provide it if you'd like to overwrite an existing result."),
|
||||
startGroupId: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe('Start chat from a specific group.'),
|
||||
prefilledVariables: z
|
||||
.record(z.unknown())
|
||||
.optional()
|
||||
.describe(
|
||||
'[More info about prefilled variables.](https://docs.typebot.io/editor/variables#prefilled-variables)'
|
||||
),
|
||||
})
|
||||
|
||||
export const sendMessageInputSchema = z.object({
|
||||
message: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe(
|
||||
'The answer to the previous chat input. Do not provide it if you are starting a new chat.'
|
||||
),
|
||||
sessionId: z
|
||||
.string()
|
||||
.optional()
|
||||
.describe(
|
||||
'Session ID that you get from the initial chat request to a bot. If not provided, it will create a new session.'
|
||||
),
|
||||
startParams: startParamsSchema.optional(),
|
||||
})
|
||||
|
||||
const runtimeOptionsSchema = paymentInputRuntimeOptionsSchema.optional()
|
||||
|
||||
const replyLogSchema = logSchema
|
||||
.pick({
|
||||
status: true,
|
||||
description: true,
|
||||
})
|
||||
.merge(z.object({ details: z.unknown().optional() }))
|
||||
|
||||
const clientSideActionSchema = z
|
||||
.object({
|
||||
lastBubbleBlockId: z.string().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(),
|
||||
}),
|
||||
})
|
||||
)
|
||||
)
|
||||
|
||||
export const chatReplySchema = z.object({
|
||||
messages: z.array(chatMessageSchema),
|
||||
input: inputBlockSchema
|
||||
.and(
|
||||
z.object({
|
||||
prefilledValue: z.string().optional(),
|
||||
runtimeOptions: runtimeOptionsSchema.optional(),
|
||||
})
|
||||
)
|
||||
.optional(),
|
||||
clientSideActions: z.array(clientSideActionSchema).optional(),
|
||||
sessionId: z.string().optional(),
|
||||
typebot: typebotSchema
|
||||
.pick({ id: true, theme: true, settings: true })
|
||||
.optional(),
|
||||
resultId: z.string().optional(),
|
||||
dynamicTheme: dynamicThemeSchema.optional(),
|
||||
logs: z.array(replyLogSchema).optional(),
|
||||
})
|
||||
|
||||
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>
|
||||
export type ScriptToExecute = z.infer<typeof scriptToExecuteSchema>
|
||||
export type StartParams = z.infer<typeof startParamsSchema>
|
||||
export type RuntimeOptions = z.infer<typeof runtimeOptionsSchema>
|
||||
export type StartTypebot = z.infer<typeof startTypebotSchema>
|
||||
export type ReplyLog = z.infer<typeof replyLogSchema>
|
14
packages/schemas/features/credentials.ts
Normal file
14
packages/schemas/features/credentials.ts
Normal file
@ -0,0 +1,14 @@
|
||||
import { z } from 'zod'
|
||||
import { stripeCredentialsSchema } from './blocks/inputs/payment/schemas'
|
||||
import { googleSheetsCredentialsSchema } from './blocks/integrations/googleSheets/schemas'
|
||||
import { openAICredentialsSchema } from './blocks/integrations/openai'
|
||||
import { smtpCredentialsSchema } from './blocks/integrations/sendEmail'
|
||||
|
||||
export const credentialsSchema = z.discriminatedUnion('type', [
|
||||
smtpCredentialsSchema,
|
||||
googleSheetsCredentialsSchema,
|
||||
stripeCredentialsSchema,
|
||||
openAICredentialsSchema,
|
||||
])
|
||||
|
||||
export type Credentials = z.infer<typeof credentialsSchema>
|
9
packages/schemas/features/items/baseSchemas.ts
Normal file
9
packages/schemas/features/items/baseSchemas.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { z } from 'zod'
|
||||
|
||||
export const itemBaseSchema = z.object({
|
||||
id: z.string(),
|
||||
blockId: z.string(),
|
||||
outgoingEdgeId: z.string().optional(),
|
||||
})
|
||||
|
||||
export type ItemBase = z.infer<typeof itemBaseSchema>
|
4
packages/schemas/features/items/enums.ts
Normal file
4
packages/schemas/features/items/enums.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export enum ItemType {
|
||||
BUTTON,
|
||||
CONDITION,
|
||||
}
|
4
packages/schemas/features/items/index.ts
Normal file
4
packages/schemas/features/items/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export * from './baseSchemas'
|
||||
export * from './enums'
|
||||
export * from './schemas'
|
||||
export * from './types'
|
7
packages/schemas/features/items/schemas.ts
Normal file
7
packages/schemas/features/items/schemas.ts
Normal file
@ -0,0 +1,7 @@
|
||||
import { z } from 'zod'
|
||||
import { buttonItemSchema } from '../blocks/inputs/choice'
|
||||
import { conditionItemSchema } from '../blocks/logic/condition'
|
||||
|
||||
const itemSchema = buttonItemSchema.or(conditionItemSchema)
|
||||
|
||||
export type Item = z.infer<typeof itemSchema>
|
5
packages/schemas/features/items/types.ts
Normal file
5
packages/schemas/features/items/types.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export type ItemIndices = {
|
||||
blockIndex: number
|
||||
groupIndex: number
|
||||
itemIndex: number
|
||||
}
|
30
packages/schemas/features/publicTypebot.ts
Normal file
30
packages/schemas/features/publicTypebot.ts
Normal file
@ -0,0 +1,30 @@
|
||||
import { PublicTypebot as PrismaPublicTypebot } from '@typebot.io/prisma'
|
||||
import {
|
||||
groupSchema,
|
||||
edgeSchema,
|
||||
variableSchema,
|
||||
themeSchema,
|
||||
settingsSchema,
|
||||
typebotSchema,
|
||||
} from './typebot'
|
||||
import { z } from 'zod'
|
||||
|
||||
export const publicTypebotSchema = z.object({
|
||||
id: z.string(),
|
||||
version: z.enum(['3']).nullable(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
typebotId: z.string(),
|
||||
groups: z.array(groupSchema),
|
||||
edges: z.array(edgeSchema),
|
||||
variables: z.array(variableSchema),
|
||||
theme: themeSchema,
|
||||
settings: settingsSchema,
|
||||
}) satisfies z.ZodType<PrismaPublicTypebot>
|
||||
|
||||
const publicTypebotWithName = publicTypebotSchema.merge(
|
||||
typebotSchema.pick({ name: true, isArchived: true, isClosed: true })
|
||||
)
|
||||
|
||||
export type PublicTypebot = z.infer<typeof publicTypebotSchema>
|
||||
export type PublicTypebotWithName = z.infer<typeof publicTypebotWithName>
|
64
packages/schemas/features/result.ts
Normal file
64
packages/schemas/features/result.ts
Normal file
@ -0,0 +1,64 @@
|
||||
import { z } from 'zod'
|
||||
import { answerInputSchema, answerSchema } from './answer'
|
||||
import { InputBlockType } from './blocks'
|
||||
import { variableWithValueSchema } from './typebot/variable'
|
||||
import { Result as ResultPrisma, Log as LogPrisma } from '@typebot.io/prisma'
|
||||
|
||||
export const resultSchema = z.object({
|
||||
id: z.string(),
|
||||
createdAt: z.date(),
|
||||
typebotId: z.string(),
|
||||
variables: z.array(variableWithValueSchema),
|
||||
isCompleted: z.boolean(),
|
||||
hasStarted: z.boolean().nullable(),
|
||||
isArchived: z.boolean().nullable(),
|
||||
}) satisfies z.ZodType<ResultPrisma>
|
||||
|
||||
export const resultWithAnswersSchema = resultSchema.merge(
|
||||
z.object({
|
||||
answers: z.array(answerSchema),
|
||||
})
|
||||
)
|
||||
|
||||
export const resultWithAnswersInputSchema = resultSchema.merge(
|
||||
z.object({
|
||||
answers: z.array(answerInputSchema),
|
||||
})
|
||||
)
|
||||
|
||||
export const logSchema = z.object({
|
||||
id: z.string(),
|
||||
createdAt: z.date(),
|
||||
resultId: z.string(),
|
||||
status: z.string(),
|
||||
description: z.string(),
|
||||
details: z.string().nullable(),
|
||||
}) satisfies z.ZodType<LogPrisma>
|
||||
|
||||
export type Result = z.infer<typeof resultSchema>
|
||||
export type ResultWithAnswers = z.infer<typeof resultWithAnswersSchema>
|
||||
export type ResultWithAnswersInput = z.infer<
|
||||
typeof resultWithAnswersInputSchema
|
||||
>
|
||||
export type Log = z.infer<typeof logSchema>
|
||||
|
||||
export type ResultValuesInput = Pick<
|
||||
ResultWithAnswersInput,
|
||||
'answers' | 'createdAt' | 'variables'
|
||||
>
|
||||
|
||||
export type ResultValues = Pick<
|
||||
ResultWithAnswers,
|
||||
'answers' | 'createdAt' | 'variables'
|
||||
>
|
||||
|
||||
export type ResultHeaderCell = {
|
||||
id: string
|
||||
label: string
|
||||
blocks?: {
|
||||
id: string
|
||||
groupId: string
|
||||
}[]
|
||||
blockType?: InputBlockType
|
||||
variableIds?: string[]
|
||||
}
|
90
packages/schemas/features/telemetry.ts
Normal file
90
packages/schemas/features/telemetry.ts
Normal file
@ -0,0 +1,90 @@
|
||||
import { Plan } from '@typebot.io/prisma'
|
||||
import { z } from 'zod'
|
||||
|
||||
const userEvent = z.object({
|
||||
userId: z.string(),
|
||||
})
|
||||
|
||||
const workspaceEvent = userEvent.merge(
|
||||
z.object({
|
||||
workspaceId: z.string(),
|
||||
})
|
||||
)
|
||||
|
||||
const typebotEvent = workspaceEvent.merge(
|
||||
z.object({
|
||||
typebotId: z.string(),
|
||||
})
|
||||
)
|
||||
|
||||
const workspaceCreatedEventSchema = workspaceEvent.merge(
|
||||
z.object({
|
||||
name: z.literal('Workspace created'),
|
||||
data: z.object({
|
||||
name: z.string().optional(),
|
||||
plan: z.nativeEnum(Plan),
|
||||
}),
|
||||
})
|
||||
)
|
||||
|
||||
const userCreatedEventSchema = userEvent.merge(
|
||||
z.object({
|
||||
name: z.literal('User created'),
|
||||
data: z.object({
|
||||
email: z.string(),
|
||||
name: z.string().optional(),
|
||||
}),
|
||||
})
|
||||
)
|
||||
|
||||
const typebotCreatedEventSchema = typebotEvent.merge(
|
||||
z.object({
|
||||
name: z.literal('Typebot created'),
|
||||
data: z.object({
|
||||
name: z.string(),
|
||||
template: z.string().optional(),
|
||||
}),
|
||||
})
|
||||
)
|
||||
|
||||
const publishedTypebotEventSchema = typebotEvent.merge(
|
||||
z.object({
|
||||
name: z.literal('Typebot published'),
|
||||
data: z.object({
|
||||
name: z.string(),
|
||||
isFirstPublish: z.literal(true).optional(),
|
||||
}),
|
||||
})
|
||||
)
|
||||
|
||||
const subscriptionUpdatedEventSchema = workspaceEvent.merge(
|
||||
z.object({
|
||||
name: z.literal('Subscription updated'),
|
||||
data: z.object({
|
||||
plan: z.nativeEnum(Plan),
|
||||
additionalChatsIndex: z.number(),
|
||||
additionalStorageIndex: z.number(),
|
||||
}),
|
||||
})
|
||||
)
|
||||
|
||||
const newResultsCollectedEventSchema = typebotEvent.merge(
|
||||
z.object({
|
||||
name: z.literal('New results collected'),
|
||||
data: z.object({
|
||||
total: z.number(),
|
||||
isFirstOfKind: z.literal(true).optional(),
|
||||
}),
|
||||
})
|
||||
)
|
||||
|
||||
export const eventSchema = z.discriminatedUnion('name', [
|
||||
workspaceCreatedEventSchema,
|
||||
userCreatedEventSchema,
|
||||
typebotCreatedEventSchema,
|
||||
publishedTypebotEventSchema,
|
||||
subscriptionUpdatedEventSchema,
|
||||
newResultsCollectedEventSchema,
|
||||
])
|
||||
|
||||
export type TelemetryEvent = z.infer<typeof eventSchema>
|
4
packages/schemas/features/typebot/index.ts
Normal file
4
packages/schemas/features/typebot/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export * from './typebot'
|
||||
export * from './theme'
|
||||
export * from './settings'
|
||||
export * from './variable'
|
49
packages/schemas/features/typebot/settings.ts
Normal file
49
packages/schemas/features/typebot/settings.ts
Normal file
@ -0,0 +1,49 @@
|
||||
import { z } from 'zod'
|
||||
|
||||
const generalSettings = z.object({
|
||||
isBrandingEnabled: z.boolean(),
|
||||
isTypingEmulationEnabled: z.boolean().optional(),
|
||||
isInputPrefillEnabled: z.boolean().optional(),
|
||||
isHideQueryParamsEnabled: z.boolean().optional(),
|
||||
isNewResultOnRefreshEnabled: z.boolean().optional(),
|
||||
})
|
||||
|
||||
const typingEmulation = z.object({
|
||||
enabled: z.boolean(),
|
||||
speed: z.number(),
|
||||
maxDelay: z.number(),
|
||||
})
|
||||
|
||||
const metadataSchema = z.object({
|
||||
title: z.string().optional(),
|
||||
description: z.string().optional(),
|
||||
imageUrl: z.string().optional(),
|
||||
favIconUrl: z.string().optional(),
|
||||
customHeadCode: z.string().optional(),
|
||||
googleTagManagerId: z.string().optional(),
|
||||
})
|
||||
|
||||
export const settingsSchema = z.object({
|
||||
general: generalSettings,
|
||||
typingEmulation: typingEmulation,
|
||||
metadata: metadataSchema,
|
||||
})
|
||||
|
||||
export const defaultSettings: Settings = {
|
||||
general: {
|
||||
isBrandingEnabled: true,
|
||||
isNewResultOnRefreshEnabled: true,
|
||||
isInputPrefillEnabled: true,
|
||||
isHideQueryParamsEnabled: true,
|
||||
},
|
||||
typingEmulation: { enabled: true, speed: 300, maxDelay: 1.5 },
|
||||
metadata: {
|
||||
description:
|
||||
'Build beautiful conversational forms and embed them directly in your applications without a line of code. Triple your response rate and collect answers that has more value compared to a traditional form.',
|
||||
},
|
||||
}
|
||||
|
||||
export type Settings = z.infer<typeof settingsSchema>
|
||||
export type GeneralSettings = z.infer<typeof generalSettings>
|
||||
export type TypingEmulation = z.infer<typeof typingEmulation>
|
||||
export type Metadata = z.infer<typeof metadataSchema>
|
5
packages/schemas/features/typebot/theme/enums.ts
Normal file
5
packages/schemas/features/typebot/theme/enums.ts
Normal file
@ -0,0 +1,5 @@
|
||||
export enum BackgroundType {
|
||||
COLOR = 'Color',
|
||||
IMAGE = 'Image',
|
||||
NONE = 'None',
|
||||
}
|
2
packages/schemas/features/typebot/theme/index.ts
Normal file
2
packages/schemas/features/typebot/theme/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './enums'
|
||||
export * from './schemas'
|
68
packages/schemas/features/typebot/theme/schemas.ts
Normal file
68
packages/schemas/features/typebot/theme/schemas.ts
Normal file
@ -0,0 +1,68 @@
|
||||
import { z } from 'zod'
|
||||
import { BackgroundType } from './enums'
|
||||
|
||||
const avatarPropsSchema = z.object({
|
||||
isEnabled: z.boolean(),
|
||||
url: z.string().optional(),
|
||||
})
|
||||
|
||||
const containerColorsSchema = z.object({
|
||||
backgroundColor: z.string(),
|
||||
color: z.string(),
|
||||
})
|
||||
|
||||
const inputColorsSchema = containerColorsSchema.merge(
|
||||
z.object({
|
||||
placeholderColor: z.string(),
|
||||
})
|
||||
)
|
||||
|
||||
export const chatThemeSchema = z.object({
|
||||
hostAvatar: avatarPropsSchema.optional(),
|
||||
guestAvatar: avatarPropsSchema.optional(),
|
||||
hostBubbles: containerColorsSchema,
|
||||
guestBubbles: containerColorsSchema,
|
||||
buttons: containerColorsSchema,
|
||||
inputs: inputColorsSchema,
|
||||
})
|
||||
|
||||
const backgroundSchema = z.object({
|
||||
type: z.nativeEnum(BackgroundType),
|
||||
content: z.string().optional(),
|
||||
})
|
||||
|
||||
const generalThemeSchema = z.object({
|
||||
font: z.string(),
|
||||
background: backgroundSchema,
|
||||
})
|
||||
|
||||
export const themeSchema = z.object({
|
||||
general: generalThemeSchema,
|
||||
chat: chatThemeSchema,
|
||||
customCss: z.string().optional(),
|
||||
})
|
||||
|
||||
export const defaultTheme: Theme = {
|
||||
chat: {
|
||||
hostBubbles: { backgroundColor: '#F7F8FF', color: '#303235' },
|
||||
guestBubbles: { backgroundColor: '#FF8E21', color: '#FFFFFF' },
|
||||
buttons: { backgroundColor: '#0042DA', color: '#FFFFFF' },
|
||||
inputs: {
|
||||
backgroundColor: '#FFFFFF',
|
||||
color: '#303235',
|
||||
placeholderColor: '#9095A0',
|
||||
},
|
||||
},
|
||||
general: {
|
||||
font: 'Open Sans',
|
||||
background: { type: BackgroundType.COLOR, content: '#ffffff' },
|
||||
},
|
||||
}
|
||||
|
||||
export type Theme = z.infer<typeof themeSchema>
|
||||
export type ChatTheme = z.infer<typeof chatThemeSchema>
|
||||
export type AvatarProps = z.infer<typeof avatarPropsSchema>
|
||||
export type GeneralTheme = z.infer<typeof generalThemeSchema>
|
||||
export type Background = z.infer<typeof backgroundSchema>
|
||||
export type ContainerColors = z.infer<typeof containerColorsSchema>
|
||||
export type InputColors = z.infer<typeof inputColorsSchema>
|
69
packages/schemas/features/typebot/typebot.ts
Normal file
69
packages/schemas/features/typebot/typebot.ts
Normal file
@ -0,0 +1,69 @@
|
||||
import { z } from 'zod'
|
||||
import { settingsSchema } from './settings'
|
||||
import { themeSchema } from './theme'
|
||||
import { variableSchema } from './variable'
|
||||
import { Typebot as TypebotPrisma } from '@typebot.io/prisma'
|
||||
import { blockSchema } from '../blocks/schemas'
|
||||
|
||||
export const groupSchema = z.object({
|
||||
id: z.string(),
|
||||
title: z.string(),
|
||||
graphCoordinates: z.object({
|
||||
x: z.number(),
|
||||
y: z.number(),
|
||||
}),
|
||||
blocks: z.array(blockSchema),
|
||||
})
|
||||
|
||||
const sourceSchema = z.object({
|
||||
groupId: z.string(),
|
||||
blockId: z.string(),
|
||||
itemId: z.string().optional(),
|
||||
})
|
||||
|
||||
const targetSchema = z.object({
|
||||
groupId: z.string(),
|
||||
blockId: z.string().optional(),
|
||||
})
|
||||
|
||||
export const edgeSchema = z.object({
|
||||
id: z.string(),
|
||||
from: sourceSchema,
|
||||
to: targetSchema,
|
||||
})
|
||||
|
||||
const resultsTablePreferencesSchema = z.object({
|
||||
columnsOrder: z.array(z.string()),
|
||||
columnsVisibility: z.record(z.string(), z.boolean()),
|
||||
columnsWidth: z.record(z.string(), z.number()),
|
||||
})
|
||||
|
||||
export const typebotSchema = z.object({
|
||||
version: z.enum(['3']).nullable(),
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
groups: z.array(groupSchema),
|
||||
edges: z.array(edgeSchema),
|
||||
variables: z.array(variableSchema),
|
||||
theme: themeSchema,
|
||||
settings: settingsSchema,
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
icon: z.string().nullable(),
|
||||
folderId: z.string().nullable(),
|
||||
publicId: z.string().nullable(),
|
||||
customDomain: z.string().nullable(),
|
||||
workspaceId: z.string(),
|
||||
resultsTablePreferences: resultsTablePreferencesSchema.nullable(),
|
||||
isArchived: z.boolean(),
|
||||
isClosed: z.boolean(),
|
||||
}) satisfies z.ZodType<TypebotPrisma>
|
||||
|
||||
export type Typebot = z.infer<typeof typebotSchema>
|
||||
export type Target = z.infer<typeof targetSchema>
|
||||
export type Source = z.infer<typeof sourceSchema>
|
||||
export type Edge = z.infer<typeof edgeSchema>
|
||||
export type Group = z.infer<typeof groupSchema>
|
||||
export type ResultsTablePreferences = z.infer<
|
||||
typeof resultsTablePreferencesSchema
|
||||
>
|
31
packages/schemas/features/typebot/variable.ts
Normal file
31
packages/schemas/features/typebot/variable.ts
Normal file
@ -0,0 +1,31 @@
|
||||
import { z } from 'zod'
|
||||
|
||||
export const variableSchema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
value: z.string().or(z.array(z.string())).nullish(),
|
||||
})
|
||||
|
||||
/**
|
||||
* Variable when retrieved from the database
|
||||
*/
|
||||
export const variableWithValueSchema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
value: z.string().or(z.array(z.string())),
|
||||
})
|
||||
|
||||
/**
|
||||
* Variable when computed or retrieved from a block
|
||||
*/
|
||||
const VariableWithUnknowValueSchema = z.object({
|
||||
id: z.string(),
|
||||
name: z.string(),
|
||||
value: z.unknown(),
|
||||
})
|
||||
|
||||
export type Variable = z.infer<typeof variableSchema>
|
||||
export type VariableWithValue = z.infer<typeof variableWithValueSchema>
|
||||
export type VariableWithUnknowValue = z.infer<
|
||||
typeof VariableWithUnknowValueSchema
|
||||
>
|
9
packages/schemas/features/utils.ts
Normal file
9
packages/schemas/features/utils.ts
Normal file
@ -0,0 +1,9 @@
|
||||
import { z } from 'zod'
|
||||
|
||||
export type IdMap<T> = { [id: string]: T }
|
||||
|
||||
export const variableStringSchema = z.custom<`{{${string}}}`>((val) =>
|
||||
/^{{.+}}$/g.test(val as string)
|
||||
)
|
||||
|
||||
export type VariableString = z.infer<typeof variableStringSchema>
|
38
packages/schemas/features/webhooks.ts
Normal file
38
packages/schemas/features/webhooks.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import { Webhook as WebhookFromPrisma } from '@typebot.io/prisma'
|
||||
|
||||
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: [],
|
||||
}
|
55
packages/schemas/features/workspace.ts
Normal file
55
packages/schemas/features/workspace.ts
Normal file
@ -0,0 +1,55 @@
|
||||
import { z } from 'zod'
|
||||
import {
|
||||
Workspace as WorkspacePrisma,
|
||||
Plan,
|
||||
MemberInWorkspace as MemberInWorkspacePrisma,
|
||||
WorkspaceRole,
|
||||
User as UserPrisma,
|
||||
WorkspaceInvitation as WorkspaceInvitationPrisma,
|
||||
} from '@typebot.io/prisma'
|
||||
|
||||
export const workspaceMemberSchema = z.object({
|
||||
workspaceId: z.string(),
|
||||
user: z.object({
|
||||
name: z.string().nullable(),
|
||||
email: z.string().nullable(),
|
||||
image: z.string().nullable(),
|
||||
}),
|
||||
role: z.nativeEnum(WorkspaceRole),
|
||||
}) satisfies z.ZodType<
|
||||
Omit<MemberInWorkspacePrisma, 'userId' | 'createdAt' | 'updatedAt'> & {
|
||||
user: Pick<UserPrisma, 'name' | 'email' | 'image'>
|
||||
}
|
||||
>
|
||||
|
||||
export const workspaceInvitationSchema = z.object({
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
email: z.string(),
|
||||
type: z.nativeEnum(WorkspaceRole),
|
||||
}) satisfies z.ZodType<
|
||||
Omit<WorkspaceInvitationPrisma, 'workspaceId' | 'userId' | 'id'>
|
||||
>
|
||||
|
||||
export const workspaceSchema = z.object({
|
||||
id: z.string(),
|
||||
createdAt: z.date(),
|
||||
updatedAt: z.date(),
|
||||
name: z.string(),
|
||||
icon: z.string().nullable(),
|
||||
plan: z.nativeEnum(Plan),
|
||||
stripeId: z.string().nullable(),
|
||||
additionalChatsIndex: z.number(),
|
||||
additionalStorageIndex: z.number(),
|
||||
chatsLimitFirstEmailSentAt: z.date().nullable(),
|
||||
chatsLimitSecondEmailSentAt: z.date().nullable(),
|
||||
storageLimitFirstEmailSentAt: z.date().nullable(),
|
||||
storageLimitSecondEmailSentAt: z.date().nullable(),
|
||||
customChatsLimit: z.number().nullable(),
|
||||
customStorageLimit: z.number().nullable(),
|
||||
customSeatsLimit: z.number().nullable(),
|
||||
}) satisfies z.ZodType<WorkspacePrisma>
|
||||
|
||||
export type Workspace = z.infer<typeof workspaceSchema>
|
||||
export type WorkspaceMember = z.infer<typeof workspaceMemberSchema>
|
||||
export type WorkspaceInvitation = z.infer<typeof workspaceInvitationSchema>
|
Reference in New Issue
Block a user