diff --git a/.eslintrc.js b/.eslintrc.js index 5a8fe9e97..1ec3834e6 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -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"] } + ], } -}; +}; \ No newline at end of file diff --git a/babel.config.js b/babel.config.js new file mode 100644 index 000000000..a089167a7 --- /dev/null +++ b/babel.config.js @@ -0,0 +1,6 @@ +module.exports = { + plugins: [ + ['@babel/plugin-proposal-decorators', { legacy: true }], + [require.resolve('@babel/plugin-proposal-class-properties'), { loose: true }], + ], +}; \ No newline at end of file diff --git a/docs/README.md b/docs/README.md index 12c8f1fbe..85da75163 100644 --- a/docs/README.md +++ b/docs/README.md @@ -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 - diff --git a/docs/config/navbar.js b/docs/config/navbar.js index 0f0486398..20d5e5f90 100644 --- a/docs/config/navbar.js +++ b/docs/config/navbar.js @@ -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', diff --git a/docs/config/sidebars.js b/docs/config/sidebars.js index e2de2d49c..77a2e1f22 100644 --- a/docs/config/sidebars.js +++ b/docs/config/sidebars.js @@ -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'), }; diff --git a/docs/docs/api/canvas.md b/docs/docs/api/canvas.md new file mode 100644 index 000000000..582f2354b --- /dev/null +++ b/docs/docs/api/canvas.md @@ -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)
+> **@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; +``` diff --git a/docs/docs/api/common.md b/docs/docs/api/common.md index c16d22043..e5bfa8629 100644 --- a/docs/docs/api/common.md +++ b/docs/docs/api/common.md @@ -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)
+> **@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; +``` \ No newline at end of file diff --git a/docs/docs/api/config.md b/docs/docs/api/config.md index 40d18eb3a..ea4c7dbfc 100644 --- a/docs/docs/api/config.md +++ b/docs/docs/api/config.md @@ -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)
+> **@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 +/** + * 获取指定 key 的值,若此时还未赋值,则等待,若已有值,则直接返回值 + * 注:此函数返回 Promise 实例,只会执行(fullfill)一次 + * wait until value of certain key is set, will only be + * triggered once. + * @param key + * @returns + */ +onceGot(key: string): Promise; ``` -**调用示例** +#### 示例 ```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) -无 +``` \ No newline at end of file diff --git a/docs/docs/api/event.md b/docs/docs/api/event.md index b24c91054..0eb8b9738 100644 --- a/docs/docs/api/event.md +++ b/docs/docs/api/event.md @@ -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)
+> **@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}`); // 触发事件 diff --git a/docs/docs/api/hotkey.md b/docs/docs/api/hotkey.md index 60e8a3f3f..a244b94c2 100644 --- a/docs/docs/api/hotkey.md +++ b/docs/docs/api/hotkey.md @@ -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)
+> **@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() { diff --git a/docs/docs/api/index.md b/docs/docs/api/index.md index 212337a62..993c39e88 100644 --- a/docs/docs/api/index.md +++ b/docs/docs/api/index.md @@ -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 可能会发生改变. \ No newline at end of file diff --git a/docs/docs/api/init.md b/docs/docs/api/init.md index 93ad133d3..f8bf2cdbe 100644 --- a/docs/docs/api/init.md +++ b/docs/docs/api/init.md @@ -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'; diff --git a/docs/docs/api/logger.md b/docs/docs/api/logger.md index d523622d8..7493f34dc 100644 --- a/docs/docs/api/logger.md +++ b/docs/docs/api/logger.md @@ -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)
+> **@since** v1.0.0 + + +## 模块简介 +引擎日志模块,可以按照 **日志级别 **和** 业务类型 **两个维度来定制日志。 +> 注:日志级别可以通过 url query 动态调整,详见下方[查看示例](#查看示例)。
+> 参考 [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 +- 方式 2:url 上追加 __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 ``` diff --git a/docs/docs/api/material.md b/docs/docs/api/material.md index 4cf1948cf..b52ad8cb2 100644 --- a/docs/docs/api/material.md +++ b/docs/docs/api/material.md @@ -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)
+> **@since** v1.0.0 + + +## 模块简介 负责物料相关的 API,包括资产包、设计器辅助层、物料元数据和物料元数据管道函数。 -# 变量(variables) -## componentsMap +## 变量 +### componentsMap 获取组件 map 结构 +```typescript +/** + * 获取组件 map 结构 + * get map of components + */ +get componentsMap(): { [key: string]: IPublicTypeNpmInfo | ComponentType | 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-/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-/assets.json'; @@ -83,57 +115,23 @@ import assets2 from '@alilc/mc-assets-/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 | 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; -``` -**示例** +```typescript + /** + * 获取所有已注册的物料元数据 + * get map of all component metas + * @returns + */ + getComponentMetasMap(): Map; +``` +相关类型:[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'; diff --git a/docs/docs/api/model/_category_.json b/docs/docs/api/model/_category_.json new file mode 100644 index 000000000..5b1f74b36 --- /dev/null +++ b/docs/docs/api/model/_category_.json @@ -0,0 +1,6 @@ +{ + "label": "模型定义 Models", + "position": 14, + "collapsed": false, + "collapsible": true +} diff --git a/docs/docs/api/model/clipboard.md b/docs/docs/api/model/clipboard.md new file mode 100644 index 000000000..15d9e280c --- /dev/null +++ b/docs/docs/api/model/clipboard.md @@ -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)
+> **@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; +``` \ No newline at end of file diff --git a/docs/docs/api/model/component-meta.md b/docs/docs/api/model/component-meta.md new file mode 100644 index 000000000..28f7fe740 --- /dev/null +++ b/docs/docs/api/model/component-meta.md @@ -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)
+> **@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; +``` diff --git a/docs/docs/api/model/detecting.md b/docs/docs/api/model/detecting.md new file mode 100644 index 000000000..ccd60e3a6 --- /dev/null +++ b/docs/docs/api/model/detecting.md @@ -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)
+> **@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** \ No newline at end of file diff --git a/docs/docs/api/model/document-model.md b/docs/docs/api/model/document-model.md new file mode 100644 index 000000000..4da765d30 --- /dev/null +++ b/docs/docs/api/model/document-model.md @@ -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)
+> **@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} ` + + +相关章节:[节点模型](./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** \ No newline at end of file diff --git a/docs/docs/api/model/dragon.md b/docs/docs/api/model/dragon.md new file mode 100644 index 000000000..995fd1b1f --- /dev/null +++ b/docs/docs/api/model/dragon.md @@ -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)
+> **@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; +``` \ No newline at end of file diff --git a/docs/docs/api/model/drop-location.md b/docs/docs/api/model/drop-location.md new file mode 100644 index 000000000..dc6a684e4 --- /dev/null +++ b/docs/docs/api/model/drop-location.md @@ -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)
+> **@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) \ No newline at end of file diff --git a/docs/docs/api/model/history.md b/docs/docs/api/model/history.md new file mode 100644 index 000000000..b8c4d791b --- /dev/null +++ b/docs/docs/api/model/history.md @@ -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)
+> **@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) \ No newline at end of file diff --git a/docs/docs/api/model/modal-nodes-manager.md b/docs/docs/api/model/modal-nodes-manager.md new file mode 100644 index 000000000..acff26734 --- /dev/null +++ b/docs/docs/api/model/modal-nodes-manager.md @@ -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)
+> **@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) diff --git a/docs/docs/api/model/node-children.md b/docs/docs/api/model/node-children.md new file mode 100644 index 000000000..10488a733 --- /dev/null +++ b/docs/docs/api/model/node-children.md @@ -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)
+> **@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(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) diff --git a/docs/docs/api/model/node.md b/docs/docs/api/model/node.md new file mode 100644 index 000000000..333e973f0 --- /dev/null +++ b/docs/docs/api/model/node.md @@ -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)
+> **@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** diff --git a/docs/docs/api/model/plugin-instance.md b/docs/docs/api/model/plugin-instance.md new file mode 100644 index 000000000..14ce38837 --- /dev/null +++ b/docs/docs/api/model/plugin-instance.md @@ -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)
+> **@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) diff --git a/docs/docs/api/model/prop.md b/docs/docs/api/model/prop.md new file mode 100644 index 000000000..d9b0d14f4 --- /dev/null +++ b/docs/docs/api/model/prop.md @@ -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)
+> **@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) \ No newline at end of file diff --git a/docs/docs/api/model/props.md b/docs/docs/api/model/props.md new file mode 100644 index 000000000..9bd6eaa66 --- /dev/null +++ b/docs/docs/api/model/props.md @@ -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)
+> **@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** \ No newline at end of file diff --git a/docs/docs/api/model/resource.md b/docs/docs/api/model/resource.md new file mode 100644 index 000000000..397723454 --- /dev/null +++ b/docs/docs/api/model/resource.md @@ -0,0 +1,46 @@ +--- +title: Resource +sidebar_position: 13 +--- + +> **[@experimental](./#experimental)**
+> **@types** [IPublicModelResource](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/resource.ts)
+> **@since** v1.1.0 + +## 属性 + +### title + +资源标题 + +`@type {string}` + +### name + +资源名字 + +`@type {string}` + +### type + +资源类型 + +`@type {string}` + +### category + +资源分类 + +`@type {string}` + +### icon + +资源 icon + +`@type {ReactElement}` + +### options + +资源配置信息 + +`@type {Object}` diff --git a/docs/docs/api/model/selection.md b/docs/docs/api/model/selection.md new file mode 100644 index 000000000..9fc2e3a1c --- /dev/null +++ b/docs/docs/api/model/selection.md @@ -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)
+> **@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** \ No newline at end of file diff --git a/docs/docs/api/model/window.md b/docs/docs/api/model/window.md new file mode 100644 index 000000000..f102c0cab --- /dev/null +++ b/docs/docs/api/model/window.md @@ -0,0 +1,76 @@ +--- +title: Window +sidebar_position: 12 +--- + +> **[@experimental](./#experimental)**
+> **@types** [IPublicModelWindow](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/window.ts)
+> **@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) diff --git a/docs/docs/api/plugins.md b/docs/docs/api/plugins.md index f225386fc..58be1fde0 100644 --- a/docs/docs/api/plugins.md +++ b/docs/docs/api/plugins.md @@ -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)
+> **@since** v1.0.0 + ## 模块简介 插件管理器,提供编排模块中管理插件的能力。 -## 变量(variables) -无 -## 方法签名(functions) + +## 方法 ### register 注册插件 -#### 类型定义 ```typescript async function register( - pluginConfigCreator: (ctx: ILowCodePluginContext) => ILowCodePluginConfig, - options?: ILowCodeRegisterOptions, + plugin: IPublicTypePlugin, + options?: IPublicTypePluginRegisterOptions, ): Promise ``` -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 -``` -**调用示例** -```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) diff --git a/docs/docs/api/project.md b/docs/docs/api/project.md index 7c5896852..0c7213aac 100644 --- a/docs/docs/api/project.md +++ b/docs/docs/api/project.md @@ -2,880 +2,316 @@ title: project - 模型 API sidebar_position: 3 --- -# 模块简介 -引擎编排模块中包含多种模型,包括[项目模型(project)](#DADnF)、[文档模型(document-model)](#lp7xO)、[节点模型(node)](#m0cJS)、[节点孩子模型(node-children)](#W8seq)、[属性集模型(props)](#IJeRY)以及[属性模型(prop)](#w1diM)。 +## 模块简介 + +引擎编排模块中包含多种模型,包括: +- [文档模型 DocumentModel](./model/document-model) +- [节点模型 Node](./model/node) +- [节点孩子模型 NodeChildren](./model/node-children) +- [属性模型 Prop](./model/prop) +- [属性集模型 Props](./model/props) + 他们的依赖关系如下图: ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01B1bAZi1asNU3KaSUJ_!!6000000003385-2-tps-1650-1352.png) -在文档模型内部,又有一些引申模型,比如[历史操作(history)](#xvIKj)、[画布节点选中(selection)](#GtFkP)、[画布节点悬停(detecting)](#Tjt05)等。 -整个模型系统,以项目模型为最顶层的模型,其他模型实例均需要通过 project 来获得,比如 project.currentDocument 来获取当前的文档模型,project.currentDocument.nodesMap 来获取当前文档模型里所有的节点列表。 +在文档模型内部,又有一些引申模型,比如: +- [历史操作 History)](./model/history) +- [画布节点选中 Selection)](./model/selection) +- [画布节点悬停 Detecting)](./model/detecting) +- [模态节点管理器 ModalNodesManager](./model/modal-nodes-manager) -# 项目模型(Project) -## 变量(variables) +整个模型系统,以 project API 为入口,所有模型实例均需要通过 project 来获得,比如 project.currentDocument 来获取当前的文档模型,project.currentDocument.nodesMap 来获取当前文档模型里所有的节点列表。 + +下面来看看 project API 的具体介绍 + +## 变量 ### currentDocument 获取当前的 document 实例 + +```typescript +/** + * 获取当前的 document + * get current document + */ +get currentDocument(): IPublicModelDocumentModel | null; +``` + +相关类型:[IPublicModelDocumentModel](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/document-model.ts) + ### documents 获取当前 project 下所有 documents + +```typescript +/** + * 获取当前 project 下所有 documents + * get all documents of this project + * @returns + */ +get documents(): IPublicModelDocumentModel[]; +``` + +相关类型:[IPublicModelDocumentModel](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/document-model.ts) + ### simulatorHost 获取模拟器的 host -## -## 方法签名(functions) -### openDocument -openDocument(doc?: string | RootSchema | undefined) +```typescript +/** + * 获取模拟器的 host + * get simulator host + */ +get simulatorHost(): IPublicApiSimulatorHost | null; +``` + +相关类型:[IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts) + + +## 方法 +### openDocument 打开一个 document +```typescript +/** + * 打开一个 document + * @param doc + * @returns + */ +openDocument(doc?: string | IPublicTypeRootSchema | undefined): IPublicModelDocumentModel | null; +``` + +相关类型: +- [IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts) +- [IPublicTypeRootSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/root-schema.ts) + ### createDocument -createDocument(data?: RootSchema): DocumentModel | null - 创建一个 document -### -### removeDocument -removeDocument(doc: DocumentModel) +```typescript +/** + * 创建一个 document + * create a document + * @param data + * @returns + */ +createDocument(data?: IPublicTypeRootSchema): IPublicModelDocumentModel | null; +``` + +相关类型: +- [IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts) +- [IPublicTypeRootSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/root-schema.ts) + +### removeDocument 删除一个 document +```typescript +/** + * 删除一个 document + * remove a document + * @param doc + */ +removeDocument(doc: IPublicModelDocumentModel): void; +``` + +相关类型:[IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts) + ### getDocumentByFileName -getDocumentByFileName(fileName: string): DocumentModel | null - 根据 fileName 获取 document +```typescript +/** + * 根据 fileName 获取 document + * get a document by filename + * @param fileName + * @returns + */ +getDocumentByFileName(fileName: string): IPublicModelDocumentModel | null; +``` + +相关类型:[IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts) ### getDocumentById -getDocumentById(id: string): DocumentModel | null - 根据 id 获取 document +```typescript +/** + * 根据 id 获取 document + * get a document by id + * @param id + * @returns + */ +getDocumentById(id: string): IPublicModelDocumentModel | null; +``` + +相关类型:[IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts) + ### exportSchema -exportSchema() +导出 project schema -导出 project +```typescript +/** + * 导出 project + * export project to schema + * @returns + */ +exportSchema(stage: IPublicEnumTransformStage): IPublicTypeProjectSchema; +``` + +相关类型: +- [IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts) +- [IPublicTypeProjectSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/project-schema.ts) ### importSchema -importSchema(schema?: ProjectSchema) - 导入 project +```typescript +/** + * 导入 project schema + * import schema to project + * @param schema 待导入的 project 数据 + */ +importSchema(schema?: IPublicTypeProjectSchema): void; +``` +相关类型:[IPublicTypeProjectSchema](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/project-schema.ts) + ### getCurrentDocument - -getCurrentDocument(): DocumentModel | null - 获取当前的 document +```typescript +/** + * 获取当前的 document + * get current document + * @returns + */ +getCurrentDocument(): IPublicModelDocumentModel | null; +``` +相关类型:[IPublicModelDocumentModel](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/document-model.ts) + ### addPropsTransducer - -addPropsTransducer(transducer: PropsTransducer, stage: TransformStage) - 增加一个属性的管道处理函数 -**示例 1:在保存的时候删除每一个组件的 props.hidden** ```typescript -import { ILowCodePluginContext, project } from '@alilc/lowcode-engine'; -import { CompositeObject, TransformStage } from '@alilc/lowcode-types'; +/** + * 增加一个属性的管道处理函数 + * add a transducer to process prop + * @param transducer + * @param stage + */ +addPropsTransducer( + transducer: IPublicTypePropsTransducer, + stage: IPublicEnumTransformStage, + ): void; +``` +相关类型: +- [IPublicTypePropsTransducer](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/props-transducer.ts) +- [IPublicEnumTransformStage](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/enum/transform-stage.ts) -export const deleteHiddenTransducer = (ctx: ILowCodePluginContext) => { +#### 示例 +在保存的时候删除每一个组件的 props.hidden +```typescript +import { project } from '@alilc/lowcode-engine'; +import { IPublicTypeCompositeObject, IPublicEnumTransformStage, IPublicModelPluginContext } from '@alilc/lowcode-types'; + +export const DeleteHiddenTransducer = (ctx: IPublicModelPluginContext) => { return { - name: 'deleteHiddenTransducer', async init() { - project.addPropsTransducer((props: CompositeObject): CompositeObject => { + const { project } = ctx; + project.addPropsTransducer((props: IPublicTypeCompositeObject): IPublicTypeCompositeObject => { delete props.hidden; return props; - }, TransformStage.Save); + }, IPublicEnumTransformStage.Save); }, }; } -deleteHiddenTransducer.pluginName = 'deleteHiddenTransducer'; +DeleteHiddenTransducer.pluginName = 'DeleteHiddenTransducer'; ``` +### setI18n +设置多语言语料 + +```typescript +/** + * 设置多语言语料 + * 数据格式参考 https://github.com/alibaba/lowcode-engine/blob/main/specs/lowcode-spec.md#2434%E5%9B%BD%E9%99%85%E5%8C%96%E5%A4%9A%E8%AF%AD%E8%A8%80%E7%B1%BB%E5%9E%8Baa + * + * set I18n data for this project + * @param value object + * @since v1.0.17 + */ +setI18n(value: object): void; +``` + +**@since v1.0.17** + + +## 事件 + ### onRemoveDocument 绑定删除文档事件 -```typescript -function onRemoveDocument(fn: (data: { docId: string}) => void) {} -``` -*引擎版本>=1.0.16 -### setI18n -设置多语言语料 -```typescript -function setI18n(value: object) {} -``` -*引擎版本>=1.0.17 -## 事件(events) -### onChangeDocument -onChangeDocument(fn: (doc: DocumentModel) => void) +```typescript +/** + * 绑定删除文档事件 + * set callback for event onDocumentRemoved + * @param fn + * @since v1.0.16 + */ +onRemoveDocument(fn: (data: { id: string }) => void): IPublicTypeDisposable; +``` +相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) + +**@since v1.0.16** + +### onChangeDocument 当前 project 内的 document 变更事件 -### onSimulatorHostReady +```typescript +/** + * 当前 project 内的 document 变更事件 + * set callback for event onDocumentChanged + */ +onChangeDocument(fn: (doc: IPublicModelDocumentModel) => void): IPublicTypeDisposable; +``` -onSimulatorHostReady(fn: (host: SimulatorHost) => void) +相关类型: +- [IPublicModelDocumentModel](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/model/document-model.ts) +- [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) + +### onSimulatorHostReady 当前 project 的模拟器 ready 事件 +```typescript +/** + * 当前 project 的模拟器 ready 事件 + * set callback for event onSimulatorHostReady + */ +onSimulatorHostReady(fn: (host: IPublicApiSimulatorHost) => void): IPublicTypeDisposable; +``` +相关类型: +- [IPublicApiSimulatorHost](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/simulator-host.ts) +- [IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) + ### onSimulatorRendererReady -onSimulatorRendererReady(fn: () => void) - 当前 project 的渲染器 ready 事件 -# -# 文档模型(DocumentModel) -## 变量(variables) -### selection - -画布节点选中区模型实例,具体方法参见 [画布节点选中区模型](#GtFkP) - -### detecting - -画布节点 hover 区模型实例,具体方法参见 [画布节点 hover 区模型](#Tjt05) - -### history - -操作历史模型实例,具体方法参见 [操作历史模型](#xvIKj) -### canvas - -获取当前画布中的一些信息,比如拖拽时的 dropLocation - -### project - -获取当前文档模型所属的 project - -### root - -获取文档的根节点 - -### nodesMap - -获取文档下所有节点 - -### modalNodesManager - -参见 [模态节点管理](#nNRF9) - -## 方法签名(functions) -### getNodeById - -getNodeById(nodeId: string) - -根据 nodeId 返回 [Node](#m0cJS) 实例 - -### importSchema - -importSchema(schema: RootSchema) - -导入 schema -### exportSchema - -exportSchema(stage: TransformStage = TransformStage.Render) - -导出 schema - -### insertNode - -insertNode( - parent: Node, - thing: Node, - at?: number | null | undefined, - copy?: boolean | undefined, - ) - -插入节点 -### createNode - -createNode(data: any) - -创建一个节点 -### removeNode - -removeNode(idOrNode: string | Node) - -移除指定节点/节点id - -### checkNesting -检查拖拽放置的目标节点是否可以放置该拖拽对象 -*引擎版本 > 1.0.16 -```typescript -function checkNesting(dropTarget: Node, dragObject: DragNodeObject | DragNodeDataObject): boolean {} -``` -## -## 事件(events) -### onAddNode - -onAddNode(fn: (node: Node) => void) - -当前 document 新增节点事件 ```typescript -import { project } from '@alilc/lowcode-engine'; - -project.currentDocument.onAddNode((node) => { - console.log('node', node); -}) +/** + * 当前 project 的渲染器 ready 事件 + * set callback for event onSimulatorRendererReady + */ +onSimulatorRendererReady(fn: () => void): IPublicTypeDisposable; ``` -### onRemoveNode - -onRemoveNode(fn: (node: Node) => void) - -当前 document 删除节点事件 - -### onChangeDetecting - -onChangeDetecting(fn: (node: Node) => void) - -当前 document 的 hover 变更事件 - -### onChangeSelection - -onChangeSelection(fn: (ids: string[]) => void) - -当前 document 的选中变更事件 - -### onChangeNodeVisible - -onChangeNodeVisible(fn: (node: Node, visible: boolean) => void) - -当前 document 的节点显隐状态变更事件 - -### onChangeNodeChildren - -onChangeNodeChildren(fn: (info?: IPublicOnChangeOptions) => void) - -当前 document 的节点 children 变更事件 - -### onChangeNodeProp -当前 document 节点属性修改事件 -```typescript -onChangeNodeProp(fn: (info: PropChangeOptions) => void) -``` - -### onImportSchema -当前 document 导入新的 schema 事件 -版本 >= 1.0.15 -```typescript -onImportSchema(fn: (schema: any) => void) -``` - -# 画布节点选中模型(Selection) -## 变量(variables) -### selected - -返回选中的节点 id - -## 方法签名(functions) -### select - -select(id: string) - -选中指定节点(覆盖方式) - -### selectAll - -selectAll(ids: string[]) - -批量选中指定节点们 - -### remove - -remove(id: string) - -**取消选中**选中的指定节点,不会删除组件 - -### clear - -clear() - -**取消选中**所有选中节点,不会删除组件 - -### has - -has(id: string) - -判断是否选中了指定节点 - -### add - -add(id: string) - -选中指定节点(增量方式) - -### getNodes - -getNodes() - -获取选中的节点实例 - -### getTopNodes -获取选区的顶层节点 -例如选中的节点为: - -- DivA - - ChildrenA -- DivB - -getNodes 返回的是 [DivA、ChildrenA、DivB],getTopNodes 返回的是 [DivA、DivB],其中 ChildrenA 由于是二层节点,getTopNodes 不会返回 - -*引擎版本 >= 1.0.16 - - -# 画布节点悬停模型(Detecting) -## 方法签名(functions) -### capture - -capture(id: string) - -hover 指定节点 - -### release - -release(id: string) - -hover 离开指定节点 - -### leave - -leave() - -清空 hover 态 - -### current -当前 hover 的节点 -*引擎版本 >= 1.0.16 - -# 操作历史记录模型(History) -## 方法签名(functions) -### go - -go(cursor: number) - -历史记录跳转到指定位置 - -### back - -back() - -历史记录后退 - -### forward - -forward() - -历史记录前进 -### savePoint - -savePoint() - -保存当前状态 -### isSavePoint - -isSavePoint() - -当前是否是「保存点」,即是否有状态变更但未保存 - -### getState - -getState() - -获取 state,判断当前是否为「可回退」、「可前进」的状态 - -## 事件(events) -### onChangeState - -onChangeState(func: () => any) - -监听 state 变更事件 - -### onChangeCursor - -onChangeCursor(func: () => any) - -监听历史记录游标位置变更事件 - -# 节点模型(Node) -## 变量(variables) -### id - -节点 id - -### title - -节点标题 - -### isContainer - -是否为「容器型」节点 - -### isRoot - -是否为根节点 - -### isEmpty - -是否为空节点(无 children 或者 children 为空) - -### isPage - -是否为 Page 节点 - -### isComponent - -是否为 Component 节点 - -### isModal - -是否为「模态框」节点 - -### isSlot - -是否为插槽节点 - -### isParental - -是否为父类/分支节点 - -### isLeaf -是否为叶子节点 - -### isLocked -获取当前节点的锁定状态 -*引擎版本>=1.0.16 - -### isRGLContainer -设置为磁贴布局节点,使用方式可参考:[磁贴布局在钉钉宜搭报表设计引擎中的实现](https://mp.weixin.qq.com/s/PSTut5ahAB8nlJ9kBpBaxw) -*引擎版本>=1.0.16 - -### index - -下标 - -### icon - -图标 - -### zLevel - -节点所在树的层级深度,根节点深度为 0 - -### componentName - -节点 componentName - -### componentMeta - -节点的物料元数据,参见 物料元数据 - -### document - -获取节点所属的[文档模型](#lp7xO)对象 - -### prevSibling - -获取当前节点的前一个兄弟节点 - -### nextSibling - -获取当前节点的后一个兄弟节点 - -### parent - -获取当前节点的父亲节点 - -### children - -获取当前节点的孩子节点模型 - -### slots - -节点上挂载的插槽节点们 - -### slotFor - -当前节点为插槽节点时,返回节点对应的属性实例 - -### props - -返回节点的属性集 - -### propsData - -返回节点的属性集值 - -## 方法签名(functions) -### getDOMNode - -getDOMNode() - -获取节点实例对应的 dom 节点 - -### getRect - -getRect() - -返回节点的尺寸、位置信息 - -### hasSlots - -hasSlots() - -是否有挂载插槽节点 - -### hasCondition - -hasCondition() - -是否设定了渲染条件 - -### hasLoop - -hasLoop() - -是否设定了循环数据 - -### getProp - -getProp(path: string): Prop | null - -获取指定 path 的属性模型实例 - -### getPropValue - -getPropValue(path: string) - -获取指定 path 的属性模型实例值 - -### getExtraProp - -getExtraProp(path: string): Prop | null - -获取指定 path 的属性模型实例,注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 - -### getExtraPropValue - -getExtraPropValue(path: string) - -获取指定 path 的属性模型实例,注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 - -### setPropValue - -setPropValue(path: string, value: CompositeValue) - -设置指定 path 的属性模型实例值 - -### setExtraPropValue - -setExtraPropValue(path: string, value: CompositeValue) - -设置指定 path 的属性模型实例值 - -### importSchema - -importSchema(data: NodeSchema) - -导入节点数据 - -### exportSchema - -exportSchema(stage: TransformStage = TransformStage.Render, options?: any) - -导出节点数据 - -### insertBefore - -insertBefore(node: Node, ref?: Node | undefined, useMutator?: boolean) - -在指定位置之前插入一个节点 - -### insertAfter - -insertAfter(node: Node, ref?: Node | undefined, useMutator?: boolean) - -在指定位置之后插入一个节点 - -### replaceChild - -replaceChild(node: Node, data: any) - -替换指定节点 - -### replaceWith - -replaceWith(schema: NodeSchema) - -将当前节点替换成指定节点描述 - -### select - -select() - -选中当前节点实例 - -### hover - -hover(flag = true) - -设置悬停态 - -### lock -设置节点锁定状态 -```typescript -function lock(flag?: boolean){} -``` -*引擎版本>=1.0.16 - -### remove - -remove() - -删除当前节点实例 - -# 节点孩子模型(NodeChildren) -## 变量(variables) -### owner - -返回当前 children 实例所属的节点实例 - -### size - -children 内的节点实例数 - -### isEmpty - -是否为空 - -## 方法签名(functions) -### delete - -delete(node: Node) - -删除指定节点 - -### insert - -insert(node: Node, at?: number | null) - -插入一个节点 - -### indexOf - -indexOf(node: Node) - -返回指定节点的下标 - -### splice - -splice(start: number, deleteCount: number, node?: Node) - -类似数组 splice 操作 - -### get - -get(index: number) - -返回指定下标的节点 - -### has - -has(node: Node) - -是否包含指定节点 - -### forEach - -forEach(fn: (node: Node, index: number) => void) - -类似数组的 forEach - -### map - -map(fn: (node: Node, index: number) => T[]) - -类似数组的 map - -### every - -every(fn: (node: Node, index: number) => boolean) - -类似数组的 every - -### some - -some(fn: (node: Node, index: number) => boolean) - -类似数组的 some - -### filter - -filter(fn: (node: Node, index: number) => boolean) - -类似数组的 filter - -### find - -find(fn: (node: Node, index: number) => boolean) - -类似数组的 find - -### reduce - -reduce(fn: (acc: any, cur: Node) => any, initialValue: any) - -类似数组的 reduce - -### importSchema - -importSchema(data?: NodeData | NodeData[]) - -导入 schema - -### exportSchema - -exportSchema(stage: TransformStage = TransformStage.Render) - -导出 schema - -### mergeChildren - -mergeChildren( - remover: (node: Node, idx: number) => boolean, - adder: (children: Node[]) => any, - sorter: (firstNode: Node, secondNode: Node) => number, - ) - -执行新增、删除、排序等操作 - -# 属性集模型(Props) -## 变量(variables) -### id - -id -### path - -返回当前 props 的路径 -### node - -返回当前属性集所属的节点实例 - -## 方法签名(functions) -### getProp - -getProp(path: string): Prop | null - -获取指定 path 的属性模型实例 - -### getPropValue - -getPropValue(path: string) - -获取指定 path 的属性模型实例值 - -### getExtraProp - -getExtraProp(path: string): Prop | null - -获取指定 path 的属性模型实例,注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 -### getExtraPropValue - -getExtraPropValue(path: string) - -获取指定 path 的属性模型实例值,注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 -### - -### setPropValue - -setPropValue(path: string, value: CompositeValue) - -设置指定 path 的属性模型实例值 - -### setExtraPropValue - -setExtraPropValue(path: string, value: CompositeValue) - -设置指定 path 的属性模型实例值 - -# 属性模型(Prop) -## 变量(variables) -### id - -id - -### key - -key 值 - -### path - -返回当前 prop 的路径 - -### node - -返回所属的节点实例 - -## 方法签名(functions) -### setValue - -setValue(val: CompositeValue) - -设置值 - -### getValue - -getValue() - -获取值 - -### remove -移除值 -*引擎版本>=1.0.16 - -### exportSchema - -exportSchema(stage: TransformStage = TransformStage.Render) - -导出值 - -# 模态节点管理模型(ModalNodesManager) -## 方法签名(functions) -### getModalNodes - -getModalNodes() - -获取模态节点(们) - -### getVisibleModalNode - -getVisibleModalNode() - -获取当前可见的模态节点 - -### hideModalNodes - -hideModalNodes() - -隐藏模态节点(们) - -### setVisible - -setVisible(node: Node) - -设置指定节点为可见态 - -### setInvisible - -setInvisible(node: Node) - -设置指定节点为不可见态 - -### setNodes - -setNodes() - -设置模态节点,触发内部事件 +相关类型:[IPublicTypeDisposable](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/type/disposable.ts) diff --git a/docs/docs/api/setters.md b/docs/docs/api/setters.md index 41c992e16..92d24f4e1 100644 --- a/docs/docs/api/setters.md +++ b/docs/docs/api/setters.md @@ -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)
+> **@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 +/** + * 获取已注册的所有 settersMap + * get map of all registered setters + * @returns + */ +getSettersMap(): Map; ``` +相关类型:[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 -``` - -### 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 { - 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 ( - onChange(val)} - > - ); - } -} -``` -开发完毕之后,注册 AltStringSetter 到设计器中: -```typescript -import AltStringSetter from './AltStringSetter'; -const registerSetter = window.AliLowCodeEngine.setters.registerSetter; +import { setters } from '@alilc/lowcode-engine'; +const { registerSetter } = registerSetter; registerSetter('AltStringSetter', AltStringSetter); ``` 注册之后,我们就可以在物料中使用了,其中核心配置如下: diff --git a/docs/docs/api/simulatorHost.md b/docs/docs/api/simulatorHost.md index fc0009d3a..b30a61499 100644 --- a/docs/docs/api/simulatorHost.md +++ b/docs/docs/api/simulatorHost.md @@ -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)
+> **@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** diff --git a/docs/docs/api/skeleton.md b/docs/docs/api/skeleton.md index 1ae573e7e..6c8d898ff 100644 --- a/docs/docs/api/skeleton.md +++ b/docs/docs/api/skeleton.md @@ -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)
+> **@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): 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 widget,and 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 diff --git a/docs/docs/api/workspace.md b/docs/docs/api/workspace.md new file mode 100644 index 000000000..9d9960927 --- /dev/null +++ b/docs/docs/api/workspace.md @@ -0,0 +1,146 @@ +--- +title: workspace - 应用级 API +sidebar_position: 12 +--- + +> **[@experimental](./#experimental)**
+> **@types** [IPublicApiWorkspace](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/shell/api/workspace.ts)
+> **@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) diff --git a/docs/docs/article/index.md b/docs/docs/article/index.md index fd09a59a3..ed8b05ec0 100644 --- a/docs/docs/article/index.md +++ b/docs/docs/article/index.md @@ -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/) \ No newline at end of file +- [阿里低代码引擎项目实战 (7)-自定义插件 - 页面管理 (完结)](https://www.bilibili.com/video/BV13Y4y1e7EV/) diff --git a/docs/docs/faq/faq011.md b/docs/docs/faq/faq011.md index 3c6bf1d2d..f61d9830f 100644 --- a/docs/docs/faq/faq011.md +++ b/docs/docs/faq/faq011.md @@ -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) 再执行 diff --git a/docs/docs/faq/faq015.md b/docs/docs/faq/faq015.md index 48e97bc22..683e7df3a 100644 --- a/docs/docs/faq/faq015.md +++ b/docs/docs/faq/faq015.md @@ -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) diff --git a/docs/docs/guide/create/useEditor.md b/docs/docs/guide/create/useEditor.md index 21de39108..cbb38f77d 100644 --- a/docs/docs/guide/create/useEditor.md +++ b/docs/docs/guide/create/useEditor.md @@ -54,13 +54,13 @@ sidebar_position: 0 ```html - + - + @@ -76,11 +76,12 @@ sidebar_position: 0 - + - + ``` -> 注:如果 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) ### 配置打包 diff --git a/docs/docs/guide/design/editor.md b/docs/docs/guide/design/editor.md index b04cb4eb6..fcead2922 100644 --- a/docs/docs/guide/design/editor.md +++ b/docs/docs/guide/design/editor.md @@ -313,7 +313,7 @@ simulator-renderer 通过调用 host 的方法,将 schema、components 等参 - 被拖拽对象 - `DragObject` - 拖拽到的目标位置 - `DropLocation` -- 拖拽感应区 - `ISensor` +- 拖拽感应区 - `IPublicModelSensor` - 定位事件 - `LocateEvent` ##### Sensor diff --git a/docs/docs/guide/design/specs.md b/docs/docs/guide/design/specs.md index 3e2b1342c..0d97f5cc0 100644 --- a/docs/docs/guide/design/specs.md +++ b/docs/docs/guide/design/specs.md @@ -23,7 +23,7 @@ sidebar_position: 1 对于低代码物料来说,A 平台创建的物料无法使用到 B 平台上,如果想在 B 平台实现同样的物料,需要按照 B 平台的标准搭建一份物料。 -对于 ProCode 物料来说,需要在低代码平台进行消费,是需要进行转换的,包括搭建配置项的生成、物料搭建试图等,可能还需要特殊的描述文件进行描述。由于这一层没有统一,同一份 ProCode 物料每接入一个低代码,可能需要的描述文件格式不同,转换的代码不同,使用的工具也不同。 +对于 ProCode 物料来说,需要在低代码平台进行消费,是需要进行转换的,包括搭建配置项的生成、物料搭建视图等,可能还需要特殊的描述文件进行描述。由于这一层没有统一,同一份 ProCode 物料每接入一个低代码,可能需要的描述文件格式不同,转换的代码不同,使用的工具也不同。 ### 生态隔离 diff --git a/docs/docs/guide/expand/editor/cli.md b/docs/docs/guide/expand/editor/cli.md index 0218e6f73..60f44ce87 100644 --- a/docs/docs/guide/expand/editor/cli.md +++ b/docs/docs/guide/expand/editor/cli.md @@ -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() { diff --git a/docs/docs/guide/expand/editor/material.md b/docs/docs/guide/expand/editor/material.md index a5e374db9..6e4979553 100644 --- a/docs/docs/guide/expand/editor/material.md +++ b/docs/docs/guide/expand/editor/material.md @@ -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() { diff --git a/docs/docs/guide/expand/editor/metaSpec.md b/docs/docs/guide/expand/editor/metaSpec.md index 2e70550ac..2f874925f 100644 --- a/docs/docs/guide/expand/editor/metaSpec.md +++ b/docs/docs/guide/expand/editor/metaSpec.md @@ -10,7 +10,7 @@ sidebar_position: 2 ## 可视化生成物料描述 -使用 Parts 造物平台:[使用文档](/site/docs/guide/expand/editor/partsIntro) +使用 Parts 造物平台:[使用文档](/site/docs/guide/expand/editor/parts/partsIntro) ## 自动生成物料描述 diff --git a/docs/docs/guide/expand/editor/parts/_category_.json b/docs/docs/guide/expand/editor/parts/_category_.json new file mode 100644 index 000000000..005a3caf6 --- /dev/null +++ b/docs/docs/guide/expand/editor/parts/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "Parts 造物", + "position": 1 +} diff --git a/docs/docs/guide/expand/editor/parts/partsIntro.md b/docs/docs/guide/expand/editor/parts/partsIntro.md new file mode 100644 index 000000000..a6fc6e881 --- /dev/null +++ b/docs/docs/guide/expand/editor/parts/partsIntro.md @@ -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. 低代码生产组件:通过低代码的形式生产组件,极低上手门槛,提供丰富的原子组件用于组合,完善的调试预览和组件生命周期控制。生产的组件既可以在低代码引擎项目中使用,也可以出码后在普通源码项目中使用。 + + +## 联系我们 + + diff --git a/docs/docs/guide/expand/editor/parts/partsassets.md b/docs/docs/guide/expand/editor/parts/partsassets.md new file mode 100644 index 000000000..00670ecad --- /dev/null +++ b/docs/docs/guide/expand/editor/parts/partsassets.md @@ -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 ; + } + + return ( +
+ +
+ ); +}; + +ReactDOM.render(, 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: '', + }); + } + }; +} +``` +## 联系我们 + + \ No newline at end of file diff --git a/docs/docs/guide/expand/editor/parts/partslcc.md b/docs/docs/guide/expand/editor/parts/partslcc.md new file mode 100644 index 000000000..4d24b72f3 --- /dev/null +++ b/docs/docs/guide/expand/editor/parts/partslcc.md @@ -0,0 +1,92 @@ +--- +title: 低代码组件 +sidebar_position: 2 +--- +## 什么是低代码组件 +我们先了解一下什么是低代码组件,为什么要用低代码组件。 + +低代码组件是通过可视化的方式生产的组件,这些组件既可以用于低代码搭建体系,也可以用于 ProCode 开发体系(后续迭代)。 + +那么为什么我们要使用低代码的形式来开发组件: +* 首先轻快,低代码组件只需通过浏览器秒级完成初始化工作,不需要 ProCode 繁重的环境准备;环境一致(低代码环境),同时能够保证物料的开发环境和真实的运行环境是一致的,不会存在开发和运行环境不一致的问题。 +* 其次通用能力可视化方式抽象,提升研发效能,比如获取远程数据、视图开发、依赖管理、生命周期、事件绑定等功能。 + +低代码组件不是用来替代 ProCode 的开发方式,而是让开发者可以从 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,组件内部可以通过this.props.${属性名称}的方式获取属性值。 + +属性定义前建议先阅读 [物料描述详解](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) + +注意:目前导出功能暂不支持 低代码组件嵌套。 + +## 联系我们 + + \ No newline at end of file diff --git a/docs/docs/guide/expand/editor/partsIntro.md b/docs/docs/guide/expand/editor/parts/prototype.md similarity index 80% rename from docs/docs/guide/expand/editor/partsIntro.md rename to docs/docs/guide/expand/editor/parts/prototype.md index 174afc37a..b90728f65 100644 --- a/docs/docs/guide/expand/editor/partsIntro.md +++ b/docs/docs/guide/expand/editor/parts/prototype.md @@ -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) + diff --git a/docs/docs/guide/expand/editor/pluginContextMenu.md b/docs/docs/guide/expand/editor/pluginContextMenu.md index 9dc75ce65..e9dbdf3c4 100644 --- a/docs/docs/guide/expand/editor/pluginContextMenu.md +++ b/docs/docs/guide/expand/editor/pluginContextMenu.md @@ -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) diff --git a/docs/docs/guide/expand/editor/pluginWidget.md b/docs/docs/guide/expand/editor/pluginWidget.md index f1494bf2a..7efaffcf0 100644 --- a/docs/docs/guide/expand/editor/pluginWidget.md +++ b/docs/docs/guide/expand/editor/pluginWidget.md @@ -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/) \ No newline at end of file + - [阿里低代码引擎项目实战 (12)-区块管理 (完结)-给引擎插件提个 PR](https://www.bilibili.com/video/BV1hB4y1277o/) diff --git a/docs/docs/guide/expand/editor/setter.md b/docs/docs/guide/expand/editor/setter.md index 6a720374f..01fd949bb 100644 --- a/docs/docs/guide/expand/editor/setter.md +++ b/docs/docs/guide/expand/editor/setter.md @@ -1,6 +1,6 @@ --- title: 设置器扩展 -sidebar_position: 4 +sidebar_position: 5 --- ## 设置器简述 diff --git a/docs/docs/guide/expand/editor/summary.md b/docs/docs/guide/expand/editor/summary.md index 872205e21..814340f3d 100644 --- a/docs/docs/guide/expand/editor/summary.md +++ b/docs/docs/guide/expand/editor/summary.md @@ -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 组件到您的编辑器中,方位默认在左栏下侧 diff --git a/docs/docs/guide/quickStart/start.md b/docs/docs/guide/quickStart/start.md index 13f30159e..7999d1701 100644 --- a/docs/docs/guide/quickStart/start.md +++ b/docs/docs/guide/quickStart/start.md @@ -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 的编译结果。 ## 环境准备 + ### WSL(Window 电脑) + Window 环境需要使用 WSL 在 windows 下进行低代码引擎相关的开发。安装教程 ➡️ [WSL 安装教程](https://docs.microsoft.com/zh-cn/windows/wsl/install)。
**对于 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 -可以前往 github(https://github.com/alibaba/lowcode-demo)将 DEMO 下载到本地。 + +可以前往 github()将 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 进行扩展,定制一些新的功能。低代码引擎的能力还有很多很多,可以继续去探索更多的功能。 diff --git a/docs/docs/participate/config.md b/docs/docs/participate/config.md index 235cd4f02..1d70a7a89 100644 --- a/docs/docs/participate/config.md +++ b/docs/docs/participate/config.md @@ -2,13 +2,21 @@ title: 工程化配置 sidebar_position: 3 --- -目前引擎体系共包含 2 个 js 文件,即: +目前引擎体系共包含 2 个 js 文件 (配套 2 个 css),即: + + ```html - - - - + + + + + + + + + ``` + > 注,这里的版本号是示例,请尽量选用最新版 工程化配置我们进行了统一,具体如下: @@ -66,15 +74,15 @@ sidebar_position: 3 #### 所有资源: ```html - - + + - + - + ``` diff --git a/docs/docs/participate/flow.md b/docs/docs/participate/flow.md index 0a088807a..b8b804e12 100644 --- a/docs/docs/participate/flow.md +++ b/docs/docs/participate/flow.md @@ -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 ``` **官网生效** diff --git a/docs/docs/participate/prepare.md b/docs/docs/participate/prepare.md index b23dff33d..c0e1d5880 100644 --- a/docs/docs/participate/prepare.md +++ b/docs/docs/participate/prepare.md @@ -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" ], ] diff --git a/docs/docs/specs/assets-spec.md b/docs/docs/specs/assets-spec.md index dc55b12c1..5a91b8dde 100644 --- a/docs/docs/specs/assets-spec.md +++ b/docs/docs/specs/assets-spec.md @@ -2,8 +2,6 @@ title: 《低代码引擎资产包协议规范》 sidebar_position: 2 --- -# 《低代码引擎资产包协议规范》 - ## 1 介绍 ### 1.1 本协议规范涉及的问题域 diff --git a/docs/docs/specs/lowcode-spec.md b/docs/docs/specs/lowcode-spec.md index 6ad87caef..7deeedc2c 100644 --- a/docs/docs/specs/lowcode-spec.md +++ b/docs/docs/specs/lowcode-spec.md @@ -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 对象描述](#2318-componentpropdefinition-对象描述) | +| propDefinitions | 低代码业务组件属性类型定义 | **ComponentPropDefinition**[] | - | - | 选填,仅用于定义低代码业务组件的属性数据类型。详见 [ComponentPropDefinition 对象描述](#2318-componentpropdefinition-对象描述) | | condition | 渲染条件 | Boolean | ✅ | true | 选填,根据表达式结果判断是否渲染物料;支持变量表达式 | | state | 容器初始数据 | Object | ✅ | - | 选填,支持变量表达式 | | children | 子组件 | Array | - | | 选填,支持变量表达式 | @@ -751,7 +749,7 @@ try { | 参数 | 说明 | 值类型 | 默认值 | 备注 | | ----- | ---------- | --------------------- | -------- | -------------------------------------------------------------- | | type | 值类型描述 | String | 'JSSlot' | 固定值 | -| value | 具体的值 | Array\ | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述(A)) | +| value | 具体的值 | NodeSchema \| NodeSchema[] | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述(A)) | 举例描述:如 **Card** 的 **title** 属性 @@ -782,8 +780,8 @@ try { | 参数 | 说明 | 值类型 | 默认值 | 备注 | | ------ | ---------- | --------------------- | -------- | -------------------------------------------------------------- | | type | 值类型描述 | String | 'JSSlot' | 固定值 | -| value | 具体的值 | Array\ | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述 a) | -| params | 函数的参数 | Array\ | 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) | - | | diff --git a/docs/docs/specs/material-spec.md b/docs/docs/specs/material-spec.md index c74d0c96a..3bee847c0 100644 --- a/docs/docs/specs/material-spec.md +++ b/docs/docs/specs/material-spec.md @@ -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(
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 表示触发规则不会关闭。 - ``,任何情况下都不关闭,只能通过受控设置 visible - ``,用户按 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(, 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) diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 97a0237b4..0aaa4c50f 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -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, }, }), diff --git a/docs/package.json b/docs/package.json index d03668ad9..3a07ecd67 100644 --- a/docs/package.json +++ b/docs/package.json @@ -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", diff --git a/docs/scripts/getDocsFromDir.js b/docs/scripts/getDocsFromDir.js index 1d3236fe6..18e67e718 100644 --- a/docs/scripts/getDocsFromDir.js +++ b/docs/scripts/getDocsFromDir.js @@ -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), diff --git a/docs/scripts/sync-oss.js b/docs/scripts/sync-oss.js new file mode 100644 index 000000000..9518a8ea7 --- /dev/null +++ b/docs/scripts/sync-oss.js @@ -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(); \ No newline at end of file diff --git a/lerna.json b/lerna.json index af393cf27..dc8950db4 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.0.18", + "version": "1.1.0", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/modules/code-generator/babel.config.js b/modules/code-generator/babel.config.js new file mode 100644 index 000000000..c5986f2bc --- /dev/null +++ b/modules/code-generator/babel.config.js @@ -0,0 +1 @@ +module.exports = require('../../babel.config'); \ No newline at end of file diff --git a/modules/code-generator/bin/lowcode-code-generator.js b/modules/code-generator/bin/lowcode-code-generator.js index 6259a5a6f..79c36c49a 100755 --- a/modules/code-generator/bin/lowcode-code-generator.js +++ b/modules/code-generator/bin/lowcode-code-generator.js @@ -14,6 +14,7 @@ program .option('-c, --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 ', 'specify the solution options', '{}') .arguments('[input-schema] ali lowcode schema JSON file') .action(function doGenerate(inputSchema, command) { var options = command.opts(); diff --git a/modules/code-generator/package.json b/modules/code-generator/package.json index 3e7898e39..97863584c 100644 --- a/modules/code-generator/package.json +++ b/modules/code-generator/package.json @@ -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", diff --git a/modules/code-generator/src/analyzer/componentAnalyzer.ts b/modules/code-generator/src/analyzer/componentAnalyzer.ts index 952295a15..69e8ad482 100644 --- a/modules/code-generator/src/analyzer/componentAnalyzer.ts +++ b/modules/code-generator/src/analyzer/componentAnalyzer.ts @@ -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; } diff --git a/modules/code-generator/src/cli/run.ts b/modules/code-generator/src/cli/run.ts index db66b4601..ec6814f76 100644 --- a/modules/code-generator/src/cli/run.ts +++ b/modules/code-generator/src/cli/run.ts @@ -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 { 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 { +async function loadSchemaFile(schemaFile: string): Promise { if (!schemaFile) { throw new Error('invalid schema file name'); } diff --git a/modules/code-generator/src/cli/solutions/example-solution.ts b/modules/code-generator/src/cli/solutions/example-solution.ts index 2efff780c..fe303f360 100644 --- a/modules/code-generator/src/cli/solutions/example-solution.ts +++ b/modules/code-generator/src/cli/solutions/example-solution.ts @@ -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": { diff --git a/modules/code-generator/src/generator/ModuleBuilder.ts b/modules/code-generator/src/generator/ModuleBuilder.ts index f4554ef61..755ca20c6 100644 --- a/modules/code-generator/src/generator/ModuleBuilder.ts +++ b/modules/code-generator/src/generator/ModuleBuilder.ts @@ -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 => { + const generateModuleCode = async (schema: IPublicTypeProjectSchema | string): Promise => { // Init const schemaParser: ISchemaParser = new SchemaParser(); const parseResult: IParseResult = schemaParser.parse(schema); diff --git a/modules/code-generator/src/generator/ProjectBuilder.ts b/modules/code-generator/src/generator/ProjectBuilder.ts index 2a1282d6e..819f37c5c 100644 --- a/modules/code-generator/src/generator/ProjectBuilder.ts +++ b/modules/code-generator/src/generator/ProjectBuilder.ts @@ -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; + /** + * 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 { + async generateProject(originalSchema: IPublicTypeProjectSchema | string): Promise { // 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 { + private createModuleBuilders(extraContextData: Record = {}): + Record { const builders: Record = {}; 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, }); diff --git a/modules/code-generator/src/parser/SchemaParser.ts b/modules/code-generator/src/parser/SchemaParser.ts index 2e526d88b..3108fee47 100644 --- a/modules/code-generator/src/parser/SchemaParser.ts +++ b/modules/code-generator/src/parser/SchemaParser.ts @@ -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 = {}; const internalDeps: Record = {}; @@ -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( 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( 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(); // 数据源的默认类型为 fetch diff --git a/modules/code-generator/src/plugins/component/rax/containerInjectDataSourceEngine.ts b/modules/code-generator/src/plugins/component/rax/containerInjectDataSourceEngine.ts index 446b1d3f8..cb7a9e8c3 100644 --- a/modules/code-generator/src/plugins/component/rax/containerInjectDataSourceEngine.ts +++ b/modules/code-generator/src/plugins/component/rax/containerInjectDataSourceEngine.ts @@ -1,8 +1,8 @@ /* eslint-disable @typescript-eslint/indent */ import { - CompositeValue, - JSExpression, + IPublicTypeCompositeValue, + IPublicTypeJSExpression, InterpretDataSourceConfig, isJSExpression, isJSFunction, @@ -56,7 +56,7 @@ const pluginFactory: BuilderComponentPluginFactory = (config?) => (dataSourceConfig && dataSourceConfig.list) || []; const dataSourceEngineOptions = { runtimeConfig: true }; if (dataSourceItems.length > 0) { - const requestHandlersMap: Record = {}; + const requestHandlersMap: Record = {}; 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', diff --git a/modules/code-generator/src/plugins/component/rax/jsx.ts b/modules/code-generator/src/plugins/component/rax/jsx.ts index e0c6dd01f..98c80a492 100644 --- a/modules/code-generator/src/plugins/component/rax/jsx.ts +++ b/modules/code-generator/src/plugins/component/rax/jsx.ts @@ -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 = (config?) => // 2. 小程序出码的时候,很容易出现 Uncaught TypeError: Cannot read property 'avatar' of undefined 这样的异常(如下图的 50 行) -- 因为若直接出码,Rax 构建到小程序的时候会立即计算所有在视图中用到的变量 // 3. 通过 this.xxx 能拿到的东西太多了,而且自定义的 methods 可能会无意间破坏 Rax 框架或小程序框架在页面 this 上的东东 const customHandlers: HandlerSet = { - 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 = (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[] { diff --git a/modules/code-generator/src/plugins/component/react/containerInjectDataSourceEngine.ts b/modules/code-generator/src/plugins/component/react/containerInjectDataSourceEngine.ts index 20302dea9..bc5fa54ba 100644 --- a/modules/code-generator/src/plugins/component/react/containerInjectDataSourceEngine.ts +++ b/modules/code-generator/src/plugins/component/react/containerInjectDataSourceEngine.ts @@ -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 = (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 = {}; + const requestHandlersMap: Record = {}; dataSourceItems.forEach((ds) => { const dsType = ds.type || 'fetch'; @@ -187,7 +187,7 @@ const pluginFactory: BuilderComponentPluginFactory = (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', diff --git a/modules/code-generator/src/plugins/component/react/containerInjectUtils.ts b/modules/code-generator/src/plugins/component/react/containerInjectUtils.ts index 6c614f143..33fc8c28d 100644 --- a/modules/code-generator/src/plugins/component/react/containerInjectUtils.ts +++ b/modules/code-generator/src/plugins/component/react/containerInjectUtils.ts @@ -11,6 +11,7 @@ import { FileType, ICodeStruct, IContainerInfo, + IProjectTemplate, } from '../../../types'; export interface PluginConfig { @@ -32,6 +33,19 @@ const pluginFactory: BuilderComponentPluginFactory = (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 = (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 = (config?) => type: ChunkType.STRING, fileType: cfg.fileType, name: CLASS_DEFINE_CHUNK_NAME.InsMethod, - content: ` $$ = () => []; `, + content: ' $$ = () => []; ', linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]], }); } diff --git a/modules/code-generator/src/plugins/component/react/jsx.ts b/modules/code-generator/src/plugins/component/react/jsx.ts index 445dce7a5..7cf5bd9de 100644 --- a/modules/code-generator/src/plugins/component/react/jsx.ts +++ b/modules/code-generator/src/plugins/component/react/jsx.ts @@ -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 = (config?) => // 这里会将内部的一些子上下文的访问(this.xxx)转换为 __$$context.xxx 的形式 // 与 Rax 所不同的是,这里不会将最顶层的 this 转换掉 const customHandlers: HandlerSet = { - 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 = (config?) => function __$$eval(expr) { try { return expr(); - } catch (error) { + } catch (error) { ${evalErrorsHandler} } } diff --git a/modules/code-generator/src/plugins/project/framework/rax/plugins/packageJSON.ts b/modules/code-generator/src/plugins/project/framework/rax/plugins/packageJSON.ts index e95a3dc0b..401ba3f97 100644 --- a/modules/code-generator/src/plugins/project/framework/rax/plugins/packageJSON.ts +++ b/modules/code-generator/src/plugins/project/framework/rax/plugins/packageJSON.ts @@ -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 = (cfg) export default pluginFactory; -function getNpmDependencies(project: IProjectInfo): NpmInfo[] { - const npmDeps: NpmInfo[] = []; - const npmNameToPkgMap = new Map(); +function getNpmDependencies(project: IProjectInfo): IPublicTypeNpmInfo[] { + const npmDeps: IPublicTypeNpmInfo[] = []; + const npmNameToPkgMap = new Map(); const allDeps = project.packages; diff --git a/modules/code-generator/src/postprocessor/prettier/index.ts b/modules/code-generator/src/postprocessor/prettier/index.ts index afdcc6225..d4e61e3c0 100644 --- a/modules/code-generator/src/postprocessor/prettier/index.ts +++ b/modules/code-generator/src/postprocessor/prettier/index.ts @@ -9,7 +9,7 @@ const PARSERS = ['css', 'scss', 'less', 'json', 'html', 'vue']; export interface ProcessorConfig { customFileTypeParser: Record; - plugins?: Array; + plugins?: prettier.Plugin[]; } const factory: PostProcessorFactory = (config?: ProcessorConfig) => { @@ -33,6 +33,8 @@ const factory: PostProcessorFactory = (config?: ProcessorConfig return prettier.format(content, { parser, plugins: [parserBabel, parserPostCss, parserHtml, ...(cfg.plugins || [])], + singleQuote: true, + jsxSingleQuote: false, }); }; diff --git a/modules/code-generator/src/solutions/icejs.ts b/modules/code-generator/src/solutions/icejs.ts index 85ce7c1f5..1b3dec4af 100644 --- a/modules/code-generator/src/solutions/icejs.ts +++ b/modules/code-generator/src/solutions/icejs.ts @@ -91,6 +91,7 @@ export default function createIceJsProjectBuilder( packageJSON: [icejs.plugins.packageJSON()], }, postProcessors: [prettier()], + customizeBuilderOptions: options?.customizeBuilderOptions, }); } diff --git a/modules/code-generator/src/solutions/rax-app.ts b/modules/code-generator/src/solutions/rax-app.ts index c2b3adac5..f7e903835 100644 --- a/modules/code-generator/src/solutions/rax-app.ts +++ b/modules/code-generator/src/solutions/rax-app.ts @@ -71,6 +71,7 @@ export default function createRaxProjectBuilder( packageJSON: [raxApp.plugins.packageJSON(options)], }, postProcessors: [prettier()], + customizeBuilderOptions: options?.customizeBuilderOptions, }); } diff --git a/modules/code-generator/src/standalone-loader.ts b/modules/code-generator/src/standalone-loader.ts index 882b1de9d..0c8903ddc 100644 --- a/modules/code-generator/src/standalone-loader.ts +++ b/modules/code-generator/src/standalone-loader.ts @@ -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; diff --git a/modules/code-generator/src/standalone-worker.ts b/modules/code-generator/src/standalone-worker.ts index 71f56e67a..e00a4877b 100644 --- a/modules/code-generator/src/standalone-worker.ts +++ b/modules/code-generator/src/standalone-worker.ts @@ -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' }); diff --git a/modules/code-generator/src/types/analyze.ts b/modules/code-generator/src/types/analyze.ts index 43de30743..3bf444d29 100644 --- a/modules/code-generator/src/types/analyze.ts +++ b/modules/code-generator/src/types/analyze.ts @@ -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; diff --git a/modules/code-generator/src/types/core.ts b/modules/code-generator/src/types/core.ts index 99ca8c97a..39e4c32ba 100644 --- a/modules/code-generator/src/types/core.ts +++ b/modules/code-generator/src/types/core.ts @@ -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; - generateModuleCode: (schema: ProjectSchema | string) => Promise; + generateModuleCode: (schema: IPublicTypeProjectSchema | string) => Promise; linkCodeChunks: (chunks: Record, 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; + toCode: (schema: IPublicTypeProjectSchema) => Promise; } 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; + generateProject: (schema: IPublicTypeProjectSchema | string) => Promise; } /** 项目级别的前置处理器 */ -export type ProjectPreProcessor = (schema: ProjectSchema) => Promise | ProjectSchema; +export type ProjectPreProcessor = (schema: IPublicTypeProjectSchema) => Promise | 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; /** 模块级别的后置处理器的工厂方法 */ @@ -198,20 +216,20 @@ type CompositeTypeGenerator = | BaseGenerator | Array>; -export type NodeGenerator = (nodeItem: NodeDataType, scope: IScope) => T; +export type NodeGenerator = (nodeItem: IPublicTypeNodeDataType, scope: IScope) => T; // FIXME: 在新的实现中,添加了第一参数 this: CustomHandlerSet 作为上下文。究其本质 // scopeBindings?: IScopeBindings; -// 这个组合只用来用来处理 CompositeValue 类型,不是这个类型的不要放在这里 +// 这个组合只用来用来处理 IPublicTypeCompositeValue 类型,不是这个类型的不要放在这里 export interface HandlerSet { string?: CompositeTypeGenerator; boolean?: CompositeTypeGenerator; number?: CompositeTypeGenerator; - expression?: CompositeTypeGenerator; - function?: CompositeTypeGenerator; - slot?: CompositeTypeGenerator; - array?: CompositeTypeGenerator; - object?: CompositeTypeGenerator; + expression?: CompositeTypeGenerator; + function?: CompositeTypeGenerator; + slot?: CompositeTypeGenerator; + array?: CompositeTypeGenerator; + object?: CompositeTypeGenerator; } export interface CompositeValueGeneratorOptions { diff --git a/modules/code-generator/src/types/intermediate.ts b/modules/code-generator/src/types/intermediate.ts index 43d8f0e84..30d6c4f7f 100644 --- a/modules/code-generator/src/types/intermediate.ts +++ b/modules/code-generator/src/types/intermediate.ts @@ -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; config?: Record; dataSourcesTypes?: string[]; + projectRemark?: ProjectRemark; } export interface IPageMeta { diff --git a/modules/code-generator/src/types/jsx.ts b/modules/code-generator/src/types/jsx.ts index c79f1d207..28f948d63 100644 --- a/modules/code-generator/src/types/jsx.ts +++ b/modules/code-generator/src/types/jsx.ts @@ -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; -export type NodePlugin = BaseGenerator; +export type NodePlugin = BaseGenerator; export interface NodeGeneratorConfig { handlers?: HandlerSet; @@ -33,7 +33,7 @@ export interface NodeGeneratorConfig { /** * 是否要容忍对 JSExpression 求值时的异常 * 默认:true - * 注: 如果容忍异常,则会在求值时包裹 try-catch 块 -- 通过 __$$eval / __$$evalArray + * 注:如果容忍异常,则会在求值时包裹 try-catch 块 -- 通过 __$$eval / __$$evalArray * catch 到异常时默认会抛出一个 CustomEvent 事件里面包含异常信息和求值的表达式 */ tolerateEvalErrors?: boolean; diff --git a/modules/code-generator/src/utils/compositeType.ts b/modules/code-generator/src/utils/compositeType.ts index b66e1279c..2e09e2da0 100644 --- a/modules/code-generator/src/utils/compositeType.ts +++ b/modules/code-generator/src/utils/compositeType.ts @@ -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 { diff --git a/modules/code-generator/src/utils/dataSource.ts b/modules/code-generator/src/utils/dataSource.ts index 610f39934..cd1035162 100644 --- a/modules/code-generator/src/utils/dataSource.ts +++ b/modules/code-generator/src/utils/dataSource.ts @@ -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 { 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', }), {}, ), diff --git a/modules/code-generator/src/utils/index.ts b/modules/code-generator/src/utils/index.ts index ff5194172..cac63d415 100644 --- a/modules/code-generator/src/utils/index.ts +++ b/modules/code-generator/src/utils/index.ts @@ -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, }; diff --git a/modules/code-generator/src/utils/jsExpression.ts b/modules/code-generator/src/utils/jsExpression.ts index d6dc8c027..1162d0820 100644 --- a/modules/code-generator/src/utils/jsExpression.ts +++ b/modules/code-generator/src/utils/jsExpression.ts @@ -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); } diff --git a/modules/code-generator/src/utils/jsSlot.ts b/modules/code-generator/src/utils/jsSlot.ts index 49f7b3170..265f6857f 100644 --- a/modules/code-generator/src/utils/jsSlot.ts +++ b/modules/code-generator/src/utils/jsSlot.ts @@ -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 { 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, scope: IScope, ) { diff --git a/modules/code-generator/src/utils/nodeToJSX.ts b/modules/code-generator/src/utils/nodeToJSX.ts index 0b5919902..73dba862c 100644 --- a/modules/code-generator/src/utils/nodeToJSX.ts +++ b/modules/code-generator/src/utils/nodeToJSX.ts @@ -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( + const res = executeFunctionStack( 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 { - 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 = { diff --git a/modules/code-generator/src/utils/schema.ts b/modules/code-generator/src/utils/schema.ts index b2faecbc6..509977277 100644 --- a/modules/code-generator/src/utils/schema.ts +++ b/modules/code-generator/src/utils/schema.ts @@ -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( - 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( } 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( 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( 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( return _.flatMap(value, (v) => handleCompositeValueInProps(v)); } - // CompositeObject + // IPublicTypeCompositeObject if ( !isJSExpression(value) && !isJSFunction(value) && @@ -138,3 +138,11 @@ export function handleSubNodes( return []; } } + +export function isValidContainerType(schema: IPublicTypeNodeSchema) { + return [ + 'Page', + 'Component', + 'Block', + ].includes(schema.componentName); +} \ No newline at end of file diff --git a/modules/code-generator/tests/bugfix/i18n-with-params.test.ts b/modules/code-generator/tests/bugfix/i18n-with-params.test.ts index be2d5e9e6..b58afda8c 100644 --- a/modules/code-generator/tests/bugfix/i18n-with-params.test.ts +++ b/modules/code-generator/tests/bugfix/i18n-with-params.test.ts @@ -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, () => { ` @@ -31,7 +31,7 @@ describe(testCaseBaseName, () => { function exportProject( importPath: string, outputPath: string, - mergeSchema?: Partial, + mergeSchema?: Partial, ) { const schemaJsonStr = fs.readFileSync(importPath, { encoding: 'utf8' }); const schema = { ...JSON.parse(schemaJsonStr), ...mergeSchema }; diff --git a/modules/code-generator/tests/bugfix/icejs-import-wrong-naming.test.ts b/modules/code-generator/tests/bugfix/icejs-import-wrong-naming.test.ts index 51e22b3a9..efb7fd5be 100644 --- a/modules/code-generator/tests/bugfix/icejs-import-wrong-naming.test.ts +++ b/modules/code-generator/tests/bugfix/icejs-import-wrong-naming.test.ts @@ -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, + mergeSchema?: Partial, ) { const schemaJsonStr = fs.readFileSync(importPath, { encoding: 'utf8' }); const schema = { ...JSON.parse(schemaJsonStr), ...mergeSchema }; diff --git a/modules/code-generator/tests/bugfix/icejs-missing-imports-1.test.ts b/modules/code-generator/tests/bugfix/icejs-missing-imports-1.test.ts index 17c40a4fa..cad73474a 100644 --- a/modules/code-generator/tests/bugfix/icejs-missing-imports-1.test.ts +++ b/modules/code-generator/tests/bugfix/icejs-missing-imports-1.test.ts @@ -22,7 +22,7 @@ test(testCaseBaseName, async () => { Button, Typography, Tag, -} from "@alilc/antd-lowcode-materials/dist/antd-lowcode.esm.js";`); +} from '@alilc/antd-lowcode-materials/dist/antd-lowcode.esm.js';`); }); function exportProject(inputPath: string, outputPath: string) { diff --git a/modules/code-generator/tests/bugfix/icejs-package-json-dependencies.test.ts b/modules/code-generator/tests/bugfix/icejs-package-json-dependencies.test.ts index 6edd6b912..88ca02c6b 100644 --- a/modules/code-generator/tests/bugfix/icejs-package-json-dependencies.test.ts +++ b/modules/code-generator/tests/bugfix/icejs-package-json-dependencies.test.ts @@ -19,15 +19,15 @@ test(testCaseBaseName, async () => { // 里面有的数据源则应该生成对应的 dependencies expect(generatedPackageJson.dependencies).toMatchObject({ - '@alilc/lowcode-datasource-engine': 'latest', - '@alilc/lowcode-datasource-fetch-handler': 'latest', + '@alilc/lowcode-datasource-engine': '^1.0.0', + '@alilc/lowcode-datasource-fetch-handler': '^1.0.0', }); // 里面没有的,则不应该生成对应的 dependencies expect(generatedPackageJson.dependencies).not.toMatchObject({ - '@alilc/lowcode-datasource-url-params-handler': 'latest', - '@alilc/lowcode-datasource-mtop-handler': 'latest', - '@alilc/lowcode-datasource-mopen-handler': 'latest', + '@alilc/lowcode-datasource-url-params-handler': '^1.0.0', + '@alilc/lowcode-datasource-mtop-handler': '^1.0.0', + '@alilc/lowcode-datasource-mopen-handler': '^1.0.0', }); }); diff --git a/modules/code-generator/tests/bugfix/strict-mode-context-1.test.ts b/modules/code-generator/tests/bugfix/strict-mode-context-1.test.ts index 9cfb09325..ebca6a26f 100644 --- a/modules/code-generator/tests/bugfix/strict-mode-context-1.test.ts +++ b/modules/code-generator/tests/bugfix/strict-mode-context-1.test.ts @@ -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'; import { IceJsProjectBuilderOptions } from '../../src/solutions/icejs'; @@ -33,7 +33,7 @@ describe(testCaseBaseName, () => { function exportProject( importPath: string, outputPath: string, - mergeSchema?: Partial, + mergeSchema?: Partial, options?: IceJsProjectBuilderOptions, ) { const schemaJsonStr = fs.readFileSync(importPath, { encoding: 'utf8' }); diff --git a/modules/code-generator/tests/bugfix/tolerate-eval-errors-1-loop.test.ts b/modules/code-generator/tests/bugfix/tolerate-eval-errors-1-loop.test.ts index 11ba9de05..78f2b50b3 100644 --- a/modules/code-generator/tests/bugfix/tolerate-eval-errors-1-loop.test.ts +++ b/modules/code-generator/tests/bugfix/tolerate-eval-errors-1-loop.test.ts @@ -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'; import { IceJsProjectBuilderOptions } from '../../src/solutions/icejs'; @@ -28,7 +28,7 @@ test('loop should be generated link __$$evalArray(xxx).map', async () => { function exportProject( importPath: string, outputPath: string, - mergeSchema?: Partial, + mergeSchema?: Partial, options?: IceJsProjectBuilderOptions, ) { const schemaJsonStr = fs.readFileSync(importPath, { encoding: 'utf8' }); diff --git a/modules/code-generator/tests/bugfix/tolerate-eval-errors-2-nested-loop.test.ts b/modules/code-generator/tests/bugfix/tolerate-eval-errors-2-nested-loop.test.ts index e8b65a544..184200593 100644 --- a/modules/code-generator/tests/bugfix/tolerate-eval-errors-2-nested-loop.test.ts +++ b/modules/code-generator/tests/bugfix/tolerate-eval-errors-2-nested-loop.test.ts @@ -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'; import { IceJsProjectBuilderOptions } from '../../src/solutions/icejs'; @@ -32,7 +32,7 @@ test('loop should be generated link __$$evalArray(xxx).map', async () => { function exportProject( importPath: string, outputPath: string, - mergeSchema?: Partial, + mergeSchema?: Partial, options?: IceJsProjectBuilderOptions, ) { const schemaJsonStr = fs.readFileSync(importPath, { encoding: 'utf8' }); diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo01/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo01/expected/demo-project/package.json index 38cfdd186..fd03ed9bc 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo01/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo01/expected/demo-project/package.json @@ -11,7 +11,7 @@ "lint": "npm run eslint && npm run stylelint" }, "dependencies": { - "@alilc/lowcode-datasource-engine": "latest", + "@alilc/lowcode-datasource-engine": "^1.0.0", "universal-env": "^3.2.0", "intl-messageformat": "^9.3.6", "rax": "^1.1.0", diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo02/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo02/expected/demo-project/package.json index ca5a0f59c..4d9a77988 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo02/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo02/expected/demo-project/package.json @@ -11,9 +11,9 @@ "lint": "npm run eslint && npm run stylelint" }, "dependencies": { - "@alilc/lowcode-datasource-engine": "latest", - "@alilc/lowcode-datasource-url-params-handler": "latest", - "@alilc/lowcode-datasource-fetch-handler": "latest", + "@alilc/lowcode-datasource-engine": "^1.0.0", + "@alilc/lowcode-datasource-url-params-handler": "^1.0.0", + "@alilc/lowcode-datasource-fetch-handler": "^1.0.0", "universal-env": "^3.2.0", "intl-messageformat": "^9.3.6", "rax": "^1.1.0", diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo02/expected/demo-project/src/pages/Home/index.jsx b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo02/expected/demo-project/src/pages/Home/index.jsx index 06e39454d..7bfda59ca 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo02/expected/demo-project/src/pages/Home/index.jsx +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo02/expected/demo-project/src/pages/Home/index.jsx @@ -253,6 +253,7 @@ class Home$$Page extends Component { if (!response.success) { throw new Error(response.message); } + return response.data; }, isInit: true, @@ -279,6 +280,7 @@ class Home$$Page extends Component { if (!response.success) { throw new Error(response.message); } + return response.data.result; }, isInit: true, diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo03/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo03/expected/demo-project/package.json index 48690ff4d..58b97921b 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo03/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo03/expected/demo-project/package.json @@ -11,7 +11,7 @@ "lint": "npm run eslint && npm run stylelint" }, "dependencies": { - "@alilc/lowcode-datasource-engine": "latest", + "@alilc/lowcode-datasource-engine": "^1.0.0", "universal-env": "^3.2.0", "intl-messageformat": "^9.3.6", "rax": "^1.1.0", diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo04/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo04/expected/demo-project/package.json index 16fa70bbc..56dda7653 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo04/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo04/expected/demo-project/package.json @@ -11,7 +11,7 @@ "lint": "npm run eslint && npm run stylelint" }, "dependencies": { - "@alilc/lowcode-datasource-engine": "latest", + "@alilc/lowcode-datasource-engine": "^1.0.0", "universal-env": "^3.2.0", "intl-messageformat": "^9.3.6", "rax": "^1.1.0", diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo05/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo05/expected/demo-project/package.json index 38cfdd186..fd03ed9bc 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo05/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo05/expected/demo-project/package.json @@ -11,7 +11,7 @@ "lint": "npm run eslint && npm run stylelint" }, "dependencies": { - "@alilc/lowcode-datasource-engine": "latest", + "@alilc/lowcode-datasource-engine": "^1.0.0", "universal-env": "^3.2.0", "intl-messageformat": "^9.3.6", "rax": "^1.1.0", diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo06-jsslot/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo06-jsslot/expected/demo-project/package.json index bf31a967e..dc00ba429 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo06-jsslot/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo06-jsslot/expected/demo-project/package.json @@ -11,7 +11,7 @@ "lint": "npm run eslint && npm run stylelint" }, "dependencies": { - "@alilc/lowcode-datasource-engine": "latest", + "@alilc/lowcode-datasource-engine": "^1.0.0", "universal-env": "^3.2.0", "intl-messageformat": "^9.3.6", "rax": "^1.1.0", diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo07-newline-in-props/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo07-newline-in-props/expected/demo-project/package.json index 38cfdd186..fd03ed9bc 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo07-newline-in-props/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo07-newline-in-props/expected/demo-project/package.json @@ -11,7 +11,7 @@ "lint": "npm run eslint && npm run stylelint" }, "dependencies": { - "@alilc/lowcode-datasource-engine": "latest", + "@alilc/lowcode-datasource-engine": "^1.0.0", "universal-env": "^3.2.0", "intl-messageformat": "^9.3.6", "rax": "^1.1.0", diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo08-jsslot-with-multiple-children/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo08-jsslot-with-multiple-children/expected/demo-project/package.json index bf31a967e..dc00ba429 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo08-jsslot-with-multiple-children/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo08-jsslot-with-multiple-children/expected/demo-project/package.json @@ -11,7 +11,7 @@ "lint": "npm run eslint && npm run stylelint" }, "dependencies": { - "@alilc/lowcode-datasource-engine": "latest", + "@alilc/lowcode-datasource-engine": "^1.0.0", "universal-env": "^3.2.0", "intl-messageformat": "^9.3.6", "rax": "^1.1.0", diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo09-jsslot-with-conditional-children/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo09-jsslot-with-conditional-children/expected/demo-project/package.json index bf31a967e..dc00ba429 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo09-jsslot-with-conditional-children/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo09-jsslot-with-conditional-children/expected/demo-project/package.json @@ -11,7 +11,7 @@ "lint": "npm run eslint && npm run stylelint" }, "dependencies": { - "@alilc/lowcode-datasource-engine": "latest", + "@alilc/lowcode-datasource-engine": "^1.0.0", "universal-env": "^3.2.0", "intl-messageformat": "^9.3.6", "rax": "^1.1.0", diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo10-jsslot-with-loop-children/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo10-jsslot-with-loop-children/expected/demo-project/package.json index bf31a967e..dc00ba429 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo10-jsslot-with-loop-children/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo10-jsslot-with-loop-children/expected/demo-project/package.json @@ -11,7 +11,7 @@ "lint": "npm run eslint && npm run stylelint" }, "dependencies": { - "@alilc/lowcode-datasource-engine": "latest", + "@alilc/lowcode-datasource-engine": "^1.0.0", "universal-env": "^3.2.0", "intl-messageformat": "^9.3.6", "rax": "^1.1.0", diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo11-utils-name-alias/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo11-utils-name-alias/expected/demo-project/package.json index 60f0cb38a..067cc161d 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo11-utils-name-alias/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo11-utils-name-alias/expected/demo-project/package.json @@ -11,8 +11,8 @@ "lint": "npm run eslint && npm run stylelint" }, "dependencies": { - "@alilc/lowcode-datasource-engine": "latest", - "@alilc/lowcode-datasource-url-params-handler": "latest", + "@alilc/lowcode-datasource-engine": "^1.0.0", + "@alilc/lowcode-datasource-url-params-handler": "^1.0.0", "universal-env": "^3.2.0", "intl-messageformat": "^9.3.6", "rax": "^1.1.0", diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo12-refs/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo12-refs/expected/demo-project/package.json index 38cfdd186..fd03ed9bc 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo12-refs/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo12-refs/expected/demo-project/package.json @@ -11,7 +11,7 @@ "lint": "npm run eslint && npm run stylelint" }, "dependencies": { - "@alilc/lowcode-datasource-engine": "latest", + "@alilc/lowcode-datasource-engine": "^1.0.0", "universal-env": "^3.2.0", "intl-messageformat": "^9.3.6", "rax": "^1.1.0", diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo13-datasource-prop/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo13-datasource-prop/expected/demo-project/package.json index 3e59d2984..afadad878 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo13-datasource-prop/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo13-datasource-prop/expected/demo-project/package.json @@ -11,8 +11,8 @@ "lint": "npm run eslint && npm run stylelint" }, "dependencies": { - "@alilc/lowcode-datasource-engine": "latest", - "@alilc/lowcode-datasource-http-handler": "latest", + "@alilc/lowcode-datasource-engine": "^1.0.0", + "@alilc/lowcode-datasource-http-handler": "^1.0.0", "universal-env": "^3.2.0", "intl-messageformat": "^9.3.6", "rax": "^1.1.0", diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/package.json b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/package.json index 767ec3898..36eaf12f2 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/package.json +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/package.json @@ -11,9 +11,9 @@ "intl-messageformat": "^9.3.6", "@ice/store": "^1.4.3", "@loadable/component": "^5.15.2", - "@alilc/lowcode-datasource-engine": "latest", - "@alilc/lowcode-datasource-url-params-handler": "latest", - "@alilc/lowcode-datasource-fetch-handler": "latest", + "@alilc/lowcode-datasource-engine": "^1.0.0", + "@alilc/lowcode-datasource-url-params-handler": "^1.0.0", + "@alilc/lowcode-datasource-fetch-handler": "^1.0.0", "@alifd/next": "1.19.18" }, "devDependencies": { diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/app.js b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/app.js index fb01b106b..266d8ef71 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/app.js +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/app.js @@ -1,11 +1,11 @@ -import { createApp } from "ice"; +import { createApp } from 'ice'; const appConfig = { app: { - rootId: "app", + rootId: 'app', }, router: { - type: "hash", + type: 'hash', }, }; createApp(appConfig); diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/constants.js b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/constants.js index c4a5859ee..91198f904 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/constants.js +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/constants.js @@ -1,3 +1,3 @@ -const __$$constants = { ENV: "prod", DOMAIN: "xxx.xxx.com" }; +const __$$constants = { ENV: 'prod', DOMAIN: 'xxx.xxx.com' }; export default __$$constants; diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/global.scss b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/global.scss index 2d97c56b0..ed7204b4a 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/global.scss +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/global.scss @@ -1,5 +1,5 @@ // 引入默认全局样式 -@import "@alifd/next/reset.scss"; +@import '@alifd/next/reset.scss'; body { -webkit-font-smoothing: antialiased; diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/i18n.js b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/i18n.js index 1ae7c84b5..adbbe673d 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/i18n.js +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/i18n.js @@ -1,9 +1,9 @@ const i18nConfig = {}; let locale = - typeof navigator === "object" && typeof navigator.language === "string" + typeof navigator === 'object' && typeof navigator.language === 'string' ? navigator.language - : "zh-CN"; + : 'zh-CN'; const getLocale = () => locale; @@ -13,22 +13,22 @@ const setLocale = (target) => { const isEmptyVariables = (variables) => (Array.isArray(variables) && variables.length === 0) || - (typeof variables === "object" && + (typeof variables === 'object' && (!variables || Object.keys(variables).length === 0)); // 按低代码规范里面的要求进行变量替换 const format = (msg, variables) => - typeof msg === "string" - ? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? "") + typeof msg === 'string' + ? msg.replace(/\$\{(\w+)\}/g, (match, key) => variables?.[key] ?? '') : msg; const i18nFormat = ({ id, defaultMessage, fallback }, variables) => { const msg = i18nConfig[locale]?.[id] ?? - i18nConfig[locale.replace("-", "_")]?.[id] ?? + i18nConfig[locale.replace('-', '_')]?.[id] ?? defaultMessage; if (msg == null) { - console.warn("[i18n]: unknown message id: %o (locale=%o)", id, locale); + console.warn('[i18n]: unknown message id: %o (locale=%o)', id, locale); return fallback === undefined ? `${id}` : fallback; } @@ -49,7 +49,7 @@ const _inject2 = (target) => { }; target._i18nText = (t) => { // 优先取直接传过来的语料 - const localMsg = t[locale] ?? t[String(locale).replace("-", "_")]; + const localMsg = t[locale] ?? t[String(locale).replace('-', '_')]; if (localMsg != null) { return format(localMsg, t.params); } @@ -61,7 +61,7 @@ const _inject2 = (target) => { } // 兜底用 use 指定的或默认语言的 - return format(t[t.use || "zh-CN"] ?? t.en_US, t.params); + return format(t[t.use || 'zh-CN'] ?? t.en_US, t.params); }; // 注入到上下文中去 diff --git a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/pages/Test/index.jsx b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/pages/Test/index.jsx index b90fe6254..c8db61db7 100644 --- a/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/pages/Test/index.jsx +++ b/modules/code-generator/tests/fixtures/test-cases/react-app/demo1/expected/demo-project/src/pages/Test/index.jsx @@ -1,22 +1,22 @@ // 注意: 出码引擎注入的临时变量默认都以 "__$$" 开头,禁止在搭建的代码中直接访问。 // 例外:react 框架的导出名和各种组件名除外。 -import React from "react"; +import React from 'react'; -import { Form, Input, NumberPicker, Select, Button } from "@alifd/next"; +import { Form, Input, NumberPicker, Select, Button } from '@alifd/next'; -import { createUrlParamsHandler as __$$createUrlParamsRequestHandler } from "@alilc/lowcode-datasource-url-params-handler"; +import { createUrlParamsHandler as __$$createUrlParamsRequestHandler } from '@alilc/lowcode-datasource-url-params-handler'; -import { createFetchHandler as __$$createFetchRequestHandler } from "@alilc/lowcode-datasource-fetch-handler"; +import { createFetchHandler as __$$createFetchRequestHandler } from '@alilc/lowcode-datasource-fetch-handler'; -import { create as __$$createDataSourceEngine } from "@alilc/lowcode-datasource-engine/runtime"; +import { create as __$$createDataSourceEngine } from '@alilc/lowcode-datasource-engine/runtime'; -import utils, { RefsManager } from "../../utils"; +import utils, { RefsManager } from '../../utils'; -import * as __$$i18n from "../../i18n"; +import * as __$$i18n from '../../i18n'; -import __$$constants from "../../constants"; +import __$$constants from '../../constants'; -import "./index.css"; +import './index.css'; class Test$$Page extends React.Component { _context = this; @@ -51,7 +51,7 @@ class Test$$Page extends React.Component { __$$i18n._inject2(this); - this.state = { text: "outter" }; + this.state = { text: 'outter' }; } $ = (refName) => { @@ -67,8 +67,8 @@ class Test$$Page extends React.Component { return { list: [ { - id: "urlParams", - type: "urlParams", + id: 'urlParams', + type: 'urlParams', isInit: function () { return undefined; }, @@ -77,12 +77,12 @@ class Test$$Page extends React.Component { }, }, { - id: "user", - type: "fetch", + id: 'user', + type: 'fetch', options: function () { return { - method: "GET", - uri: "https://shs.xxx.com/mock/1458/demo/user", + method: 'GET', + uri: 'https://shs.xxx.com/mock/1458/demo/user', isSync: true, }; }, @@ -90,6 +90,7 @@ class Test$$Page extends React.Component { if (!response.data.success) { throw new Error(response.data.message); } + return response.data.data; }, isInit: function () { @@ -97,12 +98,12 @@ class Test$$Page extends React.Component { }, }, { - id: "orders", - type: "fetch", + id: 'orders', + type: 'fetch', options: function () { return { - method: "GET", - uri: "https://shs.xxx.com/mock/1458/demo/orders", + method: 'GET', + uri: 'https://shs.xxx.com/mock/1458/demo/orders', isSync: true, }; }, @@ -110,6 +111,7 @@ class Test$$Page extends React.Component { if (!response.data.success) { throw new Error(response.data.message); } + return response.data.data.result; }, isInit: function () { @@ -118,7 +120,7 @@ class Test$$Page extends React.Component { }, ], dataHandler: function (dataMap) { - console.info("All datasources loaded:", dataMap); + console.info('All datasources loaded:', dataMap); }, }; } @@ -126,18 +128,18 @@ class Test$$Page extends React.Component { componentDidMount() { this._dataSourceEngine.reloadDataSource(); - console.log("componentDidMount"); + console.log('componentDidMount'); } render() { const __$$context = this._context || this; const { state } = __$$context; return ( -
+
this.state.colNum)} style={{}} - ref={this._refsManager.linkRef("testForm")} + ref={this._refsManager.linkRef('testForm')} > @@ -148,18 +150,18 @@ class Test$$Page extends React.Component { -
+