diff --git a/.eslintrc.json b/.eslintrc.json index d229e86f250..5b5e88e67aa 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,4 +1,7 @@ { "extends": "next/core-web-vitals", - "plugins": ["prettier"] + "plugins": ["prettier", "unused-imports"], + "rules": { + "unused-imports/no-unused-imports": "warn" + } } diff --git a/app/api/[provider]/[...path]/route.ts b/app/api/[provider]/[...path]/route.ts index 24aa5ec040f..dffb3e9daa4 100644 --- a/app/api/[provider]/[...path]/route.ts +++ b/app/api/[provider]/[...path]/route.ts @@ -1,5 +1,5 @@ import { ApiPath } from "@/app/constant"; -import { NextRequest, NextResponse } from "next/server"; +import { NextRequest } from "next/server"; import { handle as openaiHandler } from "../../openai"; import { handle as azureHandler } from "../../azure"; import { handle as googleHandler } from "../../google"; diff --git a/app/api/alibaba.ts b/app/api/alibaba.ts index 675d9f301aa..894b1ae4c04 100644 --- a/app/api/alibaba.ts +++ b/app/api/alibaba.ts @@ -1,6 +1,5 @@ import { getServerSideConfig } from "@/app/config/server"; import { - Alibaba, ALIBABA_BASE_URL, ApiPath, ModelProvider, @@ -10,7 +9,6 @@ import { prettyObject } from "@/app/utils/format"; import { NextRequest, NextResponse } from "next/server"; import { auth } from "@/app/api/auth"; import { isModelAvailableInServer } from "@/app/utils/model"; -import type { RequestPayload } from "@/app/client/platforms/openai"; const serverConfig = getServerSideConfig(); diff --git a/app/api/anthropic.ts b/app/api/anthropic.ts index d7b070247b7..7a44443710f 100644 --- a/app/api/anthropic.ts +++ b/app/api/anthropic.ts @@ -3,7 +3,6 @@ import { ANTHROPIC_BASE_URL, Anthropic, ApiPath, - DEFAULT_MODELS, ServiceProvider, ModelProvider, } from "@/app/constant"; diff --git a/app/api/azure.ts b/app/api/azure.ts index e2cb0c7e66b..39d872e8cf8 100644 --- a/app/api/azure.ts +++ b/app/api/azure.ts @@ -1,4 +1,3 @@ -import { getServerSideConfig } from "@/app/config/server"; import { ModelProvider } from "@/app/constant"; import { prettyObject } from "@/app/utils/format"; import { NextRequest, NextResponse } from "next/server"; diff --git a/app/api/baidu.ts b/app/api/baidu.ts index f4315d186da..0408b43c5bc 100644 --- a/app/api/baidu.ts +++ b/app/api/baidu.ts @@ -3,7 +3,6 @@ import { BAIDU_BASE_URL, ApiPath, ModelProvider, - BAIDU_OATUH_URL, ServiceProvider, } from "@/app/constant"; import { prettyObject } from "@/app/utils/format"; diff --git a/app/api/common.ts b/app/api/common.ts index 25decbf620e..b4c792d6ff0 100644 --- a/app/api/common.ts +++ b/app/api/common.ts @@ -1,11 +1,6 @@ import { NextRequest, NextResponse } from "next/server"; import { getServerSideConfig } from "../config/server"; -import { - DEFAULT_MODELS, - OPENAI_BASE_URL, - GEMINI_BASE_URL, - ServiceProvider, -} from "../constant"; +import { OPENAI_BASE_URL, ServiceProvider } from "../constant"; import { isModelAvailableInServer } from "../utils/model"; import { cloudflareAIGatewayUrl } from "../utils/cloudflare"; diff --git a/app/api/google.ts b/app/api/google.ts index 98fe469bfb7..e6ab472568b 100644 --- a/app/api/google.ts +++ b/app/api/google.ts @@ -1,12 +1,7 @@ import { NextRequest, NextResponse } from "next/server"; import { auth } from "./auth"; import { getServerSideConfig } from "@/app/config/server"; -import { - ApiPath, - GEMINI_BASE_URL, - Google, - ModelProvider, -} from "@/app/constant"; +import { ApiPath, GEMINI_BASE_URL, ModelProvider } from "@/app/constant"; import { prettyObject } from "@/app/utils/format"; const serverConfig = getServerSideConfig(); diff --git a/app/api/iflytek.ts b/app/api/iflytek.ts index eabdd9f4ce6..8b8227dce1f 100644 --- a/app/api/iflytek.ts +++ b/app/api/iflytek.ts @@ -1,6 +1,5 @@ import { getServerSideConfig } from "@/app/config/server"; import { - Iflytek, IFLYTEK_BASE_URL, ApiPath, ModelProvider, @@ -10,7 +9,6 @@ import { prettyObject } from "@/app/utils/format"; import { NextRequest, NextResponse } from "next/server"; import { auth } from "@/app/api/auth"; import { isModelAvailableInServer } from "@/app/utils/model"; -import type { RequestPayload } from "@/app/client/platforms/openai"; // iflytek const serverConfig = getServerSideConfig(); diff --git a/app/api/moonshot.ts b/app/api/moonshot.ts index 247dd618321..5bf4807e3e6 100644 --- a/app/api/moonshot.ts +++ b/app/api/moonshot.ts @@ -1,6 +1,5 @@ import { getServerSideConfig } from "@/app/config/server"; import { - Moonshot, MOONSHOT_BASE_URL, ApiPath, ModelProvider, @@ -10,7 +9,6 @@ import { prettyObject } from "@/app/utils/format"; import { NextRequest, NextResponse } from "next/server"; import { auth } from "@/app/api/auth"; import { isModelAvailableInServer } from "@/app/utils/model"; -import type { RequestPayload } from "@/app/client/platforms/openai"; const serverConfig = getServerSideConfig(); diff --git a/app/api/tencent/route.ts b/app/api/tencent/route.ts index 885909e7a75..fc4f8c79edf 100644 --- a/app/api/tencent/route.ts +++ b/app/api/tencent/route.ts @@ -1,15 +1,8 @@ import { getServerSideConfig } from "@/app/config/server"; -import { - TENCENT_BASE_URL, - ApiPath, - ModelProvider, - ServiceProvider, - Tencent, -} from "@/app/constant"; +import { TENCENT_BASE_URL, ModelProvider } from "@/app/constant"; import { prettyObject } from "@/app/utils/format"; import { NextRequest, NextResponse } from "next/server"; import { auth } from "@/app/api/auth"; -import { isModelAvailableInServer } from "@/app/utils/model"; import { getHeader } from "@/app/utils/tencent"; const serverConfig = getServerSideConfig(); diff --git a/app/client/api.ts b/app/client/api.ts index cecc453baa2..94296b9aa81 100644 --- a/app/client/api.ts +++ b/app/client/api.ts @@ -1,7 +1,6 @@ import { getClientConfig } from "../config/client"; import { ACCESS_CODE_PREFIX, - Azure, ModelProvider, ServiceProvider, } from "../constant"; diff --git a/app/client/platforms/anthropic.ts b/app/client/platforms/anthropic.ts index 7dd39c9cddc..df128c70497 100644 --- a/app/client/platforms/anthropic.ts +++ b/app/client/platforms/anthropic.ts @@ -1,5 +1,5 @@ -import { ACCESS_CODE_PREFIX, Anthropic, ApiPath } from "@/app/constant"; -import { ChatOptions, getHeaders, LLMApi, MultimodalContent } from "../api"; +import { Anthropic, ApiPath } from "@/app/constant"; +import { ChatOptions, getHeaders, LLMApi } from "../api"; import { useAccessStore, useAppConfig, @@ -9,13 +9,6 @@ import { } from "@/app/store"; import { getClientConfig } from "@/app/config/client"; import { DEFAULT_API_HOST } from "@/app/constant"; -import { - EventStreamContentType, - fetchEventSource, -} from "@fortaine/fetch-event-source"; - -import Locale from "../../locales"; -import { prettyObject } from "@/app/utils/format"; import { getMessageTextContent, isVisionModel } from "@/app/utils"; import { preProcessImageContent, stream } from "@/app/utils/chat"; import { cloudflareAIGatewayUrl } from "@/app/utils/cloudflare"; diff --git a/app/client/platforms/iflytek.ts b/app/client/platforms/iflytek.ts index 73cea5ba0e7..e29b603e2dc 100644 --- a/app/client/platforms/iflytek.ts +++ b/app/client/platforms/iflytek.ts @@ -17,7 +17,7 @@ import { prettyObject } from "@/app/utils/format"; import { getClientConfig } from "@/app/config/client"; import { getMessageTextContent } from "@/app/utils"; -import { OpenAIListModelResponse, RequestPayload } from "./openai"; +import { RequestPayload } from "./openai"; export class SparkApi implements LLMApi { private disableListModels = true; diff --git a/app/client/platforms/moonshot.ts b/app/client/platforms/moonshot.ts index cd10d2f6c15..d09c4619edf 100644 --- a/app/client/platforms/moonshot.ts +++ b/app/client/platforms/moonshot.ts @@ -3,10 +3,8 @@ import { ApiPath, DEFAULT_API_HOST, - DEFAULT_MODELS, Moonshot, REQUEST_TIMEOUT_MS, - ServiceProvider, } from "@/app/constant"; import { useAccessStore, @@ -15,28 +13,11 @@ import { ChatMessageTool, usePluginStore, } from "@/app/store"; -import { collectModelsWithDefaultModel } from "@/app/utils/model"; -import { preProcessImageContent, stream } from "@/app/utils/chat"; -import { cloudflareAIGatewayUrl } from "@/app/utils/cloudflare"; - -import { - ChatOptions, - getHeaders, - LLMApi, - LLMModel, - LLMUsage, - MultimodalContent, -} from "../api"; -import Locale from "../../locales"; -import { - EventStreamContentType, - fetchEventSource, -} from "@fortaine/fetch-event-source"; -import { prettyObject } from "@/app/utils/format"; +import { stream } from "@/app/utils/chat"; +import { ChatOptions, getHeaders, LLMApi, LLMModel } from "../api"; import { getClientConfig } from "@/app/config/client"; import { getMessageTextContent } from "@/app/utils"; - -import { OpenAIListModelResponse, RequestPayload } from "./openai"; +import { RequestPayload } from "./openai"; export class MoonshotApi implements LLMApi { private disableListModels = true; diff --git a/app/client/platforms/openai.ts b/app/client/platforms/openai.ts index 664ff872ba3..4f9dcd4d048 100644 --- a/app/client/platforms/openai.ts +++ b/app/client/platforms/openai.ts @@ -35,15 +35,9 @@ import { MultimodalContent, } from "../api"; import Locale from "../../locales"; -import { - EventStreamContentType, - fetchEventSource, -} from "@fortaine/fetch-event-source"; -import { prettyObject } from "@/app/utils/format"; import { getClientConfig } from "@/app/config/client"; import { getMessageTextContent, - getMessageImages, isVisionModel, isDalle3 as _isDalle3, } from "@/app/utils"; diff --git a/app/components/artifacts.tsx b/app/components/artifacts.tsx index d725ee6596e..ce187fbcb2c 100644 --- a/app/components/artifacts.tsx +++ b/app/components/artifacts.tsx @@ -7,7 +7,6 @@ import { useImperativeHandle, } from "react"; import { useParams } from "react-router"; -import { useWindowSize } from "@/app/utils"; import { IconButton } from "./button"; import { nanoid } from "nanoid"; import ExportIcon from "../icons/share.svg"; diff --git a/app/components/chat-list.tsx b/app/components/chat-list.tsx index 7ef6e7b8337..03b1a5c8803 100644 --- a/app/components/chat-list.tsx +++ b/app/components/chat-list.tsx @@ -1,5 +1,4 @@ import DeleteIcon from "../icons/delete.svg"; -import BotIcon from "../icons/bot.svg"; import styles from "./home.module.scss"; import { @@ -12,7 +11,7 @@ import { import { useChatStore } from "../store"; import Locale from "../locales"; -import { Link, useLocation, useNavigate } from "react-router-dom"; +import { useLocation, useNavigate } from "react-router-dom"; import { Path } from "../constant"; import { MaskAvatar } from "./mask"; import { Mask } from "../store/mask"; diff --git a/app/components/chat.tsx b/app/components/chat.tsx index 3cc02d48672..125f265eaad 100644 --- a/app/components/chat.tsx +++ b/app/components/chat.tsx @@ -96,7 +96,6 @@ import { import { useNavigate } from "react-router-dom"; import { CHAT_PAGE_SIZE, - LAST_INPUT_KEY, Path, REQUEST_TIMEOUT_MS, UNFINISHED_INPUT, diff --git a/app/components/exporter.tsx b/app/components/exporter.tsx index 1771cc9b013..aba8dc54466 100644 --- a/app/components/exporter.tsx +++ b/app/components/exporter.tsx @@ -1,5 +1,5 @@ /* eslint-disable @next/next/no-img-element */ -import { ChatMessage, ModelType, useAppConfig, useChatStore } from "../store"; +import { ChatMessage, useAppConfig, useChatStore } from "../store"; import Locale from "../locales"; import styles from "./exporter.module.scss"; import { diff --git a/app/components/mask.tsx b/app/components/mask.tsx index ee6c7da97b8..e4dd90826c7 100644 --- a/app/components/mask.tsx +++ b/app/components/mask.tsx @@ -37,7 +37,7 @@ import Locale, { AllLangs, ALL_LANG_OPTIONS, Lang } from "../locales"; import { useNavigate } from "react-router-dom"; import chatStyle from "./chat.module.scss"; -import { useEffect, useState } from "react"; +import { useState } from "react"; import { copyToClipboard, downloadAs, @@ -48,7 +48,6 @@ import { Updater } from "../typing"; import { ModelConfigList } from "./model-config"; import { FileName, Path } from "../constant"; import { BUILTIN_MASK_STORE } from "../masks"; -import { nanoid } from "nanoid"; import { DragDropContext, Droppable, diff --git a/app/components/plugin.tsx b/app/components/plugin.tsx index 6f0b371075e..cf4ae946ef6 100644 --- a/app/components/plugin.tsx +++ b/app/components/plugin.tsx @@ -28,7 +28,7 @@ import { } from "./ui-lib"; import Locale from "../locales"; import { useNavigate } from "react-router-dom"; -import { useEffect, useState } from "react"; +import { useState } from "react"; import { getClientConfig } from "../config/client"; export function PluginPage() { diff --git a/app/components/sidebar.tsx b/app/components/sidebar.tsx index 4ec0f8c84f5..b067d41bead 100644 --- a/app/components/sidebar.tsx +++ b/app/components/sidebar.tsx @@ -7,7 +7,6 @@ import SettingsIcon from "../icons/settings.svg"; import GithubIcon from "../icons/github.svg"; import ChatGptIcon from "../icons/chatgpt.svg"; import AddIcon from "../icons/add.svg"; -import CloseIcon from "../icons/close.svg"; import DeleteIcon from "../icons/delete.svg"; import MaskIcon from "../icons/mask.svg"; import DragIcon from "../icons/drag.svg"; diff --git a/app/constant.ts b/app/constant.ts index 3d33a047e90..e281c457d0f 100644 --- a/app/constant.ts +++ b/app/constant.ts @@ -1,5 +1,3 @@ -import path from "path"; - export const OWNER = "ChatGPTNextWeb"; export const REPO = "ChatGPT-Next-Web"; export const REPO_URL = `https://github.com/${OWNER}/${REPO}`; @@ -279,7 +277,7 @@ const openaiModels = [ "gpt-4-1106-preview", "dall-e-3", "o1-mini", - "o1-preview" + "o1-preview", ]; const googleModels = [ diff --git a/app/locales/cn.ts b/app/locales/cn.ts index fcbdb6f627c..144b28ff317 100644 --- a/app/locales/cn.ts +++ b/app/locales/cn.ts @@ -1,4 +1,3 @@ -import { ShortcutKeyModal } from "../components/chat"; import { getClientConfig } from "../config/client"; import { SubmitKey } from "../store/config"; diff --git a/app/locales/sk.ts b/app/locales/sk.ts index 8f83c3ba73a..3649b763bf5 100644 --- a/app/locales/sk.ts +++ b/app/locales/sk.ts @@ -1,6 +1,5 @@ import { getClientConfig } from "../config/client"; import { SubmitKey } from "../store/config"; -import { LocaleType } from "./index"; import type { PartialLocaleType } from "./index"; // if you are adding a new translation, please use PartialLocaleType instead of LocaleType diff --git a/app/masks/index.ts b/app/masks/index.ts index 92f21c6aea7..bff5c9bbe0a 100644 --- a/app/masks/index.ts +++ b/app/masks/index.ts @@ -1,7 +1,4 @@ import { Mask } from "../store/mask"; -import { CN_MASKS } from "./cn"; -import { TW_MASKS } from "./tw"; -import { EN_MASKS } from "./en"; import { type BuiltinMask } from "./typing"; export { type BuiltinMask } from "./typing"; diff --git a/app/store/plugin.ts b/app/store/plugin.ts index 2356c6db0a7..44679cbdc25 100644 --- a/app/store/plugin.ts +++ b/app/store/plugin.ts @@ -1,5 +1,4 @@ import OpenAPIClientAxios from "openapi-client-axios"; -import { getLang, Lang } from "../locales"; import { StoreKey } from "../constant"; import { nanoid } from "nanoid"; import { createPersistStore } from "../utils/store"; diff --git a/app/store/sync.ts b/app/store/sync.ts index d3582e3c935..9db60d5f410 100644 --- a/app/store/sync.ts +++ b/app/store/sync.ts @@ -1,5 +1,4 @@ import { getClientConfig } from "../config/client"; -import { Updater } from "../typing"; import { ApiPath, STORAGE_KEY, StoreKey } from "../constant"; import { createPersistStore } from "../utils/store"; import { @@ -100,15 +99,17 @@ export const useSyncStore = createPersistStore( const remoteState = await client.get(config.username); if (!remoteState || remoteState === "") { await client.set(config.username, JSON.stringify(localState)); - console.log("[Sync] Remote state is empty, using local state instead."); - return + console.log( + "[Sync] Remote state is empty, using local state instead.", + ); + return; } else { const parsedRemoteState = JSON.parse( await client.get(config.username), ) as AppState; mergeAppState(localState, parsedRemoteState); setLocalAppState(localState); - } + } } catch (e) { console.log("[Sync] failed to get remote state", e); throw e; diff --git a/app/store/update.ts b/app/store/update.ts index 7253caffcb9..e68fde369d5 100644 --- a/app/store/update.ts +++ b/app/store/update.ts @@ -8,8 +8,6 @@ import { getClientConfig } from "../config/client"; import { createPersistStore } from "../utils/store"; import ChatGptIcon from "../icons/chatgpt.png"; import Locale from "../locales"; -import { use } from "react"; -import { useAppConfig } from "."; import { ClientApi } from "../client/api"; const ONE_MINUTE = 60 * 1000; diff --git a/app/utils.ts b/app/utils.ts index bf745092913..9a8bebf38c7 100644 --- a/app/utils.ts +++ b/app/utils.ts @@ -3,8 +3,7 @@ import { showToast } from "./components/ui-lib"; import Locale from "./locales"; import { RequestMessage } from "./client/api"; import { ServiceProvider, REQUEST_TIMEOUT_MS } from "./constant"; -import isObject from "lodash-es/isObject"; -import { fetch as tauriFetch, Body, ResponseType } from "@tauri-apps/api/http"; +import { fetch as tauriFetch, ResponseType } from "@tauri-apps/api/http"; export function trimTopic(topic: string) { // Fix an issue where double quotes still show in the Indonesian language diff --git a/app/utils/cors.ts b/app/utils/cors.ts index fa348f9bf5d..f5e5ce6f0a2 100644 --- a/app/utils/cors.ts +++ b/app/utils/cors.ts @@ -1,5 +1,5 @@ import { getClientConfig } from "../config/client"; -import { ApiPath, DEFAULT_API_HOST } from "../constant"; +import { DEFAULT_API_HOST } from "../constant"; export function corsPath(path: string) { const baseUrl = getClientConfig()?.isApp ? `${DEFAULT_API_HOST}` : ""; diff --git a/package.json b/package.json index ca5fcc0f5df..ac4c65f75e6 100644 --- a/package.json +++ b/package.json @@ -66,6 +66,7 @@ "eslint-config-next": "13.4.19", "eslint-config-prettier": "^8.8.0", "eslint-plugin-prettier": "^5.1.3", + "eslint-plugin-unused-imports": "^3.2.0", "husky": "^8.0.0", "lint-staged": "^13.2.2", "prettier": "^3.0.2", diff --git a/yarn.lock b/yarn.lock index 4979e4d995e..8751953cad6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3367,6 +3367,18 @@ eslint-plugin-react@^7.31.7: semver "^6.3.0" string.prototype.matchall "^4.0.8" +eslint-plugin-unused-imports@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-unused-imports/-/eslint-plugin-unused-imports-3.2.0.tgz#63a98c9ad5f622cd9f830f70bc77739f25ccfe0d" + integrity sha512-6uXyn6xdINEpxE1MtDjxQsyXB37lfyO2yKGVVgtD7WEWQGORSOZjgrD6hBhvGv4/SO+TOlS+UnC6JppRqbuwGQ== + dependencies: + eslint-rule-composer "^0.3.0" + +eslint-rule-composer@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/eslint-rule-composer/-/eslint-rule-composer-0.3.0.tgz#79320c927b0c5c0d3d3d2b76c8b4a488f25bbaf9" + integrity sha512-bt+Sh8CtDmn2OajxvNO+BX7Wn4CIWMpTRm3MaiKPCQcnnlm0CS2mhui6QaoeQugs+3Kj2ESKEEGJUdVafwhiCg== + eslint-scope@5.1.1: version "5.1.1" resolved "https://registry.npmmirror.com/eslint-scope/-/eslint-scope-5.1.1.tgz#e786e59a66cb92b3f6c1fb0d508aab174848f48c"