refactor: plugin manager (#965)
* feat: improve code * chore: update version * feat: api service * fix: api services * feat: improve code * feat: improve code * feat: improve code * feat: pm socket * fix: test errors * feat: add built-in plugins before upgrade * feat: update docs * feat: improve code * fix: after load
This commit is contained in:
parent
2c690a39e0
commit
249dff16d3
@ -60,10 +60,7 @@ export default {
|
||||
title: 'Getting started',
|
||||
'title.zh-CN': '快速开始',
|
||||
type: 'group',
|
||||
children: [
|
||||
'/development/index',
|
||||
'/development/your-fisrt-plugin',
|
||||
],
|
||||
children: ['/development/index', '/development/your-fisrt-plugin'],
|
||||
},
|
||||
{
|
||||
title: 'Extension Guides',
|
||||
@ -191,8 +188,8 @@ export default {
|
||||
title: '@nocobase/server',
|
||||
type: 'subMenu',
|
||||
children: [
|
||||
'/api/server/application',
|
||||
//'/api/server/plugin-manager',
|
||||
'/api/server/application',
|
||||
// '/api/server/plugin-manager',
|
||||
'/api/server/plugin',
|
||||
],
|
||||
},
|
||||
|
@ -180,28 +180,9 @@ NocoBase 默认对 context 注入了以下成员,可以在请求处理函数
|
||||
|
||||
## 事件
|
||||
|
||||
|
||||
**示例**
|
||||
|
||||
```ts
|
||||
app.on('beforeStart', async () => {
|
||||
console.log('app before start');
|
||||
});
|
||||
```
|
||||
|
||||
### beforeLoadAll
|
||||
### afterLoadAll
|
||||
### beforeLoadPlugin
|
||||
### afterLoadPlugin
|
||||
### beforeInstallPlugin
|
||||
### afterInstallPlugin
|
||||
### beforeInstall
|
||||
### afterInstall
|
||||
### beforeUpgrade
|
||||
### afterUpgrade
|
||||
### beforeStart
|
||||
### afterStart
|
||||
### beforeStop
|
||||
### afterStop
|
||||
### beforeDestroy
|
||||
### afterDestroy
|
||||
### `'beforeLoad'` / `'afterLoad'`
|
||||
### `'beforeInstall'` / `'afterInstall'`
|
||||
### `'beforeUpgrade'` / `'afterUpgrade'`
|
||||
### `'beforeStart'` / `'afterStart'`
|
||||
### `'beforeStop'` / `'afterStop'`
|
||||
### `'beforeDestroy'` / `'afterDestroy'`
|
||||
|
@ -6,16 +6,54 @@
|
||||
|
||||
### `create()`
|
||||
|
||||
在本地创建一个插件脚手架
|
||||
|
||||
**签名**
|
||||
|
||||
```ts
|
||||
create(name, options): void;
|
||||
```
|
||||
|
||||
### `addStatic()`
|
||||
|
||||
**签名**
|
||||
|
||||
```ts
|
||||
addStatic(plugin: any, options?: PluginOptions): Plugin;
|
||||
```
|
||||
|
||||
**示例**
|
||||
|
||||
```ts
|
||||
pm.addStatic('nocobase');
|
||||
```
|
||||
|
||||
### `add()`
|
||||
|
||||
**签名**
|
||||
|
||||
```ts
|
||||
async add(plugin: any, options?: PluginOptions): Promise<Plugin>;
|
||||
async add(plugin: string[], options?: PluginOptions): Promise<Plugin[]>;
|
||||
```
|
||||
|
||||
**示例**
|
||||
|
||||
```ts
|
||||
await pm.add(['test'], {
|
||||
builtIn: true,
|
||||
enabled: true,
|
||||
});
|
||||
```
|
||||
|
||||
### `get()`
|
||||
|
||||
### `install()`
|
||||
|
||||
### `upgrade()`
|
||||
获取插件实例
|
||||
|
||||
### `enable()`
|
||||
|
||||
### `disable()`
|
||||
|
||||
### `remove()`
|
||||
|
||||
### `upgrade()`
|
||||
|
@ -1,5 +1,23 @@
|
||||
# Plugin
|
||||
|
||||
## 示例
|
||||
|
||||
```ts
|
||||
const app = new Application();
|
||||
|
||||
class MyPlugin extends Plugin {
|
||||
afterAdd() {}
|
||||
beforeLoad() {}
|
||||
load() {}
|
||||
install() {}
|
||||
afterEnable() {}
|
||||
afterDisable() {}
|
||||
remove() {}
|
||||
}
|
||||
|
||||
app.plugin(MyPlugin, { name: 'my-plugin' });
|
||||
```
|
||||
|
||||
## 属性
|
||||
|
||||
### `options`
|
||||
@ -10,20 +28,32 @@
|
||||
|
||||
插件标识,只读
|
||||
|
||||
### `model`
|
||||
|
||||
插件模型数据
|
||||
|
||||
## 实例方法
|
||||
|
||||
### `afterAdd()`
|
||||
|
||||
插件 add/addStatic 之后
|
||||
|
||||
### `beforeLoad()`
|
||||
|
||||
加载前,如事件或类注册
|
||||
插件加载前,如事件或类注册
|
||||
|
||||
### `load()`
|
||||
|
||||
加载配置
|
||||
加载插件,配置之类
|
||||
|
||||
### `install()`
|
||||
|
||||
插件安装逻辑
|
||||
插件安装逻辑,如初始化数据
|
||||
|
||||
### `afterEnable()`
|
||||
|
||||
插件激活之后的逻辑
|
||||
|
||||
### `afterDisable()`
|
||||
|
||||
插件禁用之后的逻辑
|
||||
|
||||
### `remove()`
|
||||
|
||||
用于实现插件删除逻辑
|
@ -1,5 +1,5 @@
|
||||
{
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"npmClient": "yarn",
|
||||
"useWorkspaces": true,
|
||||
"npmClientArgs": [
|
||||
|
@ -1,9 +1,9 @@
|
||||
{
|
||||
"name": "@nocobase/app-client",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"license": "MIT",
|
||||
"devDependencies": {
|
||||
"@nocobase/client": "0.7.4-alpha.7"
|
||||
"@nocobase/client": "0.8.0-alpha.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@nocobase/app-server",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"description": "",
|
||||
"license": "MIT",
|
||||
"main": "./lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
"dependencies": {
|
||||
"@nocobase/preset-nocobase": "0.7.4-alpha.7"
|
||||
"@nocobase/preset-nocobase": "0.8.0-alpha.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -1,3 +1,3 @@
|
||||
import { PluginConfiguration } from '@nocobase/server';
|
||||
|
||||
export default ['@nocobase/preset-nocobase'] as PluginConfiguration[];
|
||||
export default ['nocobase'] as PluginConfiguration[];
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/acl",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"description": "",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -12,7 +12,7 @@
|
||||
"main": "./lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
"dependencies": {
|
||||
"@nocobase/resourcer": "0.7.4-alpha.7",
|
||||
"@nocobase/resourcer": "0.8.0-alpha.1",
|
||||
"json-templates": "^4.2.0"
|
||||
},
|
||||
"repository": {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/actions",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"description": "",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -12,9 +12,9 @@
|
||||
"main": "./lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
"dependencies": {
|
||||
"@nocobase/database": "0.7.4-alpha.7",
|
||||
"@nocobase/resourcer": "0.7.4-alpha.7",
|
||||
"@nocobase/cache": "0.7.4-alpha.7"
|
||||
"@nocobase/cache": "0.8.0-alpha.1",
|
||||
"@nocobase/database": "0.8.0-alpha.1",
|
||||
"@nocobase/resourcer": "0.8.0-alpha.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/build",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"description": "Library build tool based on rollup.",
|
||||
"main": "lib/index.js",
|
||||
"bin": {
|
||||
|
2
packages/core/cache/package.json
vendored
2
packages/core/cache/package.json
vendored
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/cache",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"description": "",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/cli",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"description": "",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -23,7 +23,7 @@
|
||||
"serve": "^13.0.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nocobase/devtools": "0.7.4-alpha.7"
|
||||
"@nocobase/devtools": "0.8.0-alpha.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -1,9 +1,6 @@
|
||||
import { InstallOptions, Plugin } from '@nocobase/server';
|
||||
|
||||
export class {{{pascalCaseName}}}Plugin extends Plugin {
|
||||
getName(): string {
|
||||
return this.getPackageName(__dirname);
|
||||
}
|
||||
|
||||
beforeLoad() {
|
||||
// TODO
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/client",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
{
|
||||
@ -19,8 +19,8 @@
|
||||
"@formily/antd": "2.0.20",
|
||||
"@formily/core": "2.0.20",
|
||||
"@formily/react": "2.0.20",
|
||||
"@nocobase/sdk": "0.7.4-alpha.7",
|
||||
"@nocobase/utils": "0.7.4-alpha.7",
|
||||
"@nocobase/sdk": "0.8.0-alpha.1",
|
||||
"@nocobase/utils": "0.8.0-alpha.1",
|
||||
"ahooks": "^3.0.5",
|
||||
"antd": "~4.19.5",
|
||||
"axios": "^0.26.1",
|
||||
|
@ -4,7 +4,11 @@ import { notification } from 'antd';
|
||||
import React from 'react';
|
||||
|
||||
export class APIClient extends APIClientSDK {
|
||||
services: Record<string, Result<any, any>>;
|
||||
services: Record<string, Result<any, any>> = {};
|
||||
|
||||
service(uid: string) {
|
||||
return this.services[uid];
|
||||
}
|
||||
|
||||
interceptors() {
|
||||
super.interceptors();
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Field } from '@formily/core';
|
||||
import { useField } from '@formily/react';
|
||||
import { useField, useFieldSchema } from '@formily/react';
|
||||
import { useRequest } from 'ahooks';
|
||||
import template from 'lodash/template';
|
||||
import React, { createContext, useContext } from 'react';
|
||||
@ -10,7 +10,7 @@ import { useRecordIndex } from '../record-provider';
|
||||
|
||||
export const BlockResourceContext = createContext(null);
|
||||
export const BlockAssociationContext = createContext(null);
|
||||
const BlockRequestContext = createContext(null);
|
||||
const BlockRequestContext = createContext<any>(null);
|
||||
|
||||
export const useBlockResource = () => {
|
||||
return useContext(BlockResourceContext);
|
||||
@ -80,6 +80,8 @@ export const useResourceAction = (props, opts = {}) => {
|
||||
const { fields } = useCollection();
|
||||
const appends = fields?.filter((field) => field.target).map((field) => field.name);
|
||||
const params = useActionParams(props);
|
||||
const api = useAPIClient();
|
||||
const fieldSchema = useFieldSchema();
|
||||
if (!Object.keys(params).includes('appends') && appends?.length) {
|
||||
params['appends'] = appends;
|
||||
}
|
||||
@ -96,6 +98,12 @@ export const useResourceAction = (props, opts = {}) => {
|
||||
},
|
||||
{
|
||||
...opts,
|
||||
onSuccess(data, params) {
|
||||
opts?.['onSuccess']?.(data, params);
|
||||
if (fieldSchema['x-uid']) {
|
||||
api.services[fieldSchema['x-uid']] = result;
|
||||
}
|
||||
},
|
||||
defaultParams: [params],
|
||||
refreshDeps: [JSON.stringify(params.appends)],
|
||||
},
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "create-nocobase-app",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "src/index.js",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/database",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"description": "",
|
||||
"main": "./lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
@ -12,7 +12,7 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@nocobase/utils": "0.7.4-alpha.7",
|
||||
"@nocobase/utils": "0.8.0-alpha.1",
|
||||
"async-mutex": "^0.3.2",
|
||||
"cron-parser": "4.4.0",
|
||||
"deepmerge": "^4.2.2",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/devtools",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"description": "",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -11,7 +11,7 @@
|
||||
],
|
||||
"main": "./src/index.js",
|
||||
"dependencies": {
|
||||
"@nocobase/build": "0.7.4-alpha.7",
|
||||
"@nocobase/build": "0.8.0-alpha.1",
|
||||
"@testing-library/react": "^12.1.2",
|
||||
"@types/jest": "^26.0.0",
|
||||
"@types/koa": "^2.13.4",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "dumi-theme-nocobase",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"private": true,
|
||||
"files": [
|
||||
"es",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/resourcer",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"description": "",
|
||||
"main": "./lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
@ -12,7 +12,7 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@nocobase/utils": "0.7.4-alpha.7",
|
||||
"@nocobase/utils": "0.8.0-alpha.1",
|
||||
"deepmerge": "^4.2.2",
|
||||
"koa-compose": "^4.1.0",
|
||||
"lodash": "^4.17.21",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/sdk",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
{
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/server",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
"license": "Apache-2.0",
|
||||
@ -14,10 +14,10 @@
|
||||
"@hapi/topo": "^6.0.0",
|
||||
"@koa/cors": "^3.1.0",
|
||||
"@koa/router": "^9.4.0",
|
||||
"@nocobase/acl": "0.7.4-alpha.7",
|
||||
"@nocobase/actions": "0.7.4-alpha.7",
|
||||
"@nocobase/database": "0.7.4-alpha.7",
|
||||
"@nocobase/resourcer": "0.7.4-alpha.7",
|
||||
"@nocobase/acl": "0.8.0-alpha.1",
|
||||
"@nocobase/actions": "0.8.0-alpha.1",
|
||||
"@nocobase/database": "0.8.0-alpha.1",
|
||||
"@nocobase/resourcer": "0.8.0-alpha.1",
|
||||
"chalk": "^4.1.1",
|
||||
"commander": "^9.2.0",
|
||||
"find-package-json": "^1.2.0",
|
||||
|
@ -38,6 +38,7 @@ export interface ApplicationOptions {
|
||||
i18n?: i18n | InitOptions;
|
||||
plugins?: PluginConfiguration[];
|
||||
acl?: boolean;
|
||||
pmSock?: string;
|
||||
}
|
||||
|
||||
export interface DefaultState extends KoaDefaultState {
|
||||
@ -259,20 +260,17 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
return packageJson.version;
|
||||
}
|
||||
|
||||
plugin<O = any>(pluginClass: any, options?: O): Plugin<O> {
|
||||
return this.pm.add(pluginClass, options);
|
||||
plugin<O = any>(pluginClass: any, options?: O): Plugin {
|
||||
return this.pm.addStatic(pluginClass, options);
|
||||
}
|
||||
|
||||
loadPluginConfig(pluginsConfigurations: PluginConfiguration[]) {
|
||||
for (let pluginConfiguration of pluginsConfigurations) {
|
||||
if (typeof pluginConfiguration == 'string') {
|
||||
pluginConfiguration = [pluginConfiguration, {}];
|
||||
this.plugin(pluginConfiguration);
|
||||
} else {
|
||||
this.plugin(...pluginConfiguration);
|
||||
}
|
||||
|
||||
const plugin = PluginManager.resolvePlugin(pluginConfiguration[0]);
|
||||
const pluginOptions = pluginConfiguration[1];
|
||||
|
||||
this.plugin(plugin, pluginOptions);
|
||||
}
|
||||
}
|
||||
|
||||
@ -319,13 +317,20 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
return (<any>this.cli)._findCommand(name);
|
||||
}
|
||||
|
||||
async load() {
|
||||
await this.pm.load();
|
||||
async load(options?: any) {
|
||||
if (options?.reload) {
|
||||
this.init();
|
||||
}
|
||||
await this.emitAsync('beforeLoad', this, options);
|
||||
await this.pm.load(options);
|
||||
await this.emitAsync('afterLoad', this, options);
|
||||
}
|
||||
|
||||
async reload() {
|
||||
this.init();
|
||||
await this.pm.load();
|
||||
async reload(options?: any) {
|
||||
await this.load({
|
||||
...options,
|
||||
reload: true,
|
||||
});
|
||||
}
|
||||
|
||||
getPlugin<P extends Plugin>(name: string) {
|
||||
@ -337,9 +342,9 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
}
|
||||
|
||||
async runAsCLI(argv = process.argv, options?: ParseOptions) {
|
||||
if (argv?.[2] !== 'install') {
|
||||
await this.load();
|
||||
}
|
||||
await this.load({
|
||||
method: argv?.[2],
|
||||
});
|
||||
return this.cli.parseAsync(argv, options);
|
||||
}
|
||||
|
||||
@ -352,6 +357,7 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
await this.emitAsync('beforeStart', this, options);
|
||||
|
||||
if (options?.listen?.port) {
|
||||
const pmServer = await this.pm.listen();
|
||||
const listen = () =>
|
||||
new Promise((resolve, reject) => {
|
||||
const Server = this.listen(options?.listen, () => {
|
||||
@ -361,6 +367,10 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
Server.on('error', (err) => {
|
||||
reject(err);
|
||||
});
|
||||
|
||||
Server.on('close', () => {
|
||||
pmServer.close();
|
||||
});
|
||||
});
|
||||
|
||||
try {
|
||||
@ -385,7 +395,9 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
try {
|
||||
// close database connection
|
||||
// silent if database already closed
|
||||
await this.db.close();
|
||||
if (!this.db.closed()) {
|
||||
await this.db.close();
|
||||
}
|
||||
} catch (e) {
|
||||
console.log(e);
|
||||
}
|
||||
@ -419,11 +431,11 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
|
||||
if (options?.clean) {
|
||||
await this.db.clean(isBoolean(options.clean) ? { drop: options.clean } : options.clean);
|
||||
await this.reload({ method: 'install' });
|
||||
}
|
||||
|
||||
await this.emitAsync('beforeInstall', this, options);
|
||||
|
||||
await this.load();
|
||||
await this.db.sync(options?.sync);
|
||||
await this.pm.install(options);
|
||||
await this.version.update();
|
||||
|
@ -1,5 +1,3 @@
|
||||
import axios from 'axios';
|
||||
import { resolve } from 'path';
|
||||
import Application from '../application';
|
||||
|
||||
export default (app: Application) => {
|
||||
@ -8,101 +6,6 @@ export default (app: Application) => {
|
||||
.argument('<method>')
|
||||
.arguments('<plugins...>')
|
||||
.action(async (method, plugins, options, ...args) => {
|
||||
const { APP_PORT, API_BASE_PATH = '/api/', API_BASE_URL } = process.env;
|
||||
const baseURL = API_BASE_URL || `http://localhost:${APP_PORT}${API_BASE_PATH}`;
|
||||
let started = true;
|
||||
try {
|
||||
await axios.get(`${baseURL}app:getLang`);
|
||||
} catch (error) {
|
||||
started = false;
|
||||
}
|
||||
const pm = {
|
||||
async create() {
|
||||
const name = plugins[0];
|
||||
const { run } = require('@nocobase/cli/src/util');
|
||||
const { PluginGenerator } = require('@nocobase/cli/src/plugin-generator');
|
||||
const generator = new PluginGenerator({
|
||||
cwd: resolve(process.cwd(), name),
|
||||
args: options,
|
||||
context: {
|
||||
name,
|
||||
},
|
||||
});
|
||||
await generator.run();
|
||||
await run('yarn', ['install']);
|
||||
},
|
||||
async add() {
|
||||
try {
|
||||
if (started) {
|
||||
const res = await axios.get(`${baseURL}pm:add/${plugins.join(',')}`);
|
||||
} else {
|
||||
await app.pm.add(plugins);
|
||||
}
|
||||
} catch (error) {}
|
||||
const fs = require('fs/promises');
|
||||
await Promise.all(
|
||||
plugins.map((plugin) => {
|
||||
const file = resolve(
|
||||
process.cwd(),
|
||||
'packages',
|
||||
process.env.APP_PACKAGE_ROOT || 'app',
|
||||
'client/src/plugins',
|
||||
`${plugin}.ts`,
|
||||
);
|
||||
console.log(file);
|
||||
return fs.writeFile(file, `export { default } from '@nocobase/plugin-${plugin}/client';`);
|
||||
}),
|
||||
);
|
||||
const { run } = require('@nocobase/cli/src/util');
|
||||
await run('yarn', ['nocobase', 'postinstall']);
|
||||
},
|
||||
async enable() {
|
||||
if (started) {
|
||||
const res = await axios.get(`${baseURL}pm:enable/${plugins.join(',')}`);
|
||||
console.log(res.data);
|
||||
return;
|
||||
}
|
||||
const repository = app.db.getRepository('applicationPlugins');
|
||||
await repository.update({
|
||||
filter: {
|
||||
'name.$in': plugins,
|
||||
},
|
||||
values: {
|
||||
enabled: true,
|
||||
},
|
||||
});
|
||||
},
|
||||
async disable() {
|
||||
if (started) {
|
||||
const res = await axios.get(`${baseURL}pm:disable/${plugins.join(',')}`);
|
||||
console.log(res.data);
|
||||
return;
|
||||
}
|
||||
const repository = app.db.getRepository('applicationPlugins');
|
||||
await repository.update({
|
||||
filter: {
|
||||
'name.$in': plugins,
|
||||
},
|
||||
values: {
|
||||
enabled: false,
|
||||
},
|
||||
});
|
||||
},
|
||||
async remove() {
|
||||
if (started) {
|
||||
const res = await axios.get(`${baseURL}pm:disable/${plugins.join(',')}`);
|
||||
console.log(res.data);
|
||||
return;
|
||||
}
|
||||
const repository = app.db.getRepository('applicationPlugins');
|
||||
await repository.destroy({
|
||||
filter: {
|
||||
'name.$in': plugins,
|
||||
},
|
||||
});
|
||||
plugins.map((name) => app.pm.remove(name));
|
||||
},
|
||||
};
|
||||
await pm[method]();
|
||||
app.pm.clientWrite({ method, plugins });
|
||||
});
|
||||
};
|
||||
|
@ -1,289 +0,0 @@
|
||||
import { CleanOptions, Collection, Model, Repository, SyncOptions } from '@nocobase/database';
|
||||
import Application from './application';
|
||||
import { Plugin } from './plugin';
|
||||
|
||||
interface PluginManagerOptions {
|
||||
app: Application;
|
||||
}
|
||||
|
||||
export interface InstallOptions {
|
||||
cliArgs?: any[];
|
||||
clean?: CleanOptions | boolean;
|
||||
sync?: SyncOptions;
|
||||
}
|
||||
|
||||
class PluginManagerRepository extends Repository {
|
||||
getInstance(): Plugin {
|
||||
return;
|
||||
}
|
||||
async add(name: string | string[], options) {}
|
||||
async enable(name: string | string[], options) {}
|
||||
async disable(name: string | string[], options) {}
|
||||
async remove(name: string | string[], options) {}
|
||||
async upgrade(name: string | string[], options) {}
|
||||
}
|
||||
|
||||
export class PluginManager {
|
||||
app: Application;
|
||||
collection: Collection;
|
||||
repository: PluginManagerRepository;
|
||||
plugins = new Map<string, Plugin>();
|
||||
|
||||
constructor(options: PluginManagerOptions) {
|
||||
this.app = options.app;
|
||||
this.collection = this.app.db.collection({
|
||||
name: 'applicationPlugins',
|
||||
fields: [
|
||||
{ type: 'string', name: 'name', unique: true },
|
||||
{ type: 'string', name: 'version' },
|
||||
{ type: 'boolean', name: 'enabled' },
|
||||
{ type: 'boolean', name: 'installed' },
|
||||
{ type: 'boolean', name: 'builtIn' },
|
||||
{ type: 'json', name: 'options' },
|
||||
],
|
||||
});
|
||||
const app = this.app;
|
||||
const pm = this;
|
||||
this.repository = this.collection.repository as PluginManagerRepository;
|
||||
this.app.resourcer.define({
|
||||
name: 'pm',
|
||||
actions: {
|
||||
async add(ctx, next) {
|
||||
const { filterByTk } = ctx.action.params;
|
||||
if (!filterByTk) {
|
||||
ctx.throw(400, 'null');
|
||||
}
|
||||
await pm.add(filterByTk);
|
||||
ctx.body = filterByTk;
|
||||
await next();
|
||||
},
|
||||
async enable(ctx, next) {
|
||||
const { filterByTk } = ctx.action.params;
|
||||
if (!filterByTk) {
|
||||
ctx.throw(400, 'filterByTk invalid');
|
||||
}
|
||||
const name = pm.getPackageName(filterByTk);
|
||||
const plugin = pm.get(name);
|
||||
if (plugin.model) {
|
||||
plugin.model.set('enabled', true);
|
||||
await plugin.model.save();
|
||||
}
|
||||
if (!plugin) {
|
||||
ctx.throw(400, 'plugin invalid');
|
||||
}
|
||||
await app.reload();
|
||||
if (plugin.model && !plugin.model.get('installed')) {
|
||||
await app.db.sync();
|
||||
await plugin.install();
|
||||
plugin.model.set('installed', true);
|
||||
await plugin.model.save();
|
||||
}
|
||||
await app.start();
|
||||
ctx.body = 'ok';
|
||||
await next();
|
||||
},
|
||||
async disable(ctx, next) {
|
||||
const { filterByTk } = ctx.action.params;
|
||||
if (!filterByTk) {
|
||||
ctx.throw(400, 'filterByTk invalid');
|
||||
}
|
||||
const name = pm.getPackageName(filterByTk);
|
||||
const plugin = pm.get(name);
|
||||
if (plugin.model) {
|
||||
plugin.model.set('enabled', false);
|
||||
await plugin.model.save();
|
||||
}
|
||||
if (!plugin) {
|
||||
ctx.throw(400, 'plugin invalid');
|
||||
}
|
||||
await app.reload();
|
||||
await app.start();
|
||||
ctx.body = 'ok';
|
||||
await next();
|
||||
},
|
||||
async upgrade(ctx, next) {
|
||||
ctx.body = 'ok';
|
||||
await next();
|
||||
},
|
||||
async remove(ctx, next) {
|
||||
const { filterByTk } = ctx.action.params;
|
||||
if (!filterByTk) {
|
||||
ctx.throw(400, 'filterByTk invalid');
|
||||
}
|
||||
const name = pm.getPackageName(filterByTk);
|
||||
console.log(name, pm.plugins.keys());
|
||||
const plugin = pm.get(name);
|
||||
if (plugin?.model) {
|
||||
await plugin.model.destroy();
|
||||
pm.remove(name);
|
||||
} else {
|
||||
await pm.repository.destroy({
|
||||
filter: {
|
||||
name: filterByTk,
|
||||
},
|
||||
});
|
||||
}
|
||||
await app.reload();
|
||||
await app.start();
|
||||
ctx.body = 'ok';
|
||||
await next();
|
||||
},
|
||||
},
|
||||
});
|
||||
this.app.acl.use(async (ctx, next) => {
|
||||
if (ctx.action.resourceName === 'pm') {
|
||||
ctx.permission = {
|
||||
skip: true,
|
||||
};
|
||||
}
|
||||
await next();
|
||||
});
|
||||
this.app.on('beforeInstall', async () => {
|
||||
await this.collection.sync();
|
||||
});
|
||||
this.app.on('beforeLoadAll', async (options) => {
|
||||
await this.collection.sync();
|
||||
const exists = await this.app.db.collectionExistsInDb('applicationPlugins');
|
||||
if (!exists) {
|
||||
return;
|
||||
}
|
||||
const items = await this.repository.find();
|
||||
for (const item of items) {
|
||||
await this.add(item);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getPackageName(name: string) {
|
||||
if (name.includes('@nocobase/plugin-')) {
|
||||
return name;
|
||||
}
|
||||
if (name.includes('/')) {
|
||||
return `@${name}`;
|
||||
}
|
||||
return `@nocobase/plugin-${name}`;
|
||||
}
|
||||
|
||||
private addByModel(model) {
|
||||
try {
|
||||
const packageName = this.getPackageName(model.get('name'));
|
||||
require.resolve(packageName);
|
||||
const cls = require(packageName).default;
|
||||
const instance = new cls(this.app, {
|
||||
...model.get('options'),
|
||||
name: model.get('name'),
|
||||
version: model.get('version'),
|
||||
enabled: model.get('enabled'),
|
||||
});
|
||||
instance.setModel(model);
|
||||
this.plugins.set(packageName, instance);
|
||||
return instance;
|
||||
} catch (error) {}
|
||||
}
|
||||
|
||||
getPlugins() {
|
||||
return this.plugins;
|
||||
}
|
||||
|
||||
get(name: string) {
|
||||
return this.plugins.get(name);
|
||||
}
|
||||
|
||||
remove(name: string) {
|
||||
return this.plugins.delete(name);
|
||||
}
|
||||
|
||||
add<P = Plugin, O = any>(pluginClass: any, options?: O) {
|
||||
if (Array.isArray(pluginClass)) {
|
||||
const addMultiple = async () => {
|
||||
for (const plugin of pluginClass) {
|
||||
await this.add(plugin);
|
||||
}
|
||||
};
|
||||
return addMultiple();
|
||||
}
|
||||
if (typeof pluginClass === 'string') {
|
||||
const packageName = this.getPackageName(pluginClass);
|
||||
try {
|
||||
require.resolve(packageName);
|
||||
} catch (error) {
|
||||
throw new Error(`${pluginClass} plugin does not exist`);
|
||||
}
|
||||
const packageJson = require(`${packageName}/package.json`);
|
||||
const addNew = async () => {
|
||||
let model = await this.repository.findOne({
|
||||
filter: { name: pluginClass },
|
||||
});
|
||||
if (model) {
|
||||
throw new Error(`${pluginClass} plugin already exists`);
|
||||
}
|
||||
model = await this.repository.create({
|
||||
values: {
|
||||
name: pluginClass,
|
||||
version: packageJson.version,
|
||||
enabled: false,
|
||||
options: {},
|
||||
},
|
||||
});
|
||||
return this.addByModel(model);
|
||||
};
|
||||
return addNew();
|
||||
}
|
||||
|
||||
if (pluginClass instanceof Model) {
|
||||
return this.addByModel(pluginClass);
|
||||
}
|
||||
|
||||
const instance = new pluginClass(this.app, {
|
||||
...options,
|
||||
enabled: true,
|
||||
});
|
||||
|
||||
const name = instance.getName();
|
||||
|
||||
if (this.plugins.has(name)) {
|
||||
throw new Error(`plugin name [${name}] exists`);
|
||||
}
|
||||
|
||||
this.plugins.set(name, instance);
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
||||
async load() {
|
||||
await this.app.emitAsync('beforeLoadAll');
|
||||
|
||||
for (const [name, plugin] of this.plugins) {
|
||||
if (!plugin.enabled) {
|
||||
continue;
|
||||
}
|
||||
await plugin.beforeLoad();
|
||||
}
|
||||
|
||||
for (const [name, plugin] of this.plugins) {
|
||||
if (!plugin.enabled) {
|
||||
continue;
|
||||
}
|
||||
await this.app.emitAsync('beforeLoadPlugin', plugin);
|
||||
await plugin.load();
|
||||
await this.app.emitAsync('afterLoadPlugin', plugin);
|
||||
}
|
||||
|
||||
await this.app.emitAsync('afterLoadAll');
|
||||
}
|
||||
|
||||
async install(options: InstallOptions = {}) {
|
||||
for (const [name, plugin] of this.plugins) {
|
||||
if (!plugin.enabled) {
|
||||
continue;
|
||||
}
|
||||
await this.app.emitAsync('beforeInstallPlugin', plugin, options);
|
||||
await plugin.install(options);
|
||||
await this.app.emitAsync('afterInstallPlugin', plugin, options);
|
||||
}
|
||||
}
|
||||
|
||||
static resolvePlugin(pluginName: string) {
|
||||
return require(pluginName).default;
|
||||
}
|
||||
}
|
310
packages/core/server/src/plugin-manager/PluginManager.ts
Normal file
310
packages/core/server/src/plugin-manager/PluginManager.ts
Normal file
@ -0,0 +1,310 @@
|
||||
import { CleanOptions, Collection, SyncOptions } from '@nocobase/database';
|
||||
import { requireModule } from '@nocobase/utils';
|
||||
import execa from 'execa';
|
||||
import fs from 'fs';
|
||||
import net from 'net';
|
||||
import { resolve } from 'path';
|
||||
import Application from '../application';
|
||||
import { Plugin } from '../plugin';
|
||||
import collectionOptions from './options/collection';
|
||||
import resourceOptions from './options/resource';
|
||||
import { PluginManagerRepository } from './PluginManagerRepository';
|
||||
|
||||
export interface PluginManagerOptions {
|
||||
app: Application;
|
||||
}
|
||||
|
||||
export interface InstallOptions {
|
||||
cliArgs?: any[];
|
||||
clean?: CleanOptions | boolean;
|
||||
sync?: SyncOptions;
|
||||
}
|
||||
|
||||
export class PluginManager {
|
||||
app: Application;
|
||||
collection: Collection;
|
||||
repository: PluginManagerRepository;
|
||||
plugins = new Map<string, Plugin>();
|
||||
server: net.Server;
|
||||
pmSock: string;
|
||||
|
||||
constructor(options: PluginManagerOptions) {
|
||||
this.app = options.app;
|
||||
const f = resolve(process.cwd(), 'storage', 'pm.sock');
|
||||
this.pmSock = this.app.options.pmSock || f;
|
||||
this.app.db.registerRepositories({
|
||||
PluginManagerRepository,
|
||||
});
|
||||
this.collection = this.app.db.collection(collectionOptions);
|
||||
this.repository = this.collection.repository as PluginManagerRepository;
|
||||
this.repository.setPluginManager(this);
|
||||
this.app.resourcer.define(resourceOptions);
|
||||
this.app.acl.use(async (ctx, next) => {
|
||||
if (ctx.action.resourceName === 'pm') {
|
||||
ctx.permission = {
|
||||
skip: true,
|
||||
};
|
||||
}
|
||||
await next();
|
||||
});
|
||||
this.server = net.createServer((socket) => {
|
||||
socket.on('data', async (data) => {
|
||||
const { method, plugins } = JSON.parse(data.toString());
|
||||
try {
|
||||
console.log(method, plugins);
|
||||
await this[method](plugins);
|
||||
} catch (error) {
|
||||
console.error(error.message);
|
||||
}
|
||||
});
|
||||
socket.pipe(socket);
|
||||
});
|
||||
this.app.on('beforeLoad', async (app, options) => {
|
||||
if (options?.method && ['install', 'upgrade'].includes(options.method)) {
|
||||
await this.collection.sync();
|
||||
}
|
||||
const exists = await this.app.db.collectionExistsInDb('applicationPlugins');
|
||||
if (!exists) {
|
||||
return;
|
||||
}
|
||||
if (options?.method !== 'install' || options.reload) {
|
||||
await this.repository.load();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
getPlugins() {
|
||||
return this.plugins;
|
||||
}
|
||||
|
||||
get(name: string) {
|
||||
return this.plugins.get(name);
|
||||
}
|
||||
|
||||
clientWrite(data: any) {
|
||||
const { method, plugins } = data;
|
||||
const client = new net.Socket();
|
||||
client.connect(this.pmSock, () => {
|
||||
client.write(JSON.stringify(data));
|
||||
});
|
||||
client.on('error', async () => {
|
||||
try {
|
||||
console.log(method, plugins);
|
||||
await this[method](plugins);
|
||||
} catch (error) {
|
||||
console.error(error.message);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
async listen(): Promise<net.Server> {
|
||||
if (fs.existsSync(this.pmSock)) {
|
||||
await fs.promises.unlink(this.pmSock);
|
||||
}
|
||||
return new Promise((resolve) => {
|
||||
this.server.listen(this.pmSock, () => {
|
||||
resolve(this.server);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
async create(name: string) {
|
||||
const { run } = require('@nocobase/cli/src/util');
|
||||
const { PluginGenerator } = require('@nocobase/cli/src/plugin-generator');
|
||||
const generator = new PluginGenerator({
|
||||
cwd: resolve(process.cwd(), name),
|
||||
args: {},
|
||||
context: {
|
||||
name,
|
||||
},
|
||||
});
|
||||
await generator.run();
|
||||
await run('yarn', ['install']);
|
||||
}
|
||||
|
||||
addStatic(plugin?: any, options?: any) {
|
||||
let name: string;
|
||||
if (typeof plugin === 'string') {
|
||||
name = plugin;
|
||||
plugin = PluginManager.resolvePlugin(plugin);
|
||||
} else {
|
||||
name = plugin.name;
|
||||
if (!name) {
|
||||
throw new Error(`plugin name invalid`);
|
||||
}
|
||||
}
|
||||
const instance = new plugin(this.app, {
|
||||
name,
|
||||
enabled: true,
|
||||
...options,
|
||||
});
|
||||
const pluginName = instance.getName();
|
||||
if (this.plugins.has(pluginName)) {
|
||||
throw new Error(`plugin name [${pluginName}] exists`);
|
||||
}
|
||||
this.plugins.set(pluginName, instance);
|
||||
return instance;
|
||||
}
|
||||
|
||||
async add(plugin: any, options: any = {}) {
|
||||
if (Array.isArray(plugin)) {
|
||||
return Promise.all(plugin.map((p) => this.add(p, options)));
|
||||
}
|
||||
// console.log(`adding ${plugin} plugin`);
|
||||
const packageName = await PluginManager.findPackage(plugin);
|
||||
const packageJson = require(`${packageName}/package.json`);
|
||||
const instance = this.addStatic(plugin, options);
|
||||
let model = await this.repository.findOne({
|
||||
filter: { name: plugin },
|
||||
});
|
||||
if (model) {
|
||||
throw new Error(`${plugin} plugin already exists`);
|
||||
}
|
||||
const { enabled, builtIn, installed, ...others } = options;
|
||||
await this.repository.create({
|
||||
values: {
|
||||
name: plugin,
|
||||
version: packageJson.version,
|
||||
enabled: !!enabled,
|
||||
builtIn: !!builtIn,
|
||||
installed: !!installed,
|
||||
options: {
|
||||
...others,
|
||||
},
|
||||
},
|
||||
});
|
||||
const file = resolve(
|
||||
process.cwd(),
|
||||
'packages',
|
||||
process.env.APP_PACKAGE_ROOT || 'app',
|
||||
'client/src/plugins',
|
||||
`${plugin}.ts`,
|
||||
);
|
||||
if (!fs.existsSync(file)) {
|
||||
try {
|
||||
require.resolve(`${packageName}/client`);
|
||||
await fs.promises.writeFile(file, `export { default } from '${packageName}/client';`);
|
||||
const { run } = require('@nocobase/cli/src/util');
|
||||
await run('yarn', ['nocobase', 'postinstall']);
|
||||
} catch (error) {}
|
||||
}
|
||||
return instance;
|
||||
}
|
||||
|
||||
async load(options: any = {}) {
|
||||
for (const [name, plugin] of this.plugins) {
|
||||
if (!plugin.enabled) {
|
||||
continue;
|
||||
}
|
||||
await plugin.beforeLoad();
|
||||
}
|
||||
|
||||
for (const [name, plugin] of this.plugins) {
|
||||
if (!plugin.enabled) {
|
||||
continue;
|
||||
}
|
||||
await this.app.emitAsync('beforeLoadPlugin', plugin, options);
|
||||
await plugin.load();
|
||||
await this.app.emitAsync('afterLoadPlugin', plugin, options);
|
||||
}
|
||||
}
|
||||
|
||||
async install(options: InstallOptions = {}) {
|
||||
for (const [name, plugin] of this.plugins) {
|
||||
if (!plugin.enabled) {
|
||||
continue;
|
||||
}
|
||||
await this.app.emitAsync('beforeInstallPlugin', plugin, options);
|
||||
await plugin.install(options);
|
||||
await this.app.emitAsync('afterInstallPlugin', plugin, options);
|
||||
}
|
||||
}
|
||||
|
||||
async enable(name: string | string[]) {
|
||||
try {
|
||||
const pluginNames = await this.repository.enable(name);
|
||||
await this.app.reload();
|
||||
await this.app.db.sync();
|
||||
for (const pluginName of pluginNames) {
|
||||
const plugin = this.app.getPlugin(pluginName);
|
||||
if (!plugin) {
|
||||
throw new Error(`${name} plugin does not exist`);
|
||||
}
|
||||
await plugin.install();
|
||||
await plugin.afterEnable();
|
||||
}
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async disable(name: string | string[]) {
|
||||
try {
|
||||
const pluginNames = await this.repository.disable(name);
|
||||
await this.app.reload();
|
||||
for (const pluginName of pluginNames) {
|
||||
const plugin = this.app.getPlugin(pluginName);
|
||||
if (!plugin) {
|
||||
throw new Error(`${name} plugin does not exist`);
|
||||
}
|
||||
await plugin.afterDisable();
|
||||
}
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async remove(name: string | string[]) {
|
||||
const pluginNames = typeof name === 'string' ? [name] : name;
|
||||
for (const pluginName of pluginNames) {
|
||||
const plugin = this.app.getPlugin(pluginName);
|
||||
if (!plugin) {
|
||||
throw new Error(`${name} plugin does not exist`);
|
||||
}
|
||||
await plugin.remove();
|
||||
}
|
||||
await this.repository.remove(name);
|
||||
this.app.reload();
|
||||
}
|
||||
|
||||
static getPackageName(name: string) {
|
||||
const prefixes = (process.env.PLUGIN_PACKAGE_PREFIX || '@nocobase/plugin-,@nocobase/preset-').split(',');
|
||||
for (const prefix of prefixes) {
|
||||
try {
|
||||
require.resolve(`${prefix}${name}`);
|
||||
return `${prefix}${name}`;
|
||||
} catch (error) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
throw new Error(`${name} plugin does not exist`);
|
||||
}
|
||||
|
||||
static async findPackage(name: string) {
|
||||
try {
|
||||
const packageName = this.getPackageName(name);
|
||||
return packageName;
|
||||
} catch (error) {
|
||||
const prefixes = (process.env.PLUGIN_PACKAGE_PREFIX || '@nocobase/plugin-,@nocobase/preset-').split(',');
|
||||
for (const prefix of prefixes) {
|
||||
try {
|
||||
const packageName = `${prefix}${name}`;
|
||||
await execa('npm', ['v', packageName, 'versions']);
|
||||
console.log(`${packageName} is downloading...`);
|
||||
await execa('yarn', ['add', packageName, '-W']);
|
||||
return packageName;
|
||||
} catch (error) {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
throw new Error(`${name} plugin does not exist`);
|
||||
}
|
||||
|
||||
static resolvePlugin(pluginName: string) {
|
||||
const packageName = this.getPackageName(pluginName);
|
||||
return requireModule(packageName);
|
||||
}
|
||||
}
|
||||
|
||||
export default PluginManager;
|
@ -0,0 +1,58 @@
|
||||
import { Repository } from '@nocobase/database';
|
||||
import { PluginManager } from './PluginManager';
|
||||
|
||||
export class PluginManagerRepository extends Repository {
|
||||
pm: PluginManager;
|
||||
|
||||
setPluginManager(pm: PluginManager) {
|
||||
this.pm = pm;
|
||||
}
|
||||
|
||||
async remove(name: string | string[]) {
|
||||
await this.destroy({
|
||||
filter: {
|
||||
name,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
async enable(name: string | string[]) {
|
||||
const pluginNames = typeof name === 'string' ? [name] : name;
|
||||
await this.update({
|
||||
filter: {
|
||||
name,
|
||||
},
|
||||
values: {
|
||||
enabled: true,
|
||||
installed: true,
|
||||
},
|
||||
});
|
||||
return pluginNames;
|
||||
}
|
||||
|
||||
async disable(name: string | string[]) {
|
||||
const pluginNames = typeof name === 'string' ? [name] : name;
|
||||
await this.update({
|
||||
filter: {
|
||||
name,
|
||||
},
|
||||
values: {
|
||||
enabled: false,
|
||||
installed: false,
|
||||
},
|
||||
});
|
||||
return pluginNames;
|
||||
}
|
||||
|
||||
async load() {
|
||||
const items = await this.find();
|
||||
for (const item of items) {
|
||||
await this.pm.addStatic(item.get('name'), {
|
||||
...item.get('options'),
|
||||
name: item.get('name'),
|
||||
version: item.get('version'),
|
||||
enabled: item.get('enabled'),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
2
packages/core/server/src/plugin-manager/index.ts
Normal file
2
packages/core/server/src/plugin-manager/index.ts
Normal file
@ -0,0 +1,2 @@
|
||||
export * from './PluginManager';
|
||||
|
@ -0,0 +1,12 @@
|
||||
export default {
|
||||
name: 'applicationPlugins',
|
||||
repository: 'PluginManagerRepository',
|
||||
fields: [
|
||||
{ type: 'string', name: 'name', unique: true },
|
||||
{ type: 'string', name: 'version' },
|
||||
{ type: 'boolean', name: 'enabled' },
|
||||
{ type: 'boolean', name: 'installed' },
|
||||
{ type: 'boolean', name: 'builtIn' },
|
||||
{ type: 'json', name: 'options' },
|
||||
],
|
||||
};
|
49
packages/core/server/src/plugin-manager/options/resource.ts
Normal file
49
packages/core/server/src/plugin-manager/options/resource.ts
Normal file
@ -0,0 +1,49 @@
|
||||
export default {
|
||||
name: 'pm',
|
||||
actions: {
|
||||
async add(ctx, next) {
|
||||
const pm = ctx.app.pm;
|
||||
const { filterByTk } = ctx.action.params;
|
||||
if (!filterByTk) {
|
||||
ctx.throw(400, 'plugin name invalid');
|
||||
}
|
||||
await pm.add(filterByTk);
|
||||
ctx.body = filterByTk;
|
||||
await next();
|
||||
},
|
||||
async enable(ctx, next) {
|
||||
const pm = ctx.app.pm;
|
||||
const { filterByTk } = ctx.action.params;
|
||||
if (!filterByTk) {
|
||||
ctx.throw(400, 'plugin name invalid');
|
||||
}
|
||||
await pm.enable(filterByTk);
|
||||
ctx.body = filterByTk;
|
||||
await next();
|
||||
},
|
||||
async disable(ctx, next) {
|
||||
const pm = ctx.app.pm;
|
||||
const { filterByTk } = ctx.action.params;
|
||||
if (!filterByTk) {
|
||||
ctx.throw(400, 'plugin name invalid');
|
||||
}
|
||||
await pm.disable(filterByTk);
|
||||
ctx.body = filterByTk;
|
||||
await next();
|
||||
},
|
||||
async upgrade(ctx, next) {
|
||||
ctx.body = 'ok';
|
||||
await next();
|
||||
},
|
||||
async remove(ctx, next) {
|
||||
const pm = ctx.app.pm;
|
||||
const { filterByTk } = ctx.action.params;
|
||||
if (!filterByTk) {
|
||||
ctx.throw(400, 'plugin name invalid');
|
||||
}
|
||||
await pm.remove(filterByTk);
|
||||
ctx.body = filterByTk;
|
||||
await next();
|
||||
},
|
||||
},
|
||||
};
|
@ -1,9 +1,7 @@
|
||||
import { Database, Model } from '@nocobase/database';
|
||||
import finder from 'find-package-json';
|
||||
import { Database } from '@nocobase/database';
|
||||
import { Application } from './application';
|
||||
import { InstallOptions } from './plugin-manager';
|
||||
|
||||
|
||||
export interface PluginInterface {
|
||||
beforeLoad?: () => void;
|
||||
load();
|
||||
@ -25,60 +23,46 @@ export interface PluginOptions {
|
||||
export type PluginType = typeof Plugin;
|
||||
|
||||
export abstract class Plugin<O = any> implements PluginInterface {
|
||||
options: O;
|
||||
options: any;
|
||||
app: Application;
|
||||
db: Database;
|
||||
model: Model;
|
||||
|
||||
constructor(app: Application, options?: O) {
|
||||
constructor(app: Application, options?: any) {
|
||||
this.app = app;
|
||||
this.db = app.db;
|
||||
this.setOptions(options);
|
||||
this.initialize();
|
||||
}
|
||||
|
||||
setOptions(options: O) {
|
||||
this.options = options || ({} as any);
|
||||
}
|
||||
|
||||
setModel(model) {
|
||||
this.model = model;
|
||||
this.afterAdd();
|
||||
}
|
||||
|
||||
get enabled() {
|
||||
return (this.options as any).enabled;
|
||||
return this.options.enabled;
|
||||
}
|
||||
|
||||
public abstract getName(): string;
|
||||
set enabled(value) {
|
||||
this.options.enabled = value;
|
||||
}
|
||||
|
||||
initialize() {}
|
||||
setOptions(options: any) {
|
||||
this.options = options || {};
|
||||
}
|
||||
|
||||
getName() {
|
||||
return (this.options as any).name;
|
||||
}
|
||||
|
||||
afterAdd() {}
|
||||
|
||||
beforeLoad() {}
|
||||
|
||||
async load() {}
|
||||
|
||||
async install(options?: InstallOptions) {}
|
||||
|
||||
async load() {
|
||||
const collectionPath = this.collectionPath();
|
||||
if (collectionPath) {
|
||||
await this.db.import({
|
||||
directory: collectionPath,
|
||||
});
|
||||
}
|
||||
}
|
||||
async afterEnable() {}
|
||||
|
||||
async disable() {
|
||||
|
||||
}
|
||||
async afterDisable() {}
|
||||
|
||||
collectionPath() {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected getPackageName(dirname: string) {
|
||||
const f = finder(dirname);
|
||||
const packageObj = f.next().value;
|
||||
return packageObj['name'];
|
||||
}
|
||||
async remove() {}
|
||||
}
|
||||
|
||||
export default Plugin;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/test",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
"license": "Apache-2.0",
|
||||
@ -11,7 +11,7 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@nocobase/server": "0.7.4-alpha.7",
|
||||
"@nocobase/server": "0.8.0-alpha.1",
|
||||
"@types/supertest": "^2.0.11",
|
||||
"mockjs": "^1.1.0",
|
||||
"mysql2": "^2.3.3",
|
||||
|
@ -56,6 +56,7 @@ interface Resource {
|
||||
|
||||
export class MockServer extends Application {
|
||||
async loadAndInstall(options: any = {}) {
|
||||
await this.load();
|
||||
await this.install({
|
||||
...options,
|
||||
sync: {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/utils",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
"license": "Apache-2.0",
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/plugin-acl",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"description": "",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -12,10 +12,10 @@
|
||||
"main": "./lib/index.js",
|
||||
"types": "./lib/index.d.ts",
|
||||
"dependencies": {
|
||||
"@nocobase/acl": "0.7.4-alpha.7",
|
||||
"@nocobase/database": "0.7.4-alpha.7",
|
||||
"@nocobase/plugin-users": "0.7.4-alpha.7",
|
||||
"@nocobase/server": "0.7.4-alpha.7"
|
||||
"@nocobase/acl": "0.8.0-alpha.1",
|
||||
"@nocobase/database": "0.8.0-alpha.1",
|
||||
"@nocobase/plugin-users": "0.8.0-alpha.1",
|
||||
"@nocobase/server": "0.8.0-alpha.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -30,7 +30,7 @@ describe('acl', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const userPlugin = app.getPlugin('@nocobase/plugin-users') as UsersPlugin;
|
||||
const userPlugin = app.getPlugin('users') as UsersPlugin;
|
||||
|
||||
adminAgent = app.agent().auth(
|
||||
userPlugin.jwtService.sign({
|
||||
@ -483,7 +483,7 @@ describe('acl', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const userPlugin = app.getPlugin('@nocobase/plugin-users') as UsersPlugin;
|
||||
const userPlugin = app.getPlugin('users') as UsersPlugin;
|
||||
const userAgent = app.agent().auth(
|
||||
userPlugin.jwtService.sign({
|
||||
userId: user.get('id'),
|
||||
|
@ -48,7 +48,7 @@ describe('association field acl', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const userPlugin = app.getPlugin('@nocobase/plugin-users') as UsersPlugin;
|
||||
const userPlugin = app.getPlugin('users') as UsersPlugin;
|
||||
userAgent = app.agent().auth(
|
||||
userPlugin.jwtService.sign({
|
||||
userId: user.get('id'),
|
||||
|
@ -45,7 +45,7 @@ describe('configuration', () => {
|
||||
}
|
||||
});
|
||||
|
||||
const userPlugin = app.getPlugin('@nocobase/plugin-users') as UsersPlugin;
|
||||
const userPlugin = app.getPlugin('users') as UsersPlugin;
|
||||
adminAgent = app.agent().auth(userPlugin.jwtService.sign({
|
||||
userId: admin.get('id'),
|
||||
}), { type: 'bearer' });
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { ACL } from '@nocobase/acl';
|
||||
import { Database, Model } from '@nocobase/database';
|
||||
import { MockServer } from '@nocobase/test';
|
||||
import UsersPlugin from '@nocobase/plugin-users';
|
||||
import { MockServer } from '@nocobase/test';
|
||||
import { prepareApp } from './prepare';
|
||||
|
||||
describe('middleware', () => {
|
||||
@ -30,7 +30,7 @@ describe('middleware', () => {
|
||||
}
|
||||
});
|
||||
|
||||
const userPlugin = app.getPlugin('@nocobase/plugin-users') as UsersPlugin;
|
||||
const userPlugin = app.getPlugin('users') as UsersPlugin;
|
||||
adminAgent = app.agent().auth(userPlugin.jwtService.sign({
|
||||
userId: admin.get('id'),
|
||||
}), { type: 'bearer' });
|
||||
|
@ -67,7 +67,7 @@ describe('own test', () => {
|
||||
|
||||
admin = await db.getRepository('users').findOne();
|
||||
|
||||
pluginUser = app.getPlugin('@nocobase/plugin-users');
|
||||
pluginUser = app.getPlugin('users');
|
||||
|
||||
adminToken = pluginUser.jwtService.sign({ userId: admin.get('id') });
|
||||
|
||||
|
@ -1,7 +1,3 @@
|
||||
import PluginCollectionManager from '@nocobase/plugin-collection-manager';
|
||||
import PluginErrorHandler from '@nocobase/plugin-error-handler';
|
||||
import PluginUiSchema from '@nocobase/plugin-ui-schema-storage';
|
||||
import PluginUsers from '@nocobase/plugin-users';
|
||||
import { mockServer } from '@nocobase/test';
|
||||
import PluginACL from '../server';
|
||||
|
||||
@ -9,15 +5,14 @@ export async function prepareApp() {
|
||||
const app = mockServer({
|
||||
registerActions: true,
|
||||
acl: true,
|
||||
plugins: ['error-handler', 'users', 'ui-schema-storage', 'collection-manager'],
|
||||
});
|
||||
|
||||
await app.cleanDb();
|
||||
|
||||
app.plugin(PluginUsers);
|
||||
app.plugin(PluginUiSchema);
|
||||
app.plugin(PluginErrorHandler);
|
||||
app.plugin(PluginCollectionManager);
|
||||
app.plugin(PluginACL);
|
||||
app.plugin(PluginACL, {
|
||||
name: 'acl',
|
||||
});
|
||||
await app.loadAndInstall();
|
||||
|
||||
await app.db.sync();
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { MockServer } from '@nocobase/test';
|
||||
import { Database } from '@nocobase/database';
|
||||
import UsersPlugin from '@nocobase/plugin-users';
|
||||
import { MockServer } from '@nocobase/test';
|
||||
|
||||
import { prepareApp } from './prepare';
|
||||
|
||||
@ -28,7 +28,7 @@ describe('role check action', () => {
|
||||
roles: ['test']
|
||||
}
|
||||
});
|
||||
const userPlugin = app.getPlugin('@nocobase/plugin-users') as UsersPlugin;
|
||||
const userPlugin = app.getPlugin('users') as UsersPlugin;
|
||||
const agent = app.agent().auth(userPlugin.jwtService.sign({
|
||||
userId: user.get('id'),
|
||||
}), { type: 'bearer' });
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Database, Model } from '@nocobase/database';
|
||||
import UsersPlugin from '@nocobase/plugin-users';
|
||||
import { CollectionRepository } from '@nocobase/plugin-collection-manager';
|
||||
import UsersPlugin from '@nocobase/plugin-users';
|
||||
import { MockServer } from '@nocobase/test';
|
||||
import { prepareApp } from './prepare';
|
||||
|
||||
@ -32,7 +32,7 @@ describe('role resource api', () => {
|
||||
}
|
||||
});
|
||||
|
||||
const userPlugin = app.getPlugin('@nocobase/plugin-users') as UsersPlugin;
|
||||
const userPlugin = app.getPlugin('users') as UsersPlugin;
|
||||
adminAgent = app.agent().auth(userPlugin.jwtService.sign({
|
||||
userId: admin.get('id'),
|
||||
}), { type: 'bearer' });
|
||||
|
@ -12,12 +12,12 @@ describe('role', () => {
|
||||
beforeEach(async () => {
|
||||
api = mockServer();
|
||||
await api.cleanDb();
|
||||
api.plugin(UsersPlugin);
|
||||
api.plugin(PluginACL);
|
||||
api.plugin(UsersPlugin, { name: 'users' });
|
||||
api.plugin(PluginACL, { name: 'acl' });
|
||||
await api.loadAndInstall();
|
||||
|
||||
db = api.db;
|
||||
usersPlugin = api.getPlugin('@nocobase/plugin-users');
|
||||
usersPlugin = api.getPlugin('users');
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { MockServer } from '@nocobase/test';
|
||||
import { Database, Model } from '@nocobase/database';
|
||||
import UsersPlugin from '@nocobase/plugin-users';
|
||||
import { MockServer } from '@nocobase/test';
|
||||
|
||||
import { prepareApp } from './prepare';
|
||||
|
||||
@ -36,7 +36,7 @@ describe('role api', () => {
|
||||
},
|
||||
});
|
||||
|
||||
const userPlugin = app.getPlugin('@nocobase/plugin-users') as UsersPlugin;
|
||||
const userPlugin = app.getPlugin('users') as UsersPlugin;
|
||||
adminAgent = app.agent().auth(
|
||||
userPlugin.jwtService.sign({
|
||||
userId: admin.get('id'),
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { prepareApp } from './prepare';
|
||||
import { MockServer } from '@nocobase/test';
|
||||
import { Database } from '@nocobase/database';
|
||||
import UsersPlugin from '@nocobase/plugin-users';
|
||||
import { MockServer } from '@nocobase/test';
|
||||
import { prepareApp } from './prepare';
|
||||
|
||||
describe('scope api', () => {
|
||||
let app: MockServer;
|
||||
@ -25,7 +25,7 @@ describe('scope api', () => {
|
||||
}
|
||||
});
|
||||
|
||||
const userPlugin = app.getPlugin('@nocobase/plugin-users') as UsersPlugin;
|
||||
const userPlugin = app.getPlugin('users') as UsersPlugin;
|
||||
adminAgent = app.agent().auth(userPlugin.jwtService.sign({
|
||||
userId: admin.get('id'),
|
||||
}), { type: 'bearer' });
|
||||
|
@ -15,7 +15,7 @@ describe('role', () => {
|
||||
api = await prepareApp();
|
||||
|
||||
db = api.db;
|
||||
usersPlugin = api.getPlugin('@nocobase/plugin-users');
|
||||
usersPlugin = api.getPlugin('users');
|
||||
|
||||
ctx = {
|
||||
db,
|
||||
|
@ -18,7 +18,7 @@ describe('actions', () => {
|
||||
app = await prepareApp();
|
||||
db = app.db;
|
||||
|
||||
pluginUser = app.getPlugin('@nocobase/plugin-users');
|
||||
pluginUser = app.getPlugin('users');
|
||||
adminUser = await db.getRepository('users').findOne({
|
||||
filter: {
|
||||
email: process.env.INIT_ROOT_EMAIL
|
||||
|
@ -442,9 +442,6 @@ export class PluginACL extends Plugin {
|
||||
});
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
return this.getPackageName(__dirname);
|
||||
}
|
||||
}
|
||||
|
||||
export default PluginACL;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/plugin-audit-logs",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "./lib/server/index.js",
|
||||
"types": "./lib/server/index.d.ts",
|
||||
"license": "Apache-2.0",
|
||||
@ -11,11 +11,11 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@nocobase/client": "0.7.4-alpha.7",
|
||||
"@nocobase/server": "0.7.4-alpha.7"
|
||||
"@nocobase/client": "0.8.0-alpha.1",
|
||||
"@nocobase/server": "0.8.0-alpha.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nocobase/test": "0.7.4-alpha.7"
|
||||
"@nocobase/test": "0.8.0-alpha.1"
|
||||
},
|
||||
"gitHead": "b17d1ecae5dd0b9d4e7170dcf9663bb225598990"
|
||||
}
|
||||
|
@ -8,8 +8,7 @@ describe('hook', () => {
|
||||
|
||||
beforeEach(async () => {
|
||||
api = mockServer();
|
||||
// api.plugin(require('@nocobase/plugin-users').default);
|
||||
api.plugin(logPlugin);
|
||||
api.plugin(logPlugin, { name: 'audit-logs' });
|
||||
await api.load();
|
||||
db = api.db;
|
||||
db.collection({
|
||||
|
@ -21,8 +21,4 @@ export default class PluginActionLogs extends Plugin {
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
return this.getPackageName(__dirname);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/plugin-china-region",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "lib/index.js",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -10,12 +10,12 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@nocobase/client": "0.7.4-alpha.7",
|
||||
"@nocobase/server": "0.7.4-alpha.7",
|
||||
"@nocobase/client": "0.8.0-alpha.1",
|
||||
"@nocobase/server": "0.8.0-alpha.1",
|
||||
"china-division": "^2.4.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nocobase/test": "0.7.4-alpha.7"
|
||||
"@nocobase/test": "0.8.0-alpha.1"
|
||||
},
|
||||
"gitHead": "b17d1ecae5dd0b9d4e7170dcf9663bb225598990"
|
||||
}
|
||||
|
@ -64,9 +64,6 @@ export class PluginChinaRegion extends Plugin {
|
||||
// console.log(`${count} rows of region data imported in ${(Date.now() - timer) / 1000}s`);
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
return this.getPackageName(__dirname);
|
||||
}
|
||||
}
|
||||
|
||||
export default PluginChinaRegion;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/plugin-client",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "lib/index.js",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -10,10 +10,10 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@nocobase/server": "0.7.4-alpha.7"
|
||||
"@nocobase/server": "0.8.0-alpha.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nocobase/test": "0.7.4-alpha.7"
|
||||
"@nocobase/test": "0.8.0-alpha.1"
|
||||
},
|
||||
"gitHead": "b17d1ecae5dd0b9d4e7170dcf9663bb225598990"
|
||||
}
|
||||
|
@ -108,10 +108,6 @@ export class ClientPlugin extends Plugin {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
return this.getPackageName(__dirname);
|
||||
}
|
||||
}
|
||||
|
||||
export default ClientPlugin;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/plugin-collection-manager",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "lib/index.js",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -10,13 +10,13 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@nocobase/database": "0.7.4-alpha.7",
|
||||
"@nocobase/plugin-error-handler": "0.7.4-alpha.7",
|
||||
"@nocobase/server": "0.7.4-alpha.7",
|
||||
"@nocobase/database": "0.8.0-alpha.1",
|
||||
"@nocobase/plugin-error-handler": "0.8.0-alpha.1",
|
||||
"@nocobase/server": "0.8.0-alpha.1",
|
||||
"sequelize": "^6.9.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nocobase/test": "0.7.4-alpha.7"
|
||||
"@nocobase/test": "0.8.0-alpha.1"
|
||||
},
|
||||
"gitHead": "b17d1ecae5dd0b9d4e7170dcf9663bb225598990"
|
||||
}
|
||||
|
@ -46,7 +46,9 @@ describe('field indexes', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(response3.status).toBe(400);
|
||||
console.log(response3.body);
|
||||
|
||||
expect(response3.status).toBe(500);
|
||||
|
||||
const response4 = await agent.resource(tableName).create({
|
||||
values: { title: 't1' },
|
||||
@ -82,7 +84,7 @@ describe('field indexes', () => {
|
||||
title: 't1',
|
||||
},
|
||||
});
|
||||
expect(response2.status).toBe(400);
|
||||
expect(response2.status).toBe(500);
|
||||
|
||||
// update field to remove unique constraint
|
||||
await agent.resource('fields').update({
|
||||
@ -109,7 +111,7 @@ describe('field indexes', () => {
|
||||
},
|
||||
});
|
||||
|
||||
expect(response4.status).toBe(400);
|
||||
expect(response4.status).toBe(500);
|
||||
|
||||
// remove a duplicated record
|
||||
await agent.resource(tableName).destroy({
|
||||
|
@ -13,12 +13,11 @@ export async function createApp(options = {}) {
|
||||
await app.cleanDb();
|
||||
}
|
||||
|
||||
app.plugin(PluginErrorHandler);
|
||||
app.plugin(Plugin);
|
||||
app.plugin(PluginUiSchema);
|
||||
app.plugin(PluginErrorHandler, { name: 'error-handler' });
|
||||
app.plugin(Plugin, { name: 'collection-manager' });
|
||||
app.plugin(PluginUiSchema, { name: 'ui-schema-storage' });
|
||||
|
||||
// await app.load();
|
||||
await app.install({ clean: true });
|
||||
await app.loadAndInstall({ clean: true });
|
||||
await app.start();
|
||||
return app;
|
||||
}
|
||||
|
@ -10,11 +10,10 @@ describe('collections repository', () => {
|
||||
},
|
||||
acl: false,
|
||||
});
|
||||
await app1.cleanDb();
|
||||
app1.plugin(PluginErrorHandler);
|
||||
app1.plugin(Plugin);
|
||||
await app1.install({ clean: true });
|
||||
await app1.start();
|
||||
app1.plugin(PluginErrorHandler, { name: 'error-handler' });
|
||||
app1.plugin(Plugin, { name: 'collection-manager' });
|
||||
await app1.loadAndInstall({ clean: true });
|
||||
|
||||
await app1
|
||||
.agent()
|
||||
.resource('collections')
|
||||
@ -121,10 +120,9 @@ describe('collections repository', () => {
|
||||
tablePrefix: 'through_',
|
||||
},
|
||||
});
|
||||
app2.plugin(PluginErrorHandler);
|
||||
app2.plugin(Plugin);
|
||||
app2.plugin(PluginErrorHandler, { name: 'error-handler' });
|
||||
app2.plugin(Plugin, { name: 'collection-manager' });
|
||||
await app2.load();
|
||||
await app2.start();
|
||||
|
||||
await app2.db.sync({
|
||||
force: true,
|
||||
|
@ -11,11 +11,12 @@ import {
|
||||
afterCreateForReverseField,
|
||||
beforeCreateForChildrenCollection,
|
||||
beforeCreateForReverseField,
|
||||
beforeInitOptions,
|
||||
beforeInitOptions
|
||||
} from './hooks';
|
||||
import { CollectionModel, FieldModel } from './models';
|
||||
|
||||
export class CollectionManagerPlugin extends Plugin {
|
||||
|
||||
async beforeLoad() {
|
||||
this.app.db.registerModels({
|
||||
CollectionModel,
|
||||
@ -60,7 +61,7 @@ export class CollectionManagerPlugin extends Plugin {
|
||||
await fn(model, { database: this.app.db });
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
this.app.db.on('fields.afterCreate', afterCreateForReverseField(this.app.db));
|
||||
|
||||
this.app.db.on('collections.afterCreateWithAssociations', async (model, { context, transaction }) => {
|
||||
@ -116,22 +117,10 @@ export class CollectionManagerPlugin extends Plugin {
|
||||
await model.remove(options);
|
||||
});
|
||||
|
||||
this.app.on('beforeStart', async () => {
|
||||
await this.app.db.getRepository<CollectionRepository>('collections').load();
|
||||
});
|
||||
|
||||
this.app.on('beforeUpgrade', async () => {
|
||||
await this.app.db.getRepository<CollectionRepository>('collections').load();
|
||||
});
|
||||
|
||||
this.app.on('cli.beforeMigrator', async () => {
|
||||
const exists = await this.app.db.collectionExistsInDb('collections');
|
||||
if (exists) {
|
||||
await this.app.db.getRepository<CollectionRepository>('collections').load();
|
||||
this.app.on('afterLoad', async (app, options) => {
|
||||
if (options?.method === 'install') {
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
this.app.on('cli.beforeDbSync', async () => {
|
||||
const exists = await this.app.db.collectionExistsInDb('collections');
|
||||
if (exists) {
|
||||
await this.app.db.getRepository<CollectionRepository>('collections').load();
|
||||
@ -195,7 +184,7 @@ export class CollectionManagerPlugin extends Plugin {
|
||||
directory: path.resolve(__dirname, './collections'),
|
||||
});
|
||||
|
||||
const errorHandlerPlugin = <PluginErrorHandler>this.app.getPlugin('@nocobase/plugin-error-handler');
|
||||
const errorHandlerPlugin = <PluginErrorHandler>this.app.getPlugin('error-handler');
|
||||
errorHandlerPlugin.errorHandler.register(
|
||||
(err) => {
|
||||
return err instanceof UniqueConstraintError;
|
||||
@ -205,10 +194,6 @@ export class CollectionManagerPlugin extends Plugin {
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
return this.getPackageName(__dirname);
|
||||
}
|
||||
}
|
||||
|
||||
export default CollectionManagerPlugin;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/plugin-error-handler",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"description": "",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -13,7 +13,7 @@
|
||||
"types": "./lib/index.d.ts",
|
||||
"dependencies": {
|
||||
"@formily/json-schema": "^2.0.15",
|
||||
"@nocobase/server": "0.7.4-alpha.7"
|
||||
"@nocobase/server": "0.8.0-alpha.1"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -9,14 +9,14 @@ describe('create with exception', () => {
|
||||
acl: false,
|
||||
});
|
||||
await app.cleanDb();
|
||||
app.plugin(PluginErrorHandler);
|
||||
app.plugin(PluginErrorHandler, { name: 'error-handler' });
|
||||
});
|
||||
|
||||
afterEach(async () => {
|
||||
await app.destroy();
|
||||
});
|
||||
|
||||
it.only('should handle not null error', async () => {
|
||||
it('should handle not null error', async () => {
|
||||
app.collection({
|
||||
name: 'users',
|
||||
fields: [
|
||||
|
@ -7,9 +7,6 @@ import enUS from './locale/en_US';
|
||||
import zhCN from './locale/zh_CN';
|
||||
|
||||
export class PluginErrorHandler extends Plugin {
|
||||
getName(): string {
|
||||
return this.getPackageName(__dirname);
|
||||
}
|
||||
|
||||
errorHandler: ErrorHandler = new ErrorHandler();
|
||||
i18nNs: string = 'error-handler';
|
||||
|
@ -1,10 +1,10 @@
|
||||
{
|
||||
"name": "@nocobase/plugin-export",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "lib/server/index.js",
|
||||
"dependencies": {
|
||||
"@nocobase/client": "0.7.4-alpha.7",
|
||||
"@nocobase/server": "0.7.4-alpha.7",
|
||||
"@nocobase/client": "0.8.0-alpha.1",
|
||||
"@nocobase/server": "0.8.0-alpha.1",
|
||||
"node-xlsx": "^0.16.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
@ -2,10 +2,6 @@ import { InstallOptions, Plugin } from '@nocobase/server';
|
||||
import { exportXlsx } from './actions';
|
||||
|
||||
export class ExportPlugin extends Plugin {
|
||||
getName(): string {
|
||||
return this.getPackageName(__dirname);
|
||||
}
|
||||
|
||||
beforeLoad() {}
|
||||
|
||||
async load() {
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/plugin-file-manager",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "lib/index.js",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -11,7 +11,7 @@
|
||||
],
|
||||
"dependencies": {
|
||||
"@koa/multer": "^3.0.0",
|
||||
"@nocobase/server": "0.7.4-alpha.7",
|
||||
"@nocobase/server": "0.8.0-alpha.1",
|
||||
"aws-sdk": "^2.2.32",
|
||||
"koa-static": "^5.0.0",
|
||||
"mime-match": "^1.0.2",
|
||||
@ -21,7 +21,7 @@
|
||||
"multer-s3": "^2.10.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nocobase/test": "0.7.4-alpha.7",
|
||||
"@nocobase/test": "0.8.0-alpha.1",
|
||||
"@types/koa-multer": "^1.0.1",
|
||||
"@types/multer": "^1.4.5"
|
||||
},
|
||||
|
@ -39,7 +39,4 @@ export default class PluginFileManager extends Plugin {
|
||||
this.app.acl.allow('attachments', 'upload', 'loggedIn');
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
return this.getPackageName(__dirname);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/plugin-multi-app-manager",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "lib/index.js",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -10,7 +10,7 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@nocobase/server": "0.7.4-alpha.7"
|
||||
"@nocobase/server": "0.8.0-alpha.1"
|
||||
},
|
||||
"gitHead": "b17d1ecae5dd0b9d4e7170dcf9663bb225598990"
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ describe('test with start', () => {
|
||||
values: {
|
||||
name,
|
||||
options: {
|
||||
plugins: ['@nocobase/plugin-ui-schema-storage'],
|
||||
plugins: ['ui-schema-storage'],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -57,7 +57,7 @@ describe('multiple apps create', () => {
|
||||
values: {
|
||||
name,
|
||||
options: {
|
||||
plugins: [['@nocobase/plugin-ui-schema-storage', { test: 'B' }]],
|
||||
plugins: [['ui-schema-storage', { test: 'B' }]],
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -65,7 +65,7 @@ describe('multiple apps create', () => {
|
||||
const miniApp = app.appManager.applications.get(name);
|
||||
expect(miniApp).toBeDefined();
|
||||
|
||||
const plugin = miniApp.pm.get('@nocobase/plugin-ui-schema-storage');
|
||||
const plugin = miniApp.pm.get('ui-schema-storage');
|
||||
|
||||
expect(plugin).toBeDefined();
|
||||
expect(plugin.options).toMatchObject({
|
||||
@ -79,7 +79,7 @@ describe('multiple apps create', () => {
|
||||
values: {
|
||||
name,
|
||||
options: {
|
||||
plugins: ['@nocobase/plugin-ui-schema-storage'],
|
||||
plugins: ['ui-schema-storage'],
|
||||
},
|
||||
},
|
||||
});
|
||||
@ -106,7 +106,7 @@ describe('multiple apps create', () => {
|
||||
values: {
|
||||
name,
|
||||
options: {
|
||||
plugins: ['@nocobase/plugin-ui-schema-storage'],
|
||||
plugins: ['ui-schema-storage'],
|
||||
},
|
||||
},
|
||||
});
|
||||
|
@ -17,10 +17,9 @@ export class ApplicationModel extends Model {
|
||||
}
|
||||
|
||||
static async handleAppStart(app: Application, options: registerAppOptions) {
|
||||
await app.load();
|
||||
if (!options?.skipInstall) {
|
||||
await app.install();
|
||||
} else {
|
||||
await app.load();
|
||||
}
|
||||
await app.start();
|
||||
}
|
||||
|
@ -3,9 +3,6 @@ import { resolve } from 'path';
|
||||
import { ApplicationModel } from './models/application';
|
||||
|
||||
export class PluginMultiAppManager extends Plugin {
|
||||
getName(): string {
|
||||
return this.getPackageName(__dirname);
|
||||
}
|
||||
|
||||
async install(options?: InstallOptions) {
|
||||
const repo = this.db.getRepository<any>('collections');
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/plugin-notifications",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "lib/index.js",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -13,7 +13,7 @@
|
||||
"nodemailer": "^6.6.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nocobase/test": "0.7.4-alpha.7",
|
||||
"@nocobase/test": "0.8.0-alpha.1",
|
||||
"@types/nodemailer": "6.4.4",
|
||||
"nodemailer-mock": "^1.5.11"
|
||||
},
|
||||
|
@ -1,5 +1,5 @@
|
||||
import path from 'path';
|
||||
import { Plugin } from '@nocobase/server';
|
||||
import path from 'path';
|
||||
|
||||
export default class PluginNotifications extends Plugin {
|
||||
async load() {
|
||||
@ -7,8 +7,4 @@ export default class PluginNotifications extends Plugin {
|
||||
directory: path.resolve(__dirname, 'collections'),
|
||||
});
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
return this.getPackageName(__dirname);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/plugin-system-settings",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "lib/index.js",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -10,7 +10,7 @@
|
||||
}
|
||||
],
|
||||
"devDependencies": {
|
||||
"@nocobase/test": "0.7.4-alpha.7"
|
||||
"@nocobase/test": "0.8.0-alpha.1"
|
||||
},
|
||||
"gitHead": "b17d1ecae5dd0b9d4e7170dcf9663bb225598990"
|
||||
}
|
||||
|
@ -42,10 +42,6 @@ export class SystemSettingsPlugin extends Plugin {
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
return this.getPackageName(__dirname);
|
||||
}
|
||||
}
|
||||
|
||||
export default SystemSettingsPlugin;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/plugin-ui-routes-storage",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "lib/index.js",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -13,7 +13,7 @@
|
||||
"flat-to-nested": "^1.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nocobase/test": "0.7.4-alpha.7"
|
||||
"@nocobase/test": "0.8.0-alpha.1"
|
||||
},
|
||||
"gitHead": "b17d1ecae5dd0b9d4e7170dcf9663bb225598990"
|
||||
}
|
||||
|
@ -5,9 +5,6 @@ import { resolve } from 'path';
|
||||
import { getAccessible } from './actions/getAccessible';
|
||||
|
||||
export class UiRoutesStoragePlugin extends Plugin {
|
||||
getName(): string {
|
||||
return this.getPackageName(__dirname);
|
||||
}
|
||||
|
||||
async install() {
|
||||
const repository = this.app.db.getRepository('uiRoutes');
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/plugin-ui-schema-storage",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "lib/index.js",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -11,7 +11,7 @@
|
||||
],
|
||||
"devDependencies": {
|
||||
"@formily/json-schema": "2.0.20",
|
||||
"@nocobase/test": "0.7.4-alpha.7"
|
||||
"@nocobase/test": "0.8.0-alpha.1"
|
||||
},
|
||||
"gitHead": "b17d1ecae5dd0b9d4e7170dcf9663bb225598990"
|
||||
}
|
||||
|
@ -16,7 +16,7 @@ describe('action test', () => {
|
||||
const queryInterface = db.sequelize.getQueryInterface();
|
||||
await queryInterface.dropAllTables();
|
||||
|
||||
app.plugin(PluginUiSchema);
|
||||
app.plugin(PluginUiSchema, { name: 'ui-schema-storage' });
|
||||
|
||||
await app.load();
|
||||
await db.sync({
|
||||
|
@ -1,9 +1,9 @@
|
||||
import { BelongsToManyRepository, Database } from '@nocobase/database';
|
||||
import PluginUsers from '@nocobase/plugin-users';
|
||||
import PluginACL from '@nocobase/plugin-acl';
|
||||
import PluginErrorHandler from '@nocobase/plugin-error-handler';
|
||||
import PluginCollectionManager from '@nocobase/plugin-collection-manager';
|
||||
import PluginErrorHandler from '@nocobase/plugin-error-handler';
|
||||
import UiSchemaStoragePlugin, { UiSchemaRepository } from '@nocobase/plugin-ui-schema-storage';
|
||||
import PluginUsers from '@nocobase/plugin-users';
|
||||
import { mockServer, MockServer } from '@nocobase/test';
|
||||
|
||||
describe('server hooks', () => {
|
||||
@ -24,17 +24,17 @@ describe('server hooks', () => {
|
||||
await app.cleanDb();
|
||||
db = app.db;
|
||||
|
||||
app.plugin(UiSchemaStoragePlugin);
|
||||
app.plugin(PluginErrorHandler);
|
||||
app.plugin(PluginCollectionManager);
|
||||
app.plugin(PluginUsers);
|
||||
app.plugin(PluginACL);
|
||||
app.plugin(UiSchemaStoragePlugin, { name: 'ui-schema-storage' });
|
||||
app.plugin(PluginErrorHandler, { name: 'error-handler' });
|
||||
app.plugin(PluginCollectionManager, { name: 'collection-manager' });
|
||||
app.plugin(PluginUsers, { name: 'users' });
|
||||
app.plugin(PluginACL, { name: 'acl' });
|
||||
|
||||
await app.loadAndInstall();
|
||||
|
||||
uiSchemaRepository = db.getRepository('uiSchemas');
|
||||
|
||||
uiSchemaPlugin = app.getPlugin<UiSchemaStoragePlugin>('@nocobase/plugin-ui-schema-storage');
|
||||
uiSchemaPlugin = app.getPlugin<UiSchemaStoragePlugin>('ui-schema-storage');
|
||||
});
|
||||
|
||||
it('should clean row struct', async () => {
|
||||
|
@ -1,6 +1,6 @@
|
||||
import { Database } from '@nocobase/database';
|
||||
import PluginErrorHandler from '@nocobase/plugin-error-handler';
|
||||
import PluginCollectionManager from '@nocobase/plugin-collection-manager';
|
||||
import PluginErrorHandler from '@nocobase/plugin-error-handler';
|
||||
import UiSchemaStoragePlugin, { UiSchemaRepository } from '@nocobase/plugin-ui-schema-storage';
|
||||
import { mockServer, MockServer } from '@nocobase/test';
|
||||
|
||||
@ -62,16 +62,16 @@ describe('server hooks', () => {
|
||||
await app.cleanDb();
|
||||
db = app.db;
|
||||
|
||||
app.plugin(UiSchemaStoragePlugin);
|
||||
app.plugin(PluginErrorHandler);
|
||||
app.plugin(PluginCollectionManager);
|
||||
app.plugin(UiSchemaStoragePlugin, { name: 'ui-schema-storage' });
|
||||
app.plugin(PluginErrorHandler, { name: 'error-handler' });
|
||||
app.plugin(PluginCollectionManager, { name: 'collection-manager' });
|
||||
|
||||
await app.loadAndInstall();
|
||||
|
||||
uiSchemaRepository = db.getRepository('uiSchemas');
|
||||
await uiSchemaRepository.insert(schema);
|
||||
|
||||
uiSchemaPlugin = app.getPlugin<UiSchemaStoragePlugin>('@nocobase/plugin-ui-schema-storage');
|
||||
uiSchemaPlugin = app.getPlugin<UiSchemaStoragePlugin>('ui-schema-storage');
|
||||
});
|
||||
|
||||
it('should call server hooks onFieldDestroy', async () => {
|
||||
|
@ -22,7 +22,7 @@ describe('ui schema model', () => {
|
||||
const queryInterface = db.sequelize.getQueryInterface();
|
||||
await queryInterface.dropAllTables();
|
||||
|
||||
app.plugin(PluginUiSchema);
|
||||
app.plugin(PluginUiSchema, { name: 'ui-schema-storage' });
|
||||
|
||||
await app.load();
|
||||
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { Database } from '@nocobase/database';
|
||||
import { Cache } from '@nocobase/cache';
|
||||
import { Database } from '@nocobase/database';
|
||||
import { mockServer, MockServer } from '@nocobase/test';
|
||||
import UiSchemaRepository, { GetJsonSchemaOptions, GetPropertiesOptions } from '../repository';
|
||||
import PluginUiSchema from '../server';
|
||||
@ -25,7 +25,7 @@ describe('ui_schema repository with cache', () => {
|
||||
|
||||
await db.sequelize.getQueryInterface().dropAllTables();
|
||||
|
||||
app.plugin(PluginUiSchema);
|
||||
app.plugin(PluginUiSchema, { name: 'ui-schema-storage' });
|
||||
|
||||
await app.load();
|
||||
await db.sync({
|
||||
|
@ -25,7 +25,7 @@ describe('ui_schema repository', () => {
|
||||
const queryInterface = db.sequelize.getQueryInterface();
|
||||
await queryInterface.dropAllTables();
|
||||
|
||||
app.plugin(PluginUiSchema);
|
||||
app.plugin(PluginUiSchema, { name: 'ui-schema-storage' });
|
||||
|
||||
await app.load();
|
||||
await db.sync({
|
||||
|
@ -22,7 +22,7 @@ describe('ui-schema', () => {
|
||||
|
||||
await db.sequelize.getQueryInterface().dropAllTables();
|
||||
|
||||
app.plugin(PluginUiSchema);
|
||||
app.plugin(PluginUiSchema, { name: 'ui-schema-storage' });
|
||||
|
||||
await app.loadAndInstall();
|
||||
uiSchemaRepository = db.getCollection('uiSchemas').repository as UiSchemaRepository;
|
||||
|
@ -70,10 +70,6 @@ export class UiSchemaStoragePlugin extends Plugin {
|
||||
directory: path.resolve(__dirname, 'collections'),
|
||||
});
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
return this.getPackageName(__dirname);
|
||||
}
|
||||
}
|
||||
|
||||
export default UiSchemaStoragePlugin;
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/plugin-users",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "lib/index.js",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -10,16 +10,16 @@
|
||||
}
|
||||
],
|
||||
"dependencies": {
|
||||
"@nocobase/actions": "0.7.4-alpha.7",
|
||||
"@nocobase/database": "0.7.4-alpha.7",
|
||||
"@nocobase/resourcer": "0.7.4-alpha.7",
|
||||
"@nocobase/server": "0.7.4-alpha.7",
|
||||
"@nocobase/utils": "0.7.4-alpha.7",
|
||||
"jsonwebtoken": "^8.5.1",
|
||||
"json-templates": "^4.2.0"
|
||||
"@nocobase/actions": "0.8.0-alpha.1",
|
||||
"@nocobase/database": "0.8.0-alpha.1",
|
||||
"@nocobase/resourcer": "0.8.0-alpha.1",
|
||||
"@nocobase/server": "0.8.0-alpha.1",
|
||||
"@nocobase/utils": "0.8.0-alpha.1",
|
||||
"json-templates": "^4.2.0",
|
||||
"jsonwebtoken": "^8.5.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nocobase/test": "0.7.4-alpha.7",
|
||||
"@nocobase/test": "0.8.0-alpha.1",
|
||||
"@types/jsonwebtoken": "^8.5.8"
|
||||
},
|
||||
"gitHead": "b17d1ecae5dd0b9d4e7170dcf9663bb225598990"
|
||||
|
@ -22,7 +22,7 @@ describe('actions', () => {
|
||||
await app.loadAndInstall();
|
||||
db = app.db;
|
||||
|
||||
pluginUser = app.getPlugin('@nocobase/plugin-users');
|
||||
pluginUser = app.getPlugin('users');
|
||||
adminUser = await db.getRepository('users').findOne({
|
||||
filter: {
|
||||
email: process.env.INIT_ROOT_EMAIL
|
||||
|
@ -10,9 +10,8 @@ describe('createdBy/updatedBy', () => {
|
||||
beforeEach(async () => {
|
||||
api = mockServer();
|
||||
api.plugin(UsersPlugin, userPluginConfig);
|
||||
api.plugin(PluginACL);
|
||||
await api.cleanDb();
|
||||
await api.loadAndInstall();
|
||||
api.plugin(PluginACL, { name: 'acl' });
|
||||
await api.loadAndInstall({ clean: true });
|
||||
db = api.db;
|
||||
});
|
||||
|
||||
@ -63,7 +62,7 @@ describe('createdBy/updatedBy', () => {
|
||||
await db.sync();
|
||||
const user1 = await db.getCollection('users').model.create();
|
||||
const user2 = await db.getCollection('users').model.create();
|
||||
const p1 = await Post.repository.create<any>({
|
||||
const p1 = await Post.repository.create({
|
||||
context: {
|
||||
state: {
|
||||
currentUser: user1,
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { UserPluginConfig } from '../server';
|
||||
|
||||
export const userPluginConfig: UserPluginConfig = {
|
||||
name: 'users',
|
||||
jwt: {
|
||||
secret: '09f26e402586e2faa8da4c98a35f1b20d6b033c60',
|
||||
},
|
||||
|
@ -15,7 +15,7 @@ export async function check(ctx: Context, next: Next) {
|
||||
}
|
||||
|
||||
export async function signin(ctx: Context, next: Next) {
|
||||
const { authenticators, jwtService } = ctx.app.getPlugin('@nocobase/plugin-users');
|
||||
const { authenticators, jwtService } = ctx.app.getPlugin('users');
|
||||
const branches = {};
|
||||
for (const [name, authenticator] of authenticators.getEntities()) {
|
||||
branches[name] = authenticator;
|
||||
|
@ -13,7 +13,7 @@ async function findUserByToken(ctx: Context) {
|
||||
if (!token) {
|
||||
return null;
|
||||
}
|
||||
const { jwtService } = ctx.app.getPlugin('@nocobase/plugin-users');
|
||||
const { jwtService } = ctx.app.getPlugin('users');
|
||||
try {
|
||||
const { userId } = await jwtService.decode(token);
|
||||
const collection = ctx.db.getCollection('users');
|
||||
|
@ -14,6 +14,7 @@ import { enUS, zhCN } from './locale';
|
||||
import { parseToken } from './middlewares';
|
||||
|
||||
export interface UserPluginConfig {
|
||||
name?: string;
|
||||
jwt: JwtOptions;
|
||||
}
|
||||
|
||||
@ -117,7 +118,7 @@ export default class UsersPlugin extends Plugin<UserPluginConfig> {
|
||||
initAuthenticators(this);
|
||||
|
||||
// TODO(module): should move to preset
|
||||
const verificationPlugin = this.app.getPlugin('@nocobase/plugin-verification') as any;
|
||||
const verificationPlugin = this.app.getPlugin('verification') as any;
|
||||
if (verificationPlugin && process.env.DEFAULT_SMS_VERIFY_CODE_PROVIDER) {
|
||||
verificationPlugin.interceptors.register('users:signin', {
|
||||
manual: true,
|
||||
@ -220,8 +221,4 @@ export default class UsersPlugin extends Plugin<UserPluginConfig> {
|
||||
await repo.db2cm('users');
|
||||
}
|
||||
}
|
||||
|
||||
getName(): string {
|
||||
return this.getPackageName(__dirname);
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@nocobase/plugin-verification",
|
||||
"version": "0.7.4-alpha.7",
|
||||
"version": "0.8.0-alpha.1",
|
||||
"main": "lib/index.js",
|
||||
"license": "Apache-2.0",
|
||||
"licenses": [
|
||||
@ -13,13 +13,13 @@
|
||||
"@alicloud/dysmsapi20170525": "2.0.17",
|
||||
"@alicloud/openapi-client": "0.4.1",
|
||||
"@alicloud/tea-util": "1.4.4",
|
||||
"@nocobase/actions": "0.7.4-alpha.7",
|
||||
"@nocobase/resourcer": "0.7.4-alpha.7",
|
||||
"@nocobase/server": "0.7.4-alpha.7",
|
||||
"@nocobase/utils": "0.7.4-alpha.7"
|
||||
"@nocobase/actions": "0.8.0-alpha.1",
|
||||
"@nocobase/resourcer": "0.8.0-alpha.1",
|
||||
"@nocobase/server": "0.8.0-alpha.1",
|
||||
"@nocobase/utils": "0.8.0-alpha.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@nocobase/test": "0.7.4-alpha.7"
|
||||
"@nocobase/test": "0.8.0-alpha.1"
|
||||
},
|
||||
"gitHead": "7e9556e489007577fc0ed89063b3a9ce2f9aae53"
|
||||
}
|
||||
|
@ -74,10 +74,6 @@ export default class VerificationPlugin extends Plugin {
|
||||
});
|
||||
};
|
||||
|
||||
getName(): string {
|
||||
return this.getPackageName(__dirname);
|
||||
}
|
||||
|
||||
async install() {
|
||||
const {
|
||||
DEFAULT_SMS_VERIFY_CODE_PROVIDER,
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { MockServer } from '@nocobase/test';
|
||||
import Database from '@nocobase/database';
|
||||
import { MockServer } from '@nocobase/test';
|
||||
|
||||
import Plugin, { Provider } from '..';
|
||||
|
||||
@ -21,7 +21,7 @@ describe('verification > Plugin', () => {
|
||||
app = await getApp();
|
||||
agent = app.agent();
|
||||
db = app.db;
|
||||
plugin = <Plugin>app.getPlugin('@nocobase/plugin-verification');
|
||||
plugin = <Plugin>app.getPlugin('verification');
|
||||
VerificationModel = db.getCollection('verifications').model;
|
||||
AuthorModel = db.getCollection('authors').model;
|
||||
AuthorRepo = db.getCollection('authors').repository;
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user