Merge branch 'release/1.1.0'

This commit is contained in:
JackLian 2023-02-14 09:43:26 +08:00
commit aa7287842b
757 changed files with 19846 additions and 10230 deletions

View File

@ -40,5 +40,17 @@ module.exports = {
"@typescript-eslint/no-useless-constructor": 0,
'@typescript-eslint/dot-notation': 0, // for lint performance
'@typescript-eslint/restrict-plus-operands': 0, // for lint performance
'no-unexpected-multiline': 1,
'no-multiple-empty-lines': ['error', { "max": 1 }],
'lines-around-comment': ['error', {
"beforeBlockComment": true,
"afterBlockComment": false,
"afterLineComment": false,
"allowBlockStart": true,
}],
"@typescript-eslint/member-ordering": [
"error",
{ "default": ["signature", "field", "constructor", "method"] }
],
}
};
};

6
babel.config.js Normal file
View File

@ -0,0 +1,6 @@
module.exports = {
plugins: [
['@babel/plugin-proposal-decorators', { legacy: true }],
[require.resolve('@babel/plugin-proposal-class-properties'), { loose: true }],
],
};

View File

@ -27,8 +27,8 @@ $ yarn build
1. npm run build
2. npm publish # 记得改下版本号,比如 1.0.1
# 发布完后执行 tnpm sync
3. tnpm sync
# 发布完后执行 tnpm syncOss 同步到 uipaas CDN
3. tnpm syncOss
4. 更新 diamond 版本 1.0.1
5. lowcode-engine.cn 站点生效
@ -37,10 +37,9 @@ $ yarn build
## 功能
- [x] 支持本地离线搜搜
- [x] 版本化文档管理
- [x] 版本化文档管理
- [x] 离线静态部署
- [x] 主题fork 宜搭开发者中心)
## 使用文档
https://docusaurus.io/zh-CN/docs/docs-introduction

View File

@ -33,12 +33,6 @@ module.exports = {
position: 'left',
label: 'FAQ',
},
{
type: 'doc',
docId: 'participate/index',
position: 'left',
label: '参与贡献',
},
{
type: 'doc',
docId: 'article/index',
@ -51,16 +45,6 @@ module.exports = {
position: 'left',
label: 'Demo 使用文档',
},
{
position: 'left',
href: 'https://developer.aliyun.com/ebook/7507',
label: '技术白皮书',
},
{
position: 'left',
href: 'https://github.com/alibaba/lowcode-engine/releases',
label: '更新日志',
},
{
to: '/community/issue',
position: 'left',
@ -80,6 +64,12 @@ module.exports = {
className: 'header-github-link',
'aria-label': 'GitHub repository',
},
{
type: 'doc',
docId: 'participate/index',
position: 'right',
label: '参与贡献',
},
{
type: 'search',
position: 'right',

View File

@ -22,10 +22,56 @@ module.exports = {
* 根据当前目录自动生成导航配置
*/
guide: [
{
type: 'autogenerated',
dirName: 'guide', // '.' 即当前的文档文件夹
},
[
{
type: 'category',
label: '入门',
collapsed: false,
items: getDocsFromDir('guide/quickStart'),
},
{
type: 'category',
label: '创建编辑器',
collapsed: false,
items: getDocsFromDir('guide/create'),
},
{
type: 'category',
label: '扩展编辑器',
collapsed: false,
items: getDocsFromDir('guide/expand/editor', [{ dir: 'guide/expand/editor/parts', label: 'Parts·造物' }]),
},
{
type: 'category',
label: '扩展运行时',
collapsed: false,
items: getDocsFromDir('guide/expand/runtime'),
},
{
type: 'category',
label: '设计原理',
collapsed: false,
items: getDocsFromDir('guide/design'),
},
{
type: 'category',
label: '附录',
collapsed: false,
items: [
{
type: 'link',
label: '更新日志',
href: 'https://github.com/alibaba/lowcode-engine/releases',
},
...getDocsFromDir('guide/appendix'),
],
},
{
type: 'link',
label: '技术白皮书',
href: 'https://developer.aliyun.com/ebook/7507',
},
],
],
api: [
{
@ -57,5 +103,4 @@ module.exports = {
dirName: 'demoUsage',
},
],
// api: getDocsFromDir('api'),
};

87
docs/docs/api/canvas.md Normal file
View File

@ -0,0 +1,87 @@
---
title: canvas - 画布 API
sidebar_position: 12
---
> **@types** [IPublicApiCanvas](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/canvas.ts)<br/>
> **@since** v1.1.0
## 模块简介
通过该模块可以触达对画布拖拽相关的一些能力。
## 变量
### dragon
获取拖拽操作对象的实例
`@type {IPublicModelDragon | null}`
相关类型:[IPublicModelDragon](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/dragon.ts)
### activeTracker
获取活动追踪器实例
`@type {IPublicModelActiveTracker | null}`
相关类型:[IPublicModelActiveTracker](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/active-tracker.ts)
### isInLiveEditing
是否处于 LiveEditing 状态
`@type {boolean}`
### clipboard
全局剪贴板实例
`@type {IPublicModelClipboard}`
相关类型:[IPublicModelClipboard](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/clipboard.ts)
## 方法
### createLocation
创建一个文档插入位置对象,该对象用来描述一个即将插入的节点在文档中的位置
```typescript
/**
* 创建一个文档插入位置对象,该对象用来描述一个即将插入的节点在文档中的位置
* create a drop location for document, drop location describes a location in document
* @since v1.1.0
*/
createLocation(locationData: IPublicTypeLocationData): IPublicModelDropLocation;
```
### createScroller
创建一个滚动控制器 Scroller赋予一个视图滚动的基本能力
```typescript
/**
* 创建一个滚动控制器 Scroller赋予一个视图滚动的基本能力
* a Scroller is a controller that gives a view (IPublicTypeScrollable) the ability scrolling
* to some cordination by api scrollTo.
*
* when a scroller is inited, will need to pass is a scrollable, which has a scrollTarget.
* and when scrollTo(options: { left?: number; top?: number }) is called, scroller will
* move scrollTarget`s top-left corner to (options.left, options.top) that passed in.
* @since v1.1.0
*/
createScroller(scrollable: IPublicTypeScrollable): IPublicModelScroller;
```
### createScrollTarget
创建一个 ScrollTarget与 Scroller 一起发挥作用,详见 [createScroller](#createscroller) 中的描述
```typescript
/**
* 创建一个 ScrollTarget与 Scroller 一起发挥作用,详见 createScroller 中的描述
* this works with Scroller, refer to createScroller`s description
* @since v1.1.0
*/
createScrollTarget(shell: HTMLDivElement): IPublicModelScrollTarget;
```

View File

@ -2,49 +2,126 @@
title: common - 通用 API
sidebar_position: 11
---
# 模块简介
通用模块里包含除了 9 大核心模块 API 之外的所有 API比如通用 utils、面板扩展相关 等。
> **@types** [IPublicApiCommon](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/common.ts)<br/>
> **@since** v1.0.0
## 模块简介
通用模块里包含除了几大核心模块 API 之外的所有 API比如通用 utils、面板扩展相关 等。
> 高能预警:之所以叫 skeletonCabin / designerCabin 跟兼容上一个版本的引擎有关系。若有必要,后面将用更有意义的命名空间来组织这些 API。
# 变量variables
### utils
## 变量
#### utils
通用 utils详见下方方法签名
### designerCabin
设计器扩展相关,详见下方方法签名
相关类型:[IPublicApiCommonUtils](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/common.ts)
### skeletonCabin
#### skeletonCabin
面板扩展相关,详见下方方法签名
# 方法签名functions
## utils
### isNodeSchema
## 方法
### utils
#### isNodeSchema
是否为合法的 schema 结构
### isFormEvent
```typscript
/**
* 是否为合法的 schema 结构
* check if data is valid NodeSchema
*
* @param {*} data
* @returns {boolean}
*/
isNodeSchema(data: any): boolean;
```
#### isFormEvent
是否为表单事件类型
### getNodeSchemaById
从 schema 结构中查找指定 id 节点
```typescript
/**
* 是否为表单事件类型
* check if e is a form event
* @param {(KeyboardEvent | MouseEvent)} e
* @returns {boolean}
*/
isFormEvent(e: KeyboardEvent | MouseEvent): boolean;
```
### executeTransaction
#### getNodeSchemaById
从 schema 结构中查找指定 id 节点
```typescript
/**
* 从 schema 结构中查找指定 id 节点
* get node schema from a larger schema with node id
* @param {IPublicTypeNodeSchema} schema
* @param {string} nodeId
* @returns {(IPublicTypeNodeSchema | undefined)}
*/
getNodeSchemaById(
schema: IPublicTypeNodeSchema,
nodeId: string,
): IPublicTypeNodeSchema | undefined;
```
相关类型:[IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts)
#### executeTransaction
批处理事务,用于优化特定场景的性能
*引擎版本 >= 1.0.16
```typescript
/**
* 批处理事务,用于优化特定场景的性能
* excute something in a transaction for performence
*
* @param {() => void} fn
* @param {IPublicEnumTransitionType} type
* @since v1.0.16
*/
executeTransaction(fn: () => void, type: IPublicEnumTransitionType): void;
```
**@since v1.0.16**
##### 示例
```typescript
import { common } from '@alilc/lowcode-engine';
import { TransitionType } from '@alilc/lowcode-types';
import { IPublicEnumTransitionType } from '@alilc/lowcode-types';
common.utils.startTransaction(() => {
node1.setProps();
node2.setProps();
node3.setProps();
// ...
}, TransitionType.repaint);
}, IPublicEnumTransitionType.repaint);
```
### createIntl
#### createIntl
i18n 相关工具
*引擎版本 >= 1.0.17
```typescript
/**
* i18n 相关工具
* i18n tools
*
* @param {(string | object)} instance
* @returns {{
* intlNode(id: string, params?: object): ReactNode;
* intl(id: string, params?: object): string;
* getLocale(): string;
* setLocale(locale: string): void;
* }}
* @since v1.0.17
*/
createIntl(instance: string | object): {
intlNode(id: string, params?: object): ReactNode;
intl(id: string, params?: object): string;
getLocale(): string;
setLocale(locale: string): void;
};
```
**@since v1.0.17**
##### 示例
```typescript
import { common } from '@alilc/lowcode-engine';
import enUS from './en-US.json';
@ -56,16 +133,15 @@ const { intl, getLocale, setLocale } = common.utils.createIntl({
});
```
## designerCabin
### isSettingField
是否是 SettingField 实例
### TransformStage
转换类型枚举对象,包含 init / upgrade / render 等类型,参考 [TransformStage](https://github.com/alibaba/lowcode-engine/blob/4f4ac5115d18357a7399632860808f6cffc33fad/packages/types/src/transform-stage.ts#L1)
##
## skeletonCabin
### Workbench
### skeletonCabin
#### Workbench
编辑器框架 View
# 事件events
```typescript
/**
* 编辑器框架 View
* get Workbench Component
*/
get Workbench(): Component;
```

View File

@ -2,21 +2,29 @@
title: config - 配置 API
sidebar_position: 8
---
> **@types** [IPublicModelEngineConfig](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/engine-config.ts)<br/>
> **@since** v1.0.0
## 模块简介
配置模块,负责配置的读、写等操作。
##
## 变量variables
##
## 方法签名functions
## 方法
### get
获取指定 key 的值
**类型定义**
```typescript
function get(key: string, defaultValue?: any): any
/**
* 获取指定 key 的值
* get value by key
* @param key
* @param defaultValue
* @returns
*/
get(key: string, defaultValue?: any): any;
```
**调用示例**
#### 示例
```typescript
import { config } from '@alilc/lowcode-engine';
@ -26,11 +34,16 @@ config.get('keyB', { a: 1 });
### set
设置指定 key 的值
**类型定义**
```typescript
function set(key: string, value: any)
/**
* 设置指定 key 的值
* set value for certain key
* @param key
* @param value
*/
set(key: string, value: any): void;
```
**调用示例**
#### 示例
```typescript
import { config } from '@alilc/lowcode-engine';
@ -40,40 +53,77 @@ config.set('keyC', 1);
### has
判断指定 key 是否有值
**类型定义**
```typescript
function has(key: string): boolean
/**
* 判断指定 key 是否有值
* check if config has certain key configed
* @param key
* @returns
*/
has(key: string): boolean;
```
**调用示例**
#### 示例
```typescript
import { config } from '@alilc/lowcode-engine';
config.has('keyD');
```
###
### setConfig
批量设值set 的对象版本
**类型定义**
```typescript
function setConfig(config: { [key: string]: any })
/**
* 批量设值set 的对象版本
* set multiple config key-values
* @param config
*/
setConfig(config: { [key: string]: any }): void;
```
**调用示例**
#### 示例
```typescript
import { config } from '@alilc/lowcode-engine';
config.setConfig({ keyA: false, keyB: 2 });
```
### getPreference
获取全局 Preference 管理器,用于管理全局浏览器侧用户 Preference如 Panel 是否钉住
```typescript
/**
* 获取全局 Preference, 用于管理全局浏览器侧用户 Preference如 Panel 是否钉住
* get global user preference manager, which can be use to store
* user`s preference in user localstorage, such as a panel is pinned or not.
* @returns {IPublicModelPreference}
* @since v1.1.0
*/
getPreference(): IPublicModelPreference;
```
相关类型:[IPublicModelPreference](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/preference.ts)
**@since v1.1.0**
## 事件
### onceGot
获取指定 key 的值,若此时还未赋值,则等待,若已有值,则直接返回值
注:此函数返回 Promise 实例
**类型定义**
```typescript
function onceGot(key: string): Promise<any>
/**
* 获取指定 key 的值,若此时还未赋值,则等待,若已有值,则直接返回值
* 注:此函数返回 Promise 实例只会执行fullfill一次
* wait until value of certain key is set, will only be
* triggered once.
* @param key
* @returns
*/
onceGot(key: string): Promise<any>;
```
**调用示例**
#### 示例
```typescript
import { config } from '@alilc/lowcode-engine';
@ -88,11 +138,18 @@ const value = await config.onceGot('keyA');
### onGot
获取指定 key 的值,函数回调模式,若多次被赋值,回调会被多次调用
**类型定义**
```typescript
function onGot(key: string, fn: (data: any) => void): () => void
/**
* 获取指定 key 的值,函数回调模式,若多次被赋值,回调会被多次调用
* set callback for event of value set for some key
* this will be called each time the value is set
* @param key
* @param fn
* @returns
*/
onGot(key: string, fn: (data: any) => void): () => void;
```
**调用示例**
#### 示例
```typescript
import { config } from '@alilc/lowcode-engine';
@ -102,6 +159,4 @@ config.onGot('keyA', (value) => {
const.set('keyA', 1); // 'The value of keyA is 1'
const.set('keyA', 2); // 'The value of keyA is 2'
```
## 事件events
```

View File

@ -2,41 +2,63 @@
title: event - 事件 API
sidebar_position: 7
---
> **@types** [IPublicApiEvent](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/event.ts)<br/>
> **@since** v1.0.0
## 模块简介
负责事件处理 API支持自定义监听事件、触发事件。
## 方法签名functions
## 方法
### on
监听事件
**类型定义**
```typescript
function on(event: string, listener: (...args: unknown[]) => void): void;
/**
* 监听事件
* add monitor to a event
* @param event 事件名称
* @param listener 事件回调
*/
on(event: string, listener: (...args: any[]) => void): IPublicTypeDisposable;
```
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
### off
取消监听事件
**类型定义**
```typescript
function off(event: string, listener: (...args: unknown[]) => void): void;
/**
* 取消监听事件
* cancel a monitor from a event
* @param event 事件名称
* @param listener 事件回调
*/
off(event: string, listener: (...args: any[]) => void): void;
```
### emit
触发事件
**类型定义**
```typescript
function emit(event: string, ...args: unknown[]): void;
/**
* 取消监听事件
* cancel a monitor from a event
* @param event 事件名称
* @param listener 事件回调
*/
off(event: string, listener: (...args: any[]) => void): void;
```
## 使用示例
### 事件触发和监听
```typescript
const eventName = 'eventName';
// 事件监听
// 插件中发出的事件,默认以 `common` 为前缀,监听时需要注意下
event.on(`common:${eventName}`);
// 触发事件

View File

@ -2,29 +2,36 @@
title: hotkey - 快捷键 API
sidebar_position: 5
---
> **@types** [IPublicApiHotkey](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/hotkey.ts)<br/>
> **@since** v1.0.0
## 模块简介
绑定快捷键 API可以自定义项目快捷键使用。
## 方法签名functions
## 方法
### bind
绑定快捷键
**类型定义**
```typescript
function bind(
combos: string[] | string,
callback: (e: KeyboardEvent, combo?: string) => any | false,
action?: string
): () => void;
/**
* 绑定快捷键
* bind hotkey/hotkeys,
* @param combos 快捷键,格式如:['command + s'] 、['ctrl + shift + s'] 等
* @param callback 回调函数
* @param action
* @returns
*/
bind(
combos: string[] | string,
callback: IPublicTypeHotkeyCallback,
action?: string,
): IPublicTypeDisposable;
```
相关 types
- [IPublicTypeHotkeyCallback](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/hotkey-callback.ts)
- [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
**示例**
```typescript
hotkey.bind('command+s', (e) => {
e.preventDefault();
// command+s 快捷键按下时需要执行的逻辑
});
```
## 使用示例
### 基础示例
@ -53,7 +60,7 @@ function saveSchema(schema) {
// 保存 schema 相关操作
}
const saveSampleHotKey = (ctx: ILowCodePluginContext) => {
const saveSampleHotKey = (ctx: IPublicModelPluginContext) => {
return {
name: 'saveSample',
async init() {

View File

@ -5,7 +5,7 @@ sidebar_position: 0
引擎提供的公开 API 分为`命名空间``模型`两类,其中`命名空间`用于聚合一大类的 API`模型`为各 API 涉及到的对象模型。
### 命名空间
## 命名空间
引擎直接提供以下几大类 API
@ -21,7 +21,7 @@ sidebar_position: 0
- logger 日志 API
- init 初始化 API
### 模型
## 模型
以下模型通过前面的 API 以返回值等形式间接透出。
- document-model 文档
@ -37,10 +37,14 @@ sidebar_position: 0
- history 操作历史
### API 设计约定
## API 设计约定
一些 API 设计约定:
1. 所有 API 命名空间都按照 variables / functions / events 来组织
2. 事件events的命名格式为on[Will|Did]VerbNoun?,参考 [https://code.visualstudio.com/api/references/vscode-api#events](https://code.visualstudio.com/api/references/vscode-api#events)
3. 基于 Disposable 模式,对于事件的绑定、快捷键的绑定函数,返回值则是解绑函数
4. 对于属性的导出,统一用 .xxx 的 getter 模式,(尽量)不使用 .getXxx()
## experimental
说明此模块处于公测阶段, API 可能会发生改变.

View File

@ -2,20 +2,25 @@
title: init - 初始化 API
sidebar_position: 10
---
> **@since** v1.0.0
## 模块简介
提供 init 等方法
## 方法签名
## 方法
#### 1. init
初始化引擎
**方法定义**
```typescript
function init(container?: Element, options?: EngineOptions): void
function init(container?: Element, options?: IPublicTypeEngineOptions): void
```
**初始化引擎的参数**
```typescript
interface EngineOptions {
interface IPublicTypeEngineOptions {
/**
* 指定初始化的 device
*/
@ -102,6 +107,9 @@ interface EngineOptions {
[key: string]: any;
}
```
> 源码详见 [IPublicTypeEngineOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/engine-options.ts)
## 使用示例
```typescript
import { init } from '@alilc/lowcode-engine';

View File

@ -2,48 +2,79 @@
title: logger - 日志 API
sidebar_position: 9
---
## 模块简介
引擎日志模块,可以按照 **日志级别 **和** 业务类型 **两个维度来定制日志,基于 [zen-logger](https://web.npm.alibaba-inc.com/package/zen-logger) 封装。
> 注:日志级别可以通过 url query 动态调整,详见下方使用示例。
## 变量variables
## 方法签名functions
### log / warn / error / info / debug
> **@types** [IPublicApiLogger](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/logger.ts)<br/>
> **@since** v1.0.0
## 模块简介
引擎日志模块,可以按照 **日志级别 **和** 业务类型 **两个维度来定制日志。
> 注:日志级别可以通过 url query 动态调整,详见下方[查看示例](#查看示例)。<br/>
> 参考 [zen-logger](https://web.npm.alibaba-inc.com/package/zen-logger) 实现进行封装
## 方法
日志记录方法
**类型定义**
```typescript
function log(args: any[]): void
function warn(args: any[]): void
function error(args: any[]): void
function info(args: any[]): void
function debug(args: any[]): void
```
**调用示例**
```typescript
import { logger } from '@alilc/lowcode-engine';
/**
* debug info
*/
debug(...args: any | any[]): void;
/**
* normal info output
*/
info(...args: any | any[]): void;
/**
* warning info output
*/
warn(...args: any | any[]): void;
/**
* error info output
*/
error(...args: any | any[]): void;
/**
* log info output
*/
log(...args: any | any[]): void;
```
## 输出示例
```typescript
import { Logger } from '@alilc/lowcode-utils';
const logger = new Logger({ level: 'warn', bizName: 'myPlugin:moduleA' });
logger.log('Awesome Low-Code Engine');
```
## 事件events
## 使用示例
```typescript
import { logger } from '@alilc/lowcode-engine';
## 查看示例
// 内部实现logger = getLogger({ level: 'warn', bizName: 'designer:pluginManager' })
开启查看方式:
// 若在 url query 中增加 `__logConf__` 可改变打印日志级别和限定业务类型日志
// 默认__logConf__=warn:*
logger.log('log'); // 不输出
logger.warn('warn'); // 输出
logger.error('error'); // 输出
// 比如__logConf__=log:designer:pluginManager
logger.log('log'); // 输出
logger.warn('warn'); // 输出
logger.error('error'); // 输出
- 方式 1所有 logger 创建时会有默认输出的 level, 默认为 warn , 即只展示 warn , error
- 方式 2url 上追加 __logConf__进行开启示例如下
```
https://lowcode-engine.cn/demo/demo-general/index.html?__logConf__=warn
// 开启所有 bizName的 warn 和 error
https://lowcode-engine.cn/demo/demo-general/index.html?__logConf__=debug
// 开启所有 bizName的 debug, log, info, warn 和 error
https://lowcode-engine.cn/demo/demo-general/index.html?__logConf__=log
// 开启所有 bizName的 log, info, warn 和 error
https://lowcode-engine.cn/demo/demo-general/index.html?__logConf__=warn|*
// 同 __logConf__=warn
https://lowcode-engine.cn/demo/demo-general/index.html?__logConf__=warn|bizName
// 开启 bizName 的 debug, log, info, warn 和 error
https://lowcode-engine.cn/demo/demo-general/index.html?__logConf__=warn|partOfBizName
// 开启 bizName like '%partOfBizName%' 的 debug, log, info, warn 和 error
```

View File

@ -2,24 +2,44 @@
title: material - 物料 API
sidebar_position: 2
---
# 模块简介
> **@types** [IPublicApiMaterial](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/material.ts)<br/>
> **@since** v1.0.0
## 模块简介
负责物料相关的 API包括资产包、设计器辅助层、物料元数据和物料元数据管道函数。
# 变量variables
## componentsMap
## 变量
### componentsMap
获取组件 map 结构
```typescript
/**
* 获取组件 map 结构
* get map of components
*/
get componentsMap(): { [key: string]: IPublicTypeNpmInfo | ComponentType<any> | object } ;
```
相关类型:[IPublicTypeNpmInfo](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/npm-info.ts)
# 方法签名functions
## 资产包
### setAssets
## 方法
### 资产包
#### setAssets
设置「[资产包](/site/docs/specs/lowcode-spec#2-协议结构)」结构
**类型定义**
```typescript
function setAssets(assets: AssetsJson): void;
/**
* 设置「资产包」结构
* set data for Assets
* @returns void
*/
setAssets(assets: IPublicTypeAssetsJson): void;
```
相关类型:[IPublicTypeAssetsJson](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/assets-json.ts)
**示例**
##### 示例
直接在项目中引用 npm 包
```javascript
import { material } from '@alilc/lowcode-engine';
@ -28,53 +48,65 @@ import assets from '@alilc/mc-assets-<siteId>/assets.json';
material.setAssets(assets);
```
通过物料中心接口动态引入资产包
通过接口动态引入资产包
```typescript
import { ILowCodePluginContext, material, plugins } from '@alilc/lowcode-engine'
import { material, plugins } from '@alilc/lowcode-engine';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
// 动态加载 assets
plugins.register((ctx: ILowCodePluginContext) => {
plugins.register((ctx: IPublicModelPluginContext) => {
return {
name: 'ext-assets',
async init() {
try {
// 将下述链接替换为您的物料即可。无论是通过 utils 从物料中心引入,还是通过其他途径如直接引入物料描述
const res = await window.fetch('https://fusion.alicdn.com/assets/default@0.1.95/assets.json')
const assets = await res.text()
material.setAssets(assets)
// 将下述链接替换为您的物料描述地址即可。
const res = await window.fetch('https://fusion.alicdn.com/assets/default@0.1.95/assets.json');
const assets = await res.text();
material.setAssets(assets);
} catch (err) {
console.error(err)
}
console.error(err);
};
},
}
}).catch(err => console.error(err))
};
}).catch(err => console.error(err));
```
### getAssets
#### getAssets
获取「资产包」结构
**类型定义**
```typescript
function getAssets(): AssetsJson;
/**
* 获取「资产包」结构
* get AssetsJson data
* @returns IPublicTypeAssetsJson
*/
getAssets(): IPublicTypeAssetsJson;
```
相关类型:[IPublicTypeAssetsJson](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/assets-json.ts)
**示例**
##### 示例
```typescript
import { material } from '@alilc/lowcode-engine';
material.getAssets();
```
### loadIncrementalAssets
#### loadIncrementalAssets
加载增量的「资产包」结构,该增量包会与原有的合并
**类型定义**
```typescript
function loadIncrementalAssets(incrementalAssets: AssetsJson): void;
/**
* 加载增量的「资产包」结构,该增量包会与原有的合并
* load Assets incrementally, and will merge this with exiting assets
* @param incrementalAssets
* @returns
*/
loadIncrementalAssets(incrementalAssets: IPublicTypeAssetsJson): void;
```
说明:**该增量包会与原有的合并**
相关类型:[IPublicTypeAssetsJson](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/assets-json.ts)
**示例**
##### 示例
```typescript
import { material } from '@alilc/lowcode-engine';
import assets1 from '@alilc/mc-assets-<siteId>/assets.json';
@ -83,57 +115,23 @@ import assets2 from '@alilc/mc-assets-<siteId>/assets.json';
material.setAssets(assets1);
material.loadIncrementalAssets(assets2);
```
## 设计器辅助层
### addBuiltinComponentAction
### 设计器辅助层
#### addBuiltinComponentAction
在设计器辅助层增加一个扩展 action
**类型定义**
```typescript
function addBuiltinComponentAction(action: ComponentAction): void;
export interface ComponentAction {
/**
* behaviorName
*/
name: string;
/**
* 菜单名称
*/
content: string | ReactNode | ActionContentObject;
/**
* 子集
*/
items?: ComponentAction[];
/**
* 显示与否
* always: 无法禁用
*/
condition?: boolean | ((currentNode: any) => boolean) | 'always';
/**
* 显示在工具条上
*/
important?: boolean;
}
export interface ActionContentObject {
/**
* 图标
*/
icon?: IconType;
/**
* 描述
*/
title?: TipContent;
/**
* 执行动作
*/
action?: (currentNode: any) => void;
}
export type IconType = string | ReactElement | ComponentType<any> | IconConfig;
/**
* 在设计器辅助层增加一个扩展 action
* add an action button in canvas context menu area
* @param action
*/
addBuiltinComponentAction(action: IPublicTypeComponentAction): void;
```
相关类型:[IPublicTypeComponentAction](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/component-action.ts)
**示例**
##### 示例
新增设计扩展位,并绑定事件
```typescript
import { material } from '@alilc/lowcode-engine';
@ -153,14 +151,27 @@ material.addBuiltinComponentAction({
```
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01jDbN7B1KfWVzJ16tw_!!6000000001191-2-tps-230-198.png)
### removeBuiltinComponentAction
#### removeBuiltinComponentAction
移除设计器辅助层的指定 action
**类型定义**
```typescript
function removeBuiltinComponentAction(name: string): void;
/**
* 移除设计器辅助层的指定 action
* remove a builtin action button from canvas context menu area
* @param name
*/
removeBuiltinComponentAction(name: string): void;
```
**示例**
##### 内置设计器辅助 name
- remove删除
- hide隐藏
- copy复制
- lock锁定不可编辑
- unlock解锁可编辑
##### 示例
```typescript
import { material } from '@alilc/lowcode-engine';
@ -168,16 +179,25 @@ material.removeBuiltinComponentAction('myIconName');
```
### modifyBuiltinComponentAction
#### modifyBuiltinComponentAction
修改已有的设计器辅助层的指定 action
**类型定义**
```typescript
function modifyBuiltinComponentAction(
actionName: string,
handle: (action: ComponentAction) => void
): void;
/**
* 修改已有的设计器辅助层的指定 action
* modify a builtin action button in canvas context menu area
* @param actionName
* @param handle
*/
modifyBuiltinComponentAction(
actionName: string,
handle: (action: IPublicTypeComponentAction) => void,
): void;
```
**内置设计器辅助 name**
相关类型:[IPublicTypeComponentAction](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/component-action.ts)
##### 内置设计器辅助 name
- remove删除
- hide隐藏
@ -187,7 +207,7 @@ function modifyBuiltinComponentAction(
**示例**
##### 示例
给原始的 remove 扩展时间添加执行前后的日志
```typescript
import { material } from '@alilc/lowcode-engine';
@ -201,30 +221,43 @@ material.modifyBuiltinComponentAction('remove', (action) => {
}
});
```
###
## 物料元数据
### getComponentMeta
获取指定名称的物料元数据
**类型定义**
```typescript
function getComponentMeta(componentName: string): ComponentMeta;
```
**示例**
### 物料元数据
#### getComponentMeta
获取指定名称的物料元数据
```typescript
/**
* 获取指定名称的物料元数据
* get component meta by component name
* @param componentName
* @returns
*/
getComponentMeta(componentName: string): IPublicModelComponentMeta | null;
```
相关类型:[IPublicModelComponentMeta](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/component-meta.ts)
##### 示例
```typescript
import { material } from '@alilc/lowcode-engine';
material.getComponentMeta('Input');
```
### getComponentMetasMap
#### getComponentMetasMap
获取所有已注册的物料元数据
**类型定义**
```typescript
function getComponentMetasMap(): new Map<string, ComponentMeta>;
```
**示例**
```typescript
/**
* 获取所有已注册的物料元数据
* get map of all component metas
* @returns
*/
getComponentMetasMap(): Map<string, IPublicModelComponentMeta>;
```
相关类型:[IPublicModelComponentMeta](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/component-meta.ts)
##### 示例
```typescript
import { material } from '@alilc/lowcode-engine';
@ -232,19 +265,27 @@ material.getComponentMetasMap();
```
## 物料元数据管道函数
### registerMetadataTransducer
### 物料元数据管道函数
#### registerMetadataTransducer
注册物料元数据管道函数,在物料信息初始化时执行。
**类型定义**
```typescript
function registerMetadataTransducer(
transducer: MetadataTransducer, // 管道函数
level?: number, // 优先级
id?: string | undefined, // id
/**
* 注册物料元数据管道函数,在物料信息初始化时执行。
* register transducer to process component meta, which will be
* excuted during component meta`s initialization
* @param transducer
* @param level
* @param id
*/
registerMetadataTransducer(
transducer: IPublicTypeMetadataTransducer,
level?: number,
id?: string | undefined
): void;
```
**示例**
##### 示例
给每一个组件的配置添加高级配置面板,其中有一个是否渲染配置项
```typescript
import { material } from '@alilc/lowcode-engine'
@ -289,28 +330,40 @@ function addonCombine(metadata: TransformedComponentMetadata) {
material.registerMetadataTransducer(addonCombine, 1, 'parse-func');
```
### getRegisteredMetadataTransducers
#### getRegisteredMetadataTransducers
获取所有物料元数据管道函数
**类型定义**
```typescript
function getRegisteredMetadataTransducers(): MetadataTransducer[];
/**
* 获取所有物料元数据管道函数
* get all registered metadata transducers
* @returns {IPublicTypeMetadataTransducer[]}
*/
getRegisteredMetadataTransducers(): IPublicTypeMetadataTransducer[];
```
**示例**
##### 示例
```typescript
import { material } from '@alilc/lowcode-engine'
material.getRegisteredMetadataTransducers('parse-func');
material.getRegisteredMetadataTransducers();
```
##
# 事件Event
## 事件
### onChangeAssets
监听 assets 变化的事件
**类型定义**
```typescript
function onChangeAssets(fn: () => void): void;
/**
* 监听 assets 变化的事件
* add callback for assets changed event
* @param fn
*/
onChangeAssets(fn: () => void): IPublicTypeDisposable;
```
**示例**
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
##### 示例
```typescript
import { material } from '@alilc/lowcode-engine';

View File

@ -0,0 +1,6 @@
{
"label": "模型定义 Models",
"position": 14,
"collapsed": false,
"collapsible": true
}

View File

@ -0,0 +1,43 @@
---
title: Clipboard
sidebar_position: 14
---
> **@types** [IPublicModelClipboard](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/clipboard.ts)<br/>
> **@since** v1.1.0
## 方法
### setData
给剪贴板赋值
```typescript
/**
* 给剪贴板赋值
* set data to clipboard
*
* @param {*} data
* @since v1.1.0
*/
setData(data: any): void;
```
### waitPasteData
设置剪贴板数据设置的回调
```typescript
/**
* 设置剪贴板数据设置的回调
* set callback for clipboard provide paste data
*
* @param {KeyboardEvent} keyboardEvent
* @param {(data: any, clipboardEvent: ClipboardEvent) => void} cb
* @since v1.1.0
*/
waitPasteData(
keyboardEvent: KeyboardEvent,
cb: (data: any, clipboardEvent: ClipboardEvent) => void,
): void;
```

View File

@ -0,0 +1,173 @@
---
title: ComponentMeta
sidebar_position: 15
---
> **@types** [IPublicModelComponentMeta](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/component-meta.ts)<br/>
> **@since** v1.0.0
## 基本介绍
组件元数据信息模型
## 属性
### componentName
组件名
`@type {string}`
### isContainer
是否是「容器型」组件
`@type {boolean}`
### isMinimalRenderUnit
是否是最小渲染单元
当组件需要重新渲染时:
- 若为最小渲染单元,则只渲染当前组件,
- 若不为最小渲染单元,则寻找到上层最近的最小渲染单元进行重新渲染,直至根节点。
`@type {boolean}`
### isModal
是否为「模态框」组件
`@type {boolean}`
### configure
获取用于设置面板显示用的配置
`@type {IPublicTypeFieldConfig[]}`
相关类型:[IPublicTypeFieldConfig](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/field-config.ts)
### title
标题
`@type {string | IPublicTypeI18nData | ReactElement}`
相关类型:[IPublicTypeI18nData](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/i18n-data.ts)
### icon
图标
`@type {IPublicTypeIconType}`
相关类型:[IPublicTypeIconType](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/icon-type.ts)
### npm
组件 npm 信息
`@type {IPublicTypeNpmInfo}`
相关类型:[IPublicTypeNpmInfo](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/npm-info.ts)
### availableActions
获取元数据
`@type {IPublicTypeTransformedComponentMetadata}`
相关类型:[IPublicTypeTransformedComponentMetadata](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/transformed-component-metadata.ts)
### advanced
组件元数据中高级配置部分
`@type {IPublicTypeAdvanced}`
相关类型:[IPublicTypeAdvanced](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/advanced.ts)
## 方法
### setNpm
设置 npm 信息
```typescript
/**
* 设置 npm 信息
* set method for npm inforamtion
* @param npm
*/
setNpm(npm: IPublicTypeNpmInfo): void;
```
相关类型:[IPublicTypeNpmInfo](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/npm-info.ts)
### getMetadata
获取元数据
```typescript
/**
* 获取元数据
* get component metadata
*/
getMetadata(): IPublicTypeTransformedComponentMetadata;
```
相关类型:[IPublicTypeTransformedComponentMetadata](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/transformed-component-metadata.ts)
### checkNestingUp
检测当前对应节点是否可被放置在父节点中
```typescript
/**
* 检测当前对应节点是否可被放置在父节点中
* check if the current node could be placed in parent node
* @param my 当前节点
* @param parent 父节点
*/
checkNestingUp(my: IPublicModelNode | IPublicTypeNodeData, parent: any): boolean;
```
相关类型:
- [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
- [IPublicTypeNodeData](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-data.ts)
### checkNestingDown
检测目标节点是否可被放置在父节点中
```typescript
/**
* 检测目标节点是否可被放置在父节点中
* check if the target node(s) could be placed in current node
* @param my 当前节点
* @param parent 父节点
*/
checkNestingDown(
my: IPublicModelNode | IPublicTypeNodeData,
target: IPublicTypeNodeSchema | IPublicModelNode | IPublicTypeNodeSchema[],
): boolean;
```
相关类型:
- [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
- [IPublicTypeNodeData](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-data.ts)
- [IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts)
### refreshMetadata
刷新元数据,会触发元数据的重新解析和刷新
```typescript
/**
* 刷新元数据,会触发元数据的重新解析和刷新
* refresh metadata
*/
refreshMetadata(): void;
```

View File

@ -0,0 +1,87 @@
---
title: Detecting
sidebar_position: 6
---
> **@types** [IPublicModelDetecting](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/detecting.ts)<br/>
> **@since** v1.0.0
## 基本介绍
画布节点悬停模型
## 属性
### current
当前 hover 的节点
`@type {IPublicModelNode | null}`
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
**@since v1.0.16**
### enable
是否启用
`@type {boolean}`
## 方法
### capture
hover 指定节点
```typescript
/**
* hover 指定节点
* capture node with nodeId
* @param id 节点 id
*/
capture(id: string): void;
```
### release
hover 离开指定节点
```typescript
/**
* hover 离开指定节点
* release node with nodeId
* @param id 节点 id
*/
release(id: string): void;
```
### leave
清空 hover 态
```typescript
/**
* 清空 hover 态
* clear all hover state
*/
leave(): void;
```
## 事件
### onDetectingChange
hover 节点变化事件
```typescript
/**
* hover 节点变化事件
* set callback which will be called when hovering object changed.
* @since v1.1.0
*/
onDetectingChange(fn: (node: IPublicModelNode | null) => void): IPublicTypeDisposable;
```
相关类型:
- [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
- [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
**@since v1.1.0**

View File

@ -0,0 +1,406 @@
---
title: DocumentModel
sidebar_position: 0
---
> **@types** [IPublicModelDocumentModel](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/document-model.ts)<br/>
> **@since** v1.0.0
## 基本介绍
文档模型
## 属性
### id
唯一 ID
`@type {string}`
### selection
画布节点选中区模型实例
`@type {IPublicModelSelection}`
相关章节:[节点选中区模型](./selection)
相关类型:[IPublicModelSelection](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/selection.ts)
### detecting
画布节点 hover 区模型实例
`@type {IPublicModelDetecting}`
相关章节:[画布节点悬停模型](./detecting)
相关类型:[IPublicModelDetecting](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/detecting.ts)
### history
操作历史模型实例
`@type {IPublicModelHistory}`
相关章节:[操作历史模型](./history)
相关类型:[IPublicModelHistory](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/history.ts)
### project
获取当前文档模型所属的 project
`@type {IPublicApiProject}`
相关类型:[IPublicApiProject](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/project.ts)
### root
获取文档的根节点
`@type {IPublicModelNode | null}`
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### nodesMap
获取文档下所有节点 Map, key 为 nodeId
`@type {Map<string, IPublicModelNode>} `
相关章节:[节点模型](./node)
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### modalNodesManager
模态节点管理器
`@type {IPublicModelModalNodesManager | null}`
相关章节:[模态节点管理](./modal-nodes-manager)
相关类型:[IPublicModelModalNodesManager](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/modal-nodes-manager.ts)
### dropLocation
文档的 dropLocation
`@type {IPublicModelDropLocation | null}`
相关类型:[IPublicModelDropLocation](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/drop-location.ts)
**@since v1.1.0**
## 方法
### getNodeById
根据 nodeId 返回 [Node](./node) 实例
```typescript
/**
* 根据 nodeId 返回 Node 实例
* get node by nodeId
* @param nodeId
* @returns
*/
getNodeById(nodeId: string): IPublicModelNode | null;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### importSchema
导入 schema
```typescript
/**
* 导入 schema
* import schema data
* @param schema
*/
importSchema(schema: IPublicTypeRootSchema): void;
```
相关类型:[IPublicTypeRootSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/root-schema.ts)
### exportSchema
导出 schema
```typescript
/**
* 导出 schema
* export schema
* @param stage
* @returns
*/
exportSchema(stage: IPublicEnumTransformStage): any;
```
相关类型:[IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts)
### insertNode
插入节点
```typescript
/**
* 插入节点
* insert a node
*/
insertNode(
parent: IPublicModelNode,
thing: IPublicModelNode,
at?: number | null | undefined,
copy?: boolean | undefined
): IPublicModelNode | null;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### createNode
创建一个节点
```typescript
/**
* 创建一个节点
* create a node
* @param data
* @returns
*/
createNode(data: any): IPublicModelNode | null;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### removeNode
移除指定节点/节点id
```typescript
/**
* 移除指定节点/节点id
* remove a node by node instance or nodeId
* @param idOrNode
*/
removeNode(idOrNode: string | IPublicModelNode): void;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### checkNesting
检查拖拽放置的目标节点是否可以放置该拖拽对象
```typescript
/**
* 检查拖拽放置的目标节点是否可以放置该拖拽对象
* check if dragOjbect can be put in this dragTarget
* @param dropTarget 拖拽放置的目标节点
* @param dragObject 拖拽的对象
* @returns boolean 是否可以放置
* @since v1.0.16
*/
checkNesting(
dropTarget: IPublicModelNode,
dragObject: IPublicTypeDragNodeObject | IPublicTypeDragNodeDataObject
): boolean;
```
相关类型:
- [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
- [IPublicTypeDragNodeObject](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/drag-node-object.ts)
- [IPublicTypeDragNodeDataObject](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/drag-node-object-data.ts)
**@since v1.0.16**
### isDetectingNode
检查拖拽放置的目标节点是否可以放置该拖拽对象
```typescript
/**
* 判断是否当前节点处于被探测状态
* check is node being detected
* @param node
* @since v1.1.0
*/
isDetectingNode(node: IPublicModelNode): boolean;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
**@since v1.1.0**
## 事件
### onAddNode
当前 document 新增节点事件
```typescript
/**
* 当前 document 新增节点事件
* set callback for event on node is created for a document
*/
onAddNode(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable;
```
相关类型:
- [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
- [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
### onMountNode
当前 document 新增节点事件,此时节点已经挂载到 document 上
```typescript
/**
* 当前 document 新增节点事件,此时节点已经挂载到 document 上
* set callback for event on node is mounted to canvas
*/
onMountNode(fn: (payload: { node: IPublicModelNode }) => void): IPublicTypeDisposable;
```
相关类型:
- [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
- [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
### onRemoveNode
当前 document 删除节点事件
```typescript
/**
* 当前 document 删除节点事件
* set callback for event on node is removed
*/
onRemoveNode(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable;
```
相关类型:
- [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
- [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
### onChangeDetecting
当前 document 的 hover 变更事件
```typescript
/**
* 当前 document 的 hover 变更事件
*
* set callback for event on detecting changed
*/
onChangeDetecting(fn: (node: IPublicModelNode) => void): IPublicTypeDisposable;
```
相关类型:
- [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
- [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
### onChangeSelection
当前 document 的选中变更事件
```typescript
/**
* 当前 document 的选中变更事件
* set callback for event on selection changed
*/
onChangeSelection(fn: (ids: string[]) => void): IPublicTypeDisposable;
```
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
### onChangeNodeVisible
当前 document 的节点显隐状态变更事件
```typescript
/**
* 当前 document 的节点显隐状态变更事件
* set callback for event on visibility changed for certain node
* @param fn
*/
onChangeNodeVisible(fn: (node: IPublicModelNode, visible: boolean) => void): IPublicTypeDisposable;
```
- 相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
- 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
### onChangeNodeChildren
当前 document 的节点 children 变更事件
```typescript
onChangeNodeChildren(fn: (info?: IPublicTypeOnChangeOptions) => void): IPublicTypeDisposable;
```
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
### onChangeNodeProp
当前 document 节点属性修改事件
```typescript
onChangeNodeProp(fn: (info: IPublicTypePropChangeOptions) => void): IPublicTypeDisposable;
```
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
### onImportSchema
当前 document 导入新的 schema 事件
```typescript
/**
* import schema event
* @param fn
* @since v1.0.15
*/
onImportSchema(fn: (schema: IPublicTypeRootSchema) => void): IPublicTypeDisposable;
```
相关类型:
- [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
- [IPublicTypeRootSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/root-schema.ts)
**@since v1.0.15**
### onFocusNodeChanged
设置聚焦节点变化的回调
```typescript
/**
* 设置聚焦节点变化的回调
* triggered focused node is set mannually from plugin
* @param fn
* @since v1.1.0
*/
onFocusNodeChanged(
fn: (doc: IPublicModelDocumentModel, focusNode: IPublicModelNode) => void,
): IPublicTypeDisposable;
```
相关类型:
- [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
- [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
**@since v1.1.0**
### onDropLocationChanged
设置 DropLocation 变化的回调
```typescript
/**
* 设置 DropLocation 变化的回调
* triggered when drop location changed
* @param fn
* @since v1.1.0
*/
onDropLocationChanged(fn: (doc: IPublicModelDocumentModel) => void): IPublicTypeDisposable;
```
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
**@since v1.1.0**

View File

@ -0,0 +1,129 @@
---
title: Dragon
sidebar_position: 99
---
> **@types** [IPublicModelDragon](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/dragon.ts)<br/>
> **@since** v1.0.0
## 基本介绍
拖拽对象
### 对应接口
```typescript
import { IPublicModelDragon } from '@alilc/lowcode-types';
```
### 支持版本
**@since** v1.1.0
## 属性
### dragging
是否正在拖动
```typescript
/**
* is dragging or not
*/
get dragging(): boolean;
```
## 方法
### onDragstart
绑定 dragstart 事件
```typescript
/**
* 绑定 dragstart 事件
* bind a callback function which will be called on dragging start
* @param func
* @returns
*/
onDragstart(func: (e: IPublicModelLocateEvent) => any): () => void;
```
### onDrag
绑定 drag 事件
```typescript
/**
* 绑定 drag 事件
* bind a callback function which will be called on dragging
* @param func
* @returns
*/
onDrag(func: (e: IPublicModelLocateEvent) => any): () => void;
```
### onDragend
绑定 dragend 事件
```typescript
/**
* 绑定 dragend 事件
* bind a callback function which will be called on dragging end
* @param func
* @returns
*/
onDragend(func: (o: { dragObject: IPublicModelDragObject; copy?: boolean }) => any): () => void;
```
### from
设置拖拽监听的区域 shell以及自定义拖拽转换函数 boost
```typescript
/**
* 设置拖拽监听的区域 shell以及自定义拖拽转换函数 boost
* set a html element as shell to dragon as monitoring target, and
* set boost function which is used to transform a MouseEvent to type
* IPublicTypeDragNodeDataObject.
* @param shell 拖拽监听的区域
* @param boost 拖拽转换函数
*/
from(shell: Element, boost: (e: MouseEvent) => IPublicTypeDragNodeDataObject | null): any;
```
### boost
发射拖拽对象
```typescript
/**
* 发射拖拽对象
* boost your dragObject for dragging(flying)
*
* @param dragObject 拖拽对象
* @param boostEvent 拖拽初始时事件
*/
boost(dragObject: IPublicTypeDragObject, boostEvent: MouseEvent | DragEvent, fromRglNode?: Node | IPublicModelNode): void;
```
### addSensor
添加投放感应区
```typescript
/**
* 添加投放感应区
* add sensor area
*/
addSensor(sensor: any): void;
```
### removeSensor
移除投放感应
```typescript
/**
* 移除投放感应
* remove sensor area
*/
removeSensor(sensor: any): void;
```

View File

@ -0,0 +1,54 @@
---
title: DropLocation
sidebar_position: 13
---
> **@types** [IPublicModelDropLocation](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/drop-location.ts)<br/>
> **@since** v1.1.0
## 基本介绍
拖拽放置位置模型
## 属性
### target
拖拽放置位置目标
`@type {IPublicModelNode | null}`
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### detail
拖拽放置位置详情
`@type {IPublicTypeLocationDetail}`
相关类型:[IPublicTypeLocationDetail](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/location-detail.ts)
### event
拖拽放置位置对应的事件
`@type {IPublicTypeLocationDetail}`
相关类型:[IPublicModelLocateEvent](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/location-event.ts)
## 方法
### clone
获取一份当前对象的克隆
```typescript
/**
* 获取一份当前对象的克隆
* get a clone object of current dropLocation
*/
clone(event: IPublicModelLocateEvent): IPublicModelDropLocation;
```
相关类型:[IPublicModelLocateEvent](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/location-event.ts)

View File

@ -0,0 +1,124 @@
---
title: History
sidebar_position: 5
---
> **@types** [IPublicModelHistory](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/history.ts)<br/>
> **@since** v1.0.0
## 基本介绍
操作历史记录模型
## 方法
### go
历史记录跳转到指定位置
```typescript
/**
* 历史记录跳转到指定位置
* go to a specific history
* @param cursor
*/
go(cursor: number): void;
```
### back
历史记录后退
```typescript
/**
* 历史记录后退
* go backward in history
*/
back(): void;
```
### forward
forward()
历史记录前进
```typescript
/**
* 历史记录前进
* go forward in history
*/
forward(): void;
```
### savePoint
保存当前状态
```typescript
/**
* 保存当前状态
* do save current change as a record in history
*/
savePoint(): void;
```
### isSavePoint
当前是否是「保存点」,即是否有状态变更但未保存
```typescript
/**
* 当前是否是「保存点」,即是否有状态变更但未保存
* check if there is unsaved change for history
*/
isSavePoint(): boolean;
```
### getState
获取 state判断当前是否为「可回退」、「可前进」的状态
```typescript
/**
* 获取 state判断当前是否为「可回退」、「可前进」的状态
* get flags in number which indicat current change state
*
* | 1 | 1 | 1 |
* | -------- | -------- | -------- |
* | modified | redoable | undoable |
* eg:
* 7 means : modified && redoable && undoable
* 5 means : modified && undoable
*/
getState(): number;
```
## 事件
### onChangeState
监听 state 变更事件
```typescript
/**
* 监听 state 变更事件
* monitor on stateChange event
* @param func
*/
onChangeState(func: () => any): IPublicTypeDisposable;
```
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
### onChangeCursor
监听历史记录游标位置变更事件
```typescript
/**
* 监听历史记录游标位置变更事件
* monitor on cursorChange event
* @param func
*/
onChangeCursor(func: () => any): IPublicTypeDisposable;
```
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)

View File

@ -0,0 +1,94 @@
---
title: ModalNodesManager
sidebar_position: 7
---
> **@types** [IPublicModelModalNodesManager](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/modal-nodes-manager.ts)<br/>
> **@since** v1.0.0
## 基本介绍
模态节点管理器模型
## 方法
### setNodes
设置模态节点,触发内部事件
```typescript
/**
* 设置模态节点,触发内部事件
* set modal nodes, trigger internal events
*/
setNodes(): void;
```
### getModalNodes
获取模态节点(们)
```typescript
/**
* 获取模态节点(们)
* get modal nodes
*/
getModalNodes(): IPublicModelNode[];
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### getVisibleModalNode
获取当前可见的模态节点
```typescript
/**
* 获取当前可见的模态节点
* get current visible modal node
*/
getVisibleModalNode(): IPublicModelNode | null;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### hideModalNodes
隐藏模态节点(们)
```typescript
/**
* 隐藏模态节点(们)
* hide modal nodes
*/
hideModalNodes(): void;
```
### setVisible
设置指定节点为可见态
```typescript
/**
* 设置指定节点为可见态
* set specfic model node as visible
* @param node Node
*/
setVisible(node: IPublicModelNode): void;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### setInvisible
设置指定节点为不可见态
```typescript
/**
* 设置指定节点为不可见态
* set specfic model node as invisible
* @param node Node
*/
setInvisible(node: IPublicModelNode): void;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)

View File

@ -0,0 +1,310 @@
---
title: NodeChildren
sidebar_position: 2
---
> **@types** [IPublicModelNodeChildren](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node-children.ts)<br/>
> **@since** v1.0.0
## 基本介绍
节点孩子模型
## 属性
### owner
返回当前 children 实例所属的节点实例
`@type {IPublicModelNode | null}`
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### size
children 内的节点实例数
`@type {number}`
### isEmptyNode
是否为空
`@type {boolean}`
**@since v1.1.0**
> v1.1.0 之前请使用 `isEmpty`
### notEmptyNode
是否不为空
`@type {boolean}`
**@since v1.1.0**
## 方法
### delete
删除指定节点
```typescript
/**
* 删除指定节点
* delete the node
* @param node
*/
delete(node: IPublicModelNode): boolean;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### insert
插入一个节点
```typescript
/**
* 删除指定节点
* delete the node
* @param node
*/
delete(node: IPublicModelNode): boolean;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### indexOf
返回指定节点的下标
```typescript
/**
* 返回指定节点的下标
* get index of node in current children
* @param node
* @returns
*/
indexOf(node: IPublicModelNode): number;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### splice
类似数组 splice 操作
```typescript
/**
* 类似数组 splice 操作
* provide the same function with {Array.prototype.splice}
* @param start
* @param deleteCount
* @param node
*/
splice(start: number, deleteCount: number, node?: IPublicModelNode): any;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### get
返回指定下标的节点
```typescript
/**
* 返回指定下标的节点
* get node with index
* @param index
* @returns
*/
get(index: number): IPublicModelNode | null;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### has
是否包含指定节点
```typescript
/**
* 是否包含指定节点
* check if node exists in current children
* @param node
* @returns
*/
has(node: IPublicModelNode): boolean;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### forEach
类似数组的 forEach
```typescript
/**
* 类似数组的 forEach
* provide the same function with {Array.prototype.forEach}
* @param fn
*/
forEach(fn: (node: IPublicModelNode, index: number) => void): void;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### map
类似数组的 map
```typescript
/**
* 类似数组的 map
* provide the same function with {Array.prototype.map}
* @param fn
*/
map<T>(fn: (node: IPublicModelNode, index: number) => T[]): any[] | null;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### every
类似数组的 every
```typescript
/**
* 类似数组的 every
* provide the same function with {Array.prototype.every}
* @param fn
*/
every(fn: (node: IPublicModelNode, index: number) => boolean): boolean;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### some
类似数组的 some
```typescript
/**
* 类似数组的 some
* provide the same function with {Array.prototype.some}
* @param fn
*/
some(fn: (node: IPublicModelNode, index: number) => boolean): boolean;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### filter
类似数组的 filter
```typescript
/**
* 类似数组的 filter
* provide the same function with {Array.prototype.filter}
* @param fn
*/
filter(fn: (node: IPublicModelNode, index: number) => boolean): any;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### find
类似数组的 find
```typescript
/**
* 类似数组的 find
* provide the same function with {Array.prototype.find}
* @param fn
*/
find(fn: (node: IPublicModelNode, index: number) => boolean): IPublicModelNode | null;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### reduce
类似数组的 reduce
```typescript
/**
* 类似数组的 reduce
* provide the same function with {Array.prototype.reduce}
* @param fn
*/
reduce(fn: (acc: any, cur: IPublicModelNode) => any, initialValue: any): void;
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### importSchema
导入 schema
```typescript
/**
* 导入 schema
* import schema
* @param data
*/
importSchema(data?: IPublicTypeNodeData | IPublicTypeNodeData[]): void;
```
相关类型:[IPublicTypeNodeData](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-data.ts)
### exportSchema
导出 schema
```typescript
/**
* 导出 schema
* export schema
* @param stage
*/
exportSchema(stage: IPublicEnumTransformStage): IPublicTypeNodeSchema;
```
相关类型:
- [IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts)
- [IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts)
### mergeChildren
执行新增、删除、排序等操作
```typescript
/**
* 执行新增、删除、排序等操作
* excute remove/add/sort operations
* @param remover
* @param adder
* @param sorter
*/
mergeChildren(
remover: (node: IPublicModelNode, idx: number) => boolean,
adder: (children: IPublicModelNode[]) => IPublicTypeNodeData[] | null,
sorter: (firstNode: IPublicModelNode, secondNode: IPublicModelNode) => number
): any;
```
相关类型:
- [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
- [IPublicTypeNodeData](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-data.ts)

647
docs/docs/api/model/node.md Normal file
View File

@ -0,0 +1,647 @@
---
title: Node
sidebar_position: 1
---
> **@types** [IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)<br/>
> **@since** v1.0.0
## 基本介绍
节点模型
## 属性
### id
节点 id
`@type {string}`
### title
节点标题
`@type {string | IPublicTypeI18nData | ReactElement}`
相关类型:[IPublicTypeI18nData](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/i18n-data.ts)
### isContainerNode
是否为「容器型」节点
`@type {boolean}`
**@since v1.1.0**
> v1.1.0 之前请使用 `isContainer`
### isRootNode
是否为根节点
`@type {boolean}`
**@since v1.1.0**
> v1.1.0 之前请使用 `isRoot`
### isEmptyNode
是否为空节点(无 children 或者 children 为空)
`@type {boolean}`
**@since v1.1.0**
> v1.1.0 之前请使用 `isEmpty`
### isPageNode
是否为 Page 节点
`@type {boolean}`
**@since v1.1.0**
> v1.1.0 之前请使用 `isPage`
### isComponentNode
是否为 Component 节点
`@type {boolean}`
**@since v1.1.0**
> v1.1.0 之前请使用 `isComponent`
### isModalNode
是否为「模态框」节点
`@type {boolean}`
**@since v1.1.0**
> v1.1.0 之前请使用 `isModal`
### isSlotNode
是否为插槽节点
`@type {boolean}`
**@since v1.1.0**
> v1.1.0 之前请使用 `isSlot`
### isParentalNode
是否为父类/分支节点
`@type {boolean}`
**@since v1.1.0**
> v1.1.0 之前请使用 `isParental`
### isLeafNode
是否为叶子节点
`@type {boolean}`
**@since v1.1.0**
> v1.1.0 之前请使用 `isLeaf`
### isLocked
获取当前节点的锁定状态
**@since v1.0.16**
### isRGLContainerNode
设置为磁贴布局节点,使用方式可参考:[磁贴布局在钉钉宜搭报表设计引擎中的实现](https://mp.weixin.qq.com/s/PSTut5ahAB8nlJ9kBpBaxw)
`@type {boolean}`
**@since v1.1.0**
> v1.0.16 - v1.1.0 请使用 `isRGLContainer`
### index
下标
`@type {number}`
### icon
图标
`@type {IPublicTypeIconType}`
相关类型:[IPublicTypeIconType](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/icon-type.ts)
### zLevel
节点所在树的层级深度,根节点深度为 0
`@type {number}`
### componentName
节点 componentName
`@type {string}`
### componentMeta
节点的物料元数据
`@type {IPublicModelComponentMeta | null}`
相关类型:[IPublicModelComponentMeta](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/component-meta.ts)
### document
获取节点所属的[文档模型](./document-model)对象
`@type {IPublicModelDocumentModel | null}`
相关类型:[IPublicModelDocumentModel](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/document-model.ts)
### prevSibling
获取当前节点的前一个兄弟节点
`@type {IPublicModelNode | null}`
### nextSibling
获取当前节点的后一个兄弟节点
`@type {IPublicModelNode | null}`
### parent
获取当前节点的父亲节点
`@type {IPublicModelNode | null}`
### children
获取当前节点的孩子节点模型
`@type {IPublicModelNodeChildren | null}`
相关类型:[IPublicModelNodeChildren](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node-children.ts)
### slots
节点上挂载的插槽节点们
`@type {IPublicModelNode[]}`
### slotFor
当前节点为插槽节点时,返回节点对应的属性实例
`@type {IPublicModelProp | null}`
相关类型:[IPublicModelProp](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/prop.ts)
### props
返回节点的属性集
`@type {IPublicModelProps | null}`
相关类型:[IPublicModelProps](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/props.ts)
### propsData
返回节点的属性集值
`@type {IPublicTypePropsMap | IPublicTypePropsList | null}`
相关类型:
- [IPublicTypePropsMap](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/props-map.ts)
- [IPublicTypePropsList](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/props-list.ts)
### conditionGroup
获取条件组
`@type {IPublicModelExclusiveGroup | null}`
相关类型:[IPublicModelExclusiveGroup](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/exclusive-group.ts)
**@since v1.1.0**
### schema
获取符合搭建协议 - 节点 schema 结构
`@type {IPublicTypeNodeSchema | null}`
相关类型:[IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts)
### settingEntry
获取对应的 setting entry
`@type {IPublicModelSettingTopEntry}`
相关类型:[IPublicModelSettingTopEntry](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/setting-top-entry.ts)
### visible
当前节点是否可见
`@type {boolean}`
**@since v1.1.0**
## 方法
### getRect
返回节点的尺寸、位置信息
```typescript
/**
* 返回节点的尺寸、位置信息
* get rect information for this node
*/
getRect(): DOMRect | null;
```
### hasSlots
是否有挂载插槽节点
```typescript
/**
* 是否有挂载插槽节点
* check if current node has slots
*/
hasSlots(): boolean;
```
### hasCondition
是否设定了渲染条件
```typescript
/**
* 是否设定了渲染条件
* check if current node has condition value set
*/
hasCondition(): boolean;
```
### hasLoop
是否设定了循环数据
```typescript
/**
* 是否设定了循环数据
* check if loop is set for this node
*/
hasLoop(): boolean;
```
### getProp
获取指定 path 的属性模型实例
```typescript
/**
* 获取指定 path 的属性模型实例
* get prop by path
* @param path 属性路径,支持 a / a.b / a.0 等格式
*/
getProp(path: string, createIfNone: boolean): IPublicModelProp | null;
```
相关类型:[IPublicModelProp](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/prop.ts)
### getPropValue
获取指定 path 的属性模型实例值
```typescript
/**
* 获取指定 path 的属性模型实例值
* get prop value by path
* @param path 属性路径,支持 a / a.b / a.0 等格式
*/
getPropValue(path: string): any;
```
### getExtraProp
获取指定 path 的属性模型实例,注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级
```typescript
/**
* 获取指定 path 的属性模型实例,
* 注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级
*
* get extra prop by path, an extra prop means a prop not exists in the `props`
* but as siblint of the `props`
* @param path 属性路径,支持 a / a.b / a.0 等格式
* @param createIfNone 当没有属性的时候,是否创建一个属性
*/
getExtraProp(path: string, createIfNone?: boolean): IPublicModelProp | null;
```
相关类型:[IPublicModelProp](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/prop.ts)
### getExtraPropValue
获取指定 path 的属性模型实例,注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级
```typescript
/**
* 获取指定 path 的属性模型实例,
* 注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级
*
* get extra prop value by path, an extra prop means a prop not exists in the `props`
* but as siblint of the `props`
* @param path 属性路径,支持 a / a.b / a.0 等格式
* @returns
*/
getExtraPropValue(path: string): any;
```
### setPropValue
setPropValue(path: string, value: CompositeValue)
设置指定 path 的属性模型实例值
```typescript
/**
* 设置指定 path 的属性模型实例值
* set value for prop with path
* @param path 属性路径,支持 a / a.b / a.0 等格式
* @param value 值
*/
setPropValue(path: string, value: IPublicTypeCompositeValue): void;
```
相关类型:[IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts)
### setExtraPropValue
设置指定 path 的属性模型实例值
```typescript
/**
* 设置指定 path 的属性模型实例值
* set value for extra prop with path
* @param path 属性路径,支持 a / a.b / a.0 等格式
* @param value 值
*/
setExtraPropValue(path: string, value: IPublicTypeCompositeValue): void;
```
相关类型:[IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts)
### importSchema
导入节点数据
```typescript
/**
* 导入节点数据
* import node schema
* @param data
*/
importSchema(data: IPublicTypeNodeSchema): void;
```
相关类型:[IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts)
### exportSchema
导出节点数据
```typescript
/**
* 导出节点数据
* export schema from this node
* @param stage
* @param options
*/
exportSchema(stage: IPublicEnumTransformStage, options?: any): IPublicTypeNodeSchema;
```
相关类型:
- [IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts)
- [IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts)
### insertBefore
在指定位置之前插入一个节点
```typescript
/**
* 在指定位置之前插入一个节点
* insert a node befor current node
* @param node
* @param ref
* @param useMutator
*/
insertBefore(
node: IPublicModelNode,
ref?: IPublicModelNode | undefined,
useMutator?: boolean,
): void;
```
### insertAfter
在指定位置之后插入一个节点
```typescript
/**
* 在指定位置之后插入一个节点
* insert a node after this node
* @param node
* @param ref
* @param useMutator
*/
insertAfter(
node: IPublicModelNode,
ref?: IPublicModelNode | undefined,
useMutator?: boolean,
): void;
```
### replaceChild
替换指定子节点
```typescript
/**
* 替换指定子节点
* replace a child node with data provided
* @param node 待替换的子节点
* @param data 用作替换的节点对象或者节点描述
* @returns
*/
replaceChild(node: IPublicModelNode, data: any): IPublicModelNode | null;
```
### replaceWith
将当前节点替换成指定节点描述
```typescript
/**
* 将当前节点替换成指定节点描述
* replace current node with a new node schema
* @param schema
*/
replaceWith(schema: IPublicTypeNodeSchema): any;
```
相关类型:[IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts)
### select
选中当前节点实例
```typescript
/**
* 选中当前节点实例
* select current node
*/
select(): void;
```
### hover
设置悬停态
```typescript
/**
* 设置悬停态
* set hover value for current node
* @param flag
*/
hover(flag: boolean): void;
```
### lock
设置节点锁定状态
```typescript
/**
* 设置节点锁定状态
* set lock value for current node
* @param flag
* @since v1.0.16
*/
lock(flag?: boolean): void;
```
**@since v1.0.16**
### remove
删除当前节点实例
```typescript
/**
* 删除当前节点实例
* remove current node
*/
remove(): void;
```
### mergeChildren
执行新增、删除、排序等操作
```typescript
/**
* 执行新增、删除、排序等操作
* excute remove/add/sort operations on node`s children
*
* @since v1.1.0
*/
mergeChildren(
remover: (node: IPublicModelNode, idx: number) => boolean,
adder: (children: IPublicModelNode[]) => any,
sorter: (firstNode: IPublicModelNode, secondNode: IPublicModelNode) => number
): any;
```
**@since v1.1.0**
### contains
当前节点是否包含某子节点
```typescript
/**
* 当前节点是否包含某子节点
* check if current node contains another node as a child
* @param node
* @since v1.1.0
*/
contains(node: IPublicModelNode): boolean;
```
**@since v1.1.0**
### canPerformAction
是否可执行某 action
```typescript
/**
* 是否可执行某 action
* check if current node can perform certain aciton with actionName
* @param actionName action 名字
* @since v1.1.0
*/
canPerformAction(actionName: string): boolean;
```
**@since v1.1.0**
### isConditionalVisible
获取该节点的 ConditionalVisible 值
```typescript
/**
* 获取该节点的 ConditionalVisible 值
* check if current node ConditionalVisible
* @since v1.1.0
*/
isConditionalVisible(): boolean | undefined;
```
**@since v1.1.0**
### setConditionalVisible
设置该节点的 ConditionalVisible 为 true
```typescript
/**
* 设置该节点的 ConditionalVisible 为 true
* make this node as conditionalVisible === true
* @since v1.1.0
*/
setConditionalVisible(): void;
```
**@since v1.1.0**

View File

@ -0,0 +1,40 @@
---
title: PluginInstance
sidebar_position: 12
---
> **@types** [IPublicModelPluginInstance](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/plugin-instance.ts)<br/>
> **@since** v1.1.0
## 基本介绍
插件实例
## 属性
### pluginName
插件名字
`@type {string}`
### dep
插件依赖
`@type {string[]}`
### disabled
插件是否禁用
`@type {boolean}`
### meta
插件 meta 信息
`@type {IPublicTypePluginMeta}`
相关类型:[IPublicTypePluginMeta](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/plugin-meta.ts)

108
docs/docs/api/model/prop.md Normal file
View File

@ -0,0 +1,108 @@
---
title: Prop
sidebar_position: 3
---
> **@types** [IPublicModelProp](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/prop.ts)<br/>
> **@since** v1.0.0
## 基本介绍
属性模型
## 属性
### id
id
`@type {string}`
### key
key 值
`@type {string | number | undefined}`
### path
返回当前 prop 的路径
`@type {string[]}`
### node
返回所属的节点实例
`@type {IPublicModelNode | null}`
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### slotNode
当本 prop 代表一个 Slot 时,返回对应的 slotNode
`@type {IPublicModelNode | undefined | null}`
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
## 方法
### setValue
设置值
```typescript
/**
* 设置值
* set value for this prop
* @param val
*/
setValue(val: IPublicTypeCompositeValue): void;
```
相关类型:[IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts)
### getValue
获取值
```typescript
/**
* 获取值
* get value of this prop
*/
getValue(): any;
```
### remove
移除值
```typescript
/**
* 移除值
* remove value of this prop
* @since v1.0.16
*/
remove(): void;
```
**@since v1.0.16**
### exportSchema
导出值
```typescript
/**
* 导出值
* export schema
* @param stage
*/
exportSchema(stage: IPublicEnumTransformStage): IPublicTypeCompositeValue;
```
相关类型:
- [IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts)
- [IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts)

View File

@ -0,0 +1,160 @@
---
title: Props
sidebar_position: 4
---
> **@types** [IPublicModelProps](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/props.ts)<br/>
> **@since** v1.0.0
## 基本介绍
属性集模型
## 属性
### id
id
`@type {string}`
### path
返回当前 props 的路径
`@type {string[]}`
### node
返回当前属性集所属的节点实例
`@type {IPublicModelNode | null}`
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
## 方法
### getProp
获取指定 path 的属性模型实例
```typescript
/**
* 获取指定 path 的属性模型实例
* get prop by path
* @param path 属性路径,支持 a / a.b / a.0 等格式
*/
getProp(path: string): IPublicModelProp | null;
```
相关类型:[IPublicModelProp](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/prop.ts)
### getPropValue
获取指定 path 的属性模型实例值
```typescript
/**
* 获取指定 path 的属性模型实例值
* get value of prop by path
* @param path 属性路径,支持 a / a.b / a.0 等格式
*/
getPropValue(path: string): any;
```
### getExtraProp
获取指定 path 的属性模型实例,注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级
```typescript
/**
* 获取指定 path 的属性模型实例,
* 注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级
* get extra prop by path
* @param path 属性路径,支持 a / a.b / a.0 等格式
*/
getExtraProp(path: string): IPublicModelProp | null;
```
相关类型:[IPublicModelProp](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/prop.ts)
### getExtraPropValue
获取指定 path 的属性模型实例值,注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级
```typescript
/**
* 获取指定 path 的属性模型实例值
* 注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级
* get value of extra prop by path
* @param path 属性路径,支持 a / a.b / a.0 等格式
*/
getExtraPropValue(path: string): any;
```
### setPropValue
设置指定 path 的属性模型实例值
```typescript
/**
* 设置指定 path 的属性模型实例值
* set value of prop by path
* @param path 属性路径,支持 a / a.b / a.0 等格式
* @param value 值
*/
setPropValue(path: string, value: IPublicTypeCompositeValue): void;
```
相关类型:[IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts)
### setExtraPropValue
设置指定 path 的属性模型实例值
```typescript
/**
* 设置指定 path 的属性模型实例值
* set value of extra prop by path
* @param path 属性路径,支持 a / a.b / a.0 等格式
* @param value 值
*/
setExtraPropValue(path: string, value: IPublicTypeCompositeValue): void;
```
相关类型:[IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts)
### has
当前 props 是否包含某 prop
```typescript
/**
* 当前 props 是否包含某 prop
* check if the specified key is existing or not.
* @param key
* @since v1.1.0
*/
has(key: string): boolean;
```
**@since v1.1.0**
### add
添加一个 prop
```typescript
/**
* 添加一个 prop
* add a key with given value
* @param value
* @param key
* @since v1.1.0
*/
add(value: IPublicTypeCompositeValue, key?: string | number | undefined): any;
```
相关类型:[IPublicTypeCompositeValue](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/composite-value.ts)
**@since v1.1.0**

View File

@ -0,0 +1,46 @@
---
title: Resource
sidebar_position: 13
---
> **[@experimental](./#experimental)**<br/>
> **@types** [IPublicModelResource](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/resource.ts)<br/>
> **@since** v1.1.0
## 属性
### title
资源标题
`@type {string}`
### name
资源名字
`@type {string}`
### type
资源类型
`@type {string}`
### category
资源分类
`@type {string}`
### icon
资源 icon
`@type {ReactElement}`
### options
资源配置信息
`@type {Object}`

View File

@ -0,0 +1,161 @@
---
title: Selection
sidebar_position: 6
---
> **@types** [IPublicModelSelection](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/selection.ts)<br/>
> **@since** v1.0.0
## 基本介绍
画布节点选中模型
## 属性
### selected
返回选中的节点 id
`@type {string[]}`
### node
返回选中的节点(如多个节点只返回第一个)
`@type {IPublicModelNode | null}`
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
**@since v1.1.0**
## 方法
### select
选中指定节点(覆盖方式)
```typescript
/**
* 选中指定节点(覆盖方式)
* select node with id, this will override current selection
* @param id
*/
select(id: string): void;
```
### selectAll
批量选中指定节点们
```typescript
/**
* 批量选中指定节点们
* select node with ids, this will override current selection
*
* @param ids
*/
selectAll(ids: string[]): void;
```
### remove
**取消选中**选中的指定节点,不会删除组件
```typescript
/**
* 移除选中的指定节点
* remove node from selection with node id
* @param id
*/
remove(id: string): void;
```
### clear
**取消选中**所有选中节点,不会删除组件
```typescript
/**
* 清除所有选中节点
* clear current selection
*/
clear(): void;
```
### has
判断是否选中了指定节点
```typescript
/**
* 判断是否选中了指定节点
* check if node with specific id is selected
* @param id
*/
has(id: string): boolean;
```
### add
选中指定节点(增量方式)
```typescript
/**
* 选中指定节点(增量方式)
* add node with specific id to selection
* @param id
*/
add(id: string): void;
```
### getNodes
获取选中的节点实例
```typescript
/**
* 获取选中的节点实例
* get selected nodes
*/
getNodes(): IPublicModelNode[];
```
相关类型:[IPublicModelNode](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/node.ts)
### getTopNodes
获取选区的顶层节点
例如选中的节点为:
- DivA
- ChildrenA
- DivB
getNodes 返回的是 [DivA、ChildrenA、DivB]getTopNodes 返回的是 [DivA、DivB],其中 ChildrenA 由于是二层节点getTopNodes 不会返回
```typescript
/**
* 获取选区的顶层节点
* get seleted top nodes
* for example:
* getNodes() returns [A, subA, B], then
* getTopNodes() will return [A, B], subA will be removed
* @since v1.0.16
*/
getTopNodes(includeRoot?: boolean): IPublicModelNode[];
```
**@since v1.0.16**
## 事件
### onSelectionChange
注册 selection 变化事件回调
```typescript
/**
* 注册 selection 变化事件回调
* set callback which will be called when selection is changed
* @since v1.1.0
*/
onSelectionChange(fn: (ids: string[]) => void): IPublicTypeDisposable;
```
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
**@since v1.1.0**

View File

@ -0,0 +1,76 @@
---
title: Window
sidebar_position: 12
---
> **[@experimental](./#experimental)**<br/>
> **@types** [IPublicModelWindow](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/window.ts)<br/>
> **@since** v1.1.0
## 基本介绍
低代码设计器窗口模型
## 属性
### id
窗口唯一 id
`@type {string}`
### title
窗口标题
`@type {string}`
### icon
`@type {ReactElement}`
### resource
窗口对应资源
`@type {IPublicModelResource}`
关联模型 [IPublicModelResource](./resource)
## 方法
### importSchema
当前窗口导入 schema, 会调用当前窗口对应资源的 import 钩子
```typescript
function importSchema(schema: IPublicTypeNodeSchema): void
```
相关类型:[IPublicTypeNodeSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/node-schema.ts)
### changeViewType
修改当前窗口视图类型
```typescript
function changeViewType(viewName: string): void
```
### save
当前窗口的保存方法,会调用当前窗口对应资源的 save 钩子
```typescript
function save(): Promise(void)
```
## 事件
### onChangeViewType
窗口视图变更事件
```
onChangeViewType(fn: (viewName: string) => void): IPublicTypeDisposable;
```
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)

View File

@ -2,32 +2,35 @@
title: plugins - 插件 API
sidebar_position: 4
---
> **@types** [IPublicApiPlugins](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/plugins.ts)<br/>
> **@since** v1.0.0
## 模块简介
插件管理器,提供编排模块中管理插件的能力。
## 变量variables
## 方法签名functions
## 方法
### register
注册插件
#### 类型定义
```typescript
async function register(
pluginConfigCreator: (ctx: ILowCodePluginContext) => ILowCodePluginConfig,
options?: ILowCodeRegisterOptions,
plugin: IPublicTypePlugin,
options?: IPublicTypePluginRegisterOptions,
): Promise<void>
```
pluginConfigCreator 是一个 ILowCodePluginConfig 生成函数ILowCodePluginConfig 中包含了该插件的 init / destroy 等钩子函数,以及 exports 函数用于返回插件对外暴露的值。
相关 types:
- [IPublicTypePlugin](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/plugin.ts)
- [IPublicTypePluginRegisterOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/plugin-register-options.ts)
另外pluginConfigCreator 还必须挂载 pluginName 字段,全局确保唯一,否则 register 时会报错,可以选择性挂载 meta 字段,用于描述插件的元数据信息,比如兼容的引擎版本、支持的参数配置、依赖插件声明等。
> 注pluginConfigCreator 挂载 pluginName / meta 可以通过低代码工具链的插件脚手架生成,写如 package.json 后将会自动注入到代码中,具体见 [插件元数据工程化示例](#RO9YY)
其中第一个参数 plugin 通过低代码工具链的插件脚手架生成编写模板,开发者可以参考[这个章节](/site/docs/guide/expand/editor/cli)进行创建
#### 简单示例
```typescript
import { plugins } from '@alilc/lowcode-engine';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
const builtinPluginRegistry = (ctx: ILowCodePluginContext) => {
const builtinPluginRegistry = (ctx: IPublicModelPluginContext) => {
return {
async init() {
const { skeleton } = ctx;
@ -58,58 +61,61 @@ await plugins.register(builtinPluginRegistry);
#### 使用 exports 示例
```typescript
import { plugins } from '@alilc/lowcode-engine';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
const pluginA = (ctx: ILowCodePluginContext) => {
const PluginA = (ctx: IPublicModelPluginContext) => {
return {
async init() {},
exports() { return { x: 1, } },
};
}
pluginA.pluginName = 'pluginA';
PluginA.pluginName = 'PluginA';
const pluginB = (ctx: ILowCodePluginContext) => {
const PluginB = (ctx: IPublicModelPluginContext) => {
return {
async init() {
// 获取 pluginA 的导出值
console.log(ctx.plugins.pluginA.x); // => 1
console.log(ctx.plugins.PluginA.x); // => 1
},
};
}
pluginA.pluginName = 'pluginA';
pluginB.pluginName = 'pluginB';
pluginB.meta = {
dependencies: ['pluginA'],
PluginA.pluginName = 'pluginA';
PluginB.pluginName = 'PluginB';
PluginB.meta = {
dependencies: ['PluginA'],
}
await plugins.register(pluginA);
await plugins.register(pluginB);
await plugins.register(PluginA);
await plugins.register(PluginB);
```
> 注ctx 是在插件 creator 中获取引擎 API 的上下文,具体定义参见 [ILowCodePluginContext](#qEhTb)
> 注ctx 是在插件中获取引擎 API 的唯一渠道,具体定义参见 [IPublicModelPluginContext](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/plugin-context.ts)
####
#### 设置兼容引擎版本示例
```typescript
import { plugins } from '@alilc/lowcode-engine';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
const builtinPluginRegistry = (ctx: ILowCodePluginContext) => {
const BuiltinPluginRegistry = (ctx: IPublicModelPluginContext) => {
return {
async init() {
...
},
};
}
builtinPluginRegistry.pluginName = 'builtinPluginRegistry';
builtinPluginRegistry.meta = {
BuiltinPluginRegistry.pluginName = 'BuiltinPluginRegistry';
BuiltinPluginRegistry.meta = {
engines: {
lowcodeEngine: '^1.0.0', // 插件需要配合 ^1.0.0 的引擎才可运行
},
}
await plugins.register(builtinPluginRegistry);
await plugins.register(BuiltinPluginRegistry);
```
#### 设置插件参数版本示例
```typescript
import { plugins } from '@alilc/lowcode-engine';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
const builtinPluginRegistry = (ctx: ILowCodePluginContext, options: any) => {
const BuiltinPluginRegistry = (ctx: IPublicModelPluginContext, options: any) => {
return {
async init() {
// 1.0.4 之后的传值方式,通过 register(xxx, options)
@ -120,8 +126,8 @@ const builtinPluginRegistry = (ctx: ILowCodePluginContext, options: any) => {
},
};
}
builtinPluginRegistry.pluginName = 'builtinPluginRegistry';
builtinPluginRegistry.meta = {
BuiltinPluginRegistry.pluginName = 'BuiltinPluginRegistry';
BuiltinPluginRegistry.meta = {
preferenceDeclaration: {
title: 'pluginA 的参数定义',
properties: [
@ -150,101 +156,55 @@ builtinPluginRegistry.meta = {
}
// 从 1.0.4 开始,支持直接在 pluginCreator 的第二个参数 options 获取入参
await plugins.register(builtinPluginRegistry, { key1: 'abc', key5: 'willNotPassToPlugin' });
// 1.0.4 之前,通过 preference 来传递 / 获取值
const preference = new Map();
preference.set('builtinPluginRegistry', {
key1: 'abc',
key5: 'willNotPassToPlugin', // 因为 key5 不在插件声明可接受的参数里
});
init(document.getElementById('lce'), engineOptions, preference);
await plugins.register(BuiltinPluginRegistry, { key1: 'abc', key5: 'willNotPassToPlugin' });
```
### get
获取插件实例
**类型定义**
```typescript
function get(pluginName: string): ILowCodePlugin | undefined
```
**调用示例**
```typescript
import { plugins } from '@alilc/lowcode-engine';
获取指定插件
```typescript
function get(pluginName: string): IPublicModelPluginInstance;
plugins.get(builtinPluginRegistry);
```
###
关联模型 [IPublicModelPluginInstance](./model/plugin-instance)
### getAll
获取所有插件实例
**类型定义**
```typescript
function getAll(): ILowCodePlugin[]
```
**调用示例**
```typescript
import { plugins } from '@alilc/lowcode-engine';
获取所有的插件实例
```typescript
function getAll(): IPublicModelPluginInstance[];
plugins.getAll();
```
###
关联模型 [IPublicModelPluginInstance](./model/plugin-instance)
### has
判断是否已经加载了指定插件
**类型定义**
```typescript
function has(pluginName: string): boolean
```
**调用示例**
```typescript
import { plugins } from '@alilc/lowcode-engine';
plugins.has('builtinPluginRegistry');
判断是否有指定插件
```typescript
function has(pluginName: string): boolean;
```
### delete
删除指定插件
**类型定义**
```typescript
async function delete(pluginName: string): Promise<boolean>
```
**调用示例**
```typescript
import { plugins } from '@alilc/lowcode-engine';
plugins.delete('builtinPluginRegistry');
```
##
## 事件events
## 相关模块
### ILowCodePluginContext
**类型定义**
删除指定插件
```typescript
export interface ILowCodePluginContext {
skeleton: Skeleton; // 参考面板 API
hotkey: Hotkey; // 参考快捷键 API
setters: Setters; // 参考设置器 API
config: EngineConfig; // 参考配置 API
material: Material; // 参考物料 API
event: Event; // 参考事件 API
project: Project; // 参考模型 API
common: Common; // 参考模型 API
logger: Logger; // 参考日志 API
plugins: ILowCodePluginManager; // 即本文档描述内容
preference: IPluginPreferenceMananger;
}
```
### ILowCodePluginConfig
**类型定义**
```typescript
export interface ILowCodePluginConfig {
init?(): void;
destroy?(): void;
exports?(): any;
}
function delete(pluginName: string): void;
```
## 相关类型定义
- [IPublicModelPluginContext](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/plugin-context.ts)
- [IPublicTypePluginConfig](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/plugin-config.ts)
- [IPublicModelPluginInstance](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/plugin-instance.ts)
## 插件元数据工程转化示例
your-plugin/package.json
```json
@ -262,8 +222,8 @@ your-plugin/package.json
}
```
转换后的结构:
```json
const debug = (ctx: ILowCodePluginContext, options: any) => {
```typescript
const debug = (ctx: IPublicModelPluginContext, options: any) => {
return {};
}
@ -275,8 +235,3 @@ debug.meta = {
preferenceDeclaration: { ... }
};
```
###
## 使用示例
更多示例参考:[https://github.com/alibaba/lowcode-demo/blob/058450edb584d92be6cb665b1f3a9646ba464ffa/src/universal/plugin.tsx#L36](https://github.com/alibaba/lowcode-demo/blob/058450edb584d92be6cb665b1f3a9646ba464ffa/src/universal/plugin.tsx#L36)

File diff suppressed because it is too large Load Diff

View File

@ -2,44 +2,72 @@
title: setters - 设置器 API
sidebar_position: 6
---
> **@types** [IPublicApiSetters](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/setters.ts)<br/>
> **@since** v1.0.0
## 模块简介
负责注册设置器、管理设置器的 API。注册自定义设置器之后可以在物料中进行使用。
## 方法签名functions
## 方法
### getSetter
获取指定 setter
**类型定义**
```typescript
function getSetter(type: string): RegisteredSetter;
/**
* 获取指定 setter
* get setter by type
* @param type
* @returns
*/
getSetter(type: string): IPublicTypeRegisteredSetter | null;
```
相关类型:[IPublicTypeRegisteredSetter](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/registerd-setter.ts)
### getSettersMap
获取已注册的所有 settersMap
**类型定义**
```typescript
function getSettersMap(): Map<string, RegisteredSetter>
/**
* 获取已注册的所有 settersMap
* get map of all registered setters
* @returns
*/
getSettersMap(): Map<string, IPublicTypeRegisteredSetter & {
type: string;
}>;
```
相关类型:[IPublicTypeRegisteredSetter](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/registerd-setter.ts)
### registerSetter
注册一个 setter
**类型定义**
```typescript
function registerSetter(
typeOrMaps: string | { [key: string]: CustomView | RegisteredSetter },
setter?: CustomView | RegisteredSetter | undefined,
/**
* 注册一个 setter
* register a setter
* @param typeOrMaps
* @param setter
* @returns
*/
registerSetter(
typeOrMaps: string | { [key: string]: IPublicTypeCustomView | IPublicTypeRegisteredSetter },
setter?: IPublicTypeCustomView | IPublicTypeRegisteredSetter | undefined
): void;
```
相关类型:
- [IPublicTypeRegisteredSetter](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/registerd-setter.ts)
- [IPublicTypeCustomView](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/custom-view.ts)
## 使用示例
### 注册官方内置 Setter 到设计器中
```typescript
import { setters, skeleton } from '@alilc/lowcode-engine';
import { setterMap, pluginMap } from '@alilc/lowcode-engine-ext';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
const setterRegistry = (ctx: ILowCodePluginContext) => {
const SetterRegistry = (ctx: IPublicModelPluginContext) => {
return {
name: 'ext-setters-registry',
async init() {
@ -67,8 +95,8 @@ const setterRegistry = (ctx: ILowCodePluginContext) => {
};
}
setterRegistry.pluginName = 'setterRegistry';
await plugins.register(setterRegistry);
SetterRegistry.pluginName = 'SetterRegistry';
await plugins.register(SetterRegistry);
```
### 开发自定义 Setter
@ -111,181 +139,13 @@ export default class AltStringSetter extends React.PureComponent<AltStringSetter
}
}
```
开发完毕之后,注册 AltStringSetter 到设计器中:
```typescript
import AltStringSetter from './AltStringSetter';
const registerSetter = window.AliLowCodeEngine.setters.registerSetter;
registerSetter('AltStringSetter', AltStringSetter);
```
注册之后,我们就可以在物料中使用了,其中核心配置如下:
```typescript
{
"props": {
"isExtends": true,
"override": [
{
"name": "type",
"setter": "AltStringSetter"
}
]
}
}
```
完整配置如下:
```typescript
{
"componentName": "Message",
"title": "Message",
"props": [
{
"name": "title",
"propType": "string",
"description": "标题",
"defaultValue": "标题"
},
{
"name": "type",
"propType": {
"type": "oneOf",
"value": [
"success",
"warning",
"error",
"notice",
"help",
"loading"
]
},
"description": "反馈类型",
"defaultValue": "success"
}
],
"configure": {
"props": {
"isExtends": true,
"override": [
{
"name": "type",
"setter": "AltStringSetter"
}
]
}
}
}
```
## 模块简介
负责注册设置器、管理设置器的 API。注册自定义设置器之后可以在物料中进行使用。
## 方法签名functions
### getSetter
获取指定 setter
**类型定义**
```typescript
function getSetter(type: string): RegisteredSetter;
```
### getSettersMap
获取已注册的所有 settersMap
**类型定义**
```typescript
function getSettersMap(): Map<string, RegisteredSetter>
```
### registerSetter
注册一个 setter
**类型定义**
```typescript
function registerSetter(
typeOrMaps: string | { [key: string]: CustomView | RegisteredSetter },
setter?: CustomView | RegisteredSetter | undefined,
): void;
```
## 使用示例
### 注册官方内置 Setter 到设计器中
```typescript
import { setters, skeleton } from '@alilc/lowcode-engine';
import { setterMap, pluginMap } from '@alilc/lowcode-engine-ext';
const setterRegistry = (ctx: ILowCodePluginContext) => {
return {
name: 'ext-setters-registry',
async init() {
// 注册 setterMap
setters.registerSetter(setterMap);
// 注册插件
// 注册事件绑定面板
skeleton.add({
area: 'centerArea',
type: 'Widget',
content: pluginMap.EventBindDialog,
name: 'eventBindDialog',
props: {},
});
// 注册变量绑定面板
skeleton.add({
area: 'centerArea',
type: 'Widget',
content: pluginMap.VariableBindDialog,
name: 'variableBindDialog',
props: {},
});
},
};
}
setterRegistry.pluginName = 'setterRegistry';
await plugins.register(setterRegistry);
```
### 开发自定义 Setter
AltStringSetter 代码如下:
```typescript
import * as React from "react";
import { Input } from "@alifd/next";
import "./index.scss";
interface AltStringSetterProps {
// 当前值
value: string;
// 默认值
initialValue: string;
// setter 唯一输出
onChange: (val: string) => void;
// AltStringSetter 特殊配置
placeholder: string;
}
export default class AltStringSetter extends React.PureComponent<AltStringSetterProps> {
componentDidMount() {
const { onChange, value, defaultValue } = this.props;
if (value == undefined && defaultValue) {
onChange(defaultValue);
}
}
// 声明 Setter 的 title
static displayName = 'AltStringSetter';
render() {
const { onChange, value, placeholder } = this.props;
return (
<Input
value={value}
placeholder={placeholder || ""}
onChange={(val: any) => onChange(val)}
></Input>
);
}
}
```
开发完毕之后,注册 AltStringSetter 到设计器中:
```typescript
import AltStringSetter from './AltStringSetter';
const registerSetter = window.AliLowCodeEngine.setters.registerSetter;
import { setters } from '@alilc/lowcode-engine';
const { registerSetter } = registerSetter;
registerSetter('AltStringSetter', AltStringSetter);
```
注册之后,我们就可以在物料中使用了,其中核心配置如下:

View File

@ -2,11 +2,25 @@
title: simulatorHost - 模拟器 API
sidebar_position: 3
---
# 模块简介
> **@types** [IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts)<br/>
> **@since** v1.0.0
## 模块简介
负责模拟器相关的 API包括画布尺寸、语言等。
# 方法functions
## set
## 方法
### set
设置 host 配置值
```typescript
/**
* 设置若干用于画布渲染的变量比如画布大小、locale 等。
* set config for simulator host, eg. device locale and so on.
* @param key
* @param value
*/
set(key: string, value: any): void;
```
#### 示例
设置若干用于画布渲染的变量比如画布大小、locale 等。
以设置画布大小为例:
@ -21,11 +35,41 @@ project.simulatorHost.set('deviceClassName', 'my-canvas-class');
project.simulatorHost.set('deviceStyle', { canvas: { width: '300px', backgroundColor: 'red' }, viewport: { width: '280px' } });
```
## get
### get
获取模拟器中设置的变量比如画布大小、locale 等。
```typescript
project.simulatorHost.get('device');
/**
* 获取模拟器中设置的变量比如画布大小、locale 等。
* set config value by key
* @param key
* @returns
*/
get(key: string): any;
```
## rerender
### rerender
刷新渲染画布
```typescript
/**
* 刷新渲染画布
* make simulator render again
*/
rerender(): void;
```
### scrollToNode
滚动到指定节点
```typescript
/**
* 滚动到指定节点
* scroll to specific node
* @param node
* @since v1.1.0
*/
scrollToNode(node: IPublicModelNode): void;
```
**@since v1.1.0**

View File

@ -2,6 +2,10 @@
title: skeleton - 面板 API
sidebar_position: 1
---
> **@types** [IPublicApiSkeleton](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/skeleton.ts)<br/>
> **@since** v1.0.0
## 模块简介
面板 API 提供了面板扩展和管理的能力,如下图蓝色内容都是扩展出来的。
@ -131,21 +135,24 @@ skeleton.add({
});
```
## 变量variables
## 方法
## 方法签名functions
### 1. add
```tsx
add(config: IWidgetBaseConfig & {
area?: string;
}, extraConfig?: object): IWidget | Panel;
```
### add
往指定扩展区加入一块面板
```typescript
/**
* 增加一个面板实例
* add a new panel
* @param config
* @param extraConfig
* @returns
*/
add(config: IPublicTypeWidgetBaseConfig, extraConfig?: Record<string, any>): any;
```
IWidgetBaseConfig 定义如下:
| 属性名 | 含义 | 备注 |
@ -160,74 +167,188 @@ IWidgetBaseConfig 定义如下:
| index | 面板的位置,不传默认按插件注册顺序 | |
### 2. remove
remove(config: IWidgetBaseConfig)
### remove
移除一个面板实例
### 3. showPanel
```typescript
/**
* 移除一个面板实例
* remove a panel
* @param config
* @returns
*/
remove(config: IPublicTypeWidgetBaseConfig): number | undefined;
```
showPanel(name: string)
### showPanel
展示指定 Panel 实例
### 4. hidePanel
```typescript
/**
* 展示指定 Panel 实例
* show panel by name
* @param name
*/
showPanel(name: string): void;
```
hidePanel(name: string)
### hidePanel
隐藏面板
### 5. showWidget
```typescript
/**
* 隐藏面板
* hide panel by name
* @param name
*/
hidePanel(name: string): void;
```
showWidget(name: string)
### showWidget
展示指定 Widget 实例
### 6. hideWidget
```typescript
/**
* 展示指定 Widget 实例
* show widget by name
* @param name
*/
showWidget(name: string): void;
```
hideWidget(name: string)
### enableWidget
将 widget 启用。
```typescript
/**
* 将 widget 启用
* enable widget
* @param name
*/
enableWidget(name: string): void;
```
### hideWidget
隐藏指定 widget 实例。
### 7. enableWidget
```typescript
/**
* 隐藏指定 widget 实例
* hide widget by name
* @param name
*/
hideWidget(name: string): void;
```
enableWidget(name: string)
将 widget 启用。
注:该函数将会触发全局事件 'skeleton.widget.enable'
### 8. disableWidget
disableWidget(name: string)
### disableWidget
将 widget 禁用掉,禁用后,所有鼠标事件都会被禁止掉。
适用场景:在该面板还在进行初始化构造时,可以先禁止掉,防止用户点击报错,待初始化完成,重新启用。
## 事件events
### 1. onShowPanel
```typescript
/**
* 将 widget 禁用掉,禁用后,所有鼠标事件都会被禁止掉。
* disable widgetand make it not responding any click event.
* @param name
*/
disableWidget(name: string): void;
```
onShowPanel(listener: (...args: unknown[]) => void)
### showArea
显示某个 Area
```typescript
/**
* 显示某个 Area
* show area
* @param areaName name of area
*/
showArea(areaName: string): void;
```
### hideArea
隐藏某个 Area
```typescript
/**
* 隐藏某个 Area
* hide area
* @param areaName name of area
*/
hideArea(areaName: string): void;
```
## 事件
### onShowPanel
监听 Panel 实例显示事件
### 2. onHidePanel
```typescript
/**
* 监听 panel 显示事件
* set callback for panel shown event
* @param listener
* @returns
*/
onShowPanel(listener: (...args: any[]) => void): IPublicTypeDisposable;
```
onHidePanel(listener: (...args: unknown[]) => void)
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
### onHidePanel
监听 Panel 实例隐藏事件
### 3. onShowWidget
```typescript
/**
* 监听 Panel 实例隐藏事件
* set callback for panel hidden event
* @param listener
* @returns
*/
onHidePanel(listener: (...args: any[]) => void): IPublicTypeDisposable;
```
onShowWidget(listener: (...args: unknown[]) => void)
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
### onShowWidget
监听 Widget 实例显示事件
### 4. onHideWidget
```typescript
/**
* 监听 Widget 显示事件
* set callback for widget shown event
* @param listener
* @returns
*/
onShowWidget(listener: (...args: any[]) => void): IPublicTypeDisposable;
```
onHideWidget(listener: (...args: unknown[]) => void)
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
### onHideWidget
监听 Widget 实例隐藏事件
```typescript
/**
* 监听 Widget 隐藏事件
* set callback for widget hidden event
* @param listener
* @returns
*/
onHideWidget(listener: (...args: any[]) => void): IPublicTypeDisposable;
```
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
## 使用示例
```typescript

146
docs/docs/api/workspace.md Normal file
View File

@ -0,0 +1,146 @@
---
title: workspace - 应用级 API
sidebar_position: 12
---
> **[@experimental](./#experimental)**<br/>
> **@types** [IPublicApiWorkspace](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/workspace.ts)<br/>
> **@since** v1.1.0
## 模块简介
通过该模块可以开发应用级低代码设计器。
## 变量
### isActive
是否启用 workspace 模式
### window
当前设计器窗口模型
```typescript
get window(): IPublicModelWindow
```
关联模型 [IPublicModelWindow](./model/window)
### plugins
应用级别的插件注册
```typescript
get plugins(): IPublicApiPlugins
```
关联模型 [IPublicApiPlugins](./plugins)
### windows
当前设计器的编辑窗口
```typescript
get window(): IPublicModelWindow[]
```
关联模型 [IPublicModelWindow](./model/window)
### resourceList
当前设计器的资源列表数据
```
get resourceList(): IPublicModelResource;
```
关联模型 [IPublicModelResource](./model/resource)
## 方法
### registerResourceType
注册资源
```typescript
/** 注册资源 */
registerResourceType(resourceTypeModel: IPublicTypeResourceType): void;
```
相关类型:[IPublicTypeResourceType](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/resource-type.ts)
### setResourceList
设置设计器资源列表数据
```typescript
setResourceList(resourceList: IPublicResourceList) {}
```
相关类型:[IPublicResourceOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/resource-options.ts)
### openEditorWindow
打开视图窗口
```typescript
openEditorWindow(resourceName: string, title: string, options: Object, viewName?: string): void;
```
### openEditorWindowById
通过视图 id 打开窗口
```typescript
openEditorWindowById(id: string): void;
```
### removeEditorWindow
移除视图窗口
```typescript
removeEditorWindow(resourceName: string, title: string): void;
```
### removeEditorWindowById
通过视图 id 移除窗口
```typescript
removeEditorWindowById(id: string): void;
```
## 事件
### onChangeWindows
窗口新增/删除的事件
```typescript
function onChangeWindows(fn: () => void): IPublicTypeDisposable;
```
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
### onChangeActiveWindow
active 窗口变更事件
```typescript
function onChangeActiveWindow(fn: () => void): IPublicTypeDisposable;
```
相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)
### onResourceListChange
设计器资源列表数据变更事件
```typescript
onResourceListChange(fn: (resourceList: IPublicResourceList): void): (): IPublicTypeDisposable;
```
- 相关类型:[IPublicResourceOptions](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/resource-options.ts)
- 相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts)

View File

@ -4,6 +4,7 @@ title: 低代码引擎相关文章资料
## 官方文章
- [低代码多分支协同开发的建设与实践](https://mp.weixin.qq.com/s/DmwxL67htHfTUP1U966N-Q)
- [低代码引擎半岁啦,来跟大家唠唠嗑...](https://segmentfault.com/a/1190000042884409)
- [低代码技术在研发团队的应用模式探讨](https://mp.weixin.qq.com/s/Ynk_wjJbmNw7fEG6UtGZbQ)
- [关于 LowCode&ProCode 混合研发的思考](https://mp.weixin.qq.com/s/TY3VXjkSmsQoT47xma3wig)
@ -35,4 +36,4 @@ title: 低代码引擎相关文章资料
- [【有翻车】阿里低代码引擎项目实战 (5)-表单回显](https://www.bilibili.com/video/BV1UY4y1v7D7/)
- [阿里低代码引擎项目实战 (6)-自定义插件 - 页面管理 - 后端](https://www.bilibili.com/video/BV1uZ4y1U7Ly/)
- [阿里低代码引擎项目实战 (6)-自定义插件 - 页面管理 - 前端](https://www.bilibili.com/video/BV1Yq4y1a74P/)
- [阿里低代码引擎项目实战 (7)-自定义插件 - 页面管理 (完结)](https://www.bilibili.com/video/BV13Y4y1e7EV/)
- [阿里低代码引擎项目实战 (7)-自定义插件 - 页面管理 (完结)](https://www.bilibili.com/video/BV13Y4y1e7EV/)

View File

@ -5,6 +5,7 @@ tags: [FAQ]
---
## 简单场景
可以利用 props.__designMode
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01btr66024FOEldBOr2_!!6000000007361-2-tps-1616-440.png)
设计态中__designMode 值为 "design"
@ -13,10 +14,12 @@ tags: [FAQ]
## 复杂场景
在资产包里定义 editUrls
![image.png](https://img.alicdn.com/imgextra/i1/O1CN01odal6P27Rhjn8NoJ6_!!6000000007794-2-tps-1590-538.png)
### editUrls
在 lowcode/xx/ 下新建一个 view.tsx
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01q0Bbn91Lrig7d0alA_!!6000000001353-2-tps-598-154.png)
再执行

View File

@ -4,4 +4,4 @@ sidebar_position: 15
tags: [FAQ]
---
你可以通过在线工具「Parts 造物」生产物料描述协议,然后使用到你的项目中去。
文档地址:[利用 Parts 造物快速使用 react 组件](/site/docs/guide/expand/editor/partsIntro)
文档地址:[利用 Parts 造物快速使用 react 组件](/site/docs/guide/expand/editor/parts/partsIntro)

View File

@ -54,13 +54,13 @@ sidebar_position: 0
```html
<!-- 低代码引擎的页面框架样式 -->
<link rel="stylesheet" href="https://alifd.alicdn.com/npm/@alilc/lowcode-engine@latest/dist/css/engine-core.css" />
<link rel="stylesheet" href="https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.18/dist/css/engine-core.css" />
<!-- Fusion Next 控件样式 -->
<link rel="stylesheet" href="https://g.alicdn.com/code/lib/alifd__next/1.23.24/next.min.css">
<!-- 低代码引擎的页面主题样式,可以替换为 theme-lowcode-dark -->
<link rel="stylesheet" href="https://alifd.alicdn.com/npm/@alifd/theme-lowcode-light/0.2.0/next.min.css">
<!-- 低代码引擎官方扩展的样式 -->
<link rel="stylesheet" href="https://alifd.alicdn.com/npm/@alilc/lowcode-engine-ext@latest/dist/css/engine-ext.css" />
<link rel="stylesheet" href="https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine-ext/1.0.5/dist/css/engine-ext.css" />
<!-- React可替换为 production 包 -->
<script src="https://g.alicdn.com/code/lib/react/16.14.0/umd/react.development.js"></script>
@ -76,11 +76,12 @@ sidebar_position: 0
<!-- Fusion Next 的主包,低代码编辑器的依赖 -->
<script src="https://g.alicdn.com/code/lib/alifd__next/1.23.24/next.min.js"></script>
<!-- 低代码引擎的主包 -->
<script crossorigin="anonymous" src="https://alifd.alicdn.com/npm/@alilc/lowcode-engine@latest/dist/js/engine-core.js"></script>
<script crossorigin="anonymous" src="https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.18/dist/js/engine-core.js"></script>
<!-- 低代码引擎官方扩展的主包 -->
<script crossorigin="anonymous" src="https://alifd.alicdn.com/npm/@alilc/lowcode-engine-ext@latest/dist/js/engine-ext.js"></script>
<script crossorigin="anonymous" src="https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine-ext/1.0.5/dist/js/engine-ext.js"></script>
```
> 注:如果 unpkg 的服务比较缓慢,您可以使用 alicdn 来获得确定版本的低代码引擎,如对于引擎的 1.0.1 版本,可用 [https://alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.1/dist/js/engine-core.js](https://alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.1/dist/js/engine-core.js)
> 注:如果 unpkg 的服务比较缓慢,您可以使用官方 CDN 来获得确定版本的低代码引擎,如对于引擎的 1.0.18 版本,可用以下官方 CDN 替代
> - [https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.18/dist/js/engine-core.js](https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.18/dist/js/engine-core.js)
### 配置打包

View File

@ -313,7 +313,7 @@ simulator-renderer 通过调用 host 的方法,将 schema、components 等参
- 被拖拽对象 - `DragObject`
- 拖拽到的目标位置 - `DropLocation`
- 拖拽感应区 - `ISensor`
- 拖拽感应区 - `IPublicModelSensor`
- 定位事件 - `LocateEvent`
##### Sensor

View File

@ -23,7 +23,7 @@ sidebar_position: 1
对于低代码物料来说A 平台创建的物料无法使用到 B 平台上,如果想在 B 平台实现同样的物料,需要按照 B 平台的标准搭建一份物料。
对于 ProCode 物料来说,需要在低代码平台进行消费,是需要进行转换的,包括搭建配置项的生成、物料搭建图等,可能还需要特殊的描述文件进行描述。由于这一层没有统一,同一份 ProCode 物料每接入一个低代码,可能需要的描述文件格式不同,转换的代码不同,使用的工具也不同。
对于 ProCode 物料来说,需要在低代码平台进行消费,是需要进行转换的,包括搭建配置项的生成、物料搭建图等,可能还需要特殊的描述文件进行描述。由于这一层没有统一,同一份 ProCode 物料每接入一个低代码,可能需要的描述文件格式不同,转换的代码不同,使用的工具也不同。
### 生态隔离

View File

@ -1,6 +1,6 @@
---
title: 低代码生态脚手架 & 调试机制
sidebar_position: 7
sidebar_position: 8
---
## 脚手架简述
@ -130,12 +130,13 @@ npm publish
2. 在引擎初始化侧引入插件
```typescript
import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
export default async () => {
// 注意 Inject 插件必须在其他插件前注册,且所有插件的注册必须 await
await plugins.register(Inject);
await plugins.register(OtherPlugin);
await plugins.register((ctx: ILowCodePluginContext) => {
await plugins.register((ctx: IPublicModelPluginContext) => {
return {
name: "editor-init",
async init() {

View File

@ -270,10 +270,11 @@ npm publish
### 在项目中引入资产包
```typescript
import { ILowCodePluginContext, material, plugins } from '@alilc/lowcode-engine';
import { material, plugins } from '@alilc/lowcode-engine';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
// 动态加载 assets
plugins.register((ctx: ILowCodePluginContext) => {
plugins.register((ctx: IPublicModelPluginContext) => {
return {
name: 'ext-assets',
async init() {

View File

@ -10,7 +10,7 @@ sidebar_position: 2
## 可视化生成物料描述
使用 Parts 造物平台:[使用文档](/site/docs/guide/expand/editor/partsIntro)
使用 Parts 造物平台:[使用文档](/site/docs/guide/expand/editor/parts/partsIntro)
## 自动生成物料描述

View File

@ -0,0 +1,4 @@
{
"label": "Parts 造物",
"position": 1
}

View File

@ -0,0 +1,18 @@
---
title: 介绍
sidebar_position: 1
---
## 介绍
![](https://gw.alicdn.com/imgextra/i2/O1CN01Gyq6AZ1nOENPTVXX7_!!6000000005079-2-tps-256-104.png)
「Parts·造物」是基于开源低代码引擎打造的次时代物料研发和集成工具一方面作为低代码引擎搭建低代码平台的一个样板展示开源生态下的各个组件如何集合在一起形成生产力另一方面也可以生产低代码平台所需的物料。
目前「Parts·造物」主要提供两大产品功能
1. React 组件导入低代码引擎:通过在线可视化的「物料描述」配置,任意工具开发的 React 组件都可以快速完成对低代码引擎的适配,导入到低代码引擎项目中进行使用。不必额外开发新的组件。
2. 低代码生产组件:通过低代码的形式生产组件,极低上手门槛,提供丰富的原子组件用于组合,完善的调试预览和组件生命周期控制。生产的组件既可以在低代码引擎项目中使用,也可以出码后在普通源码项目中使用。
## 联系我们
<img src="https://img.alicdn.com/imgextra/i2/O1CN01UF88Xi1jC5SZ6m4wt_!!6000000004511-2-tps-750-967.png" width="300" />

View File

@ -0,0 +1,267 @@
---
title: 资产包管理
sidebar_position: 4
---
## 介绍
通过前述介绍,相信大家已经了解如何使用「[Parts·造物](https://parts.lowcode-engine.cn/)」来将已有的 React 组件快速接入低代码引擎,以及生产低代码组件。
大家在使用的过程中,可能会希望构建出来的资产包可以后续随时访问下载,或者希望构建资产包时各个组件的版本等信息可以持久化起来并且能够多人维护。
通过「[Parts·造物](https://parts.lowcode-engine.cn/)」的 `资产包` 管理功能帮助大家解决这个问题
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01Fkaznh1zWj9wYKpcH_!!6000000006722-2-tps-1702-628.png)
## 新建资产包
首先,我们在 我的资产包 tab 中点击 `新建资产包`
![image.png](https://img.alicdn.com/imgextra/i1/O1CN01qe8zfO1ilysebSfD5_!!6000000004454-2-tps-3064-1432.png)
- 填写资产包名称
- 配置资产包管理员,管理员拥有该资产包的所有权限,初始默认为资产包的创建者,还可以添加其他人作为管理员,
- 配置资产包描述 (可选)
- 点击 `确定`, 即可完成资产包的创建
接下来需要为资产包添加一个或者多个组件。
## 添加组件
第二步:新建完资产包以后,我们就可以为其添加组件了,如果是新建资产包流程,新建完成之后会自动弹出组件配置的弹窗,当然,你可可以通过点击资产包卡片的方式打开组件配置的弹窗。
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01kqymdB1nkDQclPk7F_!!6000000005127-2-tps-965-261.png)
- 点击弹窗中 `添加组件` 按钮,在弹出的组件选择面板中,选中需要添加的组件并点击 `下一步`
![image.png](https://img.alicdn.com/imgextra/i1/O1CN014Baihf1r742Qi1Wel_!!6000000005583-2-tps-1856-1520.png)
- 进入组件版本以及描述协议版本选择界面,选择所需要的正确版本,点击 `安装` 即可完成一个组件的添加。
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01Y7aWWi1MMPDVlidgz_!!6000000001420-2-tps-1668-1462.png)
## 构建资产包
添加完组件以后就点击 `保存并构建资产包` 进入资产包构建配置弹窗
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01iZf4Ue1PlXnyKYxnK_!!6000000001881-2-tps-1288-670.png)
- `开启缓存` : 可充分利用之前的构建结果缓存来加速资产包的生成,我们会将每个组件的构建结果以 包名和版本号为 key 进行缓存。
- `任务描述` : 当前构建任务的一些描述信息。
点击 `确认` 按钮 会自动跳转到当前资产包的构建历史界面:
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01krDaFc1TuTztMPssI_!!6000000002442-2-tps-1726-696.png)
构建历史界面会显示当前资产包所有的构建历史记录,表格状态栏展示了构建的状态:`成功`,`失败`,`正在运行` 三种状态,操作列可以在构建成功时复制或者下载资产包结果
## 使用资产包
你可以在 [lowcode-demo](https://github.com/alibaba/lowcode-demo) 中直接引用,可直接替换 demo 中原来的资产包文件:
例如,在 [demo-lowcode-component](https://github.com/alibaba/lowcode-demo/tree/main/demo-lowcode-component) 中,直接用你的资产包文件替换文件[assets.json](https://github.com/alibaba/lowcode-demo/blob/main/demo-lowcode-component/src/services/assets.json),即可快速使用自己的物料了。
### 在编辑器中使用资产包
在使用含有低代码组件的资产包注意 注意引擎版本必须大于等于 `1.1.0-beta.9`
然后直接替换 [lowcode-demo](https://github.com/alibaba/lowcode-demo) demo 中的 `assets.json` 文件即可。
### 在预览中使用资产包
在预览中使用资产包的整体思路是从 `资产包` 中提取并转换出 `ReactRenderer` 渲染所需要的 react 组件列表 (`components` 参数),然后将 `schema` 以及 `components` 传入到 `ReactRenderer` 中进行渲染,需要注意的是,在 `资产包` 的转换过程中,我们也需要将 `低代码组件` 转换成 react 组件,具体逻辑可以参考下 [demo-lowcode-component](https://github.com/alibaba/lowcode-demo/tree/main/demo-lowcode-component) 中 `src/parse-assets.ts` 文件的实现。
基于资产包进行预览的整体逻辑如下: [详见](https://github.com/alibaba/lowcode-demo/blob/main/demo-lowcode-component/src/preview.tsx)
```ts
import ReactDOM from 'react-dom';
import React, { useState } from 'react';
import { Loading } from '@alifd/next';
import ReactRenderer from '@alilc/lowcode-react-renderer';
import { createFetchHandler } from '@alilc/lowcode-datasource-fetch-handler';
import {
getProjectSchemaFromLocalStorage,
} from './services/mockService';
import assets from './services/assets.json';
import { parseAssets } from './parse-assets';
const getScenarioName = function () {
if (location.search) {
return new URLSearchParams(location.search.slice(1)).get('scenarioName') || 'index';
}
return 'index';
};
const SamplePreview = () => {
const [data, setData] = useState({});
async function init() {
const scenarioName = getScenarioName();
const projectSchema = getProjectSchemaFromLocalStorage(scenarioName);
const { componentsMap: componentsMapArray, componentsTree } = projectSchema;
const schema = componentsTree[0];
const componentsMap: any = {};
componentsMapArray.forEach((component: any) => {
componentsMap[component.componentName] = component;
});
// 特别提醒重点注意!!!:从资产包中解析出所有的 react 组件列表
const { components } = await parseAssets(assets);
setData({
schema,
components,
});
}
const { schema, components } = data;
if (!schema || !components) {
init();
return <Loading fullScreen />;
}
return (
<div className="lowcode-plugin-sample-preview">
<ReactRenderer
className="lowcode-plugin-sample-preview-content"
schema={schema}
// // 将 react 组件列表传入 ReactRenderer 进行渲染
components={components}
appHelper={{
requestHandlersMap: {
fetch: createFetchHandler(),
},
}}
/>
</div>
);
};
ReactDOM.render(<SamplePreview />, document.getElementById('ice-container'));
```
从资产包中解析 react 组件列表的逻辑如下,[详见](https://github.com/alibaba/lowcode-demo/blob/main/demo-lowcode-component/src/parse-assets.ts)
```ts
import { ComponentDescription, ComponentSchema, RemoteComponentDescription } from '@alilc/lowcode-types';
import { buildComponents, AssetsJson, AssetLoader } from '@alilc/lowcode-utils';
import ReactRenderer from '@alilc/lowcode-react-renderer';
import { injectComponents } from '@alilc/lowcode-plugin-inject';
import React, { createElement } from 'react';
export async function parseAssets(assets: AssetsJson) {
const { components: rawComponents, packages } = assets;
const libraryAsset = [];
const libraryMap = {};
const packagesMap = {};
packages.forEach(pkg => {
const { package: _package, library, urls, renderUrls, id } = pkg;
if (_package) {
libraryMap[id || _package] = library;
}
packagesMap[id || _package] = pkg;
if (renderUrls) {
libraryAsset.push(renderUrls);
} else if (urls) {
libraryAsset.push(urls);
}
});
const assetLoader = new AssetLoader();
await assetLoader.load(libraryAsset);
let newComponents = rawComponents;
if (rawComponents && rawComponents.length) {
const componentDescriptions: ComponentDescription[] = [];
const remoteComponentDescriptions: RemoteComponentDescription[] = [];
rawComponents.forEach((component: any) => {
if (!component) {
return;
}
if (component.exportName && component.url) {
remoteComponentDescriptions.push(component);
} else {
componentDescriptions.push(component);
}
});
newComponents = [...componentDescriptions];
// 如果有远程组件描述协议,则自动加载并补充到资产包中,同时出发 designer.incrementalAssetsReady 通知组件面板更新数据
if (remoteComponentDescriptions && remoteComponentDescriptions.length) {
await Promise.all(
remoteComponentDescriptions.map(async (component: any) => {
const { exportName, url, npm } = component;
await (new AssetLoader()).load(url);
function setAssetsComponent(component: any, extraNpmInfo: any = {}) {
const components = component.components;
if (Array.isArray(components)) {
components.forEach(d => {
newComponents = newComponents.concat({
npm: {
...npm,
...extraNpmInfo,
},
...d,
} || []);
});
return;
}
newComponents = newComponents.concat({
npm: {
...npm,
...extraNpmInfo,
},
...component.components,
} || []);
}
function setArrayAssets(value: any[], preExportName: string = '', preSubName: string = '') {
value.forEach((d: any, i: number) => {
const exportName = [preExportName, i.toString()].filter(d => !!d).join('.');
const subName = [preSubName, i.toString()].filter(d => !!d).join('.');
Array.isArray(d) ? setArrayAssets(d, exportName, subName) : setAssetsComponent(d, {
exportName,
subName,
});
});
}
if (window[exportName]) {
if (Array.isArray(window[exportName])) {
setArrayAssets(window[exportName] as any);
} else {
setAssetsComponent(window[exportName] as any);
}
}
return window[exportName];
}),
);
}
}
const lowcodeComponentsArray = [];
const proCodeComponentsMap = newComponents.reduce((acc, cur) => {
if ((cur.devMode || '').toLowerCase() === 'lowcode') {
lowcodeComponentsArray.push(cur);
} else {
acc[cur.componentName] = {
...(cur.reference || cur.npm),
componentName: cur.componentName,
};
}
return acc;
}, {})
function genLowCodeComponentsMap(components) {
const lowcodeComponentsMap = {};
lowcodeComponentsArray.forEach((lowcode) => {
const id = lowcode.reference?.id;
const schema = packagesMap[id]?.schema;
const comp = genLowcodeComp(schema, {...components, ...lowcodeComponentsMap});
lowcodeComponentsMap[lowcode.componentName] = comp;
});
return lowcodeComponentsMap;
}
let components = await injectComponents(buildComponents(libraryMap, proCodeComponentsMap));
const lowCodeComponents = genLowCodeComponentsMap(components);
return {
components: { ...components, ...lowCodeComponents }
}
}
function genLowcodeComp(schema: ComponentSchema, components: any) {
return class LowcodeComp extends React.Component {
render(): React.ReactNode {
return createElement(ReactRenderer, {
...this.props,
schema,
components,
designMode: '',
});
}
};
}
```
## 联系我们
<img src="https://img.alicdn.com/imgextra/i2/O1CN01UF88Xi1jC5SZ6m4wt_!!6000000004511-2-tps-750-967.png" width="300" />

View File

@ -0,0 +1,92 @@
---
title: 低代码组件
sidebar_position: 2
---
## 什么是低代码组件
我们先了解一下什么是低代码组件,为什么要用低代码组件。
低代码组件是通过可视化的方式生产的组件,这些组件既可以用于低代码搭建体系,也可以用于 ProCode 开发体系(后续迭代)。
那么为什么我们要使用低代码的形式来开发组件:
* <font color="red"><b>首先</b></font><b>轻快</b>,低代码组件只需通过浏览器秒级完成初始化工作,不需要 ProCode 繁重的环境准备;<b>环境一致(低代码环境)</b>,同时能够保证物料的开发环境和真实的运行环境是一致的,不会存在开发和运行环境不一致的问题。
* <font color="red"><b>其次</b></font><b>通用能力可视化方式抽象,提升研发效能</b>,比如获取远程数据、视图开发、依赖管理、生命周期、事件绑定等功能。
<font color="red">低代码组件不是用来替代 ProCode 的开发方式</font>,而是让开发者可以从 ProCode 中重复的工作脱离出来,抽象更多业务垂直的能力,从而起到提效的作用。
## 创建组件
环境准备:我们可以通过 Parts 提供的通用[低代码组件开发环境](https://parts.lowcode-engine.cn/material#/)开发。
点击开发新组件 --> 填写组件标题 --> 填写组件名称 --> 点击确定,完成组件创建工作。
![](https://img.alicdn.com/imgextra/i2/O1CN01OTQRew25y6WxuONIx_!!6000000007594-2-tps-3396-1696.png)
## 组件开发
一张图速览低代码组件开发的功能模块,其中大部分功能可以参考[低代码引擎文档](https://lowcode-engine.cn/site/docs/guide/quickStart/intro)。
![](https://img.alicdn.com/imgextra/i1/O1CN01gx96E121qzv4smV2v_!!6000000007037-2-tps-3456-1930.png)
### 依赖管理
依赖管理用于管理低代码组件本身的依赖(类似于 dependencies。步骤点击添加组件 --> 选择安装的组件 --> 保存并构建 (需要等待几分钟构建)。
![](https://img.alicdn.com/imgextra/i4/O1CN01wC9JPK1J9dKLca9wK_!!6000000000986-2-tps-1438-819.png)
### 属性定义
用于定义组件接收外部传入的 propTypes组件内部可以通过<font color="red">this.props.${属性名称}</font>的方式获取属性值。
属性定义前建议先阅读 [物料描述详解](https://lowcode-engine.cn/site/docs/guide/expand/editor/metaSpec)、[预置设置器](https://lowcode-engine.cn/site/docs/guide/appendix/setters)。
![](https://img.alicdn.com/imgextra/i2/O1CN01wesIJA1nL1eSPrk7U_!!6000000005072-2-tps-1438-821.png)
![](https://img.alicdn.com/imgextra/i3/O1CN01FZIRwv1es9lGplgIB_!!6000000003926-2-tps-1438-821.png)
### 生命周期
低代码组件的开发支持 componentDidMount、componentDidUpdate、componentDidCatch、componentWillUnmount 几个生命周期
![](https://img.alicdn.com/imgextra/i4/O1CN010bnrxJ1oLlujlfFqj_!!6000000005209-2-tps-1438-819.png)
### 组件调试
我们提供了一套线上实时调试的方案,只需点击右上角的调试按钮,就能自动创建一个低代码应用,在这个应用中可以实时调试当前的低代码组件。
![](https://img.alicdn.com/imgextra/i2/O1CN01Tk96vp1xrDeNeIUJD_!!6000000006496-2-tps-1438-820.png)
在低代码应用中使用,组件面板 --> 低代码组件,找到对应的低代码组件拖入画布即可。
![](https://img.alicdn.com/imgextra/i2/O1CN01oGHLea1lzDAhZQQVO_!!6000000004889-2-tps-1438-819.png)
### 组件发布
同时我们提供了组件发布的功能,用于组件版本管理,点击右上角的发布按钮即可发布组件
![](https://img.alicdn.com/imgextra/i2/O1CN017suVAD1NXEC8zQgO1_!!6000000001579-2-tps-1438-821.png)
## 组件使用
组件的消费是通过资产包来管理的,详情请参考 [资产包管理](./partsassets)。
## 组件导出
开发好的低代码组件可以导出成为 React 组件,脱离低代码引擎独立使用。同时导出功能也为您的组件留出一份备份,您可以放心使用本产品的服务,而不用担心万一出现的不能服务的场景。
在物料列表页面,低代码组件会有一个导出的动作。
![](https://img.alicdn.com/imgextra/i2/O1CN016oUByO21spVHZvvw2_!!6000000007041-2-tps-1395-413.png)
点击导出后,就会开启导出低代码组件的过程。这个过程持续 10s+,导出完成后会为您自动下载对应的 zip 包。
![](https://img.alicdn.com/imgextra/i1/O1CN01lctpIo1aDcEvu75Mo_!!6000000003296-2-tps-1399-512.png)
zip 包解压后可以看到一个完整的组件脚手架工程,您可以在这个工程里继续开发调试,或者发布到合适的 npm 源中。
![](https://img.alicdn.com/imgextra/i1/O1CN010aAjsf1xYRPZBAh7d_!!6000000006455-2-tps-2154-1072.png)
注意:目前导出功能暂不支持 低代码组件嵌套。
## 联系我们
<img src="https://img.alicdn.com/imgextra/i2/O1CN01UF88Xi1jC5SZ6m4wt_!!6000000004511-2-tps-750-967.png" width="300" />

View File

@ -1,5 +1,5 @@
---
title: 利用 Parts 造物快速使用 react 组件
title: React 组件导入
sidebar_position: 3
---
## 介绍
@ -50,8 +50,6 @@ sidebar_position: 3
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01klci7y1IUPflKpeVB_!!6000000000896-2-tps-1193-704.png)
#### 给组件增加物料描述
选中刚刚新增的 BlockPicker 组件,然后给它增加描述:
- 打开左侧 Setter 面板
- 按照组件的属性拖入需要 Setter 类型(如图中组件的 width 属性,拖入数字 Setter
- 各种 Setter 的介绍可以参看这篇文档:[预置设置器列表](/site/docs/guide/appendix/setters)
@ -102,31 +100,22 @@ sidebar_position: 3
- 点击确定发布完成
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01uwa8RH1QDwM7FN31k_!!6000000001943-2-tps-1431-734.png)
## 资产包构建
## 资产包
第三步:物料描述发布完成后,接下来我们就需要构建出可用的资产包用于低代码应用中。
#### 资产包构建
有两种方式可以构建资产包:
- 一种是通过 [`我的资产包`] 资产包管理模块进行整个资产包生命周期的管理,当然也包括资产包的构建,可参考 [资产包管理](./partsassets)
- 一种是通过 [`我的物料`] 组件物料管理模块的 `资产包构建` 进行构建, 具体操作如下:
- 选择需要构建的组件
- 点击构建资产包按钮
- 选择刚刚的物料描述配置
- 开始构建,构建完成后你将得到一份 json 文件(里面包含了物料描述和 umd 包),就可以到项目中使用了
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01Oc73aw1TH5vlJx9oj_!!6000000002356-2-tps-1431-770.png)
- 选择需要构建的组件
- 点击构建资产包按钮
- 选择刚刚的物料描述配置
- 开始构建,构建完成后你将得到一份 json 文件(里面包含了物料描述和 umd 包),就可以到项目中使用了
#### 资产包使用
详情请参考 [资产包管理](./partsassets#使用资产包)
**方式一、在 **[**lowcode-demo**](https://github.com/alibaba/lowcode-demo)**中直接引用,可直接替换 demo 中原来的资产包文件:**
## 联系我们
例如,在 basic-fusion demo 中,直接用你的资产包文件替换文件[assets.json](https://github.com/alibaba/lowcode-demo/blob/main/demo-basic-fusion/src/services/assets.json),即可快速使用自己的物料了。
**方式二、将新的资产包内容和现有的资产包内容融合:**
将上面构建完成的资产包与你项目中的[assets.json 文件](https://github.com/alibaba/lowcode-demo/blob/main/demo-basic-fusion/src/services/assets.json)合并,主要合并 packages 和 components。
- packages 中是构建好的 umd 包;
- components 中是上面配置好的[物料描述](https://lowcode-engine.cn/material),你也可以在基础上二次加工;
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01m7QkDN1P7hL86mjyH_!!6000000001794-2-tps-1140-744.png)
<img src="https://img.alicdn.com/imgextra/i2/O1CN01UF88Xi1jC5SZ6m4wt_!!6000000004511-2-tps-750-967.png" width="300" />

View File

@ -2,7 +2,9 @@
title: 插件扩展 - 编排扩展
sidebar_position: 6
---
## 场景一:扩展选中节点操作项
### 增加节点操作项
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01J7PrJc1S86XNDBIFQ_!!6000000002201-2-tps-1240-292.png)
@ -10,9 +12,10 @@ sidebar_position: 6
```typescript
import { plugins } from '@alilc/lowcode-engine';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
import { Icon, Message } from '@alifd/next';
const addHelloAction = (ctx: ILowCodePluginContext) => {
const addHelloAction = (ctx: IPublicModelPluginContext) => {
return {
async init() {
const { addBuiltinComponentAction } = ctx.material;
@ -30,7 +33,7 @@ const addHelloAction = (ctx: ILowCodePluginContext) => {
},
important: true,
});
}
},
};
};
addHelloAction.pluginName = 'addHelloAction';
@ -46,8 +49,9 @@ await plugins.register(addHelloAction);
```typescript
import { plugins } from '@alilc/lowcode-engine';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
const removeCopyAction = (ctx: ILowCodePluginContext) => {
const removeCopyAction = (ctx: IPublicModelPluginContext) => {
return {
async init() {
const { removeBuiltinComponentAction } = ctx.material;
@ -66,6 +70,7 @@ await plugins.register(removeCopyAction);
具体 API 参考:[API 文档](/site/docs/api/material#removebuiltincomponentaction)
## 实际案例
### 区块管理
- 仓库地址:[https://github.com/alibaba/lowcode-plugins](https://github.com/alibaba/lowcode-plugins)

View File

@ -2,6 +2,7 @@
title: 插件扩展 - 面板扩展
sidebar_position: 5
---
## 插件简述
插件功能赋予低代码引擎更高的灵活性,低代码引擎的生态提供了一些官方的插件,但是无法满足所有人的需求,所以提供了强大的插件定制功能。
@ -17,12 +18,13 @@ sidebar_position: 5
## 注册插件 API
```typescript
import { plugins, ILowCodePluginContext } from '@alilc/lowcode-engine';
import { plugins } from '@alilc/lowcode-engine';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
const pluginA = (ctx: ILowCodePluginContext, options: any) => {
const pluginA = (ctx: IPublicModelPluginContext, options: any) => {
return {
init() {
console.log(options.key);
console.log(options.key);
// 往引擎增加面板
ctx.skeleton.add({
// area 配置见下方说明
@ -35,9 +37,9 @@ const pluginA = (ctx: ILowCodePluginContext, options: any) => {
},
destroy() {
console.log('我被销毁了~');
}
}
}
},
};
};
pluginA.pluginName = 'pluginA';
@ -55,6 +57,7 @@ plugins.register(pluginA, { key: 'test' });
![image.png](https://img.alicdn.com/imgextra/i3/O1CN01y05ZHC1Gix0p4nXxH_!!6000000000657-2-tps-3068-1648.png)
### 展示区域 area
#### topArea
展示在设计器的顶部区域,常见的相关区域的插件主要是:、
@ -75,6 +78,7 @@ plugins.register(pluginA, { key: 'test' });
4. JS 等代码面板。
可以发现,这个区域的面板大多数操作时是不需要同时并存的,且交互比较复杂的,需要一个更整块的区域来进行操作。
#### centerArea
画布区域,由于画布大多数是展示作用,所以一般扩展的种类比较少。常见的扩展有:
@ -105,12 +109,12 @@ PanelDock 是以面板的形式展示在设计器的左侧区域的。其中主
接入可以参考代码
```javascript
import { skeleton } from "@alilc/lowcode-engine";
import { skeleton } from '@alilc/lowcode-engine';
skeleton.add({
area: "leftArea", // 插件区域
type: "PanelDock", // 插件类型,弹出面板
name: "sourceEditor",
area: 'leftArea', // 插件区域
type: 'PanelDock', // 插件类型,弹出面板
name: 'sourceEditor',
content: SourceEditor, // 插件组件实例
props: {
align: "left",
@ -138,12 +142,12 @@ Widget 形式是直接渲染在当前编辑器的对应位置上。如 demo 中
接入可以参考代码:
```javascript
import {skeleton} from "@alilc/lowcode-engine";
import { skeleton } from '@alilc/lowcode-engine';
// 注册 logo 面板
skeleton.add({
area: "topArea",
type: "Widget",
name: "logo",
area: 'topArea',
type: 'Widget',
name: 'logo',
content: Logo, // Widget 组件实例
contentProps: { // Widget 插件 props
logo:
@ -151,7 +155,7 @@ skeleton.add({
href: "/",
},
props: {
align: "left",
align: 'left',
width: 100,
},
});
@ -162,7 +166,7 @@ skeleton.add({
一个图标的表现形式,可以用于语言切换、跳转到外部链接、打开一个 widget 等场景。
```javascript
import { skeleton } from "@alilc/lowcode-engine";
import { skeleton } from '@alilc/lowcode-engine';
skeleton.add({
area: 'leftArea',
@ -175,12 +179,12 @@ skeleton.add({
props: {
align: 'bottom',
},
onClick: function() {
onClick: function () {
// 打开外部链接
window.open('https://lowcode-engine.cn');
// 显示 widget
skeleton.showWidget('xxx');
}
},
});
```
@ -210,4 +214,4 @@ skeleton.add({
- [阿里巴巴低代码引擎项目实战 (11)-区块管理 - ICON 优化](https://www.bilibili.com/video/BV1zr4y1H7Km/)
- [阿里巴巴低代码引擎项目实战 (11)-区块管理 - 自动截图](https://www.bilibili.com/video/BV1GZ4y117VH/)
- [阿里巴巴低代码引擎项目实战 (11)-区块管理 - 样式优化](https://www.bilibili.com/video/BV1Pi4y1S7ZT/)
- [阿里低代码引擎项目实战 (12)-区块管理 (完结)-给引擎插件提个 PR](https://www.bilibili.com/video/BV1hB4y1277o/)
- [阿里低代码引擎项目实战 (12)-区块管理 (完结)-给引擎插件提个 PR](https://www.bilibili.com/video/BV1hB4y1277o/)

View File

@ -1,6 +1,6 @@
---
title: 设置器扩展
sidebar_position: 4
sidebar_position: 5
---
## 设置器简述

View File

@ -34,10 +34,11 @@ material.setAssets(assets);
也可以通过异步加载物料中心上的物料。
```typescript
import { ILowCodePluginContext, material, plugins } from '@alilc/lowcode-engine';
import { material, plugins } from '@alilc/lowcode-engine';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
// 动态加载 assets
plugins.register((ctx: ILowCodePluginContext) => {
plugins.register((ctx: IPublicModelPluginContext) => {
return {
name: 'ext-assets',
async init() {
@ -57,7 +58,8 @@ plugins.register((ctx: ILowCodePluginContext) => {
### 配置插件
可以通过 npm 包的方式引入社区插件,配置如下所示:
```typescript
import { ILowCodePluginContext, plugins } from '@alilc/lowcode-engine';
import { plugins } from '@alilc/lowcode-engine';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
import PluginIssueTracker from '@alilc/lowcode-plugin-issue-tracker';
// 注册一个提 issue 组件到您的编辑器中,方位默认在左栏下侧

View File

@ -2,68 +2,93 @@
sidebar_position: 2
title: 快速开始
---
## 前置知识
我们假定你已经对 HTML 和 JavaScript 都比较熟悉了。即便你之前使用其他编程语言,你也可以跟上这篇教程的。除此之外,我们假定你也已经熟悉了一些编程的概念,例如,函数、对象、数组,以及 class 的一些内容。
如果你想回顾一下 JavaScript你可以阅读[这篇教程](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/A_re-introduction_to_JavaScript)。注意,我们也用到了一些 ES6较新的 JavaScript 版本)的特性。在这篇教程里,我们主要使用了[箭头函数arrow functions](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Functions/Arrow_functions)、[class](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Classes)、[let](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/let) 语句和 [const](https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/const) 语句。你可以使用 [Babel REPL](https://babeljs.io/repl/#?presets=react&code_lz=MYewdgzgLgBApgGzgWzmWBeGAeAFgRgD4AJRBEAGhgHcQAnBAEwEJsB6AwgbgChRJY_KAEMAlmDh0YWRiGABXVOgB0AczhQAokiVQAQgE8AkowAUAcjogQUcwEpeAJTjDgUACIB5ALLK6aRklTRBQ0KCohMQk6Bx4gA) 在线预览 ES6 的编译结果。
## 环境准备
### WSLWindow 电脑)
Window 环境需要使用 WSL 在 windows 下进行低代码引擎相关的开发。安装教程 ➡️ [WSL 安装教程](https://docs.microsoft.com/zh-cn/windows/wsl/install)。<br />**对于 Window 环境来说,之后所有需要执行命令的操作都是在 WSL 终端执行的。**
### Node
node 版本推荐 16.18.0。
#### 查看 Node 版本
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01oCZKNz290LIu8YUTk_!!6000000008005-2-tps-238-70.png)
#### 通过 n 来管理 node 版本
可以安装 [n](https://www.npmjs.com/package/n) 来管理和变更 node 版本。
##### 安装 n
```bash
npm install -g n
```
##### 变更 node 版本
```bash
n 14.17.0
```
### React
低代码引擎的扩展能力都是基于 React 来研发的,在继续阅读之前最好有一定的 React 基础React 学习教程 ➡️ [React 快速开始教程](https://zh-hans.reactjs.org/docs/getting-started.html)。
### 下载 Demo
可以前往 githubhttps://github.com/alibaba/lowcode-demo将 DEMO 下载到本地。
可以前往 github<https://github.com/alibaba/lowcode-demo>)将 DEMO 下载到本地。
#### git clone
##### HTTPS
需要使用到 git 工具
```bash
git clone https://github.com/alibaba/lowcode-demo.git
```
##### SSH
需要配置 SSH key如果没有配置可以
```bash
git clone git@github.com:alibaba/lowcode-demo.git
```
#### 下载 Zip 包
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01iYC7E11phaNwLFUrN_!!6000000005392-2-tps-3584-1794.png)
### 选择一个 demo 项目
在 以 `demo-general` 为例:
在 以 `demo-general` 为例:
```bash
cd demo-general
```
### 安装依赖
`lowcode-demo/demo-general` 目录下执行:
```bash
npm install
```
### 启动 demo
`lowcode-demo/demo-general` 目录下执行:
```bash
npm run start
```
@ -71,6 +96,7 @@ npm run start
之后就可以通过 [http://localhost:5556/](http://localhost:5556/) 来访问我们的 DEMO 了。
## 认识 Demo
我们的 Demo 是一个**低代码平台的设计器**。它是一个低代码平台中最重要的一环,用户可以在这里通过拖拽、配置、写代码等等来完成一个页面的开发。由于用户的人群不同、场景不同、诉求不同等等,这个页面的功能就会有所差异。
这里记住**设计器**这个词,它描述的就是下面的这个页面,后面我们会经常看到它。
@ -95,6 +121,7 @@ Demo 根据**不同的设计器所需要的物料不同**,分为了下面的 8
![](https://img.alicdn.com/imgextra/i1/O1CN01EU2jRN1wUwlal17WK_!!6000000006312-2-tps-3110-1974.png)
### 目录介绍
仓库下每个 demo-xxx-xxx 目录都是一个可独立运行的 demo 工程,分别对应到刚刚介绍的场景。
![image.png](https://img.alicdn.com/imgextra/i1/O1CN01ztxv5Y1mJozBsLdni_!!6000000004934-2-tps-696-958.png)
@ -104,11 +131,12 @@ Demo 根据**不同的设计器所需要的物料不同**,分为了下面的 8
![image.png](https://img.alicdn.com/imgextra/i1/O1CN01A50oW522S5zg2eDUH_!!6000000007118-2-tps-732-1384.png)
介绍下其中主要的内容
- 设计器入口文件 `source/index.ts` 这个文件做了下述几个事情:
- 设计器入口文件 `src/index.ts` 这个文件做了下述几个事情:
- 通过 plugins.register 注册各种插件,包括官方插件 (已发布 npm 包形式的插件) 和 `plugins` 目录下内置的示例插件
- 通过 init 初始化低代码设计器
- plugins 目录,存放的都是示例插件,方便用户从中看到一个插件是如何实现的
- services 目录,模拟数据请求、提供默认 schema、默认资产包等此目录下内容在真是项目中应替换成真是的与服务端交互的服务。
- services 目录,模拟数据请求、提供默认 schema、默认资产包等此目录下内容在真实项目中应替换成真实的与服务端交互的服务。
- 预览页面入口文件 `preview.tsx`
剩下的各位看官可以通过源码来进一步了解。
@ -118,16 +146,20 @@ Demo 根据**不同的设计器所需要的物料不同**,分为了下面的 8
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01YJVcOd1PiL1am6bz2_!!6000000001874-2-tps-3248-1970.png)
接下来我们就根据我们自己的诉求通过对设计器进行扩展,改动成我们需要的设计器功能。
## 开发一个插件
### 方式 1在 DEMO 中直接新增插件
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01pXpSRs1QvRyut2EE3_!!6000000002038-2-tps-718-1144.png)
可以在 demo/sample-plugins 直接新增插件,这里我新增的插件目录是 plugin-demo。并且新增了 index.tsx 文件,将下面的代码粘贴到 index.tsx 中。
```javascript
import * as React from 'react';
import { ILowCodePluginContext } from '@alilc/lowcode-engine';
import { IPublicModelPluginContext } from '@alilc/lowcode-types';
const LowcodePluginPluginDemo = (ctx: ILowCodePluginContext) => {
const LowcodePluginPluginDemo = (ctx: IPublicModelPluginContext) => {
return {
// 插件对外暴露的数据和方法
exports() {
@ -136,7 +168,7 @@ const LowcodePluginPluginDemo = (ctx: ILowCodePluginContext) => {
func: () => {
console.log('方法也是一样');
},
}
};
},
// 插件的初始化函数,在引擎初始化之后会立刻调用
init() {
@ -170,7 +202,7 @@ LowcodePluginPluginDemo.meta = {
engines: {
lowcodeEngine: '^1.0.0', // 插件需要配合 ^1.0.0 的引擎才可运行
},
}
};
export default LowcodePluginPluginDemo;
```
@ -182,8 +214,11 @@ export default LowcodePluginPluginDemo;
这样在我们的设计器中就新增了一个 Demo 面板。
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01wtPIOV1TQiFLz5Vkf_!!6000000002377-2-tps-3584-1806.png)
### 方式 2在新的仓库下开发插件
初始化
```bash
npm init @alilc/element your-plugin-name
```
@ -201,11 +236,13 @@ npm init @alilc/element your-plugin-name
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01iVIAXD1XVWsOdKttI_!!6000000002929-2-tps-3584-2020.png)
在插件项目下安装依赖
```bash
npm install
```
启动项目
```bash
npm run start
```
@ -220,9 +257,10 @@ npm run start
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01uqSmrX1oqupxeGH1m_!!6000000005277-2-tps-3584-2020.png)
## 开发一个自定义物料
### 初始化物料
```bash
npm init @alilc/element your-material-demo
```
@ -240,11 +278,15 @@ npm init @alilc/element your-material-demo
![image.png](https://img.alicdn.com/imgextra/i1/O1CN01SU2xn91TZPlzcARVI_!!6000000002396-2-tps-3584-2020.png)
### 启动并调试物料
#### 安装依赖
```bash
npm i
```
#### 启动
```bash
npm run lowcode:dev
```
@ -252,7 +294,9 @@ npm run lowcode:dev
我们就可以通过 [http://localhost:3333/](http://localhost:3333/) 看到我们的研发的物料了。
![image.png](https://img.alicdn.com/imgextra/i4/O1CN01JqoHqc1z7zlSWFYJD_!!6000000006668-2-tps-3584-1790.png)
#### 在 Demo 中调试
```bash
npm i @alilc/build-plugin-alt
```
@ -262,6 +306,7 @@ npm i @alilc/build-plugin-alt
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01K7u7ci1KCfYlBj2yf_!!6000000001128-2-tps-1388-1046.png)
如图,新增如下代码
```javascript
[
'@alilc/build-plugin-alt',
@ -281,12 +326,15 @@ npm i @alilc/build-plugin-alt
![image.png](https://img.alicdn.com/imgextra/i1/O1CN0166WywE26Lv7NuJMus_!!6000000007646-2-tps-3584-1812.png)
### 发布
首先进行构建
```bash
npm run lowcode:build
```
发布组件
```bash
npm publish
```
@ -344,6 +392,7 @@ npm publish
```
### 使用
我们将刚刚发布的组件的 assets-prod.json 的内容放到 demo 的 src/universal/assets.json 中。
> 最好放到最后,防止因为资源加载顺序问题导致出现报错。
@ -356,5 +405,7 @@ npm publish
![image.png](https://img.alicdn.com/imgextra/i2/O1CN01UNp89s1vQXKyfsFaL_!!6000000006167-2-tps-3584-2020.png)
这时候再启动 DEMO 项目,就会有新的低代码物料了。接下来就按照你们的需求,继续扩展物料吧。
## 总结
这里只是简单的介绍了一些低代码引擎的基础能力,带大家简单的对低代码 DEMO 进行扩展,定制一些新的功能。低代码引擎的能力还有很多很多,可以继续去探索更多的功能。

View File

@ -2,13 +2,21 @@
title: 工程化配置
sidebar_position: 3
---
目前引擎体系共包含 2 个 js 文件,即:
目前引擎体系共包含 2 个 js 文件 (配套 2 个 css),即:
```html
<!-- engine-core 引擎的 core负责引擎的基础模块 -->
<script crossorigin="anonymous" src="//alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.0/dist/js/engine-core.js"></script>
<!-- engine-ext 引擎的扩展包,负责收拢内置 setters / plugins方便迭代 -->
<script crossorigin="anonymous" src="//alifd.alicdn.com/npm/@alilc/lowcode-engine-ext@1.0.1/dist/js/engine-ext.js"></script>
<!-- 低代码引擎的页面框架样式 -->
<link rel="stylesheet" href="https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.18/dist/css/engine-core.css" />
<!-- 低代码引擎官方扩展的样式 -->
<link rel="stylesheet" href="https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine-ext/1.0.5/dist/css/engine-ext.css" />
<!-- 低代码引擎的主包 -->
<script crossorigin="anonymous" src="https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.18/dist/js/engine-core.js"></script>
<!-- 低代码引擎官方扩展的主包 -->
<script crossorigin="anonymous" src="https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine-ext/1.0.5/dist/js/engine-ext.js"></script>
```
> 注,这里的版本号是示例,请尽量选用最新版
工程化配置我们进行了统一,具体如下:
@ -66,15 +74,15 @@ sidebar_position: 3
#### 所有资源:
```html
<link rel="stylesheet" href="//alifd.alicdn.com/npm/@alifd/next/1.20.25/next.min.css">
<link rel="stylesheet" href="//alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.0/dist/css/engine-core.css"/>
<link rel="stylesheet" href="//alifd.alicdn.com/npm/@alilc/lowcode-engine-ext@1.0.1/dist/css/engine-ext.css"/>
<link rel="stylesheet" href="//uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.18/dist/css/engine-core.css"/>
<link rel="stylesheet" href="//uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.5/dist/css/engine-ext.css"/>
<script src="//polyfill.alicdn.com/s/polyfill.min.js?features=default,es2017,es6,fetch,RegeneratorRuntime"></script>
<script src="//alifd.alicdn.com/npm/@alifd/next/1.20.25/next.min.js"></script>
<script src="//g.alicdn.com/platform/c/lodash/4.6.1/lodash.min.js"></script>
<script src="//g.alicdn.com/mylib/moment/2.24.0/min/moment.min.js"></script>
<!-- engine-core 引擎的 core负责引擎的基础模块 -->
<script crossorigin="anonymous" src="//alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.0/dist/js/engine-core.js"></script>
<script crossorigin="anonymous" src="//uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.18/dist/js/engine-core.js"></script>
<!-- engine-ext 引擎的扩展包,负责收拢内置 setters / plugins方便迭代 -->
<script crossorigin="anonymous" src="//alifd.alicdn.com/npm/@alilc/lowcode-engine-ext@1.0.1/dist/js/engine-ext.js"></script>
<script crossorigin="anonymous" src="//uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.5/dist/js/engine-ext.js"></script>
```

View File

@ -70,9 +70,10 @@ sidebar_position: 2
```bash
npm run pub
```
5. 同步到 tnpm 源 & alifd CDN此步骤将发布在 npm 源的包同步到阿里内网源,因为 alifd cdn 将依赖内网 npm 源)
5. 同步到 tnpm 源 & alifd CDN & uipaas CDN(此步骤将发布在 npm 源的包同步到阿里内网源,因为 alifd cdn 将依赖内网 npm 源)
```bash
tnpm run sync
tnpm run syncOss
```
6. 更新[发布日志](https://github.com/alibaba/lowcode-engine/releases)
7. 合并 release/x.x.x 到 main 分支
@ -102,9 +103,10 @@ sidebar_position: 2
```bash
npm run pub:preminor
```
5. 同步到 tnpm 源 & alifd CDN
5. 同步到 tnpm 源 & alifd CDN & uipaas CDN
```bash
tnpm run sync
tnpm run syncOss
```
#### 发某 z 位版本首个 beta如 1.0.1-beta.0
@ -129,9 +131,10 @@ sidebar_position: 2
```bash
npm run pub:prepatch
```
5. 同步到 tnpm 源 & alifd CDN
5. 同步到 tnpm 源 & alifd CDN & uipaas CDN
```bash
tnpm run sync
tnpm run syncOss
```
#### 发某版本非首个 beta如 1.0.1-beta.0 -> 1.0.1-beta.1
@ -151,9 +154,10 @@ sidebar_position: 2
```bash
npm run pub:prerelease
```
5. 同步到 tnpm 源 & alifd CDN
5. 同步到 tnpm 源 & alifd CDN & uipaas CDN
```bash
tnpm run sync
tnpm run syncOss
```
@ -173,9 +177,10 @@ sidebar_position: 2
```bash
npm publish --tag beta
```
4. 同步到 tnpm 源 & alifd CDN
4. 同步到 tnpm 源 & alifd CDN & uipaas CDN
```bash
tnpm run sync
tnpm run syncOss
```
**官网生效**

View File

@ -32,27 +32,27 @@ npm install && npm start
{
"proxy": [
[
"https://alifd.alicdn.com/npm/@alilc/lowcode-engine@(.*)/dist/js/engine-core.js",
"https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/js/engine-core.js",
"http://localhost:5555/js/engine-core.js"
],
[
"https://alifd.alicdn.com/npm/@alilc/lowcode-engine@(.*)/dist/css/engine-core.css",
"https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/engine-core.css",
"http://localhost:5555/css/engine-core.css"
],
[
"https?://alifd.alicdn.com/npm/@alilc/lowcode-engine@(.*)/dist/js/react-simulator-renderer.js",
"https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/js/react-simulator-renderer.js",
"http://localhost:5555/js/react-simulator-renderer.js"
],
[
"https?://alifd.alicdn.com/npm/@alilc/lowcode-engine@(.*)/dist/css/react-simulator-renderer.css",
"https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/react-simulator-renderer.css",
"http://localhost:5555/css/react-simulator-renderer.css"
],
[
"https?://alifd.alicdn.com/npm/@alilc/lowcode-engine@(.*)/dist/js/rax-simulator-renderer.js",
"https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/js/rax-simulator-renderer.js",
"http://localhost:5555/js/rax-simulator-renderer.js"
],
[
"https?://alifd.alicdn.com/npm/@alilc/lowcode-engine@(.*)/dist/css/rax-simulator-renderer.css",
"https?://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/(.*)/dist/css/rax-simulator-renderer.css",
"http://localhost:5555/css/rax-simulator-renderer.css"
],
]

View File

@ -2,8 +2,6 @@
title: 《低代码引擎资产包协议规范》
sidebar_position: 2
---
# 《低代码引擎资产包协议规范》
## 1 介绍
### 1.1 本协议规范涉及的问题域

View File

@ -2,8 +2,6 @@
title: 《低代码引擎搭建协议规范》
sidebar_position: 0
---
# 《低代码引擎搭建协议规范》
## 1 介绍
@ -281,7 +279,7 @@ sidebar_position: 0
| 参数 | 说明 | 类型 | 变量支持 | 默认值 |
| --------------- | ---------------------- | ------------------------- | -------- | ------ |
| componentsMap[] | 描述组件映射关系的集合 | Array\<**ComponentMap**\> | - | null |
| componentsMap[] | 描述组件映射关系的集合 | **ComponentMap**[] | - | null |
**ComponentMap 结构描述**如下:
@ -413,7 +411,7 @@ import { Input as CustomInput } from '@ali/custom/lib/input';
| 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 |
| ----------- | ---------------------- | -------------------------------------- | -------- | ------ | ----------------------------------------------------------------------------------------------------------- |
| list[] | 数据源列表 | Array\<**ComponentDataSourceItem**\> | - | - | 成为为单个请求配置, 内容定义详见 [ComponentDataSourceItem 对象描述](#2314-componentdatasourceitem-对象描述) |
| list[] | 数据源列表 | **ComponentDataSourceItem**[] | - | - | 成为为单个请求配置, 内容定义详见 [ComponentDataSourceItem 对象描述](#2314-componentdatasourceitem-对象描述) |
| dataHandler | 所有请求数据的处理函数 | Function | - | - | 详见 [dataHandler Function 描述](#2317-datahandler-function 描述) |
##### 2.3.1.4 ComponentDataSourceItem 对象描述
@ -607,7 +605,7 @@ try {
| props { } | 组件属性对象 | **Props** | - | {} | 必填,详见 [Props 结构描述](#2311-props-结构描述) |
| static | 低代码业务组件类的静态对象 | | | | |
| defaultProps | 低代码业务组件默认属性 | Object | - | - | 选填,仅用于定义低代码业务组件的默认属性 |
| propDefinitions | 低代码业务组件属性类型定义 | **Array\<ComponentPropDefinition\>** | - | - | 选填,仅用于定义低代码业务组件的属性数据类型。详见 [ComponentPropDefinition 对象描述](#2318-componentpropdefinition-对象描述) |
| propDefinitions | 低代码业务组件属性类型定义 | **ComponentPropDefinition**[] | - | - | 选填,仅用于定义低代码业务组件的属性数据类型。详见 [ComponentPropDefinition 对象描述](#2318-componentpropdefinition-对象描述) |
| condition | 渲染条件 | Boolean | ✅ | true | 选填,根据表达式结果判断是否渲染物料;支持变量表达式 |
| state | 容器初始数据 | Object | ✅ | - | 选填,支持变量表达式 |
| children | 子组件 | Array | - | | 选填,支持变量表达式 |
@ -751,7 +749,7 @@ try {
| 参数 | 说明 | 值类型 | 默认值 | 备注 |
| ----- | ---------- | --------------------- | -------- | -------------------------------------------------------------- |
| type | 值类型描述 | String | 'JSSlot' | 固定值 |
| value | 具体的值 | Array\<NodeSchema\> | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述A) |
| value | 具体的值 | NodeSchema \| NodeSchema[] | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述A) |
举例描述:如 **Card** 的 **title** 属性
@ -782,8 +780,8 @@ try {
| 参数 | 说明 | 值类型 | 默认值 | 备注 |
| ------ | ---------- | --------------------- | -------- | -------------------------------------------------------------- |
| type | 值类型描述 | String | 'JSSlot' | 固定值 |
| value | 具体的值 | Array\<NodeSchema\> | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述 a) |
| params | 函数的参数 | Array\<String\> | null | 函数的入参,其子节点可以通过 `this[参数名]` 来获取对应的参数。 |
| value | 具体的值 | NodeSchema \| NodeSchema[] | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述 a) |
| params | 函数的参数 | String[] | null | 函数的入参,其子节点可以通过 `this[参数名]` 来获取对应的参数。 |
举例描述:如 **Table.Column****cell** 属性
@ -1106,7 +1104,7 @@ this.setState((prevState) => ({ count: prevState.count + 1 }));
| 参数 | 说明 | 类型 | 支持变量 | 默认值 |
| ------------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------- | -------- | ------ |
| utils[] | 工具类扩展映射关系 | Array\<**UtilItem**\> | - | |
| utils[] | 工具类扩展映射关系 | **UtilItem**[] | - | |
| *UtilItem*.name | 工具类扩展项名称 | String | - | |
| *UtilItem*.type | 工具类扩展项类型 | 枚举, `'npm'` (代表公网 npm 类型) / `'tnpm'` (代表阿里巴巴内部 npm 类型) / `'function'` (代表 Javascript 函数类型) | - | |
| *UtilItem*.content | 工具类扩展项内容 | [ComponentMap 类型](#22-组件映射关系 a) 或 [JSFunction](#2432事件函数类型 a) | - | |

View File

@ -2,7 +2,6 @@
title: 《低代码引擎物料协议规范》
sidebar_position: 1
---
# 《低代码引擎物料协议规范》
## 1 介绍
@ -85,7 +84,7 @@ component // 组件名称, 比如 biz-button
```
#### README.md
##### README.md
- README.md 应该包含业务组件的源信息、使用说明以及 API示例如下
@ -127,7 +126,7 @@ npm install @alifd/ice-layout -S
| type | type | String | `primray``normal` | normal |
```
#### package.json
##### package.json
`package.json` 中包含了一些依赖信息和配置信息,示例如下:
```json
@ -160,7 +159,7 @@ npm install @alifd/ice-layout -S
}
```
#### src/index.js
##### src/index.js
包含组件的出口文件,示例如下:
@ -179,7 +178,7 @@ export default Button;
import Button, { Group } form '@scope/button';
```
#### src/index.scss
##### src/index.scss
```css
/* 不引入依赖组件的样式,比如组件 import { Button } from '@alifd/next'; */
@ -194,7 +193,7 @@ import Button, { Group } form '@scope/button';
}
```
#### demo
##### demo
demo 目录存放的是组件的文档,无文档的业务组件无法带来任何价值,因此 demo 是必选项。demo 目录下的文件采取 markdown 的写法可以是多个文件示例demo/basic.md如下
demo/basic.md
@ -237,12 +236,12 @@ ReactDOM.render(<div className="test">
API 是组件的属性解释,给开发者作为组件属性配置的参考。为了保持 API 的一致性,我们制定这个 API 命名规范。对于业界通用的,约定俗成的命名,我们遵循社区的约定。对于业界有多种规则难以确定的,我们确定其中一种,大家共同遵守。
#### 通用规则
##### 通用规则
- 所有的 API 采用小驼峰的书写规则,如 `onChange``direction``defaultVisible`
- 标签名采用大驼峰书写规则,如 `Menu``Slider``DatePicker`
#### 通用命名
##### 通用命名
| API 名称 | 类型 | 描述 | 常见变量 |
| :------------- | :------------- | :----------------------------------------------------------- | :---------------------------------------------------- |
@ -262,7 +261,7 @@ API 是组件的属性解释,给开发者作为组件属性配置的参考。
| has+'属性' | boolean | 拥有某个属性 | 例如 `hasArrow` `hasHeader` `hasClose` 等等 |
#### 多选枚举
##### 多选枚举
当某个 API 的接口,允许用户指定多个枚举值的时候,我们把这个接口定义为多选枚举。一个很典型的例子是某个弹层组件的 `closable` 属性,我们会允许:键盘 esc 按键、点击 mask、点击 close 按钮、点击组件以外的任何区域进行关闭。
@ -281,11 +280,11 @@ true 表示触发规则都会关闭false 表示触发规则不会关闭。
- `<Dialog closable={false} />`,任何情况下都不关闭,只能通过受控设置 visible
- `<Dialog closable closeMode={['close', 'esc']} />`,用户按 esc 或者点击关闭按钮会关闭
#### 事件
##### 事件
- 标准事件或者自定义的符合 w3c 标准的事件,命名必须 on 开头, 即 `on` + 事件名,如 onExpand。
#### 表单规范
##### 表单规范
- 支持[受控模式](https://reactjs.org/docs/forms.html#controlled-components)(value + onChange) A)
- value 控制组件数据展现
@ -293,7 +292,7 @@ true 表示触发规则都会关闭false 表示触发规则不会关闭。
- `value={undefined}`的时候清空数据field 的 reset 函数会给所有组件下发 undefined 数据 (AA))
- 一次完整操作抛一次 onChange 事件 `建议` 比如有 Process 表示进展中的状态,建议增加 API `onProcess`;如果有 Start 表示启动状态,建议增加 API `onStart`  (AA)
#### 属性的传递
##### 属性的传递
**1. 原子组件Atomic Component**
> 最小粒子,不能再拆分的组件
@ -355,7 +354,7 @@ $ iceworks sync
文件命名采取 [bcp47](https://tools.ietf.org/html/bcp47) 规范
#### 目录规范
##### 目录规范
在 `src` 目录新增 `locale` 目录用于管理不同语言的文案。
@ -368,7 +367,7 @@ $ iceworks sync
|------ ja-JP.js
```
#### 定义不同的语言
##### 定义不同的语言
```javascript
// zh-CN.js
@ -391,7 +390,7 @@ export default {
};
```
#### 组件支持多语言建议方案
##### 组件支持多语言建议方案
```jsx
// index.jsx
@ -418,7 +417,7 @@ export default class BizHello extends Component {
}
```
#### 组件支持全局替换国际化文案
##### 组件支持全局替换国际化文案
配合 ConfigProvider 支持全局替换国际化文案。
@ -452,7 +451,7 @@ export default ConfigProvider.config(BizHello, {
业务组件中如果有自定义的需要跟随主题色的 UI一定要引入变量的形式增加组件的流通性。
#### src/index.scss
##### src/index.scss
```css
/* 如果需要引入主题变量引入此段 */
@ -504,7 +503,7 @@ api 属性标准参考 [https://fusion.design/help.html#/dev-biz](https://fusio
无障碍需要符合 [WCAG 2.1 A 级标准](https://www.w3.org/TR/WCAG21/),可参考 [W3C 无障碍最佳实践](https://www.w3.org/TR/wai-aria-practices-1.1/)、[Fusion 无障碍指引 2.3.1](https://alibaba-fusion.github.io/next/part1/basics.html) 章节等。
#### 增加 a11y.md 无障碍 demo
##### 增加 a11y.md 无障碍 demo
必须借助 API 才能完成无障碍工作的组件必须为开发者提供无障碍的使用文档,请[参考](https://fusion.design/pc/component/select?themeid=2#accessibility-container)组件 API 中 `ARIA and Keyboard` ,建议在 `demo` 目录新增 `a11y.md` 文件用于演示组件的无障碍使用。
@ -518,7 +517,7 @@ component
详细指引查看无障碍开发指南 [https://alibaba-fusion.github.io/next/part1/basics.html](https://alibaba-fusion.github.io/next/part1/basics.html)。
#### 通过键盘快速访问
##### 通过键盘快速访问
一般键盘事件有 Up Arrow/Down Arrow/Enter/Esc/Tab
@ -532,7 +531,7 @@ component
| Esc | 关闭列表 |
#### 对读屏软件友好
##### 对读屏软件友好
- 对于组件,我们为开发者内置 `role` 和特定 `aria-_属性`,开发者也可以对非组件 API 属性都可以透传至 DOM 元素,进行修改 `role``aria-_参数`,但是要注意对应关系,请[参考](https://alibaba-fusion.github.io/next/part1/WAI-ARIA.html)。
- 对一些特殊的组件传递参数才能支持无障碍,设置 `id``autoFocus` 和传参数,如下:
@ -926,18 +925,18 @@ props 数组下对象字段描述:
|initialChildren | 组件拖入“设计器”时根据此配置自动生成 children 节点 schema |NodeData[]/Function NodeData[] | ((target: SettingTarget) => NodeData[]);|
|getResizingHandlers| 用于配置设计器中组件 resize 操作工具的样式和内容 | Function| (currentNode: any) => Array<{ type: 'N' | 'W' | 'S' | 'E' | 'NW' | 'NE' | 'SE' | 'SW'; content?: ReactElement; propTarget?: string; appearOn?: 'mouse-enter' | 'mouse-hover' | 'selected' | 'always'; }> / ReactElement[];
|callbacks| 配置 callbacks 可捕获引擎抛出的一些事件,例如 onNodeAdd、onResize 等 | Callback| -
|callbacks.onNodeAdd| 在容器中拖入组件时触发的事件回调| Function| (e: MouseEvent, currentNode: any) => any
|callbacks.onNodeRemove| 在容器中删除组件时触发的事件回调| Function| (e: MouseEvent, currentNode: any) => any
|callbacks.onNodeAdd| 在容器中拖入组件时触发的事件回调 | Function| (e: MouseEvent, currentNode: any) => any
|callbacks.onNodeRemove| 在容器中删除组件时触发的事件回调 | Function| (e: MouseEvent, currentNode: any) => any
|callbacks.onResize| 调整容器尺寸时触发的事件回调,常常与 getResizingHandlers 搭配使用 | Function| 详见 Types 定义
|callbacks.onResizeStart| 调整容器尺寸开始时触发的事件回调,常常与 getResizingHandlers 搭配使用 | Function| 详见 Types 定义
|callbacks.onResizeEnd| 调整容器尺寸结束时触发的事件回调,常常与 getResizingHandlers 搭配使用 | Function| 详见 Types 定义
|callbacks.onSubtreeModified| 容器节点结构树发生变化时触发的回调| Function| (currentNode: any, options: any) => void;
|callbacks.onMouseDownHook| 鼠标按下操作回调| Function| (e: MouseEvent, currentNode: any) => any;
|callbacks.onClickHook| 鼠标单击操作回调| Function| (e: MouseEvent, currentNode: any) => any;
|callbacks.onDblClickHook| 鼠标双击操作回调| Function| (e: MouseEvent, currentNode: any) => any;
|callbacks.onSubtreeModified| 容器节点结构树发生变化时触发的回调 | Function| (currentNode: any, options: any) => void;
|callbacks.onMouseDownHook| 鼠标按下操作回调 | Function| (e: MouseEvent, currentNode: any) => any;
|callbacks.onClickHook| 鼠标单击操作回调 | Function| (e: MouseEvent, currentNode: any) => any;
|callbacks.onDblClickHook| 鼠标双击操作回调 | Function| (e: MouseEvent, currentNode: any) => any;
|callbacks.onMoveHook| 节点被拖动回调 | Function| (currentNode: any) => boolean;
|callbacks.onHoverHook| 节点被 hover 回调 | Function| (currentNode: any) => boolean;
|callbacks.onChildMoveHook| 容器节点的子节点被拖动回调| Function| (childNode: any, currentNode: any) => boolean;
|callbacks.onChildMoveHook| 容器节点的子节点被拖动回调 | Function| (childNode: any, currentNode: any) => boolean;
描述举例:
@ -1544,7 +1543,7 @@ block/
```
#### 入口文件
##### 入口文件
(/src/index.jsx)
@ -1560,7 +1559,7 @@ const App = hot(router);
ReactDOM.render(<App />, document.getElementById(pkg.config && pkg.config.targetRootID || 'root'));
```
#### 应用参数配置文件
##### 应用参数配置文件
(/src/config/app.js)
@ -1597,7 +1596,7 @@ export default {
}
```
#### 应用扩展配置规范:
##### 应用扩展配置规范:
(/src/utils/index.js)
@ -1619,7 +1618,7 @@ export default {
}
```
#### 应用常量配置
##### 应用常量配置
(/src/config/constants.js)
@ -1629,7 +1628,7 @@ export default {
}
```
#### 应用样式配置
##### 应用样式配置
(/src/global.scss)

View File

@ -39,7 +39,6 @@ const config = {
presets: [
[
'classic',
/** @type {import('@docusaurus/preset-classic').Options} */
({
docs: {
sidebarPath: require.resolve('./config/sidebars.js'),
@ -55,7 +54,6 @@ const config = {
],
themeConfig:
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
({
docs: {
sidebar: {
@ -76,7 +74,7 @@ const config = {
metadata: [{ name: 'referrer', content: 'no-referrer' }],
tableOfContents: {
minHeadingLevel: 2,
maxHeadingLevel: 5,
maxHeadingLevel: 6,
},
}),

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-engine-docs",
"version": "1.0.8",
"version": "1.0.18",
"description": "低代码引擎版本化文档",
"license": "MIT",
"files": [
@ -16,7 +16,8 @@
"serve": "docusaurus serve",
"write-translations": "docusaurus write-translations",
"write-heading-ids": "docusaurus write-heading-ids",
"typecheck": "tsc"
"typecheck": "tsc",
"syncOss": "node ./scripts/sync-oss.js"
},
"dependencies": {
"@docusaurus/core": "^2.2.0",

View File

@ -8,8 +8,14 @@ module.exports = function getDocsFromDir(dir, cateList) {
const baseDir = path.join(__dirname, '../docs/');
const docsDir = path.join(baseDir, dir);
function isNil(value) {
return value === undefined || value === null;
}
function getMarkdownOrder(filepath) {
return (matter(fs.readFileSync(filepath, 'utf-8')).data || {}).order || 100;
const { data } = matter(fs.readFileSync(filepath, 'utf-8'));
const { sidebar_position } = data || {};
return isNil(sidebar_position) ? 100 : sidebar_position;
}
const docs = glob.sync('*.md?(x)', {
@ -18,8 +24,8 @@ module.exports = function getDocsFromDir(dir, cateList) {
});
const result = docs
.filter(doc => !/^index.md(x)?$/.test(doc))
.map(doc => {
.filter((doc) => !/^index.md(x)?$/.test(doc))
.map((doc) => {
return path.join(docsDir, doc);
})
.sort((a, b) => {
@ -28,7 +34,7 @@ module.exports = function getDocsFromDir(dir, cateList) {
return orderA - orderB;
})
.map(filepath => {
.map((filepath) => {
// /Users/xxx/site/docs/guide/basic/router.md => guide/basic/router
const id = path
.relative(baseDir, filepath)
@ -37,7 +43,7 @@ module.exports = function getDocsFromDir(dir, cateList) {
return id;
});
(cateList || []).forEach(item => {
(cateList || []).forEach((item) => {
const { dir, subCategory, ...otherConfig } = item;
const indexList = glob.sync('index.md?(x)', {
cwd: path.join(baseDir, dir),

47
docs/scripts/sync-oss.js Normal file
View File

@ -0,0 +1,47 @@
#!/usr/bin/env node
const http = require('http');
const package = require('../package.json');
const { version, name } = package;
const options = {
method: 'PUT',
hostname: 'uipaas-node.alibaba-inc.com',
path: '/staticAssets/cdn/packages',
headers: {
'Content-Type': 'application/json',
Cookie: 'locale=en-us',
},
maxRedirects: 20,
};
const onResponse = function (res) {
const chunks = [];
res.on('data', (chunk) => {
chunks.push(chunk);
});
res.on('end', (chunk) => {
const body = Buffer.concat(chunks);
console.table(JSON.stringify(JSON.parse(body.toString()), null, 2));
});
res.on('error', (error) => {
console.error(error);
});
};
const req = http.request(options, onResponse);
const postData = JSON.stringify({
packages: [
{
packageName: name,
version,
},
],
// 可以发布指定源的 npm 包,默认公网 npm
useTnpm: false,
});
req.write(postData);
req.end();

View File

@ -1,6 +1,6 @@
{
"lerna": "4.0.0",
"version": "1.0.18",
"version": "1.1.0",
"npmClient": "yarn",
"useWorkspaces": true,
"packages": [

View File

@ -0,0 +1 @@
module.exports = require('../../babel.config');

View File

@ -14,6 +14,7 @@ program
.option('-c, --cwd <cwd>', 'specify the working directory', '.')
.option('-q, --quiet', 'be quiet, do not output anything unless get error', false)
.option('-v, --verbose', 'be verbose, output more information', false)
.option('--solution-options <options>', 'specify the solution options', '{}')
.arguments('[input-schema] ali lowcode schema JSON file')
.action(function doGenerate(inputSchema, command) {
var options = command.opts();

View File

@ -1,6 +1,6 @@
{
"name": "@alilc/lowcode-code-generator",
"version": "1.0.7-beta.3",
"version": "1.0.7",
"description": "出码引擎 for LowCode Engine",
"license": "MIT",
"main": "lib/index.js",
@ -98,6 +98,7 @@
"qs": "^6.10.1",
"semver": "^7.3.4",
"short-uuid": "^3.1.1",
"babel-jest": "^26.5.2",
"tslib": "^2.3.1"
},
"browser": {
@ -125,11 +126,11 @@
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-react": "^7.22.0",
"eslint-plugin-react-hooks": "^4.2.0",
"jest": "^27.4.7",
"jest": "^26.5.2",
"jest-util": "^27.4.2",
"rimraf": "^3.0.2",
"standard-version": "^9.1.1",
"ts-jest": "^27.1.3",
"ts-jest": "^26.5.2",
"ts-loader": "^6.2.2",
"ts-node": "^8.10.2",
"tsconfig-paths": "^3.9.0",

View File

@ -1,13 +1,13 @@
import type { NodeSchema, CompositeObject } from '@alilc/lowcode-types';
import type { IPublicTypeNodeSchema, IPublicTypeCompositeObject } from '@alilc/lowcode-types';
import type { TComponentAnalyzer } from '../types';
import { handleSubNodes } from '../utils/schema';
export const componentAnalyzer: TComponentAnalyzer = (container) => {
let hasRefAttr = false;
const nodeValidator = (n: NodeSchema) => {
const nodeValidator = (n: IPublicTypeNodeSchema) => {
if (n.props) {
const props = n.props as CompositeObject;
const props = n.props as IPublicTypeCompositeObject;
if (props.ref) {
hasRefAttr = true;
}

View File

@ -9,7 +9,7 @@ import * as path from 'path';
import { getErrorMessage } from '../utils/errors';
import CodeGenerator from '..';
import type { IProjectBuilder } from '..';
import type { ProjectSchema } from '@alilc/lowcode-types';
import type { IPublicTypeProjectSchema } from '@alilc/lowcode-types';
/**
* CLI
@ -25,6 +25,7 @@ export async function run(
output?: string;
quiet?: boolean;
verbose?: boolean;
solutionOptions?: string;
},
): Promise<number> {
try {
@ -41,6 +42,19 @@ export async function run(
);
}
let solutionOptions = {};
if (options.solutionOptions) {
try {
solutionOptions = JSON.parse(options.solutionOptions);
} catch (err: any) {
throw new Error(
`solution options parse error, error message is "${err.message}"`,
);
}
}
// 读取 Schema
const schema = await loadSchemaFile(schemaFile);
@ -48,7 +62,7 @@ export async function run(
const createProjectBuilder = await getProjectBuilderFactory(options.solution, {
quiet: options.quiet,
});
const builder = createProjectBuilder();
const builder = createProjectBuilder(solutionOptions);
// 生成代码
const generatedSourceCodes = await builder.generateProject(schema);
@ -75,7 +89,7 @@ export async function run(
async function getProjectBuilderFactory(
solution: string,
{ quiet }: { quiet?: boolean },
): Promise<() => IProjectBuilder> {
): Promise<(options: {[prop: string]: any}) => IProjectBuilder> {
if (solution in CodeGenerator.solutions) {
return CodeGenerator.solutions[solution as 'icejs' | 'rax'];
}
@ -117,7 +131,7 @@ function isLocalSolution(solution: string) {
return solution.startsWith('.') || solution.startsWith('/') || solution.startsWith('~');
}
async function loadSchemaFile(schemaFile: string): Promise<ProjectSchema> {
async function loadSchemaFile(schemaFile: string): Promise<IPublicTypeProjectSchema> {
if (!schemaFile) {
throw new Error('invalid schema file name');
}

View File

@ -559,8 +559,8 @@ codealike.json
"registry": "https://registry.npm.xxx.com"
},
"dependencies": {
"@alilc/lowcode-code-generator": "^1.0.0-beta.16",
"@alilc/lowcode-types": "^1.0.0-beta.21",
"@alilc/lowcode-code-generator": "^1.0.0",
"@alilc/lowcode-types": "^1.0.0",
"tslib": "^2.3.0"
},
"devDependencies": {

View File

@ -1,4 +1,4 @@
import { ProjectSchema, ResultFile, ResultDir } from '@alilc/lowcode-types';
import { IPublicTypeProjectSchema, ResultFile, ResultDir } from '@alilc/lowcode-types';
import {
BuilderComponentPlugin,
@ -77,7 +77,7 @@ export function createModuleBuilder(
};
};
const generateModuleCode = async (schema: ProjectSchema | string): Promise<ResultDir> => {
const generateModuleCode = async (schema: IPublicTypeProjectSchema | string): Promise<ResultDir> => {
// Init
const schemaParser: ISchemaParser = new SchemaParser();
const parseResult: IParseResult = schemaParser.parse(schema);

View File

@ -1,4 +1,4 @@
import { ResultDir, ResultFile, ProjectSchema } from '@alilc/lowcode-types';
import { ResultDir, ResultFile, IPublicTypeProjectSchema } from '@alilc/lowcode-types';
import {
IModuleBuilder,
@ -40,6 +40,11 @@ export interface ProjectBuilderInitOptions {
inStrictMode?: boolean;
/** 一些额外的上下文数据 */
extraContextData?: Record<string, unknown>;
/**
* Hook which is used to customize original options, we can reorder/add/remove plugins/processors
* of the existing solution.
*/
customizeBuilderOptions?(originalOptions: ProjectBuilderInitOptions): ProjectBuilderInitOptions;
}
export class ProjectBuilder implements IProjectBuilder {
@ -62,21 +67,26 @@ export class ProjectBuilder implements IProjectBuilder {
private projectPostProcessors: ProjectPostProcessor[];
/** 是否处于严格模式 */
public readonly inStrictMode: boolean;
readonly inStrictMode: boolean;
/** 一些额外的上下文数据 */
public readonly extraContextData: IContextData;
readonly extraContextData: IContextData;
constructor({
template,
plugins,
postProcessors,
schemaParser = new SchemaParser(),
projectPreProcessors = [],
projectPostProcessors = [],
inStrictMode = false,
extraContextData = {},
}: ProjectBuilderInitOptions) {
constructor(builderOptions: ProjectBuilderInitOptions) {
let customBuilderOptions = builderOptions;
if (typeof builderOptions.customizeBuilderOptions === 'function') {
customBuilderOptions = builderOptions.customizeBuilderOptions(builderOptions);
}
const {
template,
plugins,
postProcessors,
schemaParser = new SchemaParser(),
projectPreProcessors = [],
projectPostProcessors = [],
inStrictMode = false,
extraContextData = {},
} = customBuilderOptions;
this.template = template;
this.plugins = plugins;
this.postProcessors = postProcessors;
@ -87,34 +97,37 @@ export class ProjectBuilder implements IProjectBuilder {
this.extraContextData = extraContextData;
}
async generateProject(originalSchema: ProjectSchema | string): Promise<ResultDir> {
async generateProject(originalSchema: IPublicTypeProjectSchema | string): Promise<ResultDir> {
// Init
const { schemaParser } = this;
const builders = this.createModuleBuilders();
const projectRoot = await this.template.generateTemplate();
let schema: ProjectSchema =
let schema: IPublicTypeProjectSchema =
typeof originalSchema === 'string' ? JSON.parse(originalSchema) : originalSchema;
// Validate
if (!schemaParser.validate(schema)) {
throw new CodeGeneratorError('Schema is invalid');
}
// Parse / Format
// Preprocess
for (const preProcessor of this.projectPreProcessors) {
// eslint-disable-next-line no-await-in-loop
schema = await preProcessor(schema);
}
// Validate
if (!schemaParser.validate(schema)) {
throw new CodeGeneratorError('Schema is invalid');
}
// Collect Deps
// Parse JSExpression
const parseResult: IParseResult = schemaParser.parse(schema);
let buildResult: IModuleInfo[] = [];
const builders = this.createModuleBuilders({
extraContextData: {
projectRemark: parseResult?.project?.projectRemark,
},
});
// Generator Code module
// components
// pages
@ -241,14 +254,24 @@ export class ProjectBuilder implements IProjectBuilder {
});
}
// demo
if (parseResult.project && builders.demo) {
const { files } = await builders.demo.generateModule(parseResult.project);
buildResult.push({
path: this.template.slots.demo.path,
files,
});
}
// TODO: 更多 slots 的处理??是不是可以考虑把 template 中所有的 slots 都处理下?
// Post Process
const isSingleComponent = parseResult?.project?.projectRemark?.isSingleComponent;
// Combine Modules
buildResult.forEach((moduleInfo) => {
let targetDir = getDirFromRoot(projectRoot, moduleInfo.path);
if (moduleInfo.moduleName) {
// if project only contain single component, skip creation of directory.
if (moduleInfo.moduleName && !isSingleComponent) {
const dir = createResultDir(moduleInfo.moduleName);
addDirectory(targetDir, dir);
targetDir = dir;
@ -260,13 +283,17 @@ export class ProjectBuilder implements IProjectBuilder {
let finalResult = projectRoot;
for (const projectPostProcessor of this.projectPostProcessors) {
// eslint-disable-next-line no-await-in-loop
finalResult = await projectPostProcessor(finalResult, schema, originalSchema);
finalResult = await projectPostProcessor(finalResult, schema, originalSchema, {
template: this.template,
parseResult,
});
}
return finalResult;
}
private createModuleBuilders(): Record<string, IModuleBuilder> {
private createModuleBuilders(extraContextData: Record<string, unknown> = {}):
Record<string, IModuleBuilder> {
const builders: Record<string, IModuleBuilder> = {};
Object.keys(this.plugins).forEach((pluginName) => {
@ -279,10 +306,12 @@ export class ProjectBuilder implements IProjectBuilder {
plugins: this.plugins[pluginName],
postProcessors: this.postProcessors,
contextData: {
// template: this.template,
inStrictMode: this.inStrictMode,
tolerateEvalErrors: true,
evalErrorsHandler: '',
...this.extraContextData,
...extraContextData,
},
...options,
});

View File

@ -4,14 +4,14 @@
*/
import changeCase from 'change-case';
import {
UtilItem,
NodeDataType,
NodeSchema,
ContainerSchema,
ProjectSchema,
PropsMap,
NodeData,
NpmInfo,
IPublicTypeUtilItem,
IPublicTypeNodeDataType,
IPublicTypeNodeSchema,
IPublicTypeContainerSchema,
IPublicTypeProjectSchema,
IPublicTypePropsMap,
IPublicTypeNodeData,
IPublicTypeNpmInfo,
} from '@alilc/lowcode-types';
import {
IPageMeta,
@ -32,10 +32,11 @@ import {
import { SUPPORT_SCHEMA_VERSION_LIST } from '../const';
import { getErrorMessage } from '../utils/errors';
import { handleSubNodes } from '../utils/schema';
import { handleSubNodes, isValidContainerType } from '../utils/schema';
import { uniqueArray } from '../utils/common';
import { componentAnalyzer } from '../analyzer/componentAnalyzer';
import { ensureValidClassName } from '../utils/validate';
import type { ProjectRemark } from '../types/intermediate';
const defaultContainer: IContainerInfo = {
containerType: 'Component',
@ -71,18 +72,18 @@ function getRootComponentName(typeName: string, maps: Record<string, IExternalDe
return typeName;
}
function processChildren(schema: NodeSchema): void {
function processChildren(schema: IPublicTypeNodeSchema): void {
if (schema.props) {
if (Array.isArray(schema.props)) {
// FIXME: is array type props description
} else {
const nodeProps = schema.props as PropsMap;
const nodeProps = schema.props as IPublicTypePropsMap;
if (nodeProps.children) {
if (!schema.children) {
// eslint-disable-next-line no-param-reassign
schema.children = nodeProps.children as NodeDataType;
schema.children = nodeProps.children as IPublicTypeNodeDataType;
} else {
let _children: NodeData[] = [];
let _children: IPublicTypeNodeData[] = [];
if (Array.isArray(schema.children)) {
_children = _children.concat(schema.children);
@ -91,9 +92,9 @@ function processChildren(schema: NodeSchema): void {
}
if (Array.isArray(nodeProps.children)) {
_children = _children.concat(nodeProps.children as NodeData[]);
_children = _children.concat(nodeProps.children as IPublicTypeNodeData[]);
} else {
_children.push(nodeProps.children as NodeData);
_children.push(nodeProps.children as IPublicTypeNodeData);
}
// eslint-disable-next-line no-param-reassign
@ -106,7 +107,7 @@ function processChildren(schema: NodeSchema): void {
}
export class SchemaParser implements ISchemaParser {
validate(schema: ProjectSchema): boolean {
validate(schema: IPublicTypeProjectSchema): boolean {
if (SUPPORT_SCHEMA_VERSION_LIST.indexOf(schema.version) < 0) {
throw new CompatibilityError(`Not support schema with version [${schema.version}]`);
}
@ -114,7 +115,7 @@ export class SchemaParser implements ISchemaParser {
return true;
}
parse(schemaSrc: ProjectSchema | string): IParseResult {
parse(schemaSrc: IPublicTypeProjectSchema | string): IParseResult {
// TODO: collect utils depends in JSExpression
const compDeps: Record<string, IExternalDependency> = {};
const internalDeps: Record<string, IInternalDependency> = {};
@ -139,9 +140,9 @@ export class SchemaParser implements ISchemaParser {
let containers: IContainerInfo[];
// Test if this is a lowcode component without container
if (schema.componentsTree.length > 0) {
const firstRoot: ContainerSchema = schema.componentsTree[0] as ContainerSchema;
const firstRoot: IPublicTypeContainerSchema = schema.componentsTree[0] as IPublicTypeContainerSchema;
if (!('fileName' in firstRoot) || !firstRoot.fileName) {
if (!firstRoot.fileName && !isValidContainerType(firstRoot)) {
// 整个 schema 描述一个容器,且无根节点定义
const container: IContainerInfo = {
...firstRoot,
@ -149,13 +150,13 @@ export class SchemaParser implements ISchemaParser {
props: firstRoot.props || defaultContainer.props,
css: firstRoot.css || defaultContainer.css,
moduleName: (firstRoot as IContainerInfo).moduleName || defaultContainer.moduleName,
children: schema.componentsTree as NodeSchema[],
children: schema.componentsTree as IPublicTypeNodeSchema[],
};
containers = [container];
} else {
// 普通带 1 到多个容器的 schema
containers = schema.componentsTree.map((n) => {
const subRoot = n as ContainerSchema;
const subRoot = n as IPublicTypeContainerSchema;
const container: IContainerInfo = {
...subRoot,
componentName: getRootComponentName(subRoot.componentName, compDeps),
@ -172,7 +173,7 @@ export class SchemaParser implements ISchemaParser {
// 分析引用能力的依赖
containers = containers.map((con) => ({
...con,
analyzeResult: componentAnalyzer(con as ContainerSchema),
analyzeResult: componentAnalyzer(con as IPublicTypeContainerSchema),
}));
// 建立所有容器的内部依赖索引
@ -210,7 +211,7 @@ export class SchemaParser implements ISchemaParser {
handleSubNodes<void>(
container.children,
{
node: (i: NodeSchema) => processChildren(i),
node: (i: IPublicTypeNodeSchema) => processChildren(i),
},
{
rerun: true,
@ -254,13 +255,12 @@ export class SchemaParser implements ISchemaParser {
.filter((dep) => !!dep);
// 分析 Utils 依赖
let utils: UtilItem[];
let utils: IPublicTypeUtilItem[];
if (schema.utils) {
utils = schema.utils;
utilsDeps = schema.utils
.filter(
(u): u is { name: string; type: 'npm' | 'tnpm'; content: NpmInfo } =>
u.type !== 'function',
(u): u is { name: string; type: 'npm' | 'tnpm'; content: IPublicTypeNpmInfo } => u.type !== 'function',
)
.map(
(u): IExternalDependency => ({
@ -320,15 +320,22 @@ export class SchemaParser implements ISchemaParser {
utilsDeps,
packages: npms || [],
dataSourcesTypes: this.collectDataSourcesTypes(schema),
projectRemark: this.getProjectRemark(containers),
},
};
}
getComponentNames(children: NodeDataType): string[] {
getProjectRemark(containers: IContainerInfo[]): ProjectRemark {
return {
isSingleComponent: containers.length === 1 && containers[0].containerType === 'Component',
};
}
getComponentNames(children: IPublicTypeNodeDataType): string[] {
return handleSubNodes<string>(
children,
{
node: (i: NodeSchema) => i.componentName,
node: (i: IPublicTypeNodeSchema) => i.componentName,
},
{
rerun: true,
@ -336,8 +343,8 @@ export class SchemaParser implements ISchemaParser {
);
}
decodeSchema(schemaSrc: string | ProjectSchema): ProjectSchema {
let schema: ProjectSchema;
decodeSchema(schemaSrc: string | IPublicTypeProjectSchema): IPublicTypeProjectSchema {
let schema: IPublicTypeProjectSchema;
if (typeof schemaSrc === 'string') {
try {
schema = JSON.parse(schemaSrc);
@ -352,7 +359,7 @@ export class SchemaParser implements ISchemaParser {
return schema;
}
private collectDataSourcesTypes(schema: ProjectSchema): string[] {
private collectDataSourcesTypes(schema: IPublicTypeProjectSchema): string[] {
const dataSourcesTypes = new Set<string>();
// 数据源的默认类型为 fetch

View File

@ -1,8 +1,8 @@
/* eslint-disable @typescript-eslint/indent */
import {
CompositeValue,
JSExpression,
IPublicTypeCompositeValue,
IPublicTypeJSExpression,
InterpretDataSourceConfig,
isJSExpression,
isJSFunction,
@ -56,7 +56,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
(dataSourceConfig && dataSourceConfig.list) || [];
const dataSourceEngineOptions = { runtimeConfig: true };
if (dataSourceItems.length > 0) {
const requestHandlersMap: Record<string, JSExpression> = {};
const requestHandlersMap: Record<string, IPublicTypeJSExpression> = {};
dataSourceItems.forEach((ds) => {
const dsType = ds.type || 'fetch';
@ -178,7 +178,7 @@ _defineDataSourceConfig() {
export default pluginFactory;
function wrapAsFunction(value: CompositeValue, scope: IScope): CompositeValue {
function wrapAsFunction(value: IPublicTypeCompositeValue, scope: IScope): IPublicTypeCompositeValue {
if (isJSExpression(value) || isJSFunction(value)) {
return {
type: 'JSExpression',

View File

@ -1,8 +1,8 @@
import {
NodeSchema,
JSExpression,
NpmInfo,
CompositeValue,
IPublicTypeNodeSchema,
IPublicTypeJSExpression,
IPublicTypeNpmInfo,
IPublicTypeCompositeValue,
isJSExpression,
} from '@alilc/lowcode-types';
@ -86,7 +86,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
// 2. 小程序出码的时候,很容易出现 Uncaught TypeError: Cannot read property 'avatar' of undefined 这样的异常(如下图的 50 行) -- 因为若直接出码Rax 构建到小程序的时候会立即计算所有在视图中用到的变量
// 3. 通过 this.xxx 能拿到的东西太多了,而且自定义的 methods 可能会无意间破坏 Rax 框架或小程序框架在页面 this 上的东东
const customHandlers: HandlerSet<string> = {
expression(input: JSExpression, scope: IScope) {
expression(input: IPublicTypeJSExpression, scope: IScope) {
return transformJsExpr(generateExpression(input, scope), scope, {
dontWrapEval: !tolerateEvalErrors,
});
@ -171,7 +171,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
return next;
function generateRaxLoopCtrl(
nodeItem: NodeSchema,
nodeItem: IPublicTypeNodeSchema,
scope: IScope,
config?: NodeGeneratorConfig,
next?: NodePlugin,
@ -218,7 +218,7 @@ function isImportAliasDefineChunk(chunk: ICodeChunk): chunk is ICodeChunk & {
ext: {
aliasName: string;
originalName: string;
dependency: NpmInfo;
dependency: IPublicTypeNpmInfo;
};
} {
return (
@ -226,13 +226,13 @@ function isImportAliasDefineChunk(chunk: ICodeChunk): chunk is ICodeChunk & {
!!chunk.ext &&
typeof chunk.ext.aliasName === 'string' &&
typeof chunk.ext.originalName === 'string' &&
!!(chunk.ext.dependency as NpmInfo | null)?.componentName
!!(chunk.ext.dependency as IPublicTypeNpmInfo | null)?.componentName
);
}
function generateNodeAttrForRax(
this: { cfg: PluginConfig },
attrData: { attrName: string; attrValue: CompositeValue },
attrData: { attrName: string; attrValue: IPublicTypeCompositeValue },
scope: IScope,
config?: NodeGeneratorConfig,
next?: AttrPlugin,
@ -257,7 +257,7 @@ function generateNodeAttrForRax(
function generateEventHandlerAttrForRax(
attrName: string,
attrValue: CompositeValue,
attrValue: IPublicTypeCompositeValue,
scope: IScope,
config?: NodeGeneratorConfig,
): CodePiece[] {

View File

@ -1,8 +1,8 @@
/* eslint-disable @typescript-eslint/indent */
import {
CompositeValue,
JSExpression,
IPublicTypeCompositeValue,
IPublicTypeJSExpression,
InterpretDataSourceConfig,
isJSExpression,
isJSFunction,
@ -27,7 +27,7 @@ import {
import { generateCompositeType } from '../../../utils/compositeType';
import { parseExpressionConvertThis2Context } from '../../../utils/expressionParser';
import { isContainerSchema } from '../../../utils/schema';
import { isValidContainerType } from '../../../utils/schema';
import { REACT_CHUNK_NAME } from './const';
export interface PluginConfig {
@ -67,12 +67,12 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
};
const scope = Scope.createRootScope();
const dataSourceConfig = isContainerSchema(pre.ir) ? pre.ir.dataSource : null;
const dataSourceConfig = isValidContainerType(pre.ir) ? pre.ir.dataSource : null;
const dataSourceItems: InterpretDataSourceConfig[] =
(dataSourceConfig && dataSourceConfig.list) || [];
const dataSourceEngineOptions = { runtimeConfig: true };
if (dataSourceItems.length > 0) {
const requestHandlersMap: Record<string, JSExpression> = {};
const requestHandlersMap: Record<string, IPublicTypeJSExpression> = {};
dataSourceItems.forEach((ds) => {
const dsType = ds.type || 'fetch';
@ -187,7 +187,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
export default pluginFactory;
function wrapAsFunction(value: CompositeValue, scope: IScope): CompositeValue {
function wrapAsFunction(value: IPublicTypeCompositeValue, scope: IScope): IPublicTypeCompositeValue {
if (isJSExpression(value) || isJSFunction(value)) {
return {
type: 'JSExpression',

View File

@ -11,6 +11,7 @@ import {
FileType,
ICodeStruct,
IContainerInfo,
IProjectTemplate,
} from '../../../types';
export interface PluginConfig {
@ -32,6 +33,19 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
next.contextData.useRefApi = true;
const useRef = !!ir.analyzeResult?.isUsingRef;
// const isSingleComponent = next.contextData?.projectRemark?.isSingleComponent;
// const template = next.contextData?.template;
// function getRelativeUtilsPath(template: IProjectTemplate, isSingleComponent: boolean) {
// let relativeUtilsPath = '../../utils';
// const utilsPath = template.slots.utils.path;
// if (ir.containerType === 'Component') {
// // TODO: isSingleComponent
// relativeUtilsPath = getRelativePath(template.slots.components.path.join('/'), utilsPath.join('/'));
// }
// return relativeUtilsPath;
// }
next.chunks.push({
type: ChunkType.STRING,
fileType: cfg.fileType,
@ -89,7 +103,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
type: ChunkType.STRING,
fileType: cfg.fileType,
name: CLASS_DEFINE_CHUNK_NAME.InsMethod,
content: ` $ = () => null; `,
content: ' $ = () => null; ',
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]],
});
@ -97,7 +111,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
type: ChunkType.STRING,
fileType: cfg.fileType,
name: CLASS_DEFINE_CHUNK_NAME.InsMethod,
content: ` $$ = () => []; `,
content: ' $$ = () => []; ',
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]],
});
}

View File

@ -16,7 +16,7 @@ import { COMMON_CHUNK_NAME } from '../../../const/generator';
import { createReactNodeGenerator } from '../../../utils/nodeToJSX';
import { Scope } from '../../../utils/Scope';
import { JSExpression } from '@alilc/lowcode-types';
import { IPublicTypeJSExpression } from '@alilc/lowcode-types';
import { generateExpression } from '../../../utils/jsExpression';
import { transformJsExpr } from '../../../core/jsx/handlers/transformJsExpression';
import { transformThis2Context } from '../../../core/jsx/handlers/transformThis2Context';
@ -47,7 +47,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
// 这里会将内部的一些子上下文的访问(this.xxx)转换为 __$$context.xxx 的形式
// 与 Rax 所不同的是,这里不会将最顶层的 this 转换掉
const customHandlers: HandlerSet<string> = {
expression(input: JSExpression, scope: IScope, config) {
expression(input: IPublicTypeJSExpression, scope: IScope, config) {
return transformJsExpr(generateExpression(input, scope), scope, {
dontWrapEval: !(config?.tolerateEvalErrors ?? tolerateEvalErrors),
dontTransformThis2ContextAtRootScope: true,
@ -120,7 +120,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
function __$$eval(expr) {
try {
return expr();
} catch (error) {
} catch (error) {
${evalErrorsHandler}
}
}

View File

@ -1,4 +1,4 @@
import { NpmInfo, PackageJSON } from '@alilc/lowcode-types';
import { IPublicTypeNpmInfo, PackageJSON } from '@alilc/lowcode-types';
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
import {
@ -84,9 +84,9 @@ const pluginFactory: BuilderComponentPluginFactory<RaxFrameworkOptions> = (cfg)
export default pluginFactory;
function getNpmDependencies(project: IProjectInfo): NpmInfo[] {
const npmDeps: NpmInfo[] = [];
const npmNameToPkgMap = new Map<string, NpmInfo>();
function getNpmDependencies(project: IProjectInfo): IPublicTypeNpmInfo[] {
const npmDeps: IPublicTypeNpmInfo[] = [];
const npmNameToPkgMap = new Map<string, IPublicTypeNpmInfo>();
const allDeps = project.packages;

View File

@ -9,7 +9,7 @@ const PARSERS = ['css', 'scss', 'less', 'json', 'html', 'vue'];
export interface ProcessorConfig {
customFileTypeParser: Record<string, string>;
plugins?: Array<prettier.Plugin>;
plugins?: prettier.Plugin[];
}
const factory: PostProcessorFactory<ProcessorConfig> = (config?: ProcessorConfig) => {
@ -33,6 +33,8 @@ const factory: PostProcessorFactory<ProcessorConfig> = (config?: ProcessorConfig
return prettier.format(content, {
parser,
plugins: [parserBabel, parserPostCss, parserHtml, ...(cfg.plugins || [])],
singleQuote: true,
jsxSingleQuote: false,
});
};

View File

@ -91,6 +91,7 @@ export default function createIceJsProjectBuilder(
packageJSON: [icejs.plugins.packageJSON()],
},
postProcessors: [prettier()],
customizeBuilderOptions: options?.customizeBuilderOptions,
});
}

View File

@ -71,6 +71,7 @@ export default function createRaxProjectBuilder(
packageJSON: [raxApp.plugins.packageJSON(options)],
},
postProcessors: [prettier()],
customizeBuilderOptions: options?.customizeBuilderOptions,
});
}

View File

@ -1,5 +1,5 @@
import fetch from 'node-fetch';
import type { ProjectSchema, ResultDir } from '@alilc/lowcode-types';
import type { IPublicTypeProjectSchema, ResultDir } from '@alilc/lowcode-types';
import type { FlattenFile } from './types/file';
declare const Worker: any;
@ -26,7 +26,7 @@ export type Result = ResultDir | FlattenFile[];
export async function generateCode(options: {
solution: 'icejs' | 'rax';
schema: ProjectSchema;
schema: IPublicTypeProjectSchema;
flattenResult?: boolean;
workerJsUrl?: string;
timeoutInMs?: number;

View File

@ -1,5 +1,5 @@
/* eslint-disable no-console */
import type { ProjectSchema } from '@alilc/lowcode-types';
import type { IPublicTypeProjectSchema } from '@alilc/lowcode-types';
import CodeGen from './standalone';
declare const self: any;
@ -13,7 +13,7 @@ self.onmessage = (event: any) => {
self.postMessage({ type: 'ready' });
async function run(msg: { solution: string; schema: ProjectSchema; flattenResult?: boolean }) {
async function run(msg: { solution: string; schema: IPublicTypeProjectSchema; flattenResult?: boolean }) {
try {
print('begin run...');
self.postMessage({ type: 'run:begin' });

View File

@ -1,7 +1,7 @@
import type { ContainerSchema } from '@alilc/lowcode-types';
import type { IPublicTypeContainerSchema } from '@alilc/lowcode-types';
export interface ICompAnalyzeResult {
isUsingRef: boolean;
}
export type TComponentAnalyzer = (container: ContainerSchema) => ICompAnalyzeResult;
export type TComponentAnalyzer = (container: IPublicTypeContainerSchema) => ICompAnalyzeResult;

View File

@ -1,19 +1,20 @@
import {
JSONArray,
JSONObject,
CompositeArray,
CompositeObject,
IPublicTypeJSONArray,
IPublicTypeJSONObject,
IPublicTypeCompositeArray,
IPublicTypeCompositeObject,
ResultDir,
ResultFile,
NodeDataType,
ProjectSchema,
JSExpression,
JSFunction,
JSSlot,
IPublicTypeNodeDataType,
IPublicTypeProjectSchema,
IPublicTypeJSExpression,
IPublicTypeJSFunction,
IPublicTypeJSSlot,
} from '@alilc/lowcode-types';
import { IParseResult } from './intermediate';
import { IScopeBindings } from '../utils/ScopeBindings';
import type { ProjectBuilderInitOptions } from '../generator/ProjectBuilder';
export enum FileType {
CSS = 'css',
@ -25,6 +26,7 @@ export enum FileType {
TS = 'ts',
TSX = 'tsx',
JSON = 'json',
MD = 'md',
}
export enum ChunkType {
@ -64,7 +66,10 @@ export interface ICodeStruct extends IBaseCodeStruct {
/** 上下文数据,用来在插件之间共享一些数据 */
export interface IContextData extends IProjectBuilderOptions {
/** 是否使用了 Ref 的 API (this.$/this.$$) */
/**
* 使 Ref API (this.$/this.$$)
* */
useRefApi?: boolean;
/**
@ -95,7 +100,7 @@ export interface ICompiledModule {
export interface IModuleBuilder {
generateModule: (input: unknown) => Promise<ICompiledModule>;
generateModuleCode: (schema: ProjectSchema | string) => Promise<ResultDir>;
generateModuleCode: (schema: IPublicTypeProjectSchema | string) => Promise<ResultDir>;
linkCodeChunks: (chunks: Record<string, ICodeChunk[]>, fileName: string) => ResultFile[];
addPlugin: (plugin: BuilderComponentPlugin) => void;
}
@ -107,19 +112,20 @@ export interface IModuleBuilder {
* @interface ICodeGenerator
*/
export interface ICodeGenerator {
/**
* Schema
*
* @param {(ProjectSchema)} schema Schema
* @param {(IPublicTypeProjectSchema)} schema Schema
* @returns {ResultDir}
* @memberof ICodeGenerator
*/
toCode: (schema: ProjectSchema) => Promise<ResultDir>;
toCode: (schema: IPublicTypeProjectSchema) => Promise<ResultDir>;
}
export interface ISchemaParser {
validate: (schema: ProjectSchema) => boolean;
parse: (schema: ProjectSchema | string) => IParseResult;
validate: (schema: IPublicTypeProjectSchema) => boolean;
parse: (schema: IPublicTypeProjectSchema | string) => IParseResult;
}
export interface IProjectTemplate {
@ -137,44 +143,56 @@ export interface IProjectPlugins {
}
export interface IProjectBuilderOptions {
/** 是否处于严格模式(默认: 否) */
/** 是否处于严格模式 (默认:否) */
inStrictMode?: boolean;
/**
* JSExpression
* true
* : 如果容忍异 try-catch
* try-catch
* catch CustomEvent
*/
tolerateEvalErrors?: boolean;
/**
*
* 默认:
*
*
* window.dispatchEvent(new CustomEvent('lowcode-eval-error', { error, expr }))
*
*
*
* :
*
* - error: 异常信息
* - expr: 求值的表达式
*/
evalErrorsHandler?: string;
/**
* Hook which is used to customize original options, we can reorder/add/remove plugins/processors
* of the existing solution.
*/
customizeBuilderOptions?(originalOptions: ProjectBuilderInitOptions): ProjectBuilderInitOptions;
}
export interface IProjectBuilder {
generateProject: (schema: ProjectSchema | string) => Promise<ResultDir>;
generateProject: (schema: IPublicTypeProjectSchema | string) => Promise<ResultDir>;
}
/** 项目级别的前置处理器 */
export type ProjectPreProcessor = (schema: ProjectSchema) => Promise<ProjectSchema> | ProjectSchema;
export type ProjectPreProcessor = (schema: IPublicTypeProjectSchema) => Promise<IPublicTypeProjectSchema> | IPublicTypeProjectSchema;
export interface ProjectPostProcessorOptions {
parseResult?: IParseResult;
template?: IProjectTemplate;
}
/** 项目级别的后置处理器 */
export type ProjectPostProcessor = (
result: ResultDir,
schema: ProjectSchema,
originalSchema: ProjectSchema | string,
schema: IPublicTypeProjectSchema,
originalSchema: IPublicTypeProjectSchema | string,
options: ProjectPostProcessorOptions,
) => Promise<ResultDir> | ResultDir;
/** 模块级别的后置处理器的工厂方法 */
@ -198,20 +216,20 @@ type CompositeTypeGenerator<I, T> =
| BaseGenerator<I, T, CompositeValueGeneratorOptions>
| Array<BaseGenerator<I, T, CompositeValueGeneratorOptions>>;
export type NodeGenerator<T> = (nodeItem: NodeDataType, scope: IScope) => T;
export type NodeGenerator<T> = (nodeItem: IPublicTypeNodeDataType, scope: IScope) => T;
// FIXME: 在新的实现中,添加了第一参数 this: CustomHandlerSet 作为上下文。究其本质
// scopeBindings?: IScopeBindings;
// 这个组合只用来用来处理 CompositeValue 类型,不是这个类型的不要放在这里
// 这个组合只用来用来处理 IPublicTypeCompositeValue 类型,不是这个类型的不要放在这里
export interface HandlerSet<T> {
string?: CompositeTypeGenerator<string, T>;
boolean?: CompositeTypeGenerator<boolean, T>;
number?: CompositeTypeGenerator<number, T>;
expression?: CompositeTypeGenerator<JSExpression, T>;
function?: CompositeTypeGenerator<JSFunction, T>;
slot?: CompositeTypeGenerator<JSSlot, T>;
array?: CompositeTypeGenerator<JSONArray | CompositeArray, T>;
object?: CompositeTypeGenerator<JSONObject | CompositeObject, T>;
expression?: CompositeTypeGenerator<IPublicTypeJSExpression, T>;
function?: CompositeTypeGenerator<IPublicTypeJSFunction, T>;
slot?: CompositeTypeGenerator<IPublicTypeJSSlot, T>;
array?: CompositeTypeGenerator<IPublicTypeJSONArray | IPublicTypeCompositeArray, T>;
object?: CompositeTypeGenerator<IPublicTypeJSONObject | IPublicTypeCompositeObject, T>;
}
export interface CompositeValueGeneratorOptions {

View File

@ -1,4 +1,9 @@
import { I18nMap, UtilsMap, ContainerSchema, JSONObject } from '@alilc/lowcode-types';
import {
IPublicTypeI18nMap,
IPublicTypeUtilsMap,
IPublicTypeContainerSchema,
IPublicTypeJSONObject,
} from '@alilc/lowcode-types';
import { IDependency, INpmPackage } from './deps';
import { ICompAnalyzeResult } from './analyze';
@ -6,7 +11,7 @@ import { ICompAnalyzeResult } from './analyze';
export interface IParseResult {
containers: IContainerInfo[];
globalUtils?: IUtilInfo;
globalI18n?: I18nMap;
globalI18n?: IPublicTypeI18nMap;
globalRouter?: IRouterInfo;
project?: IProjectInfo;
}
@ -15,14 +20,14 @@ export interface IWithDependency {
deps?: IDependency[];
}
export interface IContainerInfo extends ContainerSchema, IWithDependency {
export interface IContainerInfo extends IPublicTypeContainerSchema, IWithDependency {
containerType: string;
moduleName: string;
analyzeResult?: ICompAnalyzeResult;
}
export interface IUtilInfo extends IWithDependency {
utils: UtilsMap;
utils: IPublicTypeUtilsMap;
}
export interface IRouterInfo extends IWithDependency {
@ -33,16 +38,25 @@ export interface IRouterInfo extends IWithDependency {
}>;
}
/**
* project's remarks
*/
export interface ProjectRemark {
/** if current project only contain one container which type is `Component` */
isSingleComponent?: boolean;
}
export interface IProjectInfo {
css?: string;
containersDeps?: IDependency[];
utilsDeps?: IDependency[];
constants?: JSONObject;
i18n?: I18nMap;
constants?: IPublicTypeJSONObject;
i18n?: IPublicTypeI18nMap;
packages: INpmPackage[];
meta?: { name?: string; title?: string } | Record<string, any>;
config?: Record<string, any>;
dataSourcesTypes?: string[];
projectRemark?: ProjectRemark;
}
export interface IPageMeta {

View File

@ -1,4 +1,4 @@
import { NodeSchema, CompositeValue } from '@alilc/lowcode-types';
import { IPublicTypeNodeSchema, IPublicTypeCompositeValue } from '@alilc/lowcode-types';
import { HandlerSet, BaseGenerator, NodeGenerator } from './core';
export enum PIECE_TYPE {
@ -17,11 +17,11 @@ export interface CodePiece {
export interface AttrData {
attrName: string;
attrValue: CompositeValue;
attrValue: IPublicTypeCompositeValue;
}
// 对 JSX 出码的理解,目前定制点包含 【包装】【标签名】【属性】
// 对 JSX 出码的理解,目前定制点包含【包装】【标签名】【属性】
export type AttrPlugin = BaseGenerator<AttrData, CodePiece[], NodeGeneratorConfig>;
export type NodePlugin = BaseGenerator<NodeSchema, CodePiece[], NodeGeneratorConfig>;
export type NodePlugin = BaseGenerator<IPublicTypeNodeSchema, CodePiece[], NodeGeneratorConfig>;
export interface NodeGeneratorConfig {
handlers?: HandlerSet<string>;
@ -33,7 +33,7 @@ export interface NodeGeneratorConfig {
/**
* JSExpression
* true
* : 如果容忍异 try-catch -- __$$eval / __$$evalArray
* try-catch -- __$$eval / __$$evalArray
* catch CustomEvent
*/
tolerateEvalErrors?: boolean;

View File

@ -1,13 +1,13 @@
import {
CompositeArray,
CompositeValue,
CompositeObject,
JSFunction,
JSExpression,
IPublicTypeCompositeArray,
IPublicTypeCompositeValue,
IPublicTypeCompositeObject,
IPublicTypeJSFunction,
IPublicTypeJSExpression,
isJSExpression,
isJSFunction,
isJSSlot,
JSSlot,
IPublicTypeJSSlot,
} from '@alilc/lowcode-types';
import _ from 'lodash';
@ -43,7 +43,7 @@ function isDataSource(v: unknown): v is DataSource {
}
function generateArray(
value: CompositeArray,
value: IPublicTypeCompositeArray,
scope: IScope,
options: CompositeValueGeneratorOptions = {},
): string {
@ -52,7 +52,7 @@ function generateArray(
}
function generateObject(
value: CompositeObject,
value: IPublicTypeCompositeObject,
scope: IScope,
options: CompositeValueGeneratorOptions = {},
): string {
@ -88,7 +88,7 @@ function generateBool(value: boolean): string {
return value ? 'true' : 'false';
}
function genFunction(value: JSFunction): string {
function genFunction(value: IPublicTypeJSFunction): string {
const globalVars = parseExpressionGetKeywords(value.value);
if (globalVars.includes('arguments')) {
@ -98,7 +98,7 @@ function genFunction(value: JSFunction): string {
return generateFunction(value, { isArrow: true });
}
function genJsSlot(value: JSSlot, scope: IScope, options: CompositeValueGeneratorOptions = {}) {
function genJsSlot(value: IPublicTypeJSSlot, scope: IScope, options: CompositeValueGeneratorOptions = {}) {
if (options.nodeGenerator) {
return generateJsSlot(value, scope, options.nodeGenerator);
}
@ -106,7 +106,7 @@ function genJsSlot(value: JSSlot, scope: IScope, options: CompositeValueGenerato
}
function generateUnknownType(
value: CompositeValue,
value: IPublicTypeCompositeValue,
scope: IScope,
options: CompositeValueGeneratorOptions = {},
): string {
@ -128,7 +128,7 @@ function generateUnknownType(
// FIXME: 这个是临时方案
// 在遇到 type variable 私有类型时,转换为 JSExpression
if (isVariable(value)) {
const transValue: JSExpression = {
const transValue: IPublicTypeJSExpression = {
type: 'JSExpression',
value: value.variable,
};
@ -188,7 +188,7 @@ function generateUnknownType(
if (options.handlers?.object) {
return executeFunctionStack(value, scope, options.handlers.object, generateObject, options);
}
return generateObject(value as CompositeObject, scope, options);
return generateObject(value as IPublicTypeCompositeObject, scope, options);
}
if (_.isString(value)) {
@ -218,7 +218,7 @@ function generateUnknownType(
// 这一层曾经是对产出做最外层包装的,但其实包装逻辑不应该属于这一层
// 这一层先不去掉,做冗余,方便后续重构
export function generateCompositeType(
value: CompositeValue,
value: IPublicTypeCompositeValue,
scope: IScope,
options: CompositeValueGeneratorOptions = {},
): string {

View File

@ -1,7 +1,7 @@
import changeCase from 'change-case';
import type { IProjectInfo } from '../types/intermediate';
export type DataSourceDependenciesConfig = {
export interface DataSourceDependenciesConfig {
/** 数据源引擎的版本 */
engineVersion?: string;
/** 数据源引擎的包名 */
@ -14,7 +14,7 @@ export type DataSourceDependenciesConfig = {
handlersPackages?: {
[key: string]: string;
};
};
}
export function buildDataSourceDependencies(
ir: IProjectInfo,
@ -22,13 +22,13 @@ export function buildDataSourceDependencies(
): Record<string, string> {
return {
// 数据源引擎的依赖包
[cfg.enginePackage || '@alilc/lowcode-datasource-engine']: cfg.engineVersion || 'latest',
[cfg.enginePackage || '@alilc/lowcode-datasource-engine']: cfg.engineVersion || '^1.0.0',
// 各种数据源的 handlers 的依赖包
...(ir.dataSourcesTypes || []).reduce(
(acc, dsType) => ({
...acc,
[getDataSourceHandlerPackageName(dsType)]: cfg.handlersVersion?.[dsType] || 'latest',
[getDataSourceHandlerPackageName(dsType)]: cfg.handlersVersion?.[dsType] || '^1.0.0',
}),
{},
),

View File

@ -11,6 +11,7 @@ import * as schema from './schema';
import * as version from './version';
import * as scope from './Scope';
import * as expressionParser from './expressionParser';
import * as dataSource from './dataSource';
export {
common,
@ -25,4 +26,5 @@ export {
version,
scope,
expressionParser,
dataSource,
};

View File

@ -2,7 +2,7 @@ import * as parser from '@babel/parser';
import generate from '@babel/generator';
import traverse from '@babel/traverse';
import * as t from '@babel/types';
import { JSExpression, JSFunction, isJSExpression, isJSFunction } from '@alilc/lowcode-types';
import { IPublicTypeJSExpression, IPublicTypeJSFunction, isJSExpression, isJSFunction } from '@alilc/lowcode-types';
import { CodeGeneratorError, IScope } from '../types';
import { transformExpressionLocalRef, ParseError } from './expressionParser';
@ -84,7 +84,7 @@ export function isJsCode(value: unknown): boolean {
export function generateExpression(value: any, scope: IScope): string {
if (isJSExpression(value)) {
const exprVal = (value as JSExpression).value.trim();
const exprVal = (value as IPublicTypeJSExpression).value.trim();
if (!exprVal) {
return 'null';
}
@ -113,7 +113,7 @@ export function generateFunction(
},
) {
if (isJsCode(value)) {
const functionCfg = value as JSFunction;
const functionCfg = value as IPublicTypeJSFunction;
if (config.isMember) {
return transformFuncExpr2MethodMember(config.name || '', functionCfg.value);
}

View File

@ -1,4 +1,4 @@
import { JSSlot, isJSSlot, NodeData } from '@alilc/lowcode-types';
import { IPublicTypeJSSlot, isJSSlot, IPublicTypeNodeData } from '@alilc/lowcode-types';
import { CodeGeneratorError, NodeGenerator, IScope } from '../types';
import { unwrapJsExprQuoteInJsx } from './jsxHelpers';
@ -8,7 +8,7 @@ function generateSingleLineComment(commentText: string): string {
export function generateJsSlot(slot: any, scope: IScope, generator: NodeGenerator<string>): string {
if (isJSSlot(slot)) {
const { title, params, value } = slot as JSSlot;
const { title, params, value } = slot as IPublicTypeJSSlot;
// slot 也是分有参数和无参数的
// - 有参数的 slot 就是类似一个 render 函数,需要创建子作用域
@ -39,7 +39,7 @@ export function generateJsSlot(slot: any, scope: IScope, generator: NodeGenerato
}
function generateNodeDataOrArrayForJsSlot(
value: NodeData | NodeData[],
value: IPublicTypeNodeData | IPublicTypeNodeData[],
generator: NodeGenerator<string>,
scope: IScope,
) {

View File

@ -1,6 +1,6 @@
import _ from 'lodash';
import { pipe } from 'fp-ts/function';
import { NodeSchema, isNodeSchema, NodeDataType, CompositeValue } from '@alilc/lowcode-types';
import { IPublicTypeNodeSchema, isNodeSchema, IPublicTypeNodeDataType, IPublicTypeCompositeValue } from '@alilc/lowcode-types';
import {
IScope,
@ -57,7 +57,7 @@ export function isPureString(v: string) {
}
function generateAttrValue(
attrData: { attrName: string; attrValue: CompositeValue },
attrData: { attrName: string; attrValue: IPublicTypeCompositeValue },
scope: IScope,
config?: NodeGeneratorConfig,
): CodePiece[] {
@ -76,7 +76,7 @@ function generateAttrValue(
function generateAttr(
attrName: string,
attrValue: CompositeValue,
attrValue: IPublicTypeCompositeValue,
scope: IScope,
config?: NodeGeneratorConfig,
): CodePiece[] {
@ -115,7 +115,7 @@ function generateAttr(
}
function generateAttrs(
nodeItem: NodeSchema,
nodeItem: IPublicTypeNodeSchema,
scope: IScope,
config?: NodeGeneratorConfig,
): CodePiece[] {
@ -144,7 +144,7 @@ function generateAttrs(
}
function generateBasicNode(
nodeItem: NodeSchema,
nodeItem: IPublicTypeNodeSchema,
scope: IScope,
config?: NodeGeneratorConfig,
): CodePiece[] {
@ -160,7 +160,7 @@ function generateBasicNode(
}
function generateSimpleNode(
nodeItem: NodeSchema,
nodeItem: IPublicTypeNodeSchema,
scope: IScope,
config?: NodeGeneratorConfig,
): CodePiece[] {
@ -182,7 +182,7 @@ function generateSimpleNode(
function linkPieces(pieces: CodePiece[]): string {
const tagsPieces = pieces.filter((p) => p.type === PIECE_TYPE.TAG);
if (tagsPieces.length !== 1) {
throw new CodeGeneratorError('One node only need one tag define');
throw new CodeGeneratorError('Only one tag definition required', tagsPieces);
}
const tagName = tagsPieces[0].value;
@ -216,13 +216,13 @@ function linkPieces(pieces: CodePiece[]): string {
}
function generateNodeSchema(
nodeItem: NodeSchema,
nodeItem: IPublicTypeNodeSchema,
scope: IScope,
config?: NodeGeneratorConfig,
): string {
const pieces: CodePiece[] = [];
if (config?.nodePlugins) {
const res = executeFunctionStack<NodeSchema, CodePiece[], NodeGeneratorConfig>(
const res = executeFunctionStack<IPublicTypeNodeSchema, CodePiece[], NodeGeneratorConfig>(
nodeItem,
scope,
config.nodePlugins,
@ -247,11 +247,11 @@ function generateNodeSchema(
* @type NodePlugin Extended
*
* @export
* @param {NodeSchema} nodeItem UI
* @param {IPublicTypeNodeSchema} nodeItem UI
* @returns {CodePiece[]}
*/
export function generateReactLoopCtrl(
nodeItem: NodeSchema,
nodeItem: IPublicTypeNodeSchema,
scope: IScope,
config?: NodeGeneratorConfig,
next?: NodePlugin,
@ -270,8 +270,7 @@ export function generateReactLoopCtrl(
const loopDataExpr = pipe(
nodeItem.loop,
// 将 JSExpression 转换为 JS 表达式代码:
(expr) =>
generateCompositeType(expr, scope, {
(expr) => generateCompositeType(expr, scope, {
handlers: config?.handlers,
tolerateEvalErrors: false, // 这个内部不需要包 try catch, 下面会统一加的
}),
@ -302,11 +301,11 @@ export function generateReactLoopCtrl(
* @type NodePlugin
*
* @export
* @param {NodeSchema} nodeItem UI
* @param {IPublicTypeNodeSchema} nodeItem UI
* @returns {CodePiece[]}
*/
export function generateConditionReactCtrl(
nodeItem: NodeSchema,
nodeItem: IPublicTypeNodeSchema,
scope: IScope,
config?: NodeGeneratorConfig,
next?: NodePlugin,
@ -337,11 +336,11 @@ export function generateConditionReactCtrl(
* @type NodePlugin
*
* @export
* @param {NodeSchema} nodeItem UI
* @param {IPublicTypeNodeSchema} nodeItem UI
* @returns {CodePiece[]}
*/
export function generateReactExprInJS(
nodeItem: NodeSchema,
nodeItem: IPublicTypeNodeSchema,
scope: IScope,
config?: NodeGeneratorConfig,
next?: NodePlugin,
@ -366,7 +365,7 @@ export function generateReactExprInJS(
const handleChildren = (v: string[]) => v.join('');
export function createNodeGenerator(cfg: NodeGeneratorConfig = {}): NodeGenerator<string> {
const generateNode = (nodeItem: NodeDataType, scope: IScope): string => {
const generateNode = (nodeItem: IPublicTypeNodeDataType, scope: IScope): string => {
if (_.isArray(nodeItem)) {
const resList = nodeItem.map((n) => generateNode(n, scope));
return handleChildren(resList);
@ -391,8 +390,7 @@ export function createNodeGenerator(cfg: NodeGeneratorConfig = {}): NodeGenerato
return `{${valueStr}}`;
};
return (nodeItem: NodeDataType, scope: IScope) =>
unwrapJsExprQuoteInJsx(generateNode(nodeItem, scope));
return (nodeItem: IPublicTypeNodeDataType, scope: IScope) => unwrapJsExprQuoteInJsx(generateNode(nodeItem, scope));
}
const defaultReactGeneratorConfig: NodeGeneratorConfig = {

View File

@ -1,20 +1,20 @@
import * as _ from 'lodash';
import {
JSExpression,
NodeData,
NodeSchema,
IPublicTypeJSExpression,
IPublicTypeNodeData,
IPublicTypeNodeSchema,
isJSExpression,
isJSSlot,
isDOMText,
ContainerSchema,
NpmInfo,
CompositeValue,
IPublicTypeContainerSchema,
IPublicTypeNpmInfo,
IPublicTypeCompositeValue,
isNodeSchema,
isJSFunction,
} from '@alilc/lowcode-types';
import { CodeGeneratorError } from '../types/error';
export function isContainerSchema(x: any): x is ContainerSchema {
export function isContainerSchema(x: any): x is IPublicTypeContainerSchema {
return (
typeof x === 'object' &&
x &&
@ -23,7 +23,7 @@ export function isContainerSchema(x: any): x is ContainerSchema {
);
}
export function isNpmInfo(x: any): x is NpmInfo {
export function isNpmInfo(x: any): x is IPublicTypeNpmInfo {
return typeof x === 'object' && x && typeof x.package === 'string';
}
@ -43,11 +43,11 @@ const DEFAULT_MAX_DEPTH = 100000;
* @returns
*/
export function handleSubNodes<T>(
children: NodeSchema['children'],
children: IPublicTypeNodeSchema['children'],
handlers: {
string?: (i: string) => T;
expression?: (i: JSExpression) => T;
node?: (i: NodeSchema) => T;
expression?: (i: IPublicTypeJSExpression) => T;
node?: (i: IPublicTypeNodeSchema) => T;
},
options?: {
rerun?: boolean;
@ -64,7 +64,7 @@ export function handleSubNodes<T>(
}
if (Array.isArray(children)) {
const list: NodeData[] = children as NodeData[];
const list: IPublicTypeNodeData[] = children as IPublicTypeNodeData[];
return list
.map((child) => handleSubNodes(child, handlers, { ...opt, maxDepth: maxDepth - 1 }))
.reduce((p, c) => p.concat(c), []);
@ -84,7 +84,7 @@ export function handleSubNodes<T>(
return handleSubNodes(children.value, handlers, { ...opt, maxDepth: maxDepth - 1 });
} else if (isNodeSchema(children)) {
const handler = handlers.node || noop;
const child = children as NodeSchema;
const child = children as IPublicTypeNodeSchema;
result = handler(child);
if (child.children) {
@ -115,7 +115,7 @@ export function handleSubNodes<T>(
return childrenRes;
function handleCompositeValueInProps(value: CompositeValue): T[] {
function handleCompositeValueInProps(value: IPublicTypeCompositeValue): T[] {
if (isJSSlot(value)) {
return handleSubNodes(value.value, handlers, { ...opt, maxDepth: maxDepth - 1 });
}
@ -125,7 +125,7 @@ export function handleSubNodes<T>(
return _.flatMap(value, (v) => handleCompositeValueInProps(v));
}
// CompositeObject
// IPublicTypeCompositeObject
if (
!isJSExpression(value) &&
!isJSFunction(value) &&
@ -138,3 +138,11 @@ export function handleSubNodes<T>(
return [];
}
}
export function isValidContainerType(schema: IPublicTypeNodeSchema) {
return [
'Page',
'Component',
'Block',
].includes(schema.componentName);
}

View File

@ -1,7 +1,7 @@
import CodeGenerator from '../../src';
import * as fs from 'fs';
import * as path from 'path';
import { ProjectSchema } from '@alilc/lowcode-types';
import { IPublicTypeProjectSchema } from '@alilc/lowcode-types';
import { createDiskPublisher } from '../helpers/solutionHelper';
const testCaseBaseName = path.basename(__filename, '.test.ts');
@ -19,7 +19,7 @@ describe(testCaseBaseName, () => {
`
<Greetings
content={this._i18nText({
key: "greetings.hello",
key: 'greetings.hello',
params: { name: this.state.name },
})}
/>
@ -31,7 +31,7 @@ describe(testCaseBaseName, () => {
function exportProject(
importPath: string,
outputPath: string,
mergeSchema?: Partial<ProjectSchema>,
mergeSchema?: Partial<IPublicTypeProjectSchema>,
) {
const schemaJsonStr = fs.readFileSync(importPath, { encoding: 'utf8' });
const schema = { ...JSON.parse(schemaJsonStr), ...mergeSchema };

View File

@ -1,7 +1,7 @@
import CodeGenerator from '../../src';
import * as fs from 'fs';
import * as path from 'path';
import { ProjectSchema } from '@alilc/lowcode-types';
import { IPublicTypeProjectSchema } from '@alilc/lowcode-types';
import { createDiskPublisher } from '../helpers/solutionHelper';
const testCaseBaseName = path.basename(__filename, '.test.ts');
@ -27,7 +27,7 @@ describe(testCaseBaseName, () => {
});
const generatedPageFileContent = readOutputTextFile('demo-project/src/pages/Test/index.jsx');
expect(generatedPageFileContent).toContain(`import Foo from "example-package/lib/index.js";`);
expect(generatedPageFileContent).toContain('import Foo from \'example-package/lib/index.js\';');
});
test('named import with no alias', async () => {
@ -47,7 +47,7 @@ describe(testCaseBaseName, () => {
const generatedPageFileContent = readOutputTextFile('demo-project/src/pages/Test/index.jsx');
expect(generatedPageFileContent).toContain(
`import { Foo } from "example-package/lib/index.js";`,
'import { Foo } from \'example-package/lib/index.js\';',
);
});
@ -68,7 +68,7 @@ describe(testCaseBaseName, () => {
const generatedPageFileContent = readOutputTextFile('demo-project/src/pages/Test/index.jsx');
expect(generatedPageFileContent).toContain(
`import { Bar as Foo } from "example-package/lib/index.js";`,
'import { Bar as Foo } from \'example-package/lib/index.js\';',
);
});
@ -88,7 +88,7 @@ describe(testCaseBaseName, () => {
});
const generatedPageFileContent = readOutputTextFile('demo-project/src/pages/Test/index.jsx');
expect(generatedPageFileContent).toContain(`import Foo from "example-package/lib/index.js";`);
expect(generatedPageFileContent).toContain('import Foo from \'example-package/lib/index.js\';');
});
test('default import with sub name and export name', async () => {
@ -107,9 +107,9 @@ describe(testCaseBaseName, () => {
});
const generatedPageFileContent = readOutputTextFile('demo-project/src/pages/Test/index.jsx');
expect(generatedPageFileContent).toContain(`import Bar from "example-package/lib/index.js";`);
expect(generatedPageFileContent).toContain('import Bar from \'example-package/lib/index.js\';');
expect(generatedPageFileContent).toContain(`const Foo = Bar.Baz;`);
expect(generatedPageFileContent).toContain('const Foo = Bar.Baz;');
});
test('default import with sub name without export name', async () => {
@ -129,10 +129,10 @@ describe(testCaseBaseName, () => {
const generatedPageFileContent = readOutputTextFile('demo-project/src/pages/Test/index.jsx');
expect(generatedPageFileContent).toContain(
`import __$examplePackage_default from "example-package/lib/index.js";`,
'import __$examplePackage_default from \'example-package/lib/index.js\';',
);
expect(generatedPageFileContent).toContain(`const Foo = __$examplePackage_default.Baz;`);
expect(generatedPageFileContent).toContain('const Foo = __$examplePackage_default.Baz;');
});
test('named import with sub name', async () => {
@ -152,10 +152,10 @@ describe(testCaseBaseName, () => {
const generatedPageFileContent = readOutputTextFile('demo-project/src/pages/Test/index.jsx');
expect(generatedPageFileContent).toContain(
`import { Bar } from "example-package/lib/index.js";`,
'import { Bar } from \'example-package/lib/index.js\';',
);
expect(generatedPageFileContent).toContain(`const Foo = Bar.Baz;`);
expect(generatedPageFileContent).toContain('const Foo = Bar.Baz;');
});
test('default imports with different componentName', async () => {
@ -187,18 +187,18 @@ describe(testCaseBaseName, () => {
});
const generatedPageFileContent = readOutputTextFile('demo-project/src/pages/Test/index.jsx');
expect(generatedPageFileContent).toContain(`import Foo from "example-package";`);
expect(generatedPageFileContent).toContain(`import Baz from "example-package";`);
expect(generatedPageFileContent).toContain('import Foo from \'example-package\';');
expect(generatedPageFileContent).toContain('import Baz from \'example-package\';');
expect(generatedPageFileContent).not.toContain(`const Foo =`);
expect(generatedPageFileContent).not.toContain(`const Baz =`);
expect(generatedPageFileContent).not.toContain('const Foo =');
expect(generatedPageFileContent).not.toContain('const Baz =');
});
});
function exportProject(
importPath: string,
outputPath: string,
mergeSchema?: Partial<ProjectSchema>,
mergeSchema?: Partial<IPublicTypeProjectSchema>,
) {
const schemaJsonStr = fs.readFileSync(importPath, { encoding: 'utf8' });
const schema = { ...JSON.parse(schemaJsonStr), ...mergeSchema };

Some files were not shown because too many files have changed in this diff Show More