docs: server application api (#842)
* feat: update docs * fix: improve code
This commit is contained in:
parent
00195fa779
commit
678b6cef21
@ -39,10 +39,7 @@ export default {
|
||||
title: 'Getting started',
|
||||
'title.zh-CN': '快速开始',
|
||||
type: 'group',
|
||||
children: [
|
||||
'/development/index',
|
||||
'/development/your-fisrt-plugin'
|
||||
],
|
||||
children: ['/development/index', '/development/your-fisrt-plugin'],
|
||||
},
|
||||
{
|
||||
title: 'Extension Guides',
|
||||
@ -83,10 +80,7 @@ export default {
|
||||
{
|
||||
title: 'HTTP API',
|
||||
type: 'group',
|
||||
children: [
|
||||
'/api/http-api/index',
|
||||
'/api/http-api/rest-api',
|
||||
],
|
||||
children: ['/api/http-api/index', '/api/http-api/rest-api'],
|
||||
},
|
||||
],
|
||||
// {
|
||||
@ -166,7 +160,7 @@ export default {
|
||||
{
|
||||
title: '@nocobase/server',
|
||||
type: 'subMenu',
|
||||
children: ['/api/server/application', '/api/server/plugin-manager', '/api/server/i18n'],
|
||||
children: ['/api/server/application', '/api/server/plugin-manager', '/api/server/plugin'],
|
||||
},
|
||||
{
|
||||
title: '@nocobase/database',
|
||||
|
@ -1,29 +1,37 @@
|
||||
# Application
|
||||
|
||||
NocoBase 的应用程序类,服务端的应用进程将实例化该类并启动。因为继承自 [Koa](https://koajs.com/),所以也可以直接调用 Koa 实例的方法。
|
||||
|
||||
同时因为 Koa 还继承自 [EventEmitter](https://nodejs.org/api/events.html#events_class_eventemitter),所以也可以通过 `app.on` 监听事件。
|
||||
基于 [Koa](https://koajs.com/) 实现的 WEB 框架,兼容所有的 Koa 插件。
|
||||
|
||||
## 构造函数
|
||||
|
||||
### `constructor()`
|
||||
|
||||
创建一个应用实例。
|
||||
|
||||
**签名**
|
||||
|
||||
* `constructor(options: ApplicationOptions)`
|
||||
|
||||
创建一个应用实例。
|
||||
|
||||
**参数**
|
||||
|
||||
| 参数名 | 类型 | 默认值 | 描述 |
|
||||
| --- | --- | --- | --- |
|
||||
| `options.database` | `IDatabaseOptions` or `Database` | `{}` | 数据库配置 |
|
||||
| `options.resourcer` | `ResourcerOptions` | `{}` | 资源路由配置 |
|
||||
| `options.cors` | `CorsOptions` | `{}` | 跨域配置,参考 [@koa/cors](https://npmjs.com/package/@koa/cors) |
|
||||
| `options.cors` | [`CorsOptions`](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/types/koa__cors/index.d.ts#L24) | `{}` | 跨域配置,参考 [@koa/cors](https://npmjs.com/package/@koa/cors) |
|
||||
| `options.dataWrapping` | `boolean` | `true` | 是否包装响应数据,`true` 则将把通常的 `ctx.body` 包装为 `{ data, meta }` 的结构。 |
|
||||
| `options.registerActions` | `boolean` | `true` | 是否注册默认的 action |
|
||||
| `options.i18n` | `I18nOptions` | `{}` | 国际化配置,参考 [i18next](https://www.npmjs.com/package/i18next) |
|
||||
| `options.registerActions` | `boolean` | `true` | 是否注册默认的 [actions](#) |
|
||||
| `options.i18n` | `I18nOptions` | `{}` | 国际化配置,参考 [i18next](https://www.i18next.com/overview/api) |
|
||||
| `options.plugins` | `PluginConfiguration[]` | `[]` | 默认启用的插件配置 |
|
||||
|
||||
Type
|
||||
|
||||
```ts
|
||||
interface ApplicationOptions {
|
||||
|
||||
}
|
||||
```
|
||||
|
||||
**示例**
|
||||
|
||||
```ts
|
||||
@ -51,31 +59,38 @@ const app = new Application({
|
||||
|
||||
### `db`
|
||||
|
||||
应用初始化自动创建的数据库实例,通过 `@nocobase/database` 封装的数据库访问类,相关方法参考 [Database](./database)。
|
||||
数据库实例,相关 API 参考 [Database](/api/database)。
|
||||
|
||||
### `resourcer`
|
||||
|
||||
应用初始化自动创建的资源路由管理实例,相关方法参考 [Resourcer](./resourcer)。
|
||||
|
||||
### `cli`
|
||||
|
||||
应用初始化自动创建的命令行工具实例,相关方法参考 [CLI](../cli)。
|
||||
应用初始化自动创建的资源路由管理实例,相关 API 参考 [Resourcer](/api/resourcer)。
|
||||
|
||||
### `acl`
|
||||
|
||||
应用初始化自动创建的访问控制表实例,相关方法参考 [ACL](./acl)。
|
||||
ACL 实例,相关 API 参考 [ACL](/api/acl)。
|
||||
|
||||
### `i18n`
|
||||
|
||||
应用初始化自动创建的国际化工具实例,相关方法参考 [I18n](./i18n)。
|
||||
|
||||
### `appManager`
|
||||
|
||||
应用初始化自动创建的应用管理实例,相关方法参考 [AppManager](./app-manager)。
|
||||
I18next 实例,相关 API 参考 [I18next](https://www.i18next.com/overview/api)。
|
||||
|
||||
### `pm`
|
||||
|
||||
应用初始化自动创建的插件管理器实例,相关方法参考 [PluginManager](./plugin-manager)。
|
||||
插件管理器实例,相关 API 参考 [PluginManager](./plugin-manager)。
|
||||
|
||||
### `version`
|
||||
|
||||
应用版本实例,相关 API 参考 [ApplicationVersion](./application-version)。
|
||||
|
||||
### `middleware`
|
||||
|
||||
内置的中间件有:
|
||||
|
||||
- i18next
|
||||
- bodyParser
|
||||
- cors
|
||||
- dataWrapping
|
||||
- collection2resource
|
||||
- restApiMiddleware
|
||||
|
||||
### `context`
|
||||
|
||||
@ -94,75 +109,42 @@ NocoBase 默认对 context 注入了以下成员,可以在请求处理函数
|
||||
|
||||
## 实例方法
|
||||
|
||||
### `getVersion()`
|
||||
|
||||
获取当前版本。
|
||||
|
||||
**签名**
|
||||
|
||||
* `getVersion(): string`
|
||||
|
||||
**示例**
|
||||
|
||||
```ts
|
||||
console.log(app.getVersion()); // 0.7.4-alpha.7
|
||||
```
|
||||
|
||||
### `plugin()`
|
||||
|
||||
向应用中注册插件的快捷方法,等同于 `app.pm.add()`,参考 [PluginManager](./plugin-manager#add)。
|
||||
|
||||
### `loadPluginConfig()`
|
||||
|
||||
批量注册插件与默认参数。
|
||||
|
||||
**签名**
|
||||
|
||||
* `loadPluginConfig(pluginsConfigurations: PluginConfiguration[]): void`
|
||||
|
||||
**参数**
|
||||
|
||||
| 参数名 | 类型 | 默认值 | 描述 |
|
||||
| --- | --- | --- | --- |
|
||||
| `pluginsConfigurations[]` | `string` | - | 插件的 npm 包名 |
|
||||
| `pluginsConfigurations[]` | `[string, any]` | - | 插件的 npm 包名与默认参数 |
|
||||
|
||||
### `getPlugin()`
|
||||
|
||||
获取已注册的插件实例,等同于 `app.pm.get(name)`,参考 [PluginManager](./plugin-manager#get)。
|
||||
|
||||
### `use()`
|
||||
|
||||
注册应用级中间件的快捷方法,等同于 `koa.use()`。
|
||||
注册中间件,兼容所有 [Koa 插件](https://www.npmjs.com/search?q=koa)
|
||||
|
||||
### `on()`
|
||||
|
||||
订阅应用级事件,主要与生命周期相关,等同于 `eventEmitter.on()`。所有可订阅事件参考 [事件](#事件)。
|
||||
|
||||
### `collection()`
|
||||
|
||||
向数据库注册数据表模型的快捷方法,等同于 `app.db.collection()`,参考 [Database](./database#collection)。
|
||||
|
||||
### `resource()`
|
||||
|
||||
向资源路由管理器注册资源的快捷方法,等同于 `app.resourcer.define()`,参考 [Resourcer](./resourcer#define)。
|
||||
|
||||
### `actions()`
|
||||
|
||||
向资源路由管理器注册 action 的快捷方法,等同于 `app.resourcer.registerActions()`,参考 [Resourcer](./resourcer#registerActions)。
|
||||
|
||||
### `command()`
|
||||
|
||||
向命令行工具注册命令的快捷方法,等同于 `app.cli.command()`,参考 [cli](./cli)。
|
||||
### `findCommand()`
|
||||
|
||||
### `runAsCLI()`
|
||||
|
||||
以 CLI 的方式运行。
|
||||
|
||||
### `load()`
|
||||
|
||||
应用生命周期方法,用于加载所有已注册的插件,等同于 `app.pm.load()`,参考 [PluginManager](./plugin-manager#load)。
|
||||
加载应用配置。
|
||||
|
||||
**签名**
|
||||
|
||||
* `async load(): Promise<void>`
|
||||
|
||||
### `reload()`
|
||||
|
||||
重载应用配置。
|
||||
|
||||
### `install()`
|
||||
|
||||
初始化安装应用,同步安装插件。
|
||||
|
||||
### `upgrade()`
|
||||
|
||||
升级应用,同步升级插件。
|
||||
|
||||
### `start()`
|
||||
|
||||
启动应用,如果配置了监听的端口,将启动监听,之后应用即可接受 HTTP 请求。
|
||||
@ -179,84 +161,16 @@ console.log(app.getVersion()); // 0.7.4-alpha.7
|
||||
| `options.listen.port?` | `number` | 13000 | 端口 |
|
||||
| `options.listen.host?` | `string` | `'localhost'` | 域名 |
|
||||
|
||||
**事件**
|
||||
|
||||
`start()` 调用会触发两个事件:
|
||||
|
||||
* `'beforeStart'`:在应用启动前触发。
|
||||
* `'afterStart'`:在应用启动后触发。
|
||||
|
||||
### `stop()`
|
||||
|
||||
停止应用,如果应用正在监听,将停止监听,并关闭数据库连接。
|
||||
|
||||
**签名**
|
||||
|
||||
* `async stop(options: any): Promise<void>`
|
||||
|
||||
| 参数名 | 类型 | 默认值 | 描述 |
|
||||
| --- | --- | --- | --- |
|
||||
| `options?` | `any` | - | 将透传至停止事件的参数 |
|
||||
|
||||
**事件**
|
||||
|
||||
`stop()` 调用会触发两个事件:
|
||||
|
||||
* `'beforeStop'`:在应用停止前触发。
|
||||
* `'afterStop'`:在应用停止后触发。
|
||||
停止应用,此方法会关闭数据库连接,关闭 HTTP 端口,不会删除数据。
|
||||
|
||||
### `destroy()`
|
||||
|
||||
销毁并停止应用,包含 `stop()` 的调用。
|
||||
|
||||
**事件**
|
||||
|
||||
`destroy()` 调用会触发两个事件:
|
||||
|
||||
* `'beforeDestroy'`:在应用销毁前触发。
|
||||
* `'afterDestroy'`:在应用销毁后触发。
|
||||
|
||||
插件相关的销毁事件可以基于该事件进行扩展。
|
||||
|
||||
### `install()`
|
||||
|
||||
应用初始化安装调用接口,用于安装应用的基础数据,包括:
|
||||
|
||||
* 同步已通过 `db.collection()` 和 `db.import()` 注入的数据库表结构到数据库。
|
||||
* 调用所有已注册插件实例的 `install()` 方法,执行相应安装过程。
|
||||
|
||||
**事件**
|
||||
|
||||
* `'beforeInstall'`:在应用安装前触发。
|
||||
* `'afterInstall'`:在应用安装后触发。
|
||||
|
||||
### `upgrade()`
|
||||
|
||||
应用调用接口,当更新新版本代码后通过命令行工具调用,用于执行应用的升级过程,包括:
|
||||
|
||||
* 数据库迁移工具执行。
|
||||
|
||||
**事件**
|
||||
|
||||
* `'beforeUpgrade'`:在应用升级前触发。
|
||||
* `'afterUpgrade'`:在应用升级后触发。
|
||||
删除应用,此方法会删除应用对应的数据库。
|
||||
|
||||
## 事件
|
||||
|
||||
应用生命周期会触发相应事件,扩展开发可以基于这些事件进行。
|
||||
|
||||
| 事件名称 | 是否异步 | 描述 |
|
||||
| --- | --- | --- |
|
||||
| `'beforeInstall'` | 是 | 安装前触发 |
|
||||
| `'afterInstall'` | 是 | 安装后触发 |
|
||||
| `'beforeUpgrade'` | 是 | 升级前触发 |
|
||||
| `'afterUpgrade'` | 是 | 升级后触发 |
|
||||
| `'beforeStart'` | 是 | 启动前触发 |
|
||||
| `'afterStart'` | 是 | 启动后触发 |
|
||||
| `'beforeStop'` | 是 | 停止前触发 |
|
||||
| `'afterStop'` | 是 | 停止后触发 |
|
||||
| `'beforeDestroy'` | 是 | 销毁前触发 |
|
||||
| `'afterDestroy'` | 是 | 销毁后触发 |
|
||||
|
||||
**示例**
|
||||
|
||||
@ -265,3 +179,20 @@ app.on('beforeStart', async () => {
|
||||
console.log('app before start');
|
||||
});
|
||||
```
|
||||
|
||||
### beforeLoadAll
|
||||
### afterLoadAll
|
||||
### beforeLoadPlugin
|
||||
### afterLoadPlugin
|
||||
### beforeInstallPlugin
|
||||
### afterInstallPlugin
|
||||
### beforeInstall
|
||||
### afterInstall
|
||||
### beforeUpgrade
|
||||
### afterUpgrade
|
||||
### beforeStart
|
||||
### afterStart
|
||||
### beforeStop
|
||||
### afterStop
|
||||
### beforeDestroy
|
||||
### afterDestroy
|
||||
|
@ -4,30 +4,18 @@
|
||||
|
||||
## 实例方法
|
||||
|
||||
### `create()`
|
||||
|
||||
### `add()`
|
||||
|
||||
**签名**
|
||||
### `get()`
|
||||
|
||||
* `add(pluginClass: PluginConstructor, options?: any): Plugin`
|
||||
### `install()`
|
||||
|
||||
**参数**
|
||||
### `upgrade()`
|
||||
|
||||
| 参数名 | 类型 | 默认值 | 描述 |
|
||||
| --- | --- | --- | --- |
|
||||
| `pluginClass` | `PluginConstructor` | - | 插件类,参考 [Plugin 类](./plugin) |
|
||||
### `enable()`
|
||||
|
||||
**返回值**
|
||||
### `disable()`
|
||||
|
||||
对应插件类的实例
|
||||
|
||||
**示例**
|
||||
|
||||
```ts
|
||||
import Application, { Plugin } from '@nocobase/server';
|
||||
|
||||
class MyPlugin extends Plugin {}
|
||||
|
||||
const app = new Application();
|
||||
|
||||
app.pm.add(MyPlugin, { a: 1 });
|
||||
```
|
||||
### `remove()`
|
||||
|
29
docs/zh-CN/api/server/plugin.md
Normal file
29
docs/zh-CN/api/server/plugin.md
Normal file
@ -0,0 +1,29 @@
|
||||
# Plugin
|
||||
|
||||
## 属性
|
||||
|
||||
### `name`
|
||||
|
||||
只读
|
||||
|
||||
### `options`
|
||||
|
||||
插件配置信息
|
||||
|
||||
## 实例方法
|
||||
|
||||
### `initialize()`
|
||||
|
||||
初始化
|
||||
|
||||
### `beforeLoad()`
|
||||
|
||||
加载前,如事件或类注册
|
||||
|
||||
### `load()`
|
||||
|
||||
加载配置
|
||||
|
||||
### `install()`
|
||||
|
||||
插件安装逻辑
|
@ -0,0 +1,2 @@
|
||||
# 区块
|
||||
|
@ -1 +1,128 @@
|
||||
# Collection Manager
|
||||
|
||||
```tsx
|
||||
import React from 'react';
|
||||
import { observer, ISchema, useForm } from '@formily/react';
|
||||
import {
|
||||
SchemaComponent,
|
||||
SchemaComponentProvider,
|
||||
Form,
|
||||
Action,
|
||||
CollectionProvider,
|
||||
CollectionField,
|
||||
} from '@nocobase/client';
|
||||
import 'antd/dist/antd.css';
|
||||
import { FormItem, Input } from '@formily/antd';
|
||||
|
||||
export default observer(() => {
|
||||
const collection = {
|
||||
name: 'tests',
|
||||
fields: [
|
||||
{
|
||||
type: 'string',
|
||||
name: 'title1',
|
||||
interface: 'input',
|
||||
uiSchema: {
|
||||
title: 'Title1',
|
||||
type: 'string',
|
||||
'x-component': 'Input',
|
||||
required: true,
|
||||
description: 'description1',
|
||||
} as ISchema,
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: 'title2',
|
||||
interface: 'input',
|
||||
uiSchema: {
|
||||
title: 'Title2',
|
||||
type: 'string',
|
||||
'x-component': 'Input',
|
||||
description: 'description',
|
||||
default: 'ttt',
|
||||
},
|
||||
},
|
||||
{
|
||||
type: 'string',
|
||||
name: 'title3',
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
const schema: ISchema = {
|
||||
type: 'object',
|
||||
properties: {
|
||||
form1: {
|
||||
type: 'void',
|
||||
'x-component': 'Form',
|
||||
properties: {
|
||||
// 字段 title1 直接使用全局提供的 uiSchema
|
||||
title1: {
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
default: '111',
|
||||
},
|
||||
// 等同于
|
||||
// title1: {
|
||||
// type: 'string',
|
||||
// title: 'Title',
|
||||
// required: true,
|
||||
// 'x-component': 'Input',
|
||||
// 'x-decorator': 'FormItem',
|
||||
// },
|
||||
title2: {
|
||||
'x-component': 'CollectionField',
|
||||
'x-decorator': 'FormItem',
|
||||
title: 'Title4', // 覆盖全局已定义的 Title2
|
||||
required: true, // 扩展的配置参数
|
||||
description: 'description4',
|
||||
},
|
||||
// 等同于
|
||||
// title2: {
|
||||
// type: 'string',
|
||||
// title: 'Title22',
|
||||
// required: true,
|
||||
// 'x-component': 'Input',
|
||||
// 'x-decorator': 'FormItem',
|
||||
// },
|
||||
// 字段 title3 没有提供 uiSchema,自行处理
|
||||
title3: {
|
||||
'x-component': 'Input',
|
||||
'x-decorator': 'FormItem',
|
||||
title: 'Title3',
|
||||
required: true,
|
||||
},
|
||||
action1: {
|
||||
// type: 'void',
|
||||
'x-component': 'Action',
|
||||
title: 'Submit',
|
||||
'x-component-props': {
|
||||
type: 'primary',
|
||||
useAction: '{{ useSubmit }}',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const useSubmit = () => {
|
||||
const form = useForm();
|
||||
return {
|
||||
async run() {
|
||||
form.submit(() => {
|
||||
console.log(form.values);
|
||||
});
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
return (
|
||||
<SchemaComponentProvider scope={{ useSubmit }} components={{ Action, Form, CollectionField, Input, FormItem }}>
|
||||
<CollectionProvider collection={collection}>
|
||||
<SchemaComponent schema={schema} />
|
||||
</CollectionProvider>
|
||||
</SchemaComponentProvider>
|
||||
);
|
||||
});
|
||||
```
|
BIN
docs/zh-CN/development/guide/ui-schema-designer/designable.png
Normal file
BIN
docs/zh-CN/development/guide/ui-schema-designer/designable.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.0 MiB |
@ -145,10 +145,13 @@ export default () => {
|
||||
|
||||
## 嵌套的 Schema
|
||||
|
||||
- `props.children` 嵌套,适用于 void 和 object 类型,例子见 [void 和 object 类型 schema 的嵌套](#void-和-object-类型-schema-的嵌套)
|
||||
- `<RecursionField />` 嵌套,适用于各种场景,例子见 [array 类型 schema 的嵌套](#array-类型-schema-的嵌套)
|
||||
- `props.children` 嵌套,适用于 void 和 object 类型的 properties,例子见 [void 和 object 类型 schema 的嵌套](#void-和-object-类型-schema-的嵌套)
|
||||
- `<RecursionField />` 自定义嵌套,所有类型都适用,例子见 [array 类型 schema 的嵌套](#array-类型-schema-的嵌套)
|
||||
|
||||
注意:仅 void 和 object 类型的 schema 可以与 onlyRenderProperties 使用
|
||||
注意:
|
||||
|
||||
- 除了 void 和 object 类型以外的 schema 的 `properties` 无法直接通过 `props.children` 渲染,但是可以使用 `<RecursionField />` 解决嵌套问题
|
||||
- 仅 void 和 object 类型的 schema 可以与 onlyRenderProperties 使用
|
||||
|
||||
```tsx | pure
|
||||
<RecursionField schema={schema} onlyRenderProperties />
|
||||
@ -190,7 +193,7 @@ export default () => {
|
||||
};
|
||||
```
|
||||
|
||||
各类型对比,array 和 string 并不会渲染 World 节点
|
||||
各类型 properties 渲染结果对比
|
||||
|
||||
```tsx
|
||||
import React from 'react';
|
||||
@ -204,7 +207,7 @@ const schema = {
|
||||
properties: {
|
||||
title1: {
|
||||
type: 'void',
|
||||
'x-content': 'Void schema',
|
||||
'x-content': 'Void schema,渲染 properties',
|
||||
},
|
||||
void: {
|
||||
type: 'void',
|
||||
@ -219,7 +222,7 @@ const schema = {
|
||||
},
|
||||
title2: {
|
||||
type: 'void',
|
||||
'x-content': 'Object schema',
|
||||
'x-content': 'Object schema,渲染 properties',
|
||||
},
|
||||
object: {
|
||||
type: 'object',
|
||||
@ -234,7 +237,7 @@ const schema = {
|
||||
},
|
||||
title3: {
|
||||
type: 'void',
|
||||
'x-content': 'Array schema',
|
||||
'x-content': 'Array schema,不渲染 properties',
|
||||
},
|
||||
array: {
|
||||
type: 'array',
|
||||
@ -249,7 +252,7 @@ const schema = {
|
||||
},
|
||||
title4: {
|
||||
type: 'void',
|
||||
'x-content': 'String schema',
|
||||
'x-content': 'String schema,不渲染 properties',
|
||||
},
|
||||
string: {
|
||||
type: 'string',
|
||||
|
@ -15,10 +15,10 @@ interface ISchema {
|
||||
['x-component']?: string;
|
||||
// 组件属性
|
||||
['x-component-props']?: any;
|
||||
// 组件的子节点,简单使用
|
||||
['x-content']?: any;
|
||||
// 展示状态,默认为 'visible'
|
||||
['x-display']?: 'none' | 'hidden' | 'visible';
|
||||
// 组件的子节点,简单使用
|
||||
['x-content']?: any;
|
||||
// children 节点 schema
|
||||
properties?: Record<string, ISchema>;
|
||||
|
||||
@ -27,17 +27,17 @@ interface ISchema {
|
||||
// 字段联动
|
||||
['x-reactions']?: SchemaReactions;
|
||||
// 字段 UI 交互模式,默认为 'editable'
|
||||
['x-pattern']?: 'editable' | 'disabled' | 'readOnly' | 'readPretty';
|
||||
['x-pattern']?: 'editable' | 'disabled' | 'readPretty';
|
||||
// 字段校验
|
||||
['x-validator']?: FieldValidator;
|
||||
['x-validator']?: Validator;
|
||||
// 默认数据
|
||||
default: ?:any;
|
||||
|
||||
// 设计器相关
|
||||
|
||||
// 设计器组件(工具栏)
|
||||
// 设计器组件(工具栏),包括:拖拽移动、插入新节点、修改参数、移除等
|
||||
['x-designer']?: any;
|
||||
// 初始化器组件(工具栏)
|
||||
// 初始化器组件(工具栏),决定当前 schema 内部可以插入什么
|
||||
['x-initializer']?: any;
|
||||
}
|
||||
```
|
||||
@ -266,7 +266,7 @@ const schema = {
|
||||
};
|
||||
```
|
||||
|
||||
JSX 等价于
|
||||
JSX 等同于
|
||||
|
||||
```tsx | pure
|
||||
<div className={'form-item'}>
|
||||
@ -293,7 +293,7 @@ const schema = {
|
||||
};
|
||||
```
|
||||
|
||||
JSX 等价于
|
||||
JSX 等同于
|
||||
|
||||
```tsx | pure
|
||||
<div className={'form-item'}>
|
||||
@ -320,7 +320,7 @@ const schema = {
|
||||
};
|
||||
```
|
||||
|
||||
JSX 等价于
|
||||
JSX 等同于
|
||||
|
||||
```tsx | pure
|
||||
<div className={'form-item'}>
|
||||
|
@ -6,7 +6,7 @@ import { applyMixins, AsyncEmitter } from '@nocobase/utils';
|
||||
import { Command, CommandOptions, ParseOptions } from 'commander';
|
||||
import { Server } from 'http';
|
||||
import { i18n, InitOptions } from 'i18next';
|
||||
import Koa from 'koa';
|
||||
import Koa, { DefaultContext as KoaDefaultContext, DefaultState as KoaDefaultState } from 'koa';
|
||||
import { isBoolean } from 'lodash';
|
||||
import semver from 'semver';
|
||||
import { createACL } from './acl';
|
||||
@ -35,14 +35,15 @@ export interface ApplicationOptions {
|
||||
plugins?: PluginConfiguration[];
|
||||
}
|
||||
|
||||
export interface DefaultState {
|
||||
export interface DefaultState extends KoaDefaultState {
|
||||
currentUser?: any;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
export interface DefaultContext {
|
||||
export interface DefaultContext extends KoaDefaultContext {
|
||||
db: Database;
|
||||
resourcer: Resourcer;
|
||||
i18n: any;
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
@ -198,6 +199,8 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
||||
this._resourcer = createResourcer(options);
|
||||
this._cli = new Command('nocobase').usage('[command] [options]');
|
||||
this._i18n = createI18n(options);
|
||||
this.context.db = this._db;
|
||||
this.context.resourcer = this._resourcer;
|
||||
|
||||
this._pm = new PluginManager({
|
||||
app: this,
|
||||
|
@ -2,10 +2,10 @@ import cors from '@koa/cors';
|
||||
import Database from '@nocobase/database';
|
||||
import Resourcer from '@nocobase/resourcer';
|
||||
import i18next from 'i18next';
|
||||
import { DefaultContext, DefaultState } from 'koa';
|
||||
import bodyParser from 'koa-bodyparser';
|
||||
import Application, { ApplicationOptions } from './application';
|
||||
import { dataWrapping } from './middlewares/data-wrapping';
|
||||
import { i18n } from './middlewares/i18n';
|
||||
import { table2resource } from './middlewares/table2resource';
|
||||
|
||||
export function createI18n(options: ApplicationOptions) {
|
||||
@ -46,27 +46,15 @@ export function registerMiddlewares(app: Application, options: ApplicationOption
|
||||
}),
|
||||
);
|
||||
|
||||
app.use<DefaultState, DefaultContext>(async (ctx, next) => {
|
||||
app.use(async (ctx, next) => {
|
||||
ctx.getBearerToken = () => {
|
||||
return ctx.get('Authorization').replace(/^Bearer\s+/gi, '');
|
||||
};
|
||||
ctx.db = app.db;
|
||||
ctx.resourcer = app.resourcer;
|
||||
const i18n = app.i18n.cloneInstance({ initImmediate: false });
|
||||
ctx.i18n = i18n;
|
||||
ctx.t = i18n.t.bind(i18n);
|
||||
const lng =
|
||||
ctx.get('X-Locale') ||
|
||||
(ctx.request.query.locale as string) ||
|
||||
app.i18n.language ||
|
||||
ctx.acceptsLanguages().shift() ||
|
||||
'en-US';
|
||||
if (lng !== '*' && lng) {
|
||||
i18n.changeLanguage(lng);
|
||||
}
|
||||
await next();
|
||||
});
|
||||
|
||||
app.use(i18n);
|
||||
|
||||
if (options.dataWrapping !== false) {
|
||||
app.use(dataWrapping());
|
||||
}
|
||||
|
15
packages/core/server/src/middlewares/i18n.ts
Normal file
15
packages/core/server/src/middlewares/i18n.ts
Normal file
@ -0,0 +1,15 @@
|
||||
export async function i18n(ctx, next) {
|
||||
const i18n = ctx.app.i18n.cloneInstance({ initImmediate: false });
|
||||
ctx.i18n = i18n;
|
||||
ctx.t = i18n.t.bind(i18n);
|
||||
const lng =
|
||||
ctx.get('X-Locale') ||
|
||||
(ctx.request.query.locale as string) ||
|
||||
ctx.app.i18n.language ||
|
||||
ctx.acceptsLanguages().shift() ||
|
||||
'en-US';
|
||||
if (lng !== '*' && lng) {
|
||||
i18n.changeLanguage(lng);
|
||||
}
|
||||
await next();
|
||||
}
|
Loading…
Reference in New Issue
Block a user