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