2
0

♻️ Remove @typebot.io/schemas from @typebot.io/lib

This commit is contained in:
Baptiste Arnaud
2024-03-15 16:32:29 +01:00
parent b53242ce6a
commit 5073be2439
186 changed files with 809 additions and 581 deletions

View 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:*"
}
}

View File

@ -0,0 +1,8 @@
{
"extends": "@typebot.io/tsconfig/base.json",
"include": ["**/*.ts"],
"exclude": ["node_modules"],
"compilerOptions": {
"lib": ["ES2021", "DOM"]
}
}

View File

@ -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'

View File

@ -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 }

View File

@ -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:

View File

@ -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'

View File

@ -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 = {

View File

@ -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'

View File

@ -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'

View File

@ -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:*",

View File

@ -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,

View File

@ -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,

View File

@ -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,

View File

@ -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[]

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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`)
}

View File

@ -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,

View File

@ -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,
}

View File

@ -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",

View File

@ -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 },
},
}

View File

@ -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

View File

@ -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)

View File

@ -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,

View File

@ -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

View 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:*"
}
}

View File

@ -0,0 +1,8 @@
{
"extends": "@typebot.io/tsconfig/base.json",
"include": ["**/*.ts"],
"exclude": ["node_modules"],
"compilerOptions": {
"lib": ["ES2021", "DOM"]
}
}

View File

@ -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'

View File

@ -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'

View File

@ -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()

View File

@ -0,0 +1,6 @@
import { setupDatabase, teardownDatabase } from './databaseSetup'
export const globalSetup = async () => {
await teardownDatabase()
await setupDatabase()
}

View 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:*"
}
}

View File

@ -0,0 +1,8 @@
{
"extends": "@typebot.io/tsconfig/base.json",
"include": ["**/*.ts"],
"exclude": ["node_modules"],
"compilerOptions": {
"lib": ["ES2021", "DOM"]
}
}

View File

@ -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 = {

View File

@ -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'],

View 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:*"
}
}

View File

@ -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,

View File

@ -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'>,

View File

@ -0,0 +1,8 @@
{
"extends": "@typebot.io/tsconfig/base.json",
"include": ["**/*.ts"],
"exclude": ["node_modules"],
"compilerOptions": {
"lib": ["ES2021", "DOM"]
}
}

View File

@ -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
View 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`)
}

View File

@ -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'

View File

@ -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()

View File

@ -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'

View File

@ -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'

View File

@ -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:*"
}
}

View 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:*"
}
}

View File

@ -0,0 +1,8 @@
{
"extends": "@typebot.io/tsconfig/base.json",
"include": ["**/*.ts"],
"exclude": ["node_modules"],
"compilerOptions": {
"lib": ["ES2021", "DOM"]
}
}