diff --git a/.eslintrc.js b/.eslintrc.js index e7631e686..d79aac226 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -24,7 +24,7 @@ module.exports = { plugins: ['react', 'react-hooks', '@typescript-eslint'], rules: { 'react/react-in-jsx-scope': 'off', - '@typescript-eslint/ban-ts-comment': ['error', { 'ts-ignore': 'allow-with-description' }], + '@typescript-eslint/ban-ts-comment': ['error', { 'ts-ignore': 'allow' }], indent: ['error', 2, { SwitchCase: 1 }], 'max-len': [ 'error', @@ -42,12 +42,6 @@ module.exports = { // 'no-plusplus': ['error', { allowForLoopAfterthoughts: true }], 'no-console': 'off', 'import/extensions': 'off', - 'no-use-before-define': [ - 'error', - { - functions: false - } - ], 'no-promise-executor-return': 'off', 'no-param-reassign': 'off', 'no-continue': 'off', @@ -103,6 +97,18 @@ module.exports = { 'plugin:@typescript-eslint/eslint-recommended', 'plugin:@typescript-eslint/recommended' ] + }, + { + files: './packages/data-provider/**/*.ts', + overrides: [ + { + files: "**/*.ts", + parser: "@typescript-eslint/parser", + parserOptions: { + project: "./packages/data-provider/tsconfig.json" + } + } + ] } ], settings: { diff --git a/.github/workflows/frontend-review.yml b/.github/workflows/frontend-review.yml index 6652d686c..acc43b503 100644 --- a/.github/workflows/frontend-review.yml +++ b/.github/workflows/frontend-review.yml @@ -25,10 +25,10 @@ jobs: cache: 'npm' - name: Install dependencies - run: npm ci --ignore-scripts + run: npm ci - name: Build Client - run: cd client && npm run build:ci + run: npm run frontend:ci - name: Run unit tests run: cd client && npm run test:ci \ No newline at end of file diff --git a/.gitignore b/.gitignore index ba54ad547..2bf3b872e 100644 --- a/.gitignore +++ b/.gitignore @@ -39,6 +39,7 @@ meili_data/ api/node_modules/ client/node_modules/ bower_components/ +types/ # Floobits .floo @@ -72,3 +73,5 @@ junit.xml meilisearch data.ms/* auth.json + +/packages/ux-shared/ diff --git a/client/package.json b/client/package.json index 784453410..7ac7694ee 100644 --- a/client/package.json +++ b/client/package.json @@ -3,6 +3,7 @@ "version": "0.5.2", "description": "", "scripts": { + "data-provider": "cd .. && npm run build:data-provider", "build": "cross-env NODE_ENV=production dotenv -e ../.env -- vite build", "build:ci": "cross-env NODE_ENV=dev vite build --mode ci", "dev": "cross-env NODE_ENV=dev dotenv -e ../.env -- vite", @@ -75,7 +76,8 @@ "tailwind-merge": "^1.9.1", "tailwindcss-animate": "^1.0.5", "tailwindcss-radix": "^2.8.0", - "url": "^0.11.0" + "url": "^0.11.0", + "@librechat/data-provider": "*" }, "devDependencies": { "@babel/cli": "^7.20.7", diff --git a/client/src/components/Auth/Login.tsx b/client/src/components/Auth/Login.tsx index 5d2b2625d..d894266dc 100644 --- a/client/src/components/Auth/Login.tsx +++ b/client/src/components/Auth/Login.tsx @@ -2,7 +2,7 @@ import { useEffect } from 'react'; import LoginForm from './LoginForm'; import { useAuthContext } from '~/hooks/AuthContext'; import { useNavigate } from 'react-router-dom'; -import { useGetStartupConfig } from '~/data-provider'; +import { useGetStartupConfig } from '@librechat/data-provider'; function Login() { const { login, error, isAuthenticated } = useAuthContext(); diff --git a/client/src/components/Auth/LoginForm.tsx b/client/src/components/Auth/LoginForm.tsx index 582ab3b21..c013ae2ca 100644 --- a/client/src/components/Auth/LoginForm.tsx +++ b/client/src/components/Auth/LoginForm.tsx @@ -1,5 +1,5 @@ import { useForm } from 'react-hook-form'; -import { TLoginUser } from '~/data-provider'; +import { TLoginUser } from '@librechat/data-provider'; type TLoginFormProps = { onSubmit: (data: TLoginUser) => void; diff --git a/client/src/components/Auth/Registration.tsx b/client/src/components/Auth/Registration.tsx index 29cf776a1..c977c955d 100644 --- a/client/src/components/Auth/Registration.tsx +++ b/client/src/components/Auth/Registration.tsx @@ -1,7 +1,11 @@ import { useState, useEffect } from 'react'; import { useNavigate } from 'react-router-dom'; import { useForm } from 'react-hook-form'; -import { useRegisterUserMutation, TRegisterUser, useGetStartupConfig } from '~/data-provider'; +import { + useRegisterUserMutation, + TRegisterUser, + useGetStartupConfig +} from '@librechat/data-provider'; function Registration() { const navigate = useNavigate(); @@ -27,7 +31,9 @@ function Registration() { }, onError: (error) => { setError(true); + //@ts-ignore - error is of type unknown if (error.response?.data?.message) { + //@ts-ignore - error is of type unknown setErrorMessage(error.response?.data?.message); } } diff --git a/client/src/components/Auth/RequestPasswordReset.tsx b/client/src/components/Auth/RequestPasswordReset.tsx index a94c587a8..6b992c0d8 100644 --- a/client/src/components/Auth/RequestPasswordReset.tsx +++ b/client/src/components/Auth/RequestPasswordReset.tsx @@ -1,6 +1,10 @@ import { useState } from 'react'; import { useForm } from 'react-hook-form'; -import { useRequestPasswordResetMutation, TRequestPasswordReset } from '~/data-provider'; +import { + useRequestPasswordResetMutation, + TRequestPasswordReset, + TRequestPasswordResetResponse +} from '@librechat/data-provider'; function RequestPasswordReset() { const { @@ -15,7 +19,7 @@ function RequestPasswordReset() { const onSubmit = (data: TRequestPasswordReset) => { requestPasswordReset.mutate(data, { - onSuccess: (data) => { + onSuccess: (data: TRequestPasswordResetResponse) => { setSuccess(true); setResetLink(data.link); }, diff --git a/client/src/components/Auth/ResetPassword.tsx b/client/src/components/Auth/ResetPassword.tsx index 452799fe0..34c7f9fa1 100644 --- a/client/src/components/Auth/ResetPassword.tsx +++ b/client/src/components/Auth/ResetPassword.tsx @@ -1,6 +1,6 @@ import { useState } from 'react'; import { useForm } from 'react-hook-form'; -import { useResetPasswordMutation, TResetPassword } from '~/data-provider'; +import { useResetPasswordMutation, TResetPassword } from '@librechat/data-provider'; import { useNavigate, useSearchParams } from 'react-router-dom'; function ResetPassword() { @@ -73,12 +73,14 @@ function ResetPassword() { diff --git a/client/src/components/Auth/__tests__/Login.spec.tsx b/client/src/components/Auth/__tests__/Login.spec.tsx index cf9b0fa41..6c6d4c9ed 100644 --- a/client/src/components/Auth/__tests__/Login.spec.tsx +++ b/client/src/components/Auth/__tests__/Login.spec.tsx @@ -1,9 +1,9 @@ import { render, waitFor } from 'layout-test-utils'; import userEvent from '@testing-library/user-event'; import Login from '../Login'; -import * as mockDataProvider from '~/data-provider'; +import * as mockDataProvider from '@librechat/data-provider'; -jest.mock('~/data-provider'); +jest.mock('@librechat/data-provider'); const setup = ({ useGetUserQueryReturnValue = { diff --git a/client/src/components/Auth/__tests__/Registration.spec.tsx b/client/src/components/Auth/__tests__/Registration.spec.tsx index 6a373be68..b720116fd 100644 --- a/client/src/components/Auth/__tests__/Registration.spec.tsx +++ b/client/src/components/Auth/__tests__/Registration.spec.tsx @@ -1,9 +1,9 @@ import { render, waitFor } from 'layout-test-utils'; import userEvent from '@testing-library/user-event'; import Registration from '../Registration'; -import * as mockDataProvider from '~/data-provider'; +import * as mockDataProvider from '@librechat/data-provider'; -jest.mock('~/data-provider'); +jest.mock('@librechat/data-provider'); const setup = ({ useGetUserQueryReturnValue = { diff --git a/client/src/components/Conversations/Conversation.jsx b/client/src/components/Conversations/Conversation.jsx index 0d4f7ccbf..9c2503e30 100644 --- a/client/src/components/Conversations/Conversation.jsx +++ b/client/src/components/Conversations/Conversation.jsx @@ -1,6 +1,6 @@ import { useState, useRef, useEffect } from 'react'; import { useRecoilState, useSetRecoilState } from 'recoil'; -import { useUpdateConversationMutation } from '~/data-provider'; +import { useUpdateConversationMutation } from '@librechat/data-provider'; import RenameButton from './RenameButton'; import DeleteButton from './DeleteButton'; import ConvoIcon from '../svg/ConvoIcon'; diff --git a/client/src/components/Conversations/DeleteButton.jsx b/client/src/components/Conversations/DeleteButton.jsx index 09b73fdb4..217aab0b3 100644 --- a/client/src/components/Conversations/DeleteButton.jsx +++ b/client/src/components/Conversations/DeleteButton.jsx @@ -2,7 +2,7 @@ import { useEffect } from 'react'; import TrashIcon from '../svg/TrashIcon'; import CrossIcon from '../svg/CrossIcon'; import { useRecoilValue } from 'recoil'; -import { useDeleteConversationMutation } from '~/data-provider'; +import { useDeleteConversationMutation } from '@librechat/data-provider'; import store from '~/store'; diff --git a/client/src/components/Endpoints/BingAI/Settings.jsx b/client/src/components/Endpoints/BingAI/Settings.jsx index daf5ab25b..65438edb0 100644 --- a/client/src/components/Endpoints/BingAI/Settings.jsx +++ b/client/src/components/Endpoints/BingAI/Settings.jsx @@ -5,7 +5,7 @@ import { Checkbox } from '~/components/ui/Checkbox.tsx'; import SelectDropDown from '../../ui/SelectDropDown'; import { cn } from '~/utils/'; import useDebounce from '~/hooks/useDebounce'; -import { useUpdateTokenCountMutation } from '~/data-provider'; +import { useUpdateTokenCountMutation } from '@librechat/data-provider'; const defaultTextProps = 'rounded-md border border-gray-200 focus:border-slate-400 focus:bg-gray-50 bg-transparent text-sm shadow-[0_0_10px_rgba(0,0,0,0.05)] outline-none placeholder:text-gray-400 focus:outline-none focus:ring-gray-400 focus:ring-opacity-20 focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-500 dark:bg-gray-700 focus:dark:bg-gray-600 dark:text-gray-50 dark:shadow-[0_0_15px_rgba(0,0,0,0.10)] dark:focus:border-gray-400 dark:focus:outline-none dark:focus:ring-0 dark:focus:ring-gray-400 dark:focus:ring-offset-0'; @@ -43,7 +43,7 @@ function Settings(props) { }, [debouncedContext]); return ( -
+
@@ -113,7 +113,8 @@ function Settings(props) { System Message {' '} diff --git a/client/src/components/Endpoints/SaveAsPresetDialog.jsx b/client/src/components/Endpoints/SaveAsPresetDialog.jsx index f2d2e7db6..a371ff080 100644 --- a/client/src/components/Endpoints/SaveAsPresetDialog.jsx +++ b/client/src/components/Endpoints/SaveAsPresetDialog.jsx @@ -1,9 +1,9 @@ import React, { useEffect, useState } from 'react'; import { useRecoilValue } from 'recoil'; -import {Dialog, DialogTemplate, Input, Label} from '../ui/'; +import { Dialog, DialogTemplate, Input, Label } from '../ui/'; import { cn } from '~/utils/'; import cleanupPreset from '~/utils/cleanupPreset'; -import { useCreatePresetMutation } from '~/data-provider'; +import { useCreatePresetMutation } from '@librechat/data-provider'; import store from '~/store'; const SaveAsPresetDialog = ({ open, onOpenChange, preset }) => { diff --git a/client/src/components/Input/Footer.tsx b/client/src/components/Input/Footer.tsx index 28c61736a..bc13159f5 100644 --- a/client/src/components/Input/Footer.tsx +++ b/client/src/components/Input/Footer.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { useGetStartupConfig } from '~/data-provider'; +import { useGetStartupConfig } from '@librechat/data-provider'; export default function Footer() { const { data: config } = useGetStartupConfig(); diff --git a/client/src/components/Input/NewConversationMenu/index.jsx b/client/src/components/Input/NewConversationMenu/index.jsx index 4255be976..3b3d64774 100644 --- a/client/src/components/Input/NewConversationMenu/index.jsx +++ b/client/src/components/Input/NewConversationMenu/index.jsx @@ -9,7 +9,7 @@ import { Trash2 } from 'lucide-react'; import FileUpload from './FileUpload'; import getIcon from '~/utils/getIcon'; import getDefaultConversation from '~/utils/getDefaultConversation'; -import { useDeletePresetMutation, useCreatePresetMutation } from '~/data-provider'; +import { useDeletePresetMutation, useCreatePresetMutation } from '@librechat/data-provider'; import { Button, DropdownMenu, @@ -19,7 +19,8 @@ import { DropdownMenuSeparator, DropdownMenuTrigger, DialogTemplate, - Dialog, DialogTrigger + Dialog, + DialogTrigger } from '../../ui/'; import { cn } from '~/utils/'; @@ -87,8 +88,9 @@ export default function NewConversationMenu() { // set the current model const onSelectEndpoint = (newEndpoint) => { setMenuOpen(false); - if (!newEndpoint) { return; } - else { + if (!newEndpoint) { + return; + } else { newConversation({}, { endpoint: newEndpoint }); } }; @@ -101,7 +103,7 @@ export default function NewConversationMenu() { const currentConvo = getDefaultConversation({ conversation, endpointsConfig, - preset: newPreset, + preset: newPreset }); setConversation(currentConvo); @@ -153,7 +155,7 @@ export default function NewConversationMenu() { event.preventDefault()} > {showEndpoints && (availableEndpoints.length ? ( - + ) : ( No endpoint available. @@ -217,7 +223,10 @@ export default function NewConversationMenu() { {showPresets && (presets.length ? ( diff --git a/client/src/components/Input/PluginsOptions/index.jsx b/client/src/components/Input/PluginsOptions/index.jsx index 62408db8a..d6fdb70d7 100644 --- a/client/src/components/Input/PluginsOptions/index.jsx +++ b/client/src/components/Input/PluginsOptions/index.jsx @@ -14,7 +14,7 @@ import { Settings, AgentSettings } from '../../Endpoints/Plugins/'; import { cn } from '~/utils/'; import store from '~/store'; import { useAuthContext } from '~/hooks/AuthContext'; -import { useAvailablePluginsQuery } from '~/data-provider'; +import { useAvailablePluginsQuery } from '@librechat/data-provider'; function PluginsOptions() { const { data: allPlugins } = useAvailablePluginsQuery(); diff --git a/client/src/components/MessageHandler/index.jsx b/client/src/components/MessageHandler/index.jsx index 7a11fe5b0..a3e04a0fc 100644 --- a/client/src/components/MessageHandler/index.jsx +++ b/client/src/components/MessageHandler/index.jsx @@ -1,7 +1,6 @@ import { useEffect } from 'react'; import { useRecoilValue, useResetRecoilState, useSetRecoilState } from 'recoil'; -import { SSE } from '~/data-provider/sse.mjs'; -import createPayload from '~/data-provider/createPayload'; +import { SSE, createPayload } from '@librechat/data-provider'; import store from '~/store'; import { useAuthContext } from '~/hooks/AuthContext'; @@ -224,7 +223,8 @@ export default function MessageHandler() { events.onopen = () => console.log('connection is opened'); - events.oncancel = () => abortConversation(message?.conversationId || submission?.conversationId); + events.oncancel = () => + abortConversation(message?.conversationId || submission?.conversationId); events.onerror = function (e) { console.log('error in opening conn.'); diff --git a/client/src/components/Messages/Message.jsx b/client/src/components/Messages/Message.jsx index 31cd9921c..635127e7d 100644 --- a/client/src/components/Messages/Message.jsx +++ b/client/src/components/Messages/Message.jsx @@ -10,7 +10,7 @@ import HoverButtons from './HoverButtons'; import SiblingSwitch from './SiblingSwitch'; import getIcon from '~/utils/getIcon'; import { useMessageHandler } from '~/utils/handleSubmit'; -import { useGetConversationByIdQuery } from '~/data-provider'; +import { useGetConversationByIdQuery } from '@librechat/data-provider'; import { cn } from '~/utils/'; import store from '~/store'; import getError from '~/utils/getError'; @@ -192,7 +192,7 @@ export default function Message({
{!isCreatedByUser ? ( <> - + ) : ( <>{text} diff --git a/client/src/components/Nav/ClearConvos.tsx b/client/src/components/Nav/ClearConvos.tsx index da51542d6..2055e62ef 100644 --- a/client/src/components/Nav/ClearConvos.tsx +++ b/client/src/components/Nav/ClearConvos.tsx @@ -1,7 +1,7 @@ import { useState, useEffect, useCallback } from 'react'; import { Dialog, DialogTemplate } from '../ui/'; import { ClearChatsButton } from './SettingsTabs/'; -import { useClearConversationsMutation } from '~/data-provider'; +import { useClearConversationsMutation } from '@librechat/data-provider'; import store from '~/store'; const ClearConvos = ({ open, onOpenChange }) => { @@ -32,7 +32,9 @@ const ClearConvos = ({ open, onOpenChange }) => { } + leftButtons={ + + } /> ); diff --git a/client/src/components/Nav/Settings.jsx b/client/src/components/Nav/Settings.jsx index 2fbdf0dc8..88dbd079f 100644 --- a/client/src/components/Nav/Settings.jsx +++ b/client/src/components/Nav/Settings.jsx @@ -4,7 +4,7 @@ import { General } from './SettingsTabs/'; import { CogIcon } from '~/components/svg'; import { useEffect, useState } from 'react'; import { cn } from '~/utils/'; -import { useClearConversationsMutation } from '~/data-provider'; +import { useClearConversationsMutation } from '@librechat/data-provider'; import store from '~/store'; export default function Settings({ open, onOpenChange }) { diff --git a/client/src/components/Nav/SettingsTabs/General.tsx b/client/src/components/Nav/SettingsTabs/General.tsx index 1d2633e3e..d3d8907b0 100644 --- a/client/src/components/Nav/SettingsTabs/General.tsx +++ b/client/src/components/Nav/SettingsTabs/General.tsx @@ -2,9 +2,15 @@ import * as Tabs from '@radix-ui/react-tabs'; import { CheckIcon } from 'lucide-react'; import { ThemeContext } from '~/hooks/ThemeContext'; import React, { useState, useContext, useCallback } from 'react'; -import { useClearConversationsMutation } from '~/data-provider'; +import { useClearConversationsMutation } from '@librechat/data-provider'; -export const ThemeSelector = ({ theme, onChange }: { theme: string, onChange: (value: string) => void }) => ( +export const ThemeSelector = ({ + theme, + onChange +}: { + theme: string; + onChange: (value: string) => void; +}) => (
Theme