♻️ Remove @typebot.io/schemas from @typebot.io/lib
This commit is contained in:
20
packages/billing/package.json
Normal file
20
packages/billing/package.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "@typebot.io/billing",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
"test": "echo \"Error: no test specified\" && exit 1"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "Baptiste Arnaud",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@typebot.io/prisma": "workspace:*",
|
||||
"@typebot.io/schemas": "workspace:*",
|
||||
"stripe": "12.13.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typebot.io/tsconfig": "workspace:*"
|
||||
}
|
||||
}
|
8
packages/billing/tsconfig.json
Normal file
8
packages/billing/tsconfig.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "@typebot.io/tsconfig/base.json",
|
||||
"include": ["**/*.ts"],
|
||||
"exclude": ["node_modules"],
|
||||
"compilerOptions": {
|
||||
"lib": ["ES2021", "DOM"]
|
||||
}
|
||||
}
|
@ -19,7 +19,7 @@ import { ExecuteIntegrationResponse } from '../../../types'
|
||||
import prisma from '@typebot.io/lib/prisma'
|
||||
import { parseVariables } from '@typebot.io/variables/parseVariables'
|
||||
import { defaultSendEmailOptions } from '@typebot.io/schemas/features/blocks/integrations/sendEmail/constants'
|
||||
import { parseAnswers } from '@typebot.io/lib/results/parseAnswers'
|
||||
import { parseAnswers } from '@typebot.io/results/parseAnswers'
|
||||
|
||||
export const sendEmailSuccessDescription = 'Email successfully sent'
|
||||
export const sendEmailErrorDescription = 'Email not sent'
|
||||
|
@ -26,7 +26,7 @@ import {
|
||||
maxTimeout,
|
||||
} from '@typebot.io/schemas/features/blocks/integrations/webhook/constants'
|
||||
import { env } from '@typebot.io/env'
|
||||
import { parseAnswers } from '@typebot.io/lib/results/parseAnswers'
|
||||
import { parseAnswers } from '@typebot.io/results/parseAnswers'
|
||||
|
||||
type ParsedWebhook = ExecutableHttpRequest & {
|
||||
basicAuth: { username?: string; password?: string }
|
||||
|
@ -7,15 +7,17 @@ import {
|
||||
TypebotLinkBlock,
|
||||
Variable,
|
||||
} from '@typebot.io/schemas'
|
||||
import { isInputBlock, byId, isNotDefined } from '@typebot.io/lib'
|
||||
import { byId, isNotDefined } from '@typebot.io/lib'
|
||||
import { isInputBlock } from '@typebot.io/schemas/helpers'
|
||||
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
|
||||
import { LogicBlockType } from '@typebot.io/schemas/features/blocks/logic/constants'
|
||||
import { parseResultHeader } from '@typebot.io/lib/results/parseResultHeader'
|
||||
import { parseResultHeader } from '@typebot.io/results/parseResultHeader'
|
||||
|
||||
export const parseSampleResult =
|
||||
(
|
||||
typebot: Pick<Typebot | PublicTypebot, 'groups' | 'variables' | 'edges'>,
|
||||
linkedTypebots: (Typebot | PublicTypebot)[]
|
||||
linkedTypebots: (Typebot | PublicTypebot)[],
|
||||
userEmail?: string
|
||||
) =>
|
||||
async (
|
||||
currentGroupId: string,
|
||||
@ -30,7 +32,7 @@ export const parseSampleResult =
|
||||
return {
|
||||
message: 'This is a sample result, it has been generated ⬇️',
|
||||
submittedAt: new Date().toISOString(),
|
||||
...parseResultSample(linkedInputBlocks, header, variables),
|
||||
...parseResultSample(linkedInputBlocks, header, variables, userEmail),
|
||||
}
|
||||
}
|
||||
|
||||
@ -83,7 +85,8 @@ const extractLinkedInputBlocks =
|
||||
const parseResultSample = (
|
||||
inputBlocks: InputBlock[],
|
||||
headerCells: ResultHeaderCell[],
|
||||
variables: Variable[]
|
||||
variables: Variable[],
|
||||
userEmail?: string
|
||||
) =>
|
||||
headerCells.reduce<Record<string, string | (string | null)[] | undefined>>(
|
||||
(resultSample, cell) => {
|
||||
@ -107,7 +110,7 @@ const parseResultSample = (
|
||||
const variableValue = variables.find(
|
||||
(variable) => cell.variableIds?.includes(variable.id) && variable.value
|
||||
)?.value
|
||||
const value = variableValue ?? getSampleValue(inputBlock)
|
||||
const value = variableValue ?? getSampleValue(inputBlock, userEmail)
|
||||
return {
|
||||
...resultSample,
|
||||
[cell.label]: value,
|
||||
@ -116,7 +119,7 @@ const parseResultSample = (
|
||||
{}
|
||||
)
|
||||
|
||||
const getSampleValue = (block: InputBlock): string => {
|
||||
const getSampleValue = (block: InputBlock, userEmail?: string): string => {
|
||||
switch (block.type) {
|
||||
case InputBlockType.CHOICE:
|
||||
return block.options?.isMultipleChoice
|
||||
@ -125,7 +128,7 @@ const getSampleValue = (block: InputBlock): string => {
|
||||
case InputBlockType.DATE:
|
||||
return new Date().toUTCString()
|
||||
case InputBlockType.EMAIL:
|
||||
return 'test@email.com'
|
||||
return userEmail ?? 'test@email.com'
|
||||
case InputBlockType.NUMBER:
|
||||
return '20'
|
||||
case InputBlockType.PHONE:
|
||||
|
@ -10,7 +10,7 @@ import { byId, isDefined, isEmpty } from '@typebot.io/lib'
|
||||
import prisma from '@typebot.io/lib/prisma'
|
||||
import { ExecuteIntegrationResponse } from '../../../types'
|
||||
import { updateVariablesInSession } from '@typebot.io/variables/updateVariablesInSession'
|
||||
import { parseAnswers } from '@typebot.io/lib/results/parseAnswers'
|
||||
import { parseAnswers } from '@typebot.io/results/parseAnswers'
|
||||
|
||||
const URL = 'https://api.zemantic.ai/v1/search-documents'
|
||||
|
||||
|
@ -1,5 +1,9 @@
|
||||
import { blockHasItems, isDefined, isInputBlock, byId } from '@typebot.io/lib'
|
||||
import { getBlockById } from '@typebot.io/lib/getBlockById'
|
||||
import { isDefined, byId } from '@typebot.io/lib'
|
||||
import {
|
||||
getBlockById,
|
||||
blockHasItems,
|
||||
isInputBlock,
|
||||
} from '@typebot.io/schemas/helpers'
|
||||
import { Block, SessionState } from '@typebot.io/schemas'
|
||||
|
||||
type Props = {
|
||||
|
@ -6,7 +6,8 @@ import {
|
||||
InputBlock,
|
||||
SessionState,
|
||||
} from '@typebot.io/schemas'
|
||||
import { isInputBlock, byId } from '@typebot.io/lib'
|
||||
import { byId } from '@typebot.io/lib'
|
||||
import { isInputBlock } from '@typebot.io/schemas/helpers'
|
||||
import { executeGroup, parseInput } from './executeGroup'
|
||||
import { getNextGroup } from './getNextGroup'
|
||||
import { validateEmail } from './blocks/inputs/email/validateEmail'
|
||||
@ -34,7 +35,7 @@ import { defaultChoiceInputOptions } from '@typebot.io/schemas/features/blocks/i
|
||||
import { defaultPictureChoiceOptions } from '@typebot.io/schemas/features/blocks/inputs/pictureChoice/constants'
|
||||
import { defaultFileInputOptions } from '@typebot.io/schemas/features/blocks/inputs/file/constants'
|
||||
import { VisitedEdge } from '@typebot.io/prisma'
|
||||
import { getBlockById } from '@typebot.io/lib/getBlockById'
|
||||
import { getBlockById } from '@typebot.io/schemas/helpers'
|
||||
import { ForgedBlock, forgedBlocks } from '@typebot.io/forge-schemas'
|
||||
import { enabledBlocks } from '@typebot.io/forge-repository'
|
||||
import { resumeChatCompletion } from './blocks/integrations/legacy/openai/resumeChatCompletion'
|
||||
|
@ -5,13 +5,13 @@ import {
|
||||
RuntimeOptions,
|
||||
SessionState,
|
||||
} from '@typebot.io/schemas'
|
||||
import { isNotEmpty } from '@typebot.io/lib'
|
||||
import {
|
||||
isBubbleBlock,
|
||||
isInputBlock,
|
||||
isIntegrationBlock,
|
||||
isLogicBlock,
|
||||
isNotEmpty,
|
||||
} from '@typebot.io/lib'
|
||||
} from '@typebot.io/schemas/helpers'
|
||||
import { getNextGroup } from './getNextGroup'
|
||||
import { executeLogic } from './executeLogic'
|
||||
import { executeIntegration } from './executeIntegration'
|
||||
|
@ -30,7 +30,8 @@
|
||||
"nodemailer": "6.9.3",
|
||||
"openai": "4.28.4",
|
||||
"qs": "6.11.2",
|
||||
"stripe": "12.13.0"
|
||||
"stripe": "12.13.0",
|
||||
"@typebot.io/results": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typebot.io/forge": "workspace:*",
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { parseVideoUrl } from '@typebot.io/lib/parseVideoUrl'
|
||||
import { parseVideoUrl } from '@typebot.io/schemas/features/blocks/bubbles/video/helpers'
|
||||
import {
|
||||
BubbleBlock,
|
||||
Variable,
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
import { TRPCError } from '@trpc/server'
|
||||
import { isDefined, omit, isNotEmpty, isInputBlock } from '@typebot.io/lib'
|
||||
import { isDefined, omit, isNotEmpty } from '@typebot.io/lib'
|
||||
import { isInputBlock } from '@typebot.io/schemas/helpers'
|
||||
import {
|
||||
Variable,
|
||||
VariableWithValue,
|
||||
|
@ -19,7 +19,7 @@ import { RatingForm } from '@/features/blocks/inputs/rating'
|
||||
import { FileUploadForm } from '@/features/blocks/inputs/fileUpload'
|
||||
import { defaultSettings } from '@typebot.io/schemas/features/typebot/settings/constants'
|
||||
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
|
||||
import { getBlockById } from '@typebot.io/lib/getBlockById'
|
||||
import { getBlockById } from '@typebot.io/schemas/helpers'
|
||||
|
||||
export const InputChatBlock = ({
|
||||
block,
|
||||
|
@ -2,16 +2,15 @@ import { useEffect, useRef, useState } from 'react'
|
||||
import { TransitionGroup, CSSTransition } from 'react-transition-group'
|
||||
import { AvatarSideContainer } from './AvatarSideContainer'
|
||||
import { LinkedTypebot, useTypebot } from '../../providers/TypebotProvider'
|
||||
import { isDefined, byId } from '@typebot.io/lib'
|
||||
import {
|
||||
isBubbleBlock,
|
||||
isBubbleBlockType,
|
||||
isChoiceInput,
|
||||
isDefined,
|
||||
isInputBlock,
|
||||
isIntegrationBlock,
|
||||
isLogicBlock,
|
||||
byId,
|
||||
} from '@typebot.io/lib'
|
||||
} from '@typebot.io/schemas/helpers'
|
||||
import {
|
||||
BubbleBlock,
|
||||
InputBlock,
|
||||
@ -30,7 +29,7 @@ import { executeLogic } from '@/utils/executeLogic'
|
||||
import { blockCanBeRetried, parseRetryBlock } from '@/utils/inputs'
|
||||
import { PopupBlockedToast } from '../PopupBlockedToast'
|
||||
import { LogicBlockType } from '@typebot.io/schemas/features/blocks/logic/constants'
|
||||
import { getBlockById } from '@typebot.io/lib/getBlockById'
|
||||
import { getBlockById } from '@typebot.io/schemas/helpers'
|
||||
|
||||
type ChatGroupProps = {
|
||||
blocks: Block[]
|
||||
|
@ -8,7 +8,8 @@ import {
|
||||
Theme,
|
||||
VariableWithValue,
|
||||
} from '@typebot.io/schemas'
|
||||
import { byId, isDefined, isInputBlock, isNotDefined } from '@typebot.io/lib'
|
||||
import { byId, isDefined, isNotDefined } from '@typebot.io/lib'
|
||||
import { isInputBlock } from '@typebot.io/schemas/helpers'
|
||||
import { animateScroll as scroll } from 'react-scroll'
|
||||
import { LinkedTypebot, useTypebot } from '@/providers/TypebotProvider'
|
||||
import { setCssVariablesValue } from '@/features/theme'
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { BubbleBlock, InputBlock, Block } from '@typebot.io/schemas'
|
||||
import { isBubbleBlock, isInputBlock } from '@typebot.io/lib'
|
||||
import { isInputBlock, isBubbleBlock } from '@typebot.io/schemas/helpers'
|
||||
import type { TypebotPostMessageData } from 'typebot-js'
|
||||
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
|
||||
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
|
||||
|
@ -11,7 +11,8 @@ import {
|
||||
UrlInputBlock,
|
||||
Variable,
|
||||
} from '@typebot.io/schemas'
|
||||
import { isDefined, isInputBlock } from '@typebot.io/lib'
|
||||
import { isDefined } from '@typebot.io/lib'
|
||||
import { isInputBlock } from '@typebot.io/schemas/helpers'
|
||||
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
|
||||
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
|
||||
|
||||
|
@ -1,24 +0,0 @@
|
||||
import { Block, Group } from '@typebot.io/schemas'
|
||||
|
||||
export const getBlockById = (
|
||||
blockId: string,
|
||||
groups: Group[]
|
||||
): { block: Block; group: Group; blockIndex: number; groupIndex: number } => {
|
||||
for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {
|
||||
for (
|
||||
let blockIndex = 0;
|
||||
blockIndex < (groups.at(groupIndex)?.blocks?.length ?? 0);
|
||||
blockIndex++
|
||||
) {
|
||||
if (groups.at(groupIndex)?.blocks?.at(blockIndex)?.id === blockId) {
|
||||
return {
|
||||
block: groups[groupIndex].blocks[blockIndex],
|
||||
group: groups[groupIndex],
|
||||
blockIndex,
|
||||
groupIndex,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Error(`Block with id ${blockId} was not found`)
|
||||
}
|
@ -1,6 +1,5 @@
|
||||
import { env } from '@typebot.io/env'
|
||||
import { Credentials as CredentialsFromDb } from '@typebot.io/prisma'
|
||||
import { GoogleSheetsCredentials } from '@typebot.io/schemas'
|
||||
import { decrypt } from './api/encryption/decrypt'
|
||||
import { encrypt } from './api/encryption/encrypt'
|
||||
import prisma from './prisma'
|
||||
@ -14,10 +13,7 @@ export const getAuthenticatedGoogleClient = async (
|
||||
where: { id: credentialsId },
|
||||
})) as CredentialsFromDb | undefined
|
||||
if (!credentials) return
|
||||
const data = (await decrypt(
|
||||
credentials.data,
|
||||
credentials.iv
|
||||
)) as GoogleSheetsCredentials['data']
|
||||
const data = await decrypt(credentials.data, credentials.iv)
|
||||
|
||||
const oauth2Client = new OAuth2Client(
|
||||
env.GOOGLE_CLIENT_ID,
|
||||
@ -30,17 +26,14 @@ export const getAuthenticatedGoogleClient = async (
|
||||
}
|
||||
|
||||
const updateTokens =
|
||||
(
|
||||
credentialsId: string,
|
||||
existingCredentials: GoogleSheetsCredentials['data']
|
||||
) =>
|
||||
(credentialsId: string, existingCredentials: any) =>
|
||||
async (credentials: Credentials) => {
|
||||
if (
|
||||
isDefined(existingCredentials.id_token) &&
|
||||
credentials.id_token !== existingCredentials.id_token
|
||||
)
|
||||
return
|
||||
const newCredentials: GoogleSheetsCredentials['data'] = {
|
||||
const newCredentials = {
|
||||
...existingCredentials,
|
||||
expiry_date: credentials.expiry_date,
|
||||
access_token: credentials.access_token,
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { User } from '@typebot.io/prisma'
|
||||
import { graphGestureNotficationKey } from '@typebot.io/schemas/features/user/constants'
|
||||
|
||||
export const mockedUser: User = {
|
||||
id: 'userId',
|
||||
@ -15,7 +14,7 @@ export const mockedUser: User = {
|
||||
onboardingCategories: [],
|
||||
updatedAt: new Date('2022-01-01'),
|
||||
displayedInAppNotifications: {
|
||||
[graphGestureNotficationKey]: true,
|
||||
['graphGestureNotification']: true,
|
||||
},
|
||||
referral: null,
|
||||
}
|
||||
|
@ -11,7 +11,6 @@
|
||||
"@typebot.io/env": "workspace:*",
|
||||
"@typebot.io/forge-repository": "workspace:*",
|
||||
"@typebot.io/prisma": "workspace:*",
|
||||
"@typebot.io/schemas": "workspace:*",
|
||||
"@typebot.io/tsconfig": "workspace:*",
|
||||
"@types/escape-html": "^1.0.4",
|
||||
"@types/nodemailer": "6.4.8",
|
||||
|
@ -1,32 +0,0 @@
|
||||
import { PlaywrightTestConfig } from '@playwright/test'
|
||||
import path from 'path'
|
||||
|
||||
export const playwrightBaseConfig: PlaywrightTestConfig = {
|
||||
globalSetup: require.resolve(path.join(__dirname, 'globalSetup')),
|
||||
timeout: process.env.CI ? 50 * 1000 : 40 * 1000,
|
||||
expect: {
|
||||
timeout: process.env.CI ? 10 * 1000 : 5 * 1000,
|
||||
},
|
||||
retries: 0,
|
||||
workers: process.env.CI ? 2 : 3,
|
||||
reporter: [
|
||||
[process.env.CI ? 'github' : 'list'],
|
||||
['html', { outputFolder: 'src/test/reporters' }],
|
||||
],
|
||||
maxFailures: process.env.CI ? 10 : undefined,
|
||||
webServer: process.env.CI
|
||||
? {
|
||||
command: 'pnpm run start',
|
||||
timeout: 60_000,
|
||||
reuseExistingServer: true,
|
||||
}
|
||||
: undefined,
|
||||
outputDir: './src/test/results',
|
||||
use: {
|
||||
trace: 'on-first-retry',
|
||||
video: 'retain-on-failure',
|
||||
locale: 'en-US',
|
||||
browserName: 'chromium',
|
||||
viewport: { width: 1400, height: 1000 },
|
||||
},
|
||||
}
|
@ -1,11 +0,0 @@
|
||||
import { FullConfig } from '@playwright/test'
|
||||
import { setupDatabase, teardownDatabase } from './databaseSetup'
|
||||
|
||||
async function globalSetup(config: FullConfig) {
|
||||
const { baseURL } = config.projects[0].use
|
||||
if (!baseURL) throw new Error('baseURL is missing')
|
||||
await teardownDatabase()
|
||||
await setupDatabase()
|
||||
}
|
||||
|
||||
export default globalSetup
|
@ -1,26 +1,3 @@
|
||||
import type {
|
||||
BubbleBlock,
|
||||
ChoiceInputBlock,
|
||||
ConditionBlock,
|
||||
InputBlock,
|
||||
IntegrationBlock,
|
||||
LogicBlock,
|
||||
Block,
|
||||
TextInputBlock,
|
||||
TextBubbleBlock,
|
||||
HttpRequestBlock,
|
||||
ImageBubbleBlock,
|
||||
VideoBubbleBlock,
|
||||
BlockWithOptionsType,
|
||||
} from '@typebot.io/schemas'
|
||||
import { BubbleBlockType } from '@typebot.io/schemas/features/blocks/bubbles/constants'
|
||||
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
|
||||
import { PictureChoiceBlock } from '@typebot.io/schemas/features/blocks/inputs/pictureChoice'
|
||||
import { IntegrationBlockType } from '@typebot.io/schemas/features/blocks/integrations/constants'
|
||||
import { LogicBlockType } from '@typebot.io/schemas/features/blocks/logic/constants'
|
||||
import { defaultChoiceInputOptions } from '@typebot.io/schemas/features/blocks/inputs/choice/constants'
|
||||
import { enabledBlocks } from '@typebot.io/forge-repository'
|
||||
|
||||
export const sendRequest = async <ResponseData>(
|
||||
params:
|
||||
| {
|
||||
@ -72,88 +49,6 @@ export const isEmpty = (
|
||||
export const isNotEmpty = (value: string | undefined | null): value is string =>
|
||||
value !== undefined && value !== null && value !== ''
|
||||
|
||||
export const isInputBlock = (block: Block): block is InputBlock =>
|
||||
(Object.values(InputBlockType) as string[]).includes(block.type)
|
||||
|
||||
export const isBubbleBlock = (block: Block): block is BubbleBlock =>
|
||||
(Object.values(BubbleBlockType) as string[]).includes(block.type)
|
||||
|
||||
export const isLogicBlock = (block: Block): block is LogicBlock =>
|
||||
(Object.values(LogicBlockType) as string[]).includes(block.type)
|
||||
|
||||
export const isTextBubbleBlock = (block: Block): block is TextBubbleBlock =>
|
||||
block.type === BubbleBlockType.TEXT
|
||||
|
||||
export const isMediaBubbleBlock = (
|
||||
block: Block
|
||||
): block is ImageBubbleBlock | VideoBubbleBlock =>
|
||||
block.type === BubbleBlockType.IMAGE || block.type === BubbleBlockType.VIDEO
|
||||
|
||||
export const isTextInputBlock = (block: Block): block is TextInputBlock =>
|
||||
block.type === InputBlockType.TEXT
|
||||
|
||||
export const isChoiceInput = (block: Block): block is ChoiceInputBlock =>
|
||||
block.type === InputBlockType.CHOICE
|
||||
|
||||
export const isPictureChoiceInput = (
|
||||
block: Block
|
||||
): block is PictureChoiceBlock => block.type === InputBlockType.PICTURE_CHOICE
|
||||
|
||||
export const isSingleChoiceInput = (block: Block): block is ChoiceInputBlock =>
|
||||
block.type === InputBlockType.CHOICE &&
|
||||
'options' in block &&
|
||||
!(
|
||||
block.options?.isMultipleChoice ??
|
||||
defaultChoiceInputOptions.isMultipleChoice
|
||||
)
|
||||
|
||||
export const isConditionBlock = (block: Block): block is ConditionBlock =>
|
||||
block.type === LogicBlockType.CONDITION
|
||||
|
||||
export const isIntegrationBlock = (block: Block): block is IntegrationBlock =>
|
||||
(
|
||||
Object.values(IntegrationBlockType).concat(
|
||||
enabledBlocks as readonly any[]
|
||||
) as any[]
|
||||
).includes(block.type)
|
||||
|
||||
export const isWebhookBlock = (block: Block): block is HttpRequestBlock =>
|
||||
[
|
||||
IntegrationBlockType.WEBHOOK,
|
||||
IntegrationBlockType.PABBLY_CONNECT,
|
||||
IntegrationBlockType.ZAPIER,
|
||||
IntegrationBlockType.MAKE_COM,
|
||||
].includes(block.type as IntegrationBlockType)
|
||||
|
||||
export const isBubbleBlockType = (
|
||||
type: Block['type']
|
||||
): type is BubbleBlockType =>
|
||||
(Object.values(BubbleBlockType) as string[]).includes(type)
|
||||
|
||||
export const blockTypeHasOption = (
|
||||
type: Block['type']
|
||||
): type is BlockWithOptionsType =>
|
||||
(Object.values(InputBlockType) as string[])
|
||||
.concat(Object.values(LogicBlockType))
|
||||
.concat(Object.values(IntegrationBlockType))
|
||||
.includes(type)
|
||||
|
||||
export const blockTypeHasItems = (
|
||||
type: Block['type']
|
||||
): type is
|
||||
| LogicBlockType.CONDITION
|
||||
| InputBlockType.CHOICE
|
||||
| LogicBlockType.AB_TEST =>
|
||||
type === LogicBlockType.CONDITION ||
|
||||
type === InputBlockType.CHOICE ||
|
||||
type === LogicBlockType.AB_TEST ||
|
||||
type === InputBlockType.PICTURE_CHOICE
|
||||
|
||||
export const blockHasItems = (
|
||||
block: Block
|
||||
): block is ConditionBlock | ChoiceInputBlock =>
|
||||
'items' in block && isDefined(block.items)
|
||||
|
||||
export const byId = (id?: string) => (obj: { id: string }) => obj.id === id
|
||||
|
||||
export const capitalize = (s: string) => s.charAt(0).toUpperCase() + s.slice(1)
|
||||
|
@ -5,8 +5,9 @@ import {
|
||||
TypebotV5,
|
||||
HttpRequest,
|
||||
} from '@typebot.io/schemas'
|
||||
import { isWebhookBlock, isDefined } from '../utils'
|
||||
import prisma from '../prisma'
|
||||
import { isWebhookBlock } from '@typebot.io/schemas/helpers'
|
||||
import { isDefined } from '@typebot.io/lib/utils'
|
||||
import prisma from '@typebot.io/lib/prisma'
|
||||
import {
|
||||
HttpMethod,
|
||||
defaultWebhookAttributes,
|
@ -11,9 +11,9 @@ import {
|
||||
import { IntegrationBlockType } from '@typebot.io/schemas/features/blocks/integrations/constants'
|
||||
import { GoogleSheetsAction } from '@typebot.io/schemas/features/blocks/integrations/googleSheets/constants'
|
||||
import { ComparisonOperators } from '@typebot.io/schemas/features/blocks/logic/condition/constants'
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
import { createId } from '@typebot.io/lib/createId'
|
||||
import { EventType } from '@typebot.io/schemas/features/events/constants'
|
||||
import { byId } from '../utils'
|
||||
import { byId } from '@typebot.io/lib/utils'
|
||||
|
||||
export const migrateTypebotFromV5ToV6 = async (
|
||||
typebot: TypebotV5 | PublicTypebotV5
|
17
packages/migrations/package.json
Normal file
17
packages/migrations/package.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "@typebot.io/migrations",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"scripts": {},
|
||||
"keywords": [],
|
||||
"author": "Baptiste Arnaud",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@typebot.io/schemas": "workspace:*",
|
||||
"@typebot.io/lib": "workspace:*",
|
||||
"@typebot.io/prisma": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typebot.io/tsconfig": "workspace:*"
|
||||
}
|
||||
}
|
8
packages/migrations/tsconfig.json
Normal file
8
packages/migrations/tsconfig.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "@typebot.io/tsconfig/base.json",
|
||||
"include": ["**/*.ts"],
|
||||
"exclude": ["node_modules"],
|
||||
"compilerOptions": {
|
||||
"lib": ["ES2021", "DOM"]
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@ import {
|
||||
Workspace,
|
||||
WorkspaceRole,
|
||||
} from '@typebot.io/prisma'
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
import { createId } from '@typebot.io/lib/createId'
|
||||
import { Typebot, TypebotV6, HttpRequest } from '@typebot.io/schemas'
|
||||
import { readFileSync } from 'fs'
|
||||
import { proWorkspaceId, userId } from './databaseSetup'
|
@ -1,13 +1,12 @@
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
import {
|
||||
BlockV5,
|
||||
BlockV6,
|
||||
Group,
|
||||
PublicTypebot,
|
||||
Typebot,
|
||||
TypebotV6,
|
||||
} from '@typebot.io/schemas'
|
||||
import { isDefined } from '../utils'
|
||||
import { isDefined } from '@typebot.io/lib/utils'
|
||||
import { createId } from '@typebot.io/lib/createId'
|
||||
import { proWorkspaceId } from './databaseSetup'
|
||||
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
|
||||
import { EventType } from '@typebot.io/schemas/features/events/constants'
|
@ -4,7 +4,7 @@ import {
|
||||
PrismaClient,
|
||||
WorkspaceRole,
|
||||
} from '@typebot.io/prisma'
|
||||
import { encrypt } from '../api/encryption/encrypt'
|
||||
import { encrypt } from '@typebot.io/lib/api/encryption/encrypt'
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
6
packages/playwright/globalSetup.ts
Normal file
6
packages/playwright/globalSetup.ts
Normal file
@ -0,0 +1,6 @@
|
||||
import { setupDatabase, teardownDatabase } from './databaseSetup'
|
||||
|
||||
export const globalSetup = async () => {
|
||||
await teardownDatabase()
|
||||
await setupDatabase()
|
||||
}
|
19
packages/playwright/package.json
Normal file
19
packages/playwright/package.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "@typebot.io/playwright",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"scripts": {},
|
||||
"keywords": [],
|
||||
"author": "Baptiste Arnaud",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@playwright/test": "^1.42.1",
|
||||
"@typebot.io/lib": "workspace:*",
|
||||
"@typebot.io/prisma": "workspace:*",
|
||||
"@typebot.io/schemas": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20.11.26",
|
||||
"@typebot.io/tsconfig": "workspace:*"
|
||||
}
|
||||
}
|
8
packages/playwright/tsconfig.json
Normal file
8
packages/playwright/tsconfig.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "@typebot.io/tsconfig/base.json",
|
||||
"include": ["**/*.ts"],
|
||||
"exclude": ["node_modules"],
|
||||
"compilerOptions": {
|
||||
"lib": ["ES2021", "DOM"]
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import { Prisma, PrismaClient } from '@typebot.io/prisma'
|
||||
import { Block, Typebot } from '@typebot.io/schemas'
|
||||
import { deleteFilesFromBucket } from '../../s3/deleteFilesFromBucket'
|
||||
import { deleteFilesFromBucket } from '@typebot.io/lib/s3/deleteFilesFromBucket'
|
||||
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
|
||||
|
||||
type ArchiveResultsProps = {
|
@ -6,7 +6,7 @@ import {
|
||||
TableData,
|
||||
} from '@typebot.io/schemas'
|
||||
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
|
||||
import { isDefined } from '../utils'
|
||||
import { isDefined } from '../lib/utils'
|
||||
|
||||
type CellParser = (
|
||||
content: VariableWithValue['value'],
|
17
packages/results/package.json
Normal file
17
packages/results/package.json
Normal file
@ -0,0 +1,17 @@
|
||||
{
|
||||
"name": "@typebot.io/results",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"scripts": {},
|
||||
"keywords": [],
|
||||
"author": "Baptiste Arnaud",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@typebot.io/schemas": "workspace:*",
|
||||
"@typebot.io/lib": "workspace:*",
|
||||
"@typebot.io/prisma": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typebot.io/tsconfig": "workspace:*"
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@ import {
|
||||
Variable,
|
||||
VariableWithValue,
|
||||
} from '@typebot.io/schemas'
|
||||
import { isDefined, isEmpty } from '../utils'
|
||||
import { isDefined, isEmpty } from '../lib/utils'
|
||||
|
||||
export const parseAnswers = ({
|
||||
answers,
|
@ -6,8 +6,9 @@ import {
|
||||
InputBlock,
|
||||
Typebot,
|
||||
} from '@typebot.io/schemas'
|
||||
import { isInputBlock } from '@typebot.io/schemas/helpers'
|
||||
import { InputBlockType } from '@typebot.io/schemas/features/blocks/inputs/constants'
|
||||
import { isInputBlock, byId, isNotEmpty } from '../utils'
|
||||
import { byId, isNotEmpty } from '@typebot.io/lib/utils'
|
||||
|
||||
export const parseResultHeader = (
|
||||
typebot: Pick<Typebot, 'groups' | 'variables'>,
|
8
packages/results/tsconfig.json
Normal file
8
packages/results/tsconfig.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "@typebot.io/tsconfig/base.json",
|
||||
"include": ["**/*.ts"],
|
||||
"exclude": ["node_modules"],
|
||||
"compilerOptions": {
|
||||
"lib": ["ES2021", "DOM"]
|
||||
}
|
||||
}
|
@ -1,14 +1,14 @@
|
||||
import { VideoBubbleBlock } from '@typebot.io/schemas'
|
||||
import {
|
||||
VideoBubbleContentType,
|
||||
gumletRegex,
|
||||
horizontalVideoSuggestionSize,
|
||||
oneDriveRegex,
|
||||
tiktokRegex,
|
||||
verticalVideoSuggestionSize,
|
||||
vimeoRegex,
|
||||
youtubeRegex,
|
||||
} from '@typebot.io/schemas/features/blocks/bubbles/video/constants'
|
||||
verticalVideoSuggestionSize,
|
||||
horizontalVideoSuggestionSize,
|
||||
vimeoRegex,
|
||||
tiktokRegex,
|
||||
gumletRegex,
|
||||
oneDriveRegex,
|
||||
} from './constants'
|
||||
import { VideoBubbleBlock } from './schema'
|
||||
|
||||
export const parseVideoUrl = (
|
||||
url: string
|
128
packages/schemas/helpers.ts
Normal file
128
packages/schemas/helpers.ts
Normal file
@ -0,0 +1,128 @@
|
||||
import { enabledBlocks } from '@typebot.io/forge-repository'
|
||||
import {
|
||||
Block,
|
||||
InputBlock,
|
||||
BubbleBlock,
|
||||
LogicBlock,
|
||||
TextBubbleBlock,
|
||||
ImageBubbleBlock,
|
||||
VideoBubbleBlock,
|
||||
TextInputBlock,
|
||||
ChoiceInputBlock,
|
||||
PictureChoiceBlock,
|
||||
ConditionBlock,
|
||||
IntegrationBlock,
|
||||
HttpRequestBlock,
|
||||
BlockWithOptionsType,
|
||||
} from './features/blocks'
|
||||
import { BubbleBlockType } from './features/blocks/bubbles/constants'
|
||||
import { defaultChoiceInputOptions } from './features/blocks/inputs/choice/constants'
|
||||
import { InputBlockType } from './features/blocks/inputs/constants'
|
||||
import { IntegrationBlockType } from './features/blocks/integrations/constants'
|
||||
import { LogicBlockType } from './features/blocks/logic/constants'
|
||||
import { Group } from './features/typebot/types'
|
||||
|
||||
export const isInputBlock = (block: Block): block is InputBlock =>
|
||||
(Object.values(InputBlockType) as string[]).includes(block.type)
|
||||
|
||||
export const isBubbleBlock = (block: Block): block is BubbleBlock =>
|
||||
(Object.values(BubbleBlockType) as string[]).includes(block.type)
|
||||
|
||||
export const isLogicBlock = (block: Block): block is LogicBlock =>
|
||||
(Object.values(LogicBlockType) as string[]).includes(block.type)
|
||||
|
||||
export const isTextBubbleBlock = (block: Block): block is TextBubbleBlock =>
|
||||
block.type === BubbleBlockType.TEXT
|
||||
|
||||
export const isMediaBubbleBlock = (
|
||||
block: Block
|
||||
): block is ImageBubbleBlock | VideoBubbleBlock =>
|
||||
block.type === BubbleBlockType.IMAGE || block.type === BubbleBlockType.VIDEO
|
||||
|
||||
export const isTextInputBlock = (block: Block): block is TextInputBlock =>
|
||||
block.type === InputBlockType.TEXT
|
||||
|
||||
export const isChoiceInput = (block: Block): block is ChoiceInputBlock =>
|
||||
block.type === InputBlockType.CHOICE
|
||||
|
||||
export const isPictureChoiceInput = (
|
||||
block: Block
|
||||
): block is PictureChoiceBlock => block.type === InputBlockType.PICTURE_CHOICE
|
||||
|
||||
export const isSingleChoiceInput = (block: Block): block is ChoiceInputBlock =>
|
||||
block.type === InputBlockType.CHOICE &&
|
||||
'options' in block &&
|
||||
!(
|
||||
block.options?.isMultipleChoice ??
|
||||
defaultChoiceInputOptions.isMultipleChoice
|
||||
)
|
||||
|
||||
export const isConditionBlock = (block: Block): block is ConditionBlock =>
|
||||
block.type === LogicBlockType.CONDITION
|
||||
|
||||
export const isIntegrationBlock = (block: Block): block is IntegrationBlock =>
|
||||
(
|
||||
Object.values(IntegrationBlockType).concat(
|
||||
enabledBlocks as readonly any[]
|
||||
) as any[]
|
||||
).includes(block.type)
|
||||
|
||||
export const isWebhookBlock = (block: Block): block is HttpRequestBlock =>
|
||||
[
|
||||
IntegrationBlockType.WEBHOOK,
|
||||
IntegrationBlockType.PABBLY_CONNECT,
|
||||
IntegrationBlockType.ZAPIER,
|
||||
IntegrationBlockType.MAKE_COM,
|
||||
].includes(block.type as IntegrationBlockType)
|
||||
|
||||
export const isBubbleBlockType = (
|
||||
type: Block['type']
|
||||
): type is BubbleBlockType =>
|
||||
(Object.values(BubbleBlockType) as string[]).includes(type)
|
||||
|
||||
export const blockTypeHasOption = (
|
||||
type: Block['type']
|
||||
): type is BlockWithOptionsType =>
|
||||
(Object.values(InputBlockType) as string[])
|
||||
.concat(Object.values(LogicBlockType))
|
||||
.concat(Object.values(IntegrationBlockType))
|
||||
.includes(type)
|
||||
|
||||
export const blockTypeHasItems = (
|
||||
type: Block['type']
|
||||
): type is
|
||||
| LogicBlockType.CONDITION
|
||||
| InputBlockType.CHOICE
|
||||
| LogicBlockType.AB_TEST =>
|
||||
type === LogicBlockType.CONDITION ||
|
||||
type === InputBlockType.CHOICE ||
|
||||
type === LogicBlockType.AB_TEST ||
|
||||
type === InputBlockType.PICTURE_CHOICE
|
||||
|
||||
export const blockHasItems = (
|
||||
block: Block
|
||||
): block is ConditionBlock | ChoiceInputBlock =>
|
||||
'items' in block && block.items !== undefined && block.items !== null
|
||||
|
||||
export const getBlockById = (
|
||||
blockId: string,
|
||||
groups: Group[]
|
||||
): { block: Block; group: Group; blockIndex: number; groupIndex: number } => {
|
||||
for (let groupIndex = 0; groupIndex < groups.length; groupIndex++) {
|
||||
for (
|
||||
let blockIndex = 0;
|
||||
blockIndex < (groups.at(groupIndex)?.blocks?.length ?? 0);
|
||||
blockIndex++
|
||||
) {
|
||||
if (groups.at(groupIndex)?.blocks?.at(blockIndex)?.id === blockId) {
|
||||
return {
|
||||
block: groups[groupIndex].blocks[blockIndex],
|
||||
group: groups[groupIndex],
|
||||
blockIndex,
|
||||
groupIndex,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Error(`Block with id ${blockId} was not found`)
|
||||
}
|
@ -1,11 +1,11 @@
|
||||
import { Plan, PrismaClient, WorkspaceRole } from '@typebot.io/prisma'
|
||||
import { isDefined, isEmpty } from '@typebot.io/lib'
|
||||
import { getChatsLimit } from '@typebot.io/lib/billing/getChatsLimit'
|
||||
import { getChatsLimit } from '@typebot.io/billing/getChatsLimit'
|
||||
import { promptAndSetEnvironment } from './utils'
|
||||
import { Workspace } from '@typebot.io/schemas'
|
||||
import { sendAlmostReachedChatsLimitEmail } from '@typebot.io/emails/src/emails/AlmostReachedChatsLimitEmail'
|
||||
import { TelemetryEvent } from '@typebot.io/schemas/features/telemetry'
|
||||
import { trackEvents } from '@typebot.io/lib/telemetry/trackEvents'
|
||||
import { trackEvents } from '@typebot.io/telemetry/trackEvents'
|
||||
import Stripe from 'stripe'
|
||||
import { createId } from '@paralleldrive/cuid2'
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { PrismaClient } from '@typebot.io/prisma'
|
||||
import { promptAndSetEnvironment } from './utils'
|
||||
import { archiveResults } from '@typebot.io/lib/api/helpers/archiveResults'
|
||||
import { archiveResults } from '@typebot.io/results/archiveResults'
|
||||
import { Typebot } from '@typebot.io/schemas'
|
||||
|
||||
const prisma = new PrismaClient()
|
||||
|
@ -1,9 +1,6 @@
|
||||
import Stripe from 'stripe'
|
||||
import { promptAndSetEnvironment } from './utils'
|
||||
import {
|
||||
proChatTiers,
|
||||
starterChatTiers,
|
||||
} from '@typebot.io/lib/billing/constants'
|
||||
import { proChatTiers, starterChatTiers } from '@typebot.io/billing/constants'
|
||||
|
||||
const chatsProductId = 'prod_MVXtq5sATQzIcM'
|
||||
|
||||
|
@ -9,9 +9,9 @@ import {
|
||||
resultWithAnswersSchema,
|
||||
} from '@typebot.io/schemas'
|
||||
import { byId } from '@typebot.io/lib'
|
||||
import { parseResultHeader } from '@typebot.io/lib/results/parseResultHeader'
|
||||
import { convertResultsToTableData } from '@typebot.io/lib/results/convertResultsToTableData'
|
||||
import { parseColumnsOrder } from '@typebot.io/lib/results/parseColumnsOrder'
|
||||
import { parseResultHeader } from '@typebot.io/results/parseResultHeader'
|
||||
import { convertResultsToTableData } from '@typebot.io/results/convertResultsToTableData'
|
||||
import { parseColumnsOrder } from '@typebot.io/results/parseColumnsOrder'
|
||||
import { parseUniqueKey } from '@typebot.io/lib/parseUniqueKey'
|
||||
import { unparse } from 'papaparse'
|
||||
import { z } from 'zod'
|
||||
|
@ -53,6 +53,9 @@
|
||||
"@clack/prompts": "^0.7.0",
|
||||
"@paralleldrive/cuid2": "2.2.1",
|
||||
"cli-progress": "^3.12.0",
|
||||
"papaparse": "5.4.1"
|
||||
"papaparse": "5.4.1",
|
||||
"@typebot.io/results": "workspace:*",
|
||||
"@typebot.io/billing": "workspace:*",
|
||||
"@typebot.io/telemetry": "workspace:*"
|
||||
}
|
||||
}
|
||||
|
18
packages/telemetry/package.json
Normal file
18
packages/telemetry/package.json
Normal file
@ -0,0 +1,18 @@
|
||||
{
|
||||
"name": "@typebot.io/telemetry",
|
||||
"version": "1.0.0",
|
||||
"description": "",
|
||||
"scripts": {},
|
||||
"keywords": [],
|
||||
"author": "Baptiste Arnaud",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"@typebot.io/schemas": "workspace:*",
|
||||
"got": "12.6.0",
|
||||
"posthog-node": "3.1.1",
|
||||
"@typebot.io/env": "workspace:*"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@typebot.io/tsconfig": "workspace:*"
|
||||
}
|
||||
}
|
8
packages/telemetry/tsconfig.json
Normal file
8
packages/telemetry/tsconfig.json
Normal file
@ -0,0 +1,8 @@
|
||||
{
|
||||
"extends": "@typebot.io/tsconfig/base.json",
|
||||
"include": ["**/*.ts"],
|
||||
"exclude": ["node_modules"],
|
||||
"compilerOptions": {
|
||||
"lib": ["ES2021", "DOM"]
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user