♻️ Include forged blocks schema in typebot schema

Closes #1364
This commit is contained in:
Baptiste Arnaud
2024-03-18 16:09:19 +01:00
parent 26a9282c20
commit ed5096e2b6
93 changed files with 8599 additions and 4965 deletions

View File

@@ -36,13 +36,14 @@ import { defaultPictureChoiceOptions } from '@typebot.io/schemas/features/blocks
import { defaultFileInputOptions } from '@typebot.io/schemas/features/blocks/inputs/file/constants'
import { VisitedEdge } from '@typebot.io/prisma'
import { getBlockById } from '@typebot.io/schemas/helpers'
import { ForgedBlock, forgedBlocks } from '@typebot.io/forge-schemas'
import { enabledBlocks } from '@typebot.io/forge-repository'
import { ForgedBlock } from '@typebot.io/forge-repository/types'
import { forgedBlocks } from '@typebot.io/forge-repository/definitions'
import { resumeChatCompletion } from './blocks/integrations/legacy/openai/resumeChatCompletion'
import { env } from '@typebot.io/env'
import { downloadMedia } from './whatsapp/downloadMedia'
import { uploadFileToBucket } from '@typebot.io/lib/s3/uploadFileToBucket'
import { isURL } from '@typebot.io/lib/validators/isURL'
import { isForgedBlockType } from '@typebot.io/schemas/features/blocks/forged/helpers'
type Params = {
version: 1 | 2
@@ -111,14 +112,12 @@ export const continueBotFlow = async (
response: JSON.parse(reply),
})
if (result.newSessionState) newSessionState = result.newSessionState
} else if (
enabledBlocks.includes(block.type as (typeof enabledBlocks)[number])
) {
} else if (isForgedBlockType(block.type)) {
if (reply) {
const options = (block as ForgedBlock).options
const action = forgedBlocks
.find((b) => b.id === block.type)
?.actions.find((a) => a.name === options?.action)
const action = forgedBlocks[block.type].actions.find(
(a) => a.name === options?.action
)
if (action) {
if (action.run?.stream?.getStreamVariableId) {
firstBubbleWasStreamed = true

View File

@@ -1,5 +1,6 @@
import { VariableStore, LogsStore } from '@typebot.io/forge'
import { ForgedBlock, forgedBlocks } from '@typebot.io/forge-schemas'
import { forgedBlocks } from '@typebot.io/forge-repository/definitions'
import { ForgedBlock } from '@typebot.io/forge-repository/types'
import { decrypt } from '@typebot.io/lib/api/encryption/decrypt'
import { isPlaneteScale } from '@typebot.io/lib/isPlanetScale'
import prisma from '@typebot.io/lib/prisma'
@@ -23,7 +24,7 @@ export const executeForgedBlock = async (
state: SessionState,
block: ForgedBlock
): Promise<ExecuteIntegrationResponse> => {
const blockDef = forgedBlocks.find((b) => b.id === block.type)
const blockDef = forgedBlocks[block.type]
if (!blockDef) return { outgoingEdgeId: block.outgoingEdgeId }
const action = blockDef.actions.find((a) => a.name === block.options.action)
const noCredentialsError = {

View File

@@ -36,7 +36,6 @@
"devDependencies": {
"@typebot.io/forge": "workspace:*",
"@typebot.io/forge-repository": "workspace:*",
"@typebot.io/forge-schemas": "workspace:*",
"@types/nodemailer": "6.4.8",
"@types/qs": "6.9.7"
}

View File

@@ -26,7 +26,6 @@
"@rollup/plugin-babel": "6.0.3",
"@rollup/plugin-node-resolve": "15.1.0",
"@rollup/plugin-terser": "0.4.3",
"@rollup/plugin-typescript": "11.1.2",
"@typebot.io/bot-engine": "workspace:*",
"@typebot.io/env": "workspace:*",
"@typebot.io/lib": "workspace:*",

View File

@@ -4,11 +4,15 @@ import { babel } from '@rollup/plugin-babel'
import postcss from 'rollup-plugin-postcss'
import autoprefixer from 'autoprefixer'
import tailwindcss from 'tailwindcss'
import typescript from '@rollup/plugin-typescript'
import { typescriptPaths } from 'rollup-plugin-typescript-paths'
import fs from 'fs'
const extensions = ['.ts', '.tsx']
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'))
const packageVersion = packageJson.version
const preamble = `// v${packageVersion}`
const indexConfig = {
input: './src/index.ts',
output: {
@@ -23,6 +27,7 @@ const indexConfig = {
presets: ['solid', '@babel/preset-typescript'],
extensions,
}),
typescriptPaths({ preserveExtensions: true }),
postcss({
plugins: [autoprefixer(), tailwindcss()],
extract: false,
@@ -31,9 +36,9 @@ const indexConfig = {
minimize: true,
inject: false,
}),
typescript(),
typescriptPaths({ preserveExtensions: true }),
terser({ output: { comments: false } }),
terser({
format: { preamble },
}),
],
}

View File

@@ -15,8 +15,7 @@ import {
} from '@/utils/storage'
import { setCssVariablesValue } from '@/utils/setCssVariablesValue'
import immutableCss from '../assets/immutable.css'
import { Font, InputBlock } from '@typebot.io/schemas'
import { StartFrom } from '@typebot.io/schemas'
import { Font, InputBlock, StartFrom } from '@typebot.io/schemas'
import { defaultTheme } from '@typebot.io/schemas/features/typebot/theme/constants'
import { clsx } from 'clsx'
import { HTTPError } from 'ky'

View File

@@ -20,7 +20,6 @@
"@rollup/plugin-babel": "6.0.3",
"@rollup/plugin-node-resolve": "15.1.0",
"@rollup/plugin-terser": "0.4.3",
"@rollup/plugin-typescript": "11.1.2",
"@typebot.io/js": "workspace:*",
"@typebot.io/lib": "workspace:*",
"@typebot.io/prisma": "workspace:*",

View File

@@ -1,11 +1,15 @@
import resolve from '@rollup/plugin-node-resolve'
import terser from '@rollup/plugin-terser'
import { babel } from '@rollup/plugin-babel'
import typescript from '@rollup/plugin-typescript'
import { typescriptPaths } from 'rollup-plugin-typescript-paths'
import fs from 'fs'
const extensions = ['.ts', '.tsx']
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'))
const packageVersion = packageJson.version
const preamble = `// v${packageVersion}`
const indexConfig = {
input: './src/index.ts',
output: {
@@ -21,9 +25,8 @@ const indexConfig = {
presets: ['@babel/preset-react', '@babel/preset-typescript'],
extensions,
}),
typescript(),
typescriptPaths({ preserveExtensions: true }),
terser({ output: { comments: false } }),
terser({ format: { preamble } }),
],
}

View File

@@ -25,7 +25,6 @@
"@rollup/plugin-babel": "6.0.3",
"@rollup/plugin-node-resolve": "15.1.0",
"@rollup/plugin-terser": "0.4.3",
"@rollup/plugin-typescript": "11.1.2",
"@typebot.io/js": "workspace:*",
"@typebot.io/lib": "workspace:*",
"@typebot.io/prisma": "workspace:*",

View File

@@ -1,11 +1,15 @@
import resolve from '@rollup/plugin-node-resolve'
import terser from '@rollup/plugin-terser'
import { babel } from '@rollup/plugin-babel'
import typescript from '@rollup/plugin-typescript'
import { typescriptPaths } from 'rollup-plugin-typescript-paths'
import fs from 'fs'
const extensions = ['.ts', '.tsx']
const packageJson = JSON.parse(fs.readFileSync('package.json', 'utf8'))
const packageVersion = packageJson.version
const preamble = `// v${packageVersion}`
const indexConfig = {
input: './src/index.ts',
output: {
@@ -21,9 +25,8 @@ const indexConfig = {
presets: ['@babel/preset-react', '@babel/preset-typescript'],
extensions,
}),
typescript(),
typescriptPaths({ preserveExtensions: true }),
terser({ output: { comments: false } }),
terser({ format: { preamble } }),
],
}

View File

@@ -90,15 +90,15 @@ export const createChatMessage = createAction({
options,
turnableInto: [
{
blockType: 'mistral',
blockId: 'mistral',
transform: transformToChatCompletionOptions,
},
{
blockType: 'openai',
blockId: 'openai',
transform: transformToChatCompletionOptions,
},
{ blockType: 'open-router', transform: transformToChatCompletionOptions },
{ blockType: 'together-ai', transform: transformToChatCompletionOptions },
{ blockId: 'open-router', transform: transformToChatCompletionOptions },
{ blockId: 'together-ai', transform: transformToChatCompletionOptions },
],
getSetVariableIds: ({ responseMapping }) =>
responseMapping?.map((res) => res.variableId).filter(isDefined) ?? [],

View File

@@ -3,7 +3,7 @@ import { AnthropicLogo } from './logo'
import { auth } from './auth'
import { createChatMessage } from './actions/createChatMessage'
export const anthropic = createBlock({
export const anthropicBlock = createBlock({
id: 'anthropic',
name: 'Anthropic',
tags: ['ai', 'chat', 'completion', 'claude', 'anthropic'],

View File

@@ -0,0 +1,6 @@
// Do not edit this file manually
import { parseBlockCredentials, parseBlockSchema } from '@typebot.io/forge'
import { anthropicBlock } from '.'
export const anthropicBlockSchema = parseBlockSchema(anthropicBlock)
export const anthropicCredentialsSchema = parseBlockCredentials(anthropicBlock)

View File

@@ -3,7 +3,7 @@ import { CalComLogo } from './logo'
import { bookEvent } from './actions/bookEvent'
import { baseOptions } from './baseOptions'
export const calCom = createBlock({
export const calComBlock = createBlock({
id: 'cal-com',
name: 'Cal.com',
tags: ['calendar', 'scheduling', 'meetings'],

View File

@@ -0,0 +1,6 @@
// Do not edit this file manually
import { parseBlockCredentials, parseBlockSchema } from '@typebot.io/forge'
import { calComBlock } from '.'
export const calComBlockSchema = parseBlockSchema(calComBlock)
export const calComCredentialsSchema = parseBlockCredentials(calComBlock)

View File

@@ -3,7 +3,7 @@ import { ChatNodeLogo } from './logo'
import { auth } from './auth'
import { sendMessage } from './actions/sendMessage'
export const chatNode = createBlock({
export const chatNodeBlock = createBlock({
id: 'chat-node',
name: 'ChatNode',
tags: ['ai', 'openai', 'document', 'url'],

View File

@@ -0,0 +1,6 @@
// Do not edit this file manually
import { parseBlockCredentials, parseBlockSchema } from '@typebot.io/forge'
import { chatNodeBlock } from '.'
export const chatNodeBlockSchema = parseBlockSchema(chatNodeBlock)
export const chatNodeCredentialsSchema = parseBlockCredentials(chatNodeBlock)

View File

@@ -3,7 +3,7 @@ import { DifyAiLogo } from './logo'
import { auth } from './auth'
import { createChatMessage } from './actions/createChatMessage'
export const difyAi = createBlock({
export const difyAiBlock = createBlock({
id: 'dify-ai',
name: 'Dify.AI',
tags: ['dify', 'ai', 'documents', 'files', 'knowledge base'],

View File

@@ -0,0 +1,6 @@
// Do not edit this file manually
import { parseBlockCredentials, parseBlockSchema } from '@typebot.io/forge'
import { difyAiBlock } from '.'
export const difyAiBlockSchema = parseBlockSchema(difyAiBlock)
export const difyAiCredentialsSchema = parseBlockCredentials(difyAiBlock)

View File

@@ -3,7 +3,7 @@ import { ElevenlabsLogo, ElevenlabsLogoDark } from './logo'
import { auth } from './auth'
import { convertTextToSpeech } from './actions/convertTextToSpeech'
export const elevenlabs = createBlock({
export const elevenlabsBlock = createBlock({
id: 'elevenlabs',
name: 'ElevenLabs',
tags: ['ai', 'voice', 'generation'],

View File

@@ -0,0 +1,7 @@
// Do not edit this file manually
import { parseBlockCredentials, parseBlockSchema } from '@typebot.io/forge'
import { elevenlabsBlock } from '.'
export const elevenlabsBlockSchema = parseBlockSchema(elevenlabsBlock)
export const elevenlabsCredentialsSchema =
parseBlockCredentials(elevenlabsBlock)

View File

@@ -69,14 +69,14 @@ export const createChatCompletion = createAction({
options,
turnableInto: [
{
blockType: 'openai',
blockId: 'openai',
},
{
blockType: 'together-ai',
blockId: 'together-ai',
},
{ blockType: 'open-router' },
{ blockId: 'open-router' },
{
blockType: 'anthropic',
blockId: 'anthropic',
transform: (options) => ({
...options,
action: 'Create Chat Message',

View File

@@ -3,7 +3,7 @@ import { MistralLogo } from './logo'
import { auth } from './auth'
import { createChatCompletion } from './actions/createChatCompletion'
export const mistral = createBlock({
export const mistralBlock = createBlock({
id: 'mistral',
name: 'Mistral',
tags: ['ai', 'chat', 'completion'],

View File

@@ -0,0 +1,6 @@
// Do not edit this file manually
import { parseBlockCredentials, parseBlockSchema } from '@typebot.io/forge'
import { mistralBlock } from '.'
export const mistralBlockSchema = parseBlockSchema(mistralBlock)
export const mistralCredentialsSchema = parseBlockCredentials(mistralBlock)

View File

@@ -14,14 +14,14 @@ export const createChatCompletion = createAction({
auth,
turnableInto: [
{
blockType: 'openai',
blockId: 'openai',
},
{
blockType: 'together-ai',
blockId: 'together-ai',
},
{ blockType: 'mistral' },
{ blockId: 'mistral' },
{
blockType: 'anthropic',
blockId: 'anthropic',
transform: (options) => ({
...options,
action: 'Create Chat Message',

View File

@@ -3,7 +3,7 @@ import { OpenRouterLogo } from './logo'
import { auth } from './auth'
import { createChatCompletion } from './actions/createChatCompletion'
export const openRouter = createBlock({
export const openRouterBlock = createBlock({
id: 'open-router',
name: 'OpenRouter',
tags: ['ai', 'openai', 'chat', 'completion'],

View File

@@ -0,0 +1,7 @@
// Do not edit this file manually
import { parseBlockCredentials, parseBlockSchema } from '@typebot.io/forge'
import { openRouterBlock } from '.'
export const openRouterBlockSchema = parseBlockSchema(openRouterBlock)
export const openRouterCredentialsSchema =
parseBlockCredentials(openRouterBlock)

View File

@@ -21,14 +21,14 @@ export const createChatCompletion = createAction({
getSetVariableIds: getChatCompletionSetVarIds,
turnableInto: [
{
blockType: 'open-router',
blockId: 'open-router',
},
{
blockType: 'together-ai',
blockId: 'together-ai',
},
{ blockType: 'mistral' },
{ blockId: 'mistral' },
{
blockType: 'anthropic',
blockId: 'anthropic',
transform: (options) => ({
...options,
action: 'Create Chat Message',

View File

@@ -0,0 +1,6 @@
// Do not edit this file manually
import { parseBlockCredentials, parseBlockSchema } from '@typebot.io/forge'
import { openAIBlock } from '.'
export const openAIBlockSchema = parseBlockSchema(openAIBlock)
export const openAICredentialsSchema = parseBlockCredentials(openAIBlock)

View File

@@ -2,7 +2,7 @@ import { createBlock } from '@typebot.io/forge'
import { QrCodeLogo } from './logo'
import { generateQrCode } from './actions/generateQrCodeImage'
export const qrCode = createBlock({
export const qrCodeBlock = createBlock({
id: 'qr-code',
name: 'QR code',
tags: [],

View File

@@ -0,0 +1,6 @@
// Do not edit this file manually
import { parseBlockCredentials, parseBlockSchema } from '@typebot.io/forge'
import { qrCodeBlock } from '.'
export const qrCodeBlockSchema = parseBlockSchema(qrCodeBlock)
export const qrCodeCredentialsSchema = parseBlockCredentials(qrCodeBlock)

View File

@@ -16,14 +16,14 @@ export const createChatCompletion = createAction({
}),
turnableInto: [
{
blockType: 'openai',
blockId: 'openai',
},
{
blockType: 'open-router',
blockId: 'open-router',
},
{ blockType: 'mistral' },
{ blockId: 'mistral' },
{
blockType: 'anthropic',
blockId: 'anthropic',
transform: (options) => ({
...options,
action: 'Create Chat Message',

View File

@@ -3,7 +3,7 @@ import { TogetherAiLogo } from './logo'
import { auth } from './auth'
import { createChatCompletion } from './actions/createChatCompletion'
export const togetherAi = createBlock({
export const togetherAiBlock = createBlock({
id: 'together-ai',
name: 'Together',
fullName: 'Together AI',

View File

@@ -0,0 +1,7 @@
// Do not edit this file manually
import { parseBlockCredentials, parseBlockSchema } from '@typebot.io/forge'
import { togetherAiBlock } from '.'
export const togetherAiBlockSchema = parseBlockSchema(togetherAiBlock)
export const togetherAiCredentialsSchema =
parseBlockCredentials(togetherAiBlock)

View File

@@ -5,7 +5,7 @@ import { searchDocuments } from './actions/searchDocuments'
import { auth } from './auth'
import { baseOptions } from './baseOptions'
export const zemanticAi = createBlock({
export const zemanticAiBlock = createBlock({
id: 'zemantic-ai',
name: 'Zemantic AI',
tags: [],

View File

@@ -0,0 +1,7 @@
// Do not edit this file manually
import { parseBlockCredentials, parseBlockSchema } from '@typebot.io/forge'
import { zemanticAiBlock } from '.'
export const zemanticAiBlockSchema = parseBlockSchema(zemanticAiBlock)
export const zemanticAiCredentialsSchema =
parseBlockCredentials(zemanticAiBlock)

View File

@@ -83,7 +83,7 @@ const main = async () => {
await createIndexFile(newBlockPath, prompt)
await createLogoFile(newBlockPath, prompt)
if (prompt.auth !== 'none') await createAuthFile(newBlockPath, prompt)
await addNewIntegrationToRepository(prompt)
await createSchemasFile(newBlockPath, prompt)
s.stop('Creating files...')
s.start('Installing dependencies...')
await new Promise<void>((resolve, reject) => {
@@ -138,7 +138,7 @@ const createIndexFile = async (
import { ${capitalize(camelCaseId)}Logo } from './logo'
${auth !== 'none' ? `import { auth } from './auth'` : ''}
export const ${camelCaseName} = createBlock({
export const ${camelCaseName}Block = createBlock({
id: '${id}',
name: '${name}',
tags: [],
@@ -175,51 +175,6 @@ const createPackageJson = async (path: string, { id }: { id: unknown }) => {
)
}
const addNewIntegrationToRepository = async ({
camelCaseId,
id,
}: {
camelCaseId: string
id: string
}) => {
const schemasPath = join(process.cwd(), `../schemas`)
const packageJson = require(join(schemasPath, 'package.json'))
packageJson.devDependencies[`@typebot.io/${id}-block`] = 'workspace:*'
writeFileSync(
join(schemasPath, 'package.json'),
await prettier.format(JSON.stringify(packageJson, null, 2), {
parser: 'json',
...prettierRc,
})
)
const repoIndexFile = readFileSync(join(schemasPath, 'index.ts')).toString()
writeFileSync(
join(schemasPath, 'index.ts'),
await prettier.format(
repoIndexFile
.replace(
'] as BlockDefinition<(typeof enabledBlocks)[number], any, any>[]',
`${camelCaseId},] as BlockDefinition<(typeof enabledBlocks)[number], any, any>[]`
)
.replace(
'// Do not edit this file manually',
`// Do not edit this file manually\nimport {${camelCaseId}} from '@typebot.io/${id}-block'`
),
{ parser: 'typescript', ...prettierRc }
)
)
const repoPath = join(process.cwd(), `../repository`)
const enabledIndexFile = readFileSync(join(repoPath, 'index.ts')).toString()
writeFileSync(
join(repoPath, 'index.ts'),
await prettier.format(
enabledIndexFile.replace('] as const', `'${id}'] as const`),
{ parser: 'typescript', ...prettierRc }
)
)
}
const createTsConfig = async (path: string) => {
writeFileSync(
join(path, 'tsconfig.json'),
@@ -289,6 +244,27 @@ const createAuthFile = async (
)
)
const createSchemasFile = async (
path: string,
{
id,
}: { id: string; name: string; auth: 'apiKey' | 'encryptedData' | 'none' }
) => {
const camelCaseName = camelize(id as string)
writeFileSync(
join(path, 'schemas.ts'),
await prettier.format(
`// Do not edit this file manually
import { parseBlockCredentials, parseBlockSchema } from '@typebot.io/forge'
import { ${camelCaseName}Block } from '.'
export const ${camelCaseName}BlockSchema = parseBlockSchema(${camelCaseName}Block)
export const ${camelCaseName}CredentialsSchema = parseBlockCredentials(${camelCaseName}Block)`,
{ parser: 'typescript', ...prettierRc }
)
)
}
main()
.then()
.catch((err) => {

View File

@@ -89,7 +89,7 @@ export const parseBlockCredentials = <
>(
blockDefinition: BlockDefinition<I, A, O>
) => {
if (!blockDefinition.auth) throw new Error('Block has no auth definition')
if (!blockDefinition.auth) return null
return z.object({
id: z.string(),
type: z.literal(blockDefinition.id),

View File

@@ -11,7 +11,6 @@
},
"devDependencies": {
"@typebot.io/tsconfig": "workspace:*",
"@types/react": "18.2.15",
"@typebot.io/forge-repository": "workspace:*"
"@types/react": "18.2.15"
}
}

View File

@@ -1,7 +1,6 @@
import { SVGProps } from 'react'
import { z } from './zod'
import { ZodRawShape } from 'zod'
import { enabledBlocks } from '@typebot.io/forge-repository'
export type VariableStore = {
get: (variableId: string) => string | (string | null)[] | null | undefined
@@ -34,7 +33,7 @@ export type FunctionToExecute = {
export type ReadOnlyVariableStore = Omit<VariableStore, 'set'>
export type TurnableIntoParam<T = {}> = {
blockType: (typeof enabledBlocks)[number]
blockId: string
/**
* If defined will be used to convert the existing block options into the new block options.
*/

View File

@@ -1,5 +1,6 @@
// Do not edit this file manually
export const enabledBlocks = [
import { ForgedBlock } from './types'
export const forgedBlockIds = [
'openai',
'zemantic-ai',
'cal-com',
@@ -11,4 +12,4 @@ export const enabledBlocks = [
'anthropic',
'together-ai',
'open-router',
] as const
] as const satisfies ForgedBlock['type'][]

View File

@@ -0,0 +1,36 @@
import { anthropicBlock } from '@typebot.io/anthropic-block'
import { anthropicCredentialsSchema } from '@typebot.io/anthropic-block/schemas'
import { calComBlock } from '@typebot.io/cal-com-block'
import { calComCredentialsSchema } from '@typebot.io/cal-com-block/schemas'
import { chatNodeBlock } from '@typebot.io/chat-node-block'
import { chatNodeCredentialsSchema } from '@typebot.io/chat-node-block/schemas'
import { difyAiBlock } from '@typebot.io/dify-ai-block'
import { difyAiCredentialsSchema } from '@typebot.io/dify-ai-block/schemas'
import { elevenlabsBlock } from '@typebot.io/elevenlabs-block'
import { elevenlabsCredentialsSchema } from '@typebot.io/elevenlabs-block/schemas'
import { mistralBlock } from '@typebot.io/mistral-block'
import { mistralCredentialsSchema } from '@typebot.io/mistral-block/schemas'
import { openRouterBlock } from '@typebot.io/open-router-block'
import { openRouterCredentialsSchema } from '@typebot.io/open-router-block/schemas'
import { openAIBlock } from '@typebot.io/openai-block'
import { openAICredentialsSchema } from '@typebot.io/openai-block/schemas'
import { qrCodeBlock } from '@typebot.io/qrcode-block'
import { qrCodeCredentialsSchema } from '@typebot.io/qrcode-block/schemas'
import { togetherAiBlock } from '@typebot.io/together-ai-block'
import { togetherAiCredentialsSchema } from '@typebot.io/together-ai-block/schemas'
import { zemanticAiBlock } from '@typebot.io/zemantic-ai-block'
import { zemanticAiCredentialsSchema } from '@typebot.io/zemantic-ai-block/schemas'
export const forgedCredentialsSchemas = {
[openAIBlock.id]: openAICredentialsSchema,
[zemanticAiBlock.id]: zemanticAiCredentialsSchema,
[calComBlock.id]: calComCredentialsSchema,
[chatNodeBlock.id]: chatNodeCredentialsSchema,
[qrCodeBlock.id]: qrCodeCredentialsSchema,
[difyAiBlock.id]: difyAiCredentialsSchema,
[mistralBlock.id]: mistralCredentialsSchema,
[elevenlabsBlock.id]: elevenlabsCredentialsSchema,
[anthropicBlock.id]: anthropicCredentialsSchema,
[togetherAiBlock.id]: togetherAiCredentialsSchema,
[openRouterBlock.id]: openRouterCredentialsSchema,
}

View File

@@ -0,0 +1,26 @@
// Do not edit this file manually
import { anthropicBlock } from '@typebot.io/anthropic-block'
import { openRouterBlock } from '@typebot.io/open-router-block'
import { togetherAiBlock } from '@typebot.io/together-ai-block'
import { elevenlabsBlock } from '@typebot.io/elevenlabs-block'
import { difyAiBlock } from '@typebot.io/dify-ai-block'
import { mistralBlock } from '@typebot.io/mistral-block'
import { qrCodeBlock } from '@typebot.io/qrcode-block'
import { chatNodeBlock } from '@typebot.io/chat-node-block'
import { calComBlock } from '@typebot.io/cal-com-block'
import { zemanticAiBlock } from '@typebot.io/zemantic-ai-block'
import { openAIBlock } from '@typebot.io/openai-block'
export const forgedBlocks = {
[openAIBlock.id]: openAIBlock,
[zemanticAiBlock.id]: zemanticAiBlock,
[calComBlock.id]: calComBlock,
[chatNodeBlock.id]: chatNodeBlock,
[qrCodeBlock.id]: qrCodeBlock,
[difyAiBlock.id]: difyAiBlock,
[mistralBlock.id]: mistralBlock,
[elevenlabsBlock.id]: elevenlabsBlock,
[anthropicBlock.id]: anthropicBlock,
[togetherAiBlock.id]: togetherAiBlock,
[openRouterBlock.id]: openRouterBlock,
} as const

View File

@@ -2,8 +2,21 @@
"name": "@typebot.io/forge-repository",
"version": "1.0.0",
"description": "",
"main": "index.ts",
"keywords": [],
"author": "Baptiste Arnaud",
"license": "ISC"
"license": "ISC",
"devDependencies": {
"@typebot.io/forge": "workspace:*",
"@typebot.io/openai-block": "workspace:*",
"@typebot.io/zemantic-ai-block": "workspace:*",
"@typebot.io/cal-com-block": "workspace:*",
"@typebot.io/chat-node-block": "workspace:*",
"@typebot.io/qrcode-block": "workspace:*",
"@typebot.io/dify-ai-block": "workspace:*",
"@typebot.io/mistral-block": "workspace:*",
"@typebot.io/elevenlabs-block": "workspace:*",
"@typebot.io/anthropic-block": "workspace:*",
"@typebot.io/together-ai-block": "workspace:*",
"@typebot.io/open-router-block": "workspace:*"
}
}

View File

@@ -0,0 +1,36 @@
import { anthropicBlock } from '@typebot.io/anthropic-block'
import { anthropicBlockSchema } from '@typebot.io/anthropic-block/schemas'
import { calComBlock } from '@typebot.io/cal-com-block'
import { calComBlockSchema } from '@typebot.io/cal-com-block/schemas'
import { chatNodeBlock } from '@typebot.io/chat-node-block'
import { chatNodeBlockSchema } from '@typebot.io/chat-node-block/schemas'
import { difyAiBlock } from '@typebot.io/dify-ai-block'
import { difyAiBlockSchema } from '@typebot.io/dify-ai-block/schemas'
import { elevenlabsBlock } from '@typebot.io/elevenlabs-block'
import { elevenlabsBlockSchema } from '@typebot.io/elevenlabs-block/schemas'
import { mistralBlock } from '@typebot.io/mistral-block'
import { mistralBlockSchema } from '@typebot.io/mistral-block/schemas'
import { openRouterBlock } from '@typebot.io/open-router-block'
import { openRouterBlockSchema } from '@typebot.io/open-router-block/schemas'
import { openAIBlock } from '@typebot.io/openai-block'
import { openAIBlockSchema } from '@typebot.io/openai-block/schemas'
import { qrCodeBlock } from '@typebot.io/qrcode-block'
import { qrCodeBlockSchema } from '@typebot.io/qrcode-block/schemas'
import { togetherAiBlock } from '@typebot.io/together-ai-block'
import { togetherAiBlockSchema } from '@typebot.io/together-ai-block/schemas'
import { zemanticAiBlock } from '@typebot.io/zemantic-ai-block'
import { zemanticAiBlockSchema } from '@typebot.io/zemantic-ai-block/schemas'
export const forgedBlockSchemas = {
[openAIBlock.id]: openAIBlockSchema,
[zemanticAiBlock.id]: zemanticAiBlockSchema,
[calComBlock.id]: calComBlockSchema,
[chatNodeBlock.id]: chatNodeBlockSchema,
[qrCodeBlock.id]: qrCodeBlockSchema,
[difyAiBlock.id]: difyAiBlockSchema,
[mistralBlock.id]: mistralBlockSchema,
[elevenlabsBlock.id]: elevenlabsBlockSchema,
[anthropicBlock.id]: anthropicBlockSchema,
[togetherAiBlock.id]: togetherAiBlockSchema,
[openRouterBlock.id]: openRouterBlockSchema,
}

View File

@@ -0,0 +1,10 @@
import { z } from '@typebot.io/forge/zod'
import { forgedBlocks } from './definitions'
import { forgedBlockSchemas } from './schemas'
export type ForgedBlock = z.infer<
(typeof forgedBlockSchemas)[keyof typeof forgedBlockSchemas]
>
export type ForgedBlockDefinition =
(typeof forgedBlocks)[keyof typeof forgedBlocks]

View File

@@ -1,42 +0,0 @@
// Do not edit this file manually
import { anthropic } from '@typebot.io/anthropic-block'
import { openRouter } from '@typebot.io/open-router-block'
import { togetherAi } from '@typebot.io/together-ai-block'
import { elevenlabs } from '@typebot.io/elevenlabs-block'
import { difyAi } from '@typebot.io/dify-ai-block'
import { mistral } from '@typebot.io/mistral-block'
import { qrCode } from '@typebot.io/qrcode-block'
import { chatNode } from '@typebot.io/chat-node-block'
import { calCom } from '@typebot.io/cal-com-block'
import { zemanticAi } from '@typebot.io/zemantic-ai-block'
import { openAIBlock } from '@typebot.io/openai-block'
import {
BlockDefinition,
parseBlockCredentials,
parseBlockSchema,
} from '@typebot.io/forge'
import { enabledBlocks } from '@typebot.io/forge-repository'
import { z } from '@typebot.io/forge/zod'
export const forgedBlocks = [
openAIBlock,
zemanticAi,
calCom,
chatNode,
qrCode,
difyAi,
mistral,
elevenlabs,
anthropic,
togetherAi,
openRouter,
] as BlockDefinition<(typeof enabledBlocks)[number], any, any>[]
export type ForgedBlockDefinition = (typeof forgedBlocks)[number]
export const forgedBlockSchemas = forgedBlocks.map(parseBlockSchema)
export type ForgedBlock = z.infer<(typeof forgedBlockSchemas)[number]>
export const forgedCredentialsSchemas = forgedBlocks
.filter((b) => b.auth)
.map(parseBlockCredentials)

View File

@@ -1,24 +0,0 @@
{
"name": "@typebot.io/forge-schemas",
"version": "1.0.0",
"description": "",
"main": "index.ts",
"keywords": [],
"author": "Baptiste Arnaud",
"license": "ISC",
"devDependencies": {
"@typebot.io/forge": "workspace:*",
"@typebot.io/forge-repository": "workspace:*",
"@typebot.io/openai-block": "workspace:*",
"@typebot.io/zemantic-ai-block": "workspace:*",
"@typebot.io/cal-com-block": "workspace:*",
"@typebot.io/chat-node-block": "workspace:*",
"@typebot.io/qrcode-block": "workspace:*",
"@typebot.io/dify-ai-block": "workspace:*",
"@typebot.io/mistral-block": "workspace:*",
"@typebot.io/elevenlabs-block": "workspace:*",
"@typebot.io/anthropic-block": "workspace:*",
"@typebot.io/together-ai-block": "workspace:*",
"@typebot.io/open-router-block": "workspace:*"
}
}

View File

@@ -9,7 +9,6 @@
"@paralleldrive/cuid2": "2.2.1",
"@playwright/test": "1.36.0",
"@typebot.io/env": "workspace:*",
"@typebot.io/forge-repository": "workspace:*",
"@typebot.io/prisma": "workspace:*",
"@typebot.io/tsconfig": "workspace:*",
"@types/escape-html": "^1.0.4",

View File

@@ -0,0 +1,9 @@
import { forgedBlocks } from '@typebot.io/forge-repository/definitions'
import { ForgedBlock } from '@typebot.io/forge-repository/types'
import { Block } from '../schema'
export const isForgedBlock = (block: Block): block is ForgedBlock =>
block.type in forgedBlocks
export const isForgedBlockType = (
type: Block['type']
): type is ForgedBlock['type'] => type in forgedBlocks

View File

@@ -6,7 +6,7 @@ import { bubbleBlockSchemas } from './bubbles/schema'
import { LogicBlock, logicBlockSchemas } from './logic/schema'
import { InputBlock, inputBlockSchemas } from './inputs/schema'
import { IntegrationBlock, integrationBlockSchemas } from './integrations'
import { enabledBlocks } from '@typebot.io/forge-repository'
import { forgedBlockSchemas } from '@typebot.io/forge-repository/schemas'
export type BlockWithOptions = Extract<Block, { options?: any }>
@@ -34,15 +34,8 @@ export const blockSchemaV6 = z
...inputBlockSchemas.v6,
...logicBlockSchemas.v6,
...integrationBlockSchemas.v6,
...Object.values(forgedBlockSchemas),
])
.or(
blockBaseSchema.merge(
z.object({
type: z.enum(enabledBlocks),
options: z.any().optional(),
})
)
)
.openapi({
title: 'Block',
ref: 'block',

View File

@@ -1,4 +1,4 @@
import { enabledBlocks } from '@typebot.io/forge-repository'
import { forgedBlockIds } from '@typebot.io/forge-repository/constants'
import {
Block,
InputBlock,
@@ -62,9 +62,7 @@ export const isConditionBlock = (block: Block): block is ConditionBlock =>
export const isIntegrationBlock = (block: Block): block is IntegrationBlock =>
(
Object.values(IntegrationBlockType).concat(
enabledBlocks as readonly any[]
) as any[]
Object.values(IntegrationBlockType).concat(forgedBlockIds as any[]) as any[]
).includes(block.type)
export const isWebhookBlock = (block: Block): block is HttpRequestBlock =>

View File

@@ -1,10 +1,10 @@
import { Variable } from '@typebot.io/schemas'
import {
defaultParseVariablesOptions,
parseVariables,
ParseVariablesOptions,
} from './parseVariables'
import { parseGuessedTypeFromString } from './parseGuessedTypeFromString'
import { Variable } from './types'
type DeepParseOptions = {
guessCorrectTypes?: boolean

View File

@@ -1,10 +1,11 @@
import { Variable } from '@typebot.io/schemas'
import { parseVariables } from './parseVariables'
import { extractVariablesFromText } from './extractVariablesFromText'
import { parseGuessedValueType } from './parseGuessedValueType'
import { isDefined } from '@typebot.io/lib'
import { defaultTimeout } from '@typebot.io/schemas/features/blocks/integrations/webhook/constants'
import { safeStringify } from '@typebot.io/lib/safeStringify'
import { Variable } from './types'
const defaultTimeout = 10
type Props = {
variables: Variable[]

View File

@@ -1,4 +1,4 @@
import { Variable } from '@typebot.io/schemas'
import { Variable } from './types'
export const extractVariablesFromText =
(variables: Variable[]) =>

View File

@@ -1,4 +1,4 @@
import { Variable } from '@typebot.io/schemas'
import { Variable } from './types'
export const findUniqueVariableValue =
(variables: Variable[]) =>

View File

@@ -1,8 +1,8 @@
import { Result, Variable } from '@typebot.io/schemas'
import { Variable } from './types'
export const injectVariablesFromExistingResult = (
variables: Variable[],
resultVariables: Result['variables']
resultVariables: any[]
): Variable[] =>
variables.map((variable) => {
const resultVariable = resultVariables.find(

View File

@@ -4,7 +4,6 @@
"license": "AGPL-3.0-or-later",
"private": true,
"dependencies": {
"@typebot.io/lib": "workspace:*",
"@typebot.io/schemas": "workspace:*"
"@typebot.io/lib": "workspace:*"
}
}

View File

@@ -1,4 +1,4 @@
import { Variable } from '@typebot.io/schemas'
import { Variable } from './types'
export const parseGuessedValueType = (
value: Variable['value']

View File

@@ -1,6 +1,6 @@
import { Variable } from '@typebot.io/schemas'
import { parseGuessedValueType } from './parseGuessedValueType'
import { parseVariables } from './parseVariables'
import { Variable } from './types'
export const parseVariableNumber =
(variables: Variable[]) =>

View File

@@ -1,7 +1,7 @@
import { safeStringify } from '@typebot.io/lib/safeStringify'
import { isDefined, isNotDefined } from '@typebot.io/lib/utils'
import { Variable, VariableWithValue } from '@typebot.io/schemas'
import { parseGuessedValueType } from './parseGuessedValueType'
import { Variable, VariableWithValue } from './types'
export type ParseVariablesOptions = {
fieldToParse?: 'value' | 'id'

View File

@@ -1,9 +1,9 @@
import { safeStringify } from '@typebot.io/lib/safeStringify'
import { StartChatInput, Variable } from '@typebot.io/schemas'
import { Variable } from './types'
export const prefillVariables = (
variables: Variable[],
prefilledVariables: NonNullable<StartChatInput['prefilledVariables']>
prefilledVariables: Record<string, any>
): Variable[] =>
variables.map((variable) => {
const prefilledVariable = prefilledVariables[variable.name]

View File

@@ -1,5 +1,5 @@
import { isNotDefined } from '@typebot.io/lib/utils'
import { Variable, VariableWithValue } from '@typebot.io/schemas'
import { Variable, VariableWithValue } from './types'
export const transformVariablesToList =
(variables: Variable[]) =>

View File

@@ -0,0 +1,13 @@
export type Variable = {
id: string
name: string
value?: string | (string | null)[] | null | undefined
}
export type VariableWithValue = Pick<Variable, 'id' | 'name'> & {
value: string | (string | null)[]
}
export type VariableWithUnknowValue = Pick<Variable, 'id' | 'name'> & {
value?: unknown
}

View File

@@ -1,26 +1,22 @@
import { safeStringify } from '@typebot.io/lib/safeStringify'
import {
SessionState,
VariableWithUnknowValue,
Variable,
} from '@typebot.io/schemas'
import { Variable, VariableWithUnknowValue } from './types'
export const updateVariablesInSession =
(state: SessionState) =>
(newVariables: VariableWithUnknowValue[]): SessionState => ({
(state: any) => (newVariables: VariableWithUnknowValue[]) => ({
...state,
typebotsQueue: state.typebotsQueue.map((typebotInQueue, index) =>
index === 0
? {
...typebotInQueue,
typebot: {
...typebotInQueue.typebot,
variables: updateTypebotVariables(typebotInQueue.typebot)(
newVariables
),
},
}
: typebotInQueue
typebotsQueue: state.typebotsQueue.map(
(typebotInQueue: { typebot: { variables: Variable[] } }, index: number) =>
index === 0
? {
...typebotInQueue,
typebot: {
...typebotInQueue.typebot,
variables: updateTypebotVariables(typebotInQueue.typebot)(
newVariables
),
},
}
: typebotInQueue
),
})