Skip to content

Commit

Permalink
Merge branch 'lobehub:main' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
imjason authored Apr 14, 2024
2 parents bd3f4b1 + a609858 commit 06fa9f7
Show file tree
Hide file tree
Showing 28 changed files with 320 additions and 248 deletions.
25 changes: 25 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,31 @@

# Changelog

### [Version 0.147.13](https://github.com/lobehub/lobe-chat/compare/v0.147.12...v0.147.13)

<sup>Released on **2024-04-14**</sup>

#### ♻ Code Refactoring

- **misc**: Refactor the service with browser db invoke.

<br/>

<details>
<summary><kbd>Improvements and Fixes</kbd></summary>

#### Code refactoring

- **misc**: Refactor the service with browser db invoke, closes [#2038](https://github.com/lobehub/lobe-chat/issues/2038) ([43a2791](https://github.com/lobehub/lobe-chat/commit/43a2791))

</details>

<div align="right">

[![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)

</div>

### [Version 0.147.12](https://github.com/lobehub/lobe-chat/compare/v0.147.11...v0.147.12)

<sup>Released on **2024-04-14**</sup>
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@lobehub/chat",
"version": "0.147.12",
"version": "0.147.13",
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
"keywords": [
"framework",
Expand Down
4 changes: 2 additions & 2 deletions src/features/PluginDevModal/UrlManifestForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next';
import { Flexbox } from 'react-layout-kit';

import ManifestPreviewer from '@/components/ManifestPreviewer';
import { pluginService } from '@/services/plugin';
import { toolService } from '@/services/tool';
import { useToolStore } from '@/store/tool';
import { pluginSelectors } from '@/store/tool/selectors';
import { PluginInstallError } from '@/types/tool/plugin';
Expand Down Expand Up @@ -77,7 +77,7 @@ const UrlManifestForm = memo<{ form: FormInstance; isEditMode: boolean }>(

try {
const useProxy = form.getFieldValue(proxyKey);
const data = await pluginService.getPluginManifest(value, useProxy);
const data = await toolService.getPluginManifest(value, useProxy);
setManifest(data);

form.setFieldsValue({ identifier: data.identifier, manifest: data });
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html

exports[`PluginService > can parse the OpenAI plugin 1`] = `
exports[`ToolService > can parse the OpenAI plugin 1`] = `
{
"api": [],
"homepage": "https://products.wolframalpha.com/api/commercial-termsofuse",
Expand Down Expand Up @@ -78,7 +78,7 @@ getWolframCloudResults guidelines:
}
`;
exports[`PluginService > getPluginManifest > support OpenAPI manifest > should get plugin manifest 1`] = `
exports[`ToolService > getPluginManifest > support OpenAPI manifest > should get plugin manifest 1`] = `
{
"$schema": "../node_modules/@lobehub/chat-plugin-sdk/schema.json",
"api": [
Expand Down
1 change: 0 additions & 1 deletion src/services/__tests__/chat.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import { DalleManifest } from '@/tools/dalle';
import { ChatMessage } from '@/types/message';
import { ChatStreamPayload } from '@/types/openai/chat';
import { LobeTool } from '@/types/tool';
import { FetchSSEOptions, fetchSSE } from '@/utils/fetch';

import { chatService } from '../chat';

Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
import { LobeChatPluginManifest } from '@lobehub/chat-plugin-sdk';
import { Mock, beforeEach, describe, expect, it, vi } from 'vitest';

import { PluginModel } from '@/database/client/models/plugin';
import { DB_Plugin } from '@/database/client/schemas/plugin';
import { globalHelpers } from '@/store/global/helpers';
import { LobeTool } from '@/types/tool';
import { LobeToolCustomPlugin } from '@/types/tool/plugin';

import { InstallPluginParams, pluginService } from '../plugin';
import { toolService } from '../tool';
import openAPIV3 from './openai/OpenAPI_V3.json';
import OpenAIPlugin from './openai/plugin.json';

Expand All @@ -18,21 +13,12 @@ vi.mock('@/store/global/helpers', () => ({
getCurrentLanguage: vi.fn(),
},
}));
vi.mock('@/database/client/models/plugin', () => ({
PluginModel: {
getList: vi.fn(),
create: vi.fn(),
delete: vi.fn(),
update: vi.fn(),
clear: vi.fn(),
},
}));

beforeEach(() => {
vi.resetAllMocks();
});

describe('PluginService', () => {
describe('ToolService', () => {
describe('getPluginList', () => {
it('should fetch and return the plugin list', async () => {
// Arrange
Expand All @@ -45,7 +31,7 @@ describe('PluginService', () => {
) as any;

// Act
const pluginList = await pluginService.getPluginList();
const pluginList = await toolService.getPluginList();

// Assert
expect(globalHelpers.getCurrentLanguage).toHaveBeenCalled();
Expand All @@ -60,7 +46,7 @@ describe('PluginService', () => {
global.fetch = vi.fn(() => Promise.reject(new Error('Network error')));

// Act & Assert
await expect(pluginService.getPluginList()).rejects.toThrow('Network error');
await expect(toolService.getPluginList()).rejects.toThrow('Network error');
});
});

Expand Down Expand Up @@ -112,15 +98,15 @@ describe('PluginService', () => {
}),
) as any;

const manifest = await pluginService.getPluginManifest(manifestUrl);
const manifest = await toolService.getPluginManifest(manifestUrl);

expect(fetch).toHaveBeenCalledWith(manifestUrl);
expect(manifest).toEqual(fakeManifest);
});

it('should return error on noManifest', async () => {
try {
await pluginService.getPluginManifest();
await toolService.getPluginManifest();
} catch (e) {
expect(e).toEqual(new TypeError('noManifest'));
}
Expand All @@ -138,7 +124,7 @@ describe('PluginService', () => {
) as any;

try {
await pluginService.getPluginManifest(manifestUrl);
await toolService.getPluginManifest(manifestUrl);
} catch (e) {
expect(e).toEqual(new TypeError('manifestInvalid'));
}
Expand All @@ -149,7 +135,7 @@ describe('PluginService', () => {
global.fetch = vi.fn(() => Promise.reject(new Error('Network error')));

try {
await pluginService.getPluginManifest(manifestUrl);
await toolService.getPluginManifest(manifestUrl);
} catch (e) {
expect(e).toEqual(new TypeError('fetchError'));
}
Expand All @@ -170,7 +156,7 @@ describe('PluginService', () => {
) as any;

try {
await pluginService.getPluginManifest(manifestUrl);
await toolService.getPluginManifest(manifestUrl);
} catch (e) {
expect(e).toEqual(new TypeError('urlError'));
}
Expand All @@ -188,7 +174,7 @@ describe('PluginService', () => {
) as any;

try {
await pluginService.getPluginManifest(manifestUrl);
await toolService.getPluginManifest(manifestUrl);
} catch (e) {
expect(e).toEqual(new TypeError('fetchError'));
}
Expand Down Expand Up @@ -228,7 +214,7 @@ describe('PluginService', () => {
}),
) as any;

const manifest = await pluginService.getPluginManifest(manifestUrl);
const manifest = await toolService.getPluginManifest(manifestUrl);

expect(manifest).toMatchSnapshot();
});
Expand Down Expand Up @@ -266,149 +252,16 @@ describe('PluginService', () => {
) as any;

try {
await pluginService.getPluginManifest(manifestUrl);
await toolService.getPluginManifest(manifestUrl);
} catch (e) {
expect(e).toEqual(new TypeError('openAPIInvalid'));
}
});
});
});

describe('installPlugin', () => {
it('should install a plugin', async () => {
// Arrange
const fakePlugin = {
identifier: 'test-plugin',
manifest: { name: 'TestPlugin', version: '1.0.0' } as unknown as LobeChatPluginManifest,
type: 'plugin',
} as InstallPluginParams;
vi.mocked(PluginModel.create).mockResolvedValue(fakePlugin);

// Act
const installedPlugin = await pluginService.installPlugin(fakePlugin);

// Assert
expect(PluginModel.create).toHaveBeenCalledWith(fakePlugin);
expect(installedPlugin).toEqual(fakePlugin);
});
});

describe('getInstalledPlugins', () => {
it('should return a list of installed plugins', async () => {
// Arrange
const fakePlugins = [{ identifier: 'test-plugin', type: 'plugin' }] as LobeTool[];
vi.mocked(PluginModel.getList).mockResolvedValue(fakePlugins as DB_Plugin[]);

// Act
const installedPlugins = await pluginService.getInstalledPlugins();

// Assert
expect(PluginModel.getList).toHaveBeenCalled();
expect(installedPlugins).toEqual(fakePlugins);
});
});

describe('uninstallPlugin', () => {
it('should uninstall a plugin', async () => {
// Arrange
const identifier = 'test-plugin';
vi.mocked(PluginModel.delete).mockResolvedValue();

// Act
const result = await pluginService.uninstallPlugin(identifier);

// Assert
expect(PluginModel.delete).toHaveBeenCalledWith(identifier);
expect(result).toBe(undefined);
});
});

describe('createCustomPlugin', () => {
it('should create a custom plugin', async () => {
// Arrange
const customPlugin = {
identifier: 'custom-plugin',
manifest: {},
type: 'customPlugin',
} as LobeToolCustomPlugin;
vi.mocked(PluginModel.create).mockResolvedValue(customPlugin);

// Act
const result = await pluginService.createCustomPlugin(customPlugin);

// Assert
expect(PluginModel.create).toHaveBeenCalledWith({
...customPlugin,
type: 'customPlugin',
});
expect(result).toEqual(customPlugin);
});
});

describe('updatePlugin', () => {
it('should update a plugin', async () => {
// Arrange
const id = 'plugin-id';
const value = { settings: { ab: '1' } } as unknown as LobeToolCustomPlugin;
vi.mocked(PluginModel.update).mockResolvedValue(1);

// Act
const result = await pluginService.updatePlugin(id, value);

// Assert
expect(PluginModel.update).toHaveBeenCalledWith(id, value);
expect(result).toEqual(1);
});
});

describe('updatePluginManifest', () => {
it('should update a plugin manifest', async () => {
// Arrange
const id = 'plugin-id';
const manifest = { name: 'NewPluginManifest' } as unknown as LobeChatPluginManifest;
vi.mocked(PluginModel.update).mockResolvedValue(1);

// Act
const result = await pluginService.updatePluginManifest(id, manifest);

// Assert
expect(PluginModel.update).toHaveBeenCalledWith(id, { manifest });
expect(result).toEqual(1);
});
});

describe('removeAllPlugins', () => {
it('should remove all plugins', async () => {
// Arrange
vi.mocked(PluginModel.clear).mockResolvedValue(undefined);

// Act
const result = await pluginService.removeAllPlugins();

// Assert
expect(PluginModel.clear).toHaveBeenCalled();
expect(result).toBe(undefined);
});
});

describe('updatePluginSettings', () => {
it('should update plugin settings', async () => {
// Arrange
const id = 'plugin-id';
const settings = { color: 'blue' };
vi.mocked(PluginModel.update).mockResolvedValue(1);

// Act
const result = await pluginService.updatePluginSettings(id, settings);

// Assert
expect(PluginModel.update).toHaveBeenCalledWith(id, { settings });
expect(result).toEqual(1);
});
});

it('can parse the OpenAI plugin', async () => {
const manifest = pluginService['convertOpenAIManifestToLobeManifest'](OpenAIPlugin as any);
const manifest = toolService['convertOpenAIManifestToLobeManifest'](OpenAIPlugin as any);

expect(manifest).toMatchSnapshot();
});
Expand Down
6 changes: 2 additions & 4 deletions src/services/file.ts → src/services/file/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import { DB_File } from '@/database/client/schemas/files';
import { FilePreview } from '@/types/files';
import compressImage from '@/utils/compressImage';

import { API_ENDPOINTS } from './_url';
import { API_ENDPOINTS } from '../_url';

class FileService {
export class FileService {
private isImage(fileType: string) {
const imageRegex = /^image\//;
return imageRegex.test(fileType);
Expand Down Expand Up @@ -84,5 +84,3 @@ class FileService {
};
}
}

export const fileService = new FileService();
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import { Mock, beforeEach, describe, expect, it, vi } from 'vitest';
import { FileModel } from '@/database/client/models/file';
import { DB_File } from '@/database/client/schemas/files';

import { fileService } from '../file';
import { FileService } from './client';

const fileService = new FileService();

// Mocks for the FileModel
vi.mock('@/database/client/models/file', () => ({
Expand Down
3 changes: 3 additions & 0 deletions src/services/file/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import { FileService } from './client';

export const fileService = new FileService();
Loading

1 comment on commit 06fa9f7

@vercel
Copy link

@vercel vercel bot commented on 06fa9f7 Apr 14, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.