⚡ (engine) Improve engine overall robustness
This commit is contained in:
37
packages/models/features/blocks/inputs/choice.ts
Normal file
37
packages/models/features/blocks/inputs/choice.ts
Normal file
@ -0,0 +1,37 @@
|
||||
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.and(
|
||||
z.object({
|
||||
isMultipleChoice: z.boolean(),
|
||||
buttonLabel: z.string(),
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultChoiceInputOptions: ChoiceInputOptions = {
|
||||
buttonLabel: defaultButtonLabel,
|
||||
isMultipleChoice: false,
|
||||
}
|
||||
|
||||
export const buttonItemSchema = itemBaseSchema.and(
|
||||
z.object({
|
||||
type: z.literal(ItemType.BUTTON),
|
||||
content: z.string().optional(),
|
||||
})
|
||||
)
|
||||
|
||||
export const choiceInputSchema = blockBaseSchema.and(
|
||||
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/models/features/blocks/inputs/constants.ts
Normal file
1
packages/models/features/blocks/inputs/constants.ts
Normal file
@ -0,0 +1 @@
|
||||
export const defaultButtonLabel = 'Send'
|
32
packages/models/features/blocks/inputs/date.ts
Normal file
32
packages/models/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.and(
|
||||
z.object({
|
||||
labels: z.object({
|
||||
button: z.string(),
|
||||
from: z.string(),
|
||||
to: z.string(),
|
||||
}),
|
||||
hasTime: z.boolean(),
|
||||
isRange: z.boolean(),
|
||||
})
|
||||
)
|
||||
|
||||
export const dateInputSchema = blockBaseSchema.and(
|
||||
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/models/features/blocks/inputs/email.ts
Normal file
32
packages/models/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
|
||||
.and(textInputOptionsBaseSchema)
|
||||
.and(
|
||||
z.object({
|
||||
retryMessageContent: z.string(),
|
||||
})
|
||||
)
|
||||
|
||||
export const emailInputSchema = blockBaseSchema.and(
|
||||
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/models/features/blocks/inputs/enums.ts
Normal file
12
packages/models/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/models/features/blocks/inputs/file.ts
Normal file
41
packages/models/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.and(
|
||||
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.and(
|
||||
z.object({
|
||||
type: z.literal(InputBlockType.FILE),
|
||||
options: fileInputOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultFileInputOptions: FileInputOptions = {
|
||||
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',
|
||||
},
|
||||
}
|
||||
|
||||
export type FileInputBlock = z.infer<typeof fileInputStepSchema>
|
||||
export type FileInputOptions = z.infer<typeof fileInputOptionsSchema>
|
13
packages/models/features/blocks/inputs/index.ts
Normal file
13
packages/models/features/blocks/inputs/index.ts
Normal file
@ -0,0 +1,13 @@
|
||||
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 './schemas'
|
||||
export * from './text'
|
||||
export * from './url'
|
29
packages/models/features/blocks/inputs/number.ts
Normal file
29
packages/models/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
|
||||
.and(textInputOptionsBaseSchema)
|
||||
.and(
|
||||
z.object({
|
||||
min: z.number().optional(),
|
||||
max: z.number().optional(),
|
||||
step: z.number().optional(),
|
||||
})
|
||||
)
|
||||
|
||||
export const numberInputSchema = blockBaseSchema.and(
|
||||
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/models/features/blocks/inputs/payment/enums.ts
Normal file
3
packages/models/features/blocks/inputs/payment/enums.ts
Normal file
@ -0,0 +1,3 @@
|
||||
export enum PaymentProvider {
|
||||
STRIPE = 'Stripe',
|
||||
}
|
2
packages/models/features/blocks/inputs/payment/index.ts
Normal file
2
packages/models/features/blocks/inputs/payment/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './enums'
|
||||
export * from './schemas'
|
56
packages/models/features/blocks/inputs/payment/schemas.ts
Normal file
56
packages/models/features/blocks/inputs/payment/schemas.ts
Normal file
@ -0,0 +1,56 @@
|
||||
import { z } from 'zod'
|
||||
import { optionBaseSchema, blockBaseSchema } 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.and(
|
||||
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.and(
|
||||
z.object({
|
||||
type: z.enum([InputBlockType.PAYMENT]),
|
||||
options: paymentInputOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
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
|
||||
>
|
35
packages/models/features/blocks/inputs/phone.ts
Normal file
35
packages/models/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
|
||||
.and(textInputOptionsBaseSchema)
|
||||
.and(
|
||||
z.object({
|
||||
retryMessageContent: z.string(),
|
||||
defaultCountryCode: z.string().optional(),
|
||||
})
|
||||
)
|
||||
|
||||
export const phoneNumberInputBlockSchema = blockBaseSchema.and(
|
||||
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/models/features/blocks/inputs/rating.ts
Normal file
38
packages/models/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.and(
|
||||
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.and(
|
||||
z.object({
|
||||
type: z.literal(InputBlockType.RATING),
|
||||
options: ratingInputOptionsSchema,
|
||||
})
|
||||
)
|
||||
|
||||
export type RatingInputBlock = z.infer<typeof ratingInputBlockSchema>
|
||||
export type RatingInputOptions = z.infer<typeof ratingInputOptionsSchema>
|
42
packages/models/features/blocks/inputs/schemas.ts
Normal file
42
packages/models/features/blocks/inputs/schemas.ts
Normal file
@ -0,0 +1,42 @@
|
||||
import { z } from 'zod'
|
||||
import { choiceInputOptionsSchema, choiceInputSchema } from './choice'
|
||||
import { dateInputOptionsSchema, dateInputSchema } from './date'
|
||||
import { emailInputOptionsSchema, emailInputSchema } from './email'
|
||||
import { numberInputOptionsSchema, numberInputSchema } from './number'
|
||||
import { paymentInputOptionsSchema, paymentInputSchema } from './payment'
|
||||
import {
|
||||
phoneNumberInputOptionsSchema,
|
||||
phoneNumberInputBlockSchema,
|
||||
} from './phone'
|
||||
import { ratingInputOptionsSchema, ratingInputBlockSchema } from './rating'
|
||||
import { textInputOptionsSchema, textInputSchema } from './text'
|
||||
import { fileInputOptionsSchema, fileInputStepSchema } from './file'
|
||||
import { urlInputOptionsSchema, urlInputSchema } from './url'
|
||||
import { optionBaseSchema } from '../baseSchemas'
|
||||
|
||||
export type OptionBase = z.infer<typeof optionBaseSchema>
|
||||
|
||||
export const inputBlockOptionsSchema = textInputOptionsSchema
|
||||
.or(choiceInputOptionsSchema)
|
||||
.or(emailInputOptionsSchema)
|
||||
.or(numberInputOptionsSchema)
|
||||
.or(urlInputOptionsSchema)
|
||||
.or(phoneNumberInputOptionsSchema)
|
||||
.or(dateInputOptionsSchema)
|
||||
.or(paymentInputOptionsSchema)
|
||||
.or(ratingInputOptionsSchema)
|
||||
.or(fileInputOptionsSchema)
|
||||
|
||||
export const inputBlockSchema = textInputSchema
|
||||
.or(numberInputSchema)
|
||||
.or(emailInputSchema)
|
||||
.or(urlInputSchema)
|
||||
.or(dateInputSchema)
|
||||
.or(phoneNumberInputBlockSchema)
|
||||
.or(choiceInputSchema)
|
||||
.or(paymentInputSchema)
|
||||
.or(ratingInputBlockSchema)
|
||||
.or(fileInputStepSchema)
|
||||
|
||||
export type InputBlock = z.infer<typeof inputBlockSchema>
|
||||
export type InputBlockOptions = z.infer<typeof inputBlockOptionsSchema>
|
34
packages/models/features/blocks/inputs/text.ts
Normal file
34
packages/models/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
|
||||
.and(optionBaseSchema)
|
||||
.and(
|
||||
z.object({
|
||||
isLong: z.boolean(),
|
||||
})
|
||||
)
|
||||
|
||||
export const defaultTextInputOptions: TextInputOptions = {
|
||||
isLong: false,
|
||||
labels: { button: defaultButtonLabel, placeholder: 'Type your answer...' },
|
||||
}
|
||||
|
||||
export const textInputSchema = blockBaseSchema.and(
|
||||
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/models/features/blocks/inputs/url.ts
Normal file
32
packages/models/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
|
||||
.and(textInputOptionsBaseSchema)
|
||||
.and(
|
||||
z.object({
|
||||
retryMessageContent: z.string(),
|
||||
})
|
||||
)
|
||||
|
||||
export const urlInputSchema = blockBaseSchema.and(
|
||||
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>
|
Reference in New Issue
Block a user