2
0

📝 Migrate from Docusaurus to Mintlify (#1115)

Closes #868
This commit is contained in:
Baptiste Arnaud
2023-12-22 09:13:53 +01:00
committed by GitHub
parent 512bb09282
commit 1e5fa5a575
450 changed files with 49522 additions and 104787 deletions

View File

@@ -25,6 +25,7 @@
"@giphy/js-util": "5.0.0",
"@giphy/react-components": "7.1.0",
"@googleapis/drive": "8.0.0",
"@lilyrose2798/trpc-openapi": "^1.3.9",
"@paralleldrive/cuid2": "2.2.1",
"@sentry/nextjs": "7.77.0",
"@tanstack/react-query": "4.29.19",
@@ -90,7 +91,6 @@
"svg-round-corners": "0.4.1",
"swr": "2.2.0",
"tinycolor2": "1.6.0",
"trpc-openapi": "1.2.0",
"unsplash-js": "7.0.18",
"use-debounce": "9.0.4"
},
@@ -102,9 +102,9 @@
"@typebot.io/forge-schemas": "workspace:*",
"@typebot.io/lib": "workspace:*",
"@typebot.io/prisma": "workspace:*",
"@typebot.io/radar": "workspace:*",
"@typebot.io/schemas": "workspace:*",
"@typebot.io/tsconfig": "workspace:*",
"@typebot.io/radar": "workspace:*",
"@types/canvas-confetti": "1.6.0",
"@types/jsonwebtoken": "9.0.2",
"@types/micro-cors": "0.1.3",

View File

@@ -24,7 +24,7 @@ export const getSubscription = authenticatedProcedure
)
.output(
z.object({
subscription: subscriptionSchema.or(z.null()),
subscription: subscriptionSchema.or(z.null().openapi({ type: 'string' })),
})
)
.query(async ({ input: { workspaceId }, ctx: { user } }) => {

View File

@@ -18,7 +18,11 @@ export const getUsage = authenticatedProcedure
})
.input(
z.object({
workspaceId: z.string(),
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
})
)
.output(z.object({ totalChatsUsed: z.number(), resetsAt: z.date() }))

View File

@@ -20,7 +20,11 @@ export const listInvoices = authenticatedProcedure
})
.input(
z.object({
workspaceId: z.string(),
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
})
)
.output(

View File

@@ -3,7 +3,6 @@ import { Plan } from '@typebot.io/prisma'
import { TextLink } from '@/components/TextLink'
import { useToast } from '@/hooks/useToast'
import { trpc } from '@/lib/trpc'
import { Workspace } from '@typebot.io/schemas'
import { PreCheckoutModal, PreCheckoutModalProps } from './PreCheckoutModal'
import { useState } from 'react'
import { ParentModalProvider } from '@/features/graph/providers/ParentModalProvider'
@@ -13,9 +12,10 @@ import { ProPlanPricingCard } from './ProPlanPricingCard'
import { useTranslate } from '@tolgee/react'
import { StripeClimateLogo } from './StripeClimateLogo'
import { guessIfUserIsEuropean } from '@typebot.io/lib/billing/guessIfUserIsEuropean'
import { WorkspaceInApp } from '@/features/workspace/WorkspaceProvider'
type Props = {
workspace: Workspace
workspace: WorkspaceInApp
excludedPlans?: ('STARTER' | 'PRO')[]
}

View File

@@ -9,15 +9,14 @@ import {
Tooltip,
} from '@chakra-ui/react'
import { AlertIcon } from '@/components/icons'
import { Workspace } from '@typebot.io/prisma'
import React from 'react'
import { WorkspaceInApp } from '@/features/workspace/WorkspaceProvider'
import { parseNumberWithCommas } from '@typebot.io/lib'
import { defaultQueryOptions, trpc } from '@/lib/trpc'
import { getChatsLimit } from '@typebot.io/lib/billing/getChatsLimit'
import { useTranslate } from '@tolgee/react'
type Props = {
workspace: Workspace
workspace: WorkspaceInApp
}
export const UsageProgressBars = ({ workspace }: Props) => {

View File

@@ -44,7 +44,7 @@ export const getHelpDocUrl = (
case IntegrationBlockType.CHATWOOT:
return 'https://docs.typebot.io/editor/blocks/integrations/chatwoot'
case IntegrationBlockType.GOOGLE_ANALYTICS:
return 'https://docs.typebot.io/editor/blocks/integrations/ga'
return 'https://docs.typebot.io/editor/blocks/integrations/google-analytics'
case IntegrationBlockType.GOOGLE_SHEETS:
return 'https://docs.typebot.io/editor/blocks/integrations/google-sheets'
case IntegrationBlockType.ZAPIER:

View File

@@ -37,7 +37,7 @@ export const ApiPreviewInstructions = (props: StackProps) => {
<OrderedList spacing={6} px="1">
<ListItem>
All your requests need to be authenticated with an API token.{' '}
<TextLink href="https://docs.typebot.io/api/builder/authenticate">
<TextLink href="https://docs.typebot.io/api-reference/authentication">
See instructions
</TextLink>
.
@@ -90,7 +90,7 @@ export const ApiPreviewInstructions = (props: StackProps) => {
<Text fontSize="sm" pl="1">
Check out the{' '}
<TextLink
href="https://docs.typebot.io/api/start-preview-chat"
href="https://docs.typebot.io/api-reference/chat/start-preview-chat"
isExternal
>
API reference

View File

@@ -79,7 +79,7 @@ export const WhatsAppPreviewInstructions = (props: StackProps) => {
<Text fontSize="sm">Need help?</Text>
<Button
as={Link}
href="https://docs.typebot.io/embed/whatsapp"
href="https://docs.typebot.io/deploy/whatsapp/overview"
leftIcon={<BuoyIcon />}
size="sm"
>

View File

@@ -154,7 +154,7 @@ export const PublishButton = ({
<Stack spacing="3">
<Text>
You are about to a deploy a version of your bot with an updated
engine. (Typebot V6).
engine (Typebot V6).
</Text>
<Text fontWeight="bold">
Make sure to check out all the{' '}

View File

@@ -86,7 +86,10 @@ export const ApiModal = ({
</OrderedList>
<Text fontSize="sm" colorScheme="gray">
Check out the{' '}
<TextLink href="https://docs.typebot.io/api/start-chat" isExternal>
<TextLink
href="https://docs.typebot.io/api-reference/chat/start-chat"
isExternal
>
API reference
</TextLink>{' '}
for more information

View File

@@ -30,7 +30,10 @@ export const WebflowPopupInstructions = () => {
</OrderedList>
<Text fontSize="sm" colorScheme="gray" pl="5">
Check out the{' '}
<TextLink href="https://docs.typebot.io/embed/webflow#popup" isExternal>
<TextLink
href="https://docs.typebot.io/deploy/web/webflow#popup"
isExternal
>
Webflow embed documentation
</TextLink>{' '}
for more options.

View File

@@ -302,7 +302,7 @@ const Requirements = () => (
<Text>
Make sure you have{' '}
<TextLink
href="https://docs.typebot.io/embed/whatsapp/create-meta-app"
href="https://docs.typebot.io/deploy/whatsapp/create-meta-app"
isExternal
>
created a WhatsApp Meta app

View File

@@ -18,7 +18,11 @@ export const deleteResults = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
resultIds: z
.string()
.describe(

View File

@@ -17,7 +17,11 @@ export const getResult = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
resultId: z.string(),
})
)

View File

@@ -16,7 +16,11 @@ export const getResultLogs = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
resultId: z.string(),
})
)

View File

@@ -19,7 +19,11 @@ export const getResults = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
limit: z.coerce.number().min(1).max(maxLimit).default(50),
cursor: z.string().optional(),
})

View File

@@ -18,7 +18,11 @@ export const deleteTypebot = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
})
)
.output(

View File

@@ -23,10 +23,15 @@ export const getPublishedTypebot = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
migrateToLatestVersion: z
.boolean()
.optional()
.default(false)
.describe(
'If enabled, the typebot will be converted to the latest schema version'
),
@@ -36,11 +41,14 @@ export const getPublishedTypebot = authenticatedProcedure
z.object({
publishedTypebot: publicTypebotSchema.nullable(),
version: z
.union([
publicTypebotSchemaV5._def.schema.shape.version,
publicTypebotSchemaV6.shape.version,
.enum([
...publicTypebotSchemaV5._def.schema.shape.version._def.values,
publicTypebotSchemaV6.shape.version._def.value,
])
.optional(),
.optional()
.describe(
'Provides the version the published bot was migrated from if `migrateToLatestVersion` is set to `true`.'
),
})
)
.query(

View File

@@ -20,10 +20,15 @@ export const getTypebot = publicProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
migrateToLatestVersion: z
.boolean()
.optional()
.default(false)
.describe(
'If enabled, the typebot will be converted to the latest schema version'
),

View File

@@ -35,14 +35,24 @@ const omittedProps = {
const importingTypebotSchema = z.preprocess(
preprocessTypebot,
z.discriminatedUnion('version', [
typebotV5Schema._def.schema.omit(omittedProps).extend({
resultsTablePreferences: resultsTablePreferencesSchema.nullish(),
selectedThemeTemplateId: z.string().nullish(),
}),
typebotV6Schema.omit(omittedProps).extend({
resultsTablePreferences: resultsTablePreferencesSchema.nullish(),
selectedThemeTemplateId: z.string().nullish(),
}),
typebotV6Schema
.omit(omittedProps)
.extend({
resultsTablePreferences: resultsTablePreferencesSchema.nullish(),
selectedThemeTemplateId: z.string().nullish(),
})
.openapi({
title: 'Typebot V6',
}),
typebotV5Schema._def.schema
.omit(omittedProps)
.extend({
resultsTablePreferences: resultsTablePreferencesSchema.nullish(),
selectedThemeTemplateId: z.string().nullish(),
})
.openapi({
title: 'Typebot V5',
}),
])
)
@@ -82,7 +92,11 @@ export const importTypebot = authenticatedProcedure
})
.input(
z.object({
workspaceId: z.string(),
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
typebot: importingTypebotSchema,
})
)

View File

@@ -17,7 +17,16 @@ export const listTypebots = authenticatedProcedure
tags: ['Typebot'],
},
})
.input(z.object({ workspaceId: z.string(), folderId: z.string().optional() }))
.input(
z.object({
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
folderId: z.string().optional(),
})
)
.output(
z.object({
typebots: z.array(

View File

@@ -29,7 +29,11 @@ export const publishTypebot = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
})
)
.output(

View File

@@ -16,7 +16,11 @@ export const unpublishTypebot = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
})
)
.output(

View File

@@ -51,10 +51,21 @@ export const updateTypebot = authenticatedProcedure
})
.input(
z.object({
typebotId: z.string(),
typebotId: z
.string()
.describe(
"[Where to find my bot's ID?](../how-to#how-to-find-my-typebotid)"
),
typebot: z.union([
typebotV5Schema._def.schema.pick(typebotUpdateSchemaPick).partial(),
typebotV6Schema.pick(typebotUpdateSchemaPick).partial(),
typebotV6Schema.pick(typebotUpdateSchemaPick).partial().openapi({
title: 'Typebot V6',
}),
typebotV5Schema._def.schema
.pick(typebotUpdateSchemaPick)
.partial()
.openapi({
title: 'Typebot V5',
}),
]),
updatedAt: z
.date()

View File

@@ -17,9 +17,22 @@ import { useTypebot } from '../editor/providers/TypebotProvider'
import { setWorkspaceIdInLocalStorage } from './helpers/setWorkspaceIdInLocalStorage'
import { parseNewName } from './helpers/parseNewName'
export type WorkspaceInApp = Omit<
Workspace,
| 'chatsLimitFirstEmailSentAt'
| 'chatsLimitSecondEmailSentAt'
| 'storageLimitFirstEmailSentAt'
| 'storageLimitSecondEmailSentAt'
| 'customChatsLimit'
| 'customStorageLimit'
| 'additionalChatsIndex'
| 'additionalStorageIndex'
| 'isQuarantined'
>
const workspaceContext = createContext<{
workspaces: Pick<Workspace, 'id' | 'name' | 'icon' | 'plan'>[]
workspace?: Workspace
workspace?: WorkspaceInApp
currentRole?: WorkspaceRole
switchWorkspace: (workspaceId: string) => void
createWorkspace: (name?: string) => Promise<void>

View File

@@ -19,7 +19,18 @@ export const createWorkspace = authenticatedProcedure
.input(z.object({ icon: z.string().optional(), name: z.string() }))
.output(
z.object({
workspace: workspaceSchema,
workspace: workspaceSchema.omit({
chatsLimitFirstEmailSentAt: true,
chatsLimitSecondEmailSentAt: true,
storageLimitFirstEmailSentAt: true,
storageLimitSecondEmailSentAt: true,
customChatsLimit: true,
customSeatsLimit: true,
customStorageLimit: true,
additionalChatsIndex: true,
additionalStorageIndex: true,
isQuarantined: true,
}),
})
)
.mutation(async ({ input: { name, icon }, ctx: { user } }) => {

View File

@@ -16,7 +16,11 @@ export const deleteWorkspace = authenticatedProcedure
})
.input(
z.object({
workspaceId: z.string(),
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
})
)
.output(

View File

@@ -17,12 +17,26 @@ export const getWorkspace = authenticatedProcedure
})
.input(
z.object({
workspaceId: z.string(),
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
})
)
.output(
z.object({
workspace: workspaceSchema,
workspace: workspaceSchema.omit({
chatsLimitFirstEmailSentAt: true,
chatsLimitSecondEmailSentAt: true,
storageLimitFirstEmailSentAt: true,
storageLimitSecondEmailSentAt: true,
customChatsLimit: true,
customStorageLimit: true,
additionalChatsIndex: true,
additionalStorageIndex: true,
isQuarantined: true,
}),
})
)
.query(async ({ input: { workspaceId }, ctx: { user } }) => {

View File

@@ -17,7 +17,11 @@ export const listInvitationsInWorkspace = authenticatedProcedure
})
.input(
z.object({
workspaceId: z.string(),
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
})
)
.output(

View File

@@ -17,7 +17,11 @@ export const listMembersInWorkspace = authenticatedProcedure
})
.input(
z.object({
workspaceId: z.string(),
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
})
)
.output(

View File

@@ -19,12 +19,16 @@ export const updateWorkspace = authenticatedProcedure
z.object({
name: z.string().optional(),
icon: z.string().optional(),
workspaceId: z.string(),
workspaceId: z
.string()
.describe(
'[Where to find my workspace ID?](../how-to#how-to-find-my-workspaceid)'
),
})
)
.output(
z.object({
workspace: workspaceSchema,
workspace: workspaceSchema.pick({ name: true, icon: true }),
})
)
.mutation(async ({ input: { workspaceId, ...updates }, ctx: { user } }) => {

View File

@@ -17,10 +17,10 @@ import {
MenuItem,
Text,
} from '@chakra-ui/react'
import { Workspace } from '@typebot.io/schemas'
import { WorkspaceInApp } from '../WorkspaceProvider'
type Props = {
currentWorkspace?: Workspace
currentWorkspace?: WorkspaceInApp
onWorkspaceSelected: (workspaceId: string) => void
onCreateNewWorkspaceClick: () => void
onLogoutClick: () => void

View File

@@ -6,6 +6,10 @@ import {
Button,
useDisclosure,
Text,
Input,
InputGroup,
InputRightElement,
FormHelperText,
} from '@chakra-ui/react'
import { ConfirmModal } from '@/components/ConfirmModal'
import React from 'react'
@@ -13,6 +17,7 @@ import { EditableEmojiOrImageIcon } from '@/components/EditableEmojiOrImageIcon'
import { useWorkspace } from '../WorkspaceProvider'
import { TextInput } from '@/components/inputs'
import { useTranslate } from '@tolgee/react'
import { CopyButton } from '@/components/CopyButton'
export const WorkspaceSettingsForm = ({ onClose }: { onClose: () => void }) => {
const { t } = useTranslate()
@@ -50,12 +55,31 @@ export const WorkspaceSettingsForm = ({ onClose }: { onClose: () => void }) => {
</Flex>
</FormControl>
{workspace && (
<TextInput
label={t('workspace.settings.name.label')}
withVariableButton={false}
defaultValue={workspace?.name}
onChange={handleNameChange}
/>
<>
<TextInput
label={t('workspace.settings.name.label')}
withVariableButton={false}
defaultValue={workspace?.name}
onChange={handleNameChange}
/>
<FormControl>
<FormLabel>ID:</FormLabel>
<InputGroup>
<Input
type={'text'}
defaultValue={workspace.id}
pr="16"
readOnly
/>
<InputRightElement width="72px">
<CopyButton textToCopy={workspace.id} size="xs" />
</InputRightElement>
</InputGroup>
<FormHelperText>
Used when interacting with the Typebot API.
</FormHelperText>
</FormControl>
</>
)}
{workspace && workspaces && workspaces.length > 1 && (
<DeleteWorkspaceButton

View File

@@ -15,11 +15,11 @@ import {
UsersIcon,
} from '@/components/icons'
import { EmojiOrImageIcon } from '@/components/EmojiOrImageIcon'
import { User, Workspace, WorkspaceRole } from '@typebot.io/prisma'
import { User, WorkspaceRole } from '@typebot.io/prisma'
import { useState } from 'react'
import { MembersList } from './MembersList'
import { WorkspaceSettingsForm } from './WorkspaceSettingsForm'
import { useWorkspace } from '../WorkspaceProvider'
import { WorkspaceInApp, useWorkspace } from '../WorkspaceProvider'
import packageJson from '../../../../../../package.json'
import { UserPreferencesForm } from '@/features/account/components/UserPreferencesForm'
import { MyAccountForm } from '@/features/account/components/MyAccountForm'
@@ -29,7 +29,7 @@ import { useTranslate } from '@tolgee/react'
type Props = {
isOpen: boolean
user: User
workspace: Workspace
workspace: WorkspaceInApp
onClose: () => void
}

View File

@@ -1,4 +1,4 @@
import { generateOpenApiDocument } from 'trpc-openapi'
import { generateOpenApiDocument } from '@lilyrose2798/trpc-openapi'
import { writeFileSync } from 'fs'
import { publicRouter } from './routers/publicRouter'
@@ -6,10 +6,10 @@ const openApiDocument = generateOpenApiDocument(publicRouter, {
title: 'Builder API',
version: '1.0.0',
baseUrl: 'https://app.typebot.io/api',
docsUrl: 'https://docs.typebot.io/api',
docsUrl: 'https://docs.typebot.io/api-reference',
})
writeFileSync(
'./openapi/builder/_spec_.json',
'./openapi/builder.json',
JSON.stringify(openApiDocument, null, 2)
)

View File

@@ -1,6 +1,6 @@
import { TRPCError, initTRPC } from '@trpc/server'
import { Context } from './context'
import { OpenApiMeta } from 'trpc-openapi'
import { OpenApiMeta } from '@lilyrose2798/trpc-openapi'
import superjson from 'superjson'
import * as Sentry from '@sentry/nextjs'
import { ZodError } from 'zod'

View File

@@ -1,7 +1,7 @@
import { createContext } from '@/helpers/server/context'
import * as Sentry from '@sentry/nextjs'
import { NextApiRequest, NextApiResponse } from 'next'
import { createOpenApiNextHandler } from 'trpc-openapi'
import { createOpenApiNextHandler } from '@lilyrose2798/trpc-openapi'
import cors from 'nextjs-cors'
import { publicRouter } from '@/helpers/server/routers/publicRouter'