mirror of
https://github.com/chathub-dev/chathub.git
synced 2025-12-24 12:37:53 +08:00
Add poe bot
This commit is contained in:
1
global.d.ts
vendored
Normal file
1
global.d.ts
vendored
Normal file
@@ -0,0 +1 @@
|
||||
declare module '*.gql'
|
||||
@@ -14,6 +14,7 @@
|
||||
"@parcel/config-webextension": "^2.8.3",
|
||||
"@parcel/optimizer-data-url": "2.8.3",
|
||||
"@parcel/transformer-inline-string": "2.8.3",
|
||||
"@rollup/plugin-graphql": "^2.0.3",
|
||||
"@types/lodash-es": "^4.17.6",
|
||||
"@types/react": "^18.0.28",
|
||||
"@types/react-copy-to-clipboard": "^5.0.4",
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
import { BardBot } from './bard'
|
||||
import { BingWebBot } from './bing'
|
||||
import { ChatGPTBot } from './chatgpt'
|
||||
import { ChatGPTApiBot } from './chatgpt-api'
|
||||
import { PoeWebBot } from './poe'
|
||||
|
||||
export type BotId = 'chatgpt' | 'bing' | 'bard'
|
||||
|
||||
const botClasses: Record<BotId, typeof ChatGPTApiBot | typeof BingWebBot | typeof BardBot> = {
|
||||
chatgpt: ChatGPTBot,
|
||||
bing: BingWebBot,
|
||||
bard: BardBot,
|
||||
}
|
||||
export type BotId = 'chatgpt' | 'bing' | 'bard' | 'claude'
|
||||
|
||||
export function createBotInstance(botId: BotId) {
|
||||
return new botClasses[botId]()
|
||||
switch (botId) {
|
||||
case 'chatgpt':
|
||||
return new ChatGPTBot()
|
||||
case 'bing':
|
||||
return new BingWebBot()
|
||||
case 'bard':
|
||||
return new BardBot()
|
||||
case 'claude':
|
||||
return new PoeWebBot()
|
||||
}
|
||||
}
|
||||
|
||||
64
src/app/bots/poe/api.ts
Normal file
64
src/app/bots/poe/api.ts
Normal file
@@ -0,0 +1,64 @@
|
||||
import { ofetch } from 'ofetch'
|
||||
import ChatViewQuery from './graphql/ChatViewQuery.graphql?raw'
|
||||
import AddMessageBreakMutation from './graphql/AddMessageBreakMutation.graphql?raw'
|
||||
import SendMessageMutation from './graphql/SendMessageMutation.graphql?raw'
|
||||
import SubscriptionsMutation from './graphql/SubscriptionsMutation.graphql?raw'
|
||||
import MessageAddedSubscription from './graphql/MessageAddedSubscription.graphql?raw'
|
||||
import ViewerStateUpdatedSubscription from './graphql/ViewerStateUpdatedSubscription.graphql?raw'
|
||||
import { ChatError, ErrorCode } from '~utils/errors'
|
||||
|
||||
export const GRAPHQL_QUERIES = {
|
||||
AddMessageBreakMutation,
|
||||
ChatViewQuery,
|
||||
SendMessageMutation,
|
||||
SubscriptionsMutation,
|
||||
MessageAddedSubscription,
|
||||
ViewerStateUpdatedSubscription,
|
||||
}
|
||||
|
||||
export interface PoeSettings {
|
||||
formkey: string
|
||||
tchannelData: ChannelData
|
||||
}
|
||||
|
||||
interface ChannelData {
|
||||
minSeq: string
|
||||
channel: string
|
||||
channelHash: string
|
||||
boxName: string
|
||||
baseHost: string
|
||||
targetUrl: string
|
||||
enableWebsocket: boolean
|
||||
}
|
||||
|
||||
export async function getPoeSettings() {
|
||||
return ofetch<PoeSettings>('https://poe.com/api/settings')
|
||||
}
|
||||
|
||||
export interface GqlHeaders {
|
||||
formkey: string
|
||||
tchannel: string
|
||||
}
|
||||
|
||||
export async function gqlRequest(queryName: keyof typeof GRAPHQL_QUERIES, variables: any, poeSettings: PoeSettings) {
|
||||
const query = GRAPHQL_QUERIES[queryName]
|
||||
return ofetch('https://poe.com/api/gql_POST', {
|
||||
method: 'POST',
|
||||
body: {
|
||||
query,
|
||||
variables,
|
||||
},
|
||||
headers: {
|
||||
'poe-formkey': poeSettings.formkey,
|
||||
'poe-tchannel': poeSettings.tchannelData.channel,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
export async function getChatId(bot: string, poeSettings: PoeSettings): Promise<number> {
|
||||
const resp = await gqlRequest('ChatViewQuery', { bot }, poeSettings)
|
||||
if (!resp.data) {
|
||||
throw new ChatError('You need to login to Poe first', ErrorCode.POE_UNAUTHORIZED)
|
||||
}
|
||||
return resp.data.chatOfBot.chatId
|
||||
}
|
||||
17
src/app/bots/poe/graphql/AddMessageBreakMutation.graphql
Normal file
17
src/app/bots/poe/graphql/AddMessageBreakMutation.graphql
Normal file
@@ -0,0 +1,17 @@
|
||||
mutation AddMessageBreakMutation($chatId: BigInt!) {
|
||||
messageBreakCreate(chatId: $chatId) {
|
||||
message {
|
||||
id
|
||||
__typename
|
||||
messageId
|
||||
text
|
||||
linkifiedText
|
||||
authorNickname
|
||||
state
|
||||
vote
|
||||
voteReason
|
||||
creationTime
|
||||
suggestedReplies
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
mutation AutoSubscriptionMutation($subscriptions: [AutoSubscriptionQuery!]!) {
|
||||
autoSubscribe(subscriptions: $subscriptions) {
|
||||
viewer {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
8
src/app/bots/poe/graphql/ChatViewQuery.graphql
Normal file
8
src/app/bots/poe/graphql/ChatViewQuery.graphql
Normal file
@@ -0,0 +1,8 @@
|
||||
query ChatViewQuery($bot: String!) {
|
||||
chatOfBot(bot: $bot) {
|
||||
id
|
||||
chatId
|
||||
defaultBotNickname
|
||||
shouldShowDisclaimer
|
||||
}
|
||||
}
|
||||
98
src/app/bots/poe/graphql/MessageAddedSubscription.graphql
Normal file
98
src/app/bots/poe/graphql/MessageAddedSubscription.graphql
Normal file
@@ -0,0 +1,98 @@
|
||||
subscription messageAdded($chatId: BigInt!) {
|
||||
messageAdded(chatId: $chatId) {
|
||||
id
|
||||
messageId
|
||||
creationTime
|
||||
state
|
||||
...ChatMessage_message
|
||||
...chatHelpers_isBotMessage
|
||||
}
|
||||
}
|
||||
|
||||
fragment ChatMessageDownvotedButton_message on Message {
|
||||
...MessageFeedbackReasonModal_message
|
||||
...MessageFeedbackOtherModal_message
|
||||
}
|
||||
|
||||
fragment ChatMessageDropdownMenu_message on Message {
|
||||
id
|
||||
messageId
|
||||
vote
|
||||
text
|
||||
linkifiedText
|
||||
...chatHelpers_isBotMessage
|
||||
}
|
||||
|
||||
fragment ChatMessageFeedbackButtons_message on Message {
|
||||
id
|
||||
messageId
|
||||
vote
|
||||
voteReason
|
||||
...ChatMessageDownvotedButton_message
|
||||
}
|
||||
|
||||
fragment ChatMessageOverflowButton_message on Message {
|
||||
text
|
||||
...ChatMessageDropdownMenu_message
|
||||
...chatHelpers_isBotMessage
|
||||
}
|
||||
|
||||
fragment ChatMessageSuggestedReplies_SuggestedReplyButton_message on Message {
|
||||
messageId
|
||||
}
|
||||
|
||||
fragment ChatMessageSuggestedReplies_message on Message {
|
||||
suggestedReplies
|
||||
...ChatMessageSuggestedReplies_SuggestedReplyButton_message
|
||||
}
|
||||
|
||||
fragment ChatMessage_message on Message {
|
||||
id
|
||||
messageId
|
||||
text
|
||||
author
|
||||
linkifiedText
|
||||
state
|
||||
...ChatMessageSuggestedReplies_message
|
||||
...ChatMessageFeedbackButtons_message
|
||||
...ChatMessageOverflowButton_message
|
||||
...chatHelpers_isHumanMessage
|
||||
...chatHelpers_isBotMessage
|
||||
...chatHelpers_isChatBreak
|
||||
...chatHelpers_useTimeoutLevel
|
||||
...MarkdownLinkInner_message
|
||||
}
|
||||
|
||||
fragment MarkdownLinkInner_message on Message {
|
||||
messageId
|
||||
}
|
||||
|
||||
fragment MessageFeedbackOtherModal_message on Message {
|
||||
id
|
||||
messageId
|
||||
}
|
||||
|
||||
fragment MessageFeedbackReasonModal_message on Message {
|
||||
id
|
||||
messageId
|
||||
}
|
||||
|
||||
fragment chatHelpers_isBotMessage on Message {
|
||||
...chatHelpers_isHumanMessage
|
||||
...chatHelpers_isChatBreak
|
||||
}
|
||||
|
||||
fragment chatHelpers_isChatBreak on Message {
|
||||
author
|
||||
}
|
||||
|
||||
fragment chatHelpers_isHumanMessage on Message {
|
||||
author
|
||||
}
|
||||
|
||||
fragment chatHelpers_useTimeoutLevel on Message {
|
||||
id
|
||||
state
|
||||
text
|
||||
messageId
|
||||
}
|
||||
40
src/app/bots/poe/graphql/SendMessageMutation.graphql
Normal file
40
src/app/bots/poe/graphql/SendMessageMutation.graphql
Normal file
@@ -0,0 +1,40 @@
|
||||
mutation chatHelpers_sendMessageMutation_Mutation(
|
||||
$chatId: BigInt!
|
||||
$bot: String!
|
||||
$query: String!
|
||||
$source: MessageSource
|
||||
$withChatBreak: Boolean!
|
||||
) {
|
||||
messageEdgeCreate(chatId: $chatId, bot: $bot, query: $query, source: $source, withChatBreak: $withChatBreak) {
|
||||
chatBreak {
|
||||
cursor
|
||||
node {
|
||||
id
|
||||
messageId
|
||||
text
|
||||
author
|
||||
suggestedReplies
|
||||
creationTime
|
||||
state
|
||||
}
|
||||
id
|
||||
}
|
||||
message {
|
||||
cursor
|
||||
node {
|
||||
id
|
||||
messageId
|
||||
text
|
||||
author
|
||||
suggestedReplies
|
||||
creationTime
|
||||
state
|
||||
chat {
|
||||
shouldShowDisclaimer
|
||||
id
|
||||
}
|
||||
}
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
7
src/app/bots/poe/graphql/SubscriptionsMutation.graphql
Normal file
7
src/app/bots/poe/graphql/SubscriptionsMutation.graphql
Normal file
@@ -0,0 +1,7 @@
|
||||
mutation subscriptionsMutation($subscriptions: [AutoSubscriptionQuery!]!) {
|
||||
autoSubscribe(subscriptions: $subscriptions) {
|
||||
viewer {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,43 @@
|
||||
subscription viewerStateUpdated {
|
||||
viewerStateUpdated {
|
||||
id
|
||||
...ChatPageBotSwitcher_viewer
|
||||
}
|
||||
}
|
||||
|
||||
fragment BotHeader_bot on Bot {
|
||||
displayName
|
||||
messageLimit {
|
||||
dailyLimit
|
||||
}
|
||||
...BotImage_bot
|
||||
}
|
||||
|
||||
fragment BotImage_bot on Bot {
|
||||
image {
|
||||
__typename
|
||||
... on LocalBotImage {
|
||||
localName
|
||||
}
|
||||
... on UrlBotImage {
|
||||
url
|
||||
}
|
||||
}
|
||||
displayName
|
||||
}
|
||||
|
||||
fragment BotLink_bot on Bot {
|
||||
displayName
|
||||
}
|
||||
|
||||
fragment ChatPageBotSwitcher_viewer on Viewer {
|
||||
availableBots {
|
||||
id
|
||||
messageLimit {
|
||||
dailyLimit
|
||||
}
|
||||
...BotLink_bot
|
||||
...BotHeader_bot
|
||||
}
|
||||
allowUserCreatedBots: booleanGate(gateName: "enable_user_created_bots")
|
||||
}
|
||||
149
src/app/bots/poe/index.ts
Normal file
149
src/app/bots/poe/index.ts
Normal file
@@ -0,0 +1,149 @@
|
||||
import WebSocketAsPromised from 'websocket-as-promised'
|
||||
import { requestHostPermission } from '~app/utils/permissions'
|
||||
import { AbstractBot, SendMessageParams } from '../abstract-bot'
|
||||
import { GRAPHQL_QUERIES, PoeSettings, getChatId, getPoeSettings, gqlRequest } from './api'
|
||||
import { ChatError, ErrorCode } from '~utils/errors'
|
||||
|
||||
const BOT_ID = 'a2' // Claude-instant
|
||||
|
||||
interface ChatMessage {
|
||||
id: string
|
||||
author: string
|
||||
text: string
|
||||
state: 'complete' | 'incomplete'
|
||||
messageId: number
|
||||
}
|
||||
|
||||
interface WebsocketMessage {
|
||||
message_type: 'subscriptionUpdate'
|
||||
payload: {
|
||||
subscription_name: 'messageAdded'
|
||||
unique_id: string
|
||||
data: {
|
||||
messageAdded: ChatMessage
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
interface ConversationContext {
|
||||
poeSettings: PoeSettings
|
||||
chatId: number // user specific chat id for the bot
|
||||
wsp: WebSocketAsPromised
|
||||
}
|
||||
|
||||
export class PoeWebBot extends AbstractBot {
|
||||
private conversationContext?: ConversationContext
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
}
|
||||
|
||||
async doSendMessage(params: SendMessageParams) {
|
||||
if (!(await requestHostPermission('https://*.poe.com/'))) {
|
||||
throw new ChatError('Missing poe.com permission', ErrorCode.MISSING_POE_HOST_PERMISSION)
|
||||
}
|
||||
|
||||
if (!this.conversationContext) {
|
||||
const { poeSettings, chatId } = await this.getChatInfo()
|
||||
const wsp = await this.connectWebsocket(poeSettings)
|
||||
await this.subscribe(poeSettings)
|
||||
this.conversationContext = { chatId, poeSettings, wsp }
|
||||
}
|
||||
|
||||
const wsp = this.conversationContext.wsp
|
||||
|
||||
const onUnpackedMessageListener = (data: any) => {
|
||||
console.debug('onUnpackedMessage', data)
|
||||
const messages: WebsocketMessage[] = data.messages.map((s: string) => JSON.parse(s))
|
||||
for (const m of messages) {
|
||||
if (m.message_type === 'subscriptionUpdate' && m.payload.subscription_name === 'messageAdded') {
|
||||
const chatMessage = m.payload.data.messageAdded
|
||||
console.log(chatMessage)
|
||||
params.onEvent({
|
||||
type: 'UPDATE_ANSWER',
|
||||
data: { text: chatMessage.text },
|
||||
})
|
||||
if (chatMessage.state === 'complete') {
|
||||
params.onEvent({ type: 'DONE' })
|
||||
wsp.onUnpackedMessage.removeAllListeners()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wsp.onUnpackedMessage.addListener(onUnpackedMessageListener)
|
||||
|
||||
await wsp.open()
|
||||
await this.sendMessageRequest(params.prompt)
|
||||
}
|
||||
|
||||
resetConversation() {
|
||||
if (!this.conversationContext) {
|
||||
return
|
||||
}
|
||||
const wsp = this.conversationContext.wsp
|
||||
wsp.removeAllListeners()
|
||||
wsp.close()
|
||||
this.sendChatBreak()
|
||||
this.conversationContext = undefined
|
||||
}
|
||||
|
||||
private async getChatInfo() {
|
||||
const poeSettings = await getPoeSettings()
|
||||
const chatId = await getChatId(BOT_ID, poeSettings)
|
||||
return { poeSettings, chatId }
|
||||
}
|
||||
|
||||
private async sendMessageRequest(message: string) {
|
||||
const { poeSettings, chatId } = this.conversationContext!
|
||||
await gqlRequest(
|
||||
'SendMessageMutation',
|
||||
{
|
||||
bot: BOT_ID,
|
||||
chatId,
|
||||
query: message,
|
||||
source: null,
|
||||
withChatBreak: false,
|
||||
},
|
||||
poeSettings,
|
||||
)
|
||||
}
|
||||
|
||||
private async sendChatBreak() {
|
||||
const { chatId, poeSettings } = this.conversationContext!
|
||||
await gqlRequest('AddMessageBreakMutation', { chatId }, poeSettings)
|
||||
}
|
||||
|
||||
private async subscribe(poeSettings: PoeSettings) {
|
||||
await gqlRequest(
|
||||
'SubscriptionsMutation',
|
||||
{
|
||||
subscriptions: [
|
||||
{
|
||||
subscriptionName: 'messageAdded',
|
||||
query: GRAPHQL_QUERIES.MessageAddedSubscription,
|
||||
},
|
||||
],
|
||||
},
|
||||
poeSettings,
|
||||
)
|
||||
}
|
||||
|
||||
private async getWebsocketUrl(poeSettings: PoeSettings) {
|
||||
const domain = `tch${Math.floor(Math.random() * 1000000) + 1}`
|
||||
const channel = poeSettings.tchannelData
|
||||
return `wss://${domain}.tch.${channel.baseHost}/up/${channel.boxName}/updates?min_seq=${channel.minSeq}&channel=${channel.channel}&hash=${channel.channelHash}`
|
||||
}
|
||||
|
||||
private async connectWebsocket(poeSettings: PoeSettings) {
|
||||
const wsUrl = await this.getWebsocketUrl(poeSettings)
|
||||
console.debug('ws url', wsUrl)
|
||||
|
||||
const wsp = new WebSocketAsPromised(wsUrl, {
|
||||
packMessage: (data) => JSON.stringify(data),
|
||||
unpackMessage: (data) => JSON.parse(data as string),
|
||||
})
|
||||
|
||||
return wsp
|
||||
}
|
||||
}
|
||||
@@ -54,6 +54,13 @@ const ErrorAction: FC<{ error: ChatError }> = ({ error }) => {
|
||||
</a>
|
||||
)
|
||||
}
|
||||
if (error.code === ErrorCode.POE_UNAUTHORIZED) {
|
||||
return (
|
||||
<a href="https://poe.com" target="_blank" rel="noreferrer">
|
||||
<Button color="primary" text="Login at poe.com" size="small" />
|
||||
</a>
|
||||
)
|
||||
}
|
||||
if (error.code === ErrorCode.CHATGPT_CLOUDFLARE || error.code === ErrorCode.CHATGPT_UNAUTHORIZED) {
|
||||
return <ChatGPTAuthErrorAction />
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ import settingIcon from '~/assets/icons/setting.svg'
|
||||
import logo from '~/assets/logo.svg'
|
||||
import NavLink from './NavLink'
|
||||
import CommandBar from '../CommandBar'
|
||||
import { CHATBOTS } from '~app/consts'
|
||||
|
||||
function IconButton(props: { icon: string }) {
|
||||
return (
|
||||
@@ -19,9 +20,9 @@ function Sidebar() {
|
||||
<img src={logo} className="w-[79px] mb-[55px] mt-[66px] ml-5" />
|
||||
<div className="flex flex-col gap-3">
|
||||
<NavLink to="/" text="All-In-One" />
|
||||
<NavLink to="/chat/$botId" params={{ botId: 'chatgpt' }} text="ChatGPT" />
|
||||
<NavLink to="/chat/$botId" params={{ botId: 'bing' }} text="Bing" />
|
||||
<NavLink to="/chat/$botId" params={{ botId: 'bard' }} text="Bard" />
|
||||
{Object.entries(CHATBOTS).map(([botId, bot]) => (
|
||||
<NavLink key={botId} to="/chat/$botId" params={{ botId }} text={bot.name} />
|
||||
))}
|
||||
</div>
|
||||
<div className="mt-auto">
|
||||
<hr className="border-[#ffffff4d]" />
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import chatgptLogo from '~/assets/chatgpt-logo.svg'
|
||||
import bingLogo from '~/assets/bing-logo.svg'
|
||||
import bardLogo from '~/assets/bard-logo.svg'
|
||||
import claudeLogo from '~/assets/anthropic-logo.png'
|
||||
import { BotId } from './bots'
|
||||
|
||||
export const CHATBOTS: Record<BotId, { name: string; avatar: any }> = {
|
||||
@@ -16,6 +17,10 @@ export const CHATBOTS: Record<BotId, { name: string; avatar: any }> = {
|
||||
name: 'Bard',
|
||||
avatar: bardLogo,
|
||||
},
|
||||
claude: {
|
||||
name: 'Claude',
|
||||
avatar: claudeLogo,
|
||||
},
|
||||
}
|
||||
|
||||
export const CHATGPT_HOME_URL = 'https://chat.openai.com/chat'
|
||||
|
||||
@@ -111,6 +111,7 @@ function SettingPage() {
|
||||
{ name: 'ChatGPT', value: StartupPage.ChatGPT },
|
||||
{ name: 'Bing', value: StartupPage.Bing },
|
||||
{ name: 'Bard', value: StartupPage.Bard },
|
||||
{ name: 'Claude', value: StartupPage.Claude },
|
||||
]}
|
||||
value={userConfig.startupPage}
|
||||
onChange={(v) => updateConfigValue({ startupPage: v })}
|
||||
|
||||
5
src/app/utils/permissions.ts
Normal file
5
src/app/utils/permissions.ts
Normal file
@@ -0,0 +1,5 @@
|
||||
import Browser from 'webextension-polyfill'
|
||||
|
||||
export async function requestHostPermission(host: string) {
|
||||
return Browser.permissions.request({ origins: [host] })
|
||||
}
|
||||
BIN
src/assets/anthropic-logo.png
Normal file
BIN
src/assets/anthropic-logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 4.6 KiB |
@@ -7,6 +7,7 @@ export enum StartupPage {
|
||||
ChatGPT = 'chatgpt',
|
||||
Bing = 'bing',
|
||||
Bard = 'bard',
|
||||
Claude = 'claude',
|
||||
}
|
||||
|
||||
export enum BingConversationStyle {
|
||||
|
||||
@@ -7,6 +7,8 @@ export enum ErrorCode {
|
||||
BING_FORBIDDEN = 'BING_FORBIDDEN',
|
||||
API_KEY_NOT_SET = 'API_KEY_NOT_SET',
|
||||
BARD_EMPTY_RESPONSE = 'BARD_EMPTY_RESPONSE',
|
||||
MISSING_POE_HOST_PERMISSION = 'MISSING_POE_HOST_PERMISSION',
|
||||
POE_UNAUTHORIZED = 'POE_UNAUTHORIZED',
|
||||
}
|
||||
|
||||
export class ChatError extends Error {
|
||||
|
||||
31
yarn.lock
31
yarn.lock
@@ -1764,6 +1764,14 @@
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.13.10"
|
||||
|
||||
"@rollup/plugin-graphql@^2.0.3":
|
||||
version "2.0.3"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/plugin-graphql/-/plugin-graphql-2.0.3.tgz#35fea077e225e2982ce8483dd6c381e8cca03aea"
|
||||
integrity sha512-IuuELo+0t29adRuLVg8izBFiUXFSFw8BmezespscynRfvfXSOV0S7g8RzQt75VzP6KHHVmNmlAgz+8qlkLur3w==
|
||||
dependencies:
|
||||
"@rollup/pluginutils" "^5.0.1"
|
||||
graphql-tag "^2.12.6"
|
||||
|
||||
"@rollup/pluginutils@^4.1.2":
|
||||
version "4.2.1"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-4.2.1.tgz#e6c6c3aba0744edce3fb2074922d3776c0af2a6d"
|
||||
@@ -1772,6 +1780,15 @@
|
||||
estree-walker "^2.0.1"
|
||||
picomatch "^2.2.2"
|
||||
|
||||
"@rollup/pluginutils@^5.0.1":
|
||||
version "5.0.2"
|
||||
resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.0.2.tgz#012b8f53c71e4f6f9cb317e311df1404f56e7a33"
|
||||
integrity sha512-pTd9rIsP92h+B6wWwFbW8RkZv4hiR/xKsqre4SIuAOaOEQRxi0lqLke9k2/7WegC85GgUs9pjmOjCUi3In4vwA==
|
||||
dependencies:
|
||||
"@types/estree" "^1.0.0"
|
||||
estree-walker "^2.0.2"
|
||||
picomatch "^2.3.1"
|
||||
|
||||
"@swc/helpers@^0.4.12":
|
||||
version "0.4.14"
|
||||
resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.4.14.tgz#1352ac6d95e3617ccb7c1498ff019654f1e12a74"
|
||||
@@ -1823,6 +1840,11 @@
|
||||
dependencies:
|
||||
"@types/ms" "*"
|
||||
|
||||
"@types/estree@^1.0.0":
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.0.tgz#5fb2e536c1ae9bf35366eed879e827fa59ca41c2"
|
||||
integrity sha512-WulqXMDUTYAXCjZnk6JtIHPigp55cVtDgDrO2gHRwhyJto21+1zbVCtOYB2L1F9w4qCQ0rOGWBnBe0FNTiEJIQ==
|
||||
|
||||
"@types/hast@^2.0.0":
|
||||
version "2.3.4"
|
||||
resolved "https://registry.yarnpkg.com/@types/hast/-/hast-2.3.4.tgz#8aa5ef92c117d20d974a82bdfb6a648b08c0bafc"
|
||||
@@ -3013,7 +3035,7 @@ estraverse@^5.1.0, estraverse@^5.2.0, estraverse@^5.3.0:
|
||||
resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-5.3.0.tgz#2eea5290702f26ab8fe5370370ff86c965d21123"
|
||||
integrity sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==
|
||||
|
||||
estree-walker@^2.0.1:
|
||||
estree-walker@^2.0.1, estree-walker@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac"
|
||||
integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==
|
||||
@@ -3315,6 +3337,13 @@ grapheme-splitter@^1.0.4:
|
||||
resolved "https://registry.yarnpkg.com/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz#9cf3a665c6247479896834af35cf1dbb4400767e"
|
||||
integrity sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==
|
||||
|
||||
graphql-tag@^2.12.6:
|
||||
version "2.12.6"
|
||||
resolved "https://registry.yarnpkg.com/graphql-tag/-/graphql-tag-2.12.6.tgz#d441a569c1d2537ef10ca3d1633b48725329b5f1"
|
||||
integrity sha512-FdSNcu2QQcWnM2VNvSCCDCVS5PpPqpzgFT8+GXzqJuoDd0CBncxCY278u4mhRO7tMgo2JjgJA5aZ+nWSQ/Z+xg==
|
||||
dependencies:
|
||||
tslib "^2.1.0"
|
||||
|
||||
has-bigints@^1.0.1, has-bigints@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/has-bigints/-/has-bigints-1.0.2.tgz#0871bd3e3d51626f6ca0966668ba35d5602d6eaa"
|
||||
|
||||
Reference in New Issue
Block a user