mirror of https://github.com/msgbyte/tailchat
feat: 增加手动安装插件功能
parent
ca8df00861
commit
7929ef1ecf
@ -0,0 +1,18 @@
|
||||
import { isValidJson } from '../json-helper';
|
||||
|
||||
describe('isValidJson', () => {
|
||||
test.each([
|
||||
['foo', false],
|
||||
['[]', true],
|
||||
['{}', true],
|
||||
['{"foo": []}', true],
|
||||
['{"foo": [}', false],
|
||||
['{foo: bar}', false],
|
||||
['{"foo": "bar"}', true],
|
||||
[[], false],
|
||||
[null, false],
|
||||
[undefined, false],
|
||||
])('%s => %s', (input: any, should) => {
|
||||
expect(isValidJson(input)).toBe(should);
|
||||
});
|
||||
});
|
@ -0,0 +1,16 @@
|
||||
/**
|
||||
* 判断是否是一个合法的json字符串
|
||||
* @param jsonStr json字符串
|
||||
*/
|
||||
export function isValidJson(jsonStr: string): boolean {
|
||||
if (typeof jsonStr !== 'string') {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
JSON.parse(jsonStr);
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
@ -1,11 +1,17 @@
|
||||
// mock
|
||||
jest.mock('tailchat-shared/i18n');
|
||||
|
||||
const ignoreErroMessages = [
|
||||
/Warning.*not wrapped in act/,
|
||||
/PluginManifest validation/,
|
||||
];
|
||||
|
||||
// https://github.com/testing-library/react-testing-library#suppressing-unnecessary-warnings-on-react-dom-168
|
||||
const originalError = console.error;
|
||||
console.error = (...args) => {
|
||||
if (/Warning.*not wrapped in act/.test(args[0])) {
|
||||
if (ignoreErroMessages.some((re) => re.test(args[0]))) {
|
||||
return;
|
||||
}
|
||||
|
||||
originalError.call(console, ...args);
|
||||
};
|
||||
|
@ -0,0 +1,55 @@
|
||||
import { parsePluginManifest } from '../utils';
|
||||
|
||||
describe('parsePluginManifest', () => {
|
||||
test.each([
|
||||
[
|
||||
'correct',
|
||||
JSON.stringify({
|
||||
label: '网页面板插件',
|
||||
name: 'com.msgbyte.webview',
|
||||
url: '/plugins/com.msgbyte.webview/index.js',
|
||||
version: '0.0.0',
|
||||
author: 'msgbyte',
|
||||
description: '为群组提供创建网页面板的功能',
|
||||
requireRestart: false,
|
||||
}),
|
||||
true,
|
||||
],
|
||||
['string', 'foo.bar', false],
|
||||
[
|
||||
'no used properties',
|
||||
JSON.stringify({
|
||||
label: '网页面板插件',
|
||||
foo: 'bar',
|
||||
}),
|
||||
false,
|
||||
],
|
||||
[
|
||||
'more properties',
|
||||
JSON.stringify({
|
||||
label: '网页面板插件',
|
||||
name: 'com.msgbyte.webview',
|
||||
url: '/plugins/com.msgbyte.webview/index.js',
|
||||
version: '0.0.0',
|
||||
author: 'msgbyte',
|
||||
description: '为群组提供创建网页面板的功能',
|
||||
requireRestart: false,
|
||||
foo: 'bar',
|
||||
}),
|
||||
true,
|
||||
],
|
||||
[
|
||||
'missed properties',
|
||||
JSON.stringify({
|
||||
label: '网页面板插件',
|
||||
}),
|
||||
false,
|
||||
],
|
||||
])('case: %# %s', (title, input, valid) => {
|
||||
if (valid === true) {
|
||||
expect(parsePluginManifest(input)).toEqual(JSON.parse(input));
|
||||
} else {
|
||||
expect(() => parsePluginManifest(input)).toThrowError();
|
||||
}
|
||||
});
|
||||
});
|
@ -0,0 +1,39 @@
|
||||
import { isValidJson, PluginManifest, t } from 'tailchat-shared';
|
||||
import { Validator } from 'jsonschema';
|
||||
|
||||
/**
|
||||
* 解析json字符串成插件对象
|
||||
* 如果格式不合法则会抛出异常
|
||||
*/
|
||||
export function parsePluginManifest(json: string): PluginManifest {
|
||||
if (!isValidJson(json)) {
|
||||
throw new Error(t('不是一个合法的JSON字符串'));
|
||||
}
|
||||
|
||||
const obj = JSON.parse(json);
|
||||
const { valid, errors } = new Validator().validate(obj, {
|
||||
type: 'object',
|
||||
properties: {
|
||||
label: { type: 'string' },
|
||||
name: { type: 'string' },
|
||||
url: { type: 'string' },
|
||||
version: { type: 'string' },
|
||||
author: { type: 'string' },
|
||||
description: { type: 'string' },
|
||||
requireRestart: { type: 'boolean' },
|
||||
},
|
||||
required: ['label', 'name', 'url', 'version', 'author', 'description'],
|
||||
additionalProperties: false,
|
||||
});
|
||||
|
||||
if (!valid) {
|
||||
console.error(
|
||||
'[PluginManifest validation]:',
|
||||
errors.map((e) => e.message).join(', ')
|
||||
);
|
||||
|
||||
throw new Error(t('不是一个合法的插件配置'));
|
||||
}
|
||||
|
||||
return obj;
|
||||
}
|
Loading…
Reference in New Issue