diff --git a/apps/chat-api/package.json b/apps/chat-api/package.json deleted file mode 100644 index f4dcdd6d8..000000000 --- a/apps/chat-api/package.json +++ /dev/null @@ -1,36 +0,0 @@ -{ - "name": "chat-api", - "version": "1.0.0", - "license": "AGPL-3.0-or-later", - "private": true, - "scripts": { - "dev": "dotenv -e ./.env -e ../../.env -- bun --hot src/index.ts", - "build": "dotenv -e ./.env -e ../../.env -- bun build --target=bun ./src/index.ts --outdir ./dist", - "start": "bun src/index.ts" - }, - "dependencies": { - "@hono/prometheus": "1.0.0", - "@hono/sentry": "1.0.1", - "@hono/typebox-validator": "0.2.2", - "@sinclair/typebox": "0.32.5", - "@trpc/server": "10.40.0", - "@typebot.io/bot-engine": "workspace:*", - "@typebot.io/env": "workspace:*", - "@typebot.io/forge": "workspace:*", - "@typebot.io/forge-repository": "workspace:*", - "@typebot.io/lib": "workspace:*", - "@typebot.io/prisma": "workspace:*", - "@typebot.io/schemas": "workspace:*", - "@typebot.io/variables": "workspace:*", - "ai": "3.0.31", - "hono": "4.0.5", - "openai": "4.38.3", - "prom-client": "15.1.0" - }, - "devDependencies": { - "dotenv-cli": "7.2.1", - "@typebot.io/tsconfig": "workspace:*", - "@types/react": "18.2.15", - "react": "18.2.0" - } -} diff --git a/apps/chat-api/src/auth.ts b/apps/chat-api/src/auth.ts deleted file mode 100644 index d71e112c0..000000000 --- a/apps/chat-api/src/auth.ts +++ /dev/null @@ -1,30 +0,0 @@ -import { env } from '@typebot.io/env' -import { mockedUser } from '@typebot.io/lib/mockedUser' -import prisma from '@typebot.io/lib/prisma' - -export const getAuthenticatedUserId = async ( - authorizationHeaderValue: string | undefined -): Promise => { - if (env.NEXT_PUBLIC_E2E_TEST) return mockedUser.id - const bearerToken = extractBearerToken(authorizationHeaderValue) - if (!bearerToken) return - return authenticateByToken(bearerToken) -} - -const authenticateByToken = async ( - token: string -): Promise => { - if (typeof window !== 'undefined') return - const apiToken = await prisma.apiToken.findFirst({ - where: { - token, - }, - select: { - ownerId: true, - }, - }) - return apiToken?.ownerId -} - -const extractBearerToken = (authorizationHeaderValue: string | undefined) => - authorizationHeaderValue?.slice(7) diff --git a/apps/chat-api/src/index.ts b/apps/chat-api/src/index.ts deleted file mode 100644 index d5d0545a7..000000000 --- a/apps/chat-api/src/index.ts +++ /dev/null @@ -1,36 +0,0 @@ -import { Hono } from 'hono' -import { webRuntime } from './runtimes/web' -import { whatsAppRuntime } from './runtimes/whatsapp' -import { prometheus } from '@hono/prometheus' -import { sentry } from '@hono/sentry' -import { env } from '@typebot.io/env' -import prisma from '@typebot.io/lib/prisma' - -const app = new Hono() - -app.use( - '*', - sentry({ - environment: env.NODE_ENV, - dsn: env.NEXT_PUBLIC_SENTRY_DSN, - }) -) - -const { printMetrics, registerMetrics } = prometheus() -app.use('*', registerMetrics) -app.get('/metrics', async (c) => { - const honoMetrics = await (await printMetrics(c)).text() - const prismaMetrics = await prisma.$metrics.prometheus() - return c.text(`${honoMetrics}\n\n${prismaMetrics}`, 200) -}) - -app.get('/ping', (c) => c.json({ status: 'ok' }, 200)) - -app.route('/', webRuntime) - -app.route('/', whatsAppRuntime) - -export default { - port: process.env.PORT ?? 3002, - fetch: app.fetch, -} diff --git a/apps/chat-api/src/runtimes/web.ts b/apps/chat-api/src/runtimes/web.ts deleted file mode 100644 index d0ec6c641..000000000 --- a/apps/chat-api/src/runtimes/web.ts +++ /dev/null @@ -1,132 +0,0 @@ -import { startChat } from '@typebot.io/bot-engine/apiHandlers/startChat' -import { continueChat } from '@typebot.io/bot-engine/apiHandlers/continueChat' -import { startChatPreview } from '@typebot.io/bot-engine/apiHandlers/startChatPreview' -import { getMessageStream } from '@typebot.io/bot-engine/apiHandlers/getMessageStream' -import { Hono } from 'hono' -import { cors } from 'hono/cors' -import { tbValidator } from '@hono/typebox-validator' -import { Type as t } from '@sinclair/typebox' -import { getAuthenticatedUserId } from '../auth' - -export const webRuntime = new Hono() - -webRuntime.use('*', cors()) - -webRuntime.post( - '/api/v1/typebots/:publicId/startChat', - tbValidator( - 'json', - t.Object({ - message: t.Optional(t.String()), - isStreamEnabled: t.Optional(t.Boolean()), - resultId: t.Optional(t.String()), - isOnlyRegistering: t.Optional(t.Boolean()), - prefilledVariables: t.Optional(t.Record(t.String(), t.Unknown())), - }), - (result, c) => { - if (!result.success) return c.json({ message: 'Invalid input' }, 400) - } - ), - async (c) => { - const data = c.req.valid('json') - const { corsOrigin, ...response } = await startChat({ - ...data, - publicId: c.req.param('publicId'), - isStreamEnabled: data.isStreamEnabled ?? true, - isOnlyRegistering: data.isOnlyRegistering ?? false, - origin: c.req.header('origin'), - }) - if (corsOrigin) c.res.headers.set('Access-Control-Allow-Origin', corsOrigin) - return c.json(response) - } -) - -webRuntime.post( - '/api/v1/typebots/:id/preview/startChat', - tbValidator( - 'json', - t.Object({ - message: t.Optional(t.String()), - isStreamEnabled: t.Optional(t.Boolean()), - resultId: t.Optional(t.String()), - isOnlyRegistering: t.Optional(t.Boolean()), - prefilledVariables: t.Optional(t.Record(t.String(), t.Unknown())), - startFrom: t.Optional( - t.Union([ - t.Object({ - type: t.Literal('group'), - groupId: t.String(), - }), - t.Object({ - type: t.Literal('event'), - eventId: t.String(), - }), - ]) - ), - typebot: t.Optional(t.Any()), - }), - (result, c) => { - if (!result.success) return c.json({ message: 'Invalid input' }, 400) - } - ), - async (c) => { - const data = c.req.valid('json') - const userId = !data.typebot - ? await getAuthenticatedUserId(c.req.header('Authorization')) - : undefined - return c.json( - await startChatPreview({ - ...data, - typebotId: c.req.param('id'), - userId, - isStreamEnabled: data.isStreamEnabled ?? true, - isOnlyRegistering: data.isOnlyRegistering ?? false, - }) - ) - } -) - -webRuntime.post( - '/api/v1/sessions/:sessionId/continueChat', - tbValidator( - 'json', - t.Object({ - message: t.Optional(t.String()), - }), - (result, c) => { - if (!result.success) return c.json({ message: 'Invalid input' }, 400) - } - ), - async (c) => { - const data = c.req.valid('json') - const { corsOrigin, ...response } = await continueChat({ - ...data, - sessionId: c.req.param('sessionId'), - origin: c.req.header('origin'), - }) - if (corsOrigin) c.res.headers.set('Access-Control-Allow-Origin', corsOrigin) - return c.json(response) - } -) - -webRuntime.post( - '/api/v1/sessions/:sessionId/streamMessage', - tbValidator( - 'json', - t.Object({ - messages: t.Optional(t.Array(t.Any())), - }), - (result, c) => { - if (!result.success) return c.json({ message: 'Invalid input' }, 400) - } - ), - async (c) => { - const data = c.req.valid('json') - const { stream, status, message } = await getMessageStream({ - sessionId: c.req.param('sessionId'), - messages: data.messages, - }) - if (!stream) return c.json({ message }, (status ?? 400) as ResponseInit) - return new Response(stream) - } -) diff --git a/apps/chat-api/src/runtimes/whatsapp.ts b/apps/chat-api/src/runtimes/whatsapp.ts deleted file mode 100644 index d0d764abb..000000000 --- a/apps/chat-api/src/runtimes/whatsapp.ts +++ /dev/null @@ -1,51 +0,0 @@ -import { receiveMessage } from '@typebot.io/bot-engine/apiHandlers/receiveMessage' -import { receiveMessagePreview } from '@typebot.io/bot-engine/apiHandlers/receiveMessagePreview' -import { tbValidator } from '@hono/typebox-validator' -import { Hono } from 'hono' -import { Type as t } from '@sinclair/typebox' - -export const whatsAppRuntime = new Hono() - -whatsAppRuntime.post( - '/api/v1/workspaces/:workspaceId/whatsapp/:credentialsId/webhook', - tbValidator( - 'json', - t.Object({ - object: t.String(), - entry: t.Any(), - }), - (result, c) => { - if (!result.success) return c.json({ message: 'Invalid input' }, 400) - } - ), - async (c) => { - const data = c.req.valid('json') - receiveMessage({ - workspaceId: c.req.param('workspaceId'), - credentialsId: c.req.param('credentialsId'), - ...data, - }) - return c.json({ message: 'Webhook received' }, 200) - } -) - -whatsAppRuntime.post( - '/api/v1/whatsapp/preview/webhook', - tbValidator( - 'json', - t.Object({ - object: t.String(), - entry: t.Any(), - }), - (result, c) => { - if (!result.success) return c.json({ message: 'Invalid input' }, 400) - } - ), - async (c) => { - const data = c.req.valid('json') - receiveMessagePreview({ - ...data, - }) - return c.json({ message: 'Webhook received' }, 200) - } -) diff --git a/apps/chat-api/tsconfig.json b/apps/chat-api/tsconfig.json deleted file mode 100644 index 8d02ef5be..000000000 --- a/apps/chat-api/tsconfig.json +++ /dev/null @@ -1,8 +0,0 @@ -{ - "extends": "@typebot.io/tsconfig/base.json", - "include": ["src/**/*.ts"], - "exclude": ["node_modules"], - "compilerOptions": { - "jsx": "react" - } -} diff --git a/chatApi.Dockerfile b/chatApi.Dockerfile deleted file mode 100644 index 36d58771f..000000000 --- a/chatApi.Dockerfile +++ /dev/null @@ -1,21 +0,0 @@ -FROM oven/bun - -WORKDIR /app - -COPY . . - -RUN apt-get -qy update && apt-get -qy --no-install-recommends install openssl ca-certificates git iputils-ping iptables -y && update-ca-certificates - -RUN bun install - -# Need Node for Prisma -COPY --from=node:18 /usr/local/bin/node /usr/local/bin/node -RUN bun /app/packages/prisma/scripts/db-exec.ts "bunx prisma generate" - -RUN rm -rf /usr/local/bin/node -RUN rm -rf /app/apps/builder -RUN rm -rf /app/apps/viewer - -ENV PORT=3000 -EXPOSE 3000 -CMD ["bun", "run", "apps/chat-api/src/index.ts"] diff --git a/package.json b/package.json index 06a129a09..323997213 100644 --- a/package.json +++ b/package.json @@ -16,7 +16,7 @@ "docker:up": "docker compose -f docker-compose.dev.yml up -d && node -e \"setTimeout(() => {}, 5000)\"", "docker:nuke": "docker compose -f docker-compose.dev.yml down --volumes --remove-orphans", "lint": "turbo run lint", - "dev": "pnpm docker:up && turbo build --filter=@typebot.io/nextjs... && turbo run dev --filter=builder... --filter=viewer... --filter=chat-api... --parallel --no-cache", + "dev": "pnpm docker:up && turbo build --filter=@typebot.io/nextjs... && turbo run dev --filter=builder... --filter=viewer... --parallel --no-cache", "build": "pnpm docker:up && turbo run build", "build:apps": "turbo run build --filter=builder... --filter=viewer...", "db:migrate": "cd packages/prisma && pnpm run db:migrate", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9438d08f5..d3605829a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -379,73 +379,6 @@ importers: specifier: 3.22.4 version: 3.22.4 - apps/chat-api: - dependencies: - '@hono/prometheus': - specifier: 1.0.0 - version: 1.0.0(hono@4.0.5)(prom-client@15.1.0) - '@hono/sentry': - specifier: 1.0.1 - version: 1.0.1(hono@4.0.5) - '@hono/typebox-validator': - specifier: 0.2.2 - version: 0.2.2(@sinclair/typebox@0.32.5)(hono@4.0.5) - '@sinclair/typebox': - specifier: 0.32.5 - version: 0.32.5 - '@trpc/server': - specifier: 10.40.0 - version: 10.40.0 - '@typebot.io/bot-engine': - specifier: workspace:* - version: link:../../packages/bot-engine - '@typebot.io/env': - specifier: workspace:* - version: link:../../packages/env - '@typebot.io/forge': - specifier: workspace:* - version: link:../../packages/forge/core - '@typebot.io/forge-repository': - specifier: workspace:* - version: link:../../packages/forge/repository - '@typebot.io/lib': - specifier: workspace:* - version: link:../../packages/lib - '@typebot.io/prisma': - specifier: workspace:* - version: link:../../packages/prisma - '@typebot.io/schemas': - specifier: workspace:* - version: link:../../packages/schemas - '@typebot.io/variables': - specifier: workspace:* - version: link:../../packages/variables - ai: - specifier: 3.0.31 - version: 3.0.31(react@18.2.0)(solid-js@1.7.8)(svelte@4.2.12)(vue@3.4.21)(zod@3.22.4) - hono: - specifier: 4.0.5 - version: 4.0.5 - openai: - specifier: 4.38.3 - version: 4.38.3 - prom-client: - specifier: 15.1.0 - version: 15.1.0 - devDependencies: - '@typebot.io/tsconfig': - specifier: workspace:* - version: link:../../packages/tsconfig - '@types/react': - specifier: 18.2.15 - version: 18.2.15 - dotenv-cli: - specifier: 7.2.1 - version: 7.2.1 - react: - specifier: 18.2.0 - version: 18.2.0 - apps/docs: devDependencies: dotenv-cli: @@ -6673,35 +6606,6 @@ packages: - supports-color dev: false - /@hono/prometheus@1.0.0(hono@4.0.5)(prom-client@15.1.0): - resolution: {integrity: sha512-cB4TklEw3CVqOdgLYenl6g4TM1YwYimrE044azQmVLLq7arfJfnWupvzev42LM1+ntlhsAAwS0TfpjSdnQBggw==} - peerDependencies: - hono: ^3.12.0 - prom-client: ^15.0.0 - dependencies: - hono: 4.0.5 - prom-client: 15.1.0 - dev: false - - /@hono/sentry@1.0.1(hono@4.0.5): - resolution: {integrity: sha512-4JgwdyasCQIoH3lhl4yLNxrP4/SElfK01ZV3JUaMvexVJnyAOPuXDhtJasl9Gssg7qDNt8ZIDDjqmVrOwS+AIw==} - peerDependencies: - hono: '>=3.*' - dependencies: - hono: 4.0.5 - toucan-js: 3.3.1 - dev: false - - /@hono/typebox-validator@0.2.2(@sinclair/typebox@0.32.5)(hono@4.0.5): - resolution: {integrity: sha512-6hLnF9Pe+nOWSvX5SIhobZ9Wt7vjTT3sjqDZ5lKALf+9J9XMtNzDyMSjpM5SQv8gg+fOPHu/ZSYxxmUhl65QOg==} - peerDependencies: - '@sinclair/typebox': ^0.31.15 - hono: '>=3.9.0' - dependencies: - '@sinclair/typebox': 0.32.5 - hono: 4.0.5 - dev: false - /@humanwhocodes/config-array@0.11.14: resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} @@ -7923,11 +7827,6 @@ packages: /@one-ini/wasm@0.1.1: resolution: {integrity: sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==} - /@opentelemetry/api@1.8.0: - resolution: {integrity: sha512-I/s6F7yKUDdtMsoBWXJe8Qz40Tui5vsuKCWJEWVL+5q9sSWRzzx6v2KeNsOBEwd94j0eWkpWCH4yB6rZg9Mf0w==} - engines: {node: '>=8.0.0'} - dev: false - /@panva/hkdf@1.1.1: resolution: {integrity: sha512-dhPeilub1NuIG0X5Kvhh9lH4iW3ZsHlnzwgwbOlgwQ2wG1IqFzsgHqmKPk3WzsdWAeaxKJxgM0+W433RmN45GA==} dev: false @@ -9038,14 +8937,6 @@ packages: - supports-color dev: false - /@sentry/core@7.76.0: - resolution: {integrity: sha512-M+ptkCTeCNf6fn7p2MmEb1Wd9/JXUWxIT/0QEc+t11DNR4FYy1ZP2O9Zb3Zp2XacO7ORrlL3Yc+VIfl5JTgjfw==} - engines: {node: '>=8'} - dependencies: - '@sentry/types': 7.76.0 - '@sentry/utils': 7.76.0 - dev: false - /@sentry/core@7.77.0: resolution: {integrity: sha512-Tj8oTYFZ/ZD+xW8IGIsU6gcFXD/gfE+FUxUaeSosd9KHwBQNOLhZSsYo/tTVf/rnQI/dQnsd4onPZLiL+27aTg==} engines: {node: '>=8'} @@ -9054,16 +8945,6 @@ packages: '@sentry/utils': 7.77.0 dev: false - /@sentry/integrations@7.76.0: - resolution: {integrity: sha512-4ea0PNZrGN9wKuE/8bBCRrxxw4Cq5T710y8rhdKHAlSUpbLqr/atRF53h8qH3Fi+ec0m38PB+MivKem9zUwlwA==} - engines: {node: '>=8'} - dependencies: - '@sentry/core': 7.76.0 - '@sentry/types': 7.76.0 - '@sentry/utils': 7.76.0 - localforage: 1.10.0 - dev: false - /@sentry/integrations@7.77.0: resolution: {integrity: sha512-P055qXgBHeZNKnnVEs5eZYLdy6P49Zr77A1aWJuNih/EenzMy922GOeGy2mF6XYrn1YJSjEwsNMNsQkcvMTK8Q==} engines: {node: '>=8'} @@ -9141,23 +9022,11 @@ packages: '@sentry/utils': 7.77.0 dev: false - /@sentry/types@7.76.0: - resolution: {integrity: sha512-vj6z+EAbVrKAXmJPxSv/clpwS9QjPqzkraMFk2hIdE/kii8s8kwnkBwTSpIrNc8GnzV3qYC4r3qD+BXDxAGPaw==} - engines: {node: '>=8'} - dev: false - /@sentry/types@7.77.0: resolution: {integrity: sha512-nfb00XRJVi0QpDHg+JkqrmEBHsqBnxJu191Ded+Cs1OJ5oPXEW6F59LVcBScGvMqe+WEk1a73eH8XezwfgrTsA==} engines: {node: '>=8'} dev: false - /@sentry/utils@7.76.0: - resolution: {integrity: sha512-40jFD+yfQaKpFYINghdhovzec4IEpB7aAuyH/GtE7E0gLpcqnC72r55krEIVILfqIR2Mlr5OKUzyeoCyWAU/yw==} - engines: {node: '>=8'} - dependencies: - '@sentry/types': 7.76.0 - dev: false - /@sentry/utils@7.77.0: resolution: {integrity: sha512-NmM2kDOqVchrey3N5WSzdQoCsyDkQkiRxExPaNI2oKQ/jMWHs9yt0tSy7otPBcXs0AP59ihl75Bvm1tDRcsp5g==} engines: {node: '>=8'} @@ -9189,10 +9058,6 @@ packages: resolution: {integrity: sha512-+Fj43pSMwJs4KRrH/938Uf+uAELIgVBmQzg/q1YG10djyfA3TnrU8N8XzqCh/okZdszqBQTZf96idMfE5lnwTA==} dev: true - /@sinclair/typebox@0.32.5: - resolution: {integrity: sha512-0M6FyxZwIEu/Ly6W+l7iYqiZQYJ8khLOJGzg+cxivNKRKqk9hctcuDC0UYI7B9vNgycExA8w40m4M3yDKW37RA==} - dev: false - /@sindresorhus/is@5.6.0: resolution: {integrity: sha512-TV7t8GKYaJWsn00tFDqBw8+Uqmr8A0fRU1tvTQhyZzGv0sJCGRQL3JGMI3ucuKo3XIZdUP+Lx7/gh2t3lewy7g==} engines: {node: '>=14.16'} @@ -11764,10 +11629,6 @@ packages: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} - /bintrees@1.0.2: - resolution: {integrity: sha512-VOMgTMwjAaUG580SXn3LacVgjurrbMme7ZZNYGSSV7mmtY6QQRh0Eg3pwIcntQ77DErK1L0NxkbetjcoXzVwKw==} - dev: false - /bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} dependencies: @@ -15293,11 +15154,6 @@ packages: resolution: {integrity: sha512-KZFBHenkVuyyG4uaqRSXqWJr3HTxcaPguM7rU1BlH/mtbDlzaXNSXTa9AhV+fXEjrNemHu9vtLRIaM8/8OW0xA==} dev: true - /hono@4.0.5: - resolution: {integrity: sha512-6LEGL1Pf3+dLjVA0NJxAB/3FJ6S3W5qxd/XOG7Wl9YOrpMRZT9lt83R4Ojs8dO6GbAUSutI7zTyjStnSn9sbEg==} - engines: {node: '>=16.0.0'} - dev: false - /hosted-git-info@2.8.9: resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} @@ -19938,14 +19794,6 @@ packages: engines: {node: '>=0.4.0'} dev: false - /prom-client@15.1.0: - resolution: {integrity: sha512-cCD7jLTqyPdjEPBo/Xk4Iu8jxjuZgZJ3e/oET3L+ZwOuap/7Cw3dH/TJSsZKs1TQLZ2IHpIlRAKw82ef06kmMw==} - engines: {node: ^16 || ^18 || >=20} - dependencies: - '@opentelemetry/api': 1.8.0 - tdigest: 0.1.2 - dev: false - /promise.series@0.2.0: resolution: {integrity: sha512-VWQJyU2bcDTgZw8kpfBpB/ejZASlCrzwz5f2hjb/zlujOEB4oeiAhHygAWq8ubsX2GVkD4kCU5V2dwOTaCY5EQ==} engines: {node: '>=0.12'} @@ -21984,12 +21832,6 @@ packages: yallist: 4.0.0 dev: true - /tdigest@0.1.2: - resolution: {integrity: sha512-+G0LLgjjo9BZX2MfdvPfH+MKLCrxlXSYec5DaPYP1fe6Iyhf0/fSmJ0bFiZ1F8BT6cGXl2LpltQptzjXKWEkKA==} - dependencies: - bintrees: 1.0.2 - dev: false - /terser-webpack-plugin@5.3.10(@swc/core@1.3.101)(esbuild@0.19.11)(webpack@5.90.3): resolution: {integrity: sha512-BKFPWlPDndPs+NGGCr1U59t0XScL5317Y0UReNrHaw9/FwhPENlq6bfgs+4yPfyP51vqC1bQ4rp1EfXW5ZSH9w==} engines: {node: '>= 10.13.0'} @@ -22117,15 +21959,6 @@ packages: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} engines: {node: '>=0.6'} - /toucan-js@3.3.1: - resolution: {integrity: sha512-9BpkHb/Pzsrtl1ItNq9OEQPnuUHwzce0nV2uG+DYFiQ4fPyiA6mKTBcDwQzcvNkfSER038U+8TzvdkCev+Maww==} - dependencies: - '@sentry/core': 7.76.0 - '@sentry/integrations': 7.76.0 - '@sentry/types': 7.76.0 - '@sentry/utils': 7.76.0 - dev: false - /tough-cookie@4.1.3: resolution: {integrity: sha512-aX/y5pVRkfRnfmuX+OdbSdXvPe6ieKX/G2s7e98f4poJHnqH3281gDPm/metm6E/WRamfx7WC4HUqkWHfQHprw==} engines: {node: '>=6'}