From 17778f5a1424bcb07332d8f1fb73e4dc7a69d1ee Mon Sep 17 00:00:00 2001 From: josc146 Date: Thu, 27 Apr 2023 20:31:53 +0800 Subject: [PATCH] refactor: services --- src/background/commands.mjs | 27 ++ src/background/index.mjs | 292 ++++-------------- src/background/menus.mjs | 73 +++++ src/components/ConversationCard/index.jsx | 5 +- src/content-script/index.jsx | 44 +-- src/pages/IndependentPanel/App.jsx | 2 +- .../apis/azure-openai-api.mjs | 4 +- .../apis/bing-web.mjs | 2 +- .../apis/chatgpt-web.mjs | 2 +- .../apis/custom-api.mjs | 4 +- .../apis/openai-api.mjs | 4 +- src/{background => services}/apis/poe-web.mjs | 2 +- src/{background => services}/apis/shared.mjs | 0 .../apis/waylaidwanderer-api.mjs | 2 +- .../clients/bing/index.mjs | 0 .../graphql/AddHumanMessageMutation.graphql | 0 .../graphql/AddMessageBreakMutation.graphql | 0 .../graphql/AutoSubscriptionMutation.graphql | 0 .../clients/poe/graphql/BioFragment.graphql | 0 .../poe/graphql/ChatAddedSubscription.graphql | 0 .../clients/poe/graphql/ChatFragment.graphql | 0 .../poe/graphql/ChatPaginationQuery.graphql | 0 .../clients/poe/graphql/ChatViewQuery.graphql | 0 .../DeleteHumanMessagesMutation.graphql | 0 .../poe/graphql/HandleFragment.graphql | 0 .../LoginWithVerificationCodeMutation.graphql | 0 .../graphql/MessageAddedSubscription.graphql | 0 .../MessageDeletedSubscription.graphql | 0 .../poe/graphql/MessageFragment.graphql | 0 .../graphql/MessageRemoveVoteMutation.graphql | 0 .../graphql/MessageSetVoteMutation.graphql | 0 ...ndVerificationCodeForLoginMutation.graphql | 0 .../poe/graphql/ShareMessagesMutation.graphql | 0 ...SignupWithVerificationCodeMutation.graphql | 0 .../graphql/StaleChatUpdateMutation.graphql | 0 .../graphql/SummarizePlainPostQuery.graphql | 0 .../graphql/SummarizeQuotePostQuery.graphql | 0 .../graphql/SummarizeSharePostQuery.graphql | 0 .../poe/graphql/UserSnippetFragment.graphql | 0 .../poe/graphql/ViewerInfoQuery.graphql | 0 .../poe/graphql/ViewerStateFragment.graphql | 0 .../ViewerStateUpdatedSubscription.graphql | 0 .../clients/poe/index.mjs | 0 .../clients/poe/websocket.js | 0 src/{utils => services}/init-session.mjs | 0 .../local-session.mjs} | 4 +- src/services/wrappers.mjs | 73 +++++ src/utils/index.mjs | 1 - 48 files changed, 272 insertions(+), 269 deletions(-) create mode 100644 src/background/commands.mjs create mode 100644 src/background/menus.mjs rename src/{background => services}/apis/azure-openai-api.mjs (97%) rename src/{background => services}/apis/bing-web.mjs (98%) rename src/{background => services}/apis/chatgpt-web.mjs (98%) rename src/{background => services}/apis/custom-api.mjs (97%) rename src/{background => services}/apis/openai-api.mjs (98%) rename src/{background => services}/apis/poe-web.mjs (95%) rename src/{background => services}/apis/shared.mjs (100%) rename src/{background => services}/apis/waylaidwanderer-api.mjs (98%) rename src/{background => services}/clients/bing/index.mjs (100%) rename src/{background => services}/clients/poe/graphql/AddHumanMessageMutation.graphql (100%) rename src/{background => services}/clients/poe/graphql/AddMessageBreakMutation.graphql (100%) rename src/{background => services}/clients/poe/graphql/AutoSubscriptionMutation.graphql (100%) rename src/{background => services}/clients/poe/graphql/BioFragment.graphql (100%) rename src/{background => services}/clients/poe/graphql/ChatAddedSubscription.graphql (100%) rename src/{background => services}/clients/poe/graphql/ChatFragment.graphql (100%) rename src/{background => services}/clients/poe/graphql/ChatPaginationQuery.graphql (100%) rename src/{background => services}/clients/poe/graphql/ChatViewQuery.graphql (100%) rename src/{background => services}/clients/poe/graphql/DeleteHumanMessagesMutation.graphql (100%) rename src/{background => services}/clients/poe/graphql/HandleFragment.graphql (100%) rename src/{background => services}/clients/poe/graphql/LoginWithVerificationCodeMutation.graphql (100%) rename src/{background => services}/clients/poe/graphql/MessageAddedSubscription.graphql (100%) rename src/{background => services}/clients/poe/graphql/MessageDeletedSubscription.graphql (100%) rename src/{background => services}/clients/poe/graphql/MessageFragment.graphql (100%) rename src/{background => services}/clients/poe/graphql/MessageRemoveVoteMutation.graphql (100%) rename src/{background => services}/clients/poe/graphql/MessageSetVoteMutation.graphql (100%) rename src/{background => services}/clients/poe/graphql/SendVerificationCodeForLoginMutation.graphql (100%) rename src/{background => services}/clients/poe/graphql/ShareMessagesMutation.graphql (100%) rename src/{background => services}/clients/poe/graphql/SignupWithVerificationCodeMutation.graphql (100%) rename src/{background => services}/clients/poe/graphql/StaleChatUpdateMutation.graphql (100%) rename src/{background => services}/clients/poe/graphql/SummarizePlainPostQuery.graphql (100%) rename src/{background => services}/clients/poe/graphql/SummarizeQuotePostQuery.graphql (100%) rename src/{background => services}/clients/poe/graphql/SummarizeSharePostQuery.graphql (100%) rename src/{background => services}/clients/poe/graphql/UserSnippetFragment.graphql (100%) rename src/{background => services}/clients/poe/graphql/ViewerInfoQuery.graphql (100%) rename src/{background => services}/clients/poe/graphql/ViewerStateFragment.graphql (100%) rename src/{background => services}/clients/poe/graphql/ViewerStateUpdatedSubscription.graphql (100%) rename src/{background => services}/clients/poe/index.mjs (100%) rename src/{background => services}/clients/poe/websocket.js (100%) rename src/{utils => services}/init-session.mjs (100%) rename src/{config/localSession.mjs => services/local-session.mjs} (95%) create mode 100644 src/services/wrappers.mjs diff --git a/src/background/commands.mjs b/src/background/commands.mjs new file mode 100644 index 0000000..9264910 --- /dev/null +++ b/src/background/commands.mjs @@ -0,0 +1,27 @@ +import Browser from 'webextension-polyfill' +import { config as menuConfig } from '../content-script/menu-tools/index.mjs' + +export function registerCommands() { + Browser.commands.onCommand.addListener(async (command) => { + const message = { + itemId: command, + selectionText: '', + useMenuPosition: false, + } + console.debug('command triggered', message) + + if (command in menuConfig) { + if (menuConfig[command].action) { + menuConfig[command].action() + } + + if (menuConfig[command].genPrompt) { + const currentTab = (await Browser.tabs.query({ active: true, currentWindow: true }))[0] + Browser.tabs.sendMessage(currentTab.id, { + type: 'CREATE_CHAT', + data: message, + }) + } + } + }) +} diff --git a/src/background/index.mjs b/src/background/index.mjs index 2525532..3028aad 100644 --- a/src/background/index.mjs +++ b/src/background/index.mjs @@ -4,161 +4,85 @@ import { deleteConversation, generateAnswersWithChatgptWebApi, sendMessageFeedback, -} from './apis/chatgpt-web' -import { generateAnswersWithBingWebApi } from './apis/bing-web.mjs' +} from '../services/apis/chatgpt-web' +import { generateAnswersWithBingWebApi } from '../services/apis/bing-web.mjs' import { generateAnswersWithChatgptApi, generateAnswersWithGptCompletionApi, -} from './apis/openai-api' -import { generateAnswersWithCustomApi } from './apis/custom-api.mjs' -import { generateAnswersWithAzureOpenaiApi } from './apis/azure-openai-api.mjs' -import { generateAnswersWithWaylaidwandererApi } from './apis/waylaidwanderer-api.mjs' -import { generateAnswersWithPoeWebApi } from './apis/poe-web.mjs' +} from '../services/apis/openai-api' +import { generateAnswersWithCustomApi } from '../services/apis/custom-api.mjs' +import { generateAnswersWithAzureOpenaiApi } from '../services/apis/azure-openai-api.mjs' +import { generateAnswersWithWaylaidwandererApi } from '../services/apis/waylaidwanderer-api.mjs' +import { generateAnswersWithPoeWebApi } from '../services/apis/poe-web.mjs' import { azureOpenAiApiModelKeys, bingWebModelKeys, chatgptApiModelKeys, chatgptWebModelKeys, - clearOldAccessToken, customApiModelKeys, - defaultConfig, - getPreferredLanguageKey, - getUserConfig, githubThirdPartyApiModelKeys, gptApiModelKeys, Models, poeWebModelKeys, - setAccessToken, } from '../config/index.mjs' -import { config as menuConfig } from '../content-script/menu-tools' -import { t, changeLanguage } from 'i18next' import '../_locales/i18n' import { openUrl } from '../utils/open-url' +import { + getBingAccessToken, + getChatGptAccessToken, + registerPortListener, +} from '../services/wrappers.mjs' +import { refreshMenu } from './menus.mjs' +import { registerCommands } from './commands.mjs' -async function getChatGptAccessToken() { - await clearOldAccessToken() - const userConfig = await getUserConfig() - if (userConfig.accessToken) { - return userConfig.accessToken - } else { - const cookie = (await Browser.cookies.getAll({ url: 'https://chat.openai.com/' })) - .map((cookie) => { - return `${cookie.name}=${cookie.value}` - }) - .join('; ') - const resp = await fetch('https://chat.openai.com/api/auth/session', { - headers: { - Cookie: cookie, - }, - }) - if (resp.status === 403) { - throw new Error('CLOUDFLARE') +async function executeApi(session, port, config) { + if (chatgptWebModelKeys.includes(session.modelName)) { + const accessToken = await getChatGptAccessToken() + session.messageId = uuidv4() + if (session.parentMessageId == null) { + session.parentMessageId = uuidv4() } - const data = await resp.json().catch(() => ({})) - if (!data.accessToken) { - throw new Error('UNAUTHORIZED') - } - await setAccessToken(data.accessToken) - return data.accessToken + await generateAnswersWithChatgptWebApi(port, session.question, session, accessToken) + } else if (bingWebModelKeys.includes(session.modelName)) { + const accessToken = await getBingAccessToken() + if (session.modelName === 'bingFreeSydney') + await generateAnswersWithBingWebApi(port, session.question, session, accessToken, true) + else await generateAnswersWithBingWebApi(port, session.question, session, accessToken) + } else if (gptApiModelKeys.includes(session.modelName)) { + await generateAnswersWithGptCompletionApi( + port, + session.question, + session, + config.apiKey, + session.modelName, + ) + } else if (chatgptApiModelKeys.includes(session.modelName)) { + await generateAnswersWithChatgptApi( + port, + session.question, + session, + config.apiKey, + session.modelName, + ) + } else if (customApiModelKeys.includes(session.modelName)) { + await generateAnswersWithCustomApi(port, session.question, session, '', config.customModelName) + } else if (azureOpenAiApiModelKeys.includes(session.modelName)) { + await generateAnswersWithAzureOpenaiApi(port, session.question, session) + } else if (githubThirdPartyApiModelKeys.includes(session.modelName)) { + await generateAnswersWithWaylaidwandererApi(port, session.question, session) + } else if (poeWebModelKeys.includes(session.modelName)) { + if (session.modelName === 'poeAiWebCustom') + await generateAnswersWithPoeWebApi(port, session.question, session, config.poeCustomBotName) + else + await generateAnswersWithPoeWebApi( + port, + session.question, + session, + Models[session.modelName].value, + ) } } -async function getBingAccessToken() { - return (await Browser.cookies.get({ url: 'https://bing.com/', name: '_U' }))?.value -} - -Browser.runtime.onConnect.addListener((port) => { - console.debug('connected') - const onMessage = async (msg) => { - console.debug('received msg', msg) - const session = msg.session - if (!session) return - const config = await getUserConfig() - if (!session.modelName) session.modelName = config.modelName - if (!session.aiName) session.aiName = Models[session.modelName].desc - port.postMessage({ session }) - - try { - if (chatgptWebModelKeys.includes(session.modelName)) { - const accessToken = await getChatGptAccessToken() - session.messageId = uuidv4() - if (session.parentMessageId == null) { - session.parentMessageId = uuidv4() - } - await generateAnswersWithChatgptWebApi(port, session.question, session, accessToken) - } else if (bingWebModelKeys.includes(session.modelName)) { - const accessToken = await getBingAccessToken() - if (session.modelName === 'bingFreeSydney') - await generateAnswersWithBingWebApi(port, session.question, session, accessToken, true) - else await generateAnswersWithBingWebApi(port, session.question, session, accessToken) - } else if (gptApiModelKeys.includes(session.modelName)) { - await generateAnswersWithGptCompletionApi( - port, - session.question, - session, - config.apiKey, - session.modelName, - ) - } else if (chatgptApiModelKeys.includes(session.modelName)) { - await generateAnswersWithChatgptApi( - port, - session.question, - session, - config.apiKey, - session.modelName, - ) - } else if (customApiModelKeys.includes(session.modelName)) { - await generateAnswersWithCustomApi( - port, - session.question, - session, - '', - config.customModelName, - ) - } else if (azureOpenAiApiModelKeys.includes(session.modelName)) { - await generateAnswersWithAzureOpenaiApi(port, session.question, session) - } else if (githubThirdPartyApiModelKeys.includes(session.modelName)) { - await generateAnswersWithWaylaidwandererApi(port, session.question, session) - } else if (poeWebModelKeys.includes(session.modelName)) { - if (session.modelName === 'poeAiWebCustom') - await generateAnswersWithPoeWebApi( - port, - session.question, - session, - config.poeCustomBotName, - ) - else - await generateAnswersWithPoeWebApi( - port, - session.question, - session, - Models[session.modelName].value, - ) - } - } catch (err) { - console.error(err) - if (!err.message.includes('aborted')) { - if ( - ['message you submitted was too long', 'maximum context length'].some((m) => - err.message.includes(m), - ) - ) - port.postMessage({ error: t('Exceeded maximum context length') + '\n' + err.message }) - else port.postMessage({ error: err.message }) - } - } - } - - const onDisconnect = () => { - console.debug('port disconnected, remove listener') - port.onMessage.removeListener(onMessage) - port.onDisconnect.removeListener(onDisconnect) - } - - port.onMessage.addListener(onMessage) - port.onDisconnect.addListener(onDisconnect) -}) - Browser.runtime.onMessage.addListener(async (message) => { if (message.type === 'FEEDBACK') { const token = await getChatGptAccessToken() @@ -170,105 +94,11 @@ Browser.runtime.onMessage.addListener(async (message) => { } else if (message.type === 'OPEN_URL') { const data = message.data openUrl(data.url) - } -}) - -Browser.commands.onCommand.addListener(async (command) => { - const message = { - itemId: command, - selectionText: '', - useMenuPosition: false, - } - console.debug('command triggered', message) - - if (command in menuConfig) { - if (menuConfig[command].action) { - menuConfig[command].action() - } - - if (menuConfig[command].genPrompt) { - const currentTab = (await Browser.tabs.query({ active: true, currentWindow: true }))[0] - Browser.tabs.sendMessage(currentTab.id, { - type: 'CREATE_CHAT', - data: message, - }) - } - } -}) - -function refreshMenu() { - Browser.contextMenus.removeAll().then(async () => { - await getPreferredLanguageKey().then((lang) => { - changeLanguage(lang) - }) - const menuId = 'ChatGPTBox-Menu' - Browser.contextMenus.create({ - id: menuId, - title: 'ChatGPTBox', - contexts: ['all'], - }) - - for (const [k, v] of Object.entries(menuConfig)) { - Browser.contextMenus.create({ - id: menuId + k, - parentId: menuId, - title: t(v.label), - contexts: ['all'], - }) - } - Browser.contextMenus.create({ - id: menuId + 'separator1', - parentId: menuId, - contexts: ['selection'], - type: 'separator', - }) - for (const index in defaultConfig.selectionTools) { - const key = defaultConfig.selectionTools[index] - const desc = defaultConfig.selectionToolsDesc[index] - Browser.contextMenus.create({ - id: menuId + key, - parentId: menuId, - title: t(desc), - contexts: ['selection'], - }) - } - - Browser.contextMenus.onClicked.addListener((info, tab) => { - Browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => { - const currentTab = tabs[0] - const message = { - itemId: info.menuItemId.replace(menuId, ''), - selectionText: info.selectionText, - useMenuPosition: tab.id === currentTab.id, - } - console.debug('menu clicked', message) - - if (defaultConfig.selectionTools.includes(message.itemId)) { - Browser.tabs.sendMessage(currentTab.id, { - type: 'CREATE_CHAT', - data: message, - }) - } else if (message.itemId in menuConfig) { - if (menuConfig[message.itemId].action) { - menuConfig[message.itemId].action() - } - - if (menuConfig[message.itemId].genPrompt) { - Browser.tabs.sendMessage(currentTab.id, { - type: 'CREATE_CHAT', - data: message, - }) - } - } - }) - }) - }) -} - -Browser.runtime.onMessage.addListener(async (message) => { - if (message.type === 'REFRESH_MENU') { + } else if (message.type === 'REFRESH_MENU') { refreshMenu() } }) +registerPortListener(async (session, port, config) => await executeApi(session, port, config)) +registerCommands() refreshMenu() diff --git a/src/background/menus.mjs b/src/background/menus.mjs new file mode 100644 index 0000000..19a24cf --- /dev/null +++ b/src/background/menus.mjs @@ -0,0 +1,73 @@ +import Browser from 'webextension-polyfill' +import { defaultConfig, getPreferredLanguageKey } from '../config/index.mjs' +import { changeLanguage, t } from 'i18next' +import { config as menuConfig } from '../content-script/menu-tools/index.mjs' + +export function refreshMenu() { + Browser.contextMenus.removeAll().then(async () => { + await getPreferredLanguageKey().then((lang) => { + changeLanguage(lang) + }) + const menuId = 'ChatGPTBox-Menu' + Browser.contextMenus.create({ + id: menuId, + title: 'ChatGPTBox', + contexts: ['all'], + }) + + for (const [k, v] of Object.entries(menuConfig)) { + Browser.contextMenus.create({ + id: menuId + k, + parentId: menuId, + title: t(v.label), + contexts: ['all'], + }) + } + Browser.contextMenus.create({ + id: menuId + 'separator1', + parentId: menuId, + contexts: ['selection'], + type: 'separator', + }) + for (const index in defaultConfig.selectionTools) { + const key = defaultConfig.selectionTools[index] + const desc = defaultConfig.selectionToolsDesc[index] + Browser.contextMenus.create({ + id: menuId + key, + parentId: menuId, + title: t(desc), + contexts: ['selection'], + }) + } + + Browser.contextMenus.onClicked.addListener((info, tab) => { + Browser.tabs.query({ active: true, currentWindow: true }).then((tabs) => { + const currentTab = tabs[0] + const message = { + itemId: info.menuItemId.replace(menuId, ''), + selectionText: info.selectionText, + useMenuPosition: tab.id === currentTab.id, + } + console.debug('menu clicked', message) + + if (defaultConfig.selectionTools.includes(message.itemId)) { + Browser.tabs.sendMessage(currentTab.id, { + type: 'CREATE_CHAT', + data: message, + }) + } else if (message.itemId in menuConfig) { + if (menuConfig[message.itemId].action) { + menuConfig[message.itemId].action() + } + + if (menuConfig[message.itemId].genPrompt) { + Browser.tabs.sendMessage(currentTab.id, { + type: 'CREATE_CHAT', + data: message, + }) + } + } + }) + }) + }) +} diff --git a/src/components/ConversationCard/index.jsx b/src/components/ConversationCard/index.jsx index 11b5d6e..2f9d01f 100644 --- a/src/components/ConversationCard/index.jsx +++ b/src/components/ConversationCard/index.jsx @@ -3,7 +3,7 @@ import PropTypes from 'prop-types' import Browser from 'webextension-polyfill' import InputBox from '../InputBox' import ConversationItem from '../ConversationItem' -import { createElementAtPosition, initSession, isSafari } from '../../utils' +import { createElementAtPosition, isSafari } from '../../utils' import { DownloadIcon, LinkExternalIcon, ArchiveIcon } from '@primer/octicons-react' import { WindowDesktop, XLg, Pin } from 'react-bootstrap-icons' import FileSaver from 'file-saver' @@ -14,8 +14,9 @@ import { Models } from '../../config/index.mjs' import { useTranslation } from 'react-i18next' import DeleteButton from '../DeleteButton' import { useConfig } from '../../hooks/use-config.mjs' -import { createSession } from '../../config/localSession.mjs' +import { createSession } from '../../services/local-session.mjs' import { v4 as uuidv4 } from 'uuid' +import { initSession } from '../../services/init-session.mjs' const logo = Browser.runtime.getURL('logo.png') diff --git a/src/content-script/index.jsx b/src/content-script/index.jsx index f6525ad..3240ce5 100644 --- a/src/content-script/index.jsx +++ b/src/content-script/index.jsx @@ -11,13 +11,13 @@ import { cropText, getClientPosition, getPossibleElementByQuerySelector, - initSession, } from '../utils' import FloatingToolbar from '../components/FloatingToolbar' import Browser from 'webextension-polyfill' import { getPreferredLanguage } from '../config/language.mjs' import '../_locales/i18n-react' import { changeLanguage } from 'i18next' +import { initSession } from '../services/init-session.mjs' /** * @param {SiteConfig} siteConfig @@ -99,27 +99,6 @@ async function getInput(inputQuery) { } } -async function overwriteAccessToken() { - if (location.hostname !== 'chat.openai.com') return - - let data - if (location.pathname === '/api/auth/session') { - const response = document.querySelector('pre').textContent - try { - data = JSON.parse(response) - } catch (error) { - console.error('json error', error) - } - } else { - const resp = await fetch('https://chat.openai.com/api/auth/session') - data = await resp.json().catch(() => ({})) - } - if (data && data.accessToken) { - await setAccessToken(data.accessToken) - console.log(data.accessToken) - } -} - let toolbarContainer const deleteToolbar = () => { if (toolbarContainer && toolbarContainer.className === 'chatgptbox-toolbar-container') @@ -293,6 +272,27 @@ async function prepareForStaticCard() { } } +async function overwriteAccessToken() { + if (location.hostname !== 'chat.openai.com') return + + let data + if (location.pathname === '/api/auth/session') { + const response = document.querySelector('pre').textContent + try { + data = JSON.parse(response) + } catch (error) { + console.error('json error', error) + } + } else { + const resp = await fetch('https://chat.openai.com/api/auth/session') + data = await resp.json().catch(() => ({})) + } + if (data && data.accessToken) { + await setAccessToken(data.accessToken) + console.log(data.accessToken) + } +} + async function run() { await getPreferredLanguageKey().then((lang) => { changeLanguage(lang) diff --git a/src/pages/IndependentPanel/App.jsx b/src/pages/IndependentPanel/App.jsx index 2a3f541..a809f92 100644 --- a/src/pages/IndependentPanel/App.jsx +++ b/src/pages/IndependentPanel/App.jsx @@ -5,7 +5,7 @@ import { updateSession, getSession, deleteSession, -} from '../../config/localSession' +} from '../../services/local-session.mjs' import { useEffect, useRef, useState } from 'react' import './styles.scss' import { useConfig } from '../../hooks/use-config.mjs' diff --git a/src/background/apis/azure-openai-api.mjs b/src/services/apis/azure-openai-api.mjs similarity index 97% rename from src/background/apis/azure-openai-api.mjs rename to src/services/apis/azure-openai-api.mjs index 776efc4..9352e7d 100644 --- a/src/background/apis/azure-openai-api.mjs +++ b/src/services/apis/azure-openai-api.mjs @@ -1,7 +1,7 @@ import { getUserConfig } from '../../config/index.mjs' import { getChatSystemPromptBase, pushRecord, setAbortController } from './shared.mjs' -import { getConversationPairs } from '../../utils/get-conversation-pairs' -import { fetchSSE } from '../../utils/fetch-sse' +import { getConversationPairs } from '../../utils/get-conversation-pairs.mjs' +import { fetchSSE } from '../../utils/fetch-sse.mjs' import { isEmpty } from 'lodash-es' /** diff --git a/src/background/apis/bing-web.mjs b/src/services/apis/bing-web.mjs similarity index 98% rename from src/background/apis/bing-web.mjs rename to src/services/apis/bing-web.mjs index 30d5dc1..ac1bc81 100644 --- a/src/background/apis/bing-web.mjs +++ b/src/services/apis/bing-web.mjs @@ -1,4 +1,4 @@ -import BingAIClient from '../clients/bing' +import BingAIClient from '../clients/bing/index.mjs' import { getUserConfig } from '../../config/index.mjs' import { pushRecord, setAbortController } from './shared.mjs' diff --git a/src/background/apis/chatgpt-web.mjs b/src/services/apis/chatgpt-web.mjs similarity index 98% rename from src/background/apis/chatgpt-web.mjs rename to src/services/apis/chatgpt-web.mjs index 8c08b62..34a5e34 100644 --- a/src/background/apis/chatgpt-web.mjs +++ b/src/services/apis/chatgpt-web.mjs @@ -1,6 +1,6 @@ // web version -import { fetchSSE } from '../../utils/fetch-sse' +import { fetchSSE } from '../../utils/fetch-sse.mjs' import { isEmpty } from 'lodash-es' import { chatgptWebModelKeys, getUserConfig, Models } from '../../config/index.mjs' import { pushRecord, setAbortController } from './shared.mjs' diff --git a/src/background/apis/custom-api.mjs b/src/services/apis/custom-api.mjs similarity index 97% rename from src/background/apis/custom-api.mjs rename to src/services/apis/custom-api.mjs index 7187fda..c4c1ea5 100644 --- a/src/background/apis/custom-api.mjs +++ b/src/services/apis/custom-api.mjs @@ -6,8 +6,8 @@ // If necessary, I will refactor. import { getUserConfig } from '../../config/index.mjs' -import { fetchSSE } from '../../utils/fetch-sse' -import { getConversationPairs } from '../../utils/get-conversation-pairs' +import { fetchSSE } from '../../utils/fetch-sse.mjs' +import { getConversationPairs } from '../../utils/get-conversation-pairs.mjs' import { isEmpty } from 'lodash-es' import { getCustomApiPromptBase, pushRecord, setAbortController } from './shared.mjs' diff --git a/src/background/apis/openai-api.mjs b/src/services/apis/openai-api.mjs similarity index 98% rename from src/background/apis/openai-api.mjs rename to src/services/apis/openai-api.mjs index 22ed1f2..a9de023 100644 --- a/src/background/apis/openai-api.mjs +++ b/src/services/apis/openai-api.mjs @@ -1,8 +1,8 @@ // api version import { Models, getUserConfig } from '../../config/index.mjs' -import { fetchSSE } from '../../utils/fetch-sse' -import { getConversationPairs } from '../../utils/get-conversation-pairs' +import { fetchSSE } from '../../utils/fetch-sse.mjs' +import { getConversationPairs } from '../../utils/get-conversation-pairs.mjs' import { isEmpty } from 'lodash-es' import { getChatSystemPromptBase, diff --git a/src/background/apis/poe-web.mjs b/src/services/apis/poe-web.mjs similarity index 95% rename from src/background/apis/poe-web.mjs rename to src/services/apis/poe-web.mjs index d6af778..eb88fa8 100644 --- a/src/background/apis/poe-web.mjs +++ b/src/services/apis/poe-web.mjs @@ -1,5 +1,5 @@ import { pushRecord, setAbortController } from './shared.mjs' -import PoeAiClient from '../clients/poe' +import PoeAiClient from '../clients/poe/index.mjs' /** * @param {Runtime.Port} port diff --git a/src/background/apis/shared.mjs b/src/services/apis/shared.mjs similarity index 100% rename from src/background/apis/shared.mjs rename to src/services/apis/shared.mjs diff --git a/src/background/apis/waylaidwanderer-api.mjs b/src/services/apis/waylaidwanderer-api.mjs similarity index 98% rename from src/background/apis/waylaidwanderer-api.mjs rename to src/services/apis/waylaidwanderer-api.mjs index 58d261d..4813b37 100644 --- a/src/background/apis/waylaidwanderer-api.mjs +++ b/src/services/apis/waylaidwanderer-api.mjs @@ -1,6 +1,6 @@ import { pushRecord, setAbortController } from './shared.mjs' import { getUserConfig } from '../../config/index.mjs' -import { fetchSSE } from '../../utils/fetch-sse' +import { fetchSSE } from '../../utils/fetch-sse.mjs' import { isEmpty } from 'lodash-es' /** diff --git a/src/background/clients/bing/index.mjs b/src/services/clients/bing/index.mjs similarity index 100% rename from src/background/clients/bing/index.mjs rename to src/services/clients/bing/index.mjs diff --git a/src/background/clients/poe/graphql/AddHumanMessageMutation.graphql b/src/services/clients/poe/graphql/AddHumanMessageMutation.graphql similarity index 100% rename from src/background/clients/poe/graphql/AddHumanMessageMutation.graphql rename to src/services/clients/poe/graphql/AddHumanMessageMutation.graphql diff --git a/src/background/clients/poe/graphql/AddMessageBreakMutation.graphql b/src/services/clients/poe/graphql/AddMessageBreakMutation.graphql similarity index 100% rename from src/background/clients/poe/graphql/AddMessageBreakMutation.graphql rename to src/services/clients/poe/graphql/AddMessageBreakMutation.graphql diff --git a/src/background/clients/poe/graphql/AutoSubscriptionMutation.graphql b/src/services/clients/poe/graphql/AutoSubscriptionMutation.graphql similarity index 100% rename from src/background/clients/poe/graphql/AutoSubscriptionMutation.graphql rename to src/services/clients/poe/graphql/AutoSubscriptionMutation.graphql diff --git a/src/background/clients/poe/graphql/BioFragment.graphql b/src/services/clients/poe/graphql/BioFragment.graphql similarity index 100% rename from src/background/clients/poe/graphql/BioFragment.graphql rename to src/services/clients/poe/graphql/BioFragment.graphql diff --git a/src/background/clients/poe/graphql/ChatAddedSubscription.graphql b/src/services/clients/poe/graphql/ChatAddedSubscription.graphql similarity index 100% rename from src/background/clients/poe/graphql/ChatAddedSubscription.graphql rename to src/services/clients/poe/graphql/ChatAddedSubscription.graphql diff --git a/src/background/clients/poe/graphql/ChatFragment.graphql b/src/services/clients/poe/graphql/ChatFragment.graphql similarity index 100% rename from src/background/clients/poe/graphql/ChatFragment.graphql rename to src/services/clients/poe/graphql/ChatFragment.graphql diff --git a/src/background/clients/poe/graphql/ChatPaginationQuery.graphql b/src/services/clients/poe/graphql/ChatPaginationQuery.graphql similarity index 100% rename from src/background/clients/poe/graphql/ChatPaginationQuery.graphql rename to src/services/clients/poe/graphql/ChatPaginationQuery.graphql diff --git a/src/background/clients/poe/graphql/ChatViewQuery.graphql b/src/services/clients/poe/graphql/ChatViewQuery.graphql similarity index 100% rename from src/background/clients/poe/graphql/ChatViewQuery.graphql rename to src/services/clients/poe/graphql/ChatViewQuery.graphql diff --git a/src/background/clients/poe/graphql/DeleteHumanMessagesMutation.graphql b/src/services/clients/poe/graphql/DeleteHumanMessagesMutation.graphql similarity index 100% rename from src/background/clients/poe/graphql/DeleteHumanMessagesMutation.graphql rename to src/services/clients/poe/graphql/DeleteHumanMessagesMutation.graphql diff --git a/src/background/clients/poe/graphql/HandleFragment.graphql b/src/services/clients/poe/graphql/HandleFragment.graphql similarity index 100% rename from src/background/clients/poe/graphql/HandleFragment.graphql rename to src/services/clients/poe/graphql/HandleFragment.graphql diff --git a/src/background/clients/poe/graphql/LoginWithVerificationCodeMutation.graphql b/src/services/clients/poe/graphql/LoginWithVerificationCodeMutation.graphql similarity index 100% rename from src/background/clients/poe/graphql/LoginWithVerificationCodeMutation.graphql rename to src/services/clients/poe/graphql/LoginWithVerificationCodeMutation.graphql diff --git a/src/background/clients/poe/graphql/MessageAddedSubscription.graphql b/src/services/clients/poe/graphql/MessageAddedSubscription.graphql similarity index 100% rename from src/background/clients/poe/graphql/MessageAddedSubscription.graphql rename to src/services/clients/poe/graphql/MessageAddedSubscription.graphql diff --git a/src/background/clients/poe/graphql/MessageDeletedSubscription.graphql b/src/services/clients/poe/graphql/MessageDeletedSubscription.graphql similarity index 100% rename from src/background/clients/poe/graphql/MessageDeletedSubscription.graphql rename to src/services/clients/poe/graphql/MessageDeletedSubscription.graphql diff --git a/src/background/clients/poe/graphql/MessageFragment.graphql b/src/services/clients/poe/graphql/MessageFragment.graphql similarity index 100% rename from src/background/clients/poe/graphql/MessageFragment.graphql rename to src/services/clients/poe/graphql/MessageFragment.graphql diff --git a/src/background/clients/poe/graphql/MessageRemoveVoteMutation.graphql b/src/services/clients/poe/graphql/MessageRemoveVoteMutation.graphql similarity index 100% rename from src/background/clients/poe/graphql/MessageRemoveVoteMutation.graphql rename to src/services/clients/poe/graphql/MessageRemoveVoteMutation.graphql diff --git a/src/background/clients/poe/graphql/MessageSetVoteMutation.graphql b/src/services/clients/poe/graphql/MessageSetVoteMutation.graphql similarity index 100% rename from src/background/clients/poe/graphql/MessageSetVoteMutation.graphql rename to src/services/clients/poe/graphql/MessageSetVoteMutation.graphql diff --git a/src/background/clients/poe/graphql/SendVerificationCodeForLoginMutation.graphql b/src/services/clients/poe/graphql/SendVerificationCodeForLoginMutation.graphql similarity index 100% rename from src/background/clients/poe/graphql/SendVerificationCodeForLoginMutation.graphql rename to src/services/clients/poe/graphql/SendVerificationCodeForLoginMutation.graphql diff --git a/src/background/clients/poe/graphql/ShareMessagesMutation.graphql b/src/services/clients/poe/graphql/ShareMessagesMutation.graphql similarity index 100% rename from src/background/clients/poe/graphql/ShareMessagesMutation.graphql rename to src/services/clients/poe/graphql/ShareMessagesMutation.graphql diff --git a/src/background/clients/poe/graphql/SignupWithVerificationCodeMutation.graphql b/src/services/clients/poe/graphql/SignupWithVerificationCodeMutation.graphql similarity index 100% rename from src/background/clients/poe/graphql/SignupWithVerificationCodeMutation.graphql rename to src/services/clients/poe/graphql/SignupWithVerificationCodeMutation.graphql diff --git a/src/background/clients/poe/graphql/StaleChatUpdateMutation.graphql b/src/services/clients/poe/graphql/StaleChatUpdateMutation.graphql similarity index 100% rename from src/background/clients/poe/graphql/StaleChatUpdateMutation.graphql rename to src/services/clients/poe/graphql/StaleChatUpdateMutation.graphql diff --git a/src/background/clients/poe/graphql/SummarizePlainPostQuery.graphql b/src/services/clients/poe/graphql/SummarizePlainPostQuery.graphql similarity index 100% rename from src/background/clients/poe/graphql/SummarizePlainPostQuery.graphql rename to src/services/clients/poe/graphql/SummarizePlainPostQuery.graphql diff --git a/src/background/clients/poe/graphql/SummarizeQuotePostQuery.graphql b/src/services/clients/poe/graphql/SummarizeQuotePostQuery.graphql similarity index 100% rename from src/background/clients/poe/graphql/SummarizeQuotePostQuery.graphql rename to src/services/clients/poe/graphql/SummarizeQuotePostQuery.graphql diff --git a/src/background/clients/poe/graphql/SummarizeSharePostQuery.graphql b/src/services/clients/poe/graphql/SummarizeSharePostQuery.graphql similarity index 100% rename from src/background/clients/poe/graphql/SummarizeSharePostQuery.graphql rename to src/services/clients/poe/graphql/SummarizeSharePostQuery.graphql diff --git a/src/background/clients/poe/graphql/UserSnippetFragment.graphql b/src/services/clients/poe/graphql/UserSnippetFragment.graphql similarity index 100% rename from src/background/clients/poe/graphql/UserSnippetFragment.graphql rename to src/services/clients/poe/graphql/UserSnippetFragment.graphql diff --git a/src/background/clients/poe/graphql/ViewerInfoQuery.graphql b/src/services/clients/poe/graphql/ViewerInfoQuery.graphql similarity index 100% rename from src/background/clients/poe/graphql/ViewerInfoQuery.graphql rename to src/services/clients/poe/graphql/ViewerInfoQuery.graphql diff --git a/src/background/clients/poe/graphql/ViewerStateFragment.graphql b/src/services/clients/poe/graphql/ViewerStateFragment.graphql similarity index 100% rename from src/background/clients/poe/graphql/ViewerStateFragment.graphql rename to src/services/clients/poe/graphql/ViewerStateFragment.graphql diff --git a/src/background/clients/poe/graphql/ViewerStateUpdatedSubscription.graphql b/src/services/clients/poe/graphql/ViewerStateUpdatedSubscription.graphql similarity index 100% rename from src/background/clients/poe/graphql/ViewerStateUpdatedSubscription.graphql rename to src/services/clients/poe/graphql/ViewerStateUpdatedSubscription.graphql diff --git a/src/background/clients/poe/index.mjs b/src/services/clients/poe/index.mjs similarity index 100% rename from src/background/clients/poe/index.mjs rename to src/services/clients/poe/index.mjs diff --git a/src/background/clients/poe/websocket.js b/src/services/clients/poe/websocket.js similarity index 100% rename from src/background/clients/poe/websocket.js rename to src/services/clients/poe/websocket.js diff --git a/src/utils/init-session.mjs b/src/services/init-session.mjs similarity index 100% rename from src/utils/init-session.mjs rename to src/services/init-session.mjs diff --git a/src/config/localSession.mjs b/src/services/local-session.mjs similarity index 95% rename from src/config/localSession.mjs rename to src/services/local-session.mjs index f31ccf4..909ebc9 100644 --- a/src/config/localSession.mjs +++ b/src/services/local-session.mjs @@ -1,6 +1,6 @@ import Browser from 'webextension-polyfill' -import { initSession } from '../utils/index.mjs' -import { getUserConfig } from './index.mjs' +import { initSession } from './init-session.mjs' +import { getUserConfig } from '../config/index.mjs' export const initDefaultSession = async () => { const config = await getUserConfig() diff --git a/src/services/wrappers.mjs b/src/services/wrappers.mjs new file mode 100644 index 0000000..1228b19 --- /dev/null +++ b/src/services/wrappers.mjs @@ -0,0 +1,73 @@ +import { clearOldAccessToken, getUserConfig, Models, setAccessToken } from '../config/index.mjs' +import Browser from 'webextension-polyfill' +import { t } from 'i18next' + +export async function getChatGptAccessToken() { + await clearOldAccessToken() + const userConfig = await getUserConfig() + if (userConfig.accessToken) { + return userConfig.accessToken + } else { + const cookie = (await Browser.cookies.getAll({ url: 'https://chat.openai.com/' })) + .map((cookie) => { + return `${cookie.name}=${cookie.value}` + }) + .join('; ') + const resp = await fetch('https://chat.openai.com/api/auth/session', { + headers: { + Cookie: cookie, + }, + }) + if (resp.status === 403) { + throw new Error('CLOUDFLARE') + } + const data = await resp.json().catch(() => ({})) + if (!data.accessToken) { + throw new Error('UNAUTHORIZED') + } + await setAccessToken(data.accessToken) + return data.accessToken + } +} + +export async function getBingAccessToken() { + return (await Browser.cookies.get({ url: 'https://bing.com/', name: '_U' }))?.value +} + +export function registerPortListener(executor) { + Browser.runtime.onConnect.addListener((port) => { + console.debug('connected') + const onMessage = async (msg) => { + console.debug('received msg', msg) + const session = msg.session + if (!session) return + const config = await getUserConfig() + if (!session.modelName) session.modelName = config.modelName + if (!session.aiName) session.aiName = Models[session.modelName].desc + port.postMessage({ session }) + try { + await executor(session, port, config) + } catch (err) { + console.error(err) + if (!err.message.includes('aborted')) { + if ( + ['message you submitted was too long', 'maximum context length'].some((m) => + err.message.includes(m), + ) + ) + port.postMessage({ error: t('Exceeded maximum context length') + '\n' + err.message }) + else port.postMessage({ error: err.message }) + } + } + } + + const onDisconnect = () => { + console.debug('port disconnected, remove listener') + port.onMessage.removeListener(onMessage) + port.onDisconnect.removeListener(onDisconnect) + } + + port.onMessage.addListener(onMessage) + port.onDisconnect.addListener(onDisconnect) + }) +} diff --git a/src/utils/index.mjs b/src/utils/index.mjs index 6844c1e..8bc6a7f 100644 --- a/src/utils/index.mjs +++ b/src/utils/index.mjs @@ -7,7 +7,6 @@ export * from './get-client-position' export * from './get-conversation-pairs' export * from './get-core-content-text' export * from './get-possible-element-by-query-selector' -export * from './init-session' export * from './is-edge' export * from './is-firefox' export * from './is-mobile'