From 11319e1ac95107a45b903ac7273684a0a1276d9c Mon Sep 17 00:00:00 2001 From: liujuping Date: Wed, 11 May 2022 16:08:14 +0800 Subject: [PATCH 001/823] test: add renderer-core hoc/leaf single test --- packages/renderer-core/jest.config.js | 2 + packages/renderer-core/src/hoc/leaf.tsx | 30 +- .../hoc/__snapshots__/leaf.test.tsx.snap | 207 ++++--- .../renderer-core/tests/hoc/leaf.test.tsx | 534 ++++++++++++++++-- .../__snapshots__/renderer.test.tsx.snap | 45 +- packages/renderer-core/tests/setup.ts | 10 + .../renderer-core/tests/utils/components.tsx | 15 +- packages/renderer-core/tests/utils/node.ts | 58 +- 8 files changed, 728 insertions(+), 173 deletions(-) diff --git a/packages/renderer-core/jest.config.js b/packages/renderer-core/jest.config.js index 96b36f9d27..4e27e6c90e 100644 --- a/packages/renderer-core/jest.config.js +++ b/packages/renderer-core/jest.config.js @@ -23,6 +23,8 @@ const jestConfig = { collectCoverageFrom: [ 'src/**/*.ts', 'src/**/*.tsx', + '!src/utils/logger.ts', + '!src/types/index.ts', ], }; diff --git a/packages/renderer-core/src/hoc/leaf.tsx b/packages/renderer-core/src/hoc/leaf.tsx index a4c529eab4..cb09ec2e83 100644 --- a/packages/renderer-core/src/hoc/leaf.tsx +++ b/packages/renderer-core/src/hoc/leaf.tsx @@ -216,24 +216,6 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { this.recordTime(); } - get childrenMap(): any { - const map = new Map(); - - if (!this.hasChildren) { - return map; - } - - this.children.forEach((d: any) => { - if (Array.isArray(d)) { - map.set(d[0].props.componentId, d); - return; - } - map.set(d.props.componentId, d); - }); - - return map; - } - get defaultState() { const { hidden = false, @@ -253,18 +235,18 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { super(props, context); // 监听以下事件,当变化时更新自己 __debug(`${schema.componentName}[${this.props.componentId}] leaf render in SimulatorRendererView`); - clearRerenderEvent(this.props.componentId); + clearRerenderEvent(componentCacheId); const _leaf = this.leaf; this.initOnPropsChangeEvent(_leaf); this.initOnChildrenChangeEvent(_leaf); this.initOnVisibleChangeEvent(_leaf); this.curEventLeaf = _leaf; - cache.ref.set(props.componentId, { + cache.ref.set(componentCacheId, { makeUnitRender: this.makeUnitRender, }); - let cacheState = cache.state.get(props.componentId); + let cacheState = cache.state.get(componentCacheId); if (!cacheState || cacheState.__tag !== props.__tag) { cacheState = this.defaultState; } @@ -275,7 +257,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { private curEventLeaf: Node | undefined; setState(state: any) { - cache.state.set(this.props.componentId, { + cache.state.set(componentCacheId, { ...this.state, ...state, __tag: this.props.__tag, @@ -489,7 +471,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { // TODO: 缓存同级其他元素的 children。 // 缓存二级 children Next 查询筛选组件有问题 // 缓存一级 children Next Tab 组件有问题 - const nextChild = getChildren(leaf?.export?.(TransformStage.Render) as types.ISchema, scope, Comp); // this.childrenMap + const nextChild = getChildren(leaf?.export?.(TransformStage.Render) as types.ISchema, scope, Comp); __debug(`${schema.componentName}[${this.props.componentId}] component trigger onChildrenChange event`, nextChild); this.setState({ nodeChildren: nextChild, @@ -531,7 +513,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { } get leaf(): Node | undefined { - return this.props._leaf || getNode(this.props.componentId); + return this.props._leaf || getNode(componentCacheId); } render() { diff --git a/packages/renderer-core/tests/hoc/__snapshots__/leaf.test.tsx.snap b/packages/renderer-core/tests/hoc/__snapshots__/leaf.test.tsx.snap index dbdfd1c5bc..253a099c78 100644 --- a/packages/renderer-core/tests/hoc/__snapshots__/leaf.test.tsx.snap +++ b/packages/renderer-core/tests/hoc/__snapshots__/leaf.test.tsx.snap @@ -1,97 +1,146 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`leafWrapper base 1`] = ` -
-
+exports[`children this.props.children is array 1`] = ` +
+
+ content +
+
+ content +
+
+`; + +exports[`lifecycle leaf change and make componentWillReceiveProps 1`] = ` +
+
+ content new leaf +
+
+`; + +exports[`lifecycle props change and make componentWillReceiveProps 1`] = ` +
+
+ content +
+
+`; + +exports[`lifecycle props change and make componentWillReceiveProps 2`] = ` +
+
+ content 123 +
+
+`; + +exports[`lifecycle props change and make componentWillReceiveProps 3`] = ` +
+
+ content 123 +
+
+`; + +exports[`mini unit render leaf has a loop, render from parent 1`] = ` +
+ this is a new children +
+`; + +exports[`mini unit render make text props change 1`] = ` +
+
content
`; -exports[`leafWrapper change ___condition___ props 1`] = ` +exports[`mini unit render make text props change 2`] = `
`; -exports[`leafWrapper change ___condition___ props, but not hidden component 1`] = ` -
-
- new content +exports[`mini unit render parent is a mock leaf 1`] = ` +
+
+ new content to mock
`; -exports[`leafWrapper change props 1`] = ` -
-
- new content +exports[`mini unit render props has new children 1`] = ` +
+ children 01 + children 02 +
+`; + +exports[`onChildrenChange children is array string 1`] = ` +
+ onChildrenChange content 01 + onChildrenChange content 02 +
+`; + +exports[`onPropChange change textNode [key:___condition___] props, but not hidden component 1`] = ` +
+
+ content +
+
+`; + +exports[`onPropChange change textNode [key:___condition___] props, hide textNode component 1`] = `
`; + +exports[`onPropChange change textNode [key:content], content in this.props but not in leaf.export result 1`] = ` +
+
+ content +
+
+`; + +exports[`onPropChange change textNode [key:content], content in this.props but not in leaf.export result 2`] = ` +
+
+
+`; + +exports[`onVisibleChange visible is false 1`] = `
`; + +exports[`onVisibleChange visible is true 1`] = ` +
+
+ content
`; diff --git a/packages/renderer-core/tests/hoc/leaf.test.tsx b/packages/renderer-core/tests/hoc/leaf.test.tsx index 3a6e34c91d..106e6741a9 100644 --- a/packages/renderer-core/tests/hoc/leaf.test.tsx +++ b/packages/renderer-core/tests/hoc/leaf.test.tsx @@ -6,12 +6,23 @@ import { leafWrapper } from '../../src/hoc/leaf'; import components from '../utils/components'; import Node from '../utils/node'; +let rerenderCount = 0; + +const nodeMap = new Map(); + +const makeSnapshot = (component) => { + let tree = component.toJSON(); + expect(tree).toMatchSnapshot(); +} + const baseRenderer: any = { __debug () {}, __getComponentProps (schema: any) { return schema.props; }, - __getSchemaChildrenVirtualDom () {}, + __getSchemaChildrenVirtualDom (schema: any) { + return schema.children; + }, context: { engine: { createElement, @@ -19,110 +30,525 @@ const baseRenderer: any = { }, props: { __host: {}, - getNode: () => {}, - __container: () => {}, + getNode: (id) => nodeMap.get(id), + __container: { + rerender: () => { + rerenderCount = 1 + rerenderCount; + } + }, + documentId: '01' } } -describe('leafWrapper', () => { - const Div = leafWrapper(components.Div as any, { - schema: { - id: 'div', +let Div, DivNode, Text, TextNode, component, textSchema, divSchema; +let id = 0; + +beforeEach(() => { + textSchema = { + id: 'text' + id, + props: { + content: 'content' }, + }; + + divSchema = { + id: 'div' + id, + }; + + id++; + + Div = leafWrapper(components.Div as any, { + schema: divSchema, baseRenderer, componentInfo: {}, scope: {}, }); - const DivNode = new Node({}); - const TextNode = new Node({}); + DivNode = new Node(divSchema); + TextNode = new Node(textSchema); - const Text = leafWrapper(components.Text as any, { - schema: { - id: 'div', - props: { - content: 'content' - } - }, + nodeMap.set(divSchema.id, DivNode); + nodeMap.set(textSchema.id, TextNode); + + Text = leafWrapper(components.Text as any, { + schema: textSchema, baseRenderer, componentInfo: {}, scope: {}, }); - const component = renderer.create( + component = renderer.create( // @ts-ignore
); +}); - it('base', () => { - let tree = component.toJSON(); - expect(tree).toMatchSnapshot(); - }); +afterEach(() => { + component.unmount(component); +}); - it('change props', () => { +describe('onPropChange', () => { + it('change textNode [key:content] props', () => { TextNode.emitPropChange({ key: 'content', newValue: 'new content', } as any); - let tree = component.toJSON(); - expect(tree).toMatchSnapshot(); + const root = component.root; + expect(root.findByType(components.Text).props.content).toEqual('new content') }); - it('change ___condition___ props', () => { + it('change textNode [key:___condition___] props, hide textNode component', () => { + // mock leaf?.export result TextNode.schema.condition = false; TextNode.emitPropChange({ key: '___condition___', newValue: false, } as any); - let tree = component.toJSON(); - expect(tree).toMatchSnapshot(); + makeSnapshot(component); }); - it('change ___condition___ props, but not hidden component', () => { + it('change textNode [key:___condition___] props, but not hidden component', () => { TextNode.schema.condition = true; TextNode.emitPropChange({ key: '___condition___', newValue: false, } as any); - let tree = component.toJSON(); - expect(tree).toMatchSnapshot(); - }) + makeSnapshot(component); + }); + + it('change textNode [key:content], content in this.props but not in leaf.export result', () => { + makeSnapshot(component); + + delete TextNode.schema.props.content; + TextNode.emitPropChange({ + key: 'content', + newValue: null, + } as any, true); + + makeSnapshot(component); + + const root = component.root; + + const TextInst = root.findByType(components.Text); + + expect(TextInst.props.content).toBeNull(); + }); + + it('change textNode [key:___loop___], make rerender', () => { + expect(leafWrapper(components.Text as any, { + schema: textSchema, + baseRenderer, + componentInfo: {}, + scope: {}, + })).toEqual(Text); + + const nextRerenderCount = rerenderCount + 1; + + TextNode.emitPropChange({ + key: '___loop___', + newValue: 'new content', + } as any); + + expect(rerenderCount).toBe(nextRerenderCount); + expect(leafWrapper(components.Text as any, { + schema: textSchema, + baseRenderer, + componentInfo: {}, + scope: {}, + })).not.toEqual(Text); + }); }); -describe('loop', () => { - const Div = leafWrapper(components.Div as any, { - schema: { - id: 'div', - }, - baseRenderer, - componentInfo: {}, - scope: {}, +describe('lifecycle', () => { + it('props change and make componentWillReceiveProps', () => { + makeSnapshot(component); + + // 没有 __tag 标识 + component.update(( +
+ +
+ )); + + makeSnapshot(component); + + // 有 __tag 标识 + component.update(( +
+ +
+ )); + + makeSnapshot(component); + }); + + it('leaf change and make componentWillReceiveProps', () => { + const newTextNodeLeaf = new Node(textSchema); + component.update(( +
+ +
+ )); + + newTextNodeLeaf.emitPropChange({ + key: 'content', + newValue: 'content new leaf', + }); + + makeSnapshot(component); + }); +}); + +describe('mini unit render', () => { + let miniRenderSchema, MiniRenderDiv, MiniRenderDivNode; + beforeEach(() => { + miniRenderSchema = { + id: 'miniDiv' + id, + }; + + MiniRenderDiv = leafWrapper(components.MiniRenderDiv as any, { + schema: miniRenderSchema, + baseRenderer, + componentInfo: {}, + scope: {}, + }); + + MiniRenderDivNode = new Node(miniRenderSchema, { + componentMeta: { + isMinimalRenderUnit: true, + }, + }); + + TextNode = new Node(textSchema, { + parent: MiniRenderDivNode, + }); + + component = renderer.create( + // @ts-ignore + + + + ); + }) + + it('make text props change', () => { + if (!MiniRenderDivNode.schema.props) { + MiniRenderDivNode.schema.props = {}; + } + MiniRenderDivNode.schema.props['newPropKey'] = 'newPropValue'; + + makeSnapshot(component); + + const inst = component.root; + + const TextInst = inst.findByType(Text).children[0]; + + TextNode.emitPropChange({ + key: 'content', + newValue: 'new content', + } as any); + + expect((TextInst as any)?._fiber.stateNode.renderUnitInfo).toEqual({ + singleRender: false, + minimalUnitId: 'miniDiv' + id, + minimalUnitName: undefined, + }); + + makeSnapshot(component); + }); + + it('dont render mini render component', () => { + const TextNode = new Node(textSchema, { + parent: new Node({ + id: 'random', + }, { + componentMeta: { + isMinimalRenderUnit: true, + }, + }), + }); + + renderer.create( + // @ts-ignore +
+ +
+ ); + + const nextCount = rerenderCount + 1; + + TextNode.emitPropChange({ + key: 'content', + newValue: 'new content', + } as any); + + expect(rerenderCount).toBe(nextCount); + }); + + it('leaf is a mock function', () => { + const TextNode = new Node(textSchema, { + parent: { + isEmpty: () => false, + } + }); + + renderer.create( + // @ts-ignore +
+ +
+ ); + + TextNode.emitPropChange({ + key: 'content', + newValue: 'new content', + } as any); }); - const DivNode = new Node({}); - const TextNode = new Node({}); + it('change component leaf isRoot is true', () => { + const TextNode = new Node(textSchema, { + isRoot: true, + }); - const Text = leafWrapper(components.Text as any, { - schema: { - id: 'div', + const component = renderer.create( + + ); + + const inst = component.root; + + TextNode.emitPropChange({ + key: 'content', + newValue: 'new content', + } as any); + + expect((inst.children[0] as any)?._fiber.stateNode.renderUnitInfo).toEqual({ + singleRender: true, + }); + }); + + it('change component leaf parent isRoot is true', () => { + const TextNode = new Node(textSchema, { + parent: new Node({ + id: 'first-parent', + }, { + componentMeta: { + isMinimalRenderUnit: true, + }, + parent: new Node({ + id: 'rootId', + }, { + isRoot: true, + }), + }) + }); + + const component = renderer.create( + + ); + + const inst = component.root; + + TextNode.emitPropChange({ + key: 'content', + newValue: 'new content', + } as any); + + expect((inst.children[0] as any)?._fiber.stateNode.renderUnitInfo).toEqual({ + singleRender: false, + minimalUnitId: 'first-parent', + minimalUnitName: undefined, + }); + }); + + it('parent is a mock leaf', () => { + const MiniRenderDivNode = {}; + + const component = renderer.create( + // @ts-ignore + + + + ); + + TextNode.emitPropChange({ + key: 'content', + newValue: 'new content to mock', + } as any); + + makeSnapshot(component); + }); + + it('props has new children', () => { + MiniRenderDivNode.schema.props.children = [ + 'children 01', + 'children 02', + ]; + + TextNode.emitPropChange({ + key: 'content', + newValue: 'props' + }); + + makeSnapshot(component); + }); + + it('leaf has a loop, render from parent', () => { + MiniRenderDivNode = new Node(miniRenderSchema, {}); + + TextNode = new Node(textSchema, { + parent: MiniRenderDivNode, + hasLoop: true, + }); + + component = renderer.create( + // @ts-ignore + + + + ); + + MiniRenderDivNode.schema.children = ['this is a new children']; + + TextNode.emitPropChange({ + key: 'content', + newValue: '1', + }); + + makeSnapshot(component); + }); +}); + +describe('component cache', () => { + it('get different component with same is and different doc id', () => { + const baseRenderer02 = { + ...baseRenderer, props: { - content: 'content' + ...baseRenderer.props, + documentId: '02', } - }, - baseRenderer, - componentInfo: {}, - scope: {}, + } + const Div3 = leafWrapper(components.Div as any, { + schema: divSchema, + baseRenderer: baseRenderer02, + componentInfo: {}, + scope: {}, + }); + + expect(Div).not.toEqual(Div3); }); - const component = renderer.create( - // @ts-ignore -
+ it('get component again and get ths cache component', () => { + const Div2 = leafWrapper(components.Div as any, { + schema: divSchema, + baseRenderer, + componentInfo: {}, + scope: {}, + }); + + expect(Div).toEqual(Div2); + }); +}); + +describe('onVisibleChange', () => { + it('visible is false', () => { + TextNode.emitVisibleChange(false); + makeSnapshot(component); + }); + + it('visible is true', () => { + TextNode.emitVisibleChange(true); + makeSnapshot(component); + }); +}); + +describe('children', () => { + it('this.props.children is array', () => { + const component = renderer.create( + // @ts-ignore +
+ + +
+ ); + + makeSnapshot(component); + }); +}); + +describe('onChildrenChange', () => { + it('children is array string', () => { + DivNode.schema.children = [ + 'onChildrenChange content 01', + 'onChildrenChange content 02' + ] + DivNode.emitChildrenChange(); + makeSnapshot(component); + }); +}); + +describe('not render leaf', () => { + let miniRenderSchema, MiniRenderDiv, MiniRenderDivNode; + beforeEach(() => { + miniRenderSchema = { + id: 'miniDiv' + id, + }; + + MiniRenderDivNode = new Node(miniRenderSchema, { + componentMeta: { + isMinimalRenderUnit: true, + }, + }); + + nodeMap.set(miniRenderSchema.id, MiniRenderDivNode); + + MiniRenderDiv = leafWrapper(components.MiniRenderDiv as any, { + schema: miniRenderSchema, + baseRenderer, + componentInfo: {}, + scope: {}, + }); + + TextNode = new Node(textSchema, { + parent: MiniRenderDivNode, + }); + + component = renderer.create( -
- ); + ); + }); + + it('onPropsChange', () => { + const nextCount = rerenderCount + 1; + + MiniRenderDivNode.emitPropChange({ + key: 'any', + newValue: 'any', + }); + + expect(rerenderCount).toBe(nextCount); + }); + + it('onChildrenChange', () => { + const nextCount = rerenderCount + 1; + + MiniRenderDivNode.emitChildrenChange({ + key: 'any', + newValue: 'any', + }); + + expect(rerenderCount).toBe(nextCount); + }); + + it('onVisibleChange', () => { + const nextCount = rerenderCount + 1; + + MiniRenderDivNode.emitVisibleChange(true); + + expect(rerenderCount).toBe(nextCount); + }); }); diff --git a/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap b/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap index 2b96228ad8..5ef56f7755 100644 --- a/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap +++ b/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap @@ -1026,7 +1026,20 @@ exports[`JSExpression JSSlot has loop 1`] = ` forwardRef={[Function]} useFieldIdAsDomId={false} > -
+
这是一个低代码业务组件~
@@ -1044,7 +1057,20 @@ exports[`JSExpression JSSlot has loop 1`] = ` forwardRef={[Function]} useFieldIdAsDomId={false} > -
+
这是一个低代码业务组件~
@@ -1062,7 +1088,20 @@ exports[`JSExpression JSSlot has loop 1`] = ` forwardRef={[Function]} useFieldIdAsDomId={false} > -
+
这是一个低代码业务组件~
diff --git a/packages/renderer-core/tests/setup.ts b/packages/renderer-core/tests/setup.ts index 45fe6e19bd..fd6fd9e5df 100644 --- a/packages/renderer-core/tests/setup.ts +++ b/packages/renderer-core/tests/setup.ts @@ -11,6 +11,16 @@ jest.mock('zen-logger', () => { }; }); +jest.mock('lodash', () => { + const original = jest.requireActual('lodash'); + + return { + ...original, + debounce: (fn) => () => fn(), + throttle: (fn) => () => fn(), + } +}) + export const mockConsoleWarn = jest.fn(); console.warn = mockConsoleWarn; diff --git a/packages/renderer-core/tests/utils/components.tsx b/packages/renderer-core/tests/utils/components.tsx index 5cb557d4b2..639151612f 100644 --- a/packages/renderer-core/tests/utils/components.tsx +++ b/packages/renderer-core/tests/utils/components.tsx @@ -1,9 +1,17 @@ import React from 'react'; import { Box, Breadcrumb, Form, Select, Input, Button, Table, Pagination, Dialog } from '@alifd/next'; -const Div = (props: any) => (
{props.children}
); +const Div = ({_leaf, ...rest}: any) => (
{rest.children}
); -const Text = (props: any) => (
{props.content}
); +const MiniRenderDiv = ({_leaf, ...rest}: any) => { + return ( +
+ {rest.children} +
+ ); +}; + +const Text = ({_leaf, ...rest}: any) => (
{rest.content}
); const SlotComponent = (props: any) => props.mobileSlot; @@ -24,6 +32,7 @@ const components = { Div, SlotComponent, Text, + MiniRenderDiv, }; -export default components; \ No newline at end of file +export default components; diff --git a/packages/renderer-core/tests/utils/node.ts b/packages/renderer-core/tests/utils/node.ts index 2756191c6f..01da07a695 100644 --- a/packages/renderer-core/tests/utils/node.ts +++ b/packages/renderer-core/tests/utils/node.ts @@ -6,16 +6,47 @@ export default class Node { schema: any = { props: {}, }; - hasLoop = false; - constructor(schema: any) { + componentMeta = {}; + + parent; + + hasLoop = () => this._hasLoop; + + id; + + _isRoot: false; + + _hasLoop: false; + + constructor(schema: any, info: any = {}) { this.emitter = new EventEmitter(); - this.schema = schema; + const { + componentMeta, + parent, + isRoot, + hasLoop, + } = info; + this.schema = { + props: {}, + ...schema, + }; + this.componentMeta = componentMeta || {}; + this.parent = parent; + this.id = schema.id; + this._isRoot = isRoot; + this._hasLoop = hasLoop; } - mockLoop() { - this.hasLoop = true; - } + isRoot = () => this._isRoot; + + // componentMeta() { + // return this.componentMeta; + // } + + // mockLoop() { + // // this.hasLoop = true; + // } onChildrenChange(fn: any) { this.emitter.on('onChildrenChange', fn); @@ -24,6 +55,10 @@ export default class Node { } } + emitChildrenChange() { + this.emitter?.emit('onChildrenChange', {}); + } + onPropChange(fn: any) { this.emitter.on('onPropChange', fn); return () => { @@ -31,11 +66,14 @@ export default class Node { } } - emitPropChange(val: PropChangeOptions) { - this.schema.props = { - ...this.schema.props, - [val.key + '']: val.newValue, + emitPropChange(val: PropChangeOptions, skip?: boolean) { + if (!skip) { + this.schema.props = { + ...this.schema.props, + [val.key + '']: val.newValue, + } } + this.emitter?.emit('onPropChange', val); } From a2d5c6fd90ca0226bbbfea01a4b28c8b8d307a78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Fri, 13 May 2022 14:11:45 +0800 Subject: [PATCH 002/823] fix: fix outline-tree initialization failed --- packages/plugin-outline-pane/src/main.ts | 2 +- packages/shell/src/component-meta.ts | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/plugin-outline-pane/src/main.ts b/packages/plugin-outline-pane/src/main.ts index 697af1562e..1f2e23ffdd 100644 --- a/packages/plugin-outline-pane/src/main.ts +++ b/packages/plugin-outline-pane/src/main.ts @@ -60,7 +60,7 @@ export class OutlineMain implements ISensor, ITreeBoard, IScrollable { return false; } inited = true; - const designer = await editor.onceGot(Designer); + const designer = await editor.onceGot('designer'); this.setupDesigner(designer); }; diff --git a/packages/shell/src/component-meta.ts b/packages/shell/src/component-meta.ts index bc8a44922f..8cf9a570e3 100644 --- a/packages/shell/src/component-meta.ts +++ b/packages/shell/src/component-meta.ts @@ -117,8 +117,12 @@ export default class ComponentMeta { * @param parent * @returns */ - checkNestingDown(my: Node | NodeData, target: NodeSchema | Node | NodeSchema[]) { + checkNestingDown(my: Node | NodeData, target: NodeSchema | Node | NodeSchema[]) { const curNode = my.isNode ? my[nodeSymbol] : my; return this[componentMetaSymbol].checkNestingDown(curNode as any, target[nodeSymbol] || target); } + + refreshMetadata() { + this[componentMetaSymbol].refreshMetadata(); + } } From b96f16672e023831f4b6431a2b18639e76c28c9a Mon Sep 17 00:00:00 2001 From: Verse <58654825+hakuna-tata@users.noreply.github.com> Date: Fri, 13 May 2022 14:22:46 +0800 Subject: [PATCH 003/823] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E6=B8=B2=E6=9F=93?= =?UTF-8?q?=E5=99=A8=20demo=20=E6=9C=8D=E5=8A=A1=E4=BE=9D=E8=B5=96?= =?UTF-8?q?=E9=97=AE=E9=A2=98=20(#469)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix: 渲染器支持本地调试 --- packages/react-renderer/README.md | 0 packages/react-renderer/demo/compose.md | 2 +- packages/react-renderer/demo/dataSource.md | 2 +- packages/react-renderer/demo/i18n.md | 2 +- packages/react-renderer/demo/list.md | 2 +- packages/react-renderer/demo/table.md | 2 +- 6 files changed, 5 insertions(+), 5 deletions(-) create mode 100644 packages/react-renderer/README.md diff --git a/packages/react-renderer/README.md b/packages/react-renderer/README.md new file mode 100644 index 0000000000..e69de29bb2 diff --git a/packages/react-renderer/demo/compose.md b/packages/react-renderer/demo/compose.md index c432f3e971..b828cd6041 100644 --- a/packages/react-renderer/demo/compose.md +++ b/packages/react-renderer/demo/compose.md @@ -6,7 +6,7 @@ order: 2 ````jsx import React, { PureComponent } from 'react'; import ReactDOM from 'react-dom'; -import ReactRenderer from '@ali/lowcode-react-renderer'; +import ReactRenderer from '@alilc/lowcode-react-renderer'; import schema from './schemas/compose'; import components from './config/components/index'; import utils from './config/utils'; diff --git a/packages/react-renderer/demo/dataSource.md b/packages/react-renderer/demo/dataSource.md index 7167c80254..5ec00ae8b9 100644 --- a/packages/react-renderer/demo/dataSource.md +++ b/packages/react-renderer/demo/dataSource.md @@ -6,7 +6,7 @@ order: 4 ````jsx import React, { PureComponent } from 'react'; import ReactDOM from 'react-dom'; -import ReactRenderer from '@ali/lowcode-react-renderer'; +import ReactRenderer from '@alilc/lowcode-react-renderer'; import schema from './schemas/dataSource'; import components from './config/components/index'; import utils from './config/utils'; diff --git a/packages/react-renderer/demo/i18n.md b/packages/react-renderer/demo/i18n.md index ebca94fae3..bbea036d19 100644 --- a/packages/react-renderer/demo/i18n.md +++ b/packages/react-renderer/demo/i18n.md @@ -6,7 +6,7 @@ order: 5 ````jsx import React, { PureComponent } from 'react'; import ReactDOM from 'react-dom'; -import ReactRenderer from '@ali/lowcode-react-renderer'; +import ReactRenderer from '@alilc/lowcode-react-renderer'; import schema from './schemas/i18n'; import components from './config/components/index'; import utils from './config/utils'; diff --git a/packages/react-renderer/demo/list.md b/packages/react-renderer/demo/list.md index 5d5888f4f7..d0e34ee685 100644 --- a/packages/react-renderer/demo/list.md +++ b/packages/react-renderer/demo/list.md @@ -6,7 +6,7 @@ order: 1 ````jsx import React, { PureComponent } from 'react'; import ReactDOM from 'react-dom'; -import ReactRenderer from '@ali/lowcode-react-renderer'; +import ReactRenderer from '@alilc/lowcode-react-renderer'; import schema from './schemas/list'; import components from './config/components/index'; import utils from './config/utils'; diff --git a/packages/react-renderer/demo/table.md b/packages/react-renderer/demo/table.md index 9bdacf36cb..3c7cb307ca 100644 --- a/packages/react-renderer/demo/table.md +++ b/packages/react-renderer/demo/table.md @@ -6,7 +6,7 @@ order: 1 ````jsx import React, { PureComponent } from 'react'; import ReactDOM from 'react-dom'; -import ReactRenderer from '@ali/lowcode-react-renderer'; +import ReactRenderer from '@alilc/lowcode-react-renderer'; import schema from './schemas/table'; import components from './config/components/index'; import utils from './config/utils'; From 04631f813782dbf6d175f51c40ccc75ca4c099d2 Mon Sep 17 00:00:00 2001 From: xingmolu <591745264@qq.com> Date: Fri, 13 May 2022 14:34:14 +0800 Subject: [PATCH 004/823] =?UTF-8?q?feat:=20=F0=9F=8E=B8=20=E8=AE=BE?= =?UTF-8?q?=E8=AE=A1=E6=80=81=E6=94=AF=E6=8C=81=E6=95=B0=E6=8D=AE=E6=BA=90?= =?UTF-8?q?=E5=BC=95=E6=93=8E=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/editor-core/package.json | 3 ++- packages/editor-core/src/config.ts | 5 +++++ 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index aa44859630..69cbe3a781 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -38,7 +38,8 @@ "@types/store": "^2.0.2", "build-plugin-component": "^0.2.11", "build-plugin-fusion": "^0.1.0", - "build-plugin-moment-locales": "^0.1.0" + "build-plugin-moment-locales": "^0.1.0", + "@alilc/lowcode-datasource-types": "^1.0.1" }, "publishConfig": { "access": "public", diff --git a/packages/editor-core/src/config.ts b/packages/editor-core/src/config.ts index d5da2308d2..f18e21575a 100644 --- a/packages/editor-core/src/config.ts +++ b/packages/editor-core/src/config.ts @@ -1,6 +1,9 @@ import { ComponentType } from 'react'; import { get as lodashGet } from 'lodash'; import { isPlainObject } from '@alilc/lowcode-utils'; + +import { RequestHandlersMap } from '@alilc/lowcode-datasource-types'; + import { getLogger } from './utils/logger'; const logger = getLogger({ level: 'log', bizName: 'config' }); @@ -205,6 +208,8 @@ export interface EngineOptions { // 是否开启在 render 阶段开启 filter reducer,默认值:false enableFilterReducerInRenderStage?: boolean; }; + + requestHandlersMap: RequestHandlersMap; } const getStrictModeValue = (engineOptions: EngineOptions, defaultValue: boolean): boolean => { From fb580b5fb2653aec27e2213425e2865719002542 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Fri, 13 May 2022 14:47:53 +0800 Subject: [PATCH 005/823] chore(release): publish 1.0.8 --- lerna.json | 2 +- packages/designer/package.json | 10 +++++----- packages/editor-core/package.json | 10 +++++----- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 16 ++++++++-------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 10 +++++----- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 12 ++++++------ packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- 16 files changed, 62 insertions(+), 62 deletions(-) diff --git a/lerna.json b/lerna.json index 00032c95d2..a135fb25c6 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.0.7", + "version": "1.0.8", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index 8630fb9e7e..a0f52eac8b 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.0.7", + "version": "1.0.8", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,10 +15,10 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.0.7", - "@alilc/lowcode-shell": "1.0.7", - "@alilc/lowcode-types": "1.0.7", - "@alilc/lowcode-utils": "1.0.7", + "@alilc/lowcode-editor-core": "1.0.8", + "@alilc/lowcode-shell": "1.0.8", + "@alilc/lowcode-types": "1.0.8", + "@alilc/lowcode-utils": "1.0.8", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 69cbe3a781..0688c71cbf 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.0.7", + "version": "1.0.8", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.0.7", - "@alilc/lowcode-utils": "1.0.7", + "@alilc/lowcode-types": "1.0.8", + "@alilc/lowcode-utils": "1.0.8", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", @@ -30,6 +30,7 @@ }, "devDependencies": { "@alib/build-scripts": "^0.1.18", + "@alilc/lowcode-datasource-types": "^1.0.1", "@types/classnames": "^2.2.7", "@types/lodash.get": "^4.4.6", "@types/node": "^13.7.1", @@ -38,8 +39,7 @@ "@types/store": "^2.0.2", "build-plugin-component": "^0.2.11", "build-plugin-fusion": "^0.1.0", - "build-plugin-moment-locales": "^0.1.0", - "@alilc/lowcode-datasource-types": "^1.0.1" + "build-plugin-moment-locales": "^0.1.0" }, "publishConfig": { "access": "public", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index e4f70f7e87..0f59991324 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.0.7", + "version": "1.0.8", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -18,10 +18,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.0.7", - "@alilc/lowcode-editor-core": "1.0.7", - "@alilc/lowcode-types": "1.0.7", - "@alilc/lowcode-utils": "1.0.7", + "@alilc/lowcode-designer": "1.0.8", + "@alilc/lowcode-editor-core": "1.0.8", + "@alilc/lowcode-types": "1.0.8", + "@alilc/lowcode-utils": "1.0.8", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index 280dba4b8d..d4c990d95f 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.0.7", + "version": "1.0.8", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,14 +19,14 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.0.7", - "@alilc/lowcode-editor-core": "1.0.7", - "@alilc/lowcode-editor-skeleton": "1.0.7", + "@alilc/lowcode-designer": "1.0.8", + "@alilc/lowcode-editor-core": "1.0.8", + "@alilc/lowcode-editor-skeleton": "1.0.8", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.0.7", - "@alilc/lowcode-plugin-outline-pane": "1.0.7", - "@alilc/lowcode-shell": "1.0.7", - "@alilc/lowcode-utils": "1.0.7", + "@alilc/lowcode-plugin-designer": "1.0.8", + "@alilc/lowcode-plugin-outline-pane": "1.0.8", + "@alilc/lowcode-shell": "1.0.8", + "@alilc/lowcode-utils": "1.0.8", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index 746965b8b2..025648248c 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.0.7", + "version": "1.0.8", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 0200a9ac9a..b3480fcd05 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.0.7", + "version": "1.0.8", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.0.7", - "@alilc/lowcode-editor-core": "1.0.7", - "@alilc/lowcode-utils": "1.0.7", + "@alilc/lowcode-designer": "1.0.8", + "@alilc/lowcode-editor-core": "1.0.8", + "@alilc/lowcode-utils": "1.0.8", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index 9829dd60d3..0ead7898c6 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.0.7", + "version": "1.0.8", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,10 +13,10 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-designer": "1.0.7", - "@alilc/lowcode-editor-core": "1.0.7", - "@alilc/lowcode-types": "1.0.7", - "@alilc/lowcode-utils": "1.0.7", + "@alilc/lowcode-designer": "1.0.8", + "@alilc/lowcode-editor-core": "1.0.8", + "@alilc/lowcode-types": "1.0.8", + "@alilc/lowcode-utils": "1.0.8", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0" diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index fbbd901f12..f370b29142 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.0.7", + "version": "1.0.8", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.0.7", - "@alilc/lowcode-utils": "1.0.7", + "@alilc/lowcode-renderer-core": "1.0.8", + "@alilc/lowcode-utils": "1.0.8", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index 55c77dd3bf..46fef1fb36 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.0.7", + "version": "1.0.8", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.0.7", - "@alilc/lowcode-rax-renderer": "1.0.7", - "@alilc/lowcode-types": "1.0.7", - "@alilc/lowcode-utils": "1.0.7", + "@alilc/lowcode-designer": "1.0.8", + "@alilc/lowcode-rax-renderer": "1.0.8", + "@alilc/lowcode-types": "1.0.8", + "@alilc/lowcode-utils": "1.0.8", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 156fbc0b8a..a4425a5cba 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.0.7", + "version": "1.0.8", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.0.7" + "@alilc/lowcode-renderer-core": "1.0.8" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index b46ecde698..b14e99452d 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.0.7", + "version": "1.0.8", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -16,10 +16,10 @@ "build:umd": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.0.7", - "@alilc/lowcode-react-renderer": "1.0.7", - "@alilc/lowcode-types": "1.0.7", - "@alilc/lowcode-utils": "1.0.7", + "@alilc/lowcode-designer": "1.0.8", + "@alilc/lowcode-react-renderer": "1.0.8", + "@alilc/lowcode-types": "1.0.8", + "@alilc/lowcode-utils": "1.0.8", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index b6f9a4e269..70b0b3e6ac 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.0.7", + "version": "1.0.8", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.0.7", - "@alilc/lowcode-utils": "1.0.7", + "@alilc/lowcode-types": "1.0.8", + "@alilc/lowcode-utils": "1.0.8", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -34,7 +34,7 @@ }, "devDependencies": { "@alib/build-scripts": "^0.1.18", - "@alilc/lowcode-designer": "1.0.7", + "@alilc/lowcode-designer": "1.0.8", "@alilc/lowcode-test-mate": "^1.0.1", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", diff --git a/packages/shell/package.json b/packages/shell/package.json index bc9d9341d6..3ce1c58703 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.0.7", + "version": "1.0.8", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.0.7", - "@alilc/lowcode-editor-core": "1.0.7", - "@alilc/lowcode-editor-skeleton": "1.0.7", - "@alilc/lowcode-types": "1.0.7", - "@alilc/lowcode-utils": "1.0.7", + "@alilc/lowcode-designer": "1.0.8", + "@alilc/lowcode-editor-core": "1.0.8", + "@alilc/lowcode-editor-skeleton": "1.0.8", + "@alilc/lowcode-types": "1.0.8", + "@alilc/lowcode-utils": "1.0.8", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index 756b8c11a3..3dce35e26e 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.0.7", + "version": "1.0.8", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index 311c952a05..a20bcb0f9b 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.0.7", + "version": "1.0.8", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.0.7", + "@alilc/lowcode-types": "1.0.8", "lodash": "^4.17.21", "react": "^16", "zen-logger": "^1.1.0" From aa6b9c8f7a5353771af9f46216310f044e57c533 Mon Sep 17 00:00:00 2001 From: liujuping Date: Fri, 13 May 2022 20:23:37 +0800 Subject: [PATCH 006/823] feat: change loop sertter config, set defaultValue prop to JsonSetter --- packages/editor-skeleton/src/transducers/addon-combine.ts | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/editor-skeleton/src/transducers/addon-combine.ts b/packages/editor-skeleton/src/transducers/addon-combine.ts index 3555286f68..7dd04561c8 100644 --- a/packages/editor-skeleton/src/transducers/addon-combine.ts +++ b/packages/editor-skeleton/src/transducers/addon-combine.ts @@ -261,11 +261,13 @@ export default function (metadata: TransformedComponentMetadata): TransformedCom { name: getConvertedExtraKey('loop'), title: { type: 'i18n', 'zh-CN': '循环数据', 'en-US': 'Loop Data' }, + defaultValue: [], setter: [ { componentName: 'JsonSetter', props: { label: { type: 'i18n', 'zh-CN': '编辑数据', 'en-US': 'Edit Data' }, + defaultValue: '[]', }, }, { From 8255b7945836ee5d25fae73913faa6d0af7b3ff3 Mon Sep 17 00:00:00 2001 From: liujuping Date: Thu, 19 May 2022 11:47:14 +0800 Subject: [PATCH 007/823] feat: modify the output method of rendering module parsing errors --- packages/renderer-core/src/utils/common.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index 52642c4d46..5ed5bf043b 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -1,6 +1,6 @@ /* eslint-disable no-console */ /* eslint-disable no-new-func */ -import Debug from 'debug'; +import logger from './logger'; import { isI18nData, RootSchema, NodeSchema, isJSExpression, JSSlot } from '@alilc/lowcode-types'; // moment对象配置 import _moment from 'moment'; @@ -36,8 +36,6 @@ const EXPRESSION_TYPE = { I18N: 'i18n', }; -const debug = Debug('utils:index'); - /** * check if schema passed in is a valid schema * @name isSchema @@ -264,7 +262,7 @@ export function parseExpression(str: any, self: any) { const code = `with($scope || {}) { ${tarStr} }`; return new Function('$scope', code)(self); } catch (err) { - debug('parseExpression.error', err, str, self); + logger.error('parseExpression.error', err, str, self); return undefined; } } From 2871b5ba4c3dbf1ed76bf4d6359fb457190a9b22 Mon Sep 17 00:00:00 2001 From: twinkle77 <2153165927@qq.com> Date: Thu, 19 May 2022 14:23:15 +0800 Subject: [PATCH 008/823] feat: sync utils/constants (#506) --- packages/designer/src/builtin-simulator/host.ts | 1 + packages/editor-core/src/config.ts | 9 +++++++++ packages/react-simulator-renderer/src/renderer.ts | 2 ++ 3 files changed, 12 insertions(+) diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index 8befb04333..e4cfc4c96c 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -190,6 +190,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost(() => this.componentsAsset); this.injectionConsumer = new ResourceConsumer(() => { return { + appHelper: engineConfig.get('appHelper'), i18n: this.project.i18n, }; }); diff --git a/packages/editor-core/src/config.ts b/packages/editor-core/src/config.ts index f18e21575a..ecb76afb43 100644 --- a/packages/editor-core/src/config.ts +++ b/packages/editor-core/src/config.ts @@ -208,6 +208,15 @@ export interface EngineOptions { // 是否开启在 render 阶段开启 filter reducer,默认值:false enableFilterReducerInRenderStage?: boolean; }; + /** + * 与 react-renderer 的 appHelper 一致, https://lowcode-engine.cn/docV2/nhilce#appHelper + */ + appHelper?: { + /** 全局公共函数 */ + utils?: Record; + /** 全局常量 */ + constants?: Record; + }; requestHandlersMap: RequestHandlersMap; } diff --git a/packages/react-simulator-renderer/src/renderer.ts b/packages/react-simulator-renderer/src/renderer.ts index 4c34f25d00..6c246e0949 100644 --- a/packages/react-simulator-renderer/src/renderer.ts +++ b/packages/react-simulator-renderer/src/renderer.ts @@ -25,6 +25,7 @@ import { createMemoryHistory, MemoryHistory } from 'history'; import Slot from './builtin-components/slot'; import Leaf from './builtin-components/leaf'; import { withQueryParams, parseQuery } from './utils/url'; +import { merge } from 'lodash'; const loader = new AssetLoader(); configure({ enforceActions: 'never' }); @@ -308,6 +309,7 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer { ...this._appContext, }; newCtx.utils.i18n.messages = data.i18n || {}; + merge(newCtx, data.appHelper || {}); this._appContext = newCtx; }); } From 1cfc8d668b8897ef3a53c11520312cc6d18338f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Thu, 19 May 2022 10:23:06 +0800 Subject: [PATCH 009/823] feat: add renderer for simulatorHost --- packages/shell/src/simulator-host.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/shell/src/simulator-host.ts b/packages/shell/src/simulator-host.ts index 7785fed929..d22336c3ed 100644 --- a/packages/shell/src/simulator-host.ts +++ b/packages/shell/src/simulator-host.ts @@ -29,6 +29,10 @@ export default class SimulatorHost { return this[simulatorHostSymbol].contentDocument; } + get renderer() { + return this[simulatorHostSymbol].renderer; + } + /** * 设置 host 配置值 * @param key From b4f463e7d45f7b476de04bd4d98ad9f74d53cf13 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Thu, 19 May 2022 10:42:03 +0800 Subject: [PATCH 010/823] feat: add script for synchronizing packages to intranet registry --- package.json | 3 ++- scripts/sync.sh | 17 +++++++++++++++++ 2 files changed, 19 insertions(+), 1 deletion(-) create mode 100755 scripts/sync.sh diff --git a/package.json b/package.json index 6e8ab87038..72ddd3ca62 100644 --- a/package.json +++ b/package.json @@ -28,7 +28,8 @@ "start": "./scripts/start.sh", "test": "lerna run test --stream", "test:snapshot": "lerna run test:snapshot", - "watchdog:build": "node ./scripts/watchdog.js" + "watchdog:build": "node ./scripts/watchdog.js", + "sync": "./scripts/sync.sh" }, "husky": { "hooks": { diff --git a/scripts/sync.sh b/scripts/sync.sh new file mode 100755 index 0000000000..71ab5f5a1a --- /dev/null +++ b/scripts/sync.sh @@ -0,0 +1,17 @@ +#!/usr/bin/env bash + +# sync all packages to alibaba intranet registry +tnpm sync @alilc/lowcode-types +tnpm sync @alilc/lowcode-utils +tnpm sync @alilc/lowcode-shell +tnpm sync @alilc/lowcode-editor-core +tnpm sync @alilc/lowcode-editor-skeleton +tnpm sync @alilc/lowcode-designer +tnpm sync @alilc/lowcode-plugin-designer +tnpm sync @alilc/lowcode-plugin-outline-pane +tnpm sync @alilc/lowcode-rax-renderer +tnpm sync @alilc/lowcode-rax-simulator-renderer +tnpm sync @alilc/lowcode-react-renderer +tnpm sync @alilc/lowcode-react-simulator-renderer +tnpm sync @alilc/lowcode-renderer-core +tnpm sync @alilc/lowcode-engine \ No newline at end of file From 9ccded006ef44cd538abaa140250e519243bf090 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=91=E4=BA=91=E9=85=B1?= Date: Thu, 19 May 2022 14:30:23 +0800 Subject: [PATCH 011/823] fix: missing engine options config info fix: missing engine options config info --- packages/editor-core/src/config.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/editor-core/src/config.ts b/packages/editor-core/src/config.ts index ecb76afb43..66011a14c9 100644 --- a/packages/editor-core/src/config.ts +++ b/packages/editor-core/src/config.ts @@ -30,6 +30,11 @@ const VALID_ENGINE_OPTIONS = { default: 'default', description: '设备类型', }, + deviceClassName: { + type: 'string', + default: undefined, + description: '指定初始化的 deviceClassName,挂载到画布的顶层节点上', + }, locale: { type: 'string', default: 'zh_CN', @@ -131,6 +136,10 @@ export interface EngineOptions { * 设备类型,默认值:'default' */ device?: 'default' | 'mobile' | string; + /** + * 指定初始化的 deviceClassName,挂载到画布的顶层节点上 + */ + deviceClassName?: string; /** * 语言,默认值:'zh_CN' */ From a79875cf8698d3912b50526d97f6ac72e9a21fc9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=BA=91=E4=BA=91=E9=85=B1?= Date: Thu, 19 May 2022 14:33:32 +0800 Subject: [PATCH 012/823] fix: missing engine options config info fix: missing engine options config info --- CONTRIBUTOR.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTOR.md b/CONTRIBUTOR.md index c15f58af95..89757bac92 100644 --- a/CONTRIBUTOR.md +++ b/CONTRIBUTOR.md @@ -16,6 +16,7 @@ - [leoyuan](https://github.com/leoyuan) - [liujuping](https://github.com/liujuping) - [lqy978599280](https://github.com/lqy978599280) +- [markyun](https://github.com/markyun) - [mark-ck](https://github.com/mark-ck) - [mochen666](https://github.com/mochen666) - [tsy77](https://github.com/tsy77) From acf7449ca231d45e8ed7e1d9416817ea11b1266f Mon Sep 17 00:00:00 2001 From: liujuping Date: Wed, 25 May 2022 10:48:14 +0800 Subject: [PATCH 013/823] fix: delete the defaultValue configuration outside the loop --- packages/editor-skeleton/src/transducers/addon-combine.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/editor-skeleton/src/transducers/addon-combine.ts b/packages/editor-skeleton/src/transducers/addon-combine.ts index 7dd04561c8..e1680e0ff5 100644 --- a/packages/editor-skeleton/src/transducers/addon-combine.ts +++ b/packages/editor-skeleton/src/transducers/addon-combine.ts @@ -261,7 +261,6 @@ export default function (metadata: TransformedComponentMetadata): TransformedCom { name: getConvertedExtraKey('loop'), title: { type: 'i18n', 'zh-CN': '循环数据', 'en-US': 'Loop Data' }, - defaultValue: [], setter: [ { componentName: 'JsonSetter', From 8a3a0b824162e25a930711c6fef511b4b369e897 Mon Sep 17 00:00:00 2001 From: "ruhuo.tan" Date: Thu, 19 May 2022 14:08:42 +0800 Subject: [PATCH 014/823] fix: fix setter hooks error --- .../designer/src/designer/setting/utils.ts | 27 ++++++++++++++----- packages/editor-core/src/di/setter.ts | 2 ++ packages/types/src/setter-config.ts | 2 ++ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/packages/designer/src/designer/setting/utils.ts b/packages/designer/src/designer/setting/utils.ts index b7c8fb4e58..01c2d9e395 100644 --- a/packages/designer/src/designer/setting/utils.ts +++ b/packages/designer/src/designer/setting/utils.ts @@ -1,8 +1,8 @@ // all this file for polyfill vision logic - import { isValidElement } from 'react'; -import { isSetterConfig, isDynamicSetter } from '@alilc/lowcode-types'; +import { isSetterConfig, isDynamicSetter, FieldConfig, SetterConfig } from '@alilc/lowcode-types'; import { getSetter } from '@alilc/lowcode-editor-core'; +import { SettingField } from './setting-field'; function getHotterFromSetter(setter) { return setter && (setter.Hotter || (setter.type && setter.type.Hotter)) || []; // eslint-disable-line @@ -35,7 +35,7 @@ export class Transducer { context: any; - constructor(context, config) { + constructor(context: SettingField, config: { setter: FieldConfig['setter'] }) { let { setter } = config; // 1. validElement @@ -46,16 +46,29 @@ export class Transducer { } else if (isValidElement(setter) && setter.type.displayName === 'MixedSetter') { setter = setter.props?.setters?.[0]; } else if (typeof setter === 'object' && setter.componentName === 'MixedSetter') { - setter = setter && setter.props && setter.props.setters && Array.isArray(setter.props.setters) && setter.props.setters[0]; + setter = Array.isArray(setter?.props?.setters) && setter.props.setters[0]; } + /** + * 两种方式标识是 FC 而不是动态 setter + * 1. 物料描述里面 setter 的配置,显式设置为 false + * 2. registerSetter 注册 setter 时显式设置为 false + */ + + let isDynamic = true; + if (isSetterConfig(setter)) { - setter = setter.componentName; + const { componentName, isDynamic: dynamicFlag } = setter as SetterConfig; + setter = componentName; + isDynamic = dynamicFlag !== false; } if (typeof setter === 'string') { - setter = getSetter(setter)?.component; + const { component, isDynamic: dynamicFlag } = getSetter(setter) || {}; + setter = component; + // 如果在物料配置中声明了,在 registerSetter 没有声明,取物料配置中的声明 + isDynamic = dynamicFlag === undefined ? isDynamic : dynamicFlag !== false; } - if (isDynamicSetter(setter)) { + if (isDynamicSetter(setter) && isDynamic) { setter = setter.call(context, context); } diff --git a/packages/editor-core/src/di/setter.ts b/packages/editor-core/src/di/setter.ts index 043d693cc1..2dd350deb4 100644 --- a/packages/editor-core/src/di/setter.ts +++ b/packages/editor-core/src/di/setter.ts @@ -15,6 +15,8 @@ export type RegisteredSetter = { */ initialValue?: any | ((field: any) => any); recommend?: boolean; + // 标识是否为动态setter,默认为true + isDynamic?: boolean; }; const settersMap = new Map Date: Sat, 21 May 2022 16:40:27 +0800 Subject: [PATCH 015/823] =?UTF-8?q?fix:=20=F0=9F=90=9B=20=E4=BF=AE?= =?UTF-8?q?=E5=A4=8D=E6=95=B0=E6=8D=AE=E6=BA=90=E5=BC=95=E6=93=8E=E8=AF=B7?= =?UTF-8?q?=E6=B1=82=E5=A4=84=E7=90=86=E5=99=A8=E6=98=A0=E5=B0=84=E4=B8=A5?= =?UTF-8?q?=E6=A0=BC=E6=A8=A1=E5=BC=8F=E4=B8=8B=E8=A2=AB=E8=BF=87=E6=BB=A4?= =?UTF-8?q?=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/editor-core/src/config.ts | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/packages/editor-core/src/config.ts b/packages/editor-core/src/config.ts index 66011a14c9..26a28e5006 100644 --- a/packages/editor-core/src/config.ts +++ b/packages/editor-core/src/config.ts @@ -118,6 +118,10 @@ const VALID_ENGINE_OPTIONS = { type: 'array', description: '自定义 simulatorUrl 的地址', }, + requestHandlersMap: { + type: 'object', + description: '数据源引擎的请求处理器映射', + }, }; export interface EngineOptions { /** @@ -227,6 +231,9 @@ export interface EngineOptions { constants?: Record; }; + /** + * 数据源引擎的请求处理器映射 + */ requestHandlersMap: RequestHandlersMap; } @@ -316,7 +323,7 @@ export class EngineConfig { if (isValidKey(key)) { this.set(key, engineOptions[key]); } else { - logger.warn(`failed to config ${key} to engineConfig, only predefined options can be set under strict mode, predefined options: ${VALID_ENGINE_OPTIONS}`); + logger.warn(`failed to config ${key} to engineConfig, only predefined options can be set under strict mode, predefined options: `, VALID_ENGINE_OPTIONS); } }); } else { From bf280c6fa1e46d084fc8f20323164816fad4076f Mon Sep 17 00:00:00 2001 From: liujuping Date: Thu, 26 May 2022 18:24:02 +0800 Subject: [PATCH 016/823] fix: fix monitor utils incorrect assignment method --- packages/editor-core/src/utils/monitor.ts | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/packages/editor-core/src/utils/monitor.ts b/packages/editor-core/src/utils/monitor.ts index 80313a55bd..0889d45656 100644 --- a/packages/editor-core/src/utils/monitor.ts +++ b/packages/editor-core/src/utils/monitor.ts @@ -1,6 +1,6 @@ export class Monitor { fn = (params: any) => { - const { AES } = window as any; + const { AES = {} } = window as any; if (typeof AES.log === 'function') { const { p1 = '', p2 = '', p3 = '', p4 = 'OTHER', ...rest } = params || {}; AES.log('event', { @@ -13,10 +13,6 @@ export class Monitor { } }; - constructor() { - (window as any).AES = (window as any).AES || {}; - } - register(fn: () => any) { if (typeof fn === 'function') { this.fn = fn; @@ -30,7 +26,7 @@ export class Monitor { } setConfig(key: string | object, value?: string): void { - const { AES } = window as any; + const { AES = {} } = window as any; if (typeof AES?.setConfig !== 'function') { return; } From 171b1013b2d28bdbacfac05d3cf895722e7232cc Mon Sep 17 00:00:00 2001 From: JackLian Date: Mon, 30 May 2022 16:47:33 +0800 Subject: [PATCH 017/823] test: add ut for render-core/utils/data-helper.ts --- packages/renderer-core/src/renderer/base.tsx | 7 +- packages/renderer-core/src/utils/common.ts | 2 +- .../renderer-core/src/utils/data-helper.ts | 319 +++++----- .../tests/utils/data-helper.test.ts | 569 ++++++++++++++++++ 4 files changed, 728 insertions(+), 169 deletions(-) create mode 100644 packages/renderer-core/tests/utils/data-helper.test.ts diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index fb0354af3e..830c92dbbc 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -1,3 +1,4 @@ +/* eslint-disable max-len */ /* eslint-disable react/prop-types */ import classnames from 'classnames'; import { create as createDataSourceEngine } from '@alilc/lowcode-datasource-engine/interpret'; @@ -154,8 +155,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { this.__showPlaceholder = false; return resolve({}); } - this.__dataHelper - .getInitData() + this.__dataHelper.getInitData() .then((res: any) => { this.__showPlaceholder = false; if (isEmpty(res)) { @@ -286,8 +286,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { // this.__showPlaceholder = false; return resolve({}); } - this.__dataHelper - .getInitData() + this.__dataHelper.getInitData() .then((res: any) => { // this.__showPlaceholder = false; if (isEmpty(res)) { diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index 5ed5bf043b..437e6077fd 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -118,7 +118,7 @@ export function isJSSlot(obj: any): obj is JSSlot { } // Compatible with the old protocol JSBlock - return ([EXPRESSION_TYPE.JSSLOT, EXPRESSION_TYPE.JSBLOCK].includes(obj.type)); + return [EXPRESSION_TYPE.JSSLOT, EXPRESSION_TYPE.JSBLOCK].includes(obj.type); } /** diff --git a/packages/renderer-core/src/utils/data-helper.ts b/packages/renderer-core/src/utils/data-helper.ts index 22dbf1b66e..9eb152df9e 100644 --- a/packages/renderer-core/src/utils/data-helper.ts +++ b/packages/renderer-core/src/utils/data-helper.ts @@ -1,9 +1,11 @@ +/* eslint-disable no-console */ +/* eslint-disable max-len */ /* eslint-disable object-curly-newline */ import { isJSFunction } from '@alilc/lowcode-types'; -import { transformArrayToMap, transformStringToFunction, clone } from './common'; +import { transformArrayToMap, transformStringToFunction } from './common'; import { jsonp, request, get, post } from './request'; -import { DataSource, DataSourceItem } from '../types'; import logger from './logger'; +import { DataSource, DataSourceItem, IRendererAppHelper } from '../types'; const DS_STATUS = { INIT: 'init', @@ -12,22 +14,77 @@ const DS_STATUS = { ERROR: 'error', }; +type DataSourceType = 'fetch' | 'jsonp'; + +/** + * do request for standard DataSourceType + * @param {DataSourceType} type type of DataSourceItem + * @param {any} options + */ +export function doRequest(type: DataSourceType, options: any) { + // eslint-disable-next-line prefer-const + let { uri, url, method = 'GET', headers, params, ...otherProps } = options; + otherProps = otherProps || {}; + if (type === 'jsonp') { + return jsonp(uri, params, otherProps); + } + + if (type === 'fetch') { + switch (method.toUpperCase()) { + case 'GET': + return get(uri, params, headers, otherProps); + case 'POST': + return post(uri, params, headers, otherProps); + default: + return request(uri, method, params, headers, otherProps); + } + } + + logger.log(`Engine default dataSource does not support type:[${type}] dataSource request!`, options); +} + +// TODO: according to protocol, we should implement errorHandler/shouldFetch/willFetch/requestHandler and isSync controll. export class DataHelper { + /** + * host object that will be "this" object when excuting dataHandler + * + * @type {*} + * @memberof DataHelper + */ host: any; + /** + * data source config + * + * @type {DataSource} + * @memberof DataHelper + */ config: DataSource; + /** + * a parser function which will be called to process config data + * which eventually will call common/utils.processData() to process data + * (originalConfig) => parsedConfig + * @type {*} + * @memberof DataHelper + */ parser: any; + /** + * config.list + * + * @type {any[]} + * @memberof DataHelper + */ ajaxList: any[]; ajaxMap: any; dataSourceMap: any; - appHelper: any; + appHelper: IRendererAppHelper; - constructor(comp: any, config: DataSource, appHelper: any, parser: any) { + constructor(comp: any, config: DataSource, appHelper: IRendererAppHelper, parser: any) { this.host = comp; this.config = config || {}; this.parser = parser; @@ -37,15 +94,6 @@ export class DataHelper { this.appHelper = appHelper; } - // 重置config,dataSourceMap状态会被重置; - resetConfig(config = {}) { - this.config = config as DataSource; - this.ajaxList = (config as DataSource)?.list || []; - this.ajaxMap = transformArrayToMap(this.ajaxList, 'id'); - this.dataSourceMap = this.generateDataSourceMap(); - return this.dataSourceMap; - } - // 更新config,只会更新配置,状态保存; updateConfig(config = {}) { this.config = config as DataSource; @@ -79,6 +127,7 @@ export class DataHelper { res[item.id] = { status: DS_STATUS.INIT, load: (...args: any) => { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore return this.getDataSource(item.id, ...args); }, @@ -93,41 +142,54 @@ export class DataHelper { this.dataSourceMap[id].status = error ? DS_STATUS.ERROR : DS_STATUS.LOADED; } - getInitData() { - const initSyncData = this.parser(this.ajaxList).filter((item: DataSourceItem) => { - if (item.isInit) { + /** + * get all dataSourceItems which marked as isInit === true + * @private + * @returns + * @memberof DataHelper + */ + getInitDataSourseConfigs() { + const initConfigs = this.parser(this.ajaxList).filter((item: DataSourceItem) => { + // according to [spec](https://lowcode-engine.cn/lowcode), isInit should be boolean true to be working + if (item.isInit === true) { this.dataSourceMap[item.id].status = DS_STATUS.LOADING; return true; } return false; }); + return initConfigs; + } + + /** + * process all dataSourceItems which marked as isInit === true, and get dataSource request results. + * @public + * @returns + * @memberof DataHelper + */ + getInitData() { + const initSyncData = this.getInitDataSourseConfigs(); // 所有 datasource 的 datahandler return this.asyncDataHandler(initSyncData).then((res) => { - let { dataHandler } = this.config; - if (isJSFunction(dataHandler)) { - dataHandler = transformStringToFunction(dataHandler.value); - } - if (!dataHandler || typeof dataHandler !== 'function') return res; - try { - return (dataHandler as any).call(this.host, res); - } catch (e) { - console.error('请求数据处理函数运行出错', e); - } + const { dataHandler } = this.config; + return this.handleData(null, dataHandler, res, null); }); } getDataSource(id: string, params: any, otherOptions: any, callback: any) { const req = this.parser(this.ajaxMap[id]); const options = req.options || {}; + let callbackFn = callback; + let otherOptionsObj = otherOptions; if (typeof otherOptions === 'function') { - callback = otherOptions; - otherOptions = {}; + callbackFn = otherOptions; + otherOptionsObj = {}; } - const { headers, ...otherProps } = otherOptions || {}; + const { headers, ...otherProps } = otherOptionsObj || {}; if (!req) { console.warn(`getDataSource API named ${id} not exist`); return; } + return this.asyncDataHandler([ { ...req, @@ -149,170 +211,99 @@ export class DataHelper { }, }, ]) - .then((res: any) => { - try { - callback && callback(res && res[id]); - } catch (e) { - console.error('load请求回调函数报错', e); - } - - return res && res[id]; - }) - .catch((err) => { - try { - callback && callback(null, err); - } catch (e) { - console.error('load请求回调函数报错', e); - } - - return err; - }); + .then((res: any) => { + try { + callbackFn && callbackFn(res && res[id]); + } catch (e) { + console.error('load请求回调函数报错', e); + } + return res && res[id]; + }) + .catch((err) => { + try { + callbackFn && callbackFn(null, err); + } catch (e) { + console.error('load请求回调函数报错', e); + } + return err; + }); } asyncDataHandler(asyncDataList: any[]) { return new Promise((resolve, reject) => { - const allReq = []; - const doserReq: Array<{name: string; package: string; params: any }> = []; - const doserList: string[] = []; - const beforeRequest = this.appHelper && this.appHelper.utils && this.appHelper.utils.beforeRequest; - const afterRequest = this.appHelper && this.appHelper.utils && this.appHelper.utils.afterRequest; - const csrfInput = document.getElementById('_csrf_token'); - const _tb_token_ = (csrfInput as any)?.value; + const allReq: any[] = []; asyncDataList.forEach((req) => { - const { id, type, options } = req; - if (!id || !type || type === 'legao') return; - if (type === 'doServer') { - const { uri, params } = options || {}; - if (!uri) return; - doserList.push(id); - doserReq.push({ name: uri, package: 'cms', params }); - } else { - allReq.push(req); + const { id, type } = req; + // TODO: need refactoring to remove 'legao' related logic + if (!id || !type || type === 'legao') { + return; } + allReq.push(req); }); - if (doserReq.length > 0) { - allReq.push({ - type: 'doServer', - options: { - uri: '/nrsService.do', - cors: true, - method: 'POST', - params: { - data: JSON.stringify(doserReq), - _tb_token_, - }, - }, - }); + if (allReq.length === 0) { + resolve({}); } - if (allReq.length === 0) resolve({}); const res: any = {}; - // todo: Promise.all( allReq.map((item: any) => { - return new Promise((resolve) => { + return new Promise((innerResolve) => { const { type, id, dataHandler, options } = item; - const doFetch = (type: string, options: any) => { - this.fetchOne(type as any, options) + + const fetchHandler = (data: any, error: any) => { + res[id] = this.handleData(id, dataHandler, data, error); + this.updateDataSourceMap(id, res[id], error); + innerResolve({}); + }; + + const doFetch = (innerType: string, innerOptions: any) => { + doRequest(innerType as any, innerOptions) ?.then((data: any) => { - if (afterRequest) { - this.appHelper.utils.afterRequest(item, data, undefined, (data: any, error: any) => { - fetchHandler(data, error); - }); - } else { - fetchHandler(data, undefined); - } + fetchHandler(data, undefined); }) .catch((err: Error) => { - if (afterRequest) { - // 必须要这么调用,否则beforeRequest中的this会丢失 - this.appHelper.utils.afterRequest(item, undefined, err, (data: any, error: any) => { - fetchHandler(data, error); - }); - } else { - fetchHandler(undefined, err); - } + fetchHandler(undefined, err); }); }; - const fetchHandler = (data: any, error: any) => { - if (type === 'doServer') { - if (!Array.isArray(data)) { - data = [data]; - } - doserList.forEach((id, idx) => { - const req: any = this.ajaxMap[id]; - if (req) { - res[id] = this.dataHandler(id, req.dataHandler, data && data[idx], error); - this.updateDataSourceMap(id, res[id], error); - } - }); - } else { - res[id] = this.dataHandler(id, dataHandler, data, error); - this.updateDataSourceMap(id, res[id], error); - } - resolve({}); - }; - if (type === 'doServer') { - doserList.forEach((item) => { - this.dataSourceMap[item].status = DS_STATUS.LOADING; - }); - } else { - this.dataSourceMap[id].status = DS_STATUS.LOADING; - } - // 请求切片 - if (beforeRequest) { - // 必须要这么调用,否则beforeRequest中的this会丢失 - this.appHelper.utils.beforeRequest(item, clone(options), (options: any) => doFetch(type, options)); - } else { - doFetch(type, options); - } + this.dataSourceMap[id].status = DS_STATUS.LOADING; + doFetch(type, options); }); }), - ) - .then(() => { - resolve(res); - }) - .catch((e) => { - reject(e); - }); + ).then(() => { + resolve(res); + }).catch((e) => { + reject(e); + }); }); } - // dataHandler todo: - dataHandler(id: string, dataHandler: any, data: any, error: any) { + /** + * process data using dataHandler + * + * @param {(string | null)} id request id, will be used in error message, can be null + * @param {*} dataHandler + * @param {*} data + * @param {*} error + * @returns + * @memberof DataHelper + */ + handleData(id: string | null, dataHandler: any, data: any, error: any) { + let dataHandlerFun = dataHandler; if (isJSFunction(dataHandler)) { - dataHandler = transformStringToFunction(dataHandler.value); + dataHandlerFun = transformStringToFunction(dataHandler.value); + } + if (!dataHandlerFun || typeof dataHandlerFun !== 'function') { + return data; } - if (!dataHandler || typeof dataHandler !== 'function') return data; try { - return dataHandler.call(this.host, data, error); + return dataHandlerFun.call(this.host, data, error); } catch (e) { - console.error(`[${ id }]单个请求数据处理函数运行出错`, e); - } - } - - fetchOne(type: DataSourceType, options: any) { - // eslint-disable-next-line prefer-const - let { uri, url, method = 'GET', headers, params, ...otherProps } = options; - otherProps = otherProps || {}; - if (type === 'jsonp') { - return jsonp(uri, params, otherProps); - } - - if (type === 'fetch') { - switch (method.toUpperCase()) { - case 'GET': - return get(uri, params, headers, otherProps); - case 'POST': - return post(uri, params, headers, otherProps); - default: - return request(uri, method, params, headers, otherProps); + if (id) { + console.error(`[${id}]单个请求数据处理函数运行出错`, e); + } else { + console.error('请求数据处理函数运行出错', e); } } - - logger.log(`Engine default dataSource not support type:[${type}] dataSource request!`, options); } } - -type DataSourceType = 'fetch' | 'jsonp'; diff --git a/packages/renderer-core/tests/utils/data-helper.test.ts b/packages/renderer-core/tests/utils/data-helper.test.ts new file mode 100644 index 0000000000..cd4508ea87 --- /dev/null +++ b/packages/renderer-core/tests/utils/data-helper.test.ts @@ -0,0 +1,569 @@ +// @ts-nocheck +const mockJsonp = jest.fn(); +const mockRequest = jest.fn(); +const mockGet = jest.fn(); +const mockPost = jest.fn(); +jest.mock('../../src/utils/request', () => { + return { + jsonp: (uri, params, headers, otherProps) => { + return new Promise((resolve, reject) => { + resolve(mockJsonp(uri, params, headers, otherProps)); + }); + }, + request: (uri, params, headers, otherProps) => { + return new Promise((resolve, reject) => { + resolve(mockRequest(uri, params, headers, otherProps)); + }); + }, + get: (uri, params, headers, otherProps) => { + return new Promise((resolve, reject) => { + resolve(mockGet(uri, params, headers, otherProps)); + }); + }, + post: (uri, params, headers, otherProps) => { + return new Promise((resolve, reject) => { + resolve(mockPost(uri, params, headers, otherProps)); + }); + }, + }; + }); + +import { DataHelper, doRequest } from '../../src/utils/data-helper'; +import { parseData } from '../../src/utils/common'; + +describe('test DataHelper ', () => { + beforeEach(() => { + jest.resetModules(); + }) + it('can be inited', () => { + const mockHost = {}; + let mockDataSourceConfig = {}; + const mockAppHelper = {}; + const mockParser = (config: any) => parseData(config); + let dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser); + + expect(dataHelper).toBeTruthy(); + expect(dataHelper.host).toBe(mockHost); + expect(dataHelper.config).toBe(mockDataSourceConfig); + expect(dataHelper.appHelper).toBe(mockAppHelper); + expect(dataHelper.parser).toBe(mockParser); + + + dataHelper = new DataHelper(mockHost, undefined, mockAppHelper, mockParser); + expect(dataHelper.config).toStrictEqual({}); + expect(dataHelper.ajaxList).toStrictEqual([]); + + mockDataSourceConfig = { + list: [ + { + id: 'ds1', + }, { + id: 'ds2', + }, + ] + }; + dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser); + expect(dataHelper.config).toBe(mockDataSourceConfig); + expect(dataHelper.ajaxList.length).toBe(2); + expect(dataHelper.ajaxMap.ds1).toStrictEqual({ + id: 'ds1', + }); + }); + it('should handle generateDataSourceMap properly in constructor', () => { + const mockHost = {}; + let mockDataSourceConfig = {}; + const mockAppHelper = {}; + const mockParser = (config: any) => parseData(config); + let dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser); + + // test generateDataSourceMap logic + mockDataSourceConfig = { + list: [ + { + id: 'getInfo', + isInit: true, + type: 'fetch', // fetch/mtop/jsonp/custom + options: { + uri: 'mock/info.json', + method: 'GET', + params: { a: 1 }, + timeout: 5000, + }, + }, { + id: 'postInfo', + isInit: true, + type: 'fetch', + options: { + uri: 'mock/info.json', + method: 'POST', + params: { a: 1 }, + timeout: 5000, + }, + }, + ] + }; + dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser); + expect(Object.keys(dataHelper.dataSourceMap).length).toBe(2); + expect(dataHelper.dataSourceMap.getInfo.status).toBe('init'); + expect(typeof dataHelper.dataSourceMap.getInfo.load).toBe('function'); + }); + + it('getInitDataSourseConfigs should work', () => { + const mockHost = {}; + let mockDataSourceConfig = {}; + const mockAppHelper = {}; + const mockParser = (config: any) => parseData(config); + + // test generateDataSourceMap logic + mockDataSourceConfig = { + list: [ + { + id: 'getInfo', + isInit: true, + type: 'fetch', // fetch/mtop/jsonp/custom + options: { + uri: 'mock/info.json', + method: 'GET', + params: { a: 1 }, + timeout: 5000, + }, + }, + { + id: 'postInfo', + isInit: false, + type: 'fetch', + options: { + uri: 'mock/info.json', + method: 'POST', + params: { a: 1 }, + timeout: 5000, + }, + }, + { + id: 'getInfoLater', + isInit: false, + type: 'fetch', + options: { + uri: 'mock/info.json', + method: 'POST', + params: { a: 1 }, + timeout: 5000, + }, + }, + { + id: 'getInfoLater2', + isInit: 'not a valid boolean', + type: 'fetch', + options: { + uri: 'mock/info.json', + method: 'POST', + params: { a: 1 }, + timeout: 5000, + }, + }, + ], + }; + + const dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser); + expect(dataHelper.getInitDataSourseConfigs().length).toBe(1); + expect(dataHelper.getInitDataSourseConfigs()[0].id).toBe('getInfo'); + }); + it('util function doRequest should work', () => { + doRequest('jsonp', { + uri: 'https://www.baidu.com', + params: { a: 1 }, + otherStuff1: 'aaa', + }); + expect(mockJsonp).toBeCalled(); + + // test GET + doRequest('fetch', { + uri: 'https://www.baidu.com', + method: 'get', + params: { a: 1 }, + otherStuff1: 'aaa', + }); + expect(mockGet).toBeCalled(); + + mockGet.mockClear(); + doRequest('fetch', { + uri: 'https://www.baidu.com', + method: 'Get', + params: { a: 1 }, + otherStuff1: 'aaa', + }); + expect(mockGet).toBeCalled(); + + mockGet.mockClear(); + doRequest('fetch', { + uri: 'https://www.baidu.com', + method: 'GET', + params: { a: 1 }, + otherStuff1: 'aaa', + }); + expect(mockGet).toBeCalled(); + + mockGet.mockClear(); + + // test POST + doRequest('fetch', { + uri: 'https://www.baidu.com', + method: 'post', + params: { a: 1 }, + otherStuff1: 'aaa', + }); + expect(mockPost).toBeCalled(); + mockPost.mockClear(); + + doRequest('fetch', { + uri: 'https://www.baidu.com', + method: 'POST', + params: { a: 1 }, + otherStuff1: 'aaa', + }); + expect(mockPost).toBeCalled(); + mockPost.mockClear(); + doRequest('fetch', { + uri: 'https://www.baidu.com', + method: 'Post', + params: { a: 1 }, + otherStuff1: 'aaa', + }); + expect(mockPost).toBeCalled(); + mockPost.mockClear(); + + // test default + doRequest('fetch', { + uri: 'https://www.baidu.com', + method: 'whatever', + params: { a: 1 }, + otherStuff1: 'aaa', + }); + expect(mockRequest).toBeCalled(); + mockRequest.mockClear(); + mockGet.mockClear(); + + // method will be GET when not provided + doRequest('fetch', { + uri: 'https://www.baidu.com', + params: { a: 1 }, + otherStuff1: 'aaa', + }); + expect(mockRequest).toBeCalledTimes(0); + expect(mockGet).toBeCalledTimes(1); + + mockRequest.mockClear(); + mockGet.mockClear(); + mockPost.mockClear(); + mockJsonp.mockClear(); + + doRequest('someOtherType', { + uri: 'https://www.baidu.com', + params: { a: 1 }, + otherStuff1: 'aaa', + }); + expect(mockRequest).toBeCalledTimes(0); + expect(mockGet).toBeCalledTimes(0); + expect(mockPost).toBeCalledTimes(0); + expect(mockJsonp).toBeCalledTimes(0); + }); + it('updateDataSourceMap should work', () => { + const mockHost = {}; + const mockDataSourceConfig = { + list: [ + { + id: 'ds1', + }, { + id: 'ds2', + }, + ] + }; + const mockAppHelper = {}; + const mockParser = (config: any) => parseData(config); + const dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser); + dataHelper.updateDataSourceMap('ds1', { a: 1 }, null); + expect(dataHelper.dataSourceMap['ds1']).toBeTruthy(); + expect(dataHelper.dataSourceMap['ds1'].data).toStrictEqual({ a: 1 }); + expect(dataHelper.dataSourceMap['ds1'].error).toBeUndefined(); + expect(dataHelper.dataSourceMap['ds1'].status).toBe('loaded'); + dataHelper.updateDataSourceMap('ds2', { b: 2 }, new Error()); + expect(dataHelper.dataSourceMap['ds2']).toBeTruthy(); + expect(dataHelper.dataSourceMap['ds2'].data).toStrictEqual({ b: 2 }); + expect(dataHelper.dataSourceMap['ds2'].status).toBe('error'); + expect(dataHelper.dataSourceMap['ds2'].error).toBeTruthy(); + }); + + it('handleData should work', () => { + const mockHost = { stateA: 'aValue'}; + const mockDataSourceConfig = { + list: [ + { + id: 'fullConfigGet', + isInit: true, + options: { + params: {}, + method: 'GET', + isCors: true, + timeout: 5000, + headers: {}, + uri: 'mock/info.json', + }, + shouldFetch: { + type: 'JSFunction', + value: 'function() { return true; }', + }, + dataHandler: { + type: 'JSFunction', + value: 'function(res) { return res.data; }', + }, + errorHandler: { + type: 'JSFunction', + value: 'function(error) {}', + }, + willFetch: { + type: 'JSFunction', + value: 'function(options) { return options; }', + }, + }, + ] + }; + const mockAppHelper = {}; + const mockParser = (config: any) => parseData(config); + const dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser); + // test valid case + let mockDataHandler = { + type: 'JSFunction', + value: 'function(res) { return res.data + \'+\' + this.stateA; }', + }; + let result = dataHelper.handleData('fullConfigGet', mockDataHandler, { data: 'mockDataValue' }, null); + expect(result).toBe('mockDataValue+aValue'); + + // test invalid datahandler + mockDataHandler = { + type: 'not a JSFunction', + value: 'function(res) { return res.data + \'+\' + this.stateA; }', + }; + result = dataHelper.handleData('fullConfigGet', mockDataHandler, { data: 'mockDataValue' }, null); + expect(result).toStrictEqual({ data: 'mockDataValue' }); + + // test exception + const mockError = jest.fn(); + const orginalConsole = global.console; + global.console = { error: mockError }; + + // exception with id + mockDataHandler = { + type: 'JSFunction', + value: 'function(res) { return res.data + \'+\' + JSON.parse({a:1}); }', + }; + result = dataHelper.handleData('fullConfigGet', mockDataHandler, { data: 'mockDataValue' }, null); + expect(result).toBeUndefined(); + expect(mockError).toBeCalledWith('[fullConfigGet]单个请求数据处理函数运行出错', expect.anything()); + + // exception without id + mockDataHandler = { + type: 'JSFunction', + value: 'function(res) { return res.data + \'+\' + JSON.parse({a:1}); }', + }; + result = dataHelper.handleData(null, mockDataHandler, { data: 'mockDataValue' }, null); + expect(result).toBeUndefined(); + expect(mockError).toBeCalledWith('请求数据处理函数运行出错', expect.anything()); + + global.console = orginalConsole; + }); + + + it('updateConfig should work', () => { + const mockHost = { stateA: 'aValue'}; + const mockDataSourceConfig = { + list: [ + { + id: 'ds1', + }, { + id: 'ds2', + }, + { + id: 'fullConfigGet', + isInit: true, + options: { + params: {}, + method: 'GET', + isCors: true, + timeout: 5000, + headers: {}, + uri: 'mock/info.json', + }, + shouldFetch: { + type: 'JSFunction', + value: 'function() { return true; }', + }, + dataHandler: { + type: 'JSFunction', + value: 'function(res) { return res.data; }', + }, + errorHandler: { + type: 'JSFunction', + value: 'function(error) {}', + }, + willFetch: { + type: 'JSFunction', + value: 'function(options) { return options; }', + }, + }, + ] + }; + const mockAppHelper = {}; + const mockParser = (config: any) => parseData(config); + const dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser); + + expect(dataHelper.ajaxList.length).toBe(3); + + let updatedConfig = { + list: [ + { + id: 'ds2', + }, + { + id: 'fullConfigGet', + }, + ] + }; + dataHelper.updateConfig(updatedConfig); + + expect(dataHelper.ajaxList.length).toBe(2); + expect(dataHelper.dataSourceMap.ds1).toBeUndefined(); + + updatedConfig = { + list: [ + { + id: 'ds2', + }, + { + id: 'fullConfigGet', + }, + { + id: 'ds3', + }, + ] + }; + dataHelper.updateConfig(updatedConfig); + expect(dataHelper.ajaxList.length).toBe(3); + expect(dataHelper.dataSourceMap.ds3).toBeTruthy(); + }); + + it('getInitData should work', () => { + const mockHost = { stateA: 'aValue'}; + const mockDataSourceConfig = { + list: [ + { + id: 'ds1', + }, { + id: 'ds2', + }, + { + id: 'fullConfigGet', + isInit: true, + type: 'fetch', + options: { + params: {}, + method: 'GET', + isCors: true, + timeout: 5000, + headers: { + headerA: 1, + }, + uri: 'mock/info.json', + }, + shouldFetch: { + type: 'JSFunction', + value: 'function() { return true; }', + }, + dataHandler: { + type: 'JSFunction', + value: 'function(res) { return 123; }', + }, + errorHandler: { + type: 'JSFunction', + value: 'function(error) {}', + }, + willFetch: { + type: 'JSFunction', + value: 'function(options) { return options; }', + }, + }, + ] + }; + const mockAppHelper = {}; + const mockParser = (config: any) => parseData(config); + const dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser); + + expect(dataHelper.ajaxList.length).toBe(3); + expect(mockGet).toBeCalledTimes(0); + dataHelper.getInitData().then(res => { + expect(mockGet).toBeCalledTimes(1); + expect(mockGet).toBeCalledWith('mock/info.json', {}, { + headerA: 1, + }, expect.anything()); + mockGet.mockClear(); + }); + }); + + it('getDataSource should work', () => { + const mockHost = { stateA: 'aValue'}; + const mockDataSourceConfig = { + list: [ + { + id: 'ds1', + }, { + id: 'ds2', + }, + { + id: 'fullConfigGet', + isInit: true, + type: 'fetch', + options: { + params: {}, + method: 'GET', + isCors: true, + timeout: 5000, + headers: { + headerA: 1, + }, + uri: 'mock/info.json', + }, + shouldFetch: { + type: 'JSFunction', + value: 'function() { return true; }', + }, + dataHandler: { + type: 'JSFunction', + value: 'function(res) { return 123; }', + }, + errorHandler: { + type: 'JSFunction', + value: 'function(error) {}', + }, + willFetch: { + type: 'JSFunction', + value: 'function(options) { return options; }', + }, + }, + ] + }; + const mockAppHelper = {}; + const mockParser = (config: any) => parseData(config); + const dataHelper = new DataHelper(mockHost, mockDataSourceConfig, mockAppHelper, mockParser); + + expect(dataHelper.ajaxList.length).toBe(3); + expect(mockGet).toBeCalledTimes(0); + const callbackFn = jest.fn(); + dataHelper.getDataSource('fullConfigGet', { param1: 'value1' }, {}, callbackFn).then(res => { + expect(mockGet).toBeCalledTimes(1); + expect(mockGet).toBeCalledWith('mock/info.json', { param1: 'value1' }, { + headerA: 1, + }, expect.anything()); + mockGet.mockClear(); + expect(callbackFn).toBeCalledTimes(1); + }); + }); +}); From 30267cb173fca2cd80a61450b9f2fe2bceac0f06 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Fri, 27 May 2022 10:53:50 +0800 Subject: [PATCH 018/823] feat: return unbind function for onChangeDetecting & onChangeSelection --- packages/shell/src/document-model.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/shell/src/document-model.ts b/packages/shell/src/document-model.ts index c5610fcb56..7d9afc16c5 100644 --- a/packages/shell/src/document-model.ts +++ b/packages/shell/src/document-model.ts @@ -204,7 +204,7 @@ export default class DocumentModel { * 当前 document 的 hover 变更事件 */ onChangeDetecting(fn: (node: Node) => void) { - this[documentSymbol].designer.detecting.onDetectingChange((node: InnerNode) => { + return this[documentSymbol].designer.detecting.onDetectingChange((node: InnerNode) => { fn(Node.create(node)!); }); } @@ -213,7 +213,7 @@ export default class DocumentModel { * 当前 document 的选中变更事件 */ onChangeSelection(fn: (ids: string[]) => void) { - this[documentSymbol].selection.onSelectionChange((ids: string[]) => { + return this[documentSymbol].selection.onSelectionChange((ids: string[]) => { fn(ids); }); } From 5ea53f706b6571946bcfa56b8655b55717381771 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Fri, 27 May 2022 10:47:40 +0800 Subject: [PATCH 019/823] fix: use the original object if it is not a shell object --- packages/shell/src/document-model.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/shell/src/document-model.ts b/packages/shell/src/document-model.ts index 7d9afc16c5..cf9a41eee6 100644 --- a/packages/shell/src/document-model.ts +++ b/packages/shell/src/document-model.ts @@ -157,8 +157,8 @@ export default class DocumentModel { copy?: boolean | undefined, ) { const node = this[documentSymbol].insertNode( - parent[nodeSymbol] as any, - thing?.[nodeSymbol], + parent[nodeSymbol] ? parent[nodeSymbol] : parent, + thing?.[nodeSymbol] ? thing[nodeSymbol] : thing, at, copy, ); From d16bbc32877c31ab352a372a19d2a6224b9d7c18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Fri, 27 May 2022 10:25:30 +0800 Subject: [PATCH 020/823] refactor: using a more semver-like prerelease version format --- packages/designer/src/plugin/plugin-manager.ts | 4 +++- packages/engine/build.plugin.js | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/designer/src/plugin/plugin-manager.ts b/packages/designer/src/plugin/plugin-manager.ts index f0b45f2cfe..e90b51cfe1 100644 --- a/packages/designer/src/plugin/plugin-manager.ts +++ b/packages/designer/src/plugin/plugin-manager.ts @@ -40,7 +40,9 @@ export class LowCodePluginManager implements ILowCodePluginManager { isEngineVersionMatched(versionExp: string): boolean { const engineVersion = engineConfig.get('ENGINE_VERSION'); - return semverSatisfies(engineVersion, versionExp); + // ref: https://github.com/npm/node-semver#functions + // 1.0.1-beta should match '^1.0.0' + return semverSatisfies(engineVersion, versionExp, { includePrerelease: true }); } /** diff --git a/packages/engine/build.plugin.js b/packages/engine/build.plugin.js index 0f7f403aef..4b9ca04585 100644 --- a/packages/engine/build.plugin.js +++ b/packages/engine/build.plugin.js @@ -17,7 +17,7 @@ function getVersion() { const [_, version, beta] = match; - return beta && beta.endsWith('beta') ? `${version}(beta)` : version; + return beta && beta.endsWith('beta') ? `${version}-beta` : version; } const releaseVersion = getVersion(); From 941ae0592586334694c48197aaa6692d49cefbce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Thu, 26 May 2022 14:54:41 +0800 Subject: [PATCH 021/823] feat: add id setter for DocumentModel --- packages/shell/src/document-model.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/shell/src/document-model.ts b/packages/shell/src/document-model.ts index cf9a41eee6..100d2c33b3 100644 --- a/packages/shell/src/document-model.ts +++ b/packages/shell/src/document-model.ts @@ -68,6 +68,10 @@ export default class DocumentModel { return this[documentSymbol].id; } + set id(id) { + this[documentSymbol].id = id; + } + /** * 获取当前文档所属的 project * @returns From de1f60bbee157267e2c2212df1077cc49ce506f4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Wed, 25 May 2022 19:58:36 +0800 Subject: [PATCH 022/823] feat: add availableActions for ComponentMeta --- packages/shell/src/component-meta.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/shell/src/component-meta.ts b/packages/shell/src/component-meta.ts index 8cf9a570e3..e7752f6858 100644 --- a/packages/shell/src/component-meta.ts +++ b/packages/shell/src/component-meta.ts @@ -84,6 +84,10 @@ export default class ComponentMeta { return this[componentMetaSymbol].prototype; } + get availableActions() { + return this[componentMetaSymbol].availableActions; + } + /** * 设置 npm 信息 * @param npm From 2f8b9545de0210260001a832b52f608238ac4191 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Mon, 23 May 2022 14:12:47 +0800 Subject: [PATCH 023/823] feat: add componentMeta getter for setingPropEntry --- packages/shell/src/setting-prop-entry.ts | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/packages/shell/src/setting-prop-entry.ts b/packages/shell/src/setting-prop-entry.ts index 7449e7bc2a..2414b66f55 100644 --- a/packages/shell/src/setting-prop-entry.ts +++ b/packages/shell/src/setting-prop-entry.ts @@ -3,6 +3,7 @@ import { CompositeValue, FieldConfig } from '@alilc/lowcode-types'; import { settingPropEntrySymbol } from './symbols'; import Node from './node'; import SettingTopEntry from './setting-top-entry'; +import ComponentMeta from './component-meta'; export default class SettingPropEntry { private readonly [settingPropEntrySymbol]: SettingField; @@ -89,6 +90,13 @@ export default class SettingPropEntry { return this[settingPropEntrySymbol].isSettingField; } + /** + * componentMeta + */ + get componentMeta(): ComponentMeta | null { + return ComponentMeta.create(this[settingPropEntrySymbol].componentMeta); + } + /** * 设置 key 值 * @param key From d9a44c5de7861e9180567b4afb787e381cefac61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Fri, 20 May 2022 14:19:13 +0800 Subject: [PATCH 024/823] feat: add slotNode for shell prop --- packages/shell/src/prop.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/shell/src/prop.ts b/packages/shell/src/prop.ts index 9d5f42cb5f..aba59ca731 100644 --- a/packages/shell/src/prop.ts +++ b/packages/shell/src/prop.ts @@ -43,6 +43,13 @@ export default class Prop { return Node.create(this[propSymbol].getNode()); } + /** + * return the slot node (only if the current prop represents a slot) + */ + get slotNode(): Node | null { + return Node.create(this[propSymbol].slotNode); + } + /** * judge if it is a prop or not */ From ac881145cfc8b194173565e4f0ad11197bcd5340 Mon Sep 17 00:00:00 2001 From: blueju <49681036+blueju@users.noreply.github.com> Date: Wed, 1 Jun 2022 13:55:22 +0800 Subject: [PATCH 025/823] =?UTF-8?q?chore:=20npm=20run=20setup=20=E5=92=8C?= =?UTF-8?q?=20npm=20run=20start=20=E5=91=BD=E4=BB=A4=E9=80=82=E9=85=8D=20w?= =?UTF-8?q?in=20=E7=B3=BB=E7=BB=9F=20(#574)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * chore: npm run setup & npm run start 命令适配 win 系统 * chore: 补上漏掉的 await * chore: 参考 antfu 大神的轮子 ni 源码,改用更为知名的命令行库 * chore: npm run start 命令适配 win 系统 * chore: 调整样式 --- package.json | 7 +++++-- scripts/setup.js | 26 ++++++++++++++++++++++++++ scripts/start.js | 10 ++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 scripts/setup.js create mode 100644 scripts/start.js diff --git a/package.json b/package.json index 72ddd3ca62..90c099d156 100644 --- a/package.json +++ b/package.json @@ -22,10 +22,10 @@ "pub:premajor": "npm run watchdog:build && lerna publish premajor --force-publish --exact --dist-tag beta --preid beta --no-changelog", "pub:prepatch": "npm run watchdog:build && lerna publish prepatch --force-publish --exact --dist-tag beta --preid beta --no-changelog", "pub:prerelease": "npm run watchdog:build && lerna publish prerelease --force-publish --exact --dist-tag beta --preid beta --no-changelog", - "setup": "./scripts/setup.sh", + "setup": "node ./scripts/setup.js", "setup:test": "./scripts/setup-for-test.sh", "setup:skip-build": "./scripts/setup-skip-build.sh", - "start": "./scripts/start.sh", + "start": "node ./scripts/start.js", "test": "lerna run test --stream", "test:snapshot": "lerna run test:snapshot", "watchdog:build": "node ./scripts/watchdog.js", @@ -38,7 +38,10 @@ } }, "devDependencies": { + "del": "^6.1.1", + "execa": "^5.1.1", "f2elint": "^2.0.1", + "gulp": "^4.0.2", "husky": "^7.0.4", "lerna": "^4.0.0", "typescript": "^4.5.5", diff --git a/scripts/setup.js b/scripts/setup.js new file mode 100644 index 0000000000..77da2291f4 --- /dev/null +++ b/scripts/setup.js @@ -0,0 +1,26 @@ +#!/usr/bin/env node +const os = require('os'); +const del = require('del'); +const gulp = require('gulp'); +const execa = require('execa'); + +async function deleteRootDirLockFile() { + await del('package-lock.json'); + await del('yarn.lock'); +} + +async function clean() { + await execa.command('lerna clean -y', { stdio: 'inherit', encoding: 'utf-8' }); +} + +async function deletePackagesDirLockFile() { + await del('packages/**/package-lock.json'); +} + +async function bootstrap() { + await execa.command('lerna bootstrap --force-local', { stdio: 'inherit', encoding: 'utf-8' }); +} + +const setup = gulp.series(deleteRootDirLockFile, clean, deletePackagesDirLockFile, bootstrap); + +os.type() === 'Windows_NT' ? setup() : execa.command('scripts/setup.sh', { stdio: 'inherit', encoding: 'utf-8' }); \ No newline at end of file diff --git a/scripts/start.js b/scripts/start.js new file mode 100644 index 0000000000..e1a83ea732 --- /dev/null +++ b/scripts/start.js @@ -0,0 +1,10 @@ +#!/usr/bin/env node +const os = require('os'); +const execa = require('execa'); + +async function start() { + const [, , pkgName = '@alilc/lowcode-ignitor'] = process.argv; + await execa.command(`lerna exec --scope ${pkgName} -- npm start`, { stdio: 'inherit', encoding: 'utf-8' }); +} + +os.type() === 'Windows_NT' ? start() : execa.command('scripts/start.sh', { stdio: 'inherit', encoding: 'utf-8' }); From 44ad744aac174f80e06c122a2189f0be75c24e49 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Wed, 1 Jun 2022 14:17:40 +0800 Subject: [PATCH 026/823] chore(release): publish 1.0.9 --- lerna.json | 2 +- packages/designer/package.json | 10 +++++----- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 16 ++++++++-------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 10 +++++----- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 12 ++++++------ packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- 16 files changed, 60 insertions(+), 60 deletions(-) diff --git a/lerna.json b/lerna.json index a135fb25c6..1adf2a89c7 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.0.8", + "version": "1.0.9", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index a0f52eac8b..8838691450 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.0.8", + "version": "1.0.9", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,10 +15,10 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.0.8", - "@alilc/lowcode-shell": "1.0.8", - "@alilc/lowcode-types": "1.0.8", - "@alilc/lowcode-utils": "1.0.8", + "@alilc/lowcode-editor-core": "1.0.9", + "@alilc/lowcode-shell": "1.0.9", + "@alilc/lowcode-types": "1.0.9", + "@alilc/lowcode-utils": "1.0.9", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 0688c71cbf..e5e5cc6216 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.0.8", + "version": "1.0.9", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.0.8", - "@alilc/lowcode-utils": "1.0.8", + "@alilc/lowcode-types": "1.0.9", + "@alilc/lowcode-utils": "1.0.9", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 0f59991324..439169c20e 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.0.8", + "version": "1.0.9", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -18,10 +18,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.0.8", - "@alilc/lowcode-editor-core": "1.0.8", - "@alilc/lowcode-types": "1.0.8", - "@alilc/lowcode-utils": "1.0.8", + "@alilc/lowcode-designer": "1.0.9", + "@alilc/lowcode-editor-core": "1.0.9", + "@alilc/lowcode-types": "1.0.9", + "@alilc/lowcode-utils": "1.0.9", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index d4c990d95f..2d20c7b137 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.0.8", + "version": "1.0.9", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,14 +19,14 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.0.8", - "@alilc/lowcode-editor-core": "1.0.8", - "@alilc/lowcode-editor-skeleton": "1.0.8", + "@alilc/lowcode-designer": "1.0.9", + "@alilc/lowcode-editor-core": "1.0.9", + "@alilc/lowcode-editor-skeleton": "1.0.9", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.0.8", - "@alilc/lowcode-plugin-outline-pane": "1.0.8", - "@alilc/lowcode-shell": "1.0.8", - "@alilc/lowcode-utils": "1.0.8", + "@alilc/lowcode-plugin-designer": "1.0.9", + "@alilc/lowcode-plugin-outline-pane": "1.0.9", + "@alilc/lowcode-shell": "1.0.9", + "@alilc/lowcode-utils": "1.0.9", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index 025648248c..1da40fc406 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.0.8", + "version": "1.0.9", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index b3480fcd05..baf0dea6f3 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.0.8", + "version": "1.0.9", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.0.8", - "@alilc/lowcode-editor-core": "1.0.8", - "@alilc/lowcode-utils": "1.0.8", + "@alilc/lowcode-designer": "1.0.9", + "@alilc/lowcode-editor-core": "1.0.9", + "@alilc/lowcode-utils": "1.0.9", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index 0ead7898c6..cc10435c58 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.0.8", + "version": "1.0.9", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,10 +13,10 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-designer": "1.0.8", - "@alilc/lowcode-editor-core": "1.0.8", - "@alilc/lowcode-types": "1.0.8", - "@alilc/lowcode-utils": "1.0.8", + "@alilc/lowcode-designer": "1.0.9", + "@alilc/lowcode-editor-core": "1.0.9", + "@alilc/lowcode-types": "1.0.9", + "@alilc/lowcode-utils": "1.0.9", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0" diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index f370b29142..2fa2b93a7f 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.0.8", + "version": "1.0.9", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.0.8", - "@alilc/lowcode-utils": "1.0.8", + "@alilc/lowcode-renderer-core": "1.0.9", + "@alilc/lowcode-utils": "1.0.9", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index 46fef1fb36..ede4c41154 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.0.8", + "version": "1.0.9", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.0.8", - "@alilc/lowcode-rax-renderer": "1.0.8", - "@alilc/lowcode-types": "1.0.8", - "@alilc/lowcode-utils": "1.0.8", + "@alilc/lowcode-designer": "1.0.9", + "@alilc/lowcode-rax-renderer": "1.0.9", + "@alilc/lowcode-types": "1.0.9", + "@alilc/lowcode-utils": "1.0.9", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index a4425a5cba..d89616e1e5 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.0.8", + "version": "1.0.9", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.0.8" + "@alilc/lowcode-renderer-core": "1.0.9" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index b14e99452d..b3158951b8 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.0.8", + "version": "1.0.9", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -16,10 +16,10 @@ "build:umd": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.0.8", - "@alilc/lowcode-react-renderer": "1.0.8", - "@alilc/lowcode-types": "1.0.8", - "@alilc/lowcode-utils": "1.0.8", + "@alilc/lowcode-designer": "1.0.9", + "@alilc/lowcode-react-renderer": "1.0.9", + "@alilc/lowcode-types": "1.0.9", + "@alilc/lowcode-utils": "1.0.9", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 70b0b3e6ac..0967dba562 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.0.8", + "version": "1.0.9", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.0.8", - "@alilc/lowcode-utils": "1.0.8", + "@alilc/lowcode-types": "1.0.9", + "@alilc/lowcode-utils": "1.0.9", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -34,7 +34,7 @@ }, "devDependencies": { "@alib/build-scripts": "^0.1.18", - "@alilc/lowcode-designer": "1.0.8", + "@alilc/lowcode-designer": "1.0.9", "@alilc/lowcode-test-mate": "^1.0.1", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", diff --git a/packages/shell/package.json b/packages/shell/package.json index 3ce1c58703..df9544bafc 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.0.8", + "version": "1.0.9", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.0.8", - "@alilc/lowcode-editor-core": "1.0.8", - "@alilc/lowcode-editor-skeleton": "1.0.8", - "@alilc/lowcode-types": "1.0.8", - "@alilc/lowcode-utils": "1.0.8", + "@alilc/lowcode-designer": "1.0.9", + "@alilc/lowcode-editor-core": "1.0.9", + "@alilc/lowcode-editor-skeleton": "1.0.9", + "@alilc/lowcode-types": "1.0.9", + "@alilc/lowcode-utils": "1.0.9", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index 3dce35e26e..25d6687c52 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.0.8", + "version": "1.0.9", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index a20bcb0f9b..e3804575ee 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.0.8", + "version": "1.0.9", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.0.8", + "@alilc/lowcode-types": "1.0.9", "lodash": "^4.17.21", "react": "^16", "zen-logger": "^1.1.0" From 7eecb39c97b30416228f204c20cba55d67419870 Mon Sep 17 00:00:00 2001 From: JackLian Date: Wed, 1 Jun 2022 20:06:31 +0800 Subject: [PATCH 027/823] test: add ut file and fix some obvious lint issues --- packages/renderer-core/src/utils/request.ts | 100 +++++++++++++----- .../renderer-core/tests/utils/request.test.ts | 32 ++++++ 2 files changed, 108 insertions(+), 24 deletions(-) create mode 100644 packages/renderer-core/tests/utils/request.test.ts diff --git a/packages/renderer-core/src/utils/request.ts b/packages/renderer-core/src/utils/request.ts index 9a88068c28..1af8655e06 100644 --- a/packages/renderer-core/src/utils/request.ts +++ b/packages/renderer-core/src/utils/request.ts @@ -2,7 +2,15 @@ import 'whatwg-fetch'; import fetchJsonp from 'fetch-jsonp'; import { serializeParams } from '.'; -function buildUrl(dataAPI: any, params: any) { +/** + * this is a private method, export for testing purposes only. + * + * @export + * @param {*} dataAPI + * @param {*} params + * @returns + */ +export function buildUrl(dataAPI: any, params: any) { const paramStr = serializeParams(params); if (paramStr) { return dataAPI.indexOf('?') > 0 ? `${dataAPI}&${paramStr}` : `${dataAPI}?${paramStr}`; @@ -10,43 +18,75 @@ function buildUrl(dataAPI: any, params: any) { return dataAPI; } -export function get(dataAPI: any, params = {}, headers = {}, otherProps = {}) { - headers = { +/** + * do Get request + * + * @export + * @param {*} dataAPI + * @param {*} [params={}] + * @param {*} [headers={}] + * @param {*} [otherProps={}] + * @returns + */ + export function get(dataAPI: any, params = {}, headers = {}, otherProps = {}) { + const processedHeaders = { Accept: 'application/json', ...headers, }; - dataAPI = buildUrl(dataAPI, params); - return request(dataAPI, 'GET', null, headers, otherProps); + const url = buildUrl(dataAPI, params); + return request(url, 'GET', null, processedHeaders, otherProps); } +/** + * do Post request + * + * @export + * @param {*} dataAPI + * @param {*} [params={}] + * @param {*} [headers={}] + * @param {*} [otherProps={}] + * @returns + */ export function post(dataAPI: any, params = {}, headers: any = {}, otherProps = {}) { - headers = { + const processedHeaders = { Accept: 'application/json', 'Content-Type': 'application/x-www-form-urlencoded', ...headers, }; + const body = processedHeaders['Content-Type'].indexOf('application/json') > -1 || Array.isArray(params) + ? JSON.stringify(params) + : serializeParams(params); + return request( dataAPI, 'POST', - headers['Content-Type'].indexOf('application/json') > -1 || Array.isArray(params) - ? JSON.stringify(params) - : serializeParams(params), - headers, + body, + processedHeaders, otherProps, ); } +/** + * do request + * + * @export + * @param {*} dataAPI + * @param {string} [method='GET'] + * @param {*} data + * @param {*} [headers={}] + * @param {*} [otherProps={}] + * @returns + */ export function request(dataAPI: any, method = 'GET', data: any, headers = {}, otherProps: any = {}) { - switch (method) { - case 'PUT': - case 'DELETE': - headers = { - Accept: 'application/json', - 'Content-Type': 'application/json', - ...headers, - }; - data = JSON.stringify(data || {}); - break; + let processedHeaders = headers || {}; + let payload = data; + if (method === 'PUT' || method === 'DELETE') { + processedHeaders = { + Accept: 'application/json', + 'Content-Type': 'application/json', + ...processedHeaders, + }; + payload = JSON.stringify(payload || {}); } return new Promise((resolve, reject) => { if (otherProps.timeout) { @@ -57,8 +97,8 @@ export function request(dataAPI: any, method = 'GET', data: any, headers = {}, o fetch(dataAPI, { method, credentials: 'include', - headers, - body: data, + headers: processedHeaders, + body: payload, ...otherProps, }) .then((response) => { @@ -101,6 +141,7 @@ export function request(dataAPI: any, method = 'GET', data: any, headers = {}, o code: response.status, }; }); + default: } return null; }) @@ -108,6 +149,7 @@ export function request(dataAPI: any, method = 'GET', data: any, headers = {}, o if (json && json.__success !== false) { resolve(json); } else { + // eslint-disable-next-line no-param-reassign delete json.__success; reject(json); } @@ -118,13 +160,23 @@ export function request(dataAPI: any, method = 'GET', data: any, headers = {}, o }); } +/** + * do jsonp request + * + * @export + * @param {*} dataAPI + * @param {*} [params={}] + * @param {*} [otherProps={}] + * @returns + */ export function jsonp(dataAPI: any, params = {}, otherProps = {}) { return new Promise((resolve, reject) => { - otherProps = { + const processedOtherProps = { timeout: 5000, ...otherProps, }; - fetchJsonp(buildUrl(dataAPI, params), otherProps) + const url = buildUrl(dataAPI, params); + fetchJsonp(url, processedOtherProps) .then((response) => response.json()) .then((json) => { if (json) { diff --git a/packages/renderer-core/tests/utils/request.test.ts b/packages/renderer-core/tests/utils/request.test.ts new file mode 100644 index 0000000000..ad1187ddae --- /dev/null +++ b/packages/renderer-core/tests/utils/request.test.ts @@ -0,0 +1,32 @@ +// @ts-nocheck +const mockSerializeParams = jest.fn(); +jest.mock('../../src/utils/common', () => { + return { + serializeParams: (params) => { + return mockSerializeParams(params); + }, + }; + }); + + +import { get, post, buildUrl, request, jsonp } from '../../src/utils/request'; + +describe('test utils/request.ts ', () => { + beforeEach(() => { + }) + it('buildUrl should be working properly', () => { + mockSerializeParams.mockImplementation((params) => { + return 'serializedParams=serializedParams'; + }); + expect(buildUrl('mockDataApi', { a: 1, b: 'a', c: []})).toBe('mockDataApi?serializedParams=serializedParams'); + expect(buildUrl('mockDataApi?existingParamA=valueA', { a: 1, b: 'a', c: []})).toBe('mockDataApi?existingParamA=valueA&serializedParams=serializedParams'); + mockSerializeParams.mockClear(); + + mockSerializeParams.mockImplementation((params) => { + return undefined; + }); + expect(buildUrl('mockDataApi', { a: 1, b: 'a', c: []})).toBe('mockDataApi'); + mockSerializeParams.mockClear(); + }); + +}); From 031c7f25f10a6cfebfc7929c9226f4e4167a359f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Wed, 1 Jun 2022 16:42:53 +0800 Subject: [PATCH 028/823] fix: fix outline-pane invisible occasionally when dragging tree node --- packages/editor-skeleton/src/layouts/left-float-pane.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/editor-skeleton/src/layouts/left-float-pane.tsx b/packages/editor-skeleton/src/layouts/left-float-pane.tsx index aa8bd7e275..dbfd07e3b1 100644 --- a/packages/editor-skeleton/src/layouts/left-float-pane.tsx +++ b/packages/editor-skeleton/src/layouts/left-float-pane.tsx @@ -16,6 +16,8 @@ export default class LeftFloatPane extends Component<{ area: Area }> const { area } = this.props; const triggerClose = (e: any) => { if (!area.visible) return; + // 当 MouseEvent 的 target 为「插入占位符」时,不关闭当前 panel + if (e.originalEvent?.target?.classList.contains('insertion')) return; // 假如当前操作 target 祖先节点中有属性 data-keep-visible-while-dragging="true" 代表该 target 所属 panel // 不希望 target 在 panel 范围内拖拽时关闭 panel const panelElem = e.originalEvent?.target.closest('div[data-keep-visible-while-dragging="true"]'); From f9566454ef83eb4c48b68d63a766c3d0ff927c73 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Tue, 7 Jun 2022 11:03:23 +0800 Subject: [PATCH 029/823] feat: add getComponentsMap() for DocumentModel --- packages/shell/src/document-model.ts | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/packages/shell/src/document-model.ts b/packages/shell/src/document-model.ts index 100d2c33b3..741eb08f9b 100644 --- a/packages/shell/src/document-model.ts +++ b/packages/shell/src/document-model.ts @@ -186,6 +186,15 @@ export default class DocumentModel { this[documentSymbol].removeNode(idOrNode as any); } + /** + * componentsMap of documentModel + * @param extraComps + * @returns + */ + getComponentsMap(extraComps?: string[]) { + return this[documentSymbol].getComponentsMap(extraComps); + } + /** * 当前 document 新增节点事件 */ From 00c2d5ec51e26fcf2976c6722b2331ea67c28456 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Tue, 7 Jun 2022 11:04:12 +0800 Subject: [PATCH 030/823] chore: delete node version limitation --- packages/engine/README-zh_CN.md | 2 -- packages/engine/README.md | 2 -- 2 files changed, 4 deletions(-) diff --git a/packages/engine/README-zh_CN.md b/packages/engine/README-zh_CN.md index 9f8aa964d9..089ffb2288 100644 --- a/packages/engine/README-zh_CN.md +++ b/packages/engine/README-zh_CN.md @@ -139,8 +139,6 @@ $ npm start > 📢 npm 访问速度较慢,阿里员工可以使用 tnpm,其他同学建议使用 cnpm 或者指定镜像 registry。 > -> 📢 node 版本限定在 14 -> > 📢 windows 环境必须使用 [WSL](https://docs.microsoft.com/zh-cn/windows/wsl/install),其他终端不保证能正常运行 lowcode-engine 启动后,提供了几个 umd 文件,可以结合 [lowcode-demo](https://github.com/alibaba/lowcode-demo) 项目做调试,文件代理规则参考[这里](https://www.yuque.com/lce/doc/glz0fx)。 diff --git a/packages/engine/README.md b/packages/engine/README.md index 6d13ad1667..627fbf6381 100644 --- a/packages/engine/README.md +++ b/packages/engine/README.md @@ -139,8 +139,6 @@ $ npm start > 📢 npm access speed is slow, Alibaba employees can use tnpm, other students recommend using cnpm or specifying a mirror registry. > -> 📢 node version limited to 14 -> > 📢 Windows environment must use [WSL](https://docs.microsoft.com/en-us/windows/wsl/install), other terminals are not guaranteed to work normally After lowcode-engine is started, several umd files are provided, which can be debugged in combination with the [lowcode-demo](https://github.com/alibaba/lowcode-demo) project. Refer to the file proxy rules [here](https://www.yuque.com/lce/doc/glz0fx). From dcc247c7d54f6af2ed36d46bfd79c7eacf7bd604 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Tue, 7 Jun 2022 11:19:25 +0800 Subject: [PATCH 031/823] feat: add onMountNode event for DocumentModel --- packages/shell/src/document-model.ts | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/packages/shell/src/document-model.ts b/packages/shell/src/document-model.ts index 741eb08f9b..3177f3b691 100644 --- a/packages/shell/src/document-model.ts +++ b/packages/shell/src/document-model.ts @@ -204,6 +204,16 @@ export default class DocumentModel { }); } + /** + * 当前 document 新增节点事件,此时节点已经挂载到 document 上 + */ + onMountNode(fn: (node: Node) => void) { + this[editorSymbol].on('node.add', fn as any); + return () => { + this[editorSymbol].off('node.add', fn as any); + }; + } + /** * 当前 document 删除节点事件 */ From 988719d72f979b7a3dda4789917b8bd53a56c1bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Tue, 7 Jun 2022 17:05:46 +0800 Subject: [PATCH 032/823] chore: support branch name format like 'release/1.0.0-beta.0' --- packages/engine/build.plugin.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/packages/engine/build.plugin.js b/packages/engine/build.plugin.js index 4b9ca04585..5c4ab7bfbb 100644 --- a/packages/engine/build.plugin.js +++ b/packages/engine/build.plugin.js @@ -5,9 +5,10 @@ const fse = require('fs-extra'); // get version from git branch name, // e.g. release/1.0.7 => 1.0.7 // release/1.0.7-beta => 1.0.7 (beta) +// release/1.0.7-beta.0 => 1.0.7 (beta) function getVersion() { const gitBranchName = execSync('git rev-parse --abbrev-ref HEAD', { encoding: 'utf-8' }); - const reBranchVersion = /^(?:[\w-]+\/)(\d+\.\d+\.\d+)(-?beta)?$/im; + const reBranchVersion = /^(?:[\w-]+\/)(\d+\.\d+\.\d+)(-?beta)?(?:\.\d+)?$/im; const match = reBranchVersion.exec(gitBranchName); if (!match) { From 0735f1ca76e87e69620cf2251a51c5dbbcb91de8 Mon Sep 17 00:00:00 2001 From: JackLian Date: Tue, 7 Jun 2022 16:34:34 +0800 Subject: [PATCH 033/823] test: add ut for renderer-core/utils/request --- packages/renderer-core/src/utils/request.ts | 10 +- .../renderer-core/tests/utils/request.test.ts | 133 +++++++++++++++++- 2 files changed, 138 insertions(+), 5 deletions(-) diff --git a/packages/renderer-core/src/utils/request.ts b/packages/renderer-core/src/utils/request.ts index 1af8655e06..dde5ca87e9 100644 --- a/packages/renderer-core/src/utils/request.ts +++ b/packages/renderer-core/src/utils/request.ts @@ -146,7 +146,11 @@ export function request(dataAPI: any, method = 'GET', data: any, headers = {}, o return null; }) .then((json) => { - if (json && json.__success !== false) { + if (!json) { + reject(json); + return; + } + if (json.__success !== false) { resolve(json); } else { // eslint-disable-next-line no-param-reassign @@ -177,7 +181,9 @@ export function jsonp(dataAPI: any, params = {}, otherProps = {}) { }; const url = buildUrl(dataAPI, params); fetchJsonp(url, processedOtherProps) - .then((response) => response.json()) + .then((response) => { + response.json(); + }) .then((json) => { if (json) { resolve(json); diff --git a/packages/renderer-core/tests/utils/request.test.ts b/packages/renderer-core/tests/utils/request.test.ts index ad1187ddae..d0bfeb5aaa 100644 --- a/packages/renderer-core/tests/utils/request.test.ts +++ b/packages/renderer-core/tests/utils/request.test.ts @@ -7,13 +7,24 @@ jest.mock('../../src/utils/common', () => { }, }; }); - +const mockFetchJsonp = jest.fn(); +jest.mock('fetch-jsonp', () => { + return (uri, otherProps) => { + mockFetchJsonp(uri, otherProps); + return Promise.resolve({ + json: () => { + return Promise.resolve({ data: [1, 2, 3]}); + } , + ok: true, + }); + } +}); import { get, post, buildUrl, request, jsonp } from '../../src/utils/request'; + describe('test utils/request.ts ', () => { - beforeEach(() => { - }) + it('buildUrl should be working properly', () => { mockSerializeParams.mockImplementation((params) => { return 'serializedParams=serializedParams'; @@ -29,4 +40,120 @@ describe('test utils/request.ts ', () => { mockSerializeParams.mockClear(); }); + it('request should be working properly', () => { + const fetchMock = jest + .spyOn(global, 'fetch') + .mockImplementation(() => + Promise.resolve({ + json: () => Promise.resolve([]) , + status: 200, + }) + ); + + request('https://someradomurl/api/list', 'GET', {}, {}, {}).then((response) => { + expect(fetchMock).toBeCalledWith('https://someradomurl/api/list', { body: {}, credentials: 'include', headers: {}, method: 'GET'}); + }).catch((error) => { + console.error(error); + }); + + }); + + it('get should be working properly', () => { + const fetchMock = jest + .spyOn(global, 'fetch') + .mockImplementation(() => + Promise.resolve({ + json: () => Promise.resolve([]) , + status: 200, + }) + ); + + get('https://someradomurl/api/list', {}, {}, {}).then((response) => { + expect(fetchMock).toBeCalledWith( + 'https://someradomurl/api/list', + { + body: null, + headers: { Accept: 'application/json' }, + method: 'GET', + credentials: 'include', + }); + }).catch((error) => { + console.error(error); + }); + + }); + + it('post should be working properly', () => { + const fetchMock = jest + .spyOn(global, 'fetch') + .mockImplementation(() => + Promise.resolve({ + json: () => Promise.resolve([]) , + status: 200, + }) + ); + + post('https://someradomurl/api/list', { a: 1, b: 'a', c: [] }, { 'Content-Type': 'application/json' }, {}).then((response) => { + expect(fetchMock).toBeCalledWith( + 'https://someradomurl/api/list', + { + body: '{"a":1,"b":"a","c":[]}', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/json', + }, + method: 'POST', + credentials: 'include', + }); + }).catch((error) => { + console.error(error); + }); + + + post('https://someradomurl/api/list', [ 1, 2, 3, 4 ], {}, {}).then((response) => { + expect(fetchMock).toBeCalledWith( + 'https://someradomurl/api/list', + { + body: '[1,2,3,4]', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/x-www-form-urlencoded', + }, + method: 'POST', + credentials: 'include', + }); + }).catch((error) => { + console.error(error); + }); + + mockSerializeParams.mockImplementation((params) => { + return 'serializedParams=serializedParams'; + }); + post('https://someradomurl/api/list', { a: 1, b: 'a', c: [] }, {}, {}).then((response) => { + expect(fetchMock).toBeCalledWith( + 'https://someradomurl/api/list', + { + body: 'serializedParams=serializedParams', + headers: { + Accept: 'application/json', + 'Content-Type': 'application/x-www-form-urlencoded', + }, + method: 'POST', + credentials: 'include', + }); + mockSerializeParams.mockClear(); + }).catch((error) => { + console.error(error); + }); + + }); + it('jsonp should be working properly', () => { + mockSerializeParams.mockImplementation((params) => { + return 'params'; + }); + jsonp('https://someradomurl/api/list', {}, { otherParam1: '123'}).catch(() => { + expect(mockFetchJsonp).toBeCalledWith('https://someradomurl/api/list?params', { timeout: 5000, otherParam1: '123' }); + mockSerializeParams.mockClear(); + }); + }); }); From 7b76ff357e4e638454c31a9b1324fb68966ec522 Mon Sep 17 00:00:00 2001 From: zyy7259 Date: Wed, 8 Jun 2022 11:38:44 +0800 Subject: [PATCH 034/823] feat: add isGroup & items to shell SettingPropEntry --- packages/shell/src/setting-prop-entry.ts | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/packages/shell/src/setting-prop-entry.ts b/packages/shell/src/setting-prop-entry.ts index 2414b66f55..98b2ba059b 100644 --- a/packages/shell/src/setting-prop-entry.ts +++ b/packages/shell/src/setting-prop-entry.ts @@ -1,5 +1,5 @@ import { SettingField, ISetValueOptions } from '@alilc/lowcode-designer'; -import { CompositeValue, FieldConfig } from '@alilc/lowcode-types'; +import { CompositeValue, FieldConfig, CustomView, isCustomView } from '@alilc/lowcode-types'; import { settingPropEntrySymbol } from './symbols'; import Node from './node'; import SettingTopEntry from './setting-top-entry'; @@ -16,6 +16,13 @@ export default class SettingPropEntry { return new SettingPropEntry(prop); } + /** + * 获取设置属性的 isGroup + */ + get isGroup() { + return this[settingPropEntrySymbol].isGroup; + } + /** * 获取设置属性的 id */ @@ -97,6 +104,18 @@ export default class SettingPropEntry { return ComponentMeta.create(this[settingPropEntrySymbol].componentMeta); } + /** + * 获取设置属性的 items + */ + get items(): Array { + return this[settingPropEntrySymbol].items?.map((item) => { + if (isCustomView(item)) { + return item; + } + return item.internalToShellPropEntry(); + }); + } + /** * 设置 key 值 * @param key From fc5fbc63a04a32bc887754f32e74c76149d74b05 Mon Sep 17 00:00:00 2001 From: eternalsky Date: Fri, 10 Jun 2022 14:41:44 +0800 Subject: [PATCH 035/823] fix: addon-combine affect metadata unexpectedly --- packages/editor-skeleton/src/transducers/addon-combine.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor-skeleton/src/transducers/addon-combine.ts b/packages/editor-skeleton/src/transducers/addon-combine.ts index e1680e0ff5..afb9c6d5d7 100644 --- a/packages/editor-skeleton/src/transducers/addon-combine.ts +++ b/packages/editor-skeleton/src/transducers/addon-combine.ts @@ -87,7 +87,7 @@ export default function (metadata: TransformedComponentMetadata): TransformedCom }); } // 通用设置 - let propsGroup = props || []; + let propsGroup = props ? [...props] : []; const basicInfo: any = {}; if (componentName === 'Slot') { if (!configure.component) { From 16a88578634b9da2f04698df5ca5a5e69151bb97 Mon Sep 17 00:00:00 2001 From: JackLian Date: Mon, 13 Jun 2022 15:41:24 +0800 Subject: [PATCH 036/823] fix: fix misused doc urls --- packages/editor-core/src/config.ts | 2 -- packages/renderer-core/src/types/index.ts | 3 --- packages/types/src/schema.ts | 6 +++--- packages/types/src/value-type.ts | 2 +- 4 files changed, 4 insertions(+), 9 deletions(-) diff --git a/packages/editor-core/src/config.ts b/packages/editor-core/src/config.ts index 26a28e5006..fc7d5b6024 100644 --- a/packages/editor-core/src/config.ts +++ b/packages/editor-core/src/config.ts @@ -131,8 +131,6 @@ export interface EngineOptions { /** * @todo designMode 无法映射到文档渲染模块 * - * @see https://yuque.antfin.com/ali-lowcode/docs/hk2ogo#designMode - * * 设计模式,live 模式将会实时展示变量值,默认值:'design' */ designMode?: 'design' | 'live'; diff --git a/packages/renderer-core/src/types/index.ts b/packages/renderer-core/src/types/index.ts index bd0bbedbe3..b0cc9f9963 100644 --- a/packages/renderer-core/src/types/index.ts +++ b/packages/renderer-core/src/types/index.ts @@ -148,9 +148,6 @@ export interface IBaseRendererProps { __host?: BuiltinSimulatorHost; __container?: any; config?: Record; - /** - * @see https://yuque.antfin.com/ali-lowcode/docs/hk2ogo#designMode - */ designMode?: 'live' | 'design'; className?: string; style?: CSSProperties; diff --git a/packages/types/src/schema.ts b/packages/types/src/schema.ts index 75cf6bfbb1..c36a7c436b 100644 --- a/packages/types/src/schema.ts +++ b/packages/types/src/schema.ts @@ -136,7 +136,7 @@ export interface ContainerSchema extends NodeSchema { /** * 页面容器 - * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 + * @see https://lowcode-engine.cn/lowcode */ export interface PageSchema extends ContainerSchema { componentName: 'Page'; @@ -144,7 +144,7 @@ export interface PageSchema extends ContainerSchema { /** * 低代码业务组件容器 - * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 + * @see https://lowcode-engine.cn/lowcode */ export interface ComponentSchema extends ContainerSchema { componentName: 'Component'; @@ -152,7 +152,7 @@ export interface ComponentSchema extends ContainerSchema { /** * 区块容器 - * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 + * @see https://lowcode-engine.cn/lowcode */ export interface BlockSchema extends ContainerSchema { componentName: 'Block'; diff --git a/packages/types/src/value-type.ts b/packages/types/src/value-type.ts index 390133f44a..933e9a6980 100644 --- a/packages/types/src/value-type.ts +++ b/packages/types/src/value-type.ts @@ -27,7 +27,7 @@ export interface JSExpression { /** * 事件函数类型 - * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#feHTW + * @see https://lowcode-engine.cn/lowcode * * 保留与原组件属性、生命周期( React / 小程序)一致的输入参数,并给所有事件函数 binding 统一一致的上下文(当前组件所在容器结构的 this 对象) */ From 534e29429d445d97c71d95d4c4e492868527bb6b Mon Sep 17 00:00:00 2001 From: zyy7259 Date: Fri, 10 Jun 2022 17:46:37 +0800 Subject: [PATCH 037/823] feat: add expanded to shell SettingPropEntry --- packages/shell/src/setting-prop-entry.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/shell/src/setting-prop-entry.ts b/packages/shell/src/setting-prop-entry.ts index 98b2ba059b..bffff08436 100644 --- a/packages/shell/src/setting-prop-entry.ts +++ b/packages/shell/src/setting-prop-entry.ts @@ -65,6 +65,13 @@ export default class SettingPropEntry { return this[settingPropEntrySymbol].setter; } + /** + * 获取设置属性的 expanded + */ + get expanded() { + return this[settingPropEntrySymbol].expanded; + } + /** * 获取设置属性的 extraProps */ From f61e2a2b8a3d8d6754474cd392bc259917c7eb10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Thu, 9 Jun 2022 14:12:58 +0800 Subject: [PATCH 038/823] fix: try catch calculation of dynamic setter --- packages/designer/src/designer/setting/utils.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/designer/src/designer/setting/utils.ts b/packages/designer/src/designer/setting/utils.ts index 01c2d9e395..0958b7a780 100644 --- a/packages/designer/src/designer/setting/utils.ts +++ b/packages/designer/src/designer/setting/utils.ts @@ -69,7 +69,9 @@ export class Transducer { isDynamic = dynamicFlag === undefined ? isDynamic : dynamicFlag !== false; } if (isDynamicSetter(setter) && isDynamic) { - setter = setter.call(context, context); + try { + setter = setter.call(context, context); + } catch (e) { console.error(e); } } this.setterTransducer = combineTransducer(getTransducerFromSetter(setter), getHotterFromSetter(setter), context); From a9a118fe6e79080245c6eea42ed26772b7c784ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Fri, 10 Jun 2022 14:42:24 +0800 Subject: [PATCH 039/823] fix: fallback focusNode to root if empty --- packages/designer/src/document/document-model.ts | 2 +- packages/shell/src/document-model.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index 22fe8d3c6a..e92b5aae72 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -93,7 +93,7 @@ export class DocumentModel { this.rootNode?.getExtraProp('fileName', true)?.setValue(fileName); } - @computed get focusNode() { + get focusNode() { if (this._drillDownNode) { return this._drillDownNode; } diff --git a/packages/shell/src/document-model.ts b/packages/shell/src/document-model.ts index 3177f3b691..558a31c5f2 100644 --- a/packages/shell/src/document-model.ts +++ b/packages/shell/src/document-model.ts @@ -89,7 +89,7 @@ export default class DocumentModel { } get focusNode(): Node { - return this._focusNode; + return this._focusNode || this.root; } set focusNode(node: Node) { From ba90327eac0f5f82f6349bb9a7684bf51259e9c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Mon, 13 Jun 2022 16:37:25 +0800 Subject: [PATCH 040/823] feat: add setVisible for Node --- packages/shell/src/node.ts | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/packages/shell/src/node.ts b/packages/shell/src/node.ts index 8ffbc92852..72afd46b82 100644 --- a/packages/shell/src/node.ts +++ b/packages/shell/src/node.ts @@ -306,6 +306,10 @@ export default class Node { return this[nodeSymbol].getVisible(); } + setVisible(flag: boolean) { + this[nodeSymbol].setVisible(flag); + } + isConditionalVisible() { return this[nodeSymbol].isConditionalVisible(); } From e02933c18bc15519b2eba8ad946282502a509611 Mon Sep 17 00:00:00 2001 From: liujuping Date: Tue, 14 Jun 2022 10:06:03 +0800 Subject: [PATCH 041/823] fix: fix the problem that material.getComponentMetasMap returns the wrong result --- packages/engine/README-zh_CN.md | 4 +--- packages/engine/README.md | 4 +--- packages/shell/src/material.ts | 4 +--- 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/packages/engine/README-zh_CN.md b/packages/engine/README-zh_CN.md index 089ffb2288..b668821ca0 100644 --- a/packages/engine/README-zh_CN.md +++ b/packages/engine/README-zh_CN.md @@ -12,7 +12,7 @@ [![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url] -[![Discussions][discussions-image]][discussions-url] [![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url] + [![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url] [npm-image]: https://img.shields.io/npm/v/@alilc/lowcode-engine.svg?style=flat-square [npm-url]: http://npmjs.org/package/@alilc/lowcode-engine @@ -21,8 +21,6 @@ [download-url]: https://npmjs.org/package/@alilc/lowcode-engine [help-wanted-image]: https://flat.badgen.net/github/label-issues/alibaba/lowcode-engine/help%20wanted/open [help-wanted-url]: https://github.com/alibaba/lowcode-engine/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22 -[discussions-image]: https://img.shields.io/badge/discussions-on%20github-blue?style=flat-square -[discussions-url]: https://github.com/alibaba/lowcode-engine/discussions [issues-helper-image]: https://img.shields.io/badge/using-issues--helper-orange?style=flat-square [issues-helper-url]: https://github.com/actions-cool/issues-helper diff --git a/packages/engine/README.md b/packages/engine/README.md index 627fbf6381..01a1c95588 100644 --- a/packages/engine/README.md +++ b/packages/engine/README.md @@ -12,7 +12,7 @@ An enterprise-class low-code technology stack with scale-out design [![NPM version][npm-image]][npm-url] [![NPM downloads][download-image]][download-url] -[![Discussions][discussions-image]][discussions-url] [![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url] +[![][issues-helper-image]][issues-helper-url] [![Issues need help][help-wanted-image]][help-wanted-url] [npm-image]: https://img.shields.io/npm/v/@alilc/lowcode-engine.svg?style=flat-square [npm-url]: http://npmjs.org/package/@alilc/lowcode-engine @@ -21,8 +21,6 @@ An enterprise-class low-code technology stack with scale-out design [download-url]: https://npmjs.org/package/@alilc/lowcode-engine [help-wanted-image]: https://flat.badgen.net/github/label-issues/alibaba/lowcode-engine/help%20wanted/open [help-wanted-url]: https://github.com/alibaba/lowcode-engine/issues?q=is%3Aopen+is%3Aissue+label%3A%22help+wanted%22 -[discussions-image]: https://img.shields.io/badge/discussions-on%20github-blue?style=flat-square -[discussions-url]: https://github.com/alibaba/lowcode-engine/discussions [issues-helper-image]: https://img.shields.io/badge/using-issues--helper-orange?style=flat-square [issues-helper-url]: https://github.com/actions-cool/issues-helper diff --git a/packages/shell/src/material.ts b/packages/shell/src/material.ts index 6fc4413b2c..46b25beab5 100644 --- a/packages/shell/src/material.ts +++ b/packages/shell/src/material.ts @@ -105,8 +105,6 @@ export default class Material { return isComponentMeta(obj); } - - /** * 获取所有已注册的物料元数据 * @returns @@ -114,7 +112,7 @@ export default class Material { getComponentMetasMap() { const map = new Map(); const originalMap = this[designerSymbol].getComponentMetasMap(); - for (let componentName in originalMap.keys()) { + for (let componentName of originalMap.keys()) { map.set(componentName, this.getComponentMeta(componentName)!); } return map; From bf2562e0e9aca0acc7d3c54d07c01b66656f8f24 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Tue, 14 Jun 2022 10:30:48 +0800 Subject: [PATCH 042/823] chore(release): publish 1.0.10 --- lerna.json | 2 +- packages/designer/package.json | 10 +++++----- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 16 ++++++++-------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 10 +++++----- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 12 ++++++------ packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- 16 files changed, 60 insertions(+), 60 deletions(-) diff --git a/lerna.json b/lerna.json index 1adf2a89c7..03f8059926 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.0.9", + "version": "1.0.10", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index 8838691450..73d9041429 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.0.9", + "version": "1.0.10", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,10 +15,10 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.0.9", - "@alilc/lowcode-shell": "1.0.9", - "@alilc/lowcode-types": "1.0.9", - "@alilc/lowcode-utils": "1.0.9", + "@alilc/lowcode-editor-core": "1.0.10", + "@alilc/lowcode-shell": "1.0.10", + "@alilc/lowcode-types": "1.0.10", + "@alilc/lowcode-utils": "1.0.10", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index e5e5cc6216..b424953ca7 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.0.9", + "version": "1.0.10", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.0.9", - "@alilc/lowcode-utils": "1.0.9", + "@alilc/lowcode-types": "1.0.10", + "@alilc/lowcode-utils": "1.0.10", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 439169c20e..3e31f9f64a 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.0.9", + "version": "1.0.10", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -18,10 +18,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.0.9", - "@alilc/lowcode-editor-core": "1.0.9", - "@alilc/lowcode-types": "1.0.9", - "@alilc/lowcode-utils": "1.0.9", + "@alilc/lowcode-designer": "1.0.10", + "@alilc/lowcode-editor-core": "1.0.10", + "@alilc/lowcode-types": "1.0.10", + "@alilc/lowcode-utils": "1.0.10", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index 2d20c7b137..d01872fdc2 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.0.9", + "version": "1.0.10", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,14 +19,14 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.0.9", - "@alilc/lowcode-editor-core": "1.0.9", - "@alilc/lowcode-editor-skeleton": "1.0.9", + "@alilc/lowcode-designer": "1.0.10", + "@alilc/lowcode-editor-core": "1.0.10", + "@alilc/lowcode-editor-skeleton": "1.0.10", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.0.9", - "@alilc/lowcode-plugin-outline-pane": "1.0.9", - "@alilc/lowcode-shell": "1.0.9", - "@alilc/lowcode-utils": "1.0.9", + "@alilc/lowcode-plugin-designer": "1.0.10", + "@alilc/lowcode-plugin-outline-pane": "1.0.10", + "@alilc/lowcode-shell": "1.0.10", + "@alilc/lowcode-utils": "1.0.10", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index 1da40fc406..2740bfcb5b 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.0.9", + "version": "1.0.10", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index baf0dea6f3..0b55680072 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.0.9", + "version": "1.0.10", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.0.9", - "@alilc/lowcode-editor-core": "1.0.9", - "@alilc/lowcode-utils": "1.0.9", + "@alilc/lowcode-designer": "1.0.10", + "@alilc/lowcode-editor-core": "1.0.10", + "@alilc/lowcode-utils": "1.0.10", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index cc10435c58..ec914c3403 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.0.9", + "version": "1.0.10", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,10 +13,10 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-designer": "1.0.9", - "@alilc/lowcode-editor-core": "1.0.9", - "@alilc/lowcode-types": "1.0.9", - "@alilc/lowcode-utils": "1.0.9", + "@alilc/lowcode-designer": "1.0.10", + "@alilc/lowcode-editor-core": "1.0.10", + "@alilc/lowcode-types": "1.0.10", + "@alilc/lowcode-utils": "1.0.10", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0" diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index 2fa2b93a7f..e93aed607b 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.0.9", + "version": "1.0.10", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.0.9", - "@alilc/lowcode-utils": "1.0.9", + "@alilc/lowcode-renderer-core": "1.0.10", + "@alilc/lowcode-utils": "1.0.10", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index ede4c41154..96c2e3123a 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.0.9", + "version": "1.0.10", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.0.9", - "@alilc/lowcode-rax-renderer": "1.0.9", - "@alilc/lowcode-types": "1.0.9", - "@alilc/lowcode-utils": "1.0.9", + "@alilc/lowcode-designer": "1.0.10", + "@alilc/lowcode-rax-renderer": "1.0.10", + "@alilc/lowcode-types": "1.0.10", + "@alilc/lowcode-utils": "1.0.10", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index d89616e1e5..73274bdb7b 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.0.9", + "version": "1.0.10", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.0.9" + "@alilc/lowcode-renderer-core": "1.0.10" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index b3158951b8..c581c83bde 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.0.9", + "version": "1.0.10", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -16,10 +16,10 @@ "build:umd": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.0.9", - "@alilc/lowcode-react-renderer": "1.0.9", - "@alilc/lowcode-types": "1.0.9", - "@alilc/lowcode-utils": "1.0.9", + "@alilc/lowcode-designer": "1.0.10", + "@alilc/lowcode-react-renderer": "1.0.10", + "@alilc/lowcode-types": "1.0.10", + "@alilc/lowcode-utils": "1.0.10", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 0967dba562..cb1ad7e866 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.0.9", + "version": "1.0.10", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.0.9", - "@alilc/lowcode-utils": "1.0.9", + "@alilc/lowcode-types": "1.0.10", + "@alilc/lowcode-utils": "1.0.10", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -34,7 +34,7 @@ }, "devDependencies": { "@alib/build-scripts": "^0.1.18", - "@alilc/lowcode-designer": "1.0.9", + "@alilc/lowcode-designer": "1.0.10", "@alilc/lowcode-test-mate": "^1.0.1", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", diff --git a/packages/shell/package.json b/packages/shell/package.json index df9544bafc..80f28e38be 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.0.9", + "version": "1.0.10", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.0.9", - "@alilc/lowcode-editor-core": "1.0.9", - "@alilc/lowcode-editor-skeleton": "1.0.9", - "@alilc/lowcode-types": "1.0.9", - "@alilc/lowcode-utils": "1.0.9", + "@alilc/lowcode-designer": "1.0.10", + "@alilc/lowcode-editor-core": "1.0.10", + "@alilc/lowcode-editor-skeleton": "1.0.10", + "@alilc/lowcode-types": "1.0.10", + "@alilc/lowcode-utils": "1.0.10", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index 25d6687c52..d0ea37729d 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.0.9", + "version": "1.0.10", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index e3804575ee..cd81e1f6c7 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.0.9", + "version": "1.0.10", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.0.9", + "@alilc/lowcode-types": "1.0.10", "lodash": "^4.17.21", "react": "^16", "zen-logger": "^1.1.0" From 567fd56cfe9e499a3ef77b31f5ef7c09ed18aede Mon Sep 17 00:00:00 2001 From: JackLian Date: Tue, 14 Jun 2022 14:54:55 +0800 Subject: [PATCH 043/823] test: add ut for render-core/adapter --- packages/renderer-core/src/adapter/index.ts | 22 ++-- .../tests/adapter/adapter.test.ts | 107 ++++++++++++++++++ 2 files changed, 118 insertions(+), 11 deletions(-) create mode 100644 packages/renderer-core/tests/adapter/adapter.test.ts diff --git a/packages/renderer-core/src/adapter/index.ts b/packages/renderer-core/src/adapter/index.ts index b4e0eedec7..661b3c17fb 100644 --- a/packages/renderer-core/src/adapter/index.ts +++ b/packages/renderer-core/src/adapter/index.ts @@ -25,19 +25,19 @@ class Adapter { setState() {} forceUpdate() {} render() {} - state: {}; - props: {}; - refs: {}; - context: {}; + state: Record; + props: Record; + refs: Record; + context: Record; }; const PureComponent: IGeneralConstructor = class { setState() {} forceUpdate() {} render() {} - state: {}; - props: {}; - refs: {}; - context: {}; + state: Record; + props: Record; + refs: Record; + context: Record; }; const createElement = () => {}; const createContext = () => {}; @@ -64,10 +64,10 @@ class Adapter { return false; } - return this.builtinModules.every(m => { - const flag = !!this.runtime[m]; + return this.builtinModules.every((m) => { + const flag = !!runtime[m]; if (!flag) { - throw new Error(`runtime is inValid, module '${m}' is not existed`); + throw new Error(`runtime is invalid, module '${m}' does not exist`); } return flag; }); diff --git a/packages/renderer-core/tests/adapter/adapter.test.ts b/packages/renderer-core/tests/adapter/adapter.test.ts new file mode 100644 index 0000000000..77e12c5878 --- /dev/null +++ b/packages/renderer-core/tests/adapter/adapter.test.ts @@ -0,0 +1,107 @@ +// @ts-nocheck +import adapter, { Env } from '../../src/adapter'; +import { IRuntime, IRendererModules, IGeneralConstructor } from '../../src/types'; + + + +describe('test src/adapter ', () => { + + it('adapter basic use works', () => { + expect(adapter).toBeTruthy(); + + }); + + it('isValidRuntime works', () => { + expect(adapter.isValidRuntime([] as any)).toBeFalsy(); + + expect(adapter.isValidRuntime('' as any)).toBeFalsy(); + + let invalidRuntime = {}; + expect(() => adapter.isValidRuntime(invalidRuntime as any)).toThrowError(/Component/); + invalidRuntime = { + Component: {}, + }; + expect(() => adapter.isValidRuntime(invalidRuntime as any)).toThrowError(/PureComponent/); + invalidRuntime = { + Component: {}, + PureComponent: {}, + }; + expect(() => adapter.isValidRuntime(invalidRuntime as any)).toThrowError(/createElement/); + invalidRuntime = { + Component: {}, + PureComponent: {}, + createElement: {}, + }; + expect(() => adapter.isValidRuntime(invalidRuntime as any)).toThrowError(/createContext/); + invalidRuntime = { + Component: {}, + PureComponent: {}, + createElement: {}, + createContext: {}, + }; + expect(() => adapter.isValidRuntime(invalidRuntime as any)).toThrowError(/forwardRef/); + invalidRuntime = { + Component: {}, + PureComponent: {}, + createElement: {}, + createContext: {}, + forwardRef: {}, + }; + expect(() => adapter.isValidRuntime(invalidRuntime as any)).toThrowError(/findDOMNode/); + const validRuntime = { + Component: {}, + PureComponent: {}, + createElement: {}, + createContext: {}, + forwardRef: {}, + findDOMNode: {}, + }; + + expect(adapter.isValidRuntime(validRuntime as any)).toBeTruthy(); + }); + + it('setRuntime/getRuntime works', () => { + const validRuntime = { + Component: {}, + PureComponent: {}, + createElement: {}, + createContext: {}, + forwardRef: {}, + findDOMNode: {}, + }; + + adapter.setRuntime(validRuntime as any); + expect(adapter.getRuntime()).toBe(validRuntime); + + // won`t work when invalid runtime paased in. + adapter.setRuntime([] as any); + expect(adapter.getRuntime()).toBe(validRuntime); + + + }); + + it('setEnv/.env/isReact/isRax works', () => { + adapter.setEnv(Env.React); + expect(adapter.env).toBe(Env.React); + expect(adapter.isReact()).toBeTruthy(); + expect(adapter.isRax()).toBeFalsy(); + adapter.setEnv(Env.Rax); + expect(adapter.env).toBe(Env.Rax); + expect(adapter.isRax()).toBeTruthy(); + expect(adapter.isReact()).toBeFalsy(); + }); + + it('setRenderers/getRenderers works', () => { + const mockRenderers = { BaseRenderer: {} as IBaseRenderComponent}; + adapter.setRenderers(mockRenderers); + expect(adapter.getRenderers()).toBe(mockRenderers); + adapter.setRenderers(undefined); + expect(adapter.getRenderers()).toStrictEqual({}); + }); + + it('setConfigProvider/getConfigProvider works', () => { + const mockConfigProvider = { a: 111 }; + adapter.setConfigProvider(mockConfigProvider); + expect(adapter.getConfigProvider()).toBe(mockConfigProvider); + }); +}); \ No newline at end of file From 310508146621dc19f10739240381b5731caf992a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Wed, 15 Jun 2022 14:33:03 +0800 Subject: [PATCH 044/823] refactor: reuse previous Prop instance to keep mobx reaction connnection alive --- .../designer/src/document/node/props/prop.ts | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index d0d36324d8..1809852c4e 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -297,6 +297,7 @@ export class Prop implements IPropParent { items.forEach((prop) => prop.purge()); } this._items = null; + this._prevMaps = this._maps; this._maps = null; if (this._type !== 'slot' && this._slotNode) { this._slotNode.remove(); @@ -377,6 +378,14 @@ export class Prop implements IPropParent { @obx.shallow private _maps: Map | null = null; + /** + * 作为 _maps 的一层缓存机制,主要是复用部分已存在的 Prop,保持响应式关系,比如: + * 当前 Prop#_value 值为 { a: 1 },当调用 setValue({ a: 2 }) 时,所有原来的子 Prop 均被销毁, + * 导致假如外部有 mobx reaction(常见于 observer),此时响应式链路会被打断, + * 因为 reaction 监听的是原 Prop(a) 的 _value,而不是新 Prop(a) 的 _value。 + */ + private _prevMaps: Map | null = null; + get path(): string[] { return (this.parent.path || []).concat(this.key as string); } @@ -400,7 +409,13 @@ export class Prop implements IPropParent { const maps = new Map(); const keys = Object.keys(data); for (const key of keys) { - const prop = new Prop(this, data[key], key); + let prop: Prop; + if (this._prevMaps?.has(key)) { + prop = this._prevMaps.get(key)!; + prop.setValue(data[key]); + } else { + prop = new Prop(this, data[key], key); + } items = items || []; items.push(prop); maps.set(key, prop); From 058a84226af8ca19d8c7d63599d80d0cdf70281c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Wed, 15 Jun 2022 10:00:21 +0800 Subject: [PATCH 045/823] fix: declare parameter appHelper for valid engine options --- packages/editor-core/src/config.ts | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/packages/editor-core/src/config.ts b/packages/editor-core/src/config.ts index fc7d5b6024..e90e83bea3 100644 --- a/packages/editor-core/src/config.ts +++ b/packages/editor-core/src/config.ts @@ -118,6 +118,13 @@ const VALID_ENGINE_OPTIONS = { type: 'array', description: '自定义 simulatorUrl 的地址', }, + /** + * 与 react-renderer 的 appHelper 一致, https://lowcode-engine.cn/docV2/nhilce#appHelper + */ + appHelper: { + type: 'object', + description: '定义 utils 和 constants 等对象', + }, requestHandlersMap: { type: 'object', description: '数据源引擎的请求处理器映射', From c5ffbd59c46ecd7fbc81d759f1351e09dbc6e4d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Thu, 16 Jun 2022 11:39:18 +0800 Subject: [PATCH 046/823] test: add some unit tests for ComponentMeta --- .gitignore | 1 + packages/designer/jest.config.js | 2 +- packages/designer/src/component-meta.ts | 27 +- .../fixtures/component-metadata/abcgroup.ts | 280 +++++++++++++++++ .../fixtures/component-metadata/abcitem.ts | 280 +++++++++++++++++ .../fixtures/component-metadata/abcnode.ts | 280 +++++++++++++++++ .../fixtures/component-metadata/abcoption.ts | 280 +++++++++++++++++ .../tests/fixtures/component-metadata/div.ts | 98 +++--- .../fixtures/component-metadata/div10.ts | 22 ++ .../tests/fixtures/component-metadata/div2.ts | 280 +++++++++++++++++ .../tests/fixtures/component-metadata/div3.ts | 282 +++++++++++++++++ .../tests/fixtures/component-metadata/div4.ts | 272 +++++++++++++++++ .../tests/fixtures/component-metadata/div5.ts | 283 ++++++++++++++++++ .../tests/fixtures/component-metadata/div6.ts | 283 ++++++++++++++++++ .../tests/fixtures/component-metadata/div7.ts | 276 +++++++++++++++++ .../tests/fixtures/component-metadata/div8.ts | 12 + .../tests/fixtures/component-metadata/div9.ts | 8 + .../fixtures/component-metadata/page2.ts | 279 +++++++++++++++++ .../tests/main/meta/component-meta.test.ts | 190 +++++++++++- packages/designer/tests/utils-ut/misc.test.ts | 6 +- packages/utils/src/misc.ts | 4 + 21 files changed, 3376 insertions(+), 69 deletions(-) create mode 100644 packages/designer/tests/fixtures/component-metadata/abcgroup.ts create mode 100644 packages/designer/tests/fixtures/component-metadata/abcitem.ts create mode 100644 packages/designer/tests/fixtures/component-metadata/abcnode.ts create mode 100644 packages/designer/tests/fixtures/component-metadata/abcoption.ts create mode 100644 packages/designer/tests/fixtures/component-metadata/div10.ts create mode 100644 packages/designer/tests/fixtures/component-metadata/div2.ts create mode 100644 packages/designer/tests/fixtures/component-metadata/div3.ts create mode 100644 packages/designer/tests/fixtures/component-metadata/div4.ts create mode 100644 packages/designer/tests/fixtures/component-metadata/div5.ts create mode 100644 packages/designer/tests/fixtures/component-metadata/div6.ts create mode 100644 packages/designer/tests/fixtures/component-metadata/div7.ts create mode 100644 packages/designer/tests/fixtures/component-metadata/div8.ts create mode 100644 packages/designer/tests/fixtures/component-metadata/div9.ts create mode 100644 packages/designer/tests/fixtures/component-metadata/page2.ts diff --git a/.gitignore b/.gitignore index 2f87724cb9..dc6504d08b 100644 --- a/.gitignore +++ b/.gitignore @@ -36,6 +36,7 @@ lib-cov # Coverage directory used by tools like istanbul coverage +coverage-all # nyc test coverage .nyc_output diff --git a/packages/designer/jest.config.js b/packages/designer/jest.config.js index 807f8ecebe..43bea9064d 100644 --- a/packages/designer/jest.config.js +++ b/packages/designer/jest.config.js @@ -10,7 +10,7 @@ const jestConfig = { // // '^.+\\.(js|jsx)$': 'babel-jest', // }, // testMatch: ['**/document/node/node.test.ts'], - // testMatch: ['**/designer/builtin-hotkey.test.ts'], + // testMatch: ['**/component-meta.test.ts'], // testMatch: ['**/plugin/plugin-manager.test.ts'], // testMatch: ['(/tests?/.*(test))\\.[jt]s$'], transformIgnorePatterns: [ diff --git a/packages/designer/src/component-meta.ts b/packages/designer/src/component-meta.ts index 0484c0b96c..3ca04f8093 100644 --- a/packages/designer/src/component-meta.ts +++ b/packages/designer/src/component-meta.ts @@ -13,7 +13,7 @@ import { LiveTextEditingConfig, FieldConfig, } from '@alilc/lowcode-types'; -import { deprecate } from '@alilc/lowcode-utils'; +import { deprecate, isRegExp } from '@alilc/lowcode-utils'; import { computed, engineConfig } from '@alilc/lowcode-editor-core'; import EventEmitter from 'events'; import { componentDefaults, legacyIssues } from './transducers'; @@ -31,7 +31,7 @@ import { IconHidden, } from './icons'; -function ensureAList(list?: string | string[]): string[] | null { +export function ensureAList(list?: string | string[]): string[] | null { if (!list) { return null; } @@ -47,11 +47,7 @@ function ensureAList(list?: string | string[]): string[] | null { return list; } -function isRegExp(obj: any): obj is RegExp { - return obj && obj.test && obj.exec && obj.compile; -} - -function buildFilter(rule?: string | string[] | RegExp | NestingFilter) { +export function buildFilter(rule?: string | string[] | RegExp | NestingFilter) { if (!rule) { return null; } @@ -145,9 +141,8 @@ export class ComponentMeta { private _isMinimalRenderUnit?: boolean; get title(): string | I18nData | ReactElement { - // TODO: 标记下。这块需要康师傅加一下API,页面正常渲染。 // string | i18nData | ReactElement - // TitleConfig title.label + // TitleConfig title.label if (isTitleConfig(this._title)) { return (this._title.label as any) || this.componentName; } @@ -220,10 +215,10 @@ export class ComponentMeta { collectLiveTextEditing(this.configure); this._liveTextEditing = liveTextEditing.length > 0 ? liveTextEditing : undefined; - const isTopFiexd = this._transformedMetadata.configure.advanced?.isTopFixed; + const isTopFixed = this._transformedMetadata.configure.advanced?.isTopFixed; - if (isTopFiexd) { - this._isTopFixed = isTopFiexd; + if (isTopFixed) { + this._isTopFixed = isTopFixed; } const { configure = {} } = this._transformedMetadata; @@ -403,6 +398,7 @@ const builtinComponentActions: ComponentAction[] = [ content: { icon: IconRemove, title: intlNode('remove'), + /* istanbul ignore next */ action(node: Node) { node.remove(); }, @@ -414,10 +410,12 @@ const builtinComponentActions: ComponentAction[] = [ content: { icon: IconHidden, title: intlNode('hide'), + /* istanbul ignore next */ action(node: Node) { node.setVisible(false); }, }, + /* istanbul ignore next */ condition: (node: Node) => { return node.componentMeta.isModal; }, @@ -428,6 +426,7 @@ const builtinComponentActions: ComponentAction[] = [ content: { icon: IconClone, title: intlNode('copy'), + /* istanbul ignore next */ action(node: Node) { // node.remove(); const { document: doc, parent, index } = node; @@ -459,10 +458,12 @@ const builtinComponentActions: ComponentAction[] = [ content: { icon: IconLock, // 锁定 icon title: intlNode('lock'), + /* istanbul ignore next */ action(node: Node) { node.lock(); }, }, + /* istanbul ignore next */ condition: (node: Node) => { return engineConfig.get('enableCanvasLock', false) && node.isContainer() && !node.isLocked; }, @@ -473,10 +474,12 @@ const builtinComponentActions: ComponentAction[] = [ content: { icon: IconUnlock, // 解锁 icon title: intlNode('unlock'), + /* istanbul ignore next */ action(node: Node) { node.lock(false); }, }, + /* istanbul ignore next */ condition: (node: Node) => { return engineConfig.get('enableCanvasLock', false) && node.isContainer() && node.isLocked; }, diff --git a/packages/designer/tests/fixtures/component-metadata/abcgroup.ts b/packages/designer/tests/fixtures/component-metadata/abcgroup.ts new file mode 100644 index 0000000000..986d6e3e93 --- /dev/null +++ b/packages/designer/tests/fixtures/component-metadata/abcgroup.ts @@ -0,0 +1,280 @@ +import { ComponentMetadata } from "@alilc/lowcode-types"; +export default { + componentName: 'Abc.Group', + npm: { + package: '@ali/vc-div', + componentName: 'Div', + }, + title: { label: '容器' }, + docUrl: 'https://github.com/alibaba/lowcode-materials/tree/main/docs', + devMode: 'proCode', + tags: ['布局'], + configure: { + props: [ + { + type: 'field', + name: 'behavior', + title: '默认状态', + extraProps: { + display: 'inline', + defaultValue: 'NORMAL', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + options: [ + { + title: '普通', + value: 'NORMAL', + }, + { + title: '隐藏', + value: 'HIDDEN', + }, + ], + loose: false, + cancelable: false, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: '__style__', + title: { + label: '样式设置', + tip: '点击 ? 查看样式设置器用法指南', + docUrl: 'https://lark.alipay.com/legao/help/design-tool-style', + }, + extraProps: { + display: 'accordion', + defaultValue: {}, + }, + setter: { + key: null, + ref: null, + props: { + advanced: true, + }, + _owner: null, + }, + }, + { + type: 'group', + name: 'groupkgzzeo41', + title: '高级', + extraProps: { + display: 'accordion', + }, + items: [ + { + type: 'field', + name: 'fieldId', + title: { + label: '唯一标识', + }, + extraProps: { + display: 'block', + }, + setter: { + key: null, + ref: null, + props: { + placeholder: '请输入唯一标识', + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'useFieldIdAsDomId', + title: { + label: '将唯一标识用作 DOM ID', + }, + extraProps: { + display: 'block', + defaultValue: false, + }, + setter: { + key: null, + ref: null, + props: {}, + _owner: null, + }, + }, + { + type: 'field', + name: 'customClassName', + title: '自定义样式类', + extraProps: { + display: 'block', + defaultValue: '', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + placeholder: null, + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: 'events', + title: { + label: '动作设置', + tip: '点击 ? 查看如何设置组件的事件响应动作', + docUrl: 'https://lark.alipay.com/legao/legao/events-call', + }, + extraProps: { + display: 'accordion', + defaultValue: { + ignored: true, + }, + }, + setter: { + key: null, + ref: null, + props: { + events: [ + { + name: 'onClick', + title: '当点击时', + initialValue: + "/**\n * 容器 当点击时\n */\nfunction onClick(event) {\n console.log('onClick', event);\n}", + }, + { + name: 'onMouseEnter', + title: '当鼠标进入时', + initialValue: + "/**\n * 容器 当鼠标进入时\n */\nfunction onMouseEnter(event) {\n console.log('onMouseEnter', event);\n}", + }, + { + name: 'onMouseLeave', + title: '当鼠标离开时', + initialValue: + "/**\n * 容器 当鼠标离开时\n */\nfunction onMouseLeave(event) {\n console.log('onMouseLeave', event);\n}", + }, + ], + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'onClick', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseEnter', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseLeave', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + ], + }, + ], + component: { + isContainer: true, + }, + supports: {}, + advanced: { + isTopFixed: true, + callbacks: { + onNodeAdd: (dragment, self) => { console.log(dragment); }, + onNodeRemove: (dragment, self) => { console.log(dragment); } + }, + initials: [ + { + name: 'behavior', + }, + { + name: '__style__', + }, + { + name: 'fieldId', + }, + { + name: 'useFieldIdAsDomId', + }, + { + name: 'customClassName', + }, + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + filters: [ + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + autoruns: [], + }, + }, +} as ComponentMetadata; diff --git a/packages/designer/tests/fixtures/component-metadata/abcitem.ts b/packages/designer/tests/fixtures/component-metadata/abcitem.ts new file mode 100644 index 0000000000..c378b35d56 --- /dev/null +++ b/packages/designer/tests/fixtures/component-metadata/abcitem.ts @@ -0,0 +1,280 @@ +import { ComponentMetadata } from "@alilc/lowcode-types"; +export default { + componentName: 'Abc.Item', + npm: { + package: '@ali/vc-div', + componentName: 'Div', + }, + title: { label: '容器' }, + docUrl: 'https://github.com/alibaba/lowcode-materials/tree/main/docs', + devMode: 'proCode', + tags: ['布局'], + configure: { + props: [ + { + type: 'field', + name: 'behavior', + title: '默认状态', + extraProps: { + display: 'inline', + defaultValue: 'NORMAL', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + options: [ + { + title: '普通', + value: 'NORMAL', + }, + { + title: '隐藏', + value: 'HIDDEN', + }, + ], + loose: false, + cancelable: false, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: '__style__', + title: { + label: '样式设置', + tip: '点击 ? 查看样式设置器用法指南', + docUrl: 'https://lark.alipay.com/legao/help/design-tool-style', + }, + extraProps: { + display: 'accordion', + defaultValue: {}, + }, + setter: { + key: null, + ref: null, + props: { + advanced: true, + }, + _owner: null, + }, + }, + { + type: 'group', + name: 'groupkgzzeo41', + title: '高级', + extraProps: { + display: 'accordion', + }, + items: [ + { + type: 'field', + name: 'fieldId', + title: { + label: '唯一标识', + }, + extraProps: { + display: 'block', + }, + setter: { + key: null, + ref: null, + props: { + placeholder: '请输入唯一标识', + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'useFieldIdAsDomId', + title: { + label: '将唯一标识用作 DOM ID', + }, + extraProps: { + display: 'block', + defaultValue: false, + }, + setter: { + key: null, + ref: null, + props: {}, + _owner: null, + }, + }, + { + type: 'field', + name: 'customClassName', + title: '自定义样式类', + extraProps: { + display: 'block', + defaultValue: '', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + placeholder: null, + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: 'events', + title: { + label: '动作设置', + tip: '点击 ? 查看如何设置组件的事件响应动作', + docUrl: 'https://lark.alipay.com/legao/legao/events-call', + }, + extraProps: { + display: 'accordion', + defaultValue: { + ignored: true, + }, + }, + setter: { + key: null, + ref: null, + props: { + events: [ + { + name: 'onClick', + title: '当点击时', + initialValue: + "/**\n * 容器 当点击时\n */\nfunction onClick(event) {\n console.log('onClick', event);\n}", + }, + { + name: 'onMouseEnter', + title: '当鼠标进入时', + initialValue: + "/**\n * 容器 当鼠标进入时\n */\nfunction onMouseEnter(event) {\n console.log('onMouseEnter', event);\n}", + }, + { + name: 'onMouseLeave', + title: '当鼠标离开时', + initialValue: + "/**\n * 容器 当鼠标离开时\n */\nfunction onMouseLeave(event) {\n console.log('onMouseLeave', event);\n}", + }, + ], + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'onClick', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseEnter', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseLeave', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + ], + }, + ], + component: { + isContainer: true, + }, + supports: {}, + advanced: { + isTopFixed: true, + callbacks: { + onNodeAdd: (dragment, self) => { console.log(dragment); }, + onNodeRemove: (dragment, self) => { console.log(dragment); } + }, + initials: [ + { + name: 'behavior', + }, + { + name: '__style__', + }, + { + name: 'fieldId', + }, + { + name: 'useFieldIdAsDomId', + }, + { + name: 'customClassName', + }, + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + filters: [ + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + autoruns: [], + }, + }, +} as ComponentMetadata; diff --git a/packages/designer/tests/fixtures/component-metadata/abcnode.ts b/packages/designer/tests/fixtures/component-metadata/abcnode.ts new file mode 100644 index 0000000000..f59907194e --- /dev/null +++ b/packages/designer/tests/fixtures/component-metadata/abcnode.ts @@ -0,0 +1,280 @@ +import { ComponentMetadata } from "@alilc/lowcode-types"; +export default { + componentName: 'Abc.Node', + npm: { + package: '@ali/vc-div', + componentName: 'Div', + }, + title: { label: '容器' }, + docUrl: 'https://github.com/alibaba/lowcode-materials/tree/main/docs', + devMode: 'proCode', + tags: ['布局'], + configure: { + props: [ + { + type: 'field', + name: 'behavior', + title: '默认状态', + extraProps: { + display: 'inline', + defaultValue: 'NORMAL', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + options: [ + { + title: '普通', + value: 'NORMAL', + }, + { + title: '隐藏', + value: 'HIDDEN', + }, + ], + loose: false, + cancelable: false, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: '__style__', + title: { + label: '样式设置', + tip: '点击 ? 查看样式设置器用法指南', + docUrl: 'https://lark.alipay.com/legao/help/design-tool-style', + }, + extraProps: { + display: 'accordion', + defaultValue: {}, + }, + setter: { + key: null, + ref: null, + props: { + advanced: true, + }, + _owner: null, + }, + }, + { + type: 'group', + name: 'groupkgzzeo41', + title: '高级', + extraProps: { + display: 'accordion', + }, + items: [ + { + type: 'field', + name: 'fieldId', + title: { + label: '唯一标识', + }, + extraProps: { + display: 'block', + }, + setter: { + key: null, + ref: null, + props: { + placeholder: '请输入唯一标识', + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'useFieldIdAsDomId', + title: { + label: '将唯一标识用作 DOM ID', + }, + extraProps: { + display: 'block', + defaultValue: false, + }, + setter: { + key: null, + ref: null, + props: {}, + _owner: null, + }, + }, + { + type: 'field', + name: 'customClassName', + title: '自定义样式类', + extraProps: { + display: 'block', + defaultValue: '', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + placeholder: null, + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: 'events', + title: { + label: '动作设置', + tip: '点击 ? 查看如何设置组件的事件响应动作', + docUrl: 'https://lark.alipay.com/legao/legao/events-call', + }, + extraProps: { + display: 'accordion', + defaultValue: { + ignored: true, + }, + }, + setter: { + key: null, + ref: null, + props: { + events: [ + { + name: 'onClick', + title: '当点击时', + initialValue: + "/**\n * 容器 当点击时\n */\nfunction onClick(event) {\n console.log('onClick', event);\n}", + }, + { + name: 'onMouseEnter', + title: '当鼠标进入时', + initialValue: + "/**\n * 容器 当鼠标进入时\n */\nfunction onMouseEnter(event) {\n console.log('onMouseEnter', event);\n}", + }, + { + name: 'onMouseLeave', + title: '当鼠标离开时', + initialValue: + "/**\n * 容器 当鼠标离开时\n */\nfunction onMouseLeave(event) {\n console.log('onMouseLeave', event);\n}", + }, + ], + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'onClick', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseEnter', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseLeave', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + ], + }, + ], + component: { + isContainer: true, + }, + supports: {}, + advanced: { + isTopFixed: true, + callbacks: { + onNodeAdd: (dragment, self) => { console.log(dragment); }, + onNodeRemove: (dragment, self) => { console.log(dragment); } + }, + initials: [ + { + name: 'behavior', + }, + { + name: '__style__', + }, + { + name: 'fieldId', + }, + { + name: 'useFieldIdAsDomId', + }, + { + name: 'customClassName', + }, + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + filters: [ + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + autoruns: [], + }, + }, +} as ComponentMetadata; diff --git a/packages/designer/tests/fixtures/component-metadata/abcoption.ts b/packages/designer/tests/fixtures/component-metadata/abcoption.ts new file mode 100644 index 0000000000..78490060e4 --- /dev/null +++ b/packages/designer/tests/fixtures/component-metadata/abcoption.ts @@ -0,0 +1,280 @@ +import { ComponentMetadata } from "@alilc/lowcode-types"; +export default { + componentName: 'Abc.Option', + npm: { + package: '@ali/vc-div', + componentName: 'Div', + }, + title: { label: '容器' }, + docUrl: 'https://github.com/alibaba/lowcode-materials/tree/main/docs', + devMode: 'proCode', + tags: ['布局'], + configure: { + props: [ + { + type: 'field', + name: 'behavior', + title: '默认状态', + extraProps: { + display: 'inline', + defaultValue: 'NORMAL', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + options: [ + { + title: '普通', + value: 'NORMAL', + }, + { + title: '隐藏', + value: 'HIDDEN', + }, + ], + loose: false, + cancelable: false, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: '__style__', + title: { + label: '样式设置', + tip: '点击 ? 查看样式设置器用法指南', + docUrl: 'https://lark.alipay.com/legao/help/design-tool-style', + }, + extraProps: { + display: 'accordion', + defaultValue: {}, + }, + setter: { + key: null, + ref: null, + props: { + advanced: true, + }, + _owner: null, + }, + }, + { + type: 'group', + name: 'groupkgzzeo41', + title: '高级', + extraProps: { + display: 'accordion', + }, + items: [ + { + type: 'field', + name: 'fieldId', + title: { + label: '唯一标识', + }, + extraProps: { + display: 'block', + }, + setter: { + key: null, + ref: null, + props: { + placeholder: '请输入唯一标识', + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'useFieldIdAsDomId', + title: { + label: '将唯一标识用作 DOM ID', + }, + extraProps: { + display: 'block', + defaultValue: false, + }, + setter: { + key: null, + ref: null, + props: {}, + _owner: null, + }, + }, + { + type: 'field', + name: 'customClassName', + title: '自定义样式类', + extraProps: { + display: 'block', + defaultValue: '', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + placeholder: null, + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: 'events', + title: { + label: '动作设置', + tip: '点击 ? 查看如何设置组件的事件响应动作', + docUrl: 'https://lark.alipay.com/legao/legao/events-call', + }, + extraProps: { + display: 'accordion', + defaultValue: { + ignored: true, + }, + }, + setter: { + key: null, + ref: null, + props: { + events: [ + { + name: 'onClick', + title: '当点击时', + initialValue: + "/**\n * 容器 当点击时\n */\nfunction onClick(event) {\n console.log('onClick', event);\n}", + }, + { + name: 'onMouseEnter', + title: '当鼠标进入时', + initialValue: + "/**\n * 容器 当鼠标进入时\n */\nfunction onMouseEnter(event) {\n console.log('onMouseEnter', event);\n}", + }, + { + name: 'onMouseLeave', + title: '当鼠标离开时', + initialValue: + "/**\n * 容器 当鼠标离开时\n */\nfunction onMouseLeave(event) {\n console.log('onMouseLeave', event);\n}", + }, + ], + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'onClick', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseEnter', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseLeave', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + ], + }, + ], + component: { + isContainer: true, + }, + supports: {}, + advanced: { + isTopFixed: true, + callbacks: { + onNodeAdd: (dragment, self) => { console.log(dragment); }, + onNodeRemove: (dragment, self) => { console.log(dragment); } + }, + initials: [ + { + name: 'behavior', + }, + { + name: '__style__', + }, + { + name: 'fieldId', + }, + { + name: 'useFieldIdAsDomId', + }, + { + name: 'customClassName', + }, + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + filters: [ + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + autoruns: [], + }, + }, +} as ComponentMetadata; diff --git a/packages/designer/tests/fixtures/component-metadata/div.ts b/packages/designer/tests/fixtures/component-metadata/div.ts index 730da3f623..3c29bf4888 100644 --- a/packages/designer/tests/fixtures/component-metadata/div.ts +++ b/packages/designer/tests/fixtures/component-metadata/div.ts @@ -229,55 +229,55 @@ export default { }, }, supports: {}, - }, - experimental: { - callbacks: { - onNodeAdd: (dragment, self) => { console.log(dragment); }, - onNodeRemove: (dragment, self) => { console.log(dragment); } - }, - initials: [ - { - name: 'behavior', - }, - { - name: '__style__', - }, - { - name: 'fieldId', + advanced: { + callbacks: { + onNodeAdd: (dragment, self) => { console.log(dragment); }, + onNodeRemove: (dragment, self) => { console.log(dragment); } }, - { - name: 'useFieldIdAsDomId', - }, - { - name: 'customClassName', - }, - { - name: 'events', - }, - { - name: 'onClick', - }, - { - name: 'onMouseEnter', - }, - { - name: 'onMouseLeave', - }, - ], - filters: [ - { - name: 'events', - }, - { - name: 'onClick', - }, - { - name: 'onMouseEnter', - }, - { - name: 'onMouseLeave', - }, - ], - autoruns: [], + initials: [ + { + name: 'behavior', + }, + { + name: '__style__', + }, + { + name: 'fieldId', + }, + { + name: 'useFieldIdAsDomId', + }, + { + name: 'customClassName', + }, + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + filters: [ + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + autoruns: [], + }, }, } as ComponentMetadata; diff --git a/packages/designer/tests/fixtures/component-metadata/div10.ts b/packages/designer/tests/fixtures/component-metadata/div10.ts new file mode 100644 index 0000000000..929c34f8c4 --- /dev/null +++ b/packages/designer/tests/fixtures/component-metadata/div10.ts @@ -0,0 +1,22 @@ +import { ComponentMetadata } from "@alilc/lowcode-types"; +export default { + componentName: 'Div', + title: '容器', + docUrl: 'https://github.com/alibaba/lowcode-materials/tree/main/docs', + devMode: 'proCode', + tags: ['布局'], + configure: { + component: { + nestingRule: { + parentWhitelist: (parent, my) => { + if (parent.componentName === 'Form' && my.componentName === 'Div') return true; + return false; + }, + childWhitelist: (child, my) => { + if (child.componentName === 'Image' && my.componentName === 'Div') return true; + return false; + }, + }, + }, + }, +} as ComponentMetadata; diff --git a/packages/designer/tests/fixtures/component-metadata/div2.ts b/packages/designer/tests/fixtures/component-metadata/div2.ts new file mode 100644 index 0000000000..001266d85c --- /dev/null +++ b/packages/designer/tests/fixtures/component-metadata/div2.ts @@ -0,0 +1,280 @@ +import { ComponentMetadata } from "@alilc/lowcode-types"; +export default { + componentName: 'Div', + npm: { + package: '@ali/vc-div', + componentName: 'Div', + }, + title: { label: '容器' }, + docUrl: 'https://github.com/alibaba/lowcode-materials/tree/main/docs', + devMode: 'proCode', + tags: ['布局'], + configure: { + props: [ + { + type: 'field', + name: 'behavior', + title: '默认状态', + extraProps: { + display: 'inline', + defaultValue: 'NORMAL', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + options: [ + { + title: '普通', + value: 'NORMAL', + }, + { + title: '隐藏', + value: 'HIDDEN', + }, + ], + loose: false, + cancelable: false, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: '__style__', + title: { + label: '样式设置', + tip: '点击 ? 查看样式设置器用法指南', + docUrl: 'https://lark.alipay.com/legao/help/design-tool-style', + }, + extraProps: { + display: 'accordion', + defaultValue: {}, + }, + setter: { + key: null, + ref: null, + props: { + advanced: true, + }, + _owner: null, + }, + }, + { + type: 'group', + name: 'groupkgzzeo41', + title: '高级', + extraProps: { + display: 'accordion', + }, + items: [ + { + type: 'field', + name: 'fieldId', + title: { + label: '唯一标识', + }, + extraProps: { + display: 'block', + }, + setter: { + key: null, + ref: null, + props: { + placeholder: '请输入唯一标识', + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'useFieldIdAsDomId', + title: { + label: '将唯一标识用作 DOM ID', + }, + extraProps: { + display: 'block', + defaultValue: false, + }, + setter: { + key: null, + ref: null, + props: {}, + _owner: null, + }, + }, + { + type: 'field', + name: 'customClassName', + title: '自定义样式类', + extraProps: { + display: 'block', + defaultValue: '', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + placeholder: null, + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: 'events', + title: { + label: '动作设置', + tip: '点击 ? 查看如何设置组件的事件响应动作', + docUrl: 'https://lark.alipay.com/legao/legao/events-call', + }, + extraProps: { + display: 'accordion', + defaultValue: { + ignored: true, + }, + }, + setter: { + key: null, + ref: null, + props: { + events: [ + { + name: 'onClick', + title: '当点击时', + initialValue: + "/**\n * 容器 当点击时\n */\nfunction onClick(event) {\n console.log('onClick', event);\n}", + }, + { + name: 'onMouseEnter', + title: '当鼠标进入时', + initialValue: + "/**\n * 容器 当鼠标进入时\n */\nfunction onMouseEnter(event) {\n console.log('onMouseEnter', event);\n}", + }, + { + name: 'onMouseLeave', + title: '当鼠标离开时', + initialValue: + "/**\n * 容器 当鼠标离开时\n */\nfunction onMouseLeave(event) {\n console.log('onMouseLeave', event);\n}", + }, + ], + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'onClick', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseEnter', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseLeave', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + ], + }, + ], + component: { + isContainer: true, + }, + supports: {}, + advanced: { + isTopFixed: true, + callbacks: { + onNodeAdd: (dragment, self) => { console.log(dragment); }, + onNodeRemove: (dragment, self) => { console.log(dragment); } + }, + initials: [ + { + name: 'behavior', + }, + { + name: '__style__', + }, + { + name: 'fieldId', + }, + { + name: 'useFieldIdAsDomId', + }, + { + name: 'customClassName', + }, + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + filters: [ + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + autoruns: [], + }, + }, +} as ComponentMetadata; diff --git a/packages/designer/tests/fixtures/component-metadata/div3.ts b/packages/designer/tests/fixtures/component-metadata/div3.ts new file mode 100644 index 0000000000..6b3717078b --- /dev/null +++ b/packages/designer/tests/fixtures/component-metadata/div3.ts @@ -0,0 +1,282 @@ +import { ComponentMetadata } from "@alilc/lowcode-types"; +export default { + componentName: 'Div', + npm: { + package: '@ali/vc-div', + componentName: 'Div', + }, + docUrl: 'https://github.com/alibaba/lowcode-materials/tree/main/docs', + devMode: 'proCode', + tags: ['布局'], + configure: { + props: [ + { + type: 'field', + name: 'behavior', + title: '默认状态', + extraProps: { + display: 'inline', + defaultValue: 'NORMAL', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + options: [ + { + title: '普通', + value: 'NORMAL', + }, + { + title: '隐藏', + value: 'HIDDEN', + }, + ], + loose: false, + cancelable: false, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: '__style__', + title: { + label: '样式设置', + tip: '点击 ? 查看样式设置器用法指南', + docUrl: 'https://lark.alipay.com/legao/help/design-tool-style', + }, + extraProps: { + display: 'accordion', + defaultValue: {}, + }, + setter: { + key: null, + ref: null, + props: { + advanced: true, + }, + _owner: null, + }, + }, + { + type: 'group', + name: 'groupkgzzeo41', + title: '高级', + extraProps: { + display: 'accordion', + }, + items: [ + { + type: 'field', + name: 'fieldId', + title: { + label: '唯一标识', + }, + extraProps: { + display: 'block', + }, + setter: { + key: null, + ref: null, + props: { + placeholder: '请输入唯一标识', + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'useFieldIdAsDomId', + title: { + label: '将唯一标识用作 DOM ID', + }, + extraProps: { + display: 'block', + defaultValue: false, + }, + setter: { + key: null, + ref: null, + props: {}, + _owner: null, + }, + }, + { + type: 'field', + name: 'customClassName', + title: '自定义样式类', + extraProps: { + display: 'block', + defaultValue: '', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + placeholder: null, + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: 'events', + title: { + label: '动作设置', + tip: '点击 ? 查看如何设置组件的事件响应动作', + docUrl: 'https://lark.alipay.com/legao/legao/events-call', + }, + extraProps: { + display: 'accordion', + defaultValue: { + ignored: true, + }, + }, + setter: { + key: null, + ref: null, + props: { + events: [ + { + name: 'onClick', + title: '当点击时', + initialValue: + "/**\n * 容器 当点击时\n */\nfunction onClick(event) {\n console.log('onClick', event);\n}", + }, + { + name: 'onMouseEnter', + title: '当鼠标进入时', + initialValue: + "/**\n * 容器 当鼠标进入时\n */\nfunction onMouseEnter(event) {\n console.log('onMouseEnter', event);\n}", + }, + { + name: 'onMouseLeave', + title: '当鼠标离开时', + initialValue: + "/**\n * 容器 当鼠标离开时\n */\nfunction onMouseLeave(event) {\n console.log('onMouseLeave', event);\n}", + }, + ], + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'onClick', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseEnter', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseLeave', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + ], + }, + ], + component: { + isContainer: true, + nestingRule: { + // parentWhitelist: 'Div', + // childWhitelist: 'Div', + } + }, + supports: {}, + advanced: { + callbacks: { + onNodeAdd: (dragment, self) => { console.log(dragment); }, + onNodeRemove: (dragment, self) => { console.log(dragment); } + }, + initials: [ + { + name: 'behavior', + }, + { + name: '__style__', + }, + { + name: 'fieldId', + }, + { + name: 'useFieldIdAsDomId', + }, + { + name: 'customClassName', + }, + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + filters: [ + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + autoruns: [], + }, + }, +} as ComponentMetadata; diff --git a/packages/designer/tests/fixtures/component-metadata/div4.ts b/packages/designer/tests/fixtures/component-metadata/div4.ts new file mode 100644 index 0000000000..b987e6f842 --- /dev/null +++ b/packages/designer/tests/fixtures/component-metadata/div4.ts @@ -0,0 +1,272 @@ +import { ComponentMetadata } from "@alilc/lowcode-types"; +export default { + componentName: 'Div', + npm: { + package: '@ali/vc-div', + componentName: 'Div', + }, + docUrl: 'https://github.com/alibaba/lowcode-materials/tree/main/docs', + devMode: 'proCode', + tags: ['布局'], + configure: [ + { + type: 'field', + name: 'behavior', + title: '默认状态', + extraProps: { + display: 'inline', + defaultValue: 'NORMAL', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + options: [ + { + title: '普通', + value: 'NORMAL', + }, + { + title: '隐藏', + value: 'HIDDEN', + }, + ], + loose: false, + cancelable: false, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: '__style__', + title: { + label: '样式设置', + tip: '点击 ? 查看样式设置器用法指南', + docUrl: 'https://lark.alipay.com/legao/help/design-tool-style', + }, + extraProps: { + display: 'accordion', + defaultValue: {}, + }, + setter: { + key: null, + ref: null, + props: { + advanced: true, + }, + _owner: null, + }, + }, + { + type: 'group', + name: 'groupkgzzeo41', + title: '高级', + extraProps: { + display: 'accordion', + }, + items: [ + { + type: 'field', + name: 'fieldId', + title: { + label: '唯一标识', + }, + extraProps: { + display: 'block', + }, + setter: { + key: null, + ref: null, + props: { + placeholder: '请输入唯一标识', + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'useFieldIdAsDomId', + title: { + label: '将唯一标识用作 DOM ID', + }, + extraProps: { + display: 'block', + defaultValue: false, + }, + setter: { + key: null, + ref: null, + props: {}, + _owner: null, + }, + }, + { + type: 'field', + name: 'customClassName', + title: '自定义样式类', + extraProps: { + display: 'block', + defaultValue: '', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + placeholder: null, + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: 'events', + title: { + label: '动作设置', + tip: '点击 ? 查看如何设置组件的事件响应动作', + docUrl: 'https://lark.alipay.com/legao/legao/events-call', + }, + extraProps: { + display: 'accordion', + defaultValue: { + ignored: true, + }, + }, + setter: { + key: null, + ref: null, + props: { + events: [ + { + name: 'onClick', + title: '当点击时', + initialValue: + "/**\n * 容器 当点击时\n */\nfunction onClick(event) {\n console.log('onClick', event);\n}", + }, + { + name: 'onMouseEnter', + title: '当鼠标进入时', + initialValue: + "/**\n * 容器 当鼠标进入时\n */\nfunction onMouseEnter(event) {\n console.log('onMouseEnter', event);\n}", + }, + { + name: 'onMouseLeave', + title: '当鼠标离开时', + initialValue: + "/**\n * 容器 当鼠标离开时\n */\nfunction onMouseLeave(event) {\n console.log('onMouseLeave', event);\n}", + }, + ], + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'onClick', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseEnter', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseLeave', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + ], + }, + ], + experimental: { + callbacks: { + onNodeAdd: (dragment, self) => { console.log(dragment); }, + onNodeRemove: (dragment, self) => { console.log(dragment); } + }, + initials: [ + { + name: 'behavior', + }, + { + name: '__style__', + }, + { + name: 'fieldId', + }, + { + name: 'useFieldIdAsDomId', + }, + { + name: 'customClassName', + }, + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + filters: [ + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + autoruns: [], + }, +} as ComponentMetadata; diff --git a/packages/designer/tests/fixtures/component-metadata/div5.ts b/packages/designer/tests/fixtures/component-metadata/div5.ts new file mode 100644 index 0000000000..bf47a6e855 --- /dev/null +++ b/packages/designer/tests/fixtures/component-metadata/div5.ts @@ -0,0 +1,283 @@ +import { ComponentMetadata } from "@alilc/lowcode-types"; +export default { + componentName: 'Div', + npm: { + package: '@ali/vc-div', + componentName: 'Div', + }, + docUrl: 'https://github.com/alibaba/lowcode-materials/tree/main/docs', + devMode: 'proCode', + tags: ['布局'], + configure: { + props: [ + { + type: 'field', + name: 'behavior', + title: '默认状态', + extraProps: { + display: 'inline', + defaultValue: 'NORMAL', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + options: [ + { + title: '普通', + value: 'NORMAL', + }, + { + title: '隐藏', + value: 'HIDDEN', + }, + ], + loose: false, + cancelable: false, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: '__style__', + title: { + label: '样式设置', + tip: '点击 ? 查看样式设置器用法指南', + docUrl: 'https://lark.alipay.com/legao/help/design-tool-style', + }, + extraProps: { + display: 'accordion', + defaultValue: {}, + }, + setter: { + key: null, + ref: null, + props: { + advanced: true, + }, + _owner: null, + }, + }, + { + type: 'group', + name: 'groupkgzzeo41', + title: '高级', + extraProps: { + display: 'accordion', + }, + items: [ + { + type: 'field', + name: 'fieldId', + title: { + label: '唯一标识', + }, + extraProps: { + display: 'block', + }, + setter: { + key: null, + ref: null, + props: { + placeholder: '请输入唯一标识', + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'useFieldIdAsDomId', + title: { + label: '将唯一标识用作 DOM ID', + }, + extraProps: { + display: 'block', + defaultValue: false, + }, + setter: { + key: null, + ref: null, + props: {}, + _owner: null, + }, + }, + { + type: 'field', + name: 'customClassName', + title: '自定义样式类', + extraProps: { + display: 'block', + defaultValue: '', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + placeholder: null, + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: 'events', + title: { + label: '动作设置', + tip: '点击 ? 查看如何设置组件的事件响应动作', + docUrl: 'https://lark.alipay.com/legao/legao/events-call', + }, + extraProps: { + display: 'accordion', + defaultValue: { + ignored: true, + }, + }, + setter: { + key: null, + ref: null, + props: { + events: [ + { + name: 'onClick', + title: '当点击时', + initialValue: + "/**\n * 容器 当点击时\n */\nfunction onClick(event) {\n console.log('onClick', event);\n}", + }, + { + name: 'onMouseEnter', + title: '当鼠标进入时', + initialValue: + "/**\n * 容器 当鼠标进入时\n */\nfunction onMouseEnter(event) {\n console.log('onMouseEnter', event);\n}", + }, + { + name: 'onMouseLeave', + title: '当鼠标离开时', + initialValue: + "/**\n * 容器 当鼠标离开时\n */\nfunction onMouseLeave(event) {\n console.log('onMouseLeave', event);\n}", + }, + ], + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'onClick', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseEnter', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseLeave', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + ], + }, + ], + component: { + isContainer: true, + nestingRule: { + // parentWhitelist: 'Div', + // childWhitelist: 'Div', + }, + disableBehaviors: '*', + }, + supports: {}, + advanced: { + callbacks: { + onNodeAdd: (dragment, self) => { console.log(dragment); }, + onNodeRemove: (dragment, self) => { console.log(dragment); } + }, + initials: [ + { + name: 'behavior', + }, + { + name: '__style__', + }, + { + name: 'fieldId', + }, + { + name: 'useFieldIdAsDomId', + }, + { + name: 'customClassName', + }, + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + filters: [ + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + autoruns: [], + }, + }, +} as ComponentMetadata; diff --git a/packages/designer/tests/fixtures/component-metadata/div6.ts b/packages/designer/tests/fixtures/component-metadata/div6.ts new file mode 100644 index 0000000000..47e324a80b --- /dev/null +++ b/packages/designer/tests/fixtures/component-metadata/div6.ts @@ -0,0 +1,283 @@ +import { ComponentMetadata } from "@alilc/lowcode-types"; +export default { + componentName: 'Div', + npm: { + package: '@ali/vc-div', + componentName: 'Div', + }, + docUrl: 'https://github.com/alibaba/lowcode-materials/tree/main/docs', + devMode: 'proCode', + tags: ['布局'], + configure: { + props: [ + { + type: 'field', + name: 'behavior', + title: '默认状态', + extraProps: { + display: 'inline', + defaultValue: 'NORMAL', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + options: [ + { + title: '普通', + value: 'NORMAL', + }, + { + title: '隐藏', + value: 'HIDDEN', + }, + ], + loose: false, + cancelable: false, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: '__style__', + title: { + label: '样式设置', + tip: '点击 ? 查看样式设置器用法指南', + docUrl: 'https://lark.alipay.com/legao/help/design-tool-style', + }, + extraProps: { + display: 'accordion', + defaultValue: {}, + }, + setter: { + key: null, + ref: null, + props: { + advanced: true, + }, + _owner: null, + }, + }, + { + type: 'group', + name: 'groupkgzzeo41', + title: '高级', + extraProps: { + display: 'accordion', + }, + items: [ + { + type: 'field', + name: 'fieldId', + title: { + label: '唯一标识', + }, + extraProps: { + display: 'block', + }, + setter: { + key: null, + ref: null, + props: { + placeholder: '请输入唯一标识', + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'useFieldIdAsDomId', + title: { + label: '将唯一标识用作 DOM ID', + }, + extraProps: { + display: 'block', + defaultValue: false, + }, + setter: { + key: null, + ref: null, + props: {}, + _owner: null, + }, + }, + { + type: 'field', + name: 'customClassName', + title: '自定义样式类', + extraProps: { + display: 'block', + defaultValue: '', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + placeholder: null, + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: 'events', + title: { + label: '动作设置', + tip: '点击 ? 查看如何设置组件的事件响应动作', + docUrl: 'https://lark.alipay.com/legao/legao/events-call', + }, + extraProps: { + display: 'accordion', + defaultValue: { + ignored: true, + }, + }, + setter: { + key: null, + ref: null, + props: { + events: [ + { + name: 'onClick', + title: '当点击时', + initialValue: + "/**\n * 容器 当点击时\n */\nfunction onClick(event) {\n console.log('onClick', event);\n}", + }, + { + name: 'onMouseEnter', + title: '当鼠标进入时', + initialValue: + "/**\n * 容器 当鼠标进入时\n */\nfunction onMouseEnter(event) {\n console.log('onMouseEnter', event);\n}", + }, + { + name: 'onMouseLeave', + title: '当鼠标离开时', + initialValue: + "/**\n * 容器 当鼠标离开时\n */\nfunction onMouseLeave(event) {\n console.log('onMouseLeave', event);\n}", + }, + ], + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'onClick', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseEnter', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseLeave', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + ], + }, + ], + component: { + isContainer: true, + nestingRule: { + // parentWhitelist: 'Div', + // childWhitelist: 'Div', + }, + disableBehaviors: '*', + }, + supports: {}, + }, + experimental: { + callbacks: { + onNodeAdd: (dragment, self) => { console.log(dragment); }, + onNodeRemove: (dragment, self) => { console.log(dragment); } + }, + initials: [ + { + name: 'behavior', + }, + { + name: '__style__', + }, + { + name: 'fieldId', + }, + { + name: 'useFieldIdAsDomId', + }, + { + name: 'customClassName', + }, + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + filters: [ + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + autoruns: [], + }, +} as ComponentMetadata; diff --git a/packages/designer/tests/fixtures/component-metadata/div7.ts b/packages/designer/tests/fixtures/component-metadata/div7.ts new file mode 100644 index 0000000000..33bf012594 --- /dev/null +++ b/packages/designer/tests/fixtures/component-metadata/div7.ts @@ -0,0 +1,276 @@ +import { ComponentMetadata } from "@alilc/lowcode-types"; +export default { + componentName: 'Div', + npm: { + package: '@ali/vc-div', + componentName: 'Div', + }, + title: '容器', + docUrl: 'https://github.com/alibaba/lowcode-materials/tree/main/docs', + devMode: 'proCode', + tags: ['布局'], + configure: { + props: [ + { + type: 'field', + name: 'behavior', + title: '默认状态', + extraProps: { + display: 'inline', + defaultValue: 'NORMAL', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + options: [ + { + title: '普通', + value: 'NORMAL', + }, + { + title: '隐藏', + value: 'HIDDEN', + }, + ], + loose: false, + cancelable: false, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: '__style__', + title: { + label: '样式设置', + tip: '点击 ? 查看样式设置器用法指南', + docUrl: 'https://lark.alipay.com/legao/help/design-tool-style', + }, + extraProps: { + display: 'accordion', + defaultValue: {}, + }, + setter: { + key: null, + ref: null, + props: { + advanced: true, + }, + _owner: null, + }, + }, + { + type: 'group', + name: 'groupkgzzeo41', + title: '高级', + extraProps: { + display: 'accordion', + }, + items: [ + { + type: 'field', + name: 'fieldId', + title: { + label: '唯一标识', + }, + extraProps: { + display: 'block', + }, + setter: { + key: null, + ref: null, + props: { + placeholder: '请输入唯一标识', + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'useFieldIdAsDomId', + title: { + label: '将唯一标识用作 DOM ID', + }, + extraProps: { + display: 'block', + defaultValue: false, + }, + setter: { + key: null, + ref: null, + props: {}, + _owner: null, + }, + }, + { + type: 'field', + name: 'customClassName', + title: '自定义样式类', + extraProps: { + display: 'block', + defaultValue: '', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + placeholder: null, + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: 'events', + title: { + label: '动作设置', + tip: '点击 ? 查看如何设置组件的事件响应动作', + docUrl: 'https://lark.alipay.com/legao/legao/events-call', + }, + extraProps: { + display: 'accordion', + defaultValue: { + ignored: true, + }, + }, + setter: { + key: null, + ref: null, + props: { + events: [ + { + name: 'onClick', + title: '当点击时', + initialValue: + "/**\n * 容器 当点击时\n */\nfunction onClick(event) {\n console.log('onClick', event);\n}", + }, + { + name: 'onMouseEnter', + title: '当鼠标进入时', + initialValue: + "/**\n * 容器 当鼠标进入时\n */\nfunction onMouseEnter(event) {\n console.log('onMouseEnter', event);\n}", + }, + { + name: 'onMouseLeave', + title: '当鼠标离开时', + initialValue: + "/**\n * 容器 当鼠标离开时\n */\nfunction onMouseLeave(event) {\n console.log('onMouseLeave', event);\n}", + }, + ], + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'onClick', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseEnter', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseLeave', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + ], + }, + ], + supports: {}, + advanced: { + callbacks: { + onNodeAdd: (dragment, self) => { console.log(dragment); }, + onNodeRemove: (dragment, self) => { console.log(dragment); } + }, + initials: [ + { + name: 'behavior', + }, + { + name: '__style__', + }, + { + name: 'fieldId', + }, + { + name: 'useFieldIdAsDomId', + }, + { + name: 'customClassName', + }, + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + filters: [ + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + autoruns: [], + }, + }, +} as ComponentMetadata; diff --git a/packages/designer/tests/fixtures/component-metadata/div8.ts b/packages/designer/tests/fixtures/component-metadata/div8.ts new file mode 100644 index 0000000000..2686165697 --- /dev/null +++ b/packages/designer/tests/fixtures/component-metadata/div8.ts @@ -0,0 +1,12 @@ +import { ComponentMetadata } from "@alilc/lowcode-types"; +export default { + componentName: 'Div', + npm: { + package: '@ali/vc-div', + componentName: 'Div', + }, + title: '容器', + docUrl: 'https://github.com/alibaba/lowcode-materials/tree/main/docs', + devMode: 'proCode', + tags: ['布局'], +} as ComponentMetadata; diff --git a/packages/designer/tests/fixtures/component-metadata/div9.ts b/packages/designer/tests/fixtures/component-metadata/div9.ts new file mode 100644 index 0000000000..59b3346501 --- /dev/null +++ b/packages/designer/tests/fixtures/component-metadata/div9.ts @@ -0,0 +1,8 @@ +import { ComponentMetadata } from "@alilc/lowcode-types"; +export default { + componentName: 'Div', + title: '容器', + docUrl: 'https://github.com/alibaba/lowcode-materials/tree/main/docs', + devMode: 'proCode', + tags: ['布局'], +} as ComponentMetadata; diff --git a/packages/designer/tests/fixtures/component-metadata/page2.ts b/packages/designer/tests/fixtures/component-metadata/page2.ts new file mode 100644 index 0000000000..40f9d8e388 --- /dev/null +++ b/packages/designer/tests/fixtures/component-metadata/page2.ts @@ -0,0 +1,279 @@ +import { ComponentMetadata } from "@alilc/lowcode-types"; +export default { + componentName: 'Page', + npm: { + package: '@ali/vc-page', + }, + title: '容器', + docUrl: 'https://github.com/alibaba/lowcode-materials/tree/main/docs', + devMode: 'proCode', + tags: ['布局'], + configure: { + props: [ + { + type: 'field', + name: 'behavior', + title: '默认状态', + extraProps: { + display: 'inline', + defaultValue: 'NORMAL', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + options: [ + { + title: '普通', + value: 'NORMAL', + }, + { + title: '隐藏', + value: 'HIDDEN', + }, + ], + loose: false, + cancelable: false, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: '__style__', + title: { + label: '样式设置', + tip: '点击 ? 查看样式设置器用法指南', + docUrl: 'https://lark.alipay.com/legao/help/design-tool-style', + }, + extraProps: { + display: 'accordion', + defaultValue: {}, + }, + setter: { + key: null, + ref: null, + props: { + advanced: true, + }, + _owner: null, + }, + }, + { + type: 'group', + name: 'groupkgzzeo41', + title: '高级', + extraProps: { + display: 'accordion', + }, + items: [ + { + type: 'field', + name: 'fieldId', + title: { + label: '唯一标识', + }, + extraProps: { + display: 'block', + }, + setter: { + key: null, + ref: null, + props: { + placeholder: '请输入唯一标识', + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'useFieldIdAsDomId', + title: { + label: '将唯一标识用作 DOM ID', + }, + extraProps: { + display: 'block', + defaultValue: false, + }, + setter: { + key: null, + ref: null, + props: {}, + _owner: null, + }, + }, + { + type: 'field', + name: 'customClassName', + title: '自定义样式类', + extraProps: { + display: 'block', + defaultValue: '', + }, + setter: { + componentName: 'MixedSetter', + props: { + setters: [ + { + key: null, + ref: null, + props: { + placeholder: null, + multiline: false, + rows: 10, + required: false, + pattern: null, + maxLength: null, + }, + _owner: null, + }, + 'VariableSetter', + ], + }, + }, + }, + { + type: 'field', + name: 'events', + title: { + label: '动作设置', + tip: '点击 ? 查看如何设置组件的事件响应动作', + docUrl: 'https://lark.alipay.com/legao/legao/events-call', + }, + extraProps: { + display: 'accordion', + defaultValue: { + ignored: true, + }, + }, + setter: { + key: null, + ref: null, + props: { + events: [ + { + name: 'onClick', + title: '当点击时', + initialValue: + "/**\n * 容器 当点击时\n */\nfunction onClick(event) {\n console.log('onClick', event);\n}", + }, + { + name: 'onMouseEnter', + title: '当鼠标进入时', + initialValue: + "/**\n * 容器 当鼠标进入时\n */\nfunction onMouseEnter(event) {\n console.log('onMouseEnter', event);\n}", + }, + { + name: 'onMouseLeave', + title: '当鼠标离开时', + initialValue: + "/**\n * 容器 当鼠标离开时\n */\nfunction onMouseLeave(event) {\n console.log('onMouseLeave', event);\n}", + }, + ], + }, + _owner: null, + }, + }, + { + type: 'field', + name: 'onClick', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseEnter', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + { + type: 'field', + name: 'onMouseLeave', + extraProps: { + defaultValue: { + ignored: true, + }, + }, + setter: 'I18nSetter', + }, + ], + }, + ], + component: { + isContainer: true, + nestingRule: { + // parentWhitelist: 'Div', + // childWhitelist: 'Div', + }, + }, + supports: {}, + }, + experimental: { + callbacks: {}, + initials: [ + { + name: 'behavior', + }, + { + name: '__style__', + }, + { + name: 'fieldId', + }, + { + name: 'useFieldIdAsDomId', + }, + { + name: 'customClassName', + }, + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + filters: [ + { + name: 'events', + }, + { + name: 'onClick', + }, + { + name: 'onMouseEnter', + }, + { + name: 'onMouseLeave', + }, + ], + autoruns: [], + }, +} as ComponentMetadata; diff --git a/packages/designer/tests/main/meta/component-meta.test.ts b/packages/designer/tests/main/meta/component-meta.test.ts index 8ca8e84b17..a1a113d935 100644 --- a/packages/designer/tests/main/meta/component-meta.test.ts +++ b/packages/designer/tests/main/meta/component-meta.test.ts @@ -2,7 +2,32 @@ import '../../fixtures/window'; import { Node } from '../../../src/document/node/node'; import { Designer } from '../../../src/designer/designer'; import divMeta from '../../fixtures/component-metadata/div'; -import { ComponentMeta, isComponentMeta, removeBuiltinComponentAction, addBuiltinComponentAction } from '../../../src/component-meta'; +import div2Meta from '../../fixtures/component-metadata/div2'; +import div3Meta from '../../fixtures/component-metadata/div3'; +import div4Meta from '../../fixtures/component-metadata/div4'; +import div5Meta from '../../fixtures/component-metadata/div5'; +import div6Meta from '../../fixtures/component-metadata/div6'; +import div7Meta from '../../fixtures/component-metadata/div7'; +import div8Meta from '../../fixtures/component-metadata/div8'; +import div9Meta from '../../fixtures/component-metadata/div9'; +import div10Meta from '../../fixtures/component-metadata/div10'; +import abcgroup from '../../fixtures/component-metadata/abcgroup'; +import abcitem from '../../fixtures/component-metadata/abcitem'; +import abcnode from '../../fixtures/component-metadata/abcnode'; +import abcoption from '../../fixtures/component-metadata/abcoption'; +import page2Meta from '../../fixtures/component-metadata/page2'; +import { + ComponentMeta, + isComponentMeta, + removeBuiltinComponentAction, + addBuiltinComponentAction, + modifyBuiltinComponentAction, + ensureAList, + buildFilter, + registerMetadataTransducer, + getRegisteredMetadataTransducers, +} from '../../../src/component-meta'; +import { componentDefaults } from '../../../src/transducers'; const mockCreateSettingEntry = jest.fn(); jest.mock('../../../src/designer/designer', () => { @@ -34,11 +59,64 @@ describe('组件元数据处理', () => { expect(typeof meta.icon).toBe('function'); expect(meta.getMetadata().title).toBe('容器'); expect(meta.title).toEqual({ type: 'i18n', 'en-US': 'Div', 'zh-CN': '容器' }); + expect(meta.isMinimalRenderUnit).toBeFalsy(); + expect(meta.isTopFixed).toBeFalsy(); meta.setNpm({ package: '@ali/vc-div', componentName: 'Div' }); expect(meta.npm).toEqual({ package: '@ali/vc-div', componentName: 'Div' }); + meta.npm = { package: '@ali/vc-div', componentName: 'Div' }; + expect(meta.npm).toEqual({ package: '@ali/vc-div', componentName: 'Div' }); + + const mockFn = jest.fn(); + const offFn = meta.onMetadataChange(mockFn); meta.setMetadata(divMeta); + expect(mockFn).toHaveBeenCalledTimes(1); + offFn(); + meta.setMetadata(divMeta); + // 不会再触发函数 + expect(mockFn).toHaveBeenCalledTimes(1); + }); + + it('构造函数 - 兼容场景(title 是个普通对象)', () => { + const meta = new ComponentMeta(designer, div2Meta); + expect(meta.title).toEqual('容器'); + + expect(meta.isTopFixed).toBeTruthy(); + }); + + it('构造函数 - 兼容场景(title fallback 到 componentName)', () => { + const meta = new ComponentMeta(designer, div3Meta); + expect(meta.title).toEqual('Div'); + }); + + it('构造函数 - 兼容场景(configure 是个数组)', () => { + const meta = new ComponentMeta(designer, div4Meta); + expect(meta.configure).toEqual(div4Meta.configure); + }); + + it('构造函数 - 兼容场景(使用 experimental)', () => { + const meta = new ComponentMeta(designer, div6Meta); + expect(meta.getMetadata().configure.advanced.initials).toHaveLength(9); + }); + + it('构造函数 - 兼容场景(没有 configure.component)', () => { + const meta = new ComponentMeta(designer, div7Meta); + expect(meta.isContainer).toBeFalsy(); + expect(meta.isModal).toBeFalsy(); + }); + + it('构造函数 - 兼容场景(没有 configure)', () => { + const meta = new ComponentMeta(designer, div8Meta); + expect(meta.configure).toEqual([]); + }); + + it('构造函数 - 兼容场景(没有 npm)', () => { + const meta = new ComponentMeta(designer, div9Meta); + expect(meta.npm).toBeUndefined(); + + meta.setNpm({ package: '@ali/vc-div', componentName: 'Div' }); + expect(meta.npm).toEqual({ package: '@ali/vc-div', componentName: 'Div' }); }); it('availableActions', () => { @@ -64,16 +142,116 @@ describe('组件元数据处理', () => { expect(meta.availableActions[1].name).toBe('copy'); expect(meta.availableActions[4].name).toBe('new'); }); + + it('availableActions - disableBehaviors: *', () => { + const meta = new ComponentMeta(designer, div5Meta); + expect(meta.availableActions).toHaveLength(0); + }); + + it('availableActions - rootCompoment', () => { + const meta = new ComponentMeta(designer, page2Meta); + // (hide + new) left + expect(meta.availableActions).toHaveLength(2); + }); + + describe('checkNesting', () => { + const mockNode = (componentName) => { + return { + internalToShellNode() { + return { + componentName, + }; + }, + isNode: true, + }; + }; + const mockNodeForm = mockNode('Form'); + const mockNodeImage = mockNode('Image'); + const mockNodeDiv = mockNode('Div'); + it('checkNestingUp', () => { + const meta1 = new ComponentMeta(designer, divMeta); + // 没有配置 parentWhitelist,判断默认为 true + expect(meta1.checkNestingUp(mockNodeDiv, mockNodeDiv)).toBeTruthy(); + + const meta2 = new ComponentMeta(designer, div10Meta); + expect(meta2.checkNestingUp(mockNodeDiv, mockNodeForm)).toBeTruthy(); + expect(meta2.checkNestingUp(mockNodeDiv, mockNodeDiv)).toBeFalsy(); + }); + + it('checkNestingDown', () => { + const meta1 = new ComponentMeta(designer, divMeta); + // 没有配置 childWhitelist,判断默认为 true + expect(meta1.checkNestingDown(mockNodeDiv, mockNodeDiv)).toBeTruthy(); + + const meta2 = new ComponentMeta(designer, div10Meta); + expect(meta2.checkNestingDown(mockNodeDiv, mockNodeForm)).toBeFalsy(); + expect(meta2.checkNestingDown(mockNodeDiv, mockNodeImage)).toBeTruthy(); + }); + }); }); -describe('组件元数据transducers', () => { +describe('组件元数据 transducers', () => { it('legacyIssues', () => { const legacyMeta: any = { ...divMeta, - devMode: 'procode' - } + devMode: 'procode', + }; const meta = new ComponentMeta(designer, legacyMeta); const metadata = meta.getMetadata(); expect(metadata.devMode).toBe('proCode'); - }) -}) + }); +}); + +describe('帮助函数', () => { + it('ensureAList', () => { + expect(ensureAList()).toBeNull(); + expect(ensureAList(1)).toBeNull(); + expect(ensureAList([])).toBeNull(); + expect(ensureAList('copy lock')).toEqual(['copy', 'lock']); + expect(ensureAList(['copy', 'lock'])).toEqual(['copy', 'lock']); + }); + + it('buildFilter', () => { + const mockFn = () => {}; + expect(buildFilter()).toBeNull(); + expect(buildFilter([])).toBeNull(); + expect(buildFilter(mockFn)).toBe(mockFn); + + const mockRE = /xxx/; + const filter = buildFilter(mockRE); + expect(filter({ componentName: 'xxx' })).toBeTruthy(); + expect(filter({ componentName: 'yyy' })).toBeFalsy(); + + expect(buildFilter('xxx yyy')({ componentName: 'xxx' })).toBeTruthy(); + expect(buildFilter('xxx yyy')({ componentName: 'zzz' })).toBeFalsy(); + }); + + it('registerMetadataTransducer', () => { + expect(getRegisteredMetadataTransducers()).toHaveLength(2); + // 插入到 legacy-issues 和 component-defaults 的中间 + registerMetadataTransducer((metadata) => metadata, 3, 'noop'); + expect(getRegisteredMetadataTransducers()).toHaveLength(3); + + registerMetadataTransducer((metadata) => metadata); + expect(getRegisteredMetadataTransducers()).toHaveLength(4); + }); + + it('modifyBuiltinComponentAction', () => { + modifyBuiltinComponentAction('copy', (action) => { + expect(action.name).toBe('copy'); + }); + }); +}); + +describe('transducers', () => { + it('componentDefaults', () => { + const meta1 = new ComponentMeta(designer, abcgroup); + const meta2 = new ComponentMeta(designer, abcitem); + const meta3 = new ComponentMeta(designer, abcnode); + const meta4 = new ComponentMeta(designer, abcoption); + expect(meta1.getMetadata().configure.component.nestingRule.childWhitelist).toEqual(['Abc']); + expect(meta2.getMetadata().configure.component.nestingRule.parentWhitelist).toEqual(['Abc']); + expect(meta3.getMetadata().configure.component.nestingRule.parentWhitelist).toEqual(['Abc', 'Abc.Node']); + expect(meta4.getMetadata().configure.component.nestingRule.parentWhitelist).toEqual(['Abc']); + }); +}); diff --git a/packages/designer/tests/utils-ut/misc.test.ts b/packages/designer/tests/utils-ut/misc.test.ts index a9dcfeeb5f..dc3dcd6bbb 100644 --- a/packages/designer/tests/utils-ut/misc.test.ts +++ b/packages/designer/tests/utils-ut/misc.test.ts @@ -1,5 +1,5 @@ // @ts-nocheck -import { isElementNode, isDOMNodeVisible } from '../../src/utils/misc'; +import { isElementNode, isDOMNodeVisible, normalizeTriggers } from '../../src/utils/misc'; it('isElementNode', () => { expect(isElementNode(document.createElement('div'))).toBeTruthy(); @@ -148,3 +148,7 @@ describe('isDOMNodeVisible', () => { ).toBeFalsy(); }); }); + +it('normalizeTriggers', () => { + expect(normalizeTriggers(['n', 'w'])).toEqual(['N', 'W']); +}); diff --git a/packages/utils/src/misc.ts b/packages/utils/src/misc.ts index 1cde5adb30..87eea62f82 100644 --- a/packages/utils/src/misc.ts +++ b/packages/utils/src/misc.ts @@ -104,4 +104,8 @@ export function deprecate(fail: any, message: string, alterative?: string) { if (fail) { console.warn(`Deprecation: ${message}` + (alterative ? `, use ${alterative} instead.` : '')); } +} + +export function isRegExp(obj: any): obj is RegExp { + return obj && obj.test && obj.exec && obj.compile; } \ No newline at end of file From abf8fae3ef4d62b5688362e1b98f1b508a207029 Mon Sep 17 00:00:00 2001 From: zyy7259 Date: Wed, 15 Jun 2022 15:02:50 +0800 Subject: [PATCH 047/823] feat: refine pop drawer --- .../editor-skeleton/src/components/popup/index.tsx | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/packages/editor-skeleton/src/components/popup/index.tsx b/packages/editor-skeleton/src/components/popup/index.tsx index 192fad32ba..d6cdef2baa 100644 --- a/packages/editor-skeleton/src/components/popup/index.tsx +++ b/packages/editor-skeleton/src/components/popup/index.tsx @@ -1,6 +1,6 @@ import { createContext, ReactNode, Component, PureComponent } from 'react'; import { EventEmitter } from 'events'; -import { Drawer } from '@alifd/next'; +import { Drawer, ConfigProvider } from '@alifd/next'; import { uniqueId } from '@alilc/lowcode-utils'; import './style.less'; @@ -82,6 +82,8 @@ export default class PopupService extends Component<{ popupPipe?: PopupPipe; act export class PopupContent extends PureComponent<{ safeId?: string }> { static contextType = PopupContext; + popupContainerId = uniqueId('popupContainer'); + state: any = { visible: false, offsetX: -300, @@ -151,7 +153,7 @@ export class PopupContent extends PureComponent<{ safeId?: string }> { }} trigger={
} triggerType="click" - canCloseByOutSideClick={false} + canCloseByOutSideClick animation={false} onClose={this.onClose} id={this.props.safeId} @@ -161,9 +163,13 @@ export class PopupContent extends PureComponent<{ safeId?: string }> {
{title}
- {content} + + {content} +
+
+
); } From 97665937192eda5710fb47086dc2085526787051 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Thu, 16 Jun 2022 14:22:50 +0800 Subject: [PATCH 048/823] chore: add contributor section to readme --- packages/engine/README-zh_CN.md | 10 +++++++++- packages/engine/README.md | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/packages/engine/README-zh_CN.md b/packages/engine/README-zh_CN.md index b668821ca0..cdd5ca4796 100644 --- a/packages/engine/README-zh_CN.md +++ b/packages/engine/README-zh_CN.md @@ -151,4 +151,12 @@ lowcode-engine 启动后,提供了几个 umd 文件,可以结合 [lowcode-de > 强烈推荐阅读 [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way)、[《如何向开源社区提问题》](https://github.com/seajs/seajs/issues/545) 和 [《如何有效地报告 Bug》](http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html)、[《如何向开源项目提交无法解答的问题》](https://zhuanlan.zhihu.com/p/25795393),更好的问题更容易获得帮助。(此段参考 [antd](https://github.com/ant-design/ant-design)) 关于提交 PR: -请将目标合并分支设置为 **develop**,不要指定 **main** 分支,在发布正式版本后,develop 分支将会合入 main 分支。 \ No newline at end of file +请将目标合并分支设置为 **develop**,不要指定 **main** 分支,在发布正式版本后,develop 分支将会合入 main 分支。 + +## ❤️ 致谢 + +感谢所有为引擎项目贡献力量的同学们~ + +

+ +

\ No newline at end of file diff --git a/packages/engine/README.md b/packages/engine/README.md index 01a1c95588..51eb9f5504 100644 --- a/packages/engine/README.md +++ b/packages/engine/README.md @@ -151,4 +151,12 @@ Please read first: > Strongly recommend reading ["The Wisdom of Asking Questions"](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way), ["How to Ask Questions to the Open Source Community"](https: //github.com/seajs/seajs/issues/545) and [How to Report Bugs Effectively](http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html), [ "How to Submit Unanswerable Questions to Open Source Projects"](https://zhuanlan.zhihu.com/p/25795393), better questions are easier to get help. (This paragraph refers to [antd](https://github.com/ant-design/ant-design)) About Pull Request: -- set the target branch to **develop** other than **main** \ No newline at end of file +- set the target branch to **develop** other than **main** + +## ❤️ Contributors + +Special thanks to everyone who contributed to this project. + +

+ +

\ No newline at end of file From 8dab2ce68a24567262e70139a3165fe2a32646b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Thu, 16 Jun 2022 23:41:30 +0800 Subject: [PATCH 049/823] chore: support coverage diff --- .github/workflows/cov packages.yml | 11 ++++------- packages/designer/README.md | 0 2 files changed, 4 insertions(+), 7 deletions(-) create mode 100644 packages/designer/README.md diff --git a/.github/workflows/cov packages.yml b/.github/workflows/cov packages.yml index aa80d5f3ad..228e1cf989 100644 --- a/.github/workflows/cov packages.yml +++ b/.github/workflows/cov packages.yml @@ -26,9 +26,8 @@ jobs: with: working-directory: packages/designer test-script: npm test -- --jest-ci --jest-json --jest-coverage --jest-testLocationInResults --jest-outputFile=report.json - skip-step: install + package-manager: yarn annotations: none - base-coverage-file: ./report.json cov-renderer-core: runs-on: ubuntu-latest @@ -49,9 +48,8 @@ jobs: with: working-directory: packages/renderer-core test-script: npm test -- --jest-ci --jest-json --jest-coverage --jest-testLocationInResults --jest-outputFile=report.json - skip-step: install + package-manager: yarn annotations: none - base-coverage-file: ./report.json cov-react-simulator-renderer: runs-on: ubuntu-latest @@ -72,6 +70,5 @@ jobs: with: working-directory: packages/react-simulator-renderer test-script: npm test -- --jest-ci --jest-json --jest-coverage --jest-testLocationInResults --jest-outputFile=report.json - skip-step: install - annotations: none - base-coverage-file: ./report.json \ No newline at end of file + package-manager: yarn + annotations: none \ No newline at end of file diff --git a/packages/designer/README.md b/packages/designer/README.md new file mode 100644 index 0000000000..e69de29bb2 From e005ca2e2e2e7d18bd7993bf63976b8a9ee58f66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Thu, 16 Jun 2022 23:42:22 +0800 Subject: [PATCH 050/823] chore: suppress boring warnings emitted from babel --- packages/designer/tests/fixtures/window.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/designer/tests/fixtures/window.ts b/packages/designer/tests/fixtures/window.ts index 86d1787b73..6f3e03a884 100644 --- a/packages/designer/tests/fixtures/window.ts +++ b/packages/designer/tests/fixtures/window.ts @@ -19,4 +19,10 @@ Object.defineProperty(window, 'React', { window.scrollTo = () => {}; window.console.warn = () => {}; +const originalLog = window.console.log; +window.console.log = (...args) => { + // suppress boring warnings + if (args[0].includes('@babel/plugin-proposal-private-property-in-object')) return; + originalLog.apply(window.console, args); +}; window.React = window.React || {}; From cbd95a1778415406670f37507ce957af6b3ecd4a Mon Sep 17 00:00:00 2001 From: Yingya Zhang Date: Fri, 17 Jun 2022 16:44:28 +0800 Subject: [PATCH 051/823] feat: support for hiding settings tabs when there is only one item (#669) --- packages/editor-core/src/config.ts | 8 ++++++++ .../src/components/settings/settings-primary-pane.tsx | 7 ++++++- .../editor-skeleton/src/components/settings/style.less | 10 ++++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/packages/editor-core/src/config.ts b/packages/editor-core/src/config.ts index e90e83bea3..71c16505c9 100644 --- a/packages/editor-core/src/config.ts +++ b/packages/editor-core/src/config.ts @@ -100,6 +100,10 @@ const VALID_ENGINE_OPTIONS = { default: false, description: '当选中节点切换时,是否停留在相同的设置 tab 上', }, + hideSettingsTabsWhenOnlyOneItem: { + type: 'boolean', + description: '是否在只有一个 item 的时候隐藏设置 tabs', + }, loadingComponent: { type: 'ComponentType', default: undefined, @@ -205,6 +209,10 @@ export interface EngineOptions { * 当选中节点切换时,是否停留在相同的设置 tab 上,默认值:false */ stayOnTheSameSettingTab?: boolean; + /** + * 是否在只有一个 item 的时候隐藏设置 tabs,默认值:false + */ + hideSettingsTabsWhenOnlyOneItem?: boolean; /** * 自定义 loading 组件 */ diff --git a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx index 52a84a24f3..c52780541e 100644 --- a/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-primary-pane.tsx @@ -2,6 +2,7 @@ import React, { Component } from 'react'; import { Tab, Breadcrumb } from '@alifd/next'; import { Title, observer, Editor, obx, globalContext, engineConfig, makeObservable } from '@alilc/lowcode-editor-core'; import { Node, isSettingField, SettingField, Designer } from '@alilc/lowcode-designer'; +import classNames from 'classnames'; import { SettingsMain } from './main'; import { SettingsPane } from './settings-pane'; import { StageBox } from '../stage-box'; @@ -229,8 +230,12 @@ export class SettingsPrimaryPane extends Component<{ editor: Editor; config: any }); const activeKey = matched ? this._activeKey : (items[0] as SettingField).name; + const className = classNames('lc-settings-main', { + 'lc-settings-hide-tabs': + items.length === 1 && engineConfig.get('hideSettingsTabsWhenOnlyOneItem', false), + }); return ( -
+
{ this.renderBreadcrumb() } Date: Mon, 20 Jun 2022 15:01:32 +0800 Subject: [PATCH 052/823] feat: requestHandlersMap should be optional --- packages/editor-core/src/config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/editor-core/src/config.ts b/packages/editor-core/src/config.ts index 71c16505c9..730a817499 100644 --- a/packages/editor-core/src/config.ts +++ b/packages/editor-core/src/config.ts @@ -247,7 +247,7 @@ export interface EngineOptions { /** * 数据源引擎的请求处理器映射 */ - requestHandlersMap: RequestHandlersMap; + requestHandlersMap?: RequestHandlersMap; } const getStrictModeValue = (engineOptions: EngineOptions, defaultValue: boolean): boolean => { From 3dd0b6d0a86267e3029c176ff49aff793ce3e186 Mon Sep 17 00:00:00 2001 From: liujuping Date: Wed, 22 Jun 2022 12:49:48 +0800 Subject: [PATCH 053/823] fix: when designMode is not design, the hidden attribute does not take effect --- packages/renderer-core/src/hoc/leaf.tsx | 4 +- packages/renderer-core/src/renderer/base.tsx | 4 - .../__snapshots__/renderer.test.tsx.snap | 17 ++++ .../tests/renderer/renderer.test.tsx | 81 ++++++++++++++++++- 4 files changed, 99 insertions(+), 7 deletions(-) diff --git a/packages/renderer-core/src/hoc/leaf.tsx b/packages/renderer-core/src/hoc/leaf.tsx index cb09ec2e83..e6981e729a 100644 --- a/packages/renderer-core/src/hoc/leaf.tsx +++ b/packages/renderer-core/src/hoc/leaf.tsx @@ -367,7 +367,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { return null; } - _leaf = _leaf || getNode(componentId); + _leaf = _leaf || getNode?.(componentId); if (_leaf && this.curEventLeaf && _leaf !== this.curEventLeaf) { this.disposeFunctions.forEach((fn) => fn()); this.disposeFunctions = []; @@ -513,7 +513,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { } get leaf(): Node | undefined { - return this.props._leaf || getNode(componentCacheId); + return this.props._leaf || getNode?.(componentCacheId); } render() { diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 830c92dbbc..6a6d622b15 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -475,10 +475,6 @@ export default function baseRendererFactory(): IBaseRenderComponent { // DesignMode 为 design 情况下,需要进入 leaf Hoc,进行相关事件注册 const displayInHook = engine?.props?.designMode === 'design'; - if (schema.hidden && !displayInHook) { - return null; - } - if (schema.loop != null) { const loop = parseData(schema.loop, scope); const useLoop = isUseLoop(loop, this._designModeIsDesign); diff --git a/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap b/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap index 5ef56f7755..76ed01e02d 100644 --- a/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap +++ b/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap @@ -1121,3 +1121,20 @@ exports[`JSExpression base props 1`] = ` />
`; + +exports[`designMode designMode:default 1`] = ` +
+
+
+
+
+`; diff --git a/packages/renderer-core/tests/renderer/renderer.test.tsx b/packages/renderer-core/tests/renderer/renderer.test.tsx index d1917c5a53..9847c6cc14 100644 --- a/packages/renderer-core/tests/renderer/renderer.test.tsx +++ b/packages/renderer-core/tests/renderer/renderer.test.tsx @@ -7,7 +7,7 @@ import components from '../utils/components'; const Renderer = rendererFactory(); -function getComp(schema, comp = null): Promise<{ +function getComp(schema, comp = null, others = {}): Promise<{ component, inst, }> { @@ -17,6 +17,7 @@ function getComp(schema, comp = null): Promise<{ ); const componentInstance = component.root; @@ -321,4 +322,82 @@ describe('JSExpression', () => { done(); }); }) +}); + +describe("designMode", () => { + it('designMode:default', (done) => { + const schema = { + componentName: 'Page', + props: {}, + children: [ + { + componentName: "Div", + props: { + className: 'div-ut', + children: [ + { + componentName: "Div", + visible: true, + props: { + className: 'div-ut-children', + } + } + ] + } + } + ] + }; + + getComp(schema, components.Div).then(({ component, inst }) => { + expect(inst.length).toBe(2); + expect(inst[0].props.className).toBe('div-ut'); + expect(inst[1].props.className).toBe('div-ut-children'); + componentSnapshot = component; + done(); + }); + }); + it('designMode:design', (done) => { + const schema = { + componentName: 'Page', + props: {}, + children: [ + { + componentName: "Div", + id: '0', + props: { + className: 'div-ut', + children: [ + { + componentName: "Div", + id: 'hiddenId', + hidden: true, + props: { + className: 'div-ut-children', + } + } + ] + } + } + ] + }; + + getComp(schema, components.Div, { + designMode: 'design', + getNode: (id) => { + if (id === 'hiddenId') { + return { + export() { + return { + hidden: true, + }; + } + } + } + } + }).then(({ component, inst }) => { + expect(inst.length).toBe(1); + expect(inst[0].props.className).toBe('div-ut'); + done(); + }); + }); }) \ No newline at end of file From 8f237b108953d69e953a3cd4e81d397053dddeb4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Tue, 21 Jun 2022 21:01:50 +0800 Subject: [PATCH 054/823] test: increase branch coverage percentage of designer to 81.66% --- package.json | 3 +- packages/designer/jest.config.js | 2 +- packages/designer/src/document/history.ts | 50 ++- .../designer/src/plugin/plugin-manager.ts | 3 +- .../tests/__mocks__/document-model.ts | 1 - .../__snapshots__/history.test.ts.snap | 9 + .../tests/document/history/history.test.ts | 353 +++++++++++++++++ .../tests/document/history/session.test.ts | 57 +++ .../tests/plugin/plugin-manager.test.ts | 358 +++++++++++++----- .../tests/plugin/plugin-utils.test.ts | 85 +++++ .../tests/project/project-methods.test.ts | 2 + 11 files changed, 807 insertions(+), 116 deletions(-) create mode 100644 packages/designer/tests/document/history/__snapshots__/history.test.ts.snap create mode 100644 packages/designer/tests/document/history/history.test.ts create mode 100644 packages/designer/tests/document/history/session.test.ts create mode 100644 packages/designer/tests/plugin/plugin-utils.test.ts diff --git a/package.json b/package.json index 90c099d156..38299c96e2 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,8 @@ ], "nohoist": [ "**/css-modules-typescript-loader", - "**/@alife/theme-lowcode-*" + "**/@alifc/theme-lowcode-*", + "**/jest" ] }, "scripts": { diff --git a/packages/designer/jest.config.js b/packages/designer/jest.config.js index 43bea9064d..2ffc057fab 100644 --- a/packages/designer/jest.config.js +++ b/packages/designer/jest.config.js @@ -10,7 +10,7 @@ const jestConfig = { // // '^.+\\.(js|jsx)$': 'babel-jest', // }, // testMatch: ['**/document/node/node.test.ts'], - // testMatch: ['**/component-meta.test.ts'], + // testMatch: ['**/history/history.test.ts'], // testMatch: ['**/plugin/plugin-manager.test.ts'], // testMatch: ['(/tests?/.*(test))\\.[jt]s$'], transformIgnorePatterns: [ diff --git a/packages/designer/src/document/history.ts b/packages/designer/src/document/history.ts index 8828b8e135..5ac0d99cc3 100644 --- a/packages/designer/src/document/history.ts +++ b/packages/designer/src/document/history.ts @@ -3,27 +3,12 @@ import { autorun, reaction, mobx, untracked, globalContext, Editor } from '@alil import { NodeSchema } from '@alilc/lowcode-types'; import { History as ShellHistory } from '@alilc/lowcode-shell'; -// TODO: cache to localStorage - -export interface Serialization { - serialize(data: NodeSchema): T; - unserialize(data: T): NodeSchema; -} - -let currentSerialization: Serialization = { - serialize(data: NodeSchema): string { - return JSON.stringify(data); - }, - unserialize(data: string) { - return JSON.parse(data); - }, -}; - -export function setSerialization(serialization: Serialization) { - currentSerialization = serialization; +export interface Serialization { + serialize(data: K): T; + unserialize(data: T): K; } -export class History { +export class History { private session: Session; private records: Session[]; @@ -34,16 +19,29 @@ export class History { private asleep = false; - constructor(logger: () => any, private redoer: (data: NodeSchema) => void, private timeGap: number = 1000) { + private currentSerialization: Serialization = { + serialize(data: T): string { + return JSON.stringify(data); + }, + unserialize(data: string) { + return JSON.parse(data); + }, + }; + + setSerialization(serialization: Serialization) { + this.currentSerialization = serialization; + } + + constructor(dataFn: () => T, private redoer: (data: T) => void, private timeGap: number = 1000) { this.session = new Session(0, null, this.timeGap); this.records = [this.session]; reaction(() => { - return logger(); - }, (data) => { + return dataFn(); + }, (data: T) => { if (this.asleep) return; untracked(() => { - const log = currentSerialization.serialize(data); + const log = this.currentSerialization.serialize(data); if (this.session.isActive()) { this.session.log(log); } else { @@ -98,9 +96,9 @@ export class History { this.sleep(); try { - this.redoer(currentSerialization.unserialize(hotData)); + this.redoer(this.currentSerialization.unserialize(hotData)); this.emitter.emit('cursor', hotData); - } catch (e) { + } catch (e) /* istanbul ignore next */ { console.error(e); } @@ -201,7 +199,7 @@ export class History { } } -class Session { +export class Session { private _data: any; private activeTimer: any; diff --git a/packages/designer/src/plugin/plugin-manager.ts b/packages/designer/src/plugin/plugin-manager.ts index e90b51cfe1..dc803ddfec 100644 --- a/packages/designer/src/plugin/plugin-manager.ts +++ b/packages/designer/src/plugin/plugin-manager.ts @@ -148,7 +148,7 @@ export class LowCodePluginManager implements ILowCodePluginManager { for (const pluginName of sequence) { try { await this.pluginsMap.get(pluginName)!.init(); - } catch (e) { + } catch (e) /* istanbul ignore next */ { logger.error( `Failed to init plugin:${pluginName}, it maybe affect those plugins which depend on this.`, ); @@ -189,6 +189,7 @@ export class LowCodePluginManager implements ILowCodePluginManager { }); } + /* istanbul ignore next */ setDisabled(pluginName: string, flag = true) { logger.warn(`plugin:${pluginName} has been set disable:${flag}`); this.pluginsMap.get(pluginName)?.setDisabled(flag); diff --git a/packages/designer/tests/__mocks__/document-model.ts b/packages/designer/tests/__mocks__/document-model.ts index c5f4fef8b1..0eb1910fc8 100644 --- a/packages/designer/tests/__mocks__/document-model.ts +++ b/packages/designer/tests/__mocks__/document-model.ts @@ -2,7 +2,6 @@ export class DocumentModel { a = 1; c = {}; constructor() { - console.log('xxxxxxxxxxxxxxxxxxxx'); const b = { x: { y: 2 } }; const c: number = 2; this.a = b?.x?.y; diff --git a/packages/designer/tests/document/history/__snapshots__/history.test.ts.snap b/packages/designer/tests/document/history/__snapshots__/history.test.ts.snap new file mode 100644 index 0000000000..1249a41655 --- /dev/null +++ b/packages/designer/tests/document/history/__snapshots__/history.test.ts.snap @@ -0,0 +1,9 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`History data function & records 1`] = `"{\\"data\\":1,\\"children\\":[{\\"data\\":2,\\"children\\":[]}]}"`; + +exports[`History data function & records 2`] = `"{\\"data\\":3,\\"children\\":[{\\"data\\":2,\\"children\\":[]}]}"`; + +exports[`History data function & records 3`] = `"{\\"data\\":5,\\"children\\":[{\\"data\\":2,\\"children\\":[]}]}"`; + +exports[`History data function & records 4`] = `"{\\"data\\":7,\\"children\\":[{\\"data\\":2,\\"children\\":[]}]}"`; diff --git a/packages/designer/tests/document/history/history.test.ts b/packages/designer/tests/document/history/history.test.ts new file mode 100644 index 0000000000..a4c6d3a66b --- /dev/null +++ b/packages/designer/tests/document/history/history.test.ts @@ -0,0 +1,353 @@ +import '../../fixtures/window'; +import { mobx, makeAutoObservable, globalContext, Editor } from '@alilc/lowcode-editor-core'; +import { History } from '../../../src/document/history'; +import { delay } from '../../utils/misc'; + +class Node { + data: number; + children: Node[] = []; + + constructor(data: number) { + makeAutoObservable(this); + this.data = data; + } + + addNode(node: Node) { + this.children.push(node); + } + + toObject() { + return { + data: this.data, + children: this.children.map((c) => c.toObject()), + }; + } +} + +let tree: Node = null; +beforeEach(() => { + tree = new Node(1); + tree.addNode(new Node(2)); +}); + +afterEach(() => { + tree = null; +}); + +describe('History', () => { + beforeAll(() => { + globalContext.register(new Editor(), Editor); + }); + + it('data function & records', async () => { + const mockRedoFn = jest.fn(); + const mockDataFn = jest.fn(); + const history = new History(() => { + const data = tree.toObject(); + mockDataFn(data); + return data; + }, mockRedoFn); + + expect(mockDataFn).toHaveBeenCalledTimes(1); + expect(mockDataFn).toHaveBeenCalledWith({ data: 1, children: [{ data: 2, children: [] }] }); + expect(history.hotData).toMatchSnapshot(); + // @ts-ignore + expect(history.session.cursor).toBe(0); + // @ts-ignore + expect(history.records).toHaveLength(1); + + tree.data = 3; + expect(mockDataFn).toHaveBeenCalledTimes(2); + expect(mockDataFn).toHaveBeenCalledWith({ data: 3, children: [{ data: 2, children: [] }] }); + expect(history.hotData).toMatchSnapshot(); + // @ts-ignore + expect(history.session.cursor).toBe(0); + // @ts-ignore + expect(history.records).toHaveLength(1); + + // modify data after timeGap + await delay(1200); + tree.data = 5; + expect(mockDataFn).toHaveBeenCalledTimes(3); + expect(mockDataFn).toHaveBeenCalledWith({ data: 5, children: [{ data: 2, children: [] }] }); + expect(history.hotData).toMatchSnapshot(); + // @ts-ignore + expect(history.session.cursor).toBe(1); + // @ts-ignore + expect(history.records).toHaveLength(2); + + history.setSerialization({ + serialize(data: Node): string { + return JSON.stringify(data); + }, + unserialize(data: string) { + return JSON.parse(data); + }, + }); + + // modify data after timeGap + await delay(1200); + tree.data = 7; + expect(mockDataFn).toHaveBeenCalledTimes(4); + expect(mockDataFn).toHaveBeenCalledWith({ data: 7, children: [{ data: 2, children: [] }] }); + expect(history.hotData).toMatchSnapshot(); + }); + + it('isSavePoint & savePoint', async () => { + const history = new History( + () => { + const data = tree.toObject(); + return data; + }, + () => {}, + ); + + expect(history.isSavePoint()).toBeFalsy(); + expect(history.isModified()).toBeFalsy(); + + await delay(1200); + tree.data = 3; + expect(history.isSavePoint()).toBeTruthy(); + + history.savePoint(); + expect(history.isSavePoint()).toBeFalsy(); + }); + + it('go & forward & back & onCursor', async () => { + const mockRedoFn = jest.fn(); + const mockCursorFn = jest.fn(); + const mockStateFn = jest.fn(); + const history = new History( + () => { + const data = tree.toObject(); + return data; + }, + (data) => { + mockRedoFn(data); + }, + ); + + // undoable ❌ & redoable ❌ & modified ❌ + expect(history.getState()).toBe(0); + + await delay(1200); + tree.data = 3; + + await delay(1200); + tree.data = 5; + + await delay(1200); + tree.data = 7; + + const dataCursor0 = { data: 1, children: [{ data: 2, children: [] }] }; + const dataCursor1 = { data: 3, children: [{ data: 2, children: [] }] }; + const dataCursor2 = { data: 5, children: [{ data: 2, children: [] }] }; + const dataCursor3 = { data: 7, children: [{ data: 2, children: [] }] }; + + // redoable ❌ + expect(history.getState()).toBe(7 - 2); + + const off1 = history.onCursor(mockCursorFn); + const off2 = history.onStateChange(mockStateFn); + + // @ts-ignore + expect(history.records).toHaveLength(4); + // @ts-ignore + expect(history.session.cursor).toBe(3); + + // step 1 + history.back(); + expect(mockCursorFn).toHaveBeenNthCalledWith( + 1, + JSON.stringify(dataCursor2), + ); + expect(mockStateFn).toHaveBeenNthCalledWith(1, 7); + expect(mockRedoFn).toHaveBeenNthCalledWith(1, dataCursor2); + + // step 2 + history.back(); + expect(mockCursorFn).toHaveBeenNthCalledWith( + 2, + JSON.stringify(dataCursor1), + ); + expect(mockStateFn).toHaveBeenNthCalledWith(2, 7); + expect(mockRedoFn).toHaveBeenNthCalledWith(2, dataCursor1); + + // step 3 + history.back(); + expect(mockCursorFn).toHaveBeenNthCalledWith( + 3, + JSON.stringify(dataCursor0), + ); + expect(mockStateFn).toHaveBeenNthCalledWith(3, 7 - 4 - 1); + expect(mockRedoFn).toHaveBeenNthCalledWith(3, dataCursor0); + + // step 4 + history.forward(); + expect(mockCursorFn).toHaveBeenNthCalledWith( + 4, + JSON.stringify(dataCursor1), + ); + expect(mockStateFn).toHaveBeenNthCalledWith(4, 7); + expect(mockRedoFn).toHaveBeenNthCalledWith(4, dataCursor1); + + // step 5 + history.forward(); + expect(mockCursorFn).toHaveBeenNthCalledWith( + 5, + JSON.stringify(dataCursor2), + ); + expect(mockStateFn).toHaveBeenNthCalledWith(5, 7); + expect(mockRedoFn).toHaveBeenNthCalledWith(5, dataCursor2); + + // step 6 + history.go(3); + expect(mockCursorFn).toHaveBeenNthCalledWith( + 6, + JSON.stringify(dataCursor3), + ); + expect(mockStateFn).toHaveBeenNthCalledWith(6, 7 - 2); + expect(mockRedoFn).toHaveBeenNthCalledWith(6, dataCursor3); + + // step 7 + history.go(0); + expect(mockCursorFn).toHaveBeenNthCalledWith( + 7, + JSON.stringify(dataCursor0), + ); + expect(mockStateFn).toHaveBeenNthCalledWith(7, 7 - 4 - 1); + expect(mockRedoFn).toHaveBeenNthCalledWith(7, dataCursor0); + + off1(); + off2(); + mockStateFn.mockClear(); + mockCursorFn.mockClear(); + history.go(1); + expect(mockStateFn).not.toHaveBeenCalled(); + expect(mockCursorFn).not.toHaveBeenCalled(); + }); + + it('go() - edge case of cursor', async () => { + const mockRedoFn = jest.fn(); + const mockCursorFn = jest.fn(); + const mockStateFn = jest.fn(); + const history = new History( + () => { + const data = tree.toObject(); + return data; + }, + (data) => { + mockRedoFn(data); + }, + ); + + await delay(1200); + tree.data = 3; + + await delay(1200); + tree.data = 5; + + history.go(-1); + // @ts-ignore + expect(history.session.cursor).toBe(0); + + history.go(3); + // @ts-ignore + expect(history.session.cursor).toBe(2); + }); + + it('destroy()', async () => { + const history = new History( + () => { + const data = tree.toObject(); + return data; + }, + (data) => { + mockRedoFn(data); + }, + ); + + history.destroy(); + // @ts-ignore + expect(history.records).toHaveLength(0); + }); + + it('internalToShellHistory()', async () => { + const history = new History( + () => { + const data = tree.toObject(); + return data; + }, + (data) => { + mockRedoFn(data); + }, + ); + + expect(history.internalToShellHistory().isModified).toBeUndefined(); + }); + + it('sleep & wakeup', async () => { + const mockRedoFn = jest.fn(); + const history = new History( + () => { + const data = tree.toObject(); + return data; + }, + (data) => { + mockRedoFn(data); + }, + ); + + // @ts-ignore + history.sleep(); + + await delay(1200); + tree.data = 3; + // no record has been pushed into records because of history is asleep. + // @ts-ignore + expect(history.records).toHaveLength(1); + + // @ts-ignore + history.wakeup(); + tree.data = 4; + // @ts-ignore + expect(history.records).toHaveLength(2); + }); +}); + +describe('History - errors', () => { + beforeAll(() => { + globalContext.replace(Editor, null); + }); + + it('no editor', () => { + const history = new History( + () => { + const data = tree.toObject(); + return data; + }, + (data) => { + }, + ); + + history.back(); + history.forward(); + }); + + it('no session', () => { + const history = new History( + () => { + const data = tree.toObject(); + return data; + }, + (data) => { + }, + ); + + // @ts-ignore + history.session = undefined; + history.back(); + history.forward(); + history.savePoint(); + }); +}); \ No newline at end of file diff --git a/packages/designer/tests/document/history/session.test.ts b/packages/designer/tests/document/history/session.test.ts new file mode 100644 index 0000000000..3e9e8c628b --- /dev/null +++ b/packages/designer/tests/document/history/session.test.ts @@ -0,0 +1,57 @@ +import '../../fixtures/window'; +import { Session } from '../../../src/document/history'; +import { delay } from '../../utils/misc'; + +describe('Session', () => { + it('constructor', () => { + const session = new Session(1, { a: 1 }); + expect(session.cursor).toBe(1); + expect(session.data).toEqual({ a: 1 }); + // @ts-ignore + expect(session.timeGap).toBe(1000); + expect(session.isActive()).toBeTruthy(); + }); + + it('log()', () => { + const session = new Session(1, { a: 1 }); + + session.log({ a: 2 }); + session.log({ a: 3 }); + expect(session.data).toEqual({ a: 3 }); + }); + + it('end()', () => { + const session = new Session(1, { a: 1 }); + + session.end(); + expect(session.isActive()).toBeFalsy(); + session.log({ a: 2 }); + // log is not possible if current session is inactive + expect(session.data).toEqual({ a: 1 }); + }); + + + it('timeGap', async () => { + const session = new Session(1, { a: 1 }); + + expect(session.isActive()).toBeTruthy(); + await delay(1200); + expect(session.isActive()).toBeFalsy(); + session.log({ a: 2 }); + // log is not possible if current session is inactive + expect(session.data).toEqual({ a: 1 }); + }); + + it('custom timeGap', async () => { + const session = new Session(1, { a: 1 }, 2000); + + expect(session.isActive()).toBeTruthy(); + await delay(1200); + expect(session.isActive()).toBeTruthy(); + await delay(1000); + expect(session.isActive()).toBeFalsy(); + session.log({ a: 2 }); + // log is not possible if current session is inactive + expect(session.data).toEqual({ a: 1 }); + }); +}); \ No newline at end of file diff --git a/packages/designer/tests/plugin/plugin-manager.test.ts b/packages/designer/tests/plugin/plugin-manager.test.ts index 08bc61ee7d..b0c40070a3 100644 --- a/packages/designer/tests/plugin/plugin-manager.test.ts +++ b/packages/designer/tests/plugin/plugin-manager.test.ts @@ -2,6 +2,7 @@ import '../fixtures/window'; import { Editor, engineConfig } from '@alilc/lowcode-editor-core'; import { LowCodePluginManager } from '../../src/plugin/plugin-manager'; import { ILowCodePluginContext, ILowCodePluginManager } from '../../src/plugin/plugin-types'; + const editor = new Editor(); describe('plugin 测试', () => { @@ -15,14 +16,14 @@ describe('plugin 测试', () => { it('注册插件,插件参数生成函数能被调用,且能拿到正确的 ctx ', () => { const mockFn = jest.fn(); - const creater = (ctx: ILowCodePluginContext) => { + const creator2 = (ctx: ILowCodePluginContext) => { mockFn(ctx); return { init: jest.fn(), }; }; - creater.pluginName = 'demo1'; - pluginManager.register(creater); + creator2.pluginName = 'demo1'; + pluginManager.register(creator2); const [expectedCtx] = mockFn.mock.calls[0]; expect(expectedCtx).toHaveProperty('project'); @@ -39,7 +40,7 @@ describe('plugin 测试', () => { it('注册插件,调用插件 init 方法', async () => { const mockFn = jest.fn(); - const creater = (ctx: ILowCodePluginContext) => { + const creator2 = (ctx: ILowCodePluginContext) => { return { init: mockFn, exports() { @@ -50,8 +51,8 @@ describe('plugin 测试', () => { }, }; }; - creater.pluginName = 'demo1'; - pluginManager.register(creater); + creator2.pluginName = 'demo1'; + pluginManager.register(creator2); await pluginManager.init(); expect(pluginManager.size).toBe(1); expect(pluginManager.has('demo1')).toBeTruthy(); @@ -59,35 +60,52 @@ describe('plugin 测试', () => { expect(pluginManager.demo1).toBeTruthy(); expect(pluginManager.demo1.x).toBe(1); expect(pluginManager.demo1.y).toBe(2); + expect(pluginManager.demo1.z).toBeUndefined(); expect(mockFn).toHaveBeenCalled(); }); it('注册插件,调用 setDisabled 方法', async () => { const mockFn = jest.fn(); - const creater = (ctx: ILowCodePluginContext) => { + const creator2 = (ctx: ILowCodePluginContext) => { return { init: mockFn, }; }; - creater.pluginName = 'demo1'; + creator2.pluginName = 'demo1'; - pluginManager.register(creater); + pluginManager.register(creator2); await pluginManager.init(); expect(pluginManager.demo1).toBeTruthy(); pluginManager.setDisabled('demo1', true); expect(pluginManager.demo1).toBeUndefined(); }); + it('注册插件,调用 plugin.setDisabled 方法', async () => { + const mockFn = jest.fn(); + const creator2 = (ctx: ILowCodePluginContext) => { + return { + init: mockFn, + }; + }; + creator2.pluginName = 'demo1'; + + pluginManager.register(creator2); + await pluginManager.init(); + expect(pluginManager.demo1).toBeTruthy(); + pluginManager.get('demo1').setDisabled(); + expect(pluginManager.demo1).toBeUndefined(); + }); + it('删除插件,调用插件 destroy 方法', async () => { const mockFn = jest.fn(); - const creater = (ctx: ILowCodePluginContext) => { + const creator2 = (ctx: ILowCodePluginContext) => { return { init: jest.fn(), destroy: mockFn, }; }; - creater.pluginName = 'demo1'; - pluginManager.register(creater); + creator2.pluginName = 'demo1'; + pluginManager.register(creator2); await pluginManager.init(); await pluginManager.delete('demo1'); @@ -95,109 +113,185 @@ describe('plugin 测试', () => { await pluginManager.delete('non-existing'); }); - it('dep 依赖', async () => { - const mockFn = jest.fn(); - const creater1 = (ctx: ILowCodePluginContext) => { - return { - // dep: ['demo2'], - init: () => mockFn('demo1'), + describe('dependencies 依赖', () => { + it('dependencies 依赖', async () => { + const mockFn = jest.fn(); + const creator21 = (ctx: ILowCodePluginContext) => { + return { + init: () => mockFn('demo1'), + }; }; - }; - creater1.pluginName = 'demo1'; - creater1.meta = { - dependencies: ['demo2'], - }; - pluginManager.register(creater1); - const creater2 = (ctx: ILowCodePluginContext) => { - return { - init: () => mockFn('demo2'), + creator21.pluginName = 'demo1'; + creator21.meta = { + dependencies: ['demo2'], }; - }; - creater2.pluginName = 'demo2'; - pluginManager.register(creater2); + pluginManager.register(creator21); + const creator22 = (ctx: ILowCodePluginContext) => { + return { + init: () => mockFn('demo2'), + }; + }; + creator22.pluginName = 'demo2'; + pluginManager.register(creator22); - await pluginManager.init(); - expect(mockFn).toHaveBeenNthCalledWith(1, 'demo2'); - expect(mockFn).toHaveBeenNthCalledWith(2, 'demo1'); + await pluginManager.init(); + expect(mockFn).toHaveBeenNthCalledWith(1, 'demo2'); + expect(mockFn).toHaveBeenNthCalledWith(2, 'demo1'); + }); + + it('dependencies 依赖 - string', async () => { + const mockFn = jest.fn(); + const creator21 = (ctx: ILowCodePluginContext) => { + return { + init: () => mockFn('demo1'), + }; + }; + creator21.pluginName = 'demo1'; + creator21.meta = { + dependencies: 'demo2', + }; + pluginManager.register(creator21); + const creator22 = (ctx: ILowCodePluginContext) => { + return { + init: () => mockFn('demo2'), + }; + }; + creator22.pluginName = 'demo2'; + pluginManager.register(creator22); + + await pluginManager.init(); + expect(mockFn).toHaveBeenNthCalledWith(1, 'demo2'); + expect(mockFn).toHaveBeenNthCalledWith(2, 'demo1'); + }); + + it('dependencies 依赖 - 兼容 dep', async () => { + const mockFn = jest.fn(); + const creator21 = (ctx: ILowCodePluginContext) => { + return { + dep: ['demo4'], + init: () => mockFn('demo3'), + }; + }; + creator21.pluginName = 'demo3'; + pluginManager.register(creator21); + const creator22 = (ctx: ILowCodePluginContext) => { + return { + init: () => mockFn('demo4'), + }; + }; + creator22.pluginName = 'demo4'; + pluginManager.register(creator22); + + await pluginManager.init(); + expect(mockFn).toHaveBeenNthCalledWith(1, 'demo4'); + expect(mockFn).toHaveBeenNthCalledWith(2, 'demo3'); + }); + + it('dependencies 依赖 - 兼容 dep & string', async () => { + const mockFn = jest.fn(); + const creator21 = (ctx: ILowCodePluginContext) => { + return { + dep: 'demo4', + init: () => mockFn('demo3'), + }; + }; + creator21.pluginName = 'demo3'; + pluginManager.register(creator21); + const creator22 = (ctx: ILowCodePluginContext) => { + return { + init: () => mockFn('demo4'), + }; + }; + creator22.pluginName = 'demo4'; + pluginManager.register(creator22); + + await pluginManager.init(); + expect(mockFn).toHaveBeenNthCalledWith(1, 'demo4'); + expect(mockFn).toHaveBeenNthCalledWith(2, 'demo3'); + }); }); it('version 依赖', async () => { const mockFn = jest.fn(); - const creater1 = (ctx: ILowCodePluginContext) => { + const creator21 = (ctx: ILowCodePluginContext) => { return { init: () => mockFn('demo1'), }; }; - creater1.pluginName = 'demo1'; - creater1.meta = { + creator21.pluginName = 'demo1'; + creator21.meta = { engines: { lowcodeEngine: '^1.1.0', - } + }, }; engineConfig.set('ENGINE_VERSION', '1.0.1'); - + console.log('version: ', engineConfig.get('ENGINE_VERSION')); // not match should skip - pluginManager.register(creater1).catch(e => { - expect(e).toEqual(new Error('plugin demo1 skipped, engine check failed, current engine version is 1.0.1, meta.engines.lowcodeEngine is ^1.1.0')); + pluginManager.register(creator21).catch((e) => { + expect(e).toEqual( + new Error( + 'plugin demo1 skipped, engine check failed, current engine version is 1.0.1, meta.engines.lowcodeEngine is ^1.1.0', + ), + ); }); expect(pluginManager.plugins.length).toBe(0); - const creater2 = (ctx: ILowCodePluginContext) => { + const creator22 = (ctx: ILowCodePluginContext) => { return { init: () => mockFn('demo2'), }; }; - creater2.pluginName = 'demo2'; - creater2.meta = { + creator22.pluginName = 'demo2'; + creator22.meta = { engines: { lowcodeEngine: '^1.0.1', - } + }, }; engineConfig.set('ENGINE_VERSION', '1.0.3'); - pluginManager.register(creater2); + pluginManager.register(creator22); expect(pluginManager.plugins.length).toBe(1); - const creater3 = (ctx: ILowCodePluginContext) => { + const creator23 = (ctx: ILowCodePluginContext) => { return { init: () => mockFn('demo3'), }; }; - creater3.pluginName = 'demo3'; - creater3.meta = { + creator23.pluginName = 'demo3'; + creator23.meta = { engines: { lowcodeEngine: '1.x', - } + }, }; engineConfig.set('ENGINE_VERSION', '1.1.1'); - pluginManager.register(creater3); + pluginManager.register(creator23); expect(pluginManager.plugins.length).toBe(2); }); it('autoInit 功能', async () => { const mockFn = jest.fn(); - const creater = (ctx: ILowCodePluginContext) => { + const creator2 = (ctx: ILowCodePluginContext) => { return { init: mockFn, }; }; - creater.pluginName = 'demo1'; - await pluginManager.register(creater, { autoInit: true }); + creator2.pluginName = 'demo1'; + await pluginManager.register(creator2, { autoInit: true }); expect(mockFn).toHaveBeenCalled(); }); it('插件不会重复 init,除非强制重新 init', async () => { const mockFn = jest.fn(); - const creater = (ctx: ILowCodePluginContext) => { + const creator2 = (ctx: ILowCodePluginContext) => { return { name: 'demo1', init: mockFn, }; }; - creater.pluginName = 'demo1'; - pluginManager.register(creater); + creator2.pluginName = 'demo1'; + pluginManager.register(creator2); await pluginManager.init(); expect(mockFn).toHaveBeenCalledTimes(1); @@ -217,7 +311,7 @@ describe('plugin 测试', () => { }; mockPlugin.pluginName = 'demoDuplicated'; pluginManager.register(mockPlugin); - pluginManager.register(mockPlugin).catch(e => { + pluginManager.register(mockPlugin).catch((e) => { expect(e).toEqual(new Error('Plugin with name demoDuplicated exists')); }); await pluginManager.init(); @@ -255,33 +349,35 @@ describe('plugin 测试', () => { it('内部事件机制', async () => { const mockFn = jest.fn(); - const creater = (ctx: ILowCodePluginContext) => { - return { - }; - } - creater.pluginName = 'demo1'; - pluginManager.register(creater); + const creator2 = (ctx: ILowCodePluginContext) => { + return {}; + }; + creator2.pluginName = 'demo1'; + pluginManager.register(creator2); await pluginManager.init(); const plugin = pluginManager.get('demo1')!; - plugin.on('haha', mockFn); + const off = plugin.on('haha', mockFn); plugin.emit('haha', 1, 2, 3); expect(mockFn).toHaveBeenCalledTimes(1); expect(mockFn).toHaveBeenCalledWith(1, 2, 3); + off(); + plugin.emit('haha', 1, 2, 3); + expect(mockFn).toHaveBeenCalledTimes(1); + plugin.removeAllListeners('haha'); plugin.emit('haha', 1, 2, 3); expect(mockFn).toHaveBeenCalledTimes(1); }); it('dispose 方法', async () => { - const creater = (ctx: ILowCodePluginContext) => { - return { - }; - } - creater.pluginName = 'demo1'; - pluginManager.register(creater); + const creator2 = (ctx: ILowCodePluginContext) => { + return {}; + }; + creator2.pluginName = 'demo1'; + pluginManager.register(creator2); await pluginManager.init(); const plugin = pluginManager.get('demo1')!; await plugin.dispose(); @@ -289,30 +385,61 @@ describe('plugin 测试', () => { expect(pluginManager.has('demo1')).toBeFalsy(); }); - it('注册插件,调用插件 init 方法并传入preference,可以成功获取', async () => { + it('getAll 方法', async () => { + const creator2 = (ctx: ILowCodePluginContext) => { + return {}; + }; + creator2.pluginName = 'demo1'; + pluginManager.register(creator2); + await pluginManager.init(); + + expect(pluginManager.getAll()).toHaveLength(1); + }); + + it('getPluginPreference 方法 - null', async () => { + const creator2 = (ctx: ILowCodePluginContext) => { + return {}; + }; + creator2.pluginName = 'demo1'; + pluginManager.register(creator2); + await pluginManager.init(); + + expect(pluginManager.getPluginPreference()).toBeNull(); + }); + + it('getPluginPreference 方法', async () => { + const creator2 = (ctx: ILowCodePluginContext) => { + return {}; + }; + const preference = new Map(); + preference.set('demo1', { a: 1, b: 2 }); + creator2.pluginName = 'demo1'; + pluginManager.register(creator2); + await pluginManager.init(preference); + + expect(pluginManager.getPluginPreference('demo1')).toEqual({ a: 1, b: 2 }); + }); + + it('注册插件,调用插件 init 方法并传入 preference,可以成功获取', async () => { const mockFn = jest.fn(); const mockFnForCtx = jest.fn(); + const mockFnForCtx2 = jest.fn(); const mockPreference = new Map(); - mockPreference.set('demo1',{ + mockPreference.set('demo1', { key1: 'value for key1', key2: false, key3: 123, - key5: 'value for key5, but declared, should not work' - }); - mockPreference.set('demo2',{ - key1: 'value for demo2.key1', - key2: false, - key3: 123, + key5: 'value for key5, but declared, should not work', }); - const creater = (ctx: ILowCodePluginContext) => { + const creator2 = (ctx: ILowCodePluginContext) => { mockFnForCtx(ctx); return { init: jest.fn(), }; }; - creater.pluginName = 'demo1'; - creater.meta = { + creator2.pluginName = 'demo1'; + creator2.meta = { preferenceDeclaration: { title: 'demo1的的参数定义', properties: [ @@ -338,13 +465,34 @@ describe('plugin 测试', () => { }, ], }, - } - pluginManager.register(creater); + }; + const creator22 = (ctx: ILowCodePluginContext) => { + mockFnForCtx2(ctx); + return { + init: jest.fn(), + }; + }; + creator22.pluginName = 'demo2'; + creator22.meta = { + preferenceDeclaration: { + title: 'demo1的的参数定义', + properties: [ + { + key: 'key1', + type: 'string', + description: 'this is description for key1', + }, + ], + }, + }; + pluginManager.register(creator2); + pluginManager.register(creator22); expect(mockFnForCtx).toHaveBeenCalledTimes(1); + await pluginManager.init(mockPreference); - // creater only get excuted once + // creator2 only get excuted once expect(mockFnForCtx).toHaveBeenCalledTimes(1); - + const [expectedCtx, expectedOptions] = mockFnForCtx.mock.calls[0]; expect(expectedCtx).toHaveProperty('preference'); @@ -352,9 +500,47 @@ describe('plugin 测试', () => { expect(expectedCtx.preference.getPreferenceValue('key1', 'default')).toBe('value for key1'); // test default value logic - expect(expectedCtx.preference.getPreferenceValue('key4', 'default for key4')).toBe('default for key4'); + expect(expectedCtx.preference.getPreferenceValue('key4', 'default for key4')).toBe( + 'default for key4', + ); // test undeclared key expect(expectedCtx.preference.getPreferenceValue('key5', 'default for key5')).toBeUndefined(); + + // no preference defined + const [expectedCtx2] = mockFnForCtx2.mock.calls[0]; + expect(expectedCtx2.preference.getPreferenceValue('key1')).toBeUndefined(); + }); + + it('注册插件,没有填写 pluginName,默认值为 anonymous', async () => { + const mockFn = jest.fn(); + + const creator2 = (ctx: ILowCodePluginContext) => { + return { + name: 'xxx', + init: () => mockFn('anonymous'), + }; + }; + await pluginManager.register(creator2); + expect(pluginManager.get('anonymous')).toBeUndefined(); + }); + + it('自定义/扩展 plugin context', async () => { + const mockFn = jest.fn(); + const mockFn2 = jest.fn(); + + const creator2 = (ctx: ILowCodePluginContext) => { + mockFn2(ctx); + return { + init: () => mockFn('anonymous'), + }; + }; + creator2.pluginName = 'yyy'; + editor.set('enhancePluginContextHook', (originalContext) => { + originalContext.newProp = 1; + }); + await pluginManager.register(creator2); + const [expectedCtx] = mockFn2.mock.calls[0]; + expect(expectedCtx).toHaveProperty('newProp'); }); }); diff --git a/packages/designer/tests/plugin/plugin-utils.test.ts b/packages/designer/tests/plugin/plugin-utils.test.ts new file mode 100644 index 0000000000..eb152a049a --- /dev/null +++ b/packages/designer/tests/plugin/plugin-utils.test.ts @@ -0,0 +1,85 @@ +import '../fixtures/window'; +import { isValidPreferenceKey, filterValidOptions } from '../../src/plugin/plugin-utils'; + +describe('plugin utils 测试', () => { + it('isValidPreferenceKey', () => { + expect(isValidPreferenceKey('x')).toBeFalsy(); + expect(isValidPreferenceKey('x', { properties: {} })).toBeFalsy(); + expect(isValidPreferenceKey('x', { properties: 1 })).toBeFalsy(); + expect(isValidPreferenceKey('x', { properties: 'str' })).toBeFalsy(); + expect(isValidPreferenceKey('x', { properties: [] })).toBeFalsy(); + expect( + isValidPreferenceKey('x', { + title: 'title', + properties: [ + { + key: 'y', + type: 'string', + description: 'x desc', + }, + ], + }), + ).toBeFalsy(); + expect( + isValidPreferenceKey('x', { + title: 'title', + properties: [ + { + key: 'x', + type: 'string', + description: 'x desc', + }, + ], + }), + ).toBeTruthy(); + }); + + it('filterValidOptions', () => { + const mockDeclaration = { + title: 'title', + properties: [ + { + key: 'x', + type: 'string', + description: 'x desc', + }, + { + key: 'y', + type: 'string', + description: 'y desc', + }, + { + key: 'z', + type: 'string', + description: 'z desc', + }, + ], + }; + + expect(filterValidOptions()).toBeUndefined(); + expect(filterValidOptions(1)).toBe(1); + expect(filterValidOptions({ + x: 1, + y: 2, + }, mockDeclaration)).toEqual({ + x: 1, + y: 2, + }); + expect(filterValidOptions({ + x: 1, + y: undefined, + }, mockDeclaration)).toEqual({ + x: 1, + }); + expect(filterValidOptions({ + x: 1, + z: null, + }, mockDeclaration)).toEqual({ + x: 1, + }); + expect(filterValidOptions({ + a: 1, + }, mockDeclaration)).toEqual({ + }); + }); +}); diff --git a/packages/designer/tests/project/project-methods.test.ts b/packages/designer/tests/project/project-methods.test.ts index e32daab6d3..1cce64b8c9 100644 --- a/packages/designer/tests/project/project-methods.test.ts +++ b/packages/designer/tests/project/project-methods.test.ts @@ -113,6 +113,8 @@ describe.only('Project 方法测试', () => { expect(project.documents.length).toBe(4); expect(project.getDocument(project.currentDocument?.id)).toBe(doc3); + expect(project.getDocumentByFileName(project.currentDocument?.fileName)).toBe(doc3); + expect(project.getDocumentByFileName('unknown')).toBeNull(); expect(project.checkExclusive(project.currentDocument)); expect(project.documents[0].opened).toBeTruthy(); From 2022308e21abe7c1960743f1ac25ad607b3be965 Mon Sep 17 00:00:00 2001 From: liujuping Date: Thu, 23 Jun 2022 11:52:53 +0800 Subject: [PATCH 055/823] refactor: remove redundant monitor files --- packages/editor-core/src/utils/index.ts | 1 - packages/editor-core/src/utils/monitor.ts | 42 ----------------------- 2 files changed, 43 deletions(-) delete mode 100644 packages/editor-core/src/utils/monitor.ts diff --git a/packages/editor-core/src/utils/index.ts b/packages/editor-core/src/utils/index.ts index 0e269ef3b6..c01cdfc173 100644 --- a/packages/editor-core/src/utils/index.ts +++ b/packages/editor-core/src/utils/index.ts @@ -1,5 +1,4 @@ export * from './get-public-path'; -export * from './monitor'; export * from './obx'; export * from './request'; export * from './focus-tracker'; diff --git a/packages/editor-core/src/utils/monitor.ts b/packages/editor-core/src/utils/monitor.ts deleted file mode 100644 index 0889d45656..0000000000 --- a/packages/editor-core/src/utils/monitor.ts +++ /dev/null @@ -1,42 +0,0 @@ -export class Monitor { - fn = (params: any) => { - const { AES = {} } = window as any; - if (typeof AES.log === 'function') { - const { p1 = '', p2 = '', p3 = '', p4 = 'OTHER', ...rest } = params || {}; - AES.log('event', { - p1, - p2, - p3, - p4, - ...rest, - }); - } - }; - - register(fn: () => any) { - if (typeof fn === 'function') { - this.fn = fn; - } - } - - log(params: any) { - if (typeof this.fn === 'function') { - this.fn(params); - } - } - - setConfig(key: string | object, value?: string): void { - const { AES = {} } = window as any; - if (typeof AES?.setConfig !== 'function') { - return; - } - if (typeof key === 'string' && value) { - AES.setConfig(key, value); - } else if (typeof key === 'object') { - AES.setConfig(key); - } - } -} - -const monitor = new Monitor(); -export { monitor }; From da7f77ee91b3bf441a4a57614872df32d6a1d041 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=B5=AE=E9=BB=8E?= Date: Thu, 23 Jun 2022 14:44:35 +0800 Subject: [PATCH 056/823] feat: added thisRequiredInJSE API to control whether JSExpression expression access context must use this (#702) --- .../designer/src/builtin-simulator/host.ts | 4 ++ packages/editor-core/src/config.ts | 10 ++++ .../src/renderer-view.tsx | 1 + .../src/renderer-view.tsx | 1 + packages/renderer-core/src/renderer/base.tsx | 19 ++++--- .../renderer-core/src/renderer/renderer.tsx | 1 + packages/renderer-core/src/types/index.ts | 8 ++- packages/renderer-core/src/utils/common.ts | 10 +++- .../__snapshots__/renderer.test.tsx.snap | 18 ++++++ .../tests/renderer/renderer.test.tsx | 48 +++++++++++++++- .../renderer-core/tests/utils/common.test.ts | 56 ++++++++++++++++--- 11 files changed, 154 insertions(+), 22 deletions(-) diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index e4cfc4c96c..e40566f57d 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -228,6 +228,10 @@ export class BuiltinSimulatorHost implements ISimulatorHost { diff --git a/packages/rax-simulator-renderer/src/renderer-view.tsx b/packages/rax-simulator-renderer/src/renderer-view.tsx index c11c2dfdfa..2e8d6e0fcd 100644 --- a/packages/rax-simulator-renderer/src/renderer-view.tsx +++ b/packages/rax-simulator-renderer/src/renderer-view.tsx @@ -219,6 +219,7 @@ class Renderer extends Component<{ onCompGetRef={(schema: any, ref: any) => { documentInstance.mountInstance(schema.id, ref); }} + thisRequiredInJSE={host.thisRequiredInJSE} documentId={document.id} getNode={(id: string) => documentInstance.getNode(id) as any} rendererName="PageRenderer" diff --git a/packages/react-simulator-renderer/src/renderer-view.tsx b/packages/react-simulator-renderer/src/renderer-view.tsx index 5647a5447b..d978494c02 100644 --- a/packages/react-simulator-renderer/src/renderer-view.tsx +++ b/packages/react-simulator-renderer/src/renderer-view.tsx @@ -189,6 +189,7 @@ class Renderer extends Component<{ setSchemaChangedSymbol={this.setSchemaChangedSymbol} getNode={(id: string) => documentInstance.getNode(id) as Node} rendererName="PageRenderer" + thisRequiredInJSE={host.thisRequiredInJSE} customCreateElement={(Component: any, props: any, children: any) => { const { __id, ...viewProps } = props; viewProps.componentId = __id; diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 6a6d622b15..aee0203440 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -12,6 +12,7 @@ import { getValue, parseData, parseExpression, + parseThisRequiredExpression, parseI18n, isEmpty, isSchema, @@ -83,11 +84,13 @@ export default function baseRendererFactory(): IBaseRenderComponent { getLocale: any; setLocale: any; styleElement: any; + parseExpression: any; [key: string]: any; constructor(props: IBaseRendererProps, context: IBaseRendererContext) { super(props, context); this.context = context; + this.parseExpression = props?.thisRequiredInJSE ? parseThisRequiredExpression : parseExpression; this.__beforeInit(props); this.__init(props); this.__afterInit(props); @@ -112,7 +115,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { if (func) { if (isJSExpression(func) || isJSFunction(func)) { - const fn = parseExpression(func, this); + const fn = props.thisRequiredInJSE ? parseThisRequiredExpression(func, this) : parseExpression(func, this); return fn(props, state); } @@ -193,7 +196,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { if (fn) { // TODO, cache if (isJSExpression(fn) || isJSFunction(fn)) { - fn = parseExpression(fn, this); + fn = this.parseExpression(fn, this); } if (typeof fn !== 'function') { console.error(`生命周期${method}类型不符`, fn); @@ -219,7 +222,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { this.__customMethodsList = customMethodsList; forEach(__schema.methods, (val: any, key: string) => { if (isJSExpression(val) || isJSFunction(val)) { - val = parseExpression(val, this); + val = this.parseExpression(val, this); } if (typeof val !== 'function') { console.error(`自定义函数${key}类型不符`, val); @@ -414,7 +417,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { const { __appHelper: appHelper, __components: components = {} } = this.props || {}; if (isJSExpression(schema)) { - return parseExpression(schema, scope); + return this.parseExpression(schema, scope); } if (isI18nData(schema)) { return parseI18n(schema, scope); @@ -434,7 +437,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { const _children = this.getSchemaChildren(schema); // 解析占位组件 if (schema?.componentName === 'Fragment' && _children) { - const tarChildren = isJSExpression(_children) ? parseExpression(_children, scope) : _children; + const tarChildren = isJSExpression(_children) ? this.parseExpression(_children, scope) : _children; return this.__createVirtualDom(tarChildren, scope, parentInfo); } @@ -496,7 +499,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { let scopeKey = ''; // 判断组件是否需要生成scope,且只生成一次,挂在this.__compScopes上 if (Comp.generateScope) { - const key = parseExpression(schema.props?.key, scope); + const key = this.parseExpression(schema.props?.key, scope); if (key) { // 如果组件自己设置key则使用组件自己的key scopeKey = key; @@ -647,7 +650,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { _children.forEach((_child: any) => { const _childVirtualDom = this.__createVirtualDom( - isJSExpression(_child) ? parseExpression(_child, scope) : _child, + isJSExpression(_child) ? this.parseExpression(_child, scope) : _child, scope, { schema, @@ -754,7 +757,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { return checkProps(props); } if (isJSExpression(props)) { - props = parseExpression(props, scope); + props = this.parseExpression(props, scope); // 只有当变量解析出来为模型结构的时候才会继续解析 if (!isSchema(props) && !isJSSlot(props)) return checkProps(props); } diff --git a/packages/renderer-core/src/renderer/renderer.tsx b/packages/renderer-core/src/renderer/renderer.tsx index bd2b3df8bd..59d63f7903 100644 --- a/packages/renderer-core/src/renderer/renderer.tsx +++ b/packages/renderer-core/src/renderer/renderer.tsx @@ -60,6 +60,7 @@ export default function rendererFactory(): IRenderComponent { schema: {} as RootSchema, onCompGetRef: () => { }, onCompGetCtx: () => { }, + thisRequiredInJSE: true, }; static findDOMNode = findDOMNode; diff --git a/packages/renderer-core/src/types/index.ts b/packages/renderer-core/src/types/index.ts index b0cc9f9963..a3e7f0c368 100644 --- a/packages/renderer-core/src/types/index.ts +++ b/packages/renderer-core/src/types/index.ts @@ -128,6 +128,11 @@ export interface IRendererProps { faultComponent?: IGeneralComponent; /** 设备信息 */ device?: string; + /** + * @default true + * JSExpression 是否只支持使用 this 来访问上下文变量 + */ + thisRequiredInJSE?: boolean; } export interface IRendererState { @@ -148,12 +153,13 @@ export interface IBaseRendererProps { __host?: BuiltinSimulatorHost; __container?: any; config?: Record; - designMode?: 'live' | 'design'; + designMode?: 'design'; className?: string; style?: CSSProperties; id?: string | number; getSchemaChangedSymbol?: () => boolean; setSchemaChangedSymbol?: (symbol: boolean) => void; + thisRequiredInJSE?: boolean; documentId?: string; getNode?: any; /** diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index 437e6077fd..8db913f3d3 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -242,7 +242,7 @@ export function transformStringToFunction(str: string) { * @param self scope object * @returns funtion */ -export function parseExpression(str: any, self: any) { +export function parseExpression(str: any, self: any, thisRequired = false) { try { const contextArr = ['"use strict";', 'var __self = arguments[0];']; contextArr.push('return '); @@ -259,14 +259,18 @@ export function parseExpression(str: any, self: any) { if (inSameDomain() && (window.parent as any).__newFunc) { return (window.parent as any).__newFunc(tarStr)(self); } - const code = `with($scope || {}) { ${tarStr} }`; + const code = `with(${thisRequired ? '{}' : '$scope || {}'}) { ${tarStr} }`; return new Function('$scope', code)(self); } catch (err) { - logger.error('parseExpression.error', err, str, self); + logger.error('parseExpression.error', err, str, self?.__self ?? self); return undefined; } } +export function parseThisRequiredExpression(str: any, self: any) { + return parseExpression(str, self, true); +} + /** * capitalize first letter * @param word string to be proccessed diff --git a/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap b/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap index 76ed01e02d..169ed545c6 100644 --- a/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap +++ b/packages/renderer-core/tests/renderer/__snapshots__/renderer.test.tsx.snap @@ -994,6 +994,24 @@ exports[`JSExpression JSExpression props with loop 1`] = `
`; +exports[`JSExpression JSExpression props with loop, and thisRequiredInJSE is true 1`] = ` +
+
+
+
+`; + exports[`JSExpression JSFunction props 1`] = `
{ ] }; - getComp(schema, components.Div).then(({ component, inst }) => { + getComp(schema, components.Div, { + thisRequiredInJSE: false, + }).then(({ component, inst }) => { // expect(inst[0].props.visible).toBeTruthy(); expect(inst.length).toEqual(2); [1, 2].forEach((i) => { @@ -157,6 +159,50 @@ describe('JSExpression', () => { }); }); + it('JSExpression props with loop, and thisRequiredInJSE is true', (done) => { + const schema = { + componentName: 'Page', + props: {}, + state: { + isShowDialog: true, + }, + children: [ + { + componentName: "Div", + loop: [ + { + name: '1', + }, + { + name: '2' + } + ], + props: { + className: "div-ut", + name1: { + type: 'JSExpression', + value: 'this.item.name', + }, + name2: { + type: 'JSExpression', + value: 'item.name', + }, + } + } + ] + }; + + getComp(schema, components.Div).then(({ component, inst }) => { + expect(inst.length).toEqual(2); + [0, 1].forEach((i) => { + expect(inst[i].props[`name1`]).toBe(i + 1 + ''); + expect(inst[i].props[`name2`]).toBe(undefined); + }) + componentSnapshot = component; + done(); + }); + }); + // it('JSFunction props with loop', (done) => { // const schema = { // componentName: 'Page', diff --git a/packages/renderer-core/tests/utils/common.test.ts b/packages/renderer-core/tests/utils/common.test.ts index a67842ed63..6fac55024f 100644 --- a/packages/renderer-core/tests/utils/common.test.ts +++ b/packages/renderer-core/tests/utils/common.test.ts @@ -1,10 +1,10 @@ // @ts-nocheck -import { - isSchema, - isFileSchema, - inSameDomain, - getFileCssName, - isJSSlot, +import { + isSchema, + isFileSchema, + inSameDomain, + getFileCssName, + isJSSlot, getValue, getI18n, transformArrayToMap, @@ -15,9 +15,11 @@ import { isString, serializeParams, parseExpression, + parseThisRequiredExpression, parseI18n, parseData, } from '../../src/utils/common'; +import logger from '../../src/utils/logger'; describe('test isSchema', () => { it('should be false when empty value is passed', () => { @@ -335,19 +337,55 @@ describe('test parseExpression ', () => { const result = parseExpression(mockExpression, { scopeValue: 1 }); expect(result({ param1: 2 })).toBe((1 + 2 + 5)); }); + + it('[success] JSExpression handle without this use scopeValue', () => { + const mockExpression = { + "type": "JSExpression", + "value": "state" + }; + const result = parseExpression(mockExpression, { state: 1 }); + expect(result).toBe((1)); + }); + + it('[success] JSExpression handle without this use scopeValue', () => { + const mockExpression = { + "type": "JSExpression", + "value": "this.state" + }; + const result = parseExpression(mockExpression, { state: 1 }); + expect(result).toBe((1)); + }); }); -describe('test parseExpression ', () => { +describe('test parseThisRequiredExpression', () => { it('can handle JSExpression', () => { const mockExpression = { "type": "JSExpression", "value": "function (params) { return this.scopeValue + params.param1 + 5;}" }; - const result = parseExpression(mockExpression, { scopeValue: 1 }); + const result = parseThisRequiredExpression(mockExpression, { scopeValue: 1 }); expect(result({ param1: 2 })).toBe((1 + 2 + 5)); }); -}); + it('[error] JSExpression handle without this use scopeValue', () => { + const mockExpression = { + "type": "JSExpression", + "value": "state.text" + }; + const fn = logger.error = jest.fn(); + parseThisRequiredExpression(mockExpression, { state: { text: 'text' } }); + expect(fn).toBeCalledWith('parseExpression.error', new ReferenceError('state is not defined'), {"type": "JSExpression", "value": "state.text"}, {"state": {"text": "text"}}); + }); + + it('[success] JSExpression handle without this use scopeValue', () => { + const mockExpression = { + "type": "JSExpression", + "value": "this.state" + }; + const result = parseThisRequiredExpression(mockExpression, { state: 1 }); + expect(result).toBe((1)); + }); +}) describe('test parseI18n ', () => { it('can handle normal parseI18n', () => { From 98bc477d80dbf7993f89befdb42762d78a55fb1b Mon Sep 17 00:00:00 2001 From: liujuping Date: Thu, 23 Jun 2022 14:56:51 +0800 Subject: [PATCH 057/823] fix: fix dataSource needs to be compatible due to empty schema --- packages/renderer-core/src/renderer/base.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index aee0203440..24425d5ef4 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -260,7 +260,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { this.__dataHelper = { updateConfig: (updateDataSource: any) => { const { dataSourceMap, reloadDataSource } = createDataSourceEngine( - updateDataSource, + updateDataSource ?? {}, this, props.__appHelper.requestHandlersMap ? { requestHandlersMap: props.__appHelper.requestHandlersMap } : undefined, ); From 85d1f0fd90d210630d8694b35e3e0571e4c62a83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=8F=8A=E8=90=8D=28=E7=B5=AE=E9=BB=8E=29?= Date: Thu, 23 Jun 2022 15:40:55 +0800 Subject: [PATCH 058/823] docs: added instructions for awesome-lowcode-engine to README (#712) --- packages/engine/README-zh_CN.md | 2 ++ packages/engine/README.md | 2 ++ 2 files changed, 4 insertions(+) diff --git a/packages/engine/README-zh_CN.md b/packages/engine/README-zh_CN.md index cdd5ca4796..91e90ad522 100644 --- a/packages/engine/README-zh_CN.md +++ b/packages/engine/README-zh_CN.md @@ -125,6 +125,8 @@ https://cdn.jsdelivr.net/npm/@alilc/lowcode-react-simulator-renderer@1.0.0/dist/ - [用户文档](https://lowcode-engine.cn/docV2) - [API](https://lowcode-engine.cn/docV2/vlmeme) +[awesome-lowcode-engine](https://github.com/lowcode-workspace/awesome-lowcode-engine) 中包含了一系列围绕引擎建设的工具、解决方案等,如果你有类似的解决方案或者工具,欢迎提 PR 到该仓库,让更多人了解到 + ## 💻 本地调试 ```bash diff --git a/packages/engine/README.md b/packages/engine/README.md index 51eb9f5504..f1d93ac318 100644 --- a/packages/engine/README.md +++ b/packages/engine/README.md @@ -125,6 +125,8 @@ Pass the files under packages/engine/dist and packages/(react|rax)-simulator-ren - [User Documentation](http://lowcode-engine.cn/docV2) - [API](http://lowcode-engine.cn/docV2/vlmeme) +The [awesome-lowcode-engine](https://github.com/lowcode-workspace/awesome-lowcode-engine) page links to many of the tools in the lowcode-engine, If you have an ecosystem or tools built around the engine, PR is welcome to this repository. + ## 💻 Local debugging ```bash From b216aa5d2bdd67f724222baca60331d169a74393 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=8F=8A=E8=90=8D=28=E7=B5=AE=E9=BB=8E=29?= Date: Thu, 23 Jun 2022 15:49:52 +0800 Subject: [PATCH 059/823] docs: added instructions for awesome-lowcode-engine to README --- packages/engine/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/engine/README.md b/packages/engine/README.md index f1d93ac318..c4cc5f8ae9 100644 --- a/packages/engine/README.md +++ b/packages/engine/README.md @@ -125,7 +125,7 @@ Pass the files under packages/engine/dist and packages/(react|rax)-simulator-ren - [User Documentation](http://lowcode-engine.cn/docV2) - [API](http://lowcode-engine.cn/docV2/vlmeme) -The [awesome-lowcode-engine](https://github.com/lowcode-workspace/awesome-lowcode-engine) page links to many of the tools in the lowcode-engine, If you have an ecosystem or tools built around the engine, PR is welcome to this repository. +This [awesome-lowcode-engine](https://github.com/lowcode-workspace/awesome-lowcode-engine) page links to a repository which records all of the tools\materials\solutions that use or built for the lowcode-engine, PR is welcomed. ## 💻 Local debugging From 7e5a919f9352397f11741fd911495996469c0256 Mon Sep 17 00:00:00 2001 From: liujuping Date: Fri, 24 Jun 2022 15:10:28 +0800 Subject: [PATCH 060/823] fix: fixed the issue that thisRequiredInJSE did not take effect in some scenarios --- packages/renderer-core/src/hoc/leaf.tsx | 5 +++-- packages/renderer-core/src/renderer/base.tsx | 8 ++++---- packages/renderer-core/src/renderer/page.tsx | 5 ++--- packages/renderer-core/src/utils/common.ts | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/renderer-core/src/hoc/leaf.tsx b/packages/renderer-core/src/hoc/leaf.tsx index e6981e729a..e626ab4045 100644 --- a/packages/renderer-core/src/hoc/leaf.tsx +++ b/packages/renderer-core/src/hoc/leaf.tsx @@ -141,6 +141,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { __debug, __getComponentProps: getProps, __getSchemaChildrenVirtualDom: getChildren, + __parseData, } = baseRenderer; const { engine } = baseRenderer.context; const host = baseRenderer.props?.__host; @@ -225,7 +226,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { nodeChildren: null, childrenInState: false, visible: !hidden, - condition: parseData(condition, scope), + condition: __parseData(condition, scope), nodeCacheProps: {}, nodeProps: {}, }; @@ -395,7 +396,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { if (key === '___condition___') { const { condition = true } = this.leaf?.export(TransformStage.Render) || {}; - const conditionValue = parseData(condition, scope); + const conditionValue = __parseData(condition, scope); __debug(`key is ___condition___, change condition value to [${condition}]`); // 条件表达式改变 this.setState({ diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 24425d5ef4..3a4bbd24c5 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -245,8 +245,8 @@ export default function baseRendererFactory(): IBaseRenderComponent { }; __parseData = (data: any, ctx?: Record) => { - const { __ctx } = this.props; - return parseData(data, ctx || __ctx || this); + const { __ctx, thisRequiredInJSE } = this.props; + return parseData(data, ctx || __ctx || this, { thisRequiredInJSE }); }; __initDataSource = (props = this.props) => { @@ -479,7 +479,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { const displayInHook = engine?.props?.designMode === 'design'; if (schema.loop != null) { - const loop = parseData(schema.loop, scope); + const loop = this.__parseData(schema.loop, scope); const useLoop = isUseLoop(loop, this._designModeIsDesign); if (useLoop) { return this.__createLoopVirtualDom( @@ -493,7 +493,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { ); } } - const condition = schema.condition == null ? true : parseData(schema.condition, scope); + const condition = schema.condition == null ? true : this.__parseData(schema.condition, scope); if (!condition && !displayInHook) return null; let scopeKey = ''; diff --git a/packages/renderer-core/src/renderer/page.tsx b/packages/renderer-core/src/renderer/page.tsx index 8446d332dd..380e0fb36f 100644 --- a/packages/renderer-core/src/renderer/page.tsx +++ b/packages/renderer-core/src/renderer/page.tsx @@ -1,5 +1,4 @@ import baseRendererFactory from './base'; -import { parseData } from '../utils'; import { IBaseRendererProps, IBaseRenderComponent } from '../types'; export default function pageRendererFactory(): IBaseRenderComponent { @@ -21,8 +20,8 @@ export default function pageRendererFactory(): IBaseRenderComponent { async componentDidUpdate(prevProps: IBaseRendererProps, _prevState: {}, snapshot: unknown) { const { __ctx } = this.props; - const prevState = parseData(prevProps.__schema.state, __ctx); - const newState = parseData(this.props.__schema.state, __ctx); + const prevState = this.__parseData(prevProps.__schema.state, __ctx); + const newState = this.__parseData(this.props.__schema.state, __ctx); // 当编排的时候修改schema.state值,需要将最新schema.state值setState if (JSON.stringify(newState) != JSON.stringify(prevState)) { this.setState(newState); diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index 8db913f3d3..cf46cf38da 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -330,15 +330,15 @@ export function forEach(targetObj: any, fn: any, context?: any) { Object.keys(targetObj).forEach((key) => fn.call(context, targetObj[key], key)); } -export function parseData(schema: unknown, self: any): any { +export function parseData(schema: unknown, self: any, options: any): any { if (isJSExpression(schema)) { - return parseExpression(schema, self); + return parseExpression(schema, self, options.thisRequiredInJSE); } else if (isI18nData(schema)) { return parseI18n(schema, self); } else if (typeof schema === 'string') { return schema.trim(); } else if (Array.isArray(schema)) { - return schema.map((item) => parseData(item, self)); + return schema.map((item) => parseData(item, self, options)); } else if (typeof schema === 'function') { return schema.bind(self); } else if (typeof schema === 'object') { @@ -351,7 +351,7 @@ export function parseData(schema: unknown, self: any): any { if (key.startsWith('__')) { return; } - res[key] = parseData(val, self); + res[key] = parseData(val, self, options); }); return res; } From c2c59b7ff72ba06156bbcdb952262739d6188209 Mon Sep 17 00:00:00 2001 From: liujuping Date: Fri, 24 Jun 2022 16:01:43 +0800 Subject: [PATCH 061/823] fix: fix the unit test failure problem caused by thisRequiredInJSE modification --- packages/renderer-core/src/hoc/leaf.tsx | 4 ++-- packages/renderer-core/src/utils/common.ts | 6 +++++- packages/renderer-core/tests/hoc/leaf.test.tsx | 4 ++++ packages/renderer-core/tests/renderer/renderer.test.tsx | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/packages/renderer-core/src/hoc/leaf.tsx b/packages/renderer-core/src/hoc/leaf.tsx index e626ab4045..3c1c96b721 100644 --- a/packages/renderer-core/src/hoc/leaf.tsx +++ b/packages/renderer-core/src/hoc/leaf.tsx @@ -226,7 +226,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { nodeChildren: null, childrenInState: false, visible: !hidden, - condition: __parseData(condition, scope), + condition: __parseData?.(condition, scope), nodeCacheProps: {}, nodeProps: {}, }; @@ -396,7 +396,7 @@ export function leafWrapper(Comp: types.IBaseRenderComponent, { if (key === '___condition___') { const { condition = true } = this.leaf?.export(TransformStage.Render) || {}; - const conditionValue = __parseData(condition, scope); + const conditionValue = __parseData?.(condition, scope); __debug(`key is ___condition___, change condition value to [${condition}]`); // 条件表达式改变 this.setState({ diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index cf46cf38da..0150095b3d 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -330,7 +330,11 @@ export function forEach(targetObj: any, fn: any, context?: any) { Object.keys(targetObj).forEach((key) => fn.call(context, targetObj[key], key)); } -export function parseData(schema: unknown, self: any, options: any): any { +interface IParseOptions { + thisRequiredInJSE?: boolean; +} + +export function parseData(schema: unknown, self: any, options: IParseOptions = {}): any { if (isJSExpression(schema)) { return parseExpression(schema, self, options.thisRequiredInJSE); } else if (isI18nData(schema)) { diff --git a/packages/renderer-core/tests/hoc/leaf.test.tsx b/packages/renderer-core/tests/hoc/leaf.test.tsx index 106e6741a9..308a8b900b 100644 --- a/packages/renderer-core/tests/hoc/leaf.test.tsx +++ b/packages/renderer-core/tests/hoc/leaf.test.tsx @@ -5,6 +5,7 @@ import '../utils/react-env-init'; import { leafWrapper } from '../../src/hoc/leaf'; import components from '../utils/components'; import Node from '../utils/node'; +import { parseData } from '../../src/utils'; let rerenderCount = 0; @@ -37,6 +38,9 @@ const baseRenderer: any = { } }, documentId: '01' + }, + __parseData (data, scope) { + return parseData(data, scope, {}); } } diff --git a/packages/renderer-core/tests/renderer/renderer.test.tsx b/packages/renderer-core/tests/renderer/renderer.test.tsx index 580e571859..36ee4167e8 100644 --- a/packages/renderer-core/tests/renderer/renderer.test.tsx +++ b/packages/renderer-core/tests/renderer/renderer.test.tsx @@ -329,7 +329,7 @@ describe('JSExpression', () => { ], loop: { type: "JSExpression", - value: "state.content" + value: "this.state.content" }, loopArgs: [ "item", From 8e5fcd1d598918f8b99a4f03ed853d0ccd32c300 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Mon, 27 Jun 2022 15:25:01 +0800 Subject: [PATCH 062/823] chore: update stale workflow --- .github/workflows/stale.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index aa9b14b045..2cb0ccaf8b 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -14,9 +14,9 @@ jobs: close-issue-message: 'This issue was closed because it has been stalled for 10 days with no activity.' close-pr-message: 'This PR was closed because it has been stalled for 10 days with no activity.' days-before-issue-stale: 10 - days-before-issue-close: 2 + days-before-issue-close: 10 days-before-pr-stale: 10 - days-before-pr-close: 2 - exempt-issue-labels: 'bug,enhancement,good first issue,help wanted,WIP' + days-before-pr-close: 10 + exempt-issue-labels: 'bug,enhancement,good first issue,help wanted,WIP,discussion,documentation,later,material' stale-issue-label: 'stale' stale-pr-label: 'stale' \ No newline at end of file From 152a24d65528d0a3b7990c9aa87e6d8d09aa9b2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Tue, 28 Jun 2022 10:05:16 +0800 Subject: [PATCH 063/823] feat: add flag createIfNode for ShellNode#getProp --- packages/shell/src/node.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/shell/src/node.ts b/packages/shell/src/node.ts index 72afd46b82..ca061dcb5d 100644 --- a/packages/shell/src/node.ts +++ b/packages/shell/src/node.ts @@ -330,8 +330,8 @@ export default class Node { * @param path 属性路径,支持 a / a.b / a.0 等格式 * @returns */ - getProp(path: string): Prop | null { - return Prop.create(this[nodeSymbol].getProp(path)); + getProp(path: string, createIfNone = true): Prop | null { + return Prop.create(this[nodeSymbol].getProp(path, createIfNone)); } /** @@ -340,7 +340,7 @@ export default class Node { * @returns */ getPropValue(path: string) { - return this.getProp(path)?.getValue(); + return this.getProp(path, false)?.getValue(); } /** From 3f7c0cd5191b7924f2630c58e6439f4d4a936ac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Tue, 28 Jun 2022 10:58:39 +0800 Subject: [PATCH 064/823] feat: support opening document with id --- packages/designer/src/project/project.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/designer/src/project/project.ts b/packages/designer/src/project/project.ts index 4d56d04417..3e17c1c9df 100644 --- a/packages/designer/src/project/project.ts +++ b/packages/designer/src/project/project.ts @@ -214,7 +214,7 @@ export class Project { return doc.open(); } if (typeof doc === 'string') { - const got = this.documents.find((item) => item.fileName === doc); + const got = this.documents.find((item) => item.fileName === doc || item.id === doc); if (got) { return got.open(); } From 23cf6bc7789846d97f412e862f835ffae6508e9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Tue, 28 Jun 2022 14:06:01 +0800 Subject: [PATCH 065/823] chore(release): publish 1.0.11 --- lerna.json | 2 +- packages/designer/package.json | 10 +++++----- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 16 ++++++++-------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 10 +++++----- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 12 ++++++------ packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- 16 files changed, 60 insertions(+), 60 deletions(-) diff --git a/lerna.json b/lerna.json index 03f8059926..16a30579bd 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.0.10", + "version": "1.0.11", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index 73d9041429..5ac7922622 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.0.10", + "version": "1.0.11", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,10 +15,10 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.0.10", - "@alilc/lowcode-shell": "1.0.10", - "@alilc/lowcode-types": "1.0.10", - "@alilc/lowcode-utils": "1.0.10", + "@alilc/lowcode-editor-core": "1.0.11", + "@alilc/lowcode-shell": "1.0.11", + "@alilc/lowcode-types": "1.0.11", + "@alilc/lowcode-utils": "1.0.11", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index b424953ca7..ab4a9b250a 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.0.10", + "version": "1.0.11", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.0.10", - "@alilc/lowcode-utils": "1.0.10", + "@alilc/lowcode-types": "1.0.11", + "@alilc/lowcode-utils": "1.0.11", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 3e31f9f64a..85a8444ea6 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.0.10", + "version": "1.0.11", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -18,10 +18,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.0.10", - "@alilc/lowcode-editor-core": "1.0.10", - "@alilc/lowcode-types": "1.0.10", - "@alilc/lowcode-utils": "1.0.10", + "@alilc/lowcode-designer": "1.0.11", + "@alilc/lowcode-editor-core": "1.0.11", + "@alilc/lowcode-types": "1.0.11", + "@alilc/lowcode-utils": "1.0.11", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index d01872fdc2..7895ea08ce 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.0.10", + "version": "1.0.11", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,14 +19,14 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.0.10", - "@alilc/lowcode-editor-core": "1.0.10", - "@alilc/lowcode-editor-skeleton": "1.0.10", + "@alilc/lowcode-designer": "1.0.11", + "@alilc/lowcode-editor-core": "1.0.11", + "@alilc/lowcode-editor-skeleton": "1.0.11", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.0.10", - "@alilc/lowcode-plugin-outline-pane": "1.0.10", - "@alilc/lowcode-shell": "1.0.10", - "@alilc/lowcode-utils": "1.0.10", + "@alilc/lowcode-plugin-designer": "1.0.11", + "@alilc/lowcode-plugin-outline-pane": "1.0.11", + "@alilc/lowcode-shell": "1.0.11", + "@alilc/lowcode-utils": "1.0.11", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index 2740bfcb5b..9dbb6e1ccb 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.0.10", + "version": "1.0.11", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 0b55680072..5fd0c1c734 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.0.10", + "version": "1.0.11", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.0.10", - "@alilc/lowcode-editor-core": "1.0.10", - "@alilc/lowcode-utils": "1.0.10", + "@alilc/lowcode-designer": "1.0.11", + "@alilc/lowcode-editor-core": "1.0.11", + "@alilc/lowcode-utils": "1.0.11", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index ec914c3403..c6e16d5fff 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.0.10", + "version": "1.0.11", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,10 +13,10 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-designer": "1.0.10", - "@alilc/lowcode-editor-core": "1.0.10", - "@alilc/lowcode-types": "1.0.10", - "@alilc/lowcode-utils": "1.0.10", + "@alilc/lowcode-designer": "1.0.11", + "@alilc/lowcode-editor-core": "1.0.11", + "@alilc/lowcode-types": "1.0.11", + "@alilc/lowcode-utils": "1.0.11", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0" diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index e93aed607b..3c8e5b1cec 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.0.10", + "version": "1.0.11", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.0.10", - "@alilc/lowcode-utils": "1.0.10", + "@alilc/lowcode-renderer-core": "1.0.11", + "@alilc/lowcode-utils": "1.0.11", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index 96c2e3123a..be83eb72ba 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.0.10", + "version": "1.0.11", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.0.10", - "@alilc/lowcode-rax-renderer": "1.0.10", - "@alilc/lowcode-types": "1.0.10", - "@alilc/lowcode-utils": "1.0.10", + "@alilc/lowcode-designer": "1.0.11", + "@alilc/lowcode-rax-renderer": "1.0.11", + "@alilc/lowcode-types": "1.0.11", + "@alilc/lowcode-utils": "1.0.11", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 73274bdb7b..2a344f9602 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.0.10", + "version": "1.0.11", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.0.10" + "@alilc/lowcode-renderer-core": "1.0.11" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index c581c83bde..715eaee75b 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.0.10", + "version": "1.0.11", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -16,10 +16,10 @@ "build:umd": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.0.10", - "@alilc/lowcode-react-renderer": "1.0.10", - "@alilc/lowcode-types": "1.0.10", - "@alilc/lowcode-utils": "1.0.10", + "@alilc/lowcode-designer": "1.0.11", + "@alilc/lowcode-react-renderer": "1.0.11", + "@alilc/lowcode-types": "1.0.11", + "@alilc/lowcode-utils": "1.0.11", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index cb1ad7e866..6fdb79de92 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.0.10", + "version": "1.0.11", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.0.10", - "@alilc/lowcode-utils": "1.0.10", + "@alilc/lowcode-types": "1.0.11", + "@alilc/lowcode-utils": "1.0.11", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -34,7 +34,7 @@ }, "devDependencies": { "@alib/build-scripts": "^0.1.18", - "@alilc/lowcode-designer": "1.0.10", + "@alilc/lowcode-designer": "1.0.11", "@alilc/lowcode-test-mate": "^1.0.1", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", diff --git a/packages/shell/package.json b/packages/shell/package.json index 80f28e38be..bc1dba890d 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.0.10", + "version": "1.0.11", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.0.10", - "@alilc/lowcode-editor-core": "1.0.10", - "@alilc/lowcode-editor-skeleton": "1.0.10", - "@alilc/lowcode-types": "1.0.10", - "@alilc/lowcode-utils": "1.0.10", + "@alilc/lowcode-designer": "1.0.11", + "@alilc/lowcode-editor-core": "1.0.11", + "@alilc/lowcode-editor-skeleton": "1.0.11", + "@alilc/lowcode-types": "1.0.11", + "@alilc/lowcode-utils": "1.0.11", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index d0ea37729d..2d3dfc6566 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.0.10", + "version": "1.0.11", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index cd81e1f6c7..0db08d7d04 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.0.10", + "version": "1.0.11", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.0.10", + "@alilc/lowcode-types": "1.0.11", "lodash": "^4.17.21", "react": "^16", "zen-logger": "^1.1.0" From 6bb64f3aa1fa41d1284565addaf3976ffded1abb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Tue, 28 Jun 2022 14:50:14 +0800 Subject: [PATCH 066/823] chore: remove unused deps for renderer-core --- packages/renderer-core/package.json | 2 -- packages/renderer-core/src/utils/common.ts | 9 +-------- 2 files changed, 1 insertion(+), 10 deletions(-) diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 6fdb79de92..6cfa1d924d 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -27,7 +27,6 @@ "moment": "^2.24.0", "prop-types": "^15.7.2", "react-is": "^16.10.1", - "serialize-javascript": "^1.7.0", "socket.io-client": "^2.2.0", "whatwg-fetch": "^3.0.0", "zen-logger": "^1.1.4" @@ -45,7 +44,6 @@ "@types/node": "^13.7.1", "@types/prop-types": "^15.7.3", "@types/react-test-renderer": "^17.0.1", - "@types/serialize-javascript": "^5.0.0", "babel-jest": "^26.5.2", "build-plugin-component": "^0.2.11", "jest": "^26.6.3", diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index 0150095b3d..d605589710 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -5,22 +5,15 @@ import { isI18nData, RootSchema, NodeSchema, isJSExpression, JSSlot } from '@ali // moment对象配置 import _moment from 'moment'; import 'moment/locale/zh-cn'; -import pkg from '../../package.json'; - import { isEmpty } from 'lodash'; - -import _serialize from 'serialize-javascript'; -import * as _jsonuri from 'jsonuri'; - import IntlMessageFormat from 'intl-messageformat'; +import pkg from '../../package.json'; export const moment = _moment; moment.locale('zh-cn'); (window as any).sdkVersion = pkg.version; export { pick, isEqualWith as deepEqual, cloneDeep as clone, isEmpty, throttle, debounce } from 'lodash'; -export const jsonuri = _jsonuri; -export const serialize = _serialize; const ReactIs = require('react-is'); const ReactPropTypesSecret = require('prop-types/lib/ReactPropTypesSecret'); From 6fe774d09fcde3598e5281bc102737f23ff9d959 Mon Sep 17 00:00:00 2001 From: liujuping Date: Tue, 28 Jun 2022 12:09:12 +0800 Subject: [PATCH 067/823] docs: added issue documentation --- .github/ISSUE_TEMPLATE/bug-report.md | 2 +- .github/workflows/insufficient information.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index f2292f413e..193cab77eb 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -1,6 +1,6 @@ --- name: Bug report / 提交 bug -about: Create a report to help us improve / 提交一个好的 bug 帮助我们优化引擎 +about: Create a report to help us improve / 提交一个好的 issue 帮助我们优化引擎,[引擎的 issue 说明](https://www.yuque.com/lce/doc/yvlxhs) title: '' labels: '' assignees: '' diff --git a/.github/workflows/insufficient information.yml b/.github/workflows/insufficient information.yml index 33c1d39067..2b699860d6 100644 --- a/.github/workflows/insufficient information.yml +++ b/.github/workflows/insufficient information.yml @@ -16,4 +16,4 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} issue-number: ${{ github.event.issue.number }} body: | - 你好 @${{ github.event.issue.user.login }},由于缺乏必要的信息(如 bug 重现步骤、引擎版本信息 等),无法定位问题,请按照 [issue bug 模板](https://github.com/alibaba/lowcode-engine/blob/main/.github/ISSUE_TEMPLATE/bug-report.md) 补全信息。 + 你好 @${{ github.event.issue.user.login }},由于缺乏必要的信息(如 bug 重现步骤、引擎版本信息 等),无法定位问题,请按照 [issue bug 模板](https://github.com/alibaba/lowcode-engine/blob/main/.github/ISSUE_TEMPLATE/bug-report.md) 补全信息,也可以通过阅读[引擎的 issue 说明](https://www.yuque.com/lce/doc/yvlxhs) 了解什么类型的 issue 可以获得更好、更快的支持。 From 900b2394323e85f0dce5df83dfc773f96da23e24 Mon Sep 17 00:00:00 2001 From: zyy7259 Date: Tue, 28 Jun 2022 14:34:16 +0800 Subject: [PATCH 068/823] feat: pass e to customizeIgnoreSelectors --- packages/designer/src/builtin-simulator/host.ts | 2 +- packages/editor-core/src/config.ts | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index e40566f57d..4bf049f5b8 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -618,7 +618,7 @@ export class BuiltinSimulatorHost implements ISimulatorHost string[]', + description: '定制画布中点击被忽略的 selectors, eg. (defaultIgnoreSelectors: string[], e: MouseEvent) => string[]', }, disableDefaultSettingPanel: { type: 'boolean', @@ -192,7 +192,7 @@ export interface EngineOptions { /** * 定制画布中点击被忽略的 selectors,默认值:undefined */ - customizeIgnoreSelectors?: (defaultIgnoreSelectors: string[]) => string[]; + customizeIgnoreSelectors?: (defaultIgnoreSelectors: string[], e: MouseEvent) => string[]; /** * 禁止默认的设置面板,默认值:false */ From 5dd462544fbbbccfa97165f2bcfeed8629fab2a3 Mon Sep 17 00:00:00 2001 From: liujuping Date: Wed, 29 Jun 2022 16:17:25 +0800 Subject: [PATCH 069/823] fix: fix low-code component rendering problems: 1. thisRequiredInJSE does not take effect 2. jsx components cannot obtain source components --- .../rax-simulator-renderer/src/renderer.ts | 3 ++- .../react-simulator-renderer/src/renderer.ts | 3 ++- packages/renderer-core/src/renderer/base.tsx | 10 +++++++++- packages/utils/src/build-components.ts | 19 +++++++++++++++++++ 4 files changed, 32 insertions(+), 3 deletions(-) diff --git a/packages/rax-simulator-renderer/src/renderer.ts b/packages/rax-simulator-renderer/src/renderer.ts index b2dcbaec04..0e42785e75 100644 --- a/packages/rax-simulator-renderer/src/renderer.ts +++ b/packages/rax-simulator-renderer/src/renderer.ts @@ -523,10 +523,11 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer { ...extraProps, schema: _schema, components, - designMode: renderer.designMode, + designMode: '', device: renderer.device, appHelper: renderer.context, rendererName: 'LowCodeRenderer', + thisRequiredInJSE: host.thisRequiredInJSE, customCreateElement: (Comp: any, props: any, children: any) => { const componentMeta = host.currentDocument?.getComponentMeta(Comp.displayName); if (componentMeta?.isModal) { diff --git a/packages/react-simulator-renderer/src/renderer.ts b/packages/react-simulator-renderer/src/renderer.ts index 6c246e0949..5605ba4799 100644 --- a/packages/react-simulator-renderer/src/renderer.ts +++ b/packages/react-simulator-renderer/src/renderer.ts @@ -450,10 +450,11 @@ export class SimulatorRendererContainer implements BuiltinSimulatorRenderer { // 使用 _schema 为了使低代码组件在页面设计中使用变量,同 react 组件使用效果一致 schema: _schema, components: renderer.components, - designMode: renderer.designMode, + designMode: '', device: renderer.device, appHelper: renderer.context, rendererName: 'LowCodeRenderer', + thisRequiredInJSE: host.thisRequiredInJSE, customCreateElement: (Comp: any, props: any, children: any) => { const componentMeta = host.currentDocument?.getComponentMeta(Comp.displayName); if (componentMeta?.isModal) { diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 3a4bbd24c5..28c44964a2 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -116,7 +116,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { if (func) { if (isJSExpression(func) || isJSFunction(func)) { const fn = props.thisRequiredInJSE ? parseThisRequiredExpression(func, this) : parseExpression(func, this); - return fn(props, state); + return fn?.(props, state); } if (typeof func === 'function') { @@ -210,6 +210,14 @@ export default function baseRendererFactory(): IBaseRenderComponent { } }; + _getComponentView = (componentName: string) => { + const { __components } = this.props; + if (!__components) { + return; + } + return __components[componentName]; + }; + __bindCustomMethods = (props = this.props) => { const { __schema } = props; const customMethodsList = Object.keys(__schema.methods || {}) || []; diff --git a/packages/utils/src/build-components.ts b/packages/utils/src/build-components.ts index 78c5b6c2f7..c18952af12 100644 --- a/packages/utils/src/build-components.ts +++ b/packages/utils/src/build-components.ts @@ -3,6 +3,7 @@ import { NpmInfo, ComponentSchema } from '@alilc/lowcode-types'; import { Component } from '@alilc/lowcode-designer'; import { isESModule } from './is-es-module'; import { isReactComponent, acceptsRef, wrapReactClass } from './is-react'; +import { isObject } from './is-object'; interface LibraryMap { [key: string]: string; @@ -76,6 +77,22 @@ function findComponent(libraryMap: LibraryMap, componentName: string, npm?: NpmI return getSubComponent(library, paths); } +/** + * 判断是否是一个混合组件,即 components 是一个对象,对象值是 React 组件 + * 示例: + * { + * Button: ReactNode, + * Text: ReactNode, + * } + */ +function isMixinComponent(components: any) { + if (!isObject(components)) { + return false; + } + + return Object.keys(components).some(componentName => isReactComponent(components[componentName])); +} + export function buildComponents(libraryMap: LibraryMap, componentsMap: { [componentName: string]: NpmInfo | ComponentType | ComponentSchema }, createComponent: (schema: ComponentSchema) => Component | null) { @@ -89,6 +106,8 @@ export function buildComponents(libraryMap: LibraryMap, component = wrapReactClass(component as FunctionComponent); } components[componentName] = component; + } else if (isMixinComponent(component)) { + components[componentName] = component; } else { component = findComponent(libraryMap, componentName, component); if (component) { From 4b59190c7f9d518bc7efac44b7eeee73f1b5d177 Mon Sep 17 00:00:00 2001 From: JackLian Date: Wed, 29 Jun 2022 20:16:05 +0800 Subject: [PATCH 070/823] fix: fix lint issues for renderer-core/renderer/base --- packages/renderer-core/src/renderer/base.tsx | 84 +++++++++++-------- .../tests/adapter/adapter.test.ts | 1 - .../tests/renderer/base.test.tsx | 18 ++++ 3 files changed, 66 insertions(+), 37 deletions(-) create mode 100644 packages/renderer-core/tests/renderer/base.test.tsx diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 28c44964a2..dfc1e5f42b 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -1,3 +1,4 @@ +/* eslint-disable no-console */ /* eslint-disable max-len */ /* eslint-disable react/prop-types */ import classnames from 'classnames'; @@ -47,7 +48,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { Record, any >; - const createElement = runtime.createElement; + const { createElement } = runtime; const Div = divFactory(); const VisualDom = visualDomFactory(); const AppContext = contextFactory(); @@ -97,6 +98,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { this.__debug(`constructor - ${props?.__schema?.fileName}`); } + // eslint-disable-next-line @typescript-eslint/no-unused-vars __beforeInit(_props: IBaseRendererProps) { } __init(props: IBaseRendererProps) { @@ -107,6 +109,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { this.__initI18nAPIs(); } + // eslint-disable-next-line @typescript-eslint/no-unused-vars __afterInit(_props: IBaseRendererProps) { } static getDerivedStateFromProps(props: IBaseRendererProps, state: any) { @@ -120,35 +123,36 @@ export default function baseRendererFactory(): IBaseRenderComponent { } if (typeof func === 'function') { + // eslint-disable-next-line @typescript-eslint/ban-types return (func as Function)(props, state); } } return null; } - async getSnapshotBeforeUpdate() { - this.__setLifeCycleMethods('getSnapshotBeforeUpdate', arguments); + async getSnapshotBeforeUpdate(...args: any[]) { + this.__setLifeCycleMethods('getSnapshotBeforeUpdate', args); this.__debug(`getSnapshotBeforeUpdate - ${this.props?.__schema?.fileName}`); } - async componentDidMount() { + async componentDidMount(...args: any[]) { this.reloadDataSource(); - this.__setLifeCycleMethods('componentDidMount', arguments); + this.__setLifeCycleMethods('componentDidMount', args); this.__debug(`componentDidMount - ${this.props?.__schema?.fileName}`); } - async componentDidUpdate(...args: any) { + async componentDidUpdate(...args: any[]) { this.__setLifeCycleMethods('componentDidUpdate', args); this.__debug(`componentDidUpdate - ${this.props.__schema.fileName}`); } - async componentWillUnmount(...args: any) { + async componentWillUnmount(...args: any[]) { this.__setLifeCycleMethods('componentWillUnmount', args); this.__debug(`componentWillUnmount - ${this.props?.__schema?.fileName}`); } - async componentDidCatch(e: any) { - this.__setLifeCycleMethods('componentDidCatch', arguments); + async componentDidCatch(e: any, ...args: any[]) { + this.__setLifeCycleMethods('componentDidCatch', { e, ...args }); console.warn(e); } @@ -165,7 +169,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { this.forceUpdate(); return resolve({}); } - this.setState(res, resolve); + this.setState(res, resolve as () => void); }) .catch((err: Error) => { if (this.__showPlaceholder) { @@ -229,14 +233,15 @@ export default function baseRendererFactory(): IBaseRenderComponent { }); this.__customMethodsList = customMethodsList; forEach(__schema.methods, (val: any, key: string) => { - if (isJSExpression(val) || isJSFunction(val)) { - val = this.parseExpression(val, this); + let value = val; + if (isJSExpression(value) || isJSFunction(value)) { + value = this.parseExpression(value, this); } - if (typeof val !== 'function') { - console.error(`自定义函数${key}类型不符`, val); + if (typeof value !== 'function') { + console.error(`自定义函数${key}类型不符`, value); return; } - this[key] = val.bind(this); + this[key] = value.bind(this); }); }; @@ -304,7 +309,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { this.forceUpdate(); return resolve({}); } - this.setState(res, resolve); + this.setState(res, resolve as () => void); }) .catch((err: Error) => { if (this.__showPlaceholder) { @@ -417,7 +422,9 @@ export default function baseRendererFactory(): IBaseRenderComponent { // self 为每个渲染组件构造的上下文,self是自上而下继承的 // parentInfo 父组件的信息,包含schema和Comp // idx 若为循环渲染的循环Index - __createVirtualDom = (schema: NodeData | NodeData[] | undefined, scope: any, parentInfo: IInfo, idx: string | number = ''): any => { + __createVirtualDom = (originalSchema: NodeData | NodeData[] | undefined, originalScope: any, parentInfo: IInfo, idx: string | number = ''): any => { + let scope = originalScope; + let schema = originalSchema; const { engine } = this.context || {}; try { if (!schema) return null; @@ -588,7 +595,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { } let child = this.__getSchemaChildrenVirtualDom(schema, scope, Comp); - const renderComp = (props: any) => engine.createElement(Comp, props, child); + const renderComp = (innerProps: any) => engine.createElement(Comp, innerProps, child); // 设计模式下的特殊处理 if (engine && [DESIGN_MODE.EXTEND, DESIGN_MODE.BORDER].includes(engine.props.designMode)) { // 对于overlay,dialog等组件为了使其在设计模式下显示,外层需要增加一个div容器 @@ -698,7 +705,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { if (!Array.isArray(schema.loop)) return null; const itemArg = (schema.loopArgs && schema.loopArgs[0]) || 'item'; const indexArg = (schema.loopArgs && schema.loopArgs[1]) || 'index'; - const loop: (JSONValue| CompositeValue)[] = schema.loop; + const { loop } = schema; return loop.map((item: JSONValue | CompositeValue, i: number) => { const loopSelf: any = { [itemArg]: item, @@ -722,7 +729,8 @@ export default function baseRendererFactory(): IBaseRenderComponent { return engine?.props?.designMode === 'design'; } - __parseProps = (props: any, scope: any, path: string, info: IInfo): any => { + __parseProps = (originalProps: any, scope: any, path: string, info: IInfo): any => { + let props = originalProps; const { schema, Comp, componentInfo = {} } = info; const propInfo = getValue(componentInfo.props, path); // FIXME! 将这行逻辑外置,解耦,线上环境不要验证参数,调试环境可以有,通过传参自定义 @@ -737,14 +745,14 @@ export default function baseRendererFactory(): IBaseRenderComponent { if (isEmpty(params)) { return checkProps(this.__createVirtualDom(data, scope, ({ schema, Comp } as IInfo))); } - return checkProps(function () { + return checkProps((...argValues: any[]) => { const args: any = {}; if (Array.isArray(params) && params.length) { params.forEach((item, idx) => { if (typeof item === 'string') { - args[item] = arguments[idx]; + args[item] = argValues[idx]; } else if (item && typeof item === 'object') { - args[item.name] = arguments[idx]; + args[item.name] = argValues[idx]; } }); } @@ -770,7 +778,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { if (!isSchema(props) && !isJSSlot(props)) return checkProps(props); } - const handleLegaoI18n = (props: any) => props[props.use || 'zh_CN']; + const handleLegaoI18n = (innerProps: any) => innerProps[innerProps.use || 'zh_CN']; // 兼容乐高设计态 i18n 数据 if (isI18nData(props)) { @@ -810,13 +818,16 @@ export default function baseRendererFactory(): IBaseRenderComponent { && propInfo?.props?.types?.indexOf('ReactNode') > -1 && propInfo?.props?.reactNodeProps?.type === 'function' ); + + let params = null; + if (isReactNodeFunction) { + params = propInfo?.props?.params; + } else if (isMixinReactNodeFunction) { + params = propInfo?.props?.reactNodeProps?.params; + } return parseReactNode( props, - isReactNodeFunction - ? propInfo.props.params - : isMixinReactNodeFunction - ? propInfo.props.reactNodeProps.params - : null, + params, ); } if (Array.isArray(props)) { @@ -857,15 +868,13 @@ export default function baseRendererFactory(): IBaseRenderComponent { __debug = logger.log; __renderContextProvider = (customProps?: object, children?: any) => { - customProps = customProps || {}; - children = children || this.__createDom(); return createElement(AppContext.Provider, { value: { ...this.context, blockContext: this, - ...customProps, + ...(customProps || {}), }, - children, + children: children || this.__createDom(), }); }; @@ -873,7 +882,8 @@ export default function baseRendererFactory(): IBaseRenderComponent { return createElement(AppContext.Consumer, {}, children); }; - __getHocComp(Comp: any, schema: any, scope: any) { + __getHocComp(OriginalComp: any, schema: any, scope: any) { + let Comp = OriginalComp; this.componentHoc.forEach((ComponentConstruct: IComponentConstruct) => { Comp = ComponentConstruct(Comp || Div, { schema, @@ -886,7 +896,8 @@ export default function baseRendererFactory(): IBaseRenderComponent { return Comp; } - __renderComp(Comp: any, ctxProps: object) { + __renderComp(OriginalComp: any, ctxProps: object) { + let Comp = OriginalComp; const { __schema } = this.props; const { __ctx } = this.props; const scope: any = {}; @@ -935,7 +946,8 @@ export default function baseRendererFactory(): IBaseRenderComponent { }, children); } - __checkSchema = (schema: NodeSchema | undefined, extraComponents: string | string[] = []) => { + __checkSchema = (schema: NodeSchema | undefined, originalExtraComponents: string | string[] = []) => { + let extraComponents = originalExtraComponents; if (typeof extraComponents === 'string') { extraComponents = [extraComponents]; } diff --git a/packages/renderer-core/tests/adapter/adapter.test.ts b/packages/renderer-core/tests/adapter/adapter.test.ts index 77e12c5878..a838602fbe 100644 --- a/packages/renderer-core/tests/adapter/adapter.test.ts +++ b/packages/renderer-core/tests/adapter/adapter.test.ts @@ -1,6 +1,5 @@ // @ts-nocheck import adapter, { Env } from '../../src/adapter'; -import { IRuntime, IRendererModules, IGeneralConstructor } from '../../src/types'; diff --git a/packages/renderer-core/tests/renderer/base.test.tsx b/packages/renderer-core/tests/renderer/base.test.tsx new file mode 100644 index 0000000000..5d8d24a805 --- /dev/null +++ b/packages/renderer-core/tests/renderer/base.test.tsx @@ -0,0 +1,18 @@ +const mockGetRenderers = jest.fn(); +jest.mock('../../src/adapter', () => { + return { + getRenderers: () => { return mockGetRenderers();} + }; +}); + +import baseRendererFactory from '../../src/renderer/base'; + +describe('Base Render', () => { + it('customBaseRenderer logic works', () => { + mockGetRenderers.mockReturnValue({BaseRenderer: {}}); + const baseRenderer = baseRendererFactory(); + expect(mockGetRenderers).toBeCalledTimes(1); + expect(baseRenderer).toStrictEqual({}); + mockGetRenderers.mockClear(); + }); +}); \ No newline at end of file From d85437d4af1043371e27dfde98cecf914b93a126 Mon Sep 17 00:00:00 2001 From: JackLian Date: Wed, 29 Jun 2022 21:15:24 +0800 Subject: [PATCH 071/823] fix: fix lint issues for renderer-core/renderer/base --- packages/renderer-core/src/renderer/base.tsx | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index dfc1e5f42b..372f368d9d 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -151,9 +151,9 @@ export default function baseRendererFactory(): IBaseRenderComponent { this.__debug(`componentWillUnmount - ${this.props?.__schema?.fileName}`); } - async componentDidCatch(e: any, ...args: any[]) { - this.__setLifeCycleMethods('componentDidCatch', { e, ...args }); - console.warn(e); + async componentDidCatch(...args: any[]) { + this.__setLifeCycleMethods('componentDidCatch', args); + console.warn(args); } reloadDataSource = () => new Promise((resolve, reject) => { From 951d1cb103fa46c0e7926d6138657c7d10cc4f88 Mon Sep 17 00:00:00 2001 From: keuby Date: Tue, 5 Jul 2022 15:19:20 +0800 Subject: [PATCH 072/823] fix(types): rrror declaration of the children prop --- packages/types/src/schema.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/types/src/schema.ts b/packages/types/src/schema.ts index c36a7c436b..2895cd5eee 100644 --- a/packages/types/src/schema.ts +++ b/packages/types/src/schema.ts @@ -26,7 +26,7 @@ export interface NodeSchema { * 组件属性对象 */ props?: { - children?: NodeData[]; + children?: NodeData | NodeData[]; } & PropsMap;// | PropsList; /** * 组件属性对象 From 12f67dcdeb577622eb7e2ebaa6c484db133b88b2 Mon Sep 17 00:00:00 2001 From: JackLian Date: Tue, 5 Jul 2022 15:38:28 +0800 Subject: [PATCH 073/823] refactor: change __setLifeCycleMethods to its actual meaning __excuteLifeCycleMethod --- packages/renderer-core/src/renderer/addon.tsx | 2 +- packages/renderer-core/src/renderer/base.tsx | 14 +++++++------- packages/renderer-core/src/renderer/block.tsx | 2 +- packages/renderer-core/src/renderer/component.tsx | 2 +- packages/renderer-core/src/renderer/page.tsx | 4 ++-- packages/renderer-core/src/types/index.ts | 2 +- 6 files changed, 13 insertions(+), 13 deletions(-) diff --git a/packages/renderer-core/src/renderer/addon.tsx b/packages/renderer-core/src/renderer/addon.tsx index 1341fbb352..964de1858f 100644 --- a/packages/renderer-core/src/renderer/addon.tsx +++ b/packages/renderer-core/src/renderer/addon.tsx @@ -45,7 +45,7 @@ export default function addonRendererFactory(): IBaseRenderComponent { this.__initDataSource(props); this.open = this.open || (() => { }); this.close = this.close || (() => { }); - this.__setLifeCycleMethods('constructor', [...arguments]); + this.__excuteLifeCycleMethod('constructor', [...arguments]); } async componentWillUnmount() { diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 372f368d9d..32bc0c5a82 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -131,28 +131,28 @@ export default function baseRendererFactory(): IBaseRenderComponent { } async getSnapshotBeforeUpdate(...args: any[]) { - this.__setLifeCycleMethods('getSnapshotBeforeUpdate', args); + this.__excuteLifeCycleMethod('getSnapshotBeforeUpdate', args); this.__debug(`getSnapshotBeforeUpdate - ${this.props?.__schema?.fileName}`); } async componentDidMount(...args: any[]) { this.reloadDataSource(); - this.__setLifeCycleMethods('componentDidMount', args); + this.__excuteLifeCycleMethod('componentDidMount', args); this.__debug(`componentDidMount - ${this.props?.__schema?.fileName}`); } async componentDidUpdate(...args: any[]) { - this.__setLifeCycleMethods('componentDidUpdate', args); + this.__excuteLifeCycleMethod('componentDidUpdate', args); this.__debug(`componentDidUpdate - ${this.props.__schema.fileName}`); } async componentWillUnmount(...args: any[]) { - this.__setLifeCycleMethods('componentWillUnmount', args); + this.__excuteLifeCycleMethod('componentWillUnmount', args); this.__debug(`componentWillUnmount - ${this.props?.__schema?.fileName}`); } async componentDidCatch(...args: any[]) { - this.__setLifeCycleMethods('componentDidCatch', args); + this.__excuteLifeCycleMethod('componentDidCatch', args); console.warn(args); } @@ -194,7 +194,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { } } - __setLifeCycleMethods = (method: string, args?: any) => { + __excuteLifeCycleMethod = (method: string, args?: any) => { const lifeCycleMethods = getValue(this.props.__schema, 'lifeCycles', {}); let fn = lifeCycleMethods[method]; if (fn) { @@ -360,7 +360,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { __render = () => { const schema = this.props.__schema; - this.__setLifeCycleMethods('render'); + this.__excuteLifeCycleMethod('render'); this.__writeCss(); const { engine } = this.context; diff --git a/packages/renderer-core/src/renderer/block.tsx b/packages/renderer-core/src/renderer/block.tsx index 17daccaa35..f87997864b 100644 --- a/packages/renderer-core/src/renderer/block.tsx +++ b/packages/renderer-core/src/renderer/block.tsx @@ -13,7 +13,7 @@ export default function blockRendererFactory(): IBaseRenderComponent { const schema = props.__schema || {}; this.state = this.__parseData(schema.state || {}); this.__initDataSource(props); - this.__setLifeCycleMethods('constructor', [...arguments]); + this.__excuteLifeCycleMethod('constructor', [...arguments]); } render() { diff --git a/packages/renderer-core/src/renderer/component.tsx b/packages/renderer-core/src/renderer/component.tsx index 3b73fd0fd5..85b1fd4d32 100644 --- a/packages/renderer-core/src/renderer/component.tsx +++ b/packages/renderer-core/src/renderer/component.tsx @@ -15,7 +15,7 @@ export default function componentRendererFactory(): IBaseRenderComponent { const schema = props.__schema || {}; this.state = this.__parseData(schema.state || {}); this.__initDataSource(props); - this.__setLifeCycleMethods('constructor', arguments as any); + this.__excuteLifeCycleMethod('constructor', arguments as any); } render() { diff --git a/packages/renderer-core/src/renderer/page.tsx b/packages/renderer-core/src/renderer/page.tsx index 380e0fb36f..41c1a713f8 100644 --- a/packages/renderer-core/src/renderer/page.tsx +++ b/packages/renderer-core/src/renderer/page.tsx @@ -15,7 +15,7 @@ export default function pageRendererFactory(): IBaseRenderComponent { const schema = props.__schema || {}; this.state = this.__parseData(schema.state || {}); this.__initDataSource(props); - this.__setLifeCycleMethods('constructor', [props, ...rest]); + this.__excuteLifeCycleMethod('constructor', [props, ...rest]); } async componentDidUpdate(prevProps: IBaseRendererProps, _prevState: {}, snapshot: unknown) { @@ -40,7 +40,7 @@ export default function pageRendererFactory(): IBaseRenderComponent { this.__bindCustomMethods(this.props); this.__initDataSource(this.props); - // this.__setLifeCycleMethods('constructor', arguments); + // this.__excuteLifeCycleMethod('constructor', arguments); this.__generateCtx({ page: this, diff --git a/packages/renderer-core/src/types/index.ts b/packages/renderer-core/src/types/index.ts index a3e7f0c368..34e69b1643 100644 --- a/packages/renderer-core/src/types/index.ts +++ b/packages/renderer-core/src/types/index.ts @@ -240,7 +240,7 @@ export type IBaseRendererInstance = IGeneralComponent< __beforeInit(props: IBaseRendererProps): void; __init(props: IBaseRendererProps): void; __afterInit(props: IBaseRendererProps): void; - __setLifeCycleMethods(method: string, args?: any[]): void; + __excuteLifeCycleMethod(method: string, args?: any[]): void; __bindCustomMethods(props: IBaseRendererProps): void; __generateCtx(ctx: Record): void; __parseData(data: any, ctx?: any): any; From a0c772fb903cf5eb9e0b811b64bbe3846d4ba8ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Wed, 6 Jul 2022 10:51:38 +0800 Subject: [PATCH 074/823] fix: project event listeners will not be invoked sometimes --- packages/shell/src/project.ts | 29 ++++++++++++++--------------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/packages/shell/src/project.ts b/packages/shell/src/project.ts index 297bc320f0..c6a29c4eb8 100644 --- a/packages/shell/src/project.ts +++ b/packages/shell/src/project.ts @@ -136,41 +136,40 @@ export default class Project { * 当前 project 内的 document 变更事件 */ onChangeDocument(fn: (doc: DocumentModel) => void) { + const offFn = this[projectSymbol].onCurrentDocumentChange((originalDoc) => { + fn(DocumentModel.create(originalDoc)!); + }); if (this[projectSymbol].currentDocument) { fn(DocumentModel.create(this[projectSymbol].currentDocument)!); - return () => {}; } - return this[projectSymbol].onCurrentDocumentChange((originalDoc) => { - fn(DocumentModel.create(originalDoc)!); - }); + return offFn; } /** * 当前 project 的模拟器 ready 事件 */ onSimulatorHostReady(fn: (host: SimulatorHost) => void) { - if (this[simulatorHostSymbol]) { - fn(SimulatorHost.create(this[simulatorHostSymbol])!); - return () => {}; - } - return this[projectSymbol].onSimulatorReady((simulator: BuiltinSimulatorHost) => { + const offFn = this[projectSymbol].onSimulatorReady((simulator: BuiltinSimulatorHost) => { this[simulatorHostSymbol] = simulator; fn(SimulatorHost.create(simulator)!); }); + if (this[simulatorHostSymbol]) { + fn(SimulatorHost.create(this[simulatorHostSymbol])!); + } + return offFn; } /** * 当前 project 的渲染器 ready 事件 */ onSimulatorRendererReady(fn: () => void) { - if (this[simulatorRendererSymbol]) { - fn(); - return () => {}; - } - // TODO: 补充 renderer 实例 - return this[projectSymbol].onRendererReady((renderer: any) => { + const offFn = this[projectSymbol].onRendererReady((renderer: any) => { this[simulatorRendererSymbol] = renderer; fn(); }); + if (this[simulatorRendererSymbol]) { + fn(); + } + return offFn; } } From 30d4ba9d215ce8b7e6238c2bff5e1d8ba1fc752a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Wed, 6 Jul 2022 11:20:17 +0800 Subject: [PATCH 075/823] chore(release): publish 1.0.12 --- lerna.json | 2 +- packages/designer/package.json | 10 +++++----- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 16 ++++++++-------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 10 +++++----- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 12 ++++++------ packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- 16 files changed, 60 insertions(+), 60 deletions(-) diff --git a/lerna.json b/lerna.json index 16a30579bd..40daf983c1 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.0.11", + "version": "1.0.12", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index 5ac7922622..b7e0b3a9c4 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.0.11", + "version": "1.0.12", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,10 +15,10 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.0.11", - "@alilc/lowcode-shell": "1.0.11", - "@alilc/lowcode-types": "1.0.11", - "@alilc/lowcode-utils": "1.0.11", + "@alilc/lowcode-editor-core": "1.0.12", + "@alilc/lowcode-shell": "1.0.12", + "@alilc/lowcode-types": "1.0.12", + "@alilc/lowcode-utils": "1.0.12", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index ab4a9b250a..c178d3c9d8 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.0.11", + "version": "1.0.12", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.0.11", - "@alilc/lowcode-utils": "1.0.11", + "@alilc/lowcode-types": "1.0.12", + "@alilc/lowcode-utils": "1.0.12", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 85a8444ea6..100c5c4014 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.0.11", + "version": "1.0.12", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -18,10 +18,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.0.11", - "@alilc/lowcode-editor-core": "1.0.11", - "@alilc/lowcode-types": "1.0.11", - "@alilc/lowcode-utils": "1.0.11", + "@alilc/lowcode-designer": "1.0.12", + "@alilc/lowcode-editor-core": "1.0.12", + "@alilc/lowcode-types": "1.0.12", + "@alilc/lowcode-utils": "1.0.12", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index 7895ea08ce..78c182a348 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.0.11", + "version": "1.0.12", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,14 +19,14 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.0.11", - "@alilc/lowcode-editor-core": "1.0.11", - "@alilc/lowcode-editor-skeleton": "1.0.11", + "@alilc/lowcode-designer": "1.0.12", + "@alilc/lowcode-editor-core": "1.0.12", + "@alilc/lowcode-editor-skeleton": "1.0.12", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.0.11", - "@alilc/lowcode-plugin-outline-pane": "1.0.11", - "@alilc/lowcode-shell": "1.0.11", - "@alilc/lowcode-utils": "1.0.11", + "@alilc/lowcode-plugin-designer": "1.0.12", + "@alilc/lowcode-plugin-outline-pane": "1.0.12", + "@alilc/lowcode-shell": "1.0.12", + "@alilc/lowcode-utils": "1.0.12", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index 9dbb6e1ccb..2e76e0344c 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.0.11", + "version": "1.0.12", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 5fd0c1c734..3916c79e71 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.0.11", + "version": "1.0.12", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.0.11", - "@alilc/lowcode-editor-core": "1.0.11", - "@alilc/lowcode-utils": "1.0.11", + "@alilc/lowcode-designer": "1.0.12", + "@alilc/lowcode-editor-core": "1.0.12", + "@alilc/lowcode-utils": "1.0.12", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index c6e16d5fff..aeaedcd72b 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.0.11", + "version": "1.0.12", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,10 +13,10 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-designer": "1.0.11", - "@alilc/lowcode-editor-core": "1.0.11", - "@alilc/lowcode-types": "1.0.11", - "@alilc/lowcode-utils": "1.0.11", + "@alilc/lowcode-designer": "1.0.12", + "@alilc/lowcode-editor-core": "1.0.12", + "@alilc/lowcode-types": "1.0.12", + "@alilc/lowcode-utils": "1.0.12", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0" diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index 3c8e5b1cec..3af6773b42 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.0.11", + "version": "1.0.12", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.0.11", - "@alilc/lowcode-utils": "1.0.11", + "@alilc/lowcode-renderer-core": "1.0.12", + "@alilc/lowcode-utils": "1.0.12", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index be83eb72ba..9b9a3a5887 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.0.11", + "version": "1.0.12", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.0.11", - "@alilc/lowcode-rax-renderer": "1.0.11", - "@alilc/lowcode-types": "1.0.11", - "@alilc/lowcode-utils": "1.0.11", + "@alilc/lowcode-designer": "1.0.12", + "@alilc/lowcode-rax-renderer": "1.0.12", + "@alilc/lowcode-types": "1.0.12", + "@alilc/lowcode-utils": "1.0.12", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 2a344f9602..5e31f9f2e5 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.0.11", + "version": "1.0.12", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.0.11" + "@alilc/lowcode-renderer-core": "1.0.12" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index 715eaee75b..c3e7238fd2 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.0.11", + "version": "1.0.12", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -16,10 +16,10 @@ "build:umd": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.0.11", - "@alilc/lowcode-react-renderer": "1.0.11", - "@alilc/lowcode-types": "1.0.11", - "@alilc/lowcode-utils": "1.0.11", + "@alilc/lowcode-designer": "1.0.12", + "@alilc/lowcode-react-renderer": "1.0.12", + "@alilc/lowcode-types": "1.0.12", + "@alilc/lowcode-utils": "1.0.12", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 6cfa1d924d..a660b09d23 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.0.11", + "version": "1.0.12", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.0.11", - "@alilc/lowcode-utils": "1.0.11", + "@alilc/lowcode-types": "1.0.12", + "@alilc/lowcode-utils": "1.0.12", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -33,7 +33,7 @@ }, "devDependencies": { "@alib/build-scripts": "^0.1.18", - "@alilc/lowcode-designer": "1.0.11", + "@alilc/lowcode-designer": "1.0.12", "@alilc/lowcode-test-mate": "^1.0.1", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", diff --git a/packages/shell/package.json b/packages/shell/package.json index bc1dba890d..e783415009 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.0.11", + "version": "1.0.12", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.0.11", - "@alilc/lowcode-editor-core": "1.0.11", - "@alilc/lowcode-editor-skeleton": "1.0.11", - "@alilc/lowcode-types": "1.0.11", - "@alilc/lowcode-utils": "1.0.11", + "@alilc/lowcode-designer": "1.0.12", + "@alilc/lowcode-editor-core": "1.0.12", + "@alilc/lowcode-editor-skeleton": "1.0.12", + "@alilc/lowcode-types": "1.0.12", + "@alilc/lowcode-utils": "1.0.12", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index 2d3dfc6566..34f41a6a22 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.0.11", + "version": "1.0.12", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index 0db08d7d04..c7bad384c8 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.0.11", + "version": "1.0.12", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.0.11", + "@alilc/lowcode-types": "1.0.12", "lodash": "^4.17.21", "react": "^16", "zen-logger": "^1.1.0" From 81a73049bd848524e1156761ded08ddf325863ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Wed, 6 Jul 2022 11:24:51 +0800 Subject: [PATCH 076/823] fix: adjust synchronize-order of packages --- scripts/sync.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/sync.sh b/scripts/sync.sh index 71ab5f5a1a..39a1f6e26a 100755 --- a/scripts/sync.sh +++ b/scripts/sync.sh @@ -9,9 +9,9 @@ tnpm sync @alilc/lowcode-editor-skeleton tnpm sync @alilc/lowcode-designer tnpm sync @alilc/lowcode-plugin-designer tnpm sync @alilc/lowcode-plugin-outline-pane +tnpm sync @alilc/lowcode-renderer-core tnpm sync @alilc/lowcode-rax-renderer tnpm sync @alilc/lowcode-rax-simulator-renderer tnpm sync @alilc/lowcode-react-renderer tnpm sync @alilc/lowcode-react-simulator-renderer -tnpm sync @alilc/lowcode-renderer-core tnpm sync @alilc/lowcode-engine \ No newline at end of file From 035bde453c763e656e5555d97c0b29c8949aa71b Mon Sep 17 00:00:00 2001 From: JackLian Date: Thu, 7 Jul 2022 15:29:10 +0800 Subject: [PATCH 077/823] refactor: remove useless logic, and some minor refactors --- packages/renderer-core/src/renderer/base.tsx | 64 ++++++++++---------- 1 file changed, 32 insertions(+), 32 deletions(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 32bc0c5a82..29dbded3c6 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -77,7 +77,6 @@ export default function baseRendererFactory(): IBaseRenderComponent { __compScopes: Record = {}; __instanceMap: Record = {}; __dataHelper: any; - __showPlaceholder: boolean = false; __customMethodsList: any[] = []; dataSourceMap: Record = {}; __ref: any; @@ -106,7 +105,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { this.__compScopes = {}; this.__instanceMap = {}; this.__bindCustomMethods(props); - this.__initI18nAPIs(); + this.__initI18nAPIs(props); } // eslint-disable-next-line @typescript-eslint/no-unused-vars @@ -159,12 +158,10 @@ export default function baseRendererFactory(): IBaseRenderComponent { reloadDataSource = () => new Promise((resolve, reject) => { this.__debug('reload data source'); if (!this.__dataHelper) { - this.__showPlaceholder = false; return resolve({}); } this.__dataHelper.getInitData() .then((res: any) => { - this.__showPlaceholder = false; if (isEmpty(res)) { this.forceUpdate(); return resolve({}); @@ -172,10 +169,6 @@ export default function baseRendererFactory(): IBaseRenderComponent { this.setState(res, resolve as () => void); }) .catch((err: Error) => { - if (this.__showPlaceholder) { - this.__showPlaceholder = false; - this.forceUpdate(); - } reject(err); }); }); @@ -193,12 +186,15 @@ export default function baseRendererFactory(): IBaseRenderComponent { super.forceUpdate(); } } - + /** + * execute method in schema.lifeCycles + * @PRIVATE + */ __excuteLifeCycleMethod = (method: string, args?: any) => { const lifeCycleMethods = getValue(this.props.__schema, 'lifeCycles', {}); let fn = lifeCycleMethods[method]; if (fn) { - // TODO, cache + // TODO: cache if (isJSExpression(fn) || isJSFunction(fn)) { fn = this.parseExpression(fn, this); } @@ -214,6 +210,10 @@ export default function baseRendererFactory(): IBaseRenderComponent { } }; + /** + * this method is for legacy purpose only, which used _ prefix instead of __ as private for some historical reasons + * @LEGACY + */ _getComponentView = (componentName: string) => { const { __components } = this.props; if (!__components) { @@ -262,14 +262,18 @@ export default function baseRendererFactory(): IBaseRenderComponent { return parseData(data, ctx || __ctx || this, { thisRequiredInJSE }); }; - __initDataSource = (props = this.props) => { + __initDataSource = (props: IBaseRendererProps) => { + if (!props) { + return; + } const schema = props.__schema || {}; const defaultDataSource: DataSource = { list: [], }; - const dataSource = (schema && schema?.dataSource) || defaultDataSource; + const dataSource = schema.dataSource || defaultDataSource; // requestHandlersMap 存在才走数据源引擎方案 - if (props?.__appHelper?.requestHandlersMap) { + const useDataSourceEngine = !!(props.__appHelper?.requestHandlersMap); + if (useDataSourceEngine) { this.__dataHelper = { updateConfig: (updateDataSource: any) => { const { dataSourceMap, reloadDataSource } = createDataSourceEngine( @@ -280,11 +284,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { this.reloadDataSource = () => new Promise((resolve) => { this.__debug('reload data source'); - // this.__showPlaceholder = true; reloadDataSource().then(() => { - // this.__showPlaceholder = false; - // @TODO 是否需要 forceUpate - // this.forceUpdate(); resolve({}); }); }); @@ -299,12 +299,10 @@ export default function baseRendererFactory(): IBaseRenderComponent { this.reloadDataSource = () => new Promise((resolve, reject) => { this.__debug('reload data source'); if (!this.__dataHelper) { - // this.__showPlaceholder = false; return resolve({}); } this.__dataHelper.getInitData() .then((res: any) => { - // this.__showPlaceholder = false; if (isEmpty(res)) { this.forceUpdate(); return resolve({}); @@ -312,28 +310,30 @@ export default function baseRendererFactory(): IBaseRenderComponent { this.setState(res, resolve as () => void); }) .catch((err: Error) => { - if (this.__showPlaceholder) { - this.__showPlaceholder = false; - this.forceUpdate(); - } reject(err); }); }); } - // 设置容器组件占位,若设置占位则在初始异步请求完成之前用loading占位且不渲染容器组件内部内容 - // @TODO __showPlaceholder 的逻辑一旦开启就关不掉,先注释掉了 - /* this.__showPlaceholder = this.__parseData(schema.props && schema.props.autoLoading) && (dataSource.list || []).some( - (item) => !!this.__parseData(item.isInit), - ); */ }; - __initI18nAPIs = () => { + /** + * init i18n apis + * @PRIVATE + */ + __initI18nAPIs = (props: IBaseRendererProps) => { this.i18n = (key: string, values = {}) => { - const { locale, messages } = this.props; + const { locale, messages } = props; return getI18n(key, values, locale, messages); }; - this.getLocale = () => this.props.locale; - this.setLocale = (loc: string) => this.appHelper?.utils?.i18n?.setLocale && this.appHelper?.utils?.i18n?.setLocale(loc); + this.getLocale = () => props.locale; + this.setLocale = (loc: string) => { + const setLocaleFn = this.appHelper?.utils?.i18n?.setLocale; + if (!setLocaleFn || typeof setLocaleFn !== 'function') { + console.warn('initI18nAPIs Failed, i18n only works when appHelper.utils.i18n.setLocale() exists'); + return undefined; + } + return setLocaleFn(loc); + }; }; __writeCss = () => { From b4b30a359932f5c0e8fde1b28f54a883c87901d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Thu, 7 Jul 2022 16:11:29 +0800 Subject: [PATCH 078/823] fix: simulator eclipses setting area #773 --- packages/designer/src/builtin-simulator/host.less | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/designer/src/builtin-simulator/host.less b/packages/designer/src/builtin-simulator/host.less index 669a40f6da..5e230c4007 100644 --- a/packages/designer/src/builtin-simulator/host.less +++ b/packages/designer/src/builtin-simulator/host.less @@ -4,6 +4,7 @@ position: relative; height: 100%; width: 100%; + overflow: auto; &-canvas { position: absolute; From a176e9d245981fb5718c8d144f477202b3796be6 Mon Sep 17 00:00:00 2001 From: william Date: Wed, 15 Jun 2022 15:59:55 +0800 Subject: [PATCH 079/823] fix: npm run clean error in windows MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 不管在powershell或者cmd里面 rm -rf 都会报错。使用这个第三方包 rimraf, 本地测试成功。 --- package.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 38299c96e2..27e9fbef8a 100644 --- a/package.json +++ b/package.json @@ -14,7 +14,8 @@ "build": "./scripts/build.sh", "build:npm": "lerna run build --stream", "build:umd": "lerna run build:umd --stream", - "clean": "rm -rf ./packages/*/lib ./packages/*/es ./packages/*/dist ./packages/*/build", + "clean": "rimraf ./packages/*/lib ./packages/*/es ./packages/*/dist ./packages/*/build", + "clean:lib": "rimraf ./node_modules", "lint": "f2elint scan -q -i ./packages/*/src", "lint:fix": "f2elint fix -i ./packages/*/src", "lint:modules": "f2elint scan -q -i ./modules/*/src", @@ -46,7 +47,8 @@ "husky": "^7.0.4", "lerna": "^4.0.0", "typescript": "^4.5.5", - "yarn": "^1.22.17" + "yarn": "^1.22.17", + "rimraf": "^3.0.2" }, "engines": { "node": ">=14.17.0 <16" From 9be46e7b34e3a40cbc489dbae4bfd0915c2090e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Thu, 7 Jul 2022 20:22:28 +0800 Subject: [PATCH 080/823] fix: error thrown when triggering undo after save schema on SchemaPane --- packages/designer/src/document/node/modal-nodes-manager.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/designer/src/document/node/modal-nodes-manager.ts b/packages/designer/src/document/node/modal-nodes-manager.ts index 819ac53349..6288b35478 100644 --- a/packages/designer/src/document/node/modal-nodes-manager.ts +++ b/packages/designer/src/document/node/modal-nodes-manager.ts @@ -3,6 +3,7 @@ import { Node } from './node'; import { DocumentModel } from '../document-model'; function getModalNodes(node: Node) { + if (!node) return []; let nodes: any = []; if (node.componentMeta.isModal) { nodes.push(node); From a8de3f299c7b26fa939d2b2ea1428143e2b5fb01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Thu, 7 Jul 2022 19:56:51 +0800 Subject: [PATCH 081/823] fix: should pass index param when creating a Prop instance under a list type Prop instance, fix #780 --- .../designer/src/document/node/props/prop.ts | 6 +-- .../designer/src/document/node/props/props.ts | 48 ++++++++++++------- 2 files changed, 33 insertions(+), 21 deletions(-) diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index 1809852c4e..6533b4607c 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -399,10 +399,10 @@ export class Prop implements IPropParent { let items: Prop[] | null = null; if (this._type === 'list') { const data = this._value; - for (const item of data) { + data.forEach((item: any, idx: number) => { items = items || []; - items.push(new Prop(this, item)); - } + items.push(new Prop(this, item, idx)); + }); this._maps = null; } else if (this._type === 'map') { const data = this._value; diff --git a/packages/designer/src/document/node/props/props.ts b/packages/designer/src/document/node/props/props.ts index 8c03c1e250..1ec6df9703 100644 --- a/packages/designer/src/document/node/props/props.ts +++ b/packages/designer/src/document/node/props/props.ts @@ -31,7 +31,7 @@ export class Props implements IPropParent { @computed private get maps(): Map { const maps = new Map(); if (this.items.length > 0) { - this.items.forEach(prop => { + this.items.forEach((prop) => { if (prop.key) { maps.set(prop.key, prop); } @@ -62,12 +62,14 @@ export class Props implements IPropParent { this.owner = owner; if (Array.isArray(value)) { this.type = 'list'; - this.items = value.map(item => new Prop(this, item.value, item.name, item.spread)); + this.items = value.map( + (item, idx) => new Prop(this, item.value, item.name || idx, item.spread), + ); } else if (value != null) { - this.items = Object.keys(value).map(key => new Prop(this, value[key], key, false)); + this.items = Object.keys(value).map((key) => new Prop(this, value[key], key, false)); } if (extras) { - Object.keys(extras).forEach(key => { + Object.keys(extras).forEach((key) => { this.items.push(new Prop(this, (extras as any)[key], getConvertedExtraKey(key))); }); } @@ -78,37 +80,42 @@ export class Props implements IPropParent { const originItems = this.items; if (Array.isArray(value)) { this.type = 'list'; - this.items = value.map(item => new Prop(this, item.value, item.name, item.spread)); + this.items = value.map( + (item, idx) => new Prop(this, item.value, item.name || idx, item.spread), + ); } else if (value != null) { this.type = 'map'; - this.items = Object.keys(value).map(key => new Prop(this, value[key], key)); + this.items = Object.keys(value).map((key) => new Prop(this, value[key], key)); } else { this.type = 'map'; this.items = []; } if (extras) { - Object.keys(extras).forEach(key => { + Object.keys(extras).forEach((key) => { this.items.push(new Prop(this, (extras as any)[key], getConvertedExtraKey(key))); }); } - originItems.forEach(item => item.purge()); + originItems.forEach((item) => item.purge()); } @action merge(value: PropsMap, extras?: PropsMap) { - Object.keys(value).forEach(key => { + Object.keys(value).forEach((key) => { this.query(key, true)!.setValue(value[key]); this.query(key, true)!.setupItems(); }); if (extras) { - Object.keys(extras).forEach(key => { + Object.keys(extras).forEach((key) => { this.query(getConvertedExtraKey(key), true)!.setValue(extras[key]); this.query(getConvertedExtraKey(key), true)!.setupItems(); }); } } - export(stage: TransformStage = TransformStage.Save): { props?: PropsMap | PropsList; extras?: ExtrasObject } { + export(stage: TransformStage = TransformStage.Save): { + props?: PropsMap | PropsList; + extras?: ExtrasObject; + } { stage = compatStage(stage); if (this.items.length < 1) { return {}; @@ -118,7 +125,7 @@ export class Props implements IPropParent { const extras: any = {}; if (this.type === 'list') { props = []; - this.items.forEach(item => { + this.items.forEach((item) => { let value = item.export(stage); let name = item.key as string; if (name && typeof name === 'string' && name.startsWith(EXTRA_KEY_PREFIX)) { @@ -133,7 +140,7 @@ export class Props implements IPropParent { } }); } else { - this.items.forEach(item => { + this.items.forEach((item) => { let name = item.key as string; if (name == null || item.isUnset() || item.isVirtual()) return; let value = item.export(stage); @@ -248,7 +255,12 @@ export class Props implements IPropParent { * 添加值 */ @action - add(value: CompositeValue | null, key?: string | number, spread = false, options: any = {}): Prop { + add( + value: CompositeValue | null, + key?: string | number, + spread = false, + options: any = {}, + ): Prop { const prop = new Prop(this, value, key, spread, options); this.items.push(prop); return prop; @@ -289,7 +301,7 @@ export class Props implements IPropParent { */ @action forEach(fn: (item: Prop, key: number | string | undefined) => void): void { - this.items.forEach(item => { + this.items.forEach((item) => { return fn(item, item.key); }); } @@ -299,14 +311,14 @@ export class Props implements IPropParent { */ @action map(fn: (item: Prop, key: number | string | undefined) => T): T[] | null { - return this.items.map(item => { + return this.items.map((item) => { return fn(item, item.key); }); } @action filter(fn: (item: Prop, key: number | string | undefined) => boolean) { - return this.items.filter(item => { + return this.items.filter((item) => { return fn(item, item.key); }); } @@ -322,7 +334,7 @@ export class Props implements IPropParent { return; } this.purged = true; - this.items.forEach(item => item.purge()); + this.items.forEach((item) => item.purge()); } /** From 33c7948a65db6412533beb4cf62c5186cb5699c0 Mon Sep 17 00:00:00 2001 From: liujuping Date: Fri, 8 Jul 2022 10:32:36 +0800 Subject: [PATCH 082/823] chore: added exempt-all-assignee configuration to deal with the problem of mistakenly turned off --- .github/workflows/stale.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 2cb0ccaf8b..6fa710ec4d 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -19,4 +19,5 @@ jobs: days-before-pr-close: 10 exempt-issue-labels: 'bug,enhancement,good first issue,help wanted,WIP,discussion,documentation,later,material' stale-issue-label: 'stale' - stale-pr-label: 'stale' \ No newline at end of file + stale-pr-label: 'stale' + exempt-all-assignee: true \ No newline at end of file From 969a130b373fb028f8051e96cb9d79f1de0a2a1c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Mon, 11 Jul 2022 10:51:31 +0800 Subject: [PATCH 083/823] fix: project.exportSchema should export componentsMap of all documents --- .../designer/src/document/document-model.ts | 14 +-- packages/designer/src/project/project.ts | 108 ++++++++++++------ packages/types/src/npm.ts | 24 +++- 3 files changed, 101 insertions(+), 45 deletions(-) diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index e92b5aae72..410d197189 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -1,5 +1,5 @@ import { computed, makeObservable, obx, action, runWithGlobalEventOff, wrapWithEventSwitch } from '@alilc/lowcode-editor-core'; -import { NodeData, isJSExpression, isDOMText, NodeSchema, isNodeSchema, RootSchema, PageSchema } from '@alilc/lowcode-types'; +import { NodeData, isJSExpression, isDOMText, NodeSchema, isNodeSchema, RootSchema, PageSchema, ComponentsMap } from '@alilc/lowcode-types'; import { EventEmitter } from 'events'; import { Project } from '../project'; import { ISimulatorHost } from '../simulator'; @@ -19,16 +19,6 @@ export type GetDataType = T extends undefined : any : T; -export interface ComponentMap { - componentName: string; - package?: string; - version?: string; - destructuring?: boolean; - exportName?: string; - subName?: string; - devMode?: 'lowCode' | 'proCode'; -} - export class DocumentModel { /** * 根节点 类型有:Page/Component/Block @@ -652,7 +642,7 @@ export class DocumentModel { } getComponentsMap(extraComps?: string[]) { - const componentsMap: ComponentMap[] = []; + const componentsMap: ComponentsMap = []; // 组件去重 const exsitingMap: { [componentName: string]: boolean } = {}; for (const node of this._nodesMap.values()) { diff --git a/packages/designer/src/project/project.ts b/packages/designer/src/project/project.ts index 3e17c1c9df..726b0706f8 100644 --- a/packages/designer/src/project/project.ts +++ b/packages/designer/src/project/project.ts @@ -2,7 +2,14 @@ import { EventEmitter } from 'events'; import { obx, computed, makeObservable, action } from '@alilc/lowcode-editor-core'; import { Designer } from '../designer'; import { DocumentModel, isDocumentModel, isPageSchema } from '../document'; -import { ProjectSchema, RootSchema, TransformStage } from '@alilc/lowcode-types'; +import { + ProjectSchema, + RootSchema, + ComponentsMap, + TransformStage, + isLowCodeComponentType, + isProCodeComponentType, +} from '@alilc/lowcode-types'; import { ISimulatorHost } from '../simulator'; export class Project { @@ -10,7 +17,12 @@ export class Project { @obx.shallow readonly documents: DocumentModel[] = []; - private data: ProjectSchema = { version: '1.0.0', componentsMap: [], componentsTree: [], i18n: {} }; + private data: ProjectSchema = { + version: '1.0.0', + componentsMap: [], + componentsTree: [], + i18n: {}, + }; private _simulator?: ISimulatorHost; @@ -49,15 +61,45 @@ export class Project { this._i18n = value || {}; } + private getComponentsMap(): ComponentsMap { + return this.documents.reduce((compomentsMap: ComponentsMap, curDoc: DocumentModel) => { + const curComponentsMap = curDoc.getComponentsMap(); + if (Array.isArray(curComponentsMap)) { + curComponentsMap.forEach((item) => { + const found = compomentsMap.find((eItem) => { + if ( + isProCodeComponentType(eItem) && + isProCodeComponentType(item) && + eItem.package === item.package && + eItem.componentName === item.componentName + ) { + return true; + } else if ( + isLowCodeComponentType(eItem) && + eItem.componentName === item.componentName + ) { + return true; + } + return false; + }); + if (found) return; + compomentsMap.push(item); + }); + } + return compomentsMap; + }, [] as ComponentsMap); + } + /** * 获取项目整体 schema */ getSchema(stage: TransformStage = TransformStage.Save): ProjectSchema { return { ...this.data, - // TODO: future change this filter - componentsMap: this.currentDocument?.getComponentsMap(), - componentsTree: this.documents.filter((doc) => !doc.isBlank()).map((doc) => doc.export(stage)), + componentsMap: this.getComponentsMap(), + componentsTree: this.documents + .filter((doc) => !doc.isBlank()) + .map((doc) => doc.export(stage)), i18n: this.i18n, }; } @@ -100,7 +142,9 @@ export class Project { // TODO: 暂时先读 config tabBar 里的值,后面看整个 layout 结构是否能作为引擎规范 if (this.config?.layout?.props?.tabBar?.items?.length > 0) { // slice(1)这个贼不雅,默认任务fileName 是类'/fileName'的形式 - documentInstances.find((i) => i.fileName === this.config.layout.props.tabBar.items[0].path?.slice(1))?.open(); + documentInstances + .find((i) => i.fileName === this.config.layout.props.tabBar.items[0].path?.slice(1)) + ?.open(); } else { documentInstances[0].open(); } @@ -138,15 +182,15 @@ export class Project { set( // eslint-disable-next-line @typescript-eslint/no-unused-vars key: - | 'version' - | 'componentsTree' - | 'componentsMap' - | 'utils' - | 'constants' - | 'i18n' - | 'css' - | 'dataSource' - | string, + | 'version' + | 'componentsTree' + | 'componentsMap' + | 'utils' + | 'constants' + | 'i18n' + | 'css' + | 'dataSource' + | string, // eslint-disable-next-line @typescript-eslint/no-unused-vars value: any, ): void { @@ -165,16 +209,16 @@ export class Project { get( // eslint-disable-next-line @typescript-eslint/no-unused-vars key: - | 'version' - | 'componentsTree' - | 'componentsMap' - | 'utils' - | 'constants' - | 'i18n' - | 'css' - | 'dataSource' - | 'config' - | string, + | 'version' + | 'componentsTree' + | 'componentsMap' + | 'utils' + | 'constants' + | 'i18n' + | 'css' + | 'dataSource' + | 'config' + | string, ): any { if (key === 'config') { return this.config; @@ -189,11 +233,11 @@ export class Project { getDocument(id: string): DocumentModel | null { // 此处不能使用 this.documentsMap.get(id),因为在乐高 rollback 场景,document.id 会被改成其他值 - return this.documents.find(doc => doc.id === id) || null; + return this.documents.find((doc) => doc.id === id) || null; } getDocumentByFileName(fileName: string): DocumentModel | null { - return this.documents.find(doc => doc.fileName === fileName) || null; + return this.documents.find((doc) => doc.fileName === fileName) || null; } @action @@ -230,11 +274,11 @@ export class Project { return doc.open(); } // else if (isPageSchema(doc)) { - // 暂时注释掉,影响了 diff 功能 - // const foundDoc = this.documents.find(curDoc => curDoc?.rootNode?.id && curDoc?.rootNode?.id === doc?.id); - // if (foundDoc) { - // foundDoc.remove(); - // } + // 暂时注释掉,影响了 diff 功能 + // const foundDoc = this.documents.find(curDoc => curDoc?.rootNode?.id && curDoc?.rootNode?.id === doc?.id); + // if (foundDoc) { + // foundDoc.remove(); + // } // } doc = this.createDocument(doc); diff --git a/packages/types/src/npm.ts b/packages/types/src/npm.ts index 837dc18d08..88449f435c 100644 --- a/packages/types/src/npm.ts +++ b/packages/types/src/npm.ts @@ -32,4 +32,26 @@ export interface NpmInfo { main?: string; } -export type ComponentsMap = NpmInfo[]; +export interface LowCodeComponentType { + /** + * 研发模式 + */ + devMode: 'lowCode'; + /** + * 组件名称 + */ + componentName: string; +} + +export type ProCodeComponentType = NpmInfo; +export type ComponentMap = ProCodeComponentType | LowCodeComponentType; + +export function isProCodeComponentType(desc: ComponentMap): desc is ProCodeComponentType { + return 'package' in desc; +} + +export function isLowCodeComponentType(desc: ComponentMap): desc is LowCodeComponentType { + return !isProCodeComponentType(desc); +} + +export type ComponentsMap = ComponentMap[]; From 37654cd04050fb37ee4b6afde606bd55a9de7beb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Fri, 8 Jul 2022 19:13:26 +0800 Subject: [PATCH 084/823] test(builtin-hotkey): increase designer's code branch coverage to 84.18% --- .../designer/src/designer/builtin-hotkey.ts | 9 +- .../tests/designer/builtin-hotkey.test.ts | 95 ++++++++++++++++--- .../designer/tests/designer/location.test.ts | 15 ++- 3 files changed, 104 insertions(+), 15 deletions(-) diff --git a/packages/designer/src/designer/builtin-hotkey.ts b/packages/designer/src/designer/builtin-hotkey.ts index 2bde4f712d..7a226f4f11 100644 --- a/packages/designer/src/designer/builtin-hotkey.ts +++ b/packages/designer/src/designer/builtin-hotkey.ts @@ -4,7 +4,7 @@ import { focusing } from './focusing'; import { insertChildren, TransformStage } from '../document'; import clipboard from './clipboard'; -function isInLiveEditing() { +export function isInLiveEditing() { if (globalContext.has(Editor)) { return Boolean( globalContext.get(Editor).get('designer')?.project?.simulator?.liveEditing?.editing, @@ -12,6 +12,7 @@ function isInLiveEditing() { } } +/* istanbul ignore next */ function getNextForSelect(next: any, head?: any, parent?: any): any { if (next) { if (!head) { @@ -42,6 +43,7 @@ function getNextForSelect(next: any, head?: any, parent?: any): any { return null; } +/* istanbul ignore next */ function getPrevForSelect(prev: any, head?: any, parent?: any): any { if (prev) { let ret; @@ -150,6 +152,7 @@ hotkey.bind(['command+v', 'ctrl+v'], (e) => { if (isFormEvent(e) || !designer || !doc) { return; } + /* istanbul ignore next */ clipboard.waitPasteData(e, ({ componentsTree }) => { if (componentsTree) { const { target, index } = designer.getSuitableInsertion(componentsTree) || {}; @@ -179,7 +182,7 @@ hotkey.bind(['command+z', 'ctrl+z'], (e) => { e.preventDefault(); const selection = focusing.focusDesigner?.currentSelection; - const curSelected = Array.from(selection?.selected || []); + const curSelected = Array.from(selection?.selected); his.back(); selection?.selectAll(curSelected); }); @@ -193,7 +196,7 @@ hotkey.bind(['command+y', 'ctrl+y', 'command+shift+z'], (e) => { } e.preventDefault(); const selection = focusing.focusDesigner?.currentSelection; - const curSelected = Array.from(selection?.selected || []); + const curSelected = Array.from(selection?.selected); his.forward(); selection?.selectAll(curSelected); }); diff --git a/packages/designer/tests/designer/builtin-hotkey.test.ts b/packages/designer/tests/designer/builtin-hotkey.test.ts index dafeeb612b..d0fa8a47f8 100644 --- a/packages/designer/tests/designer/builtin-hotkey.test.ts +++ b/packages/designer/tests/designer/builtin-hotkey.test.ts @@ -4,25 +4,33 @@ import { Designer } from '../../src/designer/designer'; import formSchema from '../fixtures/schema/form'; import '../../src/designer/builtin-hotkey'; import { fireEvent } from '@testing-library/react'; +import { isInLiveEditing } from '../../src/designer/builtin-hotkey'; const editor = new Editor(); let designer: Designer; -beforeAll(() => { - globalContext.register(editor, Editor); -}); -beforeEach(() => { - designer = new Designer({ editor }); - editor.set('designer', designer); - designer.project.open(formSchema); -}); -afterEach(() => { - designer = null; + +describe('error scenarios', () => { + it('edtior not registered', () => { + expect(isInLiveEditing()).toBeUndefined(); + }); }); // keyCode 对应表:https://developer.mozilla.org/en-US/docs/Web/API/KeyboardEvent/keyCode // hotkey 模块底层用的 keyCode,所以还不能用 key / code 测试 describe('快捷键测试', () => { + beforeAll(() => { + globalContext.register(editor, Editor); + }); + beforeEach(() => { + designer = new Designer({ editor }); + editor.set('designer', designer); + designer.project.open(formSchema); + }); + afterEach(() => { + designer = null; + }); + it('right', () => { const firstCardNode = designer.currentDocument?.getNode('node_k1ow3cbj')!; firstCardNode.select(); @@ -242,8 +250,10 @@ describe('快捷键测试', () => { fireEvent.keyDown(document, { keyCode: 46 }); expect(designer.currentDocument?.selection.selected[0]).toBe('page'); }); + it('isFormEvent: true', () => { const inputDOMNode = document.createElement('INPUT'); + document.body.appendChild(inputDOMNode); designer.currentDocument?.selection.select('page'); // nothing happened @@ -289,5 +299,68 @@ describe('快捷键测试', () => { fireEvent.keyDown(inputDOMNode, { keyCode: 46 }); expect(designer.currentDocument?.selection.selected[0]).toBe('page'); }); + + it('doc is null', () => { + designer.currentDocument?.selection.select('page'); + designer.project.documents = []; + + fireEvent.keyDown(document, { keyCode: 39 }); + + fireEvent.keyDown(document, { keyCode: 37 }); + + fireEvent.keyDown(document, { keyCode: 40 }); + + fireEvent.keyDown(document, { keyCode: 38 }); + + fireEvent.keyDown(document, { keyCode: 39, altKey: true }); + + fireEvent.keyDown(document, { keyCode: 37, altKey: true }); + + fireEvent.keyDown(document, { keyCode: 40, altKey: true }); + + fireEvent.keyDown(document, { keyCode: 38, altKey: true }); + + fireEvent.keyDown(document, { keyCode: 90, metaKey: true }); + + fireEvent.keyDown(document, { keyCode: 89, metaKey: true }); + + fireEvent.keyDown(document, { keyCode: 67, metaKey: true }); + + fireEvent.keyDown(document, { keyCode: 86, metaKey: true }); + + fireEvent.keyDown(document, { keyCode: 27 }); + + fireEvent.keyDown(document, { keyCode: 46 }); + }); + + it('selected is []', () => { + fireEvent.keyDown(document, { keyCode: 39 }); + + fireEvent.keyDown(document, { keyCode: 37 }); + + fireEvent.keyDown(document, { keyCode: 40 }); + + fireEvent.keyDown(document, { keyCode: 38 }); + + fireEvent.keyDown(document, { keyCode: 39, altKey: true }); + + fireEvent.keyDown(document, { keyCode: 37, altKey: true }); + + fireEvent.keyDown(document, { keyCode: 40, altKey: true }); + + fireEvent.keyDown(document, { keyCode: 38, altKey: true }); + + fireEvent.keyDown(document, { keyCode: 90, metaKey: true }); + + fireEvent.keyDown(document, { keyCode: 89, metaKey: true }); + + fireEvent.keyDown(document, { keyCode: 67, metaKey: true }); + + fireEvent.keyDown(document, { keyCode: 86, metaKey: true }); + + fireEvent.keyDown(document, { keyCode: 27 }); + + fireEvent.keyDown(document, { keyCode: 46 }); + }); }); -}); +}); \ No newline at end of file diff --git a/packages/designer/tests/designer/location.test.ts b/packages/designer/tests/designer/location.test.ts index 746d101875..205fc24b0e 100644 --- a/packages/designer/tests/designer/location.test.ts +++ b/packages/designer/tests/designer/location.test.ts @@ -128,7 +128,7 @@ it('isRowContainer', () => { .fn(() => { return { getPropertyValue: (pName) => { - return pName === 'display' ? 'flex' : 'row'; + return pName === 'display' ? 'flex' : ''; }, }; }) @@ -138,9 +138,17 @@ it('isRowContainer', () => { return pName === 'display' ? 'flex' : 'column'; }, }; + }) + .mockImplementationOnce(() => { + return { + getPropertyValue: (pName) => { + return pName === 'display' ? 'grid' : 'column'; + }, + }; }); expect(isRowContainer(getMockElement('div'))).toBeFalsy(); expect(isRowContainer(getMockElement('div'))).toBeTruthy(); + expect(isRowContainer(getMockElement('div'))).toBeTruthy(); }); it('isChildInline', () => { @@ -179,6 +187,10 @@ it('isVerticalContainer', () => { it('isVertical', () => { expect(isVertical({ elements: [] })).toBeFalsy(); expect(isVertical({ elements: [getMockElement('div')] })).toBeFalsy(); + const e1 = getMockElement('div'); + const e2 = getMockElement('div'); + e2.appendChild(e1); + expect(isVertical({ elements: [e1] })).toBeTruthy(); window.getComputedStyle = jest .fn(() => { return { @@ -193,4 +205,5 @@ it('isVertical', () => { it('getWindow', () => { const mockElem = getMockElement('div'); expect(getWindow(mockElem)).toBe(window); + expect(getWindow(document)).toBe(window); }); From 1135a30780ca5767c25c53a82f8528d562c26e50 Mon Sep 17 00:00:00 2001 From: JackLian Date: Mon, 11 Jul 2022 12:03:40 +0800 Subject: [PATCH 085/823] refactor: minor refactors for render-core/renderer/base --- packages/renderer-core/src/renderer/base.tsx | 127 ++++++++++++------- packages/renderer-core/src/types/index.ts | 2 +- packages/renderer-core/src/utils/logger.ts | 1 + 3 files changed, 84 insertions(+), 46 deletions(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 29dbded3c6..dde715c03f 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -72,7 +72,6 @@ export default function baseRendererFactory(): IBaseRenderComponent { __namespace = 'base'; - _self: any = null; appHelper?: IRendererAppHelper; __compScopes: Record = {}; __instanceMap: Record = {}; @@ -83,6 +82,12 @@ export default function baseRendererFactory(): IBaseRenderComponent { i18n: any; getLocale: any; setLocale: any; + + /** + * reference of style element contains schema.css + * + * @type {any} + */ styleElement: any; parseExpression: any; [key: string]: any; @@ -222,7 +227,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { return __components[componentName]; }; - __bindCustomMethods = (props = this.props) => { + __bindCustomMethods = (props: IBaseRendererProps) => { const { __schema } = props; const customMethodsList = Object.keys(__schema.methods || {}) || []; this.__customMethodsList @@ -336,19 +341,24 @@ export default function baseRendererFactory(): IBaseRenderComponent { }; }; - __writeCss = () => { - const css = getValue(this.props.__schema, 'css', ''); + /** + * write props.__schema.css to document as a style element, + * which will be added once and only once. + * @PRIVATE + */ + __writeCss = (props: IBaseRendererProps) => { + const css = getValue(props.__schema, 'css', ''); + this.__debug('create this.styleElement with css', css); let style = this.styleElement; if (!this.styleElement) { style = document.createElement('style'); style.type = 'text/css'; style.setAttribute('from', 'style-sheet'); - if (style.firstChild) { - style.removeChild(style.firstChild); - } + const head = document.head || document.getElementsByTagName('head')[0]; head.appendChild(style); this.styleElement = style; + this.__debug('this.styleElement is created', this.styleElement); } if (style.innerHTML === css) { @@ -361,15 +371,15 @@ export default function baseRendererFactory(): IBaseRenderComponent { __render = () => { const schema = this.props.__schema; this.__excuteLifeCycleMethod('render'); - this.__writeCss(); + this.__writeCss(this.props); const { engine } = this.context; if (engine) { engine.props.onCompGetCtx(schema, this); // 画布场景才需要每次渲染bind自定义方法 - if (engine.props.designMode) { - this.__bindCustomMethods(); - this.dataSourceMap = this.__dataHelper && this.__dataHelper.updateConfig(schema.dataSource); + if (engine.props.designMode === 'design') { + this.__bindCustomMethods(this.props); + this.dataSourceMap = this.__dataHelper?.updateConfig(schema.dataSource); } } }; @@ -381,12 +391,23 @@ export default function baseRendererFactory(): IBaseRenderComponent { this.__ref = ref; }; - getSchemaChildren = (schema: NodeSchema | undefined) => { - if (!schema || !schema.props) { - return schema?.children; + __getSchemaChildren = (schema: NodeSchema | undefined) => { + if (!schema) { + return; } - if (!schema.children) return schema.props.children; - if (!schema.props.children) return schema.children; + + if (!schema.props) { + return schema.children; + } + + if (!schema.children) { + return schema.props.children; + } + + if (!schema.props.children) { + return schema.children; + } + let _children = ([] as NodeData[]).concat(schema.children); if (Array.isArray(schema.props.children)) { _children = _children.concat(schema.props.children); @@ -400,10 +421,8 @@ export default function baseRendererFactory(): IBaseRenderComponent { const { __schema, __ctx, __components = {} } = this.props; const scope: any = {}; scope.__proto__ = __ctx || this; - if (!this._self) { - this._self = scope; - } - const _children = this.getSchemaChildren(__schema); + + const _children = this.__getSchemaChildren(__schema); let Comp = __components[__schema.componentName]; if (!Comp) { @@ -416,19 +435,25 @@ export default function baseRendererFactory(): IBaseRenderComponent { } as IInfo)); }; - - // 将模型结构转换成react Element - // schema 模型结构 - // self 为每个渲染组件构造的上下文,self是自上而下继承的 - // parentInfo 父组件的信息,包含schema和Comp - // idx 若为循环渲染的循环Index + /** + * 将模型结构转换成react Element + * @param originalSchema schema + * @param originalScope scope + * @param parentInfo 父组件的信息,包含schema和Comp + * @param idx 为循环渲染的循环Index + */ __createVirtualDom = (originalSchema: NodeData | NodeData[] | undefined, originalScope: any, parentInfo: IInfo, idx: string | number = ''): any => { + if (!originalSchema) { + return null; + } let scope = originalScope; let schema = originalSchema; const { engine } = this.context || {}; + if (!engine) { + this.__debug('this.context.engine is invalid!'); + return null; + } try { - if (!schema) return null; - const { __appHelper: appHelper, __components: components = {} } = this.props || {}; if (isJSExpression(schema)) { @@ -440,33 +465,43 @@ export default function baseRendererFactory(): IBaseRenderComponent { if (isJSSlot(schema)) { return this.__createVirtualDom(schema.value, scope, parentInfo); } - if (typeof schema === 'string') return schema; + + if (typeof schema === 'string') { + return schema; + } + if (typeof schema === 'number' || typeof schema === 'boolean') { return String(schema); } + if (Array.isArray(schema)) { - if (schema.length === 1) return this.__createVirtualDom(schema[0], scope, parentInfo); + if (schema.length === 1) { + return this.__createVirtualDom(schema[0], scope, parentInfo); + } return schema.map((item, idy) => this.__createVirtualDom(item, scope, parentInfo, (item as NodeSchema)?.__ctx?.lceKey ? '' : String(idy))); } - // FIXME - const _children = this.getSchemaChildren(schema); + + const _children = this.__getSchemaChildren(schema); // 解析占位组件 - if (schema?.componentName === 'Fragment' && _children) { + if (schema.componentName === 'Fragment' && _children) { const tarChildren = isJSExpression(_children) ? this.parseExpression(_children, scope) : _children; return this.__createVirtualDom(tarChildren, scope, parentInfo); } - if (schema?.componentName === 'Text' && typeof schema?.props?.text === 'string') { - const text: string = schema?.props?.text; + if (schema.componentName === 'Text' && typeof schema.props?.text === 'string') { + const text: string = schema.props?.text; schema = { ...schema }; schema.children = [text]; } // @ts-expect-error 如果直接转换好了,可以返回 - if (schema?.$$typeof) { + if (schema.$$typeof) { return schema; } - if (!isSchema(schema)) return null; + + if (!isSchema(schema)) { + return null; + } let Comp = components[schema.componentName] || this.props.__container?.components?.[schema.componentName]; // 容器类组件的上下文通过props传递,避免context传递带来的嵌套问题 @@ -490,9 +525,6 @@ export default function baseRendererFactory(): IBaseRenderComponent { ); } - // DesignMode 为 design 情况下,需要进入 leaf Hoc,进行相关事件注册 - const displayInHook = engine?.props?.designMode === 'design'; - if (schema.loop != null) { const loop = this.__parseData(schema.loop, scope); const useLoop = isUseLoop(loop, this._designModeIsDesign); @@ -509,7 +541,12 @@ export default function baseRendererFactory(): IBaseRenderComponent { } } const condition = schema.condition == null ? true : this.__parseData(schema.condition, scope); - if (!condition && !displayInHook) return null; + + // DesignMode 为 design 情况下,需要进入 leaf Hoc,进行相关事件注册 + const displayInHook = engine.props?.designMode === 'design'; + if (!condition && !displayInHook) { + return null; + } let scopeKey = ''; // 判断组件是否需要生成scope,且只生成一次,挂在this.__compScopes上 @@ -539,7 +576,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { scope = compSelf; } - if (engine?.props?.designMode) { + if (engine.props?.designMode) { otherProps.__designMode = engine.props.designMode; } if (this._designModeIsDesign) { @@ -572,7 +609,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { if (refProps && typeof refProps === 'string') { this[refProps] = ref; } - ref && engine?.props?.onCompGetRef(schema, ref); + ref && engine.props?.onCompGetRef(schema, ref); }; // scope需要传入到组件上 @@ -581,7 +618,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { } if (schema?.__ctx?.lceKey) { if (!isFileSchema(schema)) { - engine?.props?.onCompGetCtx(schema, scope); + engine.props?.onCompGetCtx(schema, scope); } props.key = props.key || `${schema.__ctx.lceKey}_${schema.__ctx.idx || 0}_${idx !== undefined ? idx : ''}`; } else if ((typeof idx === 'number' || typeof idx === 'string') && !props.key) { @@ -654,7 +691,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { } __getSchemaChildrenVirtualDom = (schema: NodeSchema | undefined, scope: any, Comp: any) => { - let _children = this.getSchemaChildren(schema); + let _children = this.__getSchemaChildren(schema); // @todo 补完这里的 Element 定义 @承虎 let children: any = []; diff --git a/packages/renderer-core/src/types/index.ts b/packages/renderer-core/src/types/index.ts index 34e69b1643..c98295e018 100644 --- a/packages/renderer-core/src/types/index.ts +++ b/packages/renderer-core/src/types/index.ts @@ -236,7 +236,7 @@ export type IBaseRendererInstance = IGeneralComponent< > & { reloadDataSource(): Promise; - getSchemaChildren(schema: NodeSchema | undefined): NodeData | NodeData[] | undefined; + __getSchemaChildren(schema: NodeSchema | undefined): NodeData | NodeData[] | undefined; __beforeInit(props: IBaseRendererProps): void; __init(props: IBaseRendererProps): void; __afterInit(props: IBaseRendererProps): void; diff --git a/packages/renderer-core/src/utils/logger.ts b/packages/renderer-core/src/utils/logger.ts index 1feb9f6c8f..cf4895bd2e 100644 --- a/packages/renderer-core/src/utils/logger.ts +++ b/packages/renderer-core/src/utils/logger.ts @@ -1,2 +1,3 @@ import Logger from 'zen-logger'; +// how to use this logger, see https://www.npmjs.com/package/zen-logger export default new Logger({ level: 'warn', bizName: 'renderer' }); \ No newline at end of file From 282a30afa4aa387f319f98e9115ff2fa38f259d1 Mon Sep 17 00:00:00 2001 From: JackLian Date: Tue, 12 Jul 2022 10:51:56 +0800 Subject: [PATCH 086/823] refactor: minor refactors for render-core/renderer/base. remove useless logic about __ignoreParse --- packages/renderer-core/src/renderer/base.tsx | 131 ++++++++++--------- packages/renderer-core/src/types/index.ts | 8 +- packages/types/src/schema.ts | 2 - 3 files changed, 70 insertions(+), 71 deletions(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index dde715c03f..0c2e091521 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -29,7 +29,7 @@ import { isVariable, isJSSlot, } from '../utils'; -import { IBaseRendererProps, IInfo, IBaseRenderComponent, IBaseRendererContext, IGeneralConstructor, IRendererAppHelper, DataSource } from '../types'; +import { IBaseRendererProps, INodeInfo, IBaseRenderComponent, IBaseRendererContext, IGeneralConstructor, IRendererAppHelper, DataSource } from '../types'; import { compWrapper } from '../hoc'; import { IComponentConstruct, IComponentHoc, leafWrapper } from '../hoc/leaf'; import logger from '../utils/logger'; @@ -59,6 +59,8 @@ export default function baseRendererFactory(): IBaseRenderComponent { PREVIEW: 'preview', }; const OVERLAY_LIST = ['Dialog', 'Overlay', 'Animate', 'ConfigProvider']; + const DEFAULT_LOOP_ARG_ITEM = 'item'; + const DEFAULT_LOOP_ARG_INDEX = 'index'; let scopeIdx = 0; return class BaseRenderer extends Component { @@ -377,7 +379,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { if (engine) { engine.props.onCompGetCtx(schema, this); // 画布场景才需要每次渲染bind自定义方法 - if (engine.props.designMode === 'design') { + if (this.__designModeIsDesign) { this.__bindCustomMethods(this.props); this.dataSourceMap = this.__dataHelper?.updateConfig(schema.dataSource); } @@ -432,7 +434,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { return this.__createVirtualDom(_children, scope, ({ schema: __schema, Comp: this.__getHocComp(Comp, __schema, scope), - } as IInfo)); + } as INodeInfo)); }; /** @@ -442,7 +444,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { * @param parentInfo 父组件的信息,包含schema和Comp * @param idx 为循环渲染的循环Index */ - __createVirtualDom = (originalSchema: NodeData | NodeData[] | undefined, originalScope: any, parentInfo: IInfo, idx: string | number = ''): any => { + __createVirtualDom = (originalSchema: NodeData | NodeData[] | undefined, originalScope: any, parentInfo: INodeInfo, idx: string | number = ''): any => { if (!originalSchema) { return null; } @@ -527,7 +529,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { if (schema.loop != null) { const loop = this.__parseData(schema.loop, scope); - const useLoop = isUseLoop(loop, this._designModeIsDesign); + const useLoop = isUseLoop(loop, this.__designModeIsDesign); if (useLoop) { return this.__createLoopVirtualDom( { @@ -543,7 +545,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { const condition = schema.condition == null ? true : this.__parseData(schema.condition, scope); // DesignMode 为 design 情况下,需要进入 leaf Hoc,进行相关事件注册 - const displayInHook = engine.props?.designMode === 'design'; + const displayInHook = this.__designModeIsDesign; if (!condition && !displayInHook) { return null; } @@ -579,7 +581,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { if (engine.props?.designMode) { otherProps.__designMode = engine.props.designMode; } - if (this._designModeIsDesign) { + if (this.__designModeIsDesign) { otherProps.__tag = Math.random(); } const componentInfo: any = {}; @@ -588,7 +590,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { props: transformArrayToMap(componentInfo.props, 'name'), }) || {}; - this.componentHoc.forEach((ComponentConstruct: IComponentConstruct) => { + this.__componentHoc.forEach((ComponentConstruct: IComponentConstruct) => { Comp = ComponentConstruct(Comp, { schema, componentInfo, @@ -671,7 +673,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { } }; - get componentHoc(): IComponentConstruct[] { + get __componentHoc(): IComponentConstruct[] { const componentHoc: IComponentHoc[] = [ { designMode: 'design', @@ -691,18 +693,18 @@ export default function baseRendererFactory(): IBaseRenderComponent { } __getSchemaChildrenVirtualDom = (schema: NodeSchema | undefined, scope: any, Comp: any) => { - let _children = this.__getSchemaChildren(schema); + let children = this.__getSchemaChildren(schema); // @todo 补完这里的 Element 定义 @承虎 - let children: any = []; - if (/*! isFileSchema(schema) && */_children) { - if (!Array.isArray(_children)) { - _children = [_children]; + let result: any = []; + if (children) { + if (!Array.isArray(children)) { + children = [children]; } - _children.forEach((_child: any) => { - const _childVirtualDom = this.__createVirtualDom( - isJSExpression(_child) ? this.parseExpression(_child, scope) : _child, + children.forEach((child: any) => { + const childVirtualDom = this.__createVirtualDom( + isJSExpression(child) ? this.parseExpression(child, scope) : child, scope, { schema, @@ -710,12 +712,12 @@ export default function baseRendererFactory(): IBaseRenderComponent { }, ); - children.push(_childVirtualDom); + result.push(childVirtualDom); }); } - if (children && children.length) { - return children; + if (result && result.length > 0) { + return result; } return null; }; @@ -734,14 +736,16 @@ export default function baseRendererFactory(): IBaseRenderComponent { }) || {}; }; - __createLoopVirtualDom = (schema: NodeSchema, scope: any, parentInfo: IInfo, idx: number | string) => { + __createLoopVirtualDom = (schema: NodeSchema, scope: any, parentInfo: INodeInfo, idx: number | string) => { if (isFileSchema(schema)) { console.warn('file type not support Loop'); return null; } - if (!Array.isArray(schema.loop)) return null; - const itemArg = (schema.loopArgs && schema.loopArgs[0]) || 'item'; - const indexArg = (schema.loopArgs && schema.loopArgs[1]) || 'index'; + if (!Array.isArray(schema.loop)) { + return null; + } + const itemArg = (schema.loopArgs && schema.loopArgs[0]) || DEFAULT_LOOP_ARG_ITEM; + const indexArg = (schema.loopArgs && schema.loopArgs[1]) || DEFAULT_LOOP_ARG_INDEX; const { loop } = schema; return loop.map((item: JSONValue | CompositeValue, i: number) => { const loopSelf: any = { @@ -761,26 +765,29 @@ export default function baseRendererFactory(): IBaseRenderComponent { }); }; - get _designModeIsDesign() { + get __designModeIsDesign() { const { engine } = this.context || {}; return engine?.props?.designMode === 'design'; } - __parseProps = (originalProps: any, scope: any, path: string, info: IInfo): any => { + __parseProps = (originalProps: any, scope: any, path: string, info: INodeInfo): any => { let props = originalProps; const { schema, Comp, componentInfo = {} } = info; const propInfo = getValue(componentInfo.props, path); - // FIXME! 将这行逻辑外置,解耦,线上环境不要验证参数,调试环境可以有,通过传参自定义 + // FIXME: 将这行逻辑外置,解耦,线上环境不要验证参数,调试环境可以有,通过传参自定义 const propType = propInfo?.extra?.propType; - const ignoreParse = schema?.__ignoreParse || []; + const checkProps = (value: any) => { - if (!propType) return value; + if (!propType) { + return value; + } return checkPropTypes(value, path, propType, componentInfo.name) ? value : undefined; }; const parseReactNode = (data: any, params: any) => { if (isEmpty(params)) { - return checkProps(this.__createVirtualDom(data, scope, ({ schema, Comp } as IInfo))); + const virtualDom = this.__createVirtualDom(data, scope, ({ schema, Comp } as INodeInfo)); + return checkProps(virtualDom); } return checkProps((...argValues: any[]) => { const args: any = {}; @@ -794,32 +801,23 @@ export default function baseRendererFactory(): IBaseRenderComponent { }); } args.__proto__ = scope; - return scope.__createVirtualDom(data, args, { schema, Comp }); + return scope.__createVirtualDom(data, args, ({ schema, Comp } as INodeInfo)); }); }; - // 判断是否需要解析变量 - if ( - ignoreParse.some((item: any) => { - if (item instanceof RegExp) { - return item.test(path); - } - return item === path; - }) - ) { - return checkProps(props); - } if (isJSExpression(props)) { props = this.parseExpression(props, scope); // 只有当变量解析出来为模型结构的时候才会继续解析 - if (!isSchema(props) && !isJSSlot(props)) return checkProps(props); + if (!isSchema(props) && !isJSSlot(props)) { + return checkProps(props); + } } - const handleLegaoI18n = (innerProps: any) => innerProps[innerProps.use || 'zh_CN']; + const handleI18nData = (innerProps: any) => innerProps[innerProps.use || 'zh_CN']; - // 兼容乐高设计态 i18n 数据 + // @LEGACY 兼容老平台设计态 i18n 数据 if (isI18nData(props)) { - const i18nProp = handleLegaoI18n(props); + const i18nProp = handleI18nData(props); if (i18nProp) { props = i18nProp; } else { @@ -827,11 +825,11 @@ export default function baseRendererFactory(): IBaseRenderComponent { } } - // 兼容乐高设计态的变量绑定 + // @LEGACY 兼容老平台设计态的变量绑定 if (isVariable(props)) { props = props.value; if (isI18nData(props)) { - props = handleLegaoI18n(props); + props = handleI18nData(props); } } @@ -840,15 +838,15 @@ export default function baseRendererFactory(): IBaseRenderComponent { } if (isJSSlot(props)) { const { params, value } = props; - if (!isSchema(value) || isEmpty(value)) return undefined; + if (!isSchema(value) || isEmpty(value)) { + return undefined; + } return parseReactNode(value, params); } + // 兼容通过componentInfo判断的情况 if (isSchema(props)) { - const isReactNodeFunction = !!( - propInfo?.type === 'ReactNode' - && propInfo?.props?.type === 'function' - ); + const isReactNodeFunction = !!(propInfo?.type === 'ReactNode' && propInfo?.props?.type === 'function'); const isMixinReactNodeFunction = !!( propInfo?.type === 'Mixin' @@ -874,7 +872,9 @@ export default function baseRendererFactory(): IBaseRenderComponent { return checkProps(props.bind(scope)); } if (props && typeof props === 'object') { - if (props.$$typeof) return checkProps(props); + if (props.$$typeof) { + return checkProps(props); + } const res: any = {}; forEach(props, (val: any, key: string) => { if (key.startsWith('__')) { @@ -921,7 +921,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { __getHocComp(OriginalComp: any, schema: any, scope: any) { let Comp = OriginalComp; - this.componentHoc.forEach((ComponentConstruct: IComponentConstruct) => { + this.__componentHoc.forEach((ComponentConstruct: IComponentConstruct) => { Comp = ComponentConstruct(Comp || Div, { schema, componentInfo: {}, @@ -935,8 +935,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { __renderComp(OriginalComp: any, ctxProps: object) { let Comp = OriginalComp; - const { __schema } = this.props; - const { __ctx } = this.props; + const { __schema, __ctx } = this.props; const scope: any = {}; scope.__proto__ = __ctx || this; Comp = this.__getHocComp(Comp, __schema, scope); @@ -952,7 +951,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { return null; } - if (this._designModeIsDesign) { + if (this.__designModeIsDesign) { otherProps.__tag = Math.random(); } @@ -973,13 +972,15 @@ export default function baseRendererFactory(): IBaseRenderComponent { __renderContent(children: any) { const { __schema } = this.props; - const props = this.__parseData(__schema.props); - const { id, className, style = {} } = props; + const parsedProps = this.__parseData(__schema.props); + const className = classnames(`lce-${this.__namespace}`, getFileCssName(__schema.fileName), parsedProps.className, this.props.className); + const style = { ...(parsedProps.style || {}), ...(typeof this.props.style === 'object' ? this.props.style : {}) }; + const id = this.props.id || parsedProps.id; return createElement('div', { ref: this.__getRef, - className: classnames(`lce-${this.__namespace}`, getFileCssName(__schema.fileName), className, this.props.className), - id: this.props.id || id, - style: { ...style, ...(typeof this.props.style === 'object' ? this.props.style : {}) }, + className, + id, + style, }, children); } @@ -989,8 +990,8 @@ export default function baseRendererFactory(): IBaseRenderComponent { extraComponents = [extraComponents]; } - const buitin = capitalizeFirstLetter(this.__namespace); - const componentNames = [buitin, ...extraComponents]; + const builtin = capitalizeFirstLetter(this.__namespace); + const componentNames = [builtin, ...extraComponents]; return !isSchema(schema) || !componentNames.includes(schema?.componentName ?? ''); }; diff --git a/packages/renderer-core/src/types/index.ts b/packages/renderer-core/src/types/index.ts index c98295e018..e3cec555b7 100644 --- a/packages/renderer-core/src/types/index.ts +++ b/packages/renderer-core/src/types/index.ts @@ -168,7 +168,7 @@ export interface IBaseRendererProps { device?: 'default' | 'mobile' | string; } -export interface IInfo { +export interface INodeInfo { schema?: NodeSchema; Comp: any; componentInfo?: any; @@ -254,9 +254,9 @@ export type IBaseRendererInstance = IGeneralComponent< ): any; __getComponentProps(schema: NodeSchema | undefined, scope: any, Comp: any, componentInfo?: any): any; __createDom(): any; - __createVirtualDom(schema: any, self: any, parentInfo: IInfo, idx: string | number): any; - __createLoopVirtualDom(schema: any, self: any, parentInfo: IInfo, idx: number | string): any; - __parseProps(props: any, self: any, path: string, info: IInfo): any; + __createVirtualDom(schema: any, self: any, parentInfo: INodeInfo, idx: string | number): any; + __createLoopVirtualDom(schema: any, self: any, parentInfo: INodeInfo, idx: number | string): any; + __parseProps(props: any, self: any, path: string, info: INodeInfo): any; __initDebug?(): void; __debug(...args: any[]): void; __renderContextProvider(customProps?: object, children?: any): any; diff --git a/packages/types/src/schema.ts b/packages/types/src/schema.ts index 2895cd5eee..5d0fad4444 100644 --- a/packages/types/src/schema.ts +++ b/packages/types/src/schema.ts @@ -64,8 +64,6 @@ export interface NodeSchema { /** @experimental 编辑态内部使用 */ __ctx?: any; - /** @experimental 编辑态内部使用 */ - __ignoreParse?: any[]; } export type PropsMap = CompositeObject; From 6399cce05ae494dac6facf4366949b0b97576079 Mon Sep 17 00:00:00 2001 From: "humphry.hy" Date: Tue, 12 Jul 2022 19:55:38 +0800 Subject: [PATCH 087/823] =?UTF-8?q?feat:=20=E4=B8=BA=20renderer=20?= =?UTF-8?q?=E8=BF=BD=E5=8A=A0=20displayName=EF=BC=8C=E4=BB=A5=E6=94=AF?= =?UTF-8?q?=E6=8C=81=E5=90=8E=E7=BB=AD=E7=9A=84=E5=8F=8D=E5=B0=84=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/renderer-core/src/hoc/index.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/renderer-core/src/hoc/index.tsx b/packages/renderer-core/src/hoc/index.tsx index d4c877b871..a9314060f3 100644 --- a/packages/renderer-core/src/hoc/index.tsx +++ b/packages/renderer-core/src/hoc/index.tsx @@ -12,6 +12,7 @@ export function compWrapper(Comp: any) { return createElement(Comp, this.props); } } + (Wrapper as any).displayName = Comp.displayName; return cloneEnumerableProperty(forwardRef((props: any, ref: any) => { return createElement(Wrapper, { ...props, forwardRef: ref }); From 706dad4aa5b47eaad8a2dadadb5a5c1a2da18e3e Mon Sep 17 00:00:00 2001 From: JackLian Date: Wed, 13 Jul 2022 11:52:38 +0800 Subject: [PATCH 088/823] refactor: abstract excuteLifeCycleMethod and some minor refactors --- packages/renderer-core/jest.config.js | 2 +- packages/renderer-core/src/renderer/base.tsx | 105 ++++----- packages/renderer-core/src/renderer/page.tsx | 2 - .../tests/renderer/base.test.tsx | 208 +++++++++++++++++- 4 files changed, 261 insertions(+), 56 deletions(-) diff --git a/packages/renderer-core/jest.config.js b/packages/renderer-core/jest.config.js index 4e27e6c90e..ceb8e8b563 100644 --- a/packages/renderer-core/jest.config.js +++ b/packages/renderer-core/jest.config.js @@ -10,7 +10,7 @@ const jestConfig = { // // '^.+\\.(js|jsx)$': 'babel-jest', // }, // testMatch: ['(/tests?/.*(test))\\.[jt]s$'], - // testMatch: ['**/*/common.test.ts'], + // testMatch: ['**/*/base.test.tsx'], transformIgnorePatterns: [ `/node_modules/(?!${esModules})/`, ], diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 0c2e091521..29ed7a7baf 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -35,6 +35,38 @@ import { IComponentConstruct, IComponentHoc, leafWrapper } from '../hoc/leaf'; import logger from '../utils/logger'; import isUseLoop from '../utils/is-use-loop'; +/** + * execute method in schema.lifeCycles with context + * @PRIVATE + */ +export function excuteLifeCycleMethod(context: any, schema: NodeSchema, method: string, args: any, thisRequiredInJSE: boolean | undefined): any { + if (!context || !isSchema(schema) || !method) { + return; + } + const lifeCycleMethods = getValue(schema, 'lifeCycles', {}); + let fn = lifeCycleMethods[method]; + + if (!fn) { + return; + } + + // TODO: cache + if (isJSExpression(fn) || isJSFunction(fn)) { + fn = thisRequiredInJSE ? parseThisRequiredExpression(fn, context) : parseExpression(fn, context); + } + + if (typeof fn !== 'function') { + console.error(`生命周期${method}类型不符`, fn); + return; + } + + try { + return fn.apply(context, args); + } catch (e) { + console.error(`[${schema.componentName}]生命周期${method}出错`, e); + } +} + export default function baseRendererFactory(): IBaseRenderComponent { const { BaseRenderer: customBaseRenderer } = adapter.getRenderers(); @@ -72,32 +104,33 @@ export default function baseRendererFactory(): IBaseRenderComponent { static contextType = AppContext; - __namespace = 'base'; - appHelper?: IRendererAppHelper; + i18n: any; + getLocale: any; + setLocale: any; + dataSourceMap: Record = {}; + + __namespace = 'base'; __compScopes: Record = {}; __instanceMap: Record = {}; __dataHelper: any; __customMethodsList: any[] = []; - dataSourceMap: Record = {}; + __parseExpression: any; __ref: any; - i18n: any; - getLocale: any; - setLocale: any; /** * reference of style element contains schema.css * * @type {any} */ - styleElement: any; - parseExpression: any; + __styleElement: any; + [key: string]: any; constructor(props: IBaseRendererProps, context: IBaseRendererContext) { super(props, context); this.context = context; - this.parseExpression = props?.thisRequiredInJSE ? parseThisRequiredExpression : parseExpression; + this.__parseExpression = props?.thisRequiredInJSE ? parseThisRequiredExpression : parseExpression; this.__beforeInit(props); this.__init(props); this.__afterInit(props); @@ -119,21 +152,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { __afterInit(_props: IBaseRendererProps) { } static getDerivedStateFromProps(props: IBaseRendererProps, state: any) { - logger.log('getDerivedStateFromProps'); - const func = props?.__schema?.lifeCycles?.getDerivedStateFromProps; - - if (func) { - if (isJSExpression(func) || isJSFunction(func)) { - const fn = props.thisRequiredInJSE ? parseThisRequiredExpression(func, this) : parseExpression(func, this); - return fn?.(props, state); - } - - if (typeof func === 'function') { - // eslint-disable-next-line @typescript-eslint/ban-types - return (func as Function)(props, state); - } - } - return null; + return excuteLifeCycleMethod(this, props?.__schema, 'getDerivedStateFromProps', [props, state], props.thisRequiredInJSE); } async getSnapshotBeforeUpdate(...args: any[]) { @@ -198,23 +217,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { * @PRIVATE */ __excuteLifeCycleMethod = (method: string, args?: any) => { - const lifeCycleMethods = getValue(this.props.__schema, 'lifeCycles', {}); - let fn = lifeCycleMethods[method]; - if (fn) { - // TODO: cache - if (isJSExpression(fn) || isJSFunction(fn)) { - fn = this.parseExpression(fn, this); - } - if (typeof fn !== 'function') { - console.error(`生命周期${method}类型不符`, fn); - return; - } - try { - return fn.apply(this, args); - } catch (e) { - console.error(`[${this.props.__schema.componentName}]生命周期${method}出错`, e); - } - } + excuteLifeCycleMethod(this, this.props.__schema, method, args, this.props.thisRequiredInJSE); }; /** @@ -242,7 +245,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { forEach(__schema.methods, (val: any, key: string) => { let value = val; if (isJSExpression(value) || isJSFunction(value)) { - value = this.parseExpression(value, this); + value = this.__parseExpression(value, this); } if (typeof value !== 'function') { console.error(`自定义函数${key}类型不符`, value); @@ -351,16 +354,16 @@ export default function baseRendererFactory(): IBaseRenderComponent { __writeCss = (props: IBaseRendererProps) => { const css = getValue(props.__schema, 'css', ''); this.__debug('create this.styleElement with css', css); - let style = this.styleElement; - if (!this.styleElement) { + let style = this.__styleElement; + if (!this.__styleElement) { style = document.createElement('style'); style.type = 'text/css'; style.setAttribute('from', 'style-sheet'); const head = document.head || document.getElementsByTagName('head')[0]; head.appendChild(style); - this.styleElement = style; - this.__debug('this.styleElement is created', this.styleElement); + this.__styleElement = style; + this.__debug('this.styleElement is created', this.__styleElement); } if (style.innerHTML === css) { @@ -459,7 +462,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { const { __appHelper: appHelper, __components: components = {} } = this.props || {}; if (isJSExpression(schema)) { - return this.parseExpression(schema, scope); + return this.__parseExpression(schema, scope); } if (isI18nData(schema)) { return parseI18n(schema, scope); @@ -486,7 +489,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { const _children = this.__getSchemaChildren(schema); // 解析占位组件 if (schema.componentName === 'Fragment' && _children) { - const tarChildren = isJSExpression(_children) ? this.parseExpression(_children, scope) : _children; + const tarChildren = isJSExpression(_children) ? this.__parseExpression(_children, scope) : _children; return this.__createVirtualDom(tarChildren, scope, parentInfo); } @@ -553,7 +556,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { let scopeKey = ''; // 判断组件是否需要生成scope,且只生成一次,挂在this.__compScopes上 if (Comp.generateScope) { - const key = this.parseExpression(schema.props?.key, scope); + const key = this.__parseExpression(schema.props?.key, scope); if (key) { // 如果组件自己设置key则使用组件自己的key scopeKey = key; @@ -704,7 +707,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { children.forEach((child: any) => { const childVirtualDom = this.__createVirtualDom( - isJSExpression(child) ? this.parseExpression(child, scope) : child, + isJSExpression(child) ? this.__parseExpression(child, scope) : child, scope, { schema, @@ -806,7 +809,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { }; if (isJSExpression(props)) { - props = this.parseExpression(props, scope); + props = this.__parseExpression(props, scope); // 只有当变量解析出来为模型结构的时候才会继续解析 if (!isSchema(props) && !isJSSlot(props)) { return checkProps(props); diff --git a/packages/renderer-core/src/renderer/page.tsx b/packages/renderer-core/src/renderer/page.tsx index 41c1a713f8..17e3ef4c86 100644 --- a/packages/renderer-core/src/renderer/page.tsx +++ b/packages/renderer-core/src/renderer/page.tsx @@ -40,8 +40,6 @@ export default function pageRendererFactory(): IBaseRenderComponent { this.__bindCustomMethods(this.props); this.__initDataSource(this.props); - // this.__excuteLifeCycleMethod('constructor', arguments); - this.__generateCtx({ page: this, }); diff --git a/packages/renderer-core/tests/renderer/base.test.tsx b/packages/renderer-core/tests/renderer/base.test.tsx index 5d8d24a805..f69688908e 100644 --- a/packages/renderer-core/tests/renderer/base.test.tsx +++ b/packages/renderer-core/tests/renderer/base.test.tsx @@ -1,13 +1,31 @@ + +import React, { Component, createElement, PureComponent, createContext } from 'react'; const mockGetRenderers = jest.fn(); +const mockGetRuntime = jest.fn(); +const mockParseExpression = jest.fn(); jest.mock('../../src/adapter', () => { return { - getRenderers: () => { return mockGetRenderers();} + getRenderers: () => { return mockGetRenderers();}, + getRuntime: () => { return mockGetRuntime();}, + }; +}); +jest.mock('../../src/utils', () => { + const originalUtils = jest.requireActual('../../src/utils'); + return { + ...originalUtils, + parseExpression: (...args) => { mockParseExpression(args);}, }; }); + import baseRendererFactory from '../../src/renderer/base'; +import { IBaseRendererProps } from '../../src/types'; +import TestRenderer from 'react-test-renderer'; +import components from '../utils/components'; +import schema from '../fixtures/schema/basic'; + -describe('Base Render', () => { +describe('Base Render factory', () => { it('customBaseRenderer logic works', () => { mockGetRenderers.mockReturnValue({BaseRenderer: {}}); const baseRenderer = baseRendererFactory(); @@ -15,4 +33,190 @@ describe('Base Render', () => { expect(baseRenderer).toStrictEqual({}); mockGetRenderers.mockClear(); }); +}); + +describe('Base Render methods', () => { + let RendererClass; + const mockRendererFactory = () => { + return class extends Component { + constructor(props: IBaseRendererProps, context: any) { + super(props, context); + } + } + } + beforeEach(() => { + const mockRnederers = { + PageRenderer: mockRendererFactory(), + ComponentRenderer: mockRendererFactory(), + BlockRenderer: mockRendererFactory(), + AddonRenderer: mockRendererFactory(), + TempRenderer: mockRendererFactory(), + DivRenderer: mockRendererFactory(), + }; + mockGetRenderers.mockReturnValue(mockRnederers); + mockGetRuntime.mockReturnValue({ + Component, + createElement, + PureComponent, + createContext, + }); + RendererClass = baseRendererFactory(); + }) + + afterEach(() => { + mockGetRenderers.mockClear(); + }) + + it('should excute lifecycle.getDerivedStateFromProps when defined', () => { + const mockGetDerivedStateFromProps = { + type: 'JSFunction', + value: 'function() {\n console.log(\'did mount\');\n }', + }; + const mockSchema = schema; + (mockSchema.lifeCycles as any).getDerivedStateFromProps = mockGetDerivedStateFromProps; + + // const originalUtils = jest.requireActual('../../src/utils'); + // mockParseExpression.mockImplementation(originalUtils.parseExpression); + const component = TestRenderer.create( + // @ts-ignore + ); + // console.log(component.root.props.a); + // component.update(); + // console.log(component.root.props.a); + // expect(mockParseExpression).toHaveBeenCalledWith(mockGetDerivedStateFromProps, expect.anything()) + // test lifecycle.getDerivedStateFromProps is null + + // test lifecycle.getDerivedStateFromProps is JSExpression + + // test lifecycle.getDerivedStateFromProps is JSFunction + + // test lifecycle.getDerivedStateFromProps is function + + }); + + + // it('should excute lifecycle.getSnapshotBeforeUpdate when defined', () => { + // }); + + // it('should excute lifecycle.componentDidMount when defined', () => { + // }); + + // it('should excute lifecycle.componentDidUpdate when defined', () => { + // }); + + // it('should excute lifecycle.componentWillUnmount when defined', () => { + // }); + + // it('should excute lifecycle.componentDidCatch when defined', () => { + // }); + + // it('__excuteLifeCycleMethod should work', () => { + // }); + + // it('reloadDataSource should work', () => { + // }); + + // it('shouldComponentUpdate should work', () => { + // }); + + + // it('_getComponentView should work', () => { + // }); + + // it('__bindCustomMethods should work', () => { + // }); + + // it('__generateCtx should work', () => { + // }); + + // it('__parseData should work', () => { + // }); + + // it('__initDataSource should work', () => { + // }); + + // it('__initI18nAPIs should work', () => { + // }); + + // it('__writeCss should work', () => { + // }); + + // it('__render should work', () => { + // }); + + // it('__getSchemaChildren should work', () => { + // }); + + // it('__createDom should work', () => { + // }); + + // it('__createVirtualDom should work', () => { + // }); + + // it('__componentHoc should work', () => { + // }); + + // it('__getSchemaChildrenVirtualDom should work', () => { + // }); + + // it('__getComponentProps should work', () => { + // }); + + // it('__createLoopVirtualDom should work', () => { + // }); + + // it('__designModeIsDesign should work', () => { + // }); + + // it('__parseProps should work', () => { + // }); + + // it('$ should work', () => { + // }); + + // it('__renderContextProvider should work', () => { + // }); + + // it('__renderContextConsumer should work', () => { + // }); + + // it('__getHocComp should work', () => { + // }); + + // it('__renderComp should work', () => { + // }); + + // it('__renderContent should work', () => { + // }); + + // it('__checkSchema should work', () => { + // }); + + // it('requestHandlersMap should work', () => { + // }); + + // it('utils should work', () => { + // }); + + // it('constants should work', () => { + // }); + + // it('history should work', () => { + // }); + + // it('location should work', () => { + // }); + + // it('match should work', () => { + // }); }); \ No newline at end of file From 1fa2694635275ca67545dfc9d42f3c3676a97485 Mon Sep 17 00:00:00 2001 From: JackLian Date: Fri, 15 Jul 2022 09:17:22 +0800 Subject: [PATCH 089/823] refactor: abstract getSchemaChildren --- packages/renderer-core/src/renderer/base.tsx | 127 +++++++++--------- packages/renderer-core/src/types/index.ts | 1 - .../tests/renderer/base.test.tsx | 6 +- 3 files changed, 68 insertions(+), 66 deletions(-) diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index 29ed7a7baf..0622f7a4c3 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -31,7 +31,7 @@ import { } from '../utils'; import { IBaseRendererProps, INodeInfo, IBaseRenderComponent, IBaseRendererContext, IGeneralConstructor, IRendererAppHelper, DataSource } from '../types'; import { compWrapper } from '../hoc'; -import { IComponentConstruct, IComponentHoc, leafWrapper } from '../hoc/leaf'; +import { IComponentConstruct, leafWrapper } from '../hoc/leaf'; import logger from '../utils/logger'; import isUseLoop from '../utils/is-use-loop'; @@ -67,6 +67,36 @@ export function excuteLifeCycleMethod(context: any, schema: NodeSchema, method: } } +/** + * get children from a node schema + * @PRIVATE + */ +export function getSchemaChildren(schema: NodeSchema | undefined) { + if (!schema) { + return; + } + + if (!schema.props) { + return schema.children; + } + + if (!schema.children) { + return schema.props.children; + } + + if (!schema.props.children) { + return schema.children; + } + + let result = ([] as NodeData[]).concat(schema.children); + if (Array.isArray(schema.props.children)) { + result = result.concat(schema.props.children); + } else { + result.push(schema.props.children); + } + return result; +} + export default function baseRendererFactory(): IBaseRenderComponent { const { BaseRenderer: customBaseRenderer } = adapter.getRenderers(); @@ -114,6 +144,11 @@ export default function baseRendererFactory(): IBaseRenderComponent { __compScopes: Record = {}; __instanceMap: Record = {}; __dataHelper: any; + /** + * keep track of customMethods added to this context + * + * @type {any} + */ __customMethodsList: any[] = []; __parseExpression: any; __ref: any; @@ -235,12 +270,11 @@ export default function baseRendererFactory(): IBaseRenderComponent { __bindCustomMethods = (props: IBaseRendererProps) => { const { __schema } = props; const customMethodsList = Object.keys(__schema.methods || {}) || []; - this.__customMethodsList - && this.__customMethodsList.forEach((item: any) => { - if (!customMethodsList.includes(item)) { - delete this[item]; - } - }); + (this.__customMethodsList || []).forEach((item: any) => { + if (!customMethodsList.includes(item)) { + delete this[item]; + } + }); this.__customMethodsList = customMethodsList; forEach(__schema.methods, (val: any, key: string) => { let value = val; @@ -248,7 +282,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { value = this.__parseExpression(value, this); } if (typeof value !== 'function') { - console.error(`自定义函数${key}类型不符`, value); + console.error(`custom method ${key} can not be parsed to a valid function`, value); return; } this[key] = value.bind(this); @@ -282,6 +316,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { }; const dataSource = schema.dataSource || defaultDataSource; // requestHandlersMap 存在才走数据源引擎方案 + // TODO: 下面if else 抽成独立函数 const useDataSourceEngine = !!(props.__appHelper?.requestHandlersMap); if (useDataSourceEngine) { this.__dataHelper = { @@ -396,48 +431,22 @@ export default function baseRendererFactory(): IBaseRenderComponent { this.__ref = ref; }; - __getSchemaChildren = (schema: NodeSchema | undefined) => { - if (!schema) { - return; - } - - if (!schema.props) { - return schema.children; - } - - if (!schema.children) { - return schema.props.children; - } - - if (!schema.props.children) { - return schema.children; - } - - let _children = ([] as NodeData[]).concat(schema.children); - if (Array.isArray(schema.props.children)) { - _children = _children.concat(schema.props.children); - } else { - _children.push(schema.props.children); - } - return _children; - }; - __createDom = () => { const { __schema, __ctx, __components = {} } = this.props; const scope: any = {}; scope.__proto__ = __ctx || this; - const _children = this.__getSchemaChildren(__schema); + const _children = getSchemaChildren(__schema); let Comp = __components[__schema.componentName]; if (!Comp) { this.__debug(`${__schema.componentName} is invalid!`); } - - return this.__createVirtualDom(_children, scope, ({ + const parentNodeInfo = ({ schema: __schema, - Comp: this.__getHocComp(Comp, __schema, scope), - } as INodeInfo)); + Comp: this.__getHOCWrappedComponent(Comp, __schema, scope), + } as INodeInfo); + return this.__createVirtualDom(_children, scope, parentNodeInfo); }; /** @@ -486,7 +495,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { return schema.map((item, idy) => this.__createVirtualDom(item, scope, parentInfo, (item as NodeSchema)?.__ctx?.lceKey ? '' : String(idy))); } - const _children = this.__getSchemaChildren(schema); + const _children = getSchemaChildren(schema); // 解析占位组件 if (schema.componentName === 'Fragment' && _children) { const tarChildren = isJSExpression(_children) ? this.__parseExpression(_children, scope) : _children; @@ -593,7 +602,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { props: transformArrayToMap(componentInfo.props, 'name'), }) || {}; - this.__componentHoc.forEach((ComponentConstruct: IComponentConstruct) => { + this.__componentHOCs.forEach((ComponentConstruct: IComponentConstruct) => { Comp = ComponentConstruct(Comp, { schema, componentInfo, @@ -676,27 +685,21 @@ export default function baseRendererFactory(): IBaseRenderComponent { } }; - get __componentHoc(): IComponentConstruct[] { - const componentHoc: IComponentHoc[] = [ - { - designMode: 'design', - hoc: leafWrapper, - }, - ]; - - return componentHoc - .filter((d: IComponentHoc) => { - if (Array.isArray(d.designMode)) { - return d.designMode.includes(this.props.designMode); - } - - return d.designMode === this.props.designMode; - }) - .map((d: IComponentHoc) => d.hoc); + /** + * get Component HOCs + * + * @readonly + * @type {IComponentConstruct[]} + */ + get __componentHOCs(): IComponentConstruct[] { + if (this.__designModeIsDesign) { + return [leafWrapper]; + } + return []; } __getSchemaChildrenVirtualDom = (schema: NodeSchema | undefined, scope: any, Comp: any) => { - let children = this.__getSchemaChildren(schema); + let children = getSchemaChildren(schema); // @todo 补完这里的 Element 定义 @承虎 let result: any = []; @@ -922,9 +925,9 @@ export default function baseRendererFactory(): IBaseRenderComponent { return createElement(AppContext.Consumer, {}, children); }; - __getHocComp(OriginalComp: any, schema: any, scope: any) { + __getHOCWrappedComponent(OriginalComp: any, schema: any, scope: any) { let Comp = OriginalComp; - this.__componentHoc.forEach((ComponentConstruct: IComponentConstruct) => { + this.__componentHOCs.forEach((ComponentConstruct: IComponentConstruct) => { Comp = ComponentConstruct(Comp || Div, { schema, componentInfo: {}, @@ -941,7 +944,7 @@ export default function baseRendererFactory(): IBaseRenderComponent { const { __schema, __ctx } = this.props; const scope: any = {}; scope.__proto__ = __ctx || this; - Comp = this.__getHocComp(Comp, __schema, scope); + Comp = this.__getHOCWrappedComponent(Comp, __schema, scope); const data = this.__parseProps(__schema?.props, scope, '', { schema: __schema, Comp, diff --git a/packages/renderer-core/src/types/index.ts b/packages/renderer-core/src/types/index.ts index e3cec555b7..7aa2f8ec46 100644 --- a/packages/renderer-core/src/types/index.ts +++ b/packages/renderer-core/src/types/index.ts @@ -236,7 +236,6 @@ export type IBaseRendererInstance = IGeneralComponent< > & { reloadDataSource(): Promise; - __getSchemaChildren(schema: NodeSchema | undefined): NodeData | NodeData[] | undefined; __beforeInit(props: IBaseRendererProps): void; __init(props: IBaseRendererProps): void; __afterInit(props: IBaseRendererProps): void; diff --git a/packages/renderer-core/tests/renderer/base.test.tsx b/packages/renderer-core/tests/renderer/base.test.tsx index f69688908e..fd9b453451 100644 --- a/packages/renderer-core/tests/renderer/base.test.tsx +++ b/packages/renderer-core/tests/renderer/base.test.tsx @@ -154,7 +154,7 @@ describe('Base Render methods', () => { // it('__render should work', () => { // }); - // it('__getSchemaChildren should work', () => { + // it('getSchemaChildren should work', () => { // }); // it('__createDom should work', () => { @@ -163,7 +163,7 @@ describe('Base Render methods', () => { // it('__createVirtualDom should work', () => { // }); - // it('__componentHoc should work', () => { + // it('__componentHOCs should work', () => { // }); // it('__getSchemaChildrenVirtualDom should work', () => { @@ -190,7 +190,7 @@ describe('Base Render methods', () => { // it('__renderContextConsumer should work', () => { // }); - // it('__getHocComp should work', () => { + // it('__getHOCWrappedComponent should work', () => { // }); // it('__renderComp should work', () => { From 70e7c1c2e8998e80d58447759efdf651105724a9 Mon Sep 17 00:00:00 2001 From: zyy7259 Date: Mon, 18 Jul 2022 16:42:10 +0800 Subject: [PATCH 090/823] feat: add getExtraPropValue setExtraPropValue to shell SettingPropEntry --- packages/shell/src/setting-prop-entry.ts | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/shell/src/setting-prop-entry.ts b/packages/shell/src/setting-prop-entry.ts index bffff08436..399ce4c9c7 100644 --- a/packages/shell/src/setting-prop-entry.ts +++ b/packages/shell/src/setting-prop-entry.ts @@ -195,6 +195,20 @@ export default class SettingPropEntry { return this[settingPropEntrySymbol].getPropValue(propName); } + /** + * 获取顶层附属属性值 + */ + getExtraPropValue(propName: string) { + return this[settingPropEntrySymbol].getExtraPropValue(propName); + } + + /** + * 设置顶层附属属性值 + */ + setExtraPropValue(propName: string, value: any) { + this[settingPropEntrySymbol].setExtraPropValue(propName, value); + } + /** * 获取设置属性集 * @returns From 823242469743d235923b3b946ec7d2db70887ead Mon Sep 17 00:00:00 2001 From: guowenfh Date: Thu, 21 Jul 2022 17:24:47 +0800 Subject: [PATCH 091/823] fix: designer/loadIncrementalAssets await Sequential (#841) * fix: designer/loadIncrementalAssets await Sequential * feat: change editor set support Promise --- packages/designer/src/designer/designer.ts | 3 ++- packages/editor-core/src/editor.ts | 5 ++--- packages/types/src/editor.ts | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts index b665ed1f6f..12d9bc1126 100644 --- a/packages/designer/src/designer/designer.ts +++ b/packages/designer/src/designer/designer.ts @@ -403,7 +403,8 @@ export class Designer { // 合并assets let assets = this.editor.get('assets'); let newAssets = megreAssets(assets, incrementalAssets); - this.editor.set('assets', newAssets); + // 对于 assets 存在需要二次网络下载的过程,必须 await 等待结束之后,再进行事件触发 + await this.editor.set('assets', newAssets); } // TODO: 因为涉及修改 prototype.view,之后在 renderer 里修改了 vc 的 view 获取逻辑后,可删除 this.refreshComponentMetasMap(); diff --git a/packages/editor-core/src/editor.ts b/packages/editor-core/src/editor.ts index bda15aa8f9..bc46086f65 100644 --- a/packages/editor-core/src/editor.ts +++ b/packages/editor-core/src/editor.ts @@ -76,10 +76,9 @@ export class Editor extends (EventEmitter as any) implements IEditor { return this.context.has(keyOrType); } - set(key: KeyType, data: any): void { + set(key: KeyType, data: any): void | Promise { if (key === 'assets') { - this.setAssets(data); - return; + return this.setAssets(data); } // store the data to engineConfig while invoking editor.set() if (!keyBlacklist.includes(key as string)) { diff --git a/packages/types/src/editor.ts b/packages/types/src/editor.ts index 6d917ec477..7db0a5990b 100644 --- a/packages/types/src/editor.ts +++ b/packages/types/src/editor.ts @@ -40,7 +40,7 @@ export interface IEditor extends StrictEventEmitter boolean; - set: (key: KeyType, data: any) => void; + set: (key: KeyType, data: any) => void | Promise; onceGot: (keyOrType: KeyOrType) => Promise>; From 80c805780f08348c2c4de09afbdd24b0061ddf17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Wed, 27 Jul 2022 16:50:52 +0800 Subject: [PATCH 092/823] chore(release): publish 1.0.13 --- lerna.json | 2 +- packages/designer/package.json | 10 +++++----- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 16 ++++++++-------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 10 +++++----- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 12 ++++++------ packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- 16 files changed, 60 insertions(+), 60 deletions(-) diff --git a/lerna.json b/lerna.json index 40daf983c1..8d7c614fa6 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.0.12", + "version": "1.0.13", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index b7e0b3a9c4..91fe1ac07a 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.0.12", + "version": "1.0.13", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,10 +15,10 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.0.12", - "@alilc/lowcode-shell": "1.0.12", - "@alilc/lowcode-types": "1.0.12", - "@alilc/lowcode-utils": "1.0.12", + "@alilc/lowcode-editor-core": "1.0.13", + "@alilc/lowcode-shell": "1.0.13", + "@alilc/lowcode-types": "1.0.13", + "@alilc/lowcode-utils": "1.0.13", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index c178d3c9d8..920772a645 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.0.12", + "version": "1.0.13", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.0.12", - "@alilc/lowcode-utils": "1.0.12", + "@alilc/lowcode-types": "1.0.13", + "@alilc/lowcode-utils": "1.0.13", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 100c5c4014..8fc2a2a96f 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.0.12", + "version": "1.0.13", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -18,10 +18,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.0.12", - "@alilc/lowcode-editor-core": "1.0.12", - "@alilc/lowcode-types": "1.0.12", - "@alilc/lowcode-utils": "1.0.12", + "@alilc/lowcode-designer": "1.0.13", + "@alilc/lowcode-editor-core": "1.0.13", + "@alilc/lowcode-types": "1.0.13", + "@alilc/lowcode-utils": "1.0.13", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index 78c182a348..e9276df2eb 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.0.12", + "version": "1.0.13", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,14 +19,14 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.0.12", - "@alilc/lowcode-editor-core": "1.0.12", - "@alilc/lowcode-editor-skeleton": "1.0.12", + "@alilc/lowcode-designer": "1.0.13", + "@alilc/lowcode-editor-core": "1.0.13", + "@alilc/lowcode-editor-skeleton": "1.0.13", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.0.12", - "@alilc/lowcode-plugin-outline-pane": "1.0.12", - "@alilc/lowcode-shell": "1.0.12", - "@alilc/lowcode-utils": "1.0.12", + "@alilc/lowcode-plugin-designer": "1.0.13", + "@alilc/lowcode-plugin-outline-pane": "1.0.13", + "@alilc/lowcode-shell": "1.0.13", + "@alilc/lowcode-utils": "1.0.13", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index 2e76e0344c..e193204fb5 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.0.12", + "version": "1.0.13", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 3916c79e71..641a1815e4 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.0.12", + "version": "1.0.13", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.0.12", - "@alilc/lowcode-editor-core": "1.0.12", - "@alilc/lowcode-utils": "1.0.12", + "@alilc/lowcode-designer": "1.0.13", + "@alilc/lowcode-editor-core": "1.0.13", + "@alilc/lowcode-utils": "1.0.13", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index aeaedcd72b..3a082e9340 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.0.12", + "version": "1.0.13", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,10 +13,10 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-designer": "1.0.12", - "@alilc/lowcode-editor-core": "1.0.12", - "@alilc/lowcode-types": "1.0.12", - "@alilc/lowcode-utils": "1.0.12", + "@alilc/lowcode-designer": "1.0.13", + "@alilc/lowcode-editor-core": "1.0.13", + "@alilc/lowcode-types": "1.0.13", + "@alilc/lowcode-utils": "1.0.13", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0" diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index 3af6773b42..bf3ada7bbd 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.0.12", + "version": "1.0.13", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.0.12", - "@alilc/lowcode-utils": "1.0.12", + "@alilc/lowcode-renderer-core": "1.0.13", + "@alilc/lowcode-utils": "1.0.13", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index 9b9a3a5887..4623c7ddb2 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.0.12", + "version": "1.0.13", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.0.12", - "@alilc/lowcode-rax-renderer": "1.0.12", - "@alilc/lowcode-types": "1.0.12", - "@alilc/lowcode-utils": "1.0.12", + "@alilc/lowcode-designer": "1.0.13", + "@alilc/lowcode-rax-renderer": "1.0.13", + "@alilc/lowcode-types": "1.0.13", + "@alilc/lowcode-utils": "1.0.13", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 5e31f9f2e5..85397e69b4 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.0.12", + "version": "1.0.13", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.0.12" + "@alilc/lowcode-renderer-core": "1.0.13" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index c3e7238fd2..0589fbf6c0 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.0.12", + "version": "1.0.13", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -16,10 +16,10 @@ "build:umd": "NODE_OPTIONS=--max_old_space_size=8192 build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.0.12", - "@alilc/lowcode-react-renderer": "1.0.12", - "@alilc/lowcode-types": "1.0.12", - "@alilc/lowcode-utils": "1.0.12", + "@alilc/lowcode-designer": "1.0.13", + "@alilc/lowcode-react-renderer": "1.0.13", + "@alilc/lowcode-types": "1.0.13", + "@alilc/lowcode-utils": "1.0.13", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index a660b09d23..3ec1413c3b 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.0.12", + "version": "1.0.13", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.0.12", - "@alilc/lowcode-utils": "1.0.12", + "@alilc/lowcode-types": "1.0.13", + "@alilc/lowcode-utils": "1.0.13", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -33,7 +33,7 @@ }, "devDependencies": { "@alib/build-scripts": "^0.1.18", - "@alilc/lowcode-designer": "1.0.12", + "@alilc/lowcode-designer": "1.0.13", "@alilc/lowcode-test-mate": "^1.0.1", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", diff --git a/packages/shell/package.json b/packages/shell/package.json index e783415009..be16ee4be4 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.0.12", + "version": "1.0.13", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.0.12", - "@alilc/lowcode-editor-core": "1.0.12", - "@alilc/lowcode-editor-skeleton": "1.0.12", - "@alilc/lowcode-types": "1.0.12", - "@alilc/lowcode-utils": "1.0.12", + "@alilc/lowcode-designer": "1.0.13", + "@alilc/lowcode-editor-core": "1.0.13", + "@alilc/lowcode-editor-skeleton": "1.0.13", + "@alilc/lowcode-types": "1.0.13", + "@alilc/lowcode-utils": "1.0.13", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index 34f41a6a22..390d5ba6cf 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.0.12", + "version": "1.0.13", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index c7bad384c8..d814e5d8eb 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.0.12", + "version": "1.0.13", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.0.12", + "@alilc/lowcode-types": "1.0.13", "lodash": "^4.17.21", "react": "^16", "zen-logger": "^1.1.0" From 912ee22180a424f63298c319c62fb481513af904 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Fri, 29 Jul 2022 14:50:12 +0800 Subject: [PATCH 093/823] fix: use the outer documentation url of unique key, fixes #868 --- .../src/transducers/addon-combine.ts | 16 ++++++++-------- packages/engine/src/engine-core.ts | 1 + 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/packages/editor-skeleton/src/transducers/addon-combine.ts b/packages/editor-skeleton/src/transducers/addon-combine.ts index afb9c6d5d7..8975e7efa0 100644 --- a/packages/editor-skeleton/src/transducers/addon-combine.ts +++ b/packages/editor-skeleton/src/transducers/addon-combine.ts @@ -141,13 +141,13 @@ export default function (metadata: TransformedComponentMetadata): TransformedCom }); */ const stylesGroup: FieldConfig[] = []; - const advanceGroup: FieldConfig[] = []; + const advancedGroup: FieldConfig[] = []; if (propsGroup) { let l = propsGroup.length; while (l-- > 0) { const item = propsGroup[l]; // if (item.type === 'group' && (item.title === '高级' || item.title?.label === '高级')) { - // advanceGroup = item.items || []; + // advancedGroup = item.items || []; // propsGroup.splice(l, 1); // } if ( @@ -236,7 +236,7 @@ export default function (metadata: TransformedComponentMetadata): TransformedCom if (!isRoot) { if (supports.condition !== false) { - advanceGroup.push({ + advancedGroup.push({ name: getConvertedExtraKey('condition'), title: { type: 'i18n', 'zh-CN': '是否渲染', 'en-US': 'Condition' }, defaultValue: true, @@ -254,7 +254,7 @@ export default function (metadata: TransformedComponentMetadata): TransformedCom }); } if (supports.loop !== false) { - advanceGroup.push({ + advancedGroup.push({ name: '#loop', title: { type: 'i18n', 'zh-CN': '循环', 'en-US': 'Loop' }, items: [ @@ -314,12 +314,12 @@ export default function (metadata: TransformedComponentMetadata): TransformedCom } if (supports.condition !== false || supports.loop !== false) { - advanceGroup.push({ + advancedGroup.push({ name: 'key', title: { label: '渲染唯一标识(key)', tip: '搭配「条件渲染」或「循环渲染」时使用,和 react 组件中的 key 原理相同,点击查看帮助', - docUrl: 'https://yuque.antfin-inc.com/legao/help3.0/ca5in7', + docUrl: 'https://lowcode-engine.cn/docV2/qm75w3', }, setter: [ { @@ -335,11 +335,11 @@ export default function (metadata: TransformedComponentMetadata): TransformedCom }); } } - if (advanceGroup.length > 0) { + if (advancedGroup.length > 0) { combined.push({ name: '#advanced', title: { type: 'i18n', 'zh-CN': '高级', 'en-US': 'Advanced' }, - items: advanceGroup, + items: advancedGroup, }); } diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index c8d3b49c44..6a5ab108c3 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -89,6 +89,7 @@ export const __SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED = { symbols, classes, }; +engineConfig.set('isOpenSource', isOpenSource); // 注册一批内置插件 (async function registerPlugins() { From 2432aed83d55407d2f8b5f94910ada7ea78bb59e Mon Sep 17 00:00:00 2001 From: zhangjinmei <1075487618@qq.com> Date: Thu, 4 Aug 2022 17:21:35 +0800 Subject: [PATCH 094/823] fix: delete unused typescript types --- packages/utils/src/asset.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/packages/utils/src/asset.ts b/packages/utils/src/asset.ts index bc06f29df1..b0ebd1ee50 100644 --- a/packages/utils/src/asset.ts +++ b/packages/utils/src/asset.ts @@ -1,10 +1,11 @@ -import { AssetItem, AssetType, AssetLevels, Asset, AssetList, AssetBundle, AssetLevel, AssetsJson } from '@alilc/lowcode-types'; +import { AssetType, AssetLevels, AssetLevel } from '@alilc/lowcode-types'; +import type { AssetItem, Asset, AssetList, AssetBundle, AssetsJson } from '@alilc/lowcode-types'; import { isCSSUrl } from './is-css-url'; import { createDefer } from './create-defer'; import { load, evaluate } from './script'; // API 向下兼容 -export { AssetItem, AssetType, AssetLevels, Asset, AssetList, AssetBundle, AssetLevel, AssetsJson } from '@alilc/lowcode-types'; +export { AssetType, AssetLevels, AssetLevel } from '@alilc/lowcode-types'; export function isAssetItem(obj: any): obj is AssetItem { return obj && obj.type; From 4d6dfe9f579e77651e58395474843e837061898b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=8F=8A=E8=90=8D=28=E7=B5=AE=E9=BB=8E=29?= Date: Thu, 4 Aug 2022 18:25:42 +0800 Subject: [PATCH 095/823] Revert "fix: delete unused typescript types" This reverts commit 2432aed83d55407d2f8b5f94910ada7ea78bb59e. --- packages/utils/src/asset.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/packages/utils/src/asset.ts b/packages/utils/src/asset.ts index b0ebd1ee50..bc06f29df1 100644 --- a/packages/utils/src/asset.ts +++ b/packages/utils/src/asset.ts @@ -1,11 +1,10 @@ -import { AssetType, AssetLevels, AssetLevel } from '@alilc/lowcode-types'; -import type { AssetItem, Asset, AssetList, AssetBundle, AssetsJson } from '@alilc/lowcode-types'; +import { AssetItem, AssetType, AssetLevels, Asset, AssetList, AssetBundle, AssetLevel, AssetsJson } from '@alilc/lowcode-types'; import { isCSSUrl } from './is-css-url'; import { createDefer } from './create-defer'; import { load, evaluate } from './script'; // API 向下兼容 -export { AssetType, AssetLevels, AssetLevel } from '@alilc/lowcode-types'; +export { AssetItem, AssetType, AssetLevels, Asset, AssetList, AssetBundle, AssetLevel, AssetsJson } from '@alilc/lowcode-types'; export function isAssetItem(obj: any): obj is AssetItem { return obj && obj.type; From 9a5a04ac9560fb6a51bf4e0ed8ea446381d39c35 Mon Sep 17 00:00:00 2001 From: liujuping Date: Thu, 4 Aug 2022 19:32:32 +0800 Subject: [PATCH 096/823] fix: fix css resources with parameters not loading correctly --- packages/utils/src/asset.ts | 4 +++- packages/utils/src/is-css-url.ts | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/packages/utils/src/asset.ts b/packages/utils/src/asset.ts index bc06f29df1..6396686eb5 100644 --- a/packages/utils/src/asset.ts +++ b/packages/utils/src/asset.ts @@ -4,12 +4,14 @@ import { createDefer } from './create-defer'; import { load, evaluate } from './script'; // API 向下兼容 -export { AssetItem, AssetType, AssetLevels, Asset, AssetList, AssetBundle, AssetLevel, AssetsJson } from '@alilc/lowcode-types'; +export { AssetType, AssetLevels, Asset, AssetList, AssetBundle, AssetLevel, AssetsJson } from '@alilc/lowcode-types'; export function isAssetItem(obj: any): obj is AssetItem { return obj && obj.type; } +export type { AssetItem } from '@alilc/lowcode-types'; + export function isAssetBundle(obj: any): obj is AssetBundle { return obj && obj.type === AssetType.Bundle; } diff --git a/packages/utils/src/is-css-url.ts b/packages/utils/src/is-css-url.ts index 1f900f18ce..af29604825 100644 --- a/packages/utils/src/is-css-url.ts +++ b/packages/utils/src/is-css-url.ts @@ -1,3 +1,3 @@ export function isCSSUrl(url: string): boolean { - return /\.css$/.test(url); + return /\.css(\?.*)?$/.test(url); } From 9c545cca6004f65e2f206ea001cefa3fa3cfa807 Mon Sep 17 00:00:00 2001 From: liujuping Date: Thu, 4 Aug 2022 17:58:24 +0800 Subject: [PATCH 097/823] fix: fix render module state expression initialization exception --- packages/react-simulator-renderer/src/renderer-view.tsx | 7 ++++++- packages/renderer-core/src/renderer/page.tsx | 7 +++---- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/packages/react-simulator-renderer/src/renderer-view.tsx b/packages/react-simulator-renderer/src/renderer-view.tsx index d978494c02..50c5481eea 100644 --- a/packages/react-simulator-renderer/src/renderer-view.tsx +++ b/packages/react-simulator-renderer/src/renderer-view.tsx @@ -4,7 +4,7 @@ import cn from 'classnames'; import { Node } from '@alilc/lowcode-designer'; import LowCodeRenderer from '@alilc/lowcode-react-renderer'; import { observer } from 'mobx-react'; -import { getClosestNode, isFromVC } from '@alilc/lowcode-utils'; +import { getClosestNode, isFromVC, isReactComponent } from '@alilc/lowcode-utils'; import { GlobalEvent } from '@alilc/lowcode-types'; import { SimulatorRendererContainer, DocumentInstance } from './renderer'; import { host } from './host'; @@ -241,6 +241,11 @@ class Renderer extends Component<{ }); } + if (!isReactComponent(Component)) { + console.error(`${viewProps._componentName} is not a react component!`); + return null; + } + return createElement( getDeviceView(Component, device, designMode), viewProps, diff --git a/packages/renderer-core/src/renderer/page.tsx b/packages/renderer-core/src/renderer/page.tsx index 17e3ef4c86..817b9b128f 100644 --- a/packages/renderer-core/src/renderer/page.tsx +++ b/packages/renderer-core/src/renderer/page.tsx @@ -20,10 +20,9 @@ export default function pageRendererFactory(): IBaseRenderComponent { async componentDidUpdate(prevProps: IBaseRendererProps, _prevState: {}, snapshot: unknown) { const { __ctx } = this.props; - const prevState = this.__parseData(prevProps.__schema.state, __ctx); - const newState = this.__parseData(this.props.__schema.state, __ctx); - // 当编排的时候修改schema.state值,需要将最新schema.state值setState - if (JSON.stringify(newState) != JSON.stringify(prevState)) { + // 当编排的时候修改schema.state值,需要将最新 schema.state 值 setState + if (JSON.stringify(prevProps.__schema.state) != JSON.stringify(this.props.__schema.state)) { + const newState = this.__parseData(this.props.__schema.state, __ctx); this.setState(newState); } From 573504b0e3537ca60d234ce2b2f3feedb323405e Mon Sep 17 00:00:00 2001 From: zhangjinmei <1075487618@qq.com> Date: Mon, 8 Aug 2022 12:49:21 +0800 Subject: [PATCH 098/823] fix: change typescript type export to export type --- packages/utils/src/asset.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/utils/src/asset.ts b/packages/utils/src/asset.ts index 6396686eb5..1548e24004 100644 --- a/packages/utils/src/asset.ts +++ b/packages/utils/src/asset.ts @@ -1,17 +1,17 @@ -import { AssetItem, AssetType, AssetLevels, Asset, AssetList, AssetBundle, AssetLevel, AssetsJson } from '@alilc/lowcode-types'; +import { AssetType, AssetLevels, AssetLevel } from '@alilc/lowcode-types'; +import type { AssetItem, Asset, AssetList, AssetBundle, AssetsJson } from '@alilc/lowcode-types'; import { isCSSUrl } from './is-css-url'; import { createDefer } from './create-defer'; import { load, evaluate } from './script'; // API 向下兼容 -export { AssetType, AssetLevels, Asset, AssetList, AssetBundle, AssetLevel, AssetsJson } from '@alilc/lowcode-types'; +export { AssetType, AssetLevels, AssetLevel } from '@alilc/lowcode-types'; +export type { AssetItem, Asset, AssetList, AssetBundle, AssetsJson } from '@alilc/lowcode-types'; export function isAssetItem(obj: any): obj is AssetItem { return obj && obj.type; } -export type { AssetItem } from '@alilc/lowcode-types'; - export function isAssetBundle(obj: any): obj is AssetBundle { return obj && obj.type === AssetType.Bundle; } From 7c8cd36a10a7caa61de31a15abd93ab8a97fbe08 Mon Sep 17 00:00:00 2001 From: zhangjinmei <1075487618@qq.com> Date: Mon, 8 Aug 2022 13:42:06 +0800 Subject: [PATCH 099/823] fix: in ES require changed to import --- packages/renderer-core/package.json | 1 + packages/renderer-core/src/utils/common.ts | 7 +++---- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 3ec1413c3b..bb1e4f313a 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -43,6 +43,7 @@ "@types/lodash": "^4.14.167", "@types/node": "^13.7.1", "@types/prop-types": "^15.7.3", + "@types/react-is": "^17.0.3", "@types/react-test-renderer": "^17.0.1", "babel-jest": "^26.5.2", "build-plugin-component": "^0.2.11", diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index d605589710..b4b0fc99e6 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -8,6 +8,9 @@ import 'moment/locale/zh-cn'; import { isEmpty } from 'lodash'; import IntlMessageFormat from 'intl-messageformat'; import pkg from '../../package.json'; +import * as ReactIs from 'react-is'; +import { default as ReactPropTypesSecret } from 'prop-types/lib/ReactPropTypesSecret'; +import { default as factoryWithTypeCheckers } from 'prop-types/factoryWithTypeCheckers'; export const moment = _moment; moment.locale('zh-cn'); @@ -15,10 +18,6 @@ moment.locale('zh-cn'); export { pick, isEqualWith as deepEqual, cloneDeep as clone, isEmpty, throttle, debounce } from 'lodash'; -const ReactIs = require('react-is'); -const ReactPropTypesSecret = require('prop-types/lib/ReactPropTypesSecret'); -const factoryWithTypeCheckers = require('prop-types/factoryWithTypeCheckers'); - const PropTypes2 = factoryWithTypeCheckers(ReactIs.isElement, true); const EXPRESSION_TYPE = { From c1bcb8f4d4566f58249411fc7059212d3e7b871b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Mon, 8 Aug 2022 16:50:44 +0800 Subject: [PATCH 100/823] test(selection & dragon): add some test cases for increasing code coverage rate --- .../bem-tools/drag-resize-engine.ts | 31 +---------- packages/designer/src/designer/dragon.ts | 38 ++++--------- packages/designer/src/document/selection.ts | 7 +-- packages/designer/src/utils/misc.ts | 25 +++++++++ .../bem-tools/drag-resize-engine.test.ts | 3 +- .../designer/tests/designer/detecting.test.ts | 4 ++ .../designer/tests/designer/dragon.test.ts | 53 +++++++++++++------ .../designer/tests/document/selection.test.ts | 42 ++++++++++++--- packages/designer/tests/utils-ut/misc.test.ts | 12 ++++- 9 files changed, 131 insertions(+), 84 deletions(-) diff --git a/packages/designer/src/builtin-simulator/bem-tools/drag-resize-engine.ts b/packages/designer/src/builtin-simulator/bem-tools/drag-resize-engine.ts index 68e1113577..d65e9b8afc 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/drag-resize-engine.ts +++ b/packages/designer/src/builtin-simulator/bem-tools/drag-resize-engine.ts @@ -2,35 +2,7 @@ import { EventEmitter } from 'events'; import { ISimulatorHost } from '../../simulator'; import { Designer, Point } from '../../designer'; import { cursor } from '@alilc/lowcode-utils'; -// import Cursor from './cursor'; -// import Pages from './pages'; - -function makeEventsHandler( - boostEvent: MouseEvent | DragEvent, - sensors: ISimulatorHost[], -): (fn: (sdoc: Document) => void) => void { - const topDoc = window.document; - const sourceDoc = boostEvent.view?.document || topDoc; - // TODO: optimize this logic, reduce listener - // const boostPrevented = boostEvent.defaultPrevented; - const docs = new Set(); - // if (boostPrevented || isDragEvent(boostEvent)) { - docs.add(topDoc); - // } - docs.add(sourceDoc); - // if (sourceDoc !== topDoc || isDragEvent(boostEvent)) { - sensors.forEach(sim => { - const sdoc = sim.contentDocument; - if (sdoc) { - docs.add(sdoc); - } - }); - // } - - return (handle: (sdoc: Document) => void) => { - docs.forEach(doc => handle(doc)); - }; -} +import { makeEventsHandler } from '../../utils/misc'; // 拖动缩放 export default class DragResizeEngine { @@ -73,6 +45,7 @@ export default class DragResizeEngine { const masterSensors = this.getMasterSensors(); + /* istanbul ignore next */ const createResizeEvent = (e: MouseEvent | DragEvent): Point => { const sourceDocument = e.view?.document; diff --git a/packages/designer/src/designer/dragon.ts b/packages/designer/src/designer/dragon.ts index 3f4a420f09..a74e36b98d 100644 --- a/packages/designer/src/designer/dragon.ts +++ b/packages/designer/src/designer/dragon.ts @@ -6,6 +6,7 @@ import { DropLocation } from './location'; import { Node, DocumentModel } from '../document'; import { ISimulatorHost, isSimulatorHost, NodeInstance, ComponentInstance } from '../simulator'; import { Designer } from './designer'; +import { makeEventsHandler } from '../utils/misc'; export interface LocateEvent { readonly type: 'LocateEvent'; @@ -135,7 +136,7 @@ export function isShaken(e1: MouseEvent | DragEvent, e2: MouseEvent | DragEvent) ); } -function isInvalidPoint(e: any, last: any): boolean { +export function isInvalidPoint(e: any, last: any): boolean { return ( e.clientX === 0 && e.clientY === 0 && @@ -144,7 +145,7 @@ function isInvalidPoint(e: any, last: any): boolean { ); } -function isSameAs(e1: MouseEvent | DragEvent, e2: MouseEvent | DragEvent): boolean { +export function isSameAs(e1: MouseEvent | DragEvent, e2: MouseEvent | DragEvent): boolean { return e1.clientY === e2.clientY && e1.clientX === e2.clientX; } @@ -159,31 +160,6 @@ function getSourceSensor(dragObject: DragObject): ISimulatorHost | null { return dragObject.nodes[0]?.document.simulator || null; } -/** - * make a handler that listen all sensors:document, avoid frame lost - */ -function makeEventsHandler( - boostEvent: MouseEvent | DragEvent, - sensors: ISimulatorHost[], -): (fn: (sdoc: Document) => void) => void { - const topDoc = window.document; - const sourceDoc = boostEvent.view?.document || topDoc; - // TODO: optimize this logic, reduce listener - const docs = new Set(); - docs.add(topDoc); - docs.add(sourceDoc); - sensors.forEach((sim) => { - const sdoc = sim.contentDocument; - if (sdoc) { - docs.add(sdoc); - } - }); - - return (handle: (sdoc: Document) => void) => { - docs.forEach((doc) => handle(doc)); - }; -} - function isDragEvent(e: any): e is DragEvent { return e?.type?.startsWith('drag'); } @@ -325,6 +301,7 @@ export class Dragon { const locateEvent = createLocateEvent(e); const sensor = chooseSensor(locateEvent); + /* istanbul ignore next */ if (isRGL) { // 禁止被拖拽元素的阻断 const nodeInst = dragObject.nodes[0].getDOMNode(); @@ -429,6 +406,7 @@ export class Dragon { // 发送drop事件 if (e) { const { isRGL, rglNode } = getRGL(e); + /* istanbul ignore next */ if (isRGL && this._canDrop) { const tarNode = dragObject.nodes[0]; if (rglNode.id !== tarNode.id) { @@ -468,7 +446,7 @@ export class Dragon { this._dragging = false; try { this.emitter.emit('dragend', { dragObject, copy }); - } catch (ex) { + } catch (ex) /* istanbul ignore next */ { exception = ex; } } @@ -489,6 +467,7 @@ export class Dragon { doc.removeEventListener('keydown', checkcopy, false); doc.removeEventListener('keyup', checkcopy, false); }); + /* istanbul ignore next */ if (exception) { throw exception; } @@ -509,7 +488,7 @@ export class Dragon { if (!sourceDocument || sourceDocument === document) { evt.globalX = e.clientX; evt.globalY = e.clientY; - } /* istanbul ignore next */ else { + } else /* istanbul ignore next */ { // event from simulator sandbox let srcSim: ISimulatorHost | undefined; const lastSim = lastSensor && isSimulatorHost(lastSensor) ? lastSensor : null; @@ -616,6 +595,7 @@ export class Dragon { } } + /* istanbul ignore next */ private getMasterSensors(): ISimulatorHost[] { return Array.from( new Set( diff --git a/packages/designer/src/document/selection.ts b/packages/designer/src/document/selection.ts index 4a7ad72cd5..bc012a8994 100644 --- a/packages/designer/src/document/selection.ts +++ b/packages/designer/src/document/selection.ts @@ -147,10 +147,11 @@ export class Selection { if (n === PositionNO.Contains || n === PositionNO.TheSame) { isTop = false; break; - } - // node contains nodes[i], delete nodes[i] - if (n === PositionNO.ContainedBy) { + } else if (n === PositionNO.ContainedBy) { + // node contains nodes[i], delete nodes[i] nodes.splice(i, 1); + } else { + isTop = false; } } // node is top item, push to nodes diff --git a/packages/designer/src/utils/misc.ts b/packages/designer/src/utils/misc.ts index 7b999f5ff7..3fab1c823e 100644 --- a/packages/designer/src/utils/misc.ts +++ b/packages/designer/src/utils/misc.ts @@ -1,4 +1,5 @@ import Viewport from '../builtin-simulator/viewport'; +import { ISimulatorHost } from '../simulator'; export function isElementNode(domNode: Element) { return domNode.nodeType === Node.ELEMENT_NODE; @@ -28,4 +29,28 @@ export function isDOMNodeVisible(domNode: Element, viewport: Viewport) { */ export function normalizeTriggers(triggers: string[]) { return triggers.map((trigger: string) => trigger?.toUpperCase()); +} + +/** + * make a handler that listen all sensors:document, avoid frame lost + */ + export function makeEventsHandler( + boostEvent: MouseEvent | DragEvent, + sensors: ISimulatorHost[], +): (fn: (sdoc: Document) => void) => void { + const topDoc = window.document; + const sourceDoc = boostEvent.view?.document || topDoc; + const docs = new Set(); + docs.add(topDoc); + docs.add(sourceDoc); + sensors.forEach((sim) => { + const sdoc = sim.contentDocument; + if (sdoc) { + docs.add(sdoc); + } + }); + + return (handle: (sdoc: Document) => void) => { + docs.forEach((doc) => handle(doc)); + }; } \ No newline at end of file diff --git a/packages/designer/tests/builtin-simulator/bem-tools/drag-resize-engine.test.ts b/packages/designer/tests/builtin-simulator/bem-tools/drag-resize-engine.test.ts index 4ce31cebee..1506e86adc 100644 --- a/packages/designer/tests/builtin-simulator/bem-tools/drag-resize-engine.test.ts +++ b/packages/designer/tests/builtin-simulator/bem-tools/drag-resize-engine.test.ts @@ -57,7 +57,8 @@ describe('DragResizeEngine 测试', () => { }); // do nothing - resizeEngine.from(); + const noop = resizeEngine.from(); + noop(); const offFrom = resizeEngine.from(document, 'e', mockedBoostFn); diff --git a/packages/designer/tests/designer/detecting.test.ts b/packages/designer/tests/designer/detecting.test.ts index e67e3b8070..7cc4c88e8c 100644 --- a/packages/designer/tests/designer/detecting.test.ts +++ b/packages/designer/tests/designer/detecting.test.ts @@ -1,14 +1,18 @@ import { Detecting } from '../../src/designer/detecting'; it('Detecting 测试', () => { + const fn = jest.fn(); const detecting = new Detecting(); + detecting.onDetectingChange(fn); expect(detecting.enable).toBeTruthy(); const mockNode = { document }; detecting.capture(mockNode); + expect(fn).toHaveBeenCalledWith(detecting.current); expect(detecting.current).toBe(mockNode); + detecting.release({}); detecting.release(mockNode); expect(detecting.current).toBeNull(); diff --git a/packages/designer/tests/designer/dragon.test.ts b/packages/designer/tests/designer/dragon.test.ts index b5ab55b568..9e17462ecd 100644 --- a/packages/designer/tests/designer/dragon.test.ts +++ b/packages/designer/tests/designer/dragon.test.ts @@ -3,16 +3,6 @@ import { set } from '../utils'; import { Editor, globalContext } from '@alilc/lowcode-editor-core'; import { Project } from '../../src/project/project'; import { DocumentModel } from '../../src/document/document-model'; -import { - isRootNode, - Node, - isNode, - comparePosition, - contains, - insertChild, - insertChildren, - PositionNO, -} from '../../src/document/node/node'; import { Designer } from '../../src/designer/designer'; import { Dragon, @@ -23,12 +13,10 @@ import { DragObjectType, isShaken, setShaken, + isInvalidPoint, + isSameAs, } from '../../src/designer/dragon'; import formSchema from '../fixtures/schema/form'; -import divMetadata from '../fixtures/component-metadata/div'; -import formMetadata from '../fixtures/component-metadata/form'; -import otherMeta from '../fixtures/component-metadata/other'; -import pageMetadata from '../fixtures/component-metadata/page'; import { fireEvent } from '@testing-library/react'; describe('Dragon 测试', () => { @@ -273,9 +261,32 @@ describe('Dragon 测试', () => { }); it('addSensor / removeSensor', () => { - const sensor = {}; + const sensor = { + locate: () => {}, + sensorAvailable: true, + isEnter: () => true, + fixEvent: () => {}, + deactiveSensor: () => {}, + }; + const sensor2 = {}; dragon.addSensor(sensor); expect(dragon.sensors.length).toBe(1); + expect(dragon.activeSensor).toBeUndefined(); + dragon.boost( + { + type: DragObjectType.NodeData, + data: [{ componentName: 'Button' }], + }, + new MouseEvent('mousedown', { clientX: 100, clientY: 100 }), + ); + + fireEvent.mouseMove(document, { clientX: 108, clientY: 108 }); + fireEvent.mouseMove(document, { clientX: 110, clientY: 110 }); + fireEvent.mouseUp(document, { clientX: 118, clientY: 118 }); + expect(dragon.activeSensor).toBe(sensor); + // remove a non-existing sensor + dragon.removeSensor(sensor2); + expect(dragon.sensors.length).toBe(1); dragon.removeSensor(sensor); expect(dragon.sensors.length).toBe(0); }); @@ -343,4 +354,16 @@ describe('导出的其他函数', () => { setShaken(e); expect(isShaken(e)).toBeTruthy(); }); + + it('isInvalidPoint', () => { + expect(isInvalidPoint({ clientX: 0, clientY: 0 }, { clientX: 6, clientY: 1 })).toBeTruthy(); + expect(isInvalidPoint({ clientX: 0, clientY: 0 }, { clientX: 1, clientY: 6 })).toBeTruthy(); + expect(isInvalidPoint({ clientX: 0, clientY: 0 }, { clientX: 6, clientY: 6 })).toBeTruthy(); + expect(isInvalidPoint({ clientX: 1, clientY: 1 }, { clientX: 2, clientY: 1 })).toBeFalsy(); + }); + + it('isSameAs', () => { + expect(isSameAs({ clientX: 1, clientY: 1 }, { clientX: 1, clientY: 1 })).toBeTruthy(); + expect(isSameAs({ clientX: 1, clientY: 1 }, { clientX: 2, clientY: 1 })).toBeFalsy(); + }); }); diff --git a/packages/designer/tests/document/selection.test.ts b/packages/designer/tests/document/selection.test.ts index dec871941f..630faa95e6 100644 --- a/packages/designer/tests/document/selection.test.ts +++ b/packages/designer/tests/document/selection.test.ts @@ -67,6 +67,7 @@ describe('选择区测试', () => { expect(selection.selected).toEqual(['node_k1ow3cbj', 'form']); selectionChangeHandler.mockClear(); + selection.remove('node_k1ow3cbj_fake'); selection.remove('node_k1ow3cbj'); expect(selectionChangeHandler).toHaveBeenCalledTimes(1); expect(selectionChangeHandler.mock.calls[0][0]).toEqual(['form']); @@ -141,7 +142,7 @@ describe('选择区测试', () => { selectionChangeHandler.mockClear(); }); - it('dispose 方法', () => { + it('dispose 方法 - 选中的节点没有被删除的', () => { const project = new Project(designer, { componentsTree: [ formSchema, @@ -152,16 +153,13 @@ describe('选择区测试', () => { const { currentDocument } = project; const { nodesMap, selection } = currentDocument!; - selection.selectAll(['form', 'node_k1ow3cbj', 'form2']); + selection.selectAll(['form', 'node_k1ow3cbj']); const selectionChangeHandler = jest.fn(); selection.onSelectionChange(selectionChangeHandler); selection.dispose(); - expect(selectionChangeHandler).toHaveBeenCalledTimes(1); - expect(selectionChangeHandler.mock.calls[0][0]).toEqual(['form', 'node_k1ow3cbj']); - expect(selection.selected).toEqual(['form', 'node_k1ow3cbj']); - selectionChangeHandler.mockClear(); + expect(selectionChangeHandler).not.toHaveBeenCalled(); }); it('containsNode 方法', () => { @@ -242,4 +240,36 @@ describe('选择区测试', () => { expect(selection.selected).toEqual(['page']); selectionChangeHandler.mockClear(); }); + + it('getNodes', () => { + const project = new Project(designer, { + componentsTree: [ + formSchema, + ], + }); + project.open(); + const { currentDocument } = project; + const { selection } = currentDocument!; + + selection.selectAll(['form', 'node_k1ow3cbj', 'form2']); + + // form2 is not a valid node + expect(selection.getNodes()).toHaveLength(2); + }); + + it('getTopNodes', () => { + const project = new Project(designer, { + componentsTree: [ + formSchema, + ], + }); + project.open(); + const { currentDocument } = project; + const { selection } = currentDocument!; + + selection.selectAll(['node_k1ow3cbj', 'node_k1ow3cbo', 'form', 'node_k1ow3cbl', 'form2']); + + // form2 is not a valid node, and node_k1ow3cbj is a child node of form + expect(selection.getTopNodes()).toHaveLength(1); + }); }); diff --git a/packages/designer/tests/utils-ut/misc.test.ts b/packages/designer/tests/utils-ut/misc.test.ts index dc3dcd6bbb..245d76e70e 100644 --- a/packages/designer/tests/utils-ut/misc.test.ts +++ b/packages/designer/tests/utils-ut/misc.test.ts @@ -1,5 +1,5 @@ // @ts-nocheck -import { isElementNode, isDOMNodeVisible, normalizeTriggers } from '../../src/utils/misc'; +import { isElementNode, isDOMNodeVisible, normalizeTriggers, makeEventsHandler } from '../../src/utils/misc'; it('isElementNode', () => { expect(isElementNode(document.createElement('div'))).toBeTruthy(); @@ -152,3 +152,13 @@ describe('isDOMNodeVisible', () => { it('normalizeTriggers', () => { expect(normalizeTriggers(['n', 'w'])).toEqual(['N', 'W']); }); + +it('makeEventsHandler', () => { + const sensor = { contentDocument: document }; + // no contentDocument + const sensor2 = {}; + const bind = makeEventsHandler({ view: { document } } as any, [sensor, sensor2]); + const fn = jest.fn(); + bind((doc) => fn(doc)); + expect(fn).toHaveBeenCalledTimes(1); +}); From 57df803179ca9cec4e8ab1dac1be577175732e65 Mon Sep 17 00:00:00 2001 From: liujuping Date: Mon, 8 Aug 2022 17:30:37 +0800 Subject: [PATCH 101/823] feat: added lowcode engine standard specs --- specs/assets-spec.md | 687 +++++++++++++++ specs/lowcode-spec.md | 1462 ++++++++++++++++++++++++++++++++ specs/material-spec.md | 1821 ++++++++++++++++++++++++++++++++++++++++ 3 files changed, 3970 insertions(+) create mode 100644 specs/assets-spec.md create mode 100644 specs/lowcode-spec.md create mode 100644 specs/material-spec.md diff --git a/specs/assets-spec.md b/specs/assets-spec.md new file mode 100644 index 0000000000..ab0e1abc02 --- /dev/null +++ b/specs/assets-spec.md @@ -0,0 +1,687 @@ +# 《低代码引擎资产包协议规范》 + +# 1 介绍 + +## 1.1 本协议规范涉及的问题域 + +- 定义本协议版本号规范 +- 定义本协议中每个子规范需要被支持的 Level +- 定义本协议相关的领域名词 +- 定义低代码资产包协议版本号规范(A) +- 定义低代码资产包协议组件及依赖资源描述规范(A) +- 定义低代码资产包协议组件描述资源加载规范(A) +- 定义低代码资产包协议组件在面板展示规范(AA) + +## 1.2 协议草案起草人 + +- 撰写:金禅、璿玑、彼洋 +- 审阅:力皓、絮黎、光弘、戊子、潕量、游鹿 + +## 1.3 版本号 + +1.1.0 + +## 1.4 协议版本号规范(A) + +本协议采用语义版本号,版本号格式为 `major.minor.patch` 的形式。 + +- major 是大版本号:用于发布不向下兼容的协议格式修改 +- minor 是小版本号:用于发布向下兼容的协议功能新增 +- patch 是补丁号:用于发布向下兼容的协议问题修正 + +## 1.5 协议中子规范 Level 定义 + +| 规范等级 | 实现要求 | +| -------- | ------------------------------------------------------------ | +| A | 基础规范,低代码引擎核心层支持; | +| AA | 推荐规范,由低代码引擎官方插件、setter 支持。 | +| AAA | 参考规范,需由基于引擎的上层搭建平台支持,实现可参考该规范。 | + +## 1.6 名词术语 + +- **资产包**: 低代码引擎加载资源的动态数据集合,主要包含组件及其依赖的资源、组件低代码描述、动态插件/设置器资源等。 + +## 1.7 背景 + +根据低代码引擎的实现,一个组件要在引擎上渲染和配置,需要提供组件的 umd 资源以及组件的`低代码描述`,并且组件通常都是以集合的形式被引擎消费的;除了组件之外,还有组件的依赖资源、引擎的动态插件/设置器等资源也需要注册到引擎中;因此我们定义了“低代码资产包”这个数据结构,来描述引擎所需加载的动态资源的集合。 + +## 1.8 受众 + +本协议适用于使用“低代码引擎”构建搭建平台的开发者,通过本协议的定义来进行资源的分类和加载。阅读及使用本协议,需要对低代码搭建平台的交互和实现有一定的了解,对前端开发相关技术栈的熟悉也会有帮助,协议中对通用的前端相关术语不会做进一步的解释说明。 + +# 2 协议结构 + +协议最顶层结构如下,包含 7 方面的描述内容: + +- version { String } 当前协议版本号 +- packages { Array } 低代码编辑器中加载的资源列表 +- components { Array } 所有组件的描述协议列表 +- sort { Object } 用于描述组件面板中的 tab 和 category +- plugins { Array } 设计器插件描述协议列表 +- setters { Array } 设计器中设置器描述协议列表 +- extConfig { Object } 平台自定义扩展字段 + +## 2.1 version(A) + +定义当前协议 schema 的版本号; + +| 根属性名称 | 类型 | 说明 | 变量支持 | 默认值 | +| ---------- | ------ | ---------- | -------- | ------ | +| version | String | 协议版本号 | - | 1.1.0 | + +## 2.2 packages(A) + +定义低代码编辑器中加载的资源列表,包含公共库和组件(库) cdn 资源等; + +| 字段 | 字段描述 | 字段类型 | 规范等级 | 备注 | +| -------------------- | --------------------------------------------------------------- | ------------- | -------- | -------------------------------------------------------------------------------------------------------- | +| packages[].id? | 资源唯一标识 | String | A | 资源唯一标识,如果为空,则以 package 为唯一标识 | +| packages[].title? | 资源标题 | String | A | 资源标题 | +| packages[].package | npm 包名 | String | A | 组件资源唯一标识 | +| packages[].version | npm 包版本号 | String | A | 组件资源版本号 | +| packages[].type | 资源包类型 | String | AA | 取值为: proCode(源码)、lowCode(低代码,默认为 proCode | +| packages[].schema | 低代码组件 schema 内容 | object | AA | 取值为: proCode(源码)、lowCode(低代码) | +| packages[].deps | 当前资源包的依赖资源的唯一标识列表 | Array | A | 唯一标识为 id 或者 package 对应的值 | +| packages[].library | 作为全局变量引用时的名称,用来定义全局变量名 | String | A | 低代码引擎通过该字段获取组件实例 | +| packages[].editUrls | 组件编辑态视图打包后的 CDN url 列表,包含 js 和 css | Array | A | 低代码引擎编辑器会加载这些 url | +| packages[].urls | 组件渲染态视图打包后的 CDN url 列表,包含 js 和 css | Array | AA | 低代码引擎渲染模块会加载这些 url | +| packages[].advancedEditUrls | 组件多个编辑态视图打包后的 CDN url 列表集合,包含 js 和 css | Object | AAA | 上层平台根据特定标识提取某个编辑态的资源,低代码引擎编辑器会加载这些资源,优先级高于 packages[].editUrls | +| packages[].advancedUrls | 组件多个端的渲染态视图打包后的 CDN url 列表集合,包含 js 和 css | Object | AAA | 上层平台根据特定标识提取某个渲染态的资源, 低代码引擎渲染模块会加载这些资源,优先级高于 packages[].urls | +| packages[].external | 当前资源在作为其他资源的依赖,在其他依赖打包时时是否被排除了(同 webpack 中 external 概念) | Boolean | AAA | 某些资源会被单独提取出来,是其他依赖的前置依赖,根据这个字段决定是否提前加载该资源 | +| packages[].loadEnv | 指定当前资源加载的环境 | Array | AAA | 主要用于指定 external 资源加载的环境,取值为 design(设计态)、runtime(预览态)中的一个或多个 | +| packages[].exportSourceId | 标识当前 package 内容是从哪个 package 导出来的 | String | AAA | 此时 urls 无效 | +| packages[].exportSourceLibrary | 标识当前 package 是从 window 上的哪个属性导出来的 | String | AAA | exportSourceId 的优先级高于exportSourceLibrary ,此时 urls 无效 | +| packages[].async | 标识当前 package 资源加载在 window.library 上的是否是一个异步对象 | Boolean | A | async 为 true 时,需要通过 await 才能拿到真正内容 | +| packages[].exportMode | 标识当前 package 从其他 package 的导出方式 | String | A | 目前只支持 `"functionCall"`, exportMode等于 `"functionCall"` 时,当前package 的内容以函数的方式从其他 package 中导出,具体导出接口如: (library: string, packageName: string, isRuntime?: boolean) => any | Promise, library 为当前 package 的 library, packageName 为当前的包名,返回值为当前 package 的导出内容 | + +描述举例: + +```json +{ + "packages": [ + { + "title": "fusion 组件库", + "package": "@alifd/next", + "version": "1.23.0", + "urls": [ + "https://g.alicdn.com/code/lib/alifd__next/1.23.18/next.min.css", + "https://g.alicdn.com/code/lib/alifd__next/1.23.18/next-with-locales.min.js" + ], + "library": "Next" + }, + { + "title": "Fusion 精品组件库", + "package": "@alife/fusion-ui", + "version": "0.1.5", + "editUrls": [ + "https://g.alicdn.com/code/npm/@alife/fusion-ui/0.1.7/build/lowcode/view.js", + "https://g.alicdn.com/code/npm/@alife/fusion-ui/0.1.7/build/lowcode/view.css" + ], + "urls": [ + "https://g.alicdn.com/code/npm/@alife/fusion-ui/0.1.7/dist/FusionUI.js", + "https://g.alicdn.com/code/npm/@alife/fusion-ui/0.1.7/dist/FusionUI.css" + ], + "library": "FusionUI" + }, + { + "title": "低代码组件 A", + "id": "lcc-a", + "version": "0.1.5", + "type": "lowCode", + "schema": { + "componentsMap": [ + { + "package": "@ali/vc-text", + "componentName": "Text", + "version": "4.1.1" + } + ], + "utils": [ + { + "name": "dataSource", + "type": "npm", + "content": { + "package": "@ali/vu-dataSource", + "exportName": "dataSource", + "version": "1.0.4" + } + } + ], + "componentsTree": [ + { + "defaultProps": { + "content": "这是默认值" + }, + "methods": { + "__initMethods__": { + "compiled": "function (exports, module) { /*set actions code here*/ }", + "source": "function (exports, module) { /*set actions code here*/ }", + "type": "js" + } + }, + "loopArgs": ["item", "index"], + "props": { + "mobileSlot": { + "type": "JSBlock", + "value": { + "children": [ + { + "condition": true, + "hidden": false, + "isLocked": false, + "conditionGroup": "", + "componentName": "Text", + "id": "node_ockxiczf4m2", + "title": "", + "props": { + "maxLine": 0, + "showTitle": false, + "behavior": "NORMAL", + "content": { + "en-US": "Title", + "zh-CN": "页面标题", + "type": "i18n" + }, + "__style__": {}, + "fieldId": "text_kxiczgj4" + } + } + ], + "componentName": "Slot", + "props": { + "slotName": "mobileSlot", + "slotTitle": "mobile 容器" + } + } + }, + "className": "component_k8e4naln", + "useDevice": false, + "fieldId": "symbol_k8bnubw4" + }, + "condition": true, + "children": [ + { + "condition": true, + "loopArgs": [null, null], + "componentName": "Text", + "id": "node_ockxiczf4m4", + "props": { + "maxLine": 0, + "showTitle": false, + "behavior": "NORMAL", + "content": { + "variable": "props.content", + "type": "variable", + "value": { + "use": "zh-CN", + "en-US": "Tips content", + "zh-CN": "这是一个低代码组件", + "type": "i18n" + } + }, + "fieldId": "text_kxid1d9n" + } + } + ], + "propTypes": [ + { + "defaultValue": "这是默认值", + "name": "content", + "title": "文本内容", + "type": "string" + } + ], + "componentName": "Component", + "id": "node_k8bnubvz", + "state": {} + } + ] + }, + "library": "LCCA" + }, + { + "title": "多端组件库", + "package": "@ali/atest1", + "version": "1.23.0", + "advancedUrls": { + "default": [ + "https://g.alicdn.com/legao-comp/web_bundle_0724/@alife/theme-254/1.24.0/@ali/atest1/1.0.0/theme.7c897c2.css", + "https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/atest1/1.0.0/main.3354663.js" + ], + "mobile": [ + "https://g.alicdn.com/legao-comp/web_bundle_0724/@alife/theme-254/1.24.0/@ali/atest1/1.0.0/theme.7c897c2.css", + "https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/atest1/1.0.0/main.mobile.3354663.js" + ], + "rax": [ + "https://g.alicdn.com/legao-comp/web_bundle_0724/@alife/theme-254/1.24.0/@ali/atest1/1.0.0/theme.7c897c2.css", + "https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/atest1/1.0.0/main.rax.3354663.js" + ] + }, + "advancedEditUrls": { + "design": [ + "https://g.alicdn.com/legao-comp/web_bundle_0724/@alife/theme-254/1.24.0/@ali/atest1/1.0.0/theme.7c897c2.css", + "https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/atest1/1.0.0/editView.design.js" + ], + "default": [ + "https://g.alicdn.com/legao-comp/web_bundle_0724/@alife/theme-254/1.24.0/@ali/atest1/1.0.0/theme.7c897c2.css", + "https://g.alicdn.com/legao-comp/web_bundle_0724/@ali/atest1/1.0.0/editView.js" + ] + }, + "library": "Atest1" + }, + { + "library":"UiPaaSServerless3", + "advancedUrls":{ + "default":[ + "https://g.alicdn.com/legao-comp/serverless3/1.1.0/env-staging-d224466e-0614-497d-8cd5-e4036dc50b70/main.js" + ] + }, + "id":"UiPaaSServerless3-view", + "type":"procode", + "version":"1.0.0" + }, + { + "package":"react-color", + "library":"ReactColor", + "id":"react-color", + "type":"procode", + "version":"2.19.3", + "async":true, + "exportMode":"functionCall", + "exportSourceId":"UiPaaSServerless3-view" + } + ] +} +``` + +## 2.3 components (A) + +定义资产包中包含的所有组件的低代码描述的集合,分为“ComponentDescription”和“RemoteComponentDescription”(详见 2.6 TypeScript 定义): + +- ComponentDescription: 符合“组件描述协议”的数据,详见物料规范中`2.2.2 组件描述协议`部分; +- RemoteComponentDescription 是将一个或多个 ComponentDescription 构建打包的 js 资源的描述,在浏览器中加载该资源后可获取到其中包含的每个组件的 ComponentDescription 的具体内容; + +## 2.4 sort (AA) + +定义组件列表分组 + +| 根属性名称 | 类型 | 说明 | 变量支持 | 默认值 | +| ----------------- | -------- | -------------------------------------------------------------------------------------------- | -------- | ---------------------------------------- | +| sort.groupList | String[] | 组件分组,用于组件面板 tab 展示 | - | ['精选组件', '原子组件'] | +| sort.categoryList | String[] | 组件面板中同一个 tab 下的不同区间用 category 区分,category 的排序依照 categoryList 顺序排列 | - | ['通用', '数据展示', '表格类', '表单类'] | + +## 2.5 plugins (AAA) + +自定义设计器插件列表 + +| 根属性名称 | 类型 | 说明 | 变量支持 | 默认值 | +| --------------------- | --------- | -------------------- | -------- | ------ | +| plugins[].name | String | 插件名称 | - | - | +| plugins[].title | String | 插件标题 | - | - | +| plugins[].description | String | 插件描述 | - | - | +| plugins[].docUrl | String | 插件文档地址 | - | - | +| plugins[].screenshot | String | 插件截图地址 | - | - | +| plugins[].tags | String[] | 插件标签分类 | - | - | +| plugins[].keywords | String[] | 插件检索关键字 | - | - | +| plugins[].reference | Reference | 插件引用的资源包信息 | - | - | + +## 2.6 setters (AAA) + +自定义设置器列表 + +| 根属性名称 | 类型 | 说明 | 变量支持 | 默认值 | +| --------------------- | --------- | ---------------------- | -------- | ------ | +| setters[].name | String | 设置器组件名称 | - | - | +| setters[].title | String | 设置器标题 | - | - | +| setters[].description | String | 设置器描述 | - | - | +| setters[].docUrl | String | 设置器文档地址 | - | - | +| setters[].screenshot | String | 设置器截图地址 | - | - | +| setters[].tags | String[] | 设置器标签分类 | - | - | +| setters[].keywords | String[] | 设置器检索关键字 | - | - | +| setters[].reference | Reference | 设置器引用的资源包信息 | - | - | + +## 2.7 extConfig (AAA) + +定义平台相关的扩展内容,用于存放平台自身实现的一些私有协议, 以允许存量平台能够平滑地迁移至标准协议。 extConfig 是一个 key-value 结构的对象,协议不会规定 extConfig 中的字段名称以及类型, 完全自定义 + +## 2.8 TypeScript 定义 + +_组件低代码描述相关部分字段含义详见物料规范中`2.2.2 组件描述协议`部分;_ + +```TypeScript + +/** + * 资产包协议 + */ +export interface Assets { + /** + * 资产包协议版本号 + */ + version: string; + /** + * 资源列表 + */ + packages?: Array; + /** + * 所有组件的描述协议集合 + */ + components: Array; + /** + * 低代码编辑器插件集合 + */ + plugins?: Array; + /** + * 低代码设置器集合 + */ + setters?: Array; + /** + * 平台扩展配置 + */ + extConfig?: AssetsExtConfig; + /** + * 用于描述组件面板中的 tab 和 category + */ + sort: ComponentSort; +} + +export interface AssetsExtConfig{ + [index: string]: any; +} + +/** + * 描述组件面板中的 tab 和 category 排布 + */ +export interface ComponentSort { + /** + * 用于描述组件面板的 tab 项及其排序,例如:["精选组件", "原子组件"] + */ + groupList?: String[]; + /** + * 组件面板中同一个 tab 下的不同区间用 category 区分,category 的排序依照 categoryList 顺序排列; + */ + categoryList?: String[]; +} + +/** + * 定义资产包依赖信息 + */ +export interface Package { + /** + * 唯一标识 + */ + id: string; + /** + * 包名 + */ + package: string; + /** + * 包版本号 + */ + version: string; + /** + * 资源类型 + */ + type: string; + /** + * 组件渲染态视图打包后的 CDN url 列表,包含 js 和 css + */ + urls?: string[] | any; + /** + * 组件多个渲染态视图打包后的 CDN url 列表,包含 js 和 css,优先级高于 urls + */ + advancedUrls?: ComplexUrls; + /** + * 组件编辑态视图打包后的 CDN url 列表,包含 js 和 css + */ + editUrls?: string[] | any; + /** + * 组件多个编辑态视图打包后的 CDN url 列表,包含 js 和 css,优先级高于 editUrls + */ + advancedEditUrls?: ComplexUrls; + /** + * 低代码组件的 schema 内容 + */ + schema?: ComponentSchema; + /** + * 当前资源所依赖的其他资源包的 id 列表 + */ + deps?: string[]; + /** + * 指定当前资源加载的环境 + */ + loadEnv?: LoadEnv[]; + /** + * 当前资源是否是 external 资源 + */ + external?: boolean; + /** + * 作为全局变量引用时的名称,和 webpack output.library 字段含义一样,用来定义全局变量名 + */ + library: string; + /** + * 组件描述导出名字,可以通过 window[exportName] 获取到组件描述的 Object 内容; + */ + exportName?: string; + /** + * 标识当前 package 资源加载在 window.library 上的是否是一个异步对象 + */ + async?: boolean; + /** + * 标识当前 package 从其他 package 的导出方式 + */ + exportMode?: string; + /** + * 标识当前 package 内容是从哪个 package 导出来的 + */ + exportSourceId?: string; + /** + * 标识当前 package 是从 window 上的哪个属性导出来的 + */ + exportSourceLibrary?: string; +} + + +/** + * 复杂 urls 结构,同时兼容简单结构和多模态结构 + */ +export type ComplexUrls = string[] | MultiModeUrls; + +/** + * 多模态资源 + */ +export interface MultiModeUrls { + /** + * 默认的资源 url + */ + default: string[]; + /** + * 其他模态资源的 url + */ + [index: string]: string[]; +} + + +/** + * 资源加载环境种类 + */ +export enum LoadEnv { + /** + * 设计态 + */ + design = "design", + /** + * 运行态 + */ + runtime = "runtime" +} + +/** + * 低代码设置器描述 + */ +export type SetterDescription = PluginDescription; + +/** + * 低代码插件器描述 + */ +export interface PluginDescription { + /** + * 插件名称 + */ + name: string; + /** + * 插件标题 + */ + title: string; + /** + * 插件类型 + */ + type?: string; + /** + * 插件描述 + */ + description?: string; + /** + * 插件文档地址 + */ + docUrl: string; + /** + * 插件截图 + */ + screenshot: string; + /** + * 插件相关的标签 + */ + tags?: string[]; + /** + * 插件关键字 + */ + keywords?: string[]; + /** + * 插件引用的资源信息 + */ + reference: Reference; +} + +/** + * 资源引用信息,Npm 的升级版本, + */ +export interface Reference { + /** + * 引用资源的 id 标识 + */ + id?: string; + /** + * 引用资源的包名 + */ + package?: string; + /** + * 引用资源的导出对象中的属性值名称 + */ + exportName: string; + /** + * 引用 exportName 上的子对象 + */ + subName: string; + /** + * 引用的资源主入口 + */ + main?: string; + /** + * 是否从引用资源的导出对象中获取属性值 + */ + destructuring: boolean; + /** + * 资源版本号 + */ + version: string; +} + + +/** + * 低代码片段 + * + * 内容为组件不同状态下的低代码 schema (可以有多个),用户从组件面板拖入组件到设计器时会向页面 schema 中插入 snippets 中定义的组件低代码 schema + */ +export interface Snippet { + title: string; + screenshot?: string; + schema: ElementJSON; +} + +/** + * 组件低代码描述 + */ +export interface ComponentDescription { + componentName: string; + title: string; + description?: string; + docUrl: string; + screenshot: string; + icon?: string; + tags?: string[]; + keywords?: string[]; + devMode?: 'proCode' | 'lowCode'; + npm: Npm; + props: Prop[]; + configure: Configure; + /** + * 多模态下的组件描述, 优先级高于 configure + */ + advancedConfigures: MultiModeConfigures; + snippets: Snippet[]; + group: string; + category: string; + priority: number; + /** + * 组件引用的资源信息 + */ + reference: Reference; +} + +export interface MultiModeConfigures { + default: Configure; + [index: string]: Configure; +} + +/** + * 远程物料描述 + */ +export interface RemoteComponentDescription { + /** + * 组件描述导出名字,可以通过 window[exportName] 获取到组件描述的 Object 内容; + */ + exportName?: string; + /** + * 组件描述的资源链接; + */ + url?: string; + /** + * 组件多模态描述的资源信息,优先级高于 url + */ + advancedUrls?: ComplexUrl; + /** + * 组件(库)的 npm 信息; + */ + package?: { + npm?: string; + }; +} + +export type ComplexUrl = string | MultiModeUrl + +export interface MultiModeUrl { + default: string; + [index: string]: string; +} + +export interface ComponentSchema { + version: string; + componentsMap: ComponentsMap; + componentsTree: [ComponentTree]; + i18n: I18nMap; + utils: UtilItem[]; +} + +``` + +`ComponentSchema` 的定义见[低代码业务组件描述](./1.material-spec.md#221-组件规范) diff --git a/specs/lowcode-spec.md b/specs/lowcode-spec.md new file mode 100644 index 0000000000..65e05130d3 --- /dev/null +++ b/specs/lowcode-spec.md @@ -0,0 +1,1462 @@ +# 《低代码引擎搭建协议规范》 + +# 1 介绍 + +## 1.1 本协议规范涉及的问题域 + +- 定义本协议版本号规范 +- 定义本协议中每个子规范需要被支持的 Level +- 定义本协议相关的领域名词 +- 定义搭建基础协议版本号规范(A) +- 定义搭建基础协议组件映射关系规范(A) +- 定义搭建基础协议组件树描述规范(A) +- 定义搭建基础协议国际化多语言支持规范(AA) +- 定义搭建基础协议无障碍访问规范(AAA) + + +## 1.2 协议草案起草人 + +- 撰写:月飞、康为、林熠 +- 审阅:大果、潕量、九神、元彦、戊子、屹凡、金禅、前道、天晟、戊子、游鹿、光弘、力皓 + + +## 1.3 版本号 + +1.0.0 + +## 1.4 协议版本号规范(A) + +本协议采用语义版本号,版本号格式为 `major.minor.patch` 的形式。 + +- major 是大版本号:用于发布不向下兼容的协议格式修改 +- minor 是小版本号:用于发布向下兼容的协议功能新增 +- patch 是补丁号:用于发布向下兼容的协议问题修正 + + +## 1.5 协议中子规范 Level 定义 + +| 规范等级 | 实现要求 | +| -------- | ---------------------------------------------------------------------------------- | +| A | 强制规范,必须实现;违反此类规范的协议描述数据将无法写入物料中心,不支持流通。 | +| AA | 推荐规范,推荐实现;遵守此类规范有助于业务未来的扩展性和跨团队合作研发效率的提升。 | +| AAA | 参考规范,根据业务场景实际诉求实现;是集团层面鼓励的技术实现引导。 | + + +## 1.6 名词术语 + +### 1.6.1 物料系统名词 + +- **基础组件(Basic Component)**:前端领域通用的基础组件,阿里巴巴前端委员会官方指定的基础组件库是 Fusion Next/AntD。 +- **图表组件(Chart Component)**:前端领域通用的图表组件,有代表性的图表组件库有 BizCharts。 +- **业务组件(Business Component)**:业务领域内基于基础组件之上定义的组件,可能会包含特定业务域的交互或者是业务数据,对外仅暴露可配置的属性,且必须发布到公域(如阿里 NPM);在同一个业务域内可以流通,但不需要确保可以跨业务域复用。 + - **低代码业务组件(Low-Code Business Component)**:通过低代码编辑器搭建而来,有别于源码开发的业务组件,属于业务组件中的一种类型,遵循业务组件的定义;同时低代码业务组件还可以通过低代码编辑器继续多次编辑。 +- **布局组件(Layout Component)**:前端领域通用的用于实现基础组件、图表组件、业务组件之间各类布局关系的组件,如三栏布局组件。 +- **区块(Block)**:通过低代码搭建的方式,将一系列业务组件、布局组件进行嵌套组合而成,不对外提供可配置的属性。可通过 区块容器组的包裹,实现区块内部具备有完整的样式、事件、生命周期管理、状态管理、数据流转机制。能独立存在和运行,可通过复制 schema 实现跨页面、跨应用的快速复用,保障功能和数据的正常。 +- **页面(Page)**:由组件 + 区块组合而成。由页面容器组件包裹,可描述页面级的状态管理和公共函数。 +- **模板(Template)**:特定垂直业务领域内的业务组件、区块可组合为单个页面,或者是再配合路由组合为多个页面集,统称为模板。 + + +### 1.6.2 低代码搭建系统名词 + +- **搭建编辑器**:使用可视化的方式实现页面搭建,支持组件 UI 编排、属性编辑、事件绑定、数据绑定,最终产出符合搭建基础协议规范的数据。 + - **属性面板**:低代码编辑器内部用于组件、区块、页面的属性编辑、事件绑定、数据绑定的操作面板。 + - **画布面板**:低代码编辑器内部用于 UI 编排的操作面板。 + - **大纲面板**:低代码编辑器内部用于页面组件树展示的面板。 +- **编辑器框架**:搭建编辑器的基础框架,包含主题配置机制、插件机制、setter 控件机制、快捷键管理、扩展点管理等底层基础设施。 +- **入料模块**:专注于物料接入,能自动扫描、解析源码组件,并最终产出一份符合《低代码引擎物料协议规范》的 Schema JSON。 +- **编排模块**:专注于 Schema 可视化编排,以可视化的交互方式提供页面结构编排服务,并最终产出一份符合《低代码搭建基础协议规范》的 Schema JSON。 +- **渲染模块**:专注于将 Schema JSON 渲染为 UI 界面,最终呈现一个可交互的页面。 +- **出码模块 Schema2Code**:专注于通过 Schema JSON 生成高质量源代码,将符合《低代码搭建基础协议规范》的 Schema JSON 数据分别转化为面向 React / Rax / 阿里小程序等终端可渲染的代码。 +- **事件绑定**:是指为某个组件的某个事件绑定相关的事件处理动作,比如为某个组件的**点击事件**绑定**一段处理函数**或**响应动作**(比如弹出对话框),每个组件可绑定的事件由该组件自行定义。 +- **数据绑定**:是指为某个组件的某个属性绑定用于该属性使用的数据。 +- **生命周期**: 一般指某个对象的生老病死,本文中指某个实体(组件、容器、区块等等)的创建、加载、显示、销毁等关键生命阶段的统称。 + +## 1.7 背景 + +- **协议目标**: 通过约束低代码引擎的搭建协议规范,让上层低代码编辑器的产出物(低代码业务组件、区块、应用)保持一致性,可跨低代码研发平台进行流通而提效,亦不阻碍集团业务间融合的发展。  +- **协议通**: + - 协议顶层结构统一 + - 协议 schema 具备有完整的描述能力,包含版本、国际化、组件树、组件映射关系等; + - 顶层属性 key、value 值的格式,必须保持一致; + - 组件树描述统一 + - 源码组件描述; + - 页面、区块、低代码业务组件这三种容器组件的描述; + - 数据流描述,包含数据请求、数据状态管理、数据绑定描述; + - 事件描述,包含统一事件上下文、统一搭建 API; +- **物料通**:指在相同领域内的不同搭建产品,可直接使用的物料。比如模版、区块、组件; + +## 1.8 受众 + +本协议适用于所有使用低代码搭建平台来开发页面或组件的开发者,以及围绕此协议的相关工具或工程化方案的开发者。阅读及使用本协议,需要对低代码搭建平台的交互和实现有一定的了解,对前端开发相关技术栈的熟悉也会有帮助,协议中对通用的前端相关术语不会做进一步的解释说明。 + +## 1.9 使用范围 + +本协议描述的是低代码搭建平台产物(应用、页面、区块、组件)的 schema 结构,以及实现其数据状态更新(内置 api)、能力扩展、国际化等方面完整,只在低代码搭建场景下可用; + +## 1.10 协议目标 + +一套面向开发者的 schema 规范,用于规范化约束搭建编辑器的输出,以及渲染模块和出码模块的输入,将搭建编辑器、渲染模块、出码模块解耦,保障搭建编辑器、渲染模块、出码模块的独立升级。 + +## 1.11 设计说明 + +- **语义化**:语义清晰,简明易懂,可读性强。 +- **渐进性描述**:搭建的本质是通过 源码组件 进行嵌套组合,从小往大、依次组合生成 组件、区块、页面,最终通过云端构建生成 应用 的过程。因此在搭建基础协议中,我们需要知道如何去渐进性的描述组件、区块、页面、应用这 4 个实体概念。 +- **生成标准源码**:明确每一个属性与源码对应的转换关系,可生成跟手写无差异的高质量标准源代码。 +- **可流通性**:产物能在不同搭建产品中流通,不涉及任何私域数据存储。 +- **面向多端**:不能仅面向 React,还有小程序等多端。 +- **支持国际化&无障碍访问标准的实现** + + +# 2 协议结构 + +协议最顶层结构如下,包含5方面的描述内容: + +- version { String } 当前协议版本号 +- componentsMap { Array } 组件映射关系 +- componentsTree { Array } 描述模版/页面/区块/低代码业务组件的组件树 +- utils { Array } 工具类扩展映射关系 +- i18n { Object } 国际化语料 + + +描述举例: + +```json +{ + "version": "1.0.0", // 当前协议版本号 + "componentsMap": [{ // 组件描述 + "componentName": "Button", + "package": "@alifd/next", + "version": "1.0.0", + "destructuring": true, + "exportName": "Select", + "subName": "Button" + }], + "utils": [{ + "name": "clone", + "type": "npm", + "content": { + "package": "lodash", + "version": "0.0.1", + "exportName": "clone", + "subName": "", + "destructuring": false, + "main": "/lib/clone" + } + }, { + "name": "moment", + "type": "npm", + "content": { + "package": "@alifd/next", + "version": "0.0.1", + "exportName": "Moment", + "subName": "", + "destructuring": true, + "main": "" + } + }], + "componentsTree": [{ // 描述内容,值类型 Array + "componentName": "Page", // 单个页面,枚举类型 Page|Block|Component + "fileName": "Page1", + "props": {}, + "css": "body {font-size: 12px;} .table { width: 100px;}", + "children": [{ + "componentName": "Div", + "props": { + "className": "" + }, + "children": [{ + "componentName": "Button", + "props": { + "prop1": 1234, // 简单 json 数据 + "prop2": [{ // 简单 json 数据 + "label": "选项1", + "value": 1 + }, { + "label": "选项2", + "value": 2 + }], + "prop3": [{ + "name": "myName", + "rule": { + "type": "JSExpression", + "value": "/\w+/i" + } + }], + "valueBind": { // 变量绑定 + "type": "JSExpression", + "value": "this.state.user.name" + }, + "onClick": { // 动作绑定 + "type": "JSFunction", + "value": "function(e) { console.log(e.target.innerText) }" + }, + "onClick2": { // 动作绑定 2 + "type": "JSExpression", + "value": "this.submit" + } + } + }] + }] + }], + "i18n": { + "zh-CN": { + "i18n-jwg27yo4": "你好", + "i18n-jwg27yo3": "中国" + }, + "en-US": { + "i18n-jwg27yo4": "Hello", + "i18n-jwg27yo3": "China" + } + } +} +``` + +## 2.1 协议版本号(A) + +定义当前协议 schema 的版本号,不同的版本号对应不同的渲染 SDK,以保障不同版本搭建协议产物的正常渲染; + + +| 根属性名称 | 类型 | 说明 | 变量支持 | 默认值 | +| ---------- | ------ | ---------- | -------- | ------ | +| version | String | 协议版本号 | - | 1.0.0 | + + +描述示例: + +```javascript +{ + "version": "1.0.0" +} +``` + +## 2.2 组件映射关系(A) + +协议中用于描述 componentName 到公域组件映射关系的规范。 + + +| 参数 | 说明 | 类型 | 变量支持 | 默认值 | +| --------------- | ---------------------- | ------------------------- | -------- | ------ | +| componentsMap[] | 描述组件映射关系的集合 | Array\<**ComponentMap**\> | - | null | + +**ComponentMap 结构描述**如下: + +| 参数 | 说明 | 类型 | 变量支持 | 默认值 | +| ------------- | ------------------------------------------------------------------------------------------------------ | ------- | -------- | ------ | +| componentName | 协议中的组件名,唯一性,对应包导出的组件名,是一个有效的 **JS 标识符**,而且是大写字母打头 | String | - | - | +| package | npm 公域的 package name | String | - | - | +| version | package version | String | - | - | +| destructuring | 使用解构方式对模块进行导出 | Boolean | - | - | +| exportName | 包导出的组件名 | String | - | - | +| subName | 下标子组件名称 | String | - | | +| main | 包导出组件入口文件路径 | String | - | - | + + +描述示例: + +```json +{ + "componentsMap": [{ + "componentName": "Button", + "package": "@alifd/next", + "version": "1.0.0", + "destructuring": true + }, { + "componentName": "MySelect", + "package": "@alifd/next", + "version": "1.0.0", + "destructuring": true, + "exportName": "Select" + }, { + "componentName": "ButtonGroup", + "package": "@alifd/next", + "version": "1.0.0", + "destructuring": true, + "exportName": "Button", + "subName": "Group" + }, { + "componentName": "RadioGroup", + "package": "@alifd/next", + "version": "1.0.0", + "destructuring": true, + "exportName": "Radio", + "subName": "Group" + }, { + "componentName": "CustomCard", + "package": "@ali/custom-card", + "version": "1.0.0" + }, { + "componentName": "CustomInput", + "package": "@ali/custom", + "version": "1.0.0", + "main": "/lib/input", + "destructuring": true, + "exportName": "Input" + }] +} +``` + +出码结果: + +```javascript +// 使用解构方式, destructuring is true. +import { Button } from '@alifd/next'; + +// 使用解构方式,且 exportName 和 componentName 不同 +import { Select as MySelect } from '@alifd/next'; + +// 使用解构方式,并导出其子组件 +import { Button } from '@alifd/next'; +const ButtonGroup = Button.Group; + +import { Radio } from '@alifd/next'; +const RadioGroup = Radio.Group; + +// 不使用解构方式进行导出 +import CustomCard from '@ali/custom-card'; + +// 使用特定路径进行导出 +import { Input as CustomInput } from '@ali/custom/lib/input'; + +``` + + +## 2.3 组件树描述(A) + + +协议中用于描述搭建出来的组件树结构的规范,整个组件树的描述由**组件结构**&**容器结构**两种结构嵌套构成。 + +- 组件结构:描述单个组件的名称、属性、子集的结构; +- 容器结构:描述单个容器的数据、自定义方法、生命周期的结构,用于将完整页面进行模块化拆分。 + +与源码对应的转换关系如下: + +- 组件结构:转换成一个 .jsx 文件内 React Class 类 render 函数返回的 **jsx** 代码。 +- 容器结构:将转换成一个标准文件,如 React 的 jsx 文件, export 一个 React Class,包含生命周期定义、自定义方法、事件属性绑定、异步数据请求等。 + +### 2.3.1 基础结构描述 (A) + +此部分定义了组件结构、容器结构的公共基础字段。 + +> 阅读时可先跳到后续章节,待需要时回来参考阅读 + +#### 2.3.1.1 Props 结构描述 + +| 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | +| ----------- | ------------ | ------ | -------- | ------ | ------------------------------------- | +| id | 组件 ID | String | ✅ | - | 系统属性 | +| className | 组件样式类名 | String | ✅ | - | 系统属性,支持变量表达式 | +| style | 组件内联样式 | Object | ✅ | - | 系统属性,单个内联样式属性值 | +| ref | 组件 ref 名称 | String | ✅ | - | 可通过 `this.$(ref)` 获取组件实例 | +| extendProps | 组件继承属性 | 变量 | ✅ | - | 仅支持变量绑定,常用于继承属性对象 | +| ... | 组件私有属性 | - | - | - | | + +#### 2.3.1.2 css/less/scss 样式描述 + +| 参数 | 说明 | 类型 | 支持变量 | 默认值 | +| ------------- | -------------------------------------------------------------------------- | ------ | -------- | ------ | +| css/less/scss | 用于描述容器组件内部节点的样式,对应生成一个独立的样式文件,不支持 @import | String | - | null | + +描述示例: + +```json +{ + "css": "body {font-size: 12px;} .table { width: 100px; }" +} +``` + +#### 2.3.1.3 ComponentDataSource 对象描述 + +| 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | +| ----------- | ---------------------- | -------------------------------------- | -------- | ------ | ----------------------------------------------------------------------------------------------------------- | +| list[] | 数据源列表 | Array\<**ComponentDataSourceItem**\> | - | - | 成为为单个请求配置, 内容定义详见 [ComponentDataSourceItem 对象描述](#2314-componentdatasourceitem-对象描述) | +| dataHandler | 所有请求数据的处理函数 | Function | - | - | 详见 [dataHandler Function 描述](#2317-datahandler-function 描述) | + +#### 2.3.1.4 ComponentDataSourceItem 对象描述 + +| 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | +| -------------- | ---------------------------- | ---------------------------------------------------- | -------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| id | 数据请求 ID 标识 | String | - | - | | +| isInit | 是否为初始数据 | Boolean | ✅ | true | 值为 true 时,将在组件初始化渲染时自动发送当前数据请求 | +| isSync | 是否需要串行执行 | Boolean | ✅ | false | 值为 true 时,当前请求将被串行执行 | +| type | 数据请求类型 | String | - | fetch | 支持四种类型:fetch/mtop/jsonp/custom | +| shouldFetch | 本次请求是否可以正常请求 | (options: ComponentDataSourceItemOptions) => boolean | - | ```() => true``` | function 参数参考 [ComponentDataSourceItemOptions 对象描述](#2315-componentdatasourceitemoptions-对象描述) | +| willFetch | 单个数据结果请求参数处理函数 | Function | - | options => options | 只接受一个参数(options),返回值作为请求的 options,当处理异常时,使用原 options。也可以返回一个 Promise,resolve 的值作为请求的 options,reject 时,使用原 options | +| requestHandler | 自定义扩展的外部请求处理器 | Function | - | - | 仅 type='custom' 时生效 | +| dataHandler | request 成功后的回调函数 | Function | - | `response => response.data` | 参数: 请求成功后 promise 的 value 值 | +| errorHandler | request 失败后的回调函数 | Function | - | - | 参数: 请求出错 promise 的 error 内容 | +| options {} | 请求参数 | **ComponentDataSourceItemOptions** | - | - | 每种请求类型对应不同参数, 详见 [ComponentDataSourceItemOptions 对象描述](#2315-componentdatasourceitemoptions-对象描述) | + +**关于 dataHandler 于 errorHandler 的细节说明:** + +request 返回的是一个 promise,dataHandler 和 errorHandler 遵循 Promise 对象的 then 方法,实际使用方式如下: + +```ts +// 伪代码 +try { + const result = await request(fetchConfig).then(dataHandler, errorHandler); + dataSourceItem.data = result; + dataSourceItem.status = 'success'; +} catch (err) { + dataSourceItem.error = err; + dataSourceItem.status = 'error'; +} +``` +**注意:** +- dataHandler 和 errorHandler 只会走其中的一个回调 +- 它们都有修改 promise 状态的机会,意味着可以修改当前数据源最终状态 +- 最后返回的结果会被认为是当前数据源的最终结果,如果被 catch 了,那么会认为数据源请求出错 +- dataHandler 会有默认值,考虑到返回结果入参都是 response 完整对象,默认值会返回 `response.data`,errorHandler 没有默认值 + + +#### 2.3.1.5 ComponentDataSourceItemOptions 对象描述 + +| 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | +| ------- | ------------ | ------- | -------- | ------ | ----------------------------------------------------------------------------------------------------------- | +| uri | 请求地址 | String | ✅ | - | | +| params | 请求参数 | Object | ✅ | {} | 当前数据源默认请求参数(在运行时会被实际的 load 方法的参数替换,如果 load 的 params 没有则会使用当前 params) | +| method | 请求方法 | String | ✅ | GET | | +| isCors | 是否支持跨域 | Boolean | ✅ | true | 对应 `credentials = 'include'` | +| timeout | 超时时长 | Number | ✅ | 5000 | 单位 ms | +| headers | 请求头信息 | Object | ✅ | - | 自定义请求头 | + + + +#### 2.3.1.6 ComponentLifeCycles 对象描述 + +生命周期对象,schema 面向多端,不同 DSL 有不同的生命周期方法: + +- React:对于中后台 PC 物料,已明确使用 React 作为最终渲染框架,因此提案采用 [React16 标准生命周期方法](https://reactjs.org/docs/react-component.html)标准来定义生命周期方法,降低理解成本,支持生命周期如下: + - constructor(props, context)  + - 说明:初始化渲染时执行,常用于设置 state 值。 + - render()  + - 说明:执行于容器组件 React Class 的 render 方法最前,常用于计算变量挂载到 this 对象上,供 props 上属性绑定。此 render() 方法不需要设置 return 返回值。 + - componentDidMount() + - 说明:组件已加载 + - componentDidUpdate(prevProps, prevState, snapshot) + - 说明:组件已更新 + - componentWillUnmount() + - 说明:组件即将从 DOM 中移除 + - componentDidCatch(error, info) + - 说明:组件捕获到异常 +- Rax:目前没有使用生命周期,使用 hooks 替代生命周期; + +该对象由一系列 key-value 组成,key 为生命周期方法名,value 为 JSFunction 的描述,详见下方示例: + +```json +{ + "componentDidMount": { // key 为上文中 React 的生命周期方法名 + "type": "JSFunction", // type 目前仅支持 JSFunction + "value": "function() {\ // value 为 javascript 函数 + console.log('did mount');\ + }" + }, + "componentWillUnmount": { + "type": "JSFunction", + "value": "function() {\ + console.log('will unmount');\ + }" + } + ... +}, +``` + + +#### 2.3.1.7 dataHandler Function 描述 + +- 参数:为 dataMap 对象,包含字段如下: + - key: 数据 id + - value: 单个请求结果 +- 返回值:数据对象 data,将会在渲染引擎和 schemaToCode 中通过调用 `this.setState(...)` 将返回的数据对象生效到 state 中;支持返回一个 Promise,通过 `resolve(返回数据)`,常用于串行发送请求场景。 + +#### 2.3.1.8 ComponentPropDefinition 对象描述 + +| 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | +| ------------ | ---------- | -------------- | -------- | --------- | ----------------------------------------------------------------------------------------------------------------- | +| name | 属性名称 | String | - | - | | +| propType | 属性类型 | String\|Object | - | - | 具体值内容结构,参考《低代码引擎物料协议规范》 内的 “2.2.2.3 组件属性信息”中描述的**基本类型**和**复合类型** | +| description | 属性描述 | String | - | '' | | +| defaultValue | 属性默认值 | Any | - | undefined | 当 defaultValue 和 defaultProps 中存在同一个 prop 的默认值时,优先使用 defaultValue。 | + +范例: +```json +{ + "propDefinitions": [{ + "name": "title", + "propType": "string", + "defaultValue": "Default Title" + }, { + "name": "onClick", + "propType": "func" + }] + ... +}, +``` + +### 2.3.2 组件结构描述(A) + +对应生成源码开发体系中 render 函数返回的 jsx 代码,主要描述有以下属性: + + +| 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | +| ------------- | ---------------------- | ---------------- | -------- | ----------------- | ---------------------------------------------------------------------------------------------------------- | +| id | 组件唯一标识 | String | - | | 可选, 组件 id 由引擎随机生成(UUID),并保证唯一性,消费方为上层应用平台,在组件发生移动等场景需保持 id 不变 | +| componentName | 组件名称 | String | - | Div | 必填,首字母大写, 同 [componentsMap](#22-组件映射关系 a) 中的要求 | +| props {} | 组件属性对象 | **Props** | - | {} | 必填, 详见 [Props 结构描述](#2311-props-结构描述) | +| condition | 渲染条件 | Boolean | ✅ | true | 选填,根据表达式结果判断是否渲染物料;支持变量表达式 | +| loop | 循环数据 | Array | ✅ | - | 选填,默认不进行循环渲染;支持变量表达式 | +| loopArgs | 循环迭代对象、索引名称 | [String, String] | | ["item", "index"] | 选填,仅支持字符串 | +| children | 子组件 | Array | | | 选填,支持变量表达式 | + + +描述举例: + +```json +{ + "componentName": "Button", + "props": { + "className": "btn", + "style": { + "width": 100, + "height": 20 + }, + "text": "submit", + "onClick": { + "type": "JSFunction", + "value": "function(e) {\ + console.log('btn click')\ + }" + } + }, + "condition": { + "type": "JSExpression", + "value": "!!this.state.isshow" + }, + "loop": [], + "loopArgs": ["item", "index"], + "children": [] +} +``` + + +### 2.3.3 容器结构描述 (A)  + +容器是一类特殊的组件,在组件能力基础上增加了对生命周期对象、自定义方法、样式文件、数据源等信息的描述。包含**低代码业务组件容器 Component**、**区块容器 Block**、**页面容器 Page** 3 种。主要描述有以下属性: + +- 组件类型:componentName +- 文件名称:fileName +- 组件属性:props +- state 状态管理:state +- 生命周期 Hook 方法:lifeCycles +- 自定义方法设置:methods +- 异步数据源配置:dataSource +- 条件渲染:condition +- 样式文件:css/less/scss + + +详细描述: + +| 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | +| --------------- | -------------------------- | ---------------------------------------------------------------------------------------------------------- | -------- | ------ | ----------------------------------------------------------------------------------------------------------------------------- | +| componentName | 组件名称 | 枚举类型,包括`'Page'` (代表页面容器)、`'Block'` (代表区块容器)、`'Component'` (代表低代码业务组件容器) | - | 'Div' | 必填,首字母大写 | +| fileName | 文件名称 | String | - | - | 必填,英文 | +| props { } | 组件属性对象 | **Props** | - | {} | 必填,详见 [Props 结构描述](#2311-props-结构描述) | +| static | 低代码业务组件类的静态对象 | | | | | +| defaultProps | 低代码业务组件默认属性 | Object | - | - | 选填,仅用于定义低代码业务组件的默认属性 | +| propDefinitions | 低代码业务组件属性类型定义 | **Array\** | - | - | 选填,仅用于定义低代码业务组件的属性数据类型。详见 [ComponentPropDefinition 对象描述](#2318-componentpropdefinition-对象描述) | +| condition | 渲染条件 | Boolean | ✅ | true | 选填,根据表达式结果判断是否渲染物料;支持变量表达式 | +| state | 容器初始数据 | Object | ✅ | - | 选填,支持变量表达式 | +| children | 子组件 | Array | - | | 选填,支持变量表达式 | +| css/less/scss | 样式属性 | String | ✅ | - | 选填, 详见 [css/less/scss 样式描述](#2312-csslessscss 样式描述) | +| lifeCycles | 生命周期对象 | **ComponentLifeCycles** | - | - | 详见 [ComponentLifeCycles 对象描述](#2316-componentlifecycles-对象描述) | +| methods | 自定义方法对象 | Object | - | - | 选填,对象成员为函数类型 | +| dataSource {} | 数据源对象 | **ComponentDataSource** | - | - | 选填,异步数据源, 详见 [ComponentDataSource 对象描述](#2313-componentdatasource-对象描述) | + + + +#### 完整描述示例 + +描述示例 1:(正常 fetch/mtop/jsonp 请求): + +```json +{ + "componentName": "Block", + "fileName": "block-1", + "props": { + "className": "luna-page", + "style": { + "background": "#dd2727" + } + }, + "children": [{ + "componentName": "Button", + "props": { + "text": { + "type": "JSExpression", + "value": "this.state.btnText" + } + } + }], + "state": { + "btnText": "submit" + }, + "css": "body {font-size: 12px;}", + "lifeCycles": { + "componentDidMount": { + "type": "JSFunction", + "value": "function() {\ + console.log('did mount');\ + }" + }, + "componentWillUnmount": { + "type": "JSFunction", + "value": "function() {\ + console.log('will unmount');\ + }" + } + }, + "methods": { + "testFunc": { + "type": "JSFunction", + "value": "function() {\ + console.log('test func');\ + }" + } + }, + "dataSource": { + "list": [{ + "id": "list", + "isInit": true, + "type": "fetch/mtop/jsonp", + "options": { + "uri": "", + "params": {}, + "method": "GET", + "isCors": true, + "timeout": 5000, + "headers": {} + }, + "dataHandler": { + "type": "JSFunction", + "value": "function(data, err) {}" + } + }], + "dataHandler": { + "type": "JSFunction", + "value": "function(dataMap) { }" + } + }, + "condition": { + "type": "JSExpression", + "value": "!!this.state.isShow" + } +} +``` + +描述示例 2:(自定义扩展请求处理器类型): + +```json +{ + "componentName": "Block", + "fileName": "block-1", + "props": { + "className": "luna-page", + "style": { + "background": "#dd2727" + } + }, + ... + "dataSource": { + "list": [{ + "id": "list", + "isInit": true, + "type": "custom", + "requestHandler": { + "type": "JSFunction", + "value": "this.utils.hsfHandler" + }, + "options": { + "uri": "hsf://xxx", + "param1": "a", + "param2": "b", + ... + }, + "dataHandler": { + "type": "JSFunction", + "value": "function(data, err) { }" + } + }], + "dataHandler": { + "type": "JSFunction", + "value": "function(dataMap) { }" + } + } +} +``` + +### 2.3.4 属性值类型描述(A) + +在上述**组件结构**和**容器结构**描述中,每一个属性所对应的值,除了传统的 JS 值类型(String、Number、Object、Array、Boolean)外,还包含有**节点类型**、**事件函数类型**、**变量类型**等多种复杂类型;接下来将对于复杂类型的详细描述方式进行详细介绍。 + +#### 2.3.4.1 节点类型(A) + +通常用于描述组件的某一个属性为 **ReactNode** 或 **Function-Return-ReactNode** 的场景。该类属性的描述均以 **JSSlot** 的方式进行描述,详细描述如下: + +**ReactNode** 描述: + +| 参数 | 说明 | 值类型 | 默认值 | 备注 | +| ----- | ---------- | --------------------- | -------- | -------------------------------------------------------------- | +| type | 值类型描述 | String | 'JSSlot' | 固定值 | +| value | 具体的值 | Array\ | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述(A)) | + + +举例描述:如 **Card** 的 **title** 属性 + +```json +{ + "componentName": "Card", + "props": { + "title": { + "type": "JSSlot", + "value": [{ + "componentName": "Icon", + "props": {} + },{ + "componentName": "Text", + "props": {} + }] + }, + ... + } +} + +``` + + +**Function-Return-ReactNode** 描述: + +| 参数 | 说明 | 值类型 | 默认值 | 备注 | +| ------ | ---------- | --------------------- | -------- | -------------------------------------------------------------- | +| type | 值类型描述 | String | 'JSSlot' | 固定值 | +| value | 具体的值 | Array\ | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述 a) | +| params | 函数的参数 | Array\ | null | 函数的入参,其子节点可以通过 `this[参数名]` 来获取对应的参数。 | + + +举例描述:如 **Table.Column** 的 **cell** 属性 + +```json +{ + "componentName": "TabelColumn", + "props": { + "cell": { + "type": "JSSlot", + "params": ["value", "index", "record"], + "value": [{ + "componentName": "Input", + "props": {} + }] + }, + ... + } +} + +``` + +#### 2.4.3.2 事件函数类型(A) + +协议内的事件描述,主要包含**容器结构**的**生命周期**和**自定义方法**,以及**组件结构**的**事件函数类属性**三类。所有事件函数的描述,均以 **JSFunction** 的方式进行描述,保留与原组件属性、生命周期(React / 小程序)一致的输入参数,并给所有事件函数 binding 统一一致的上下文(当前组件所在容器结构的 **this** 对象)。 + +**事件函数类型**的属性值描述如下: + +```json +{ + "type": "JSFunction", + "value": "function onClick(){\ + console.log(123);\ + }" +} +``` + +描述举例: + +```json +{ + "componentName": "Block", + "fileName": "block1", + "props": {}, + "state": { + "name": "lucy" + }, + "lifeCycles": { + "componentDidMount": { + "type": "JSFunction", + "value": "function() {\ + console.log('did mount');\ + }" + }, + "componentWillUnmount": { + "type": "JSFunction", + "value": "function() {\ + console.log('will unmount');\ + }" + } + }, + "methods": { + "getNum": { + "type": "JSFunction", + "value": "function() {\ + console.log('名称是:' + this.state.name)\ + }" + } + }, + "children": [{ + "componentName": "Button", + "props": { + "text": "按钮", + "onClick": { + "type": "JSFunction", + "value": "function(e) {\ + console.log(e.target.innerText);\ + }" + } + } + }] +} +``` + +#### 2.4.3.3 变量类型(A) + +在上述**组件结构** 或**容器结构**中,有多个属性的值类型是支持变量类型的,通常会通过变量形式来绑定某个数据,所有的变量表达式均通过 JSExpression 表达式,上下文与事件函数描述一致,表达式内通过 **this** 对象获取上下文; + +变量**类型**的属性值描述如下: + + +- return 数字类型 + + ```json + { + "type": "JSExpression", + "value": "this.state.num" + } + ``` +- return 数字类型 + + ```json + { + "type": "JSExpression", + "value": "this.state.num - this.state.num2" + } + ``` +- return "8万" 字符串类型 + + ```json + { + "type": "JSExpression", + "value": "`${this.state.num}万`" + } + ``` +- return "8万" 字符串类型 + + ```json + { + "type": "JSExpression", + "value": "this.state.num + '万'" + } + ``` +- return 13 数字类型 + + ```json + { + "type": "JSExpression", + "value": "getNum(this.state.num, this.state.num2)" + } + ``` +- return true 布尔类型 + + ```json + { + "type": "JSExpression", + "value": "this.state.num > this.state.num2" + } + ``` + +描述举例: + +```json +{ + "componentName": "Block", + "fileName": "block1", + "props": {}, + "state": { + "num": 8, + "num2": 5 + }, + "methods": { + "getNum": { + "type": "JSFunction", + "value": "function(a, b){\ + return a + b;\ + }" + } + }, + "children": [{ + "componentName": "Button", + "props": { + "text": { + "type": "JSExpression", + "value": "getNum(this.state.num, this.state.num2) + '万'" + } + }, + "condition": { + "type": "JSExpression", + "value": "this.state.num > this.state.num2" + } + }] +} +``` + +#### 2.4.3.4 国际化多语言类型(AA) + +协议内的一些文本值内容,我们希望是和协议全局的国际化多语言语料是关联的,会按照全局国际化语言环境的不同使用对应的语料。所有国际化多语言值均以 **i18n** 结构描述。这样可以更为清晰且结构化得表达使用场景。 + +**国际化多语言类型**的属性值类型描述如下: + +```typescript +type Ti18n = { + type: 'i18n'; + key: string; // i18n 结构中字段的 key 标识符 + params?: Record; // 模版型 i18n 文案的入参,JSDataType 指代传统 JS 值类型 +} +``` + +其中 `key` 对应协议 `i18n` 内容的语料键值,`params` 为语料为字符串模板时的变量内容。 + +假设协议已加入如下 i18n 内容: +```json +{ + "i18n": { + "zh-CN": { + "i18n-jwg27yo4": "你好", + "i18n-jwg27yo3": "${name}博士" + }, + "en-US": { + "i18n-jwg27yo4": "Hello", + "i18n-jwg27yo3": "Doctor ${name}" + } + } +} +``` + +**国际化多语言类型**简单范例: + +```json +{ + "type": "i18n", + "key": "i18n-jwg27yo4" +} +``` + +**国际化多语言类型**模板范例: + +```json +{ + "type": "i18n", + "key": "i18n-jwg27yo3", + "params": { + "name": "Strange" + } +} +``` + +描述举例: + +```json +{ + "componentName": "Button", + "props": { + "text": { + "type": "i18n", + "key": "i18n-jwg27yo4" + } + } +} +``` + + +### 2.3.5 上下文 API 描述(A) + +在上述**事件类型描述**和**变量类型描述**中,在函数或 JS 表达式内,均可以通过 **this** 对象获取当前组件所在容器(React Class)的实例化对象,在搭建场景下的渲染模块和出码模块实现上,统一约定了该实例化 **this** 对象下所挂载的最小 API 集合,以保障搭建协议具备有一致的**数据流**和**事件上下文**。  + +#### 2.3.5.1 容器 API: + +| 参数 | 说明 | 类型 | 备注 | +| ----------------------------------- | --------------------------------------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------- | +| **this {}** | 当前区块容器的实例对象 | Class Instance | - | +| *this*.state | 三种容器实例的数据对象 state | Object | - | +| *this*.setState(newState, callback) | 三种容器实例更新数据的方法 | Function | 这个 setState 通常会异步执行,详见下文 [setState](#setstate) | +| *this*.customMethod() | 三种容器实例的自定义方法 | Function | - | +| *this*.dataSourceMap {} | 三种容器实例的数据源对象 Map | Object | 单个请求的 id 为 key, value 详见下文 [DataSourceMapItem 结构描述](#datasourcemapitem-结构描述) | +| *this*.reloadDataSource() | 三种容器实例的初始化异步数据请求重载 | Function | 返回 \ | +| **this.page {}** | 当前页面容器的实例对象 | Class Instance | | +| *this.page*.props | 读取页面路由,参数等相关信息 | Object | query 查询参数 { key: value } 形式;path 路径;uri 页面唯一标识;其它扩展字段 | +| *this.page*.xxx | 继承 this 对象所有 API | | 此处 `xxx` 代指 `this.page` 中的其他 API | +| **this.component {}** | 当前低代码业务组件容器的实例对象 | Class Instance | | +| *this.component*.props | 读取低代码业务组件容器的外部传入的 props | Object | | +| *this.component*.xxx | 继承 this 对象所有 API | | 此处 `xxx` 代指 `this.component` 中的其他 API | +| **this.$(ref)** | 获取组件的引用(单个) | Component Instance | `ref` 对应组件上配置的 `ref` 属性,用于唯一标识一个组件;若有同名的,则会返回第一个匹配的。 | +| **this.$$(ref)** | 获取组件的引用(所有同名的) | Array of Component Instances | `ref` 对应组件上配置的 `ref` 属性,用于唯一标识一个组件;总是返回一个数组,里面是所有匹配 `ref` 的组件的引用。 | + +##### setState + +`setState()` 将对容器 `state` 的更改排入队列,并通知低代码引擎需要使用更新后的 `state` 重新渲染此组件及其子组件。这是用于更新用户界面以响应事件处理器和处理服务器数据的主要方式。 + +请将 `setState()` 视为请求而不是立即更新组件的命令。为了更好的感知性能,低代码引擎会延迟调用它,然后通过一次传递更新多个组件。低代码引擎并不会保证 state 的变更会立即生效。 + +`setState()` 并不总是立即更新组件, 它会批量推迟更新。这使得在调用 `setState()` 后立即读取 `this.state` 成为了隐患。为了消除隐患,请使用 `setState` 的回调函数(`setState(updater, callback)`),`callback` 将在应用更新后触发。即,如下例所示: + +```js +this.setState(newState, () => { + // 在这里更新已经生效了 + // 可以通过 this.state 拿到更新后的状态 + console.log(this.state); +}); + +// ⚠注意:这里拿到的并不是更新后的状态,这里还是之前的状态 +console.log(this.state); +``` + +如需基于之前的 `state` 来设置当前的 `state`,则可以将传递一个 `updater` 函数:`(state, props) => newState`,例如: + +```js +this.setState((prevState) => ({ count: prevState.count + 1 })); +``` + +为了方便更新部分状态,`setState` 会将 `newState` 浅合并到新的 `state` 上。 + + +##### DataSourceMapItem 结构描述 + +| 参数 | 说明 | 类型 | 备注 | +| ------------ | -------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------ | +| load(params) | 调用单个数据源 | Function | 当前参数 params 会替换 [ComponentDataSourceItemOptions 对象描述](#2315-componentdatasourceitemoptions-对象描述)中的 params 内容 | +| status | 获取单个数据源上次请求状态 | String | loading、loaded、error、init | +| data | 获取上次请求成功后的数据 | Any | | +| error | 获取上次请求失败的错误对象 | Error 对象 | | + +备注: 如果组件没有在区块容器内,而是直接在页面内,那么 `this === this.page` + + +#### 2.3.5.2 循环数据 API + +获取在循环场景下的数据对象。举例:上层组件设置了 loop 循环数据,且设置了 `loopArgs:["item", "index"]`,当前组件的属性表达式或绑定的事件函数中,可以通过 this 上下文获取所在循环的数据环境;默认值为 `['item','index']` ,如有多层循环,需要自定义不同 loopArgs,同样通过 `this[自定义循环别名]` 获取对应的循环数据和序号; + + +| 参数 | 说明 | 类型 | 可选值 | +| ---------- | --------------------------------- | ------ | ------ | +| this.item | 获取当前 index 对应的循环体数据; | Any | - | +| this.index | 当前物料在循环体中的 index | Number | - | + +## 2.5 工具类扩展描述(AA) + +用于描述物料开发过程中,自定义扩展或引入的第三方工具类(例如:lodash 及 moment),增强搭建基础协议的扩展性,提供通用的工具类方法的配置方案及调用 API。 + +| 参数 | 说明 | 类型 | 支持变量 | 默认值 | +| ------------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------- | -------- | ------ | +| utils[] | 工具类扩展映射关系 | Array\<**UtilItem**\> | - | | +| *UtilItem*.name | 工具类扩展项名称 | String | - | | +| *UtilItem*.type | 工具类扩展项类型 | 枚举, `'npm'` (代表公网 npm 类型) / `'tnpm'` (代表阿里巴巴内部 npm 类型) / `'function'` (代表 Javascript 函数类型) | - | | +| *UtilItem*.content | 工具类扩展项内容 | [ComponentMap 类型](#22-组件映射关系 a) 或 [JSFunction](#2432事件函数类型 a) | - | | + +描述示例: + +```javascript +{ + utils: [{ + name: 'clone', + type: 'npm', + content: { + package: 'lodash', + version: '0.0.1', + exportName: 'clone', + subName: '', + destructuring: false, + main: '/lib/clone' + } + }, { + name: 'moment', + type: 'npm', + content: { + package: '@alifd/next', + version: '0.0.1', + exportName: 'Moment', + subName: '', + destructuring: true, + main: '' + } + }, { + name: 'recordEvent', + type: 'function', + content: { + type: 'JSFunction', + value: "function(logkey, gmkey, gokey, reqMethod) {\n goldlog.record('/xxx.event.' + logkey, gmkey, gokey, reqMethod);\n}" + } + }] +} +``` + +出码结果: + +```javascript +import clone from 'lodash/lib/clone'; +import { Moment } from '@alifd/next'; + +export const recordEvent = function(logkey, gmkey, gokey, reqMethod) { + goldlog.record('/xxx.event.' + logkey, gmkey, gokey, reqMethod); +} + +... +``` + +扩展的工具类,用户可以通过统一的上下文 this.utils 方法获取所有扩展的工具类或自定义函数 ,例如:this.utils.moment、this.utils.clone。搭建协议中的使用方式如下所示: + +```javascript +{ + componentName: 'Div', + props: { + onClick: { + type: 'JSFunction, + value: 'function(){ this.utils.clone(this.state.data); }' + } + } +} +``` + +## 2.6 国际化多语言支持(AA) + +协议中用于描述国际化语料和组件引用国际化语料的规范,遵循集团国际化中台关于国际化语料规范定义。 + + +| 参数 | 说明 | 类型 | 可选值 | 默认值 | +| ---- | -------------- | ------ | ------ | ------ | +| i18n | 国际化语料信息 | Object | - | null | + + +描述示例: + +```json +{ + "i18n": { + "zh-CN": { + "i18n-jwg27yo4": "你好", + "i18n-jwg27yo3": "中国" + }, + "en-US": { + "i18n-jwg27yo4": "Hello", + "i18n-jwg27yo3": "China" + } + } +} +``` + +使用举例: + +```json +{ + "componentName": "Button", + "props": { + "text": { + "type": "i18n", + "key": "i18n-jwg27yo4" + } + } +} +``` + +```json +{ + "componentName": "Button", + "props": { + "text": "按钮", + "onClick": { + "type": "JSFunction", + "value": "function() {\ + console.log(this.i18n('i18n-jwg27yo4'));\ + }" + } + } +} +``` + +使用举例(已废弃) +```json +{ + "componentName": "Button", + "props": { + "text": { + "type": "JSExpression", + "value": "this.i18n['i18n-jwg27yo4']" + } + } +} +``` + +# 3 应用描述 + +面向开发者的,描述完整应用的 Schema 规范,用于规范化约束**低代码平台**对**完整应用**的**输出**,以及**出码模块**( Schema2Code) 或**运行时动态渲染框架**(预览)的**输入**。 + +## 3.1 结构描述 + +- version { String } 当前应用协议版本号 +- componentsMap { Array } 当前应用所有组件映射关系 +- componentsTree { Array } 描述应用所有页面、低代码组件的组件树 +- utils { Array } 应用范围内的全局自定义函数或第三方工具类扩展 +- css { string } 应用范围内的全局样式; +- config: { Object } 当前应用配置信息 +- meta: { Object } 当前应用元数据信息 +- dataSource: { Array } 当前应用的公共数据源 (待定) +- i18n { Object } 国际化语料 + + +完整应用描述举例: + +```json +{ + "version": "1.0.0", // 当前协议版本号 + "componentsMap": [{ // 依赖 npm 组件描述 + "componentName": "Button", + "package": "alife/next", + "version": "1.0.0", + "destructuring": true, + "exportName": "Select", + "subName": "Button" + }], + "componentsTree": [{ // 应用内页面、低代码组件描述 + "componentName": "Page", // 单个页面 + "fileName": "page_index", + "props": {}, + "css": "body {font-size: 12px;} .table { width: 100px;}", + "meta": { // 页面元信息 + "title": "首页", // 页面标题描述 + "router": "/", // 页面路由 + "spmb": "abef21", // spm B 位 + "url": "https://fusion.design", // 页面访问地址 + "creator": "xxx", + "gmt_create": "2020-02-11 00:00:00", // 创建时间 + "gmt_modified": "2020-02-11 00:00:00", // 修改时间 + ... + }, + "children": [{ + "componentName": "Div", + "props": { + "className": "red", + }, + "children": [{ + "componentName": "Button", + "props": { + "type": "primary", + "valueBind": { // 变量绑定 + "type": "JSExpression", + "value": "this.state.user.name" + }, + "onClick": { // 动作绑定 + "type": "JSExpression", + "value": "function(e) { console.log(e.target.innerText) }", + } + }, + }] + }, { + "componentName": "Component", // 单个组件 + "fileName": "BasicLayout", // 组件名称 + "props": {}, + "css": "body {font-size: 12px;} .table { width: 100px;}", + "meta": { // 组件元信息 + "title": "导航组件", // 组件中文标题 + "description": "这是一个导航类组件...", // 组件描述 + "creator": "xxx", + "gmt_create": "2020-02-11 00:00:00", // 创建时间 + "gmt_modified": "2020-02-11 00:00:00", // 修改时间 + ... + }, + "children": [{ + "componentName": "Nav", + "props": { + "className": "red" + }, + "children": [{ + "componentName": "NavItem", + "props": {} + }] + }] + }] + }], + "utils": [{ + "name": "clone", + "type": "npm", + "content": { + "package": "lodash", + "version": "0.0.1", + "exportName": "clone", + "subName": "", + "destructuring": false, + "main": "/lib/clone" + } + }, { + "name": "beforeRequestHandler", + "type": "function", + "content": { + "type": "JSFunction", + "value": "function(){\n ... \n}" + } + }], + "css": "body {font-size: 12px;} .table { width: 100px;}", + "config": { // 当前应用配置信息 + "sdkVersion": "1.0.3", // 渲染模块版本 + "historyMode": "hash", // 浏览器路由:browser 哈希路由:hash + "container": "J_Container", + "layout": { + "componentName": "BasicLayout", + "props": { + "logo": "...", + "name": "测试网站" + }, + }, + "theme": { + // for Fusion use dpl defined + "package": "@alife/theme-fusion", + "version": "^0.1.0", + // for Antd use variable + "primary": "#ff9966" + } + }, + "meta": { // 应用元数据信息 + "name": "demo 应用", // 应用中文名称, + "git_group": "appGroup", // 应用对应 git 分组名 + "project_name": "app_demo", // 应用对应 git 的 project 名称 + "description": "这是一个测试应用", // 应用描述 + "spma": "spa23d", // 应用 spma A 位信息 + "gmt_create": "2020-02-11 00:00:00", // 创建时间 + "gmt_modified": "2020-02-11 00:00:00", // 修改时间 + ... + }, + "i18n": { + "zh-CN": { + "i18n-jwg27yo4": "你好", + "i18n-jwg27yo3": "中国" + }, + "en-US": { + "i18n-jwg27yo4": "Hello", + "i18n-jwg27yo3": "China" + } + } +} +``` + +## 3.2 文件目录 + +以下是推荐的应用目录结构,与标准源码 build-scripts 对齐,这里的目录结构是帮助理解应用级协议的设计,不做强约束 + +```html +├── META/ # 低代码元数据信息,用于多分支冲突解决、数据回滚等功能 +├── public/ # 静态文件,构建时会 copy 到 build/ 目录 +│ ├── index.html # 应用入口 HTML +│ └── favicon.png # Favicon +├── src/ +│ ├── components/ # 应用内的低代码业务组件 +│ │ └── guide-component/ +│ │ ├── index.js # 组件入口 +│ │ ├── components.js # 组件依赖的其他组件 +│ │ ├── schema.js # schema 描述 +│ │ └── index.scss # css 样式 +│ ├── pages/ # 页面 +│ │ └── home/ # Home 页面 +│ │ ├── index.js # 页面入口 +│ │ └── index.scss # css 样式 +│ ├── layouts/ +│ │ └── basic-layout/ # layout 组件名称 +│ │ ├── index.js # layout 入口 +│ │ ├── components.js # layout 组件依赖的其他组件 +│ │ ├── schema.js # layout schema 描述 +│ │ └── index.scss # layout css 样式 +│ ├── config/ # 配置信息 +│ │ ├── components.js # 应用上下文所有组件 +│ │ ├── routes.js # 页面路由列表 +│ │ └── app.js # 应用配置文件 +│ ├── utils/ # 工具库 +│ │ └── index.js # 应用第三方扩展函数 +│ ├── locales/ # [可选]国际化资源 +│ │ ├── en-US +│ │ └── zh-CN +│ ├── global.scss # 全局样式 +│ └── index.jsx # 应用入口脚本, 依赖 config/routes.js 的路由配置动态生成路由; +├── webpack.config.js # 项目工程配置,包含插件配置及自定义 webpack 配置等 +├── README.md +├── package.json +├── .editorconfig +├── .eslintignore +├── .eslintrc.js +├── .gitignore +├── .stylelintignore +└── .stylelintrc.js +``` + +## 3.3 应用级别 APIs +> 下文中 `xxx` 代指任意 API +### 3.3.1 路由 Router API + - this.location.`xxx` + - this.history.`xxx` + - this.match.`xxx` + +### 3.3.2 应用级别的公共函数或第三方扩展 + - this.utils.`xxx` + +### 3.3.3 国际化相关 API +| API | 函数签名 | 说明 | +| -------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------ | +| this.i18n | (i18nKey: string, params?: { [paramName: string]: string; }) => string | i18nKey 是语料的标识符,params 可选,是用来做模版字符串替换的。返回语料字符串 | +| this.getLocale | () => string | 返回当前环境语言 code | +| this.setLocale | (locale: string) => void | 设置当前环境语言 code | + +**使用范例:** +```json +{ + "componentsTree": [{ + "componentName": "Page", + "fileName": "Page1", + "props": {}, + "children": [{ + "componentName": "Div", + "props": {}, + "children": [{ + "componentName": "Button", + "props": { + "children": { + "type": "JSExpression", + "value": "this.i18n('i18n-hello')" + }, + "onClick": { + "type": "JSFunction", + "value": "function () { this.setLocale('en-US'); }" + } + }, + }, { + "componentName": "Button", + "props": { + "children": { + "type": "JSExpression", + "value": "this.i18n('i18n-chicken', { count: this.state.count })" + }, + }, + }] + }], + }], + "i18n": { + "zh-CN": { + "i18n-hello": "你好", + "i18n-chicken": "我有${count}只鸡" + }, + "en-US": { + "i18n-hello": "Hello", + "i18n-chicken": "I have ${count} chicken" + } + } +} +``` diff --git a/specs/material-spec.md b/specs/material-spec.md new file mode 100644 index 0000000000..790063e7af --- /dev/null +++ b/specs/material-spec.md @@ -0,0 +1,1821 @@ +# 《低代码引擎物料协议规范》 + +# 1 介绍 + +## 1.1 本协议规范涉及的问题域 + +- 定义本协议版本号规范 +- 定义本协议中每个子规范需要被支持的 Level +- 定义中后台物料目录规范(A) +- 定义中后台物料 API 规范(A) +- 定义中后台物料入库规范(A) +- 定义中后台物料国际化多语言支持规范(AA) +- 定义中后台物料主题配置规范(AAA) +- 定义中后台物料无障碍访问规范(AAA) + + +## 1.2 协议草案起草人 + +- 撰写:九神、大果、元彦、戊子、林熠、屹凡、金禅 +- 审阅:潕量、月飞、康为、力皓、荣彬、暁仙、度城、金禅、戊子、林熠、絮黎 + +## 1.3 版本号 + +1.0.0 + +## 1.4 协议版本号规范(A) + +本协议采用语义版本号,版本号格式为 `major.minor.patch` 的形式。 + +- major 是大版本号:用于发布不向下兼容的协议格式修改 +- minor 是小版本号:用于发布向下兼容的协议功能新增 +- patch 是补丁号:用于发布向下兼容的协议问题修正 + + +## 1.5 协议中子规范 Level 定义 + +| 规范等级 | 实现要求 | +| -------- | ---------------------------------------------------------------------------------- | +| A | 强制规范,必须实现;违反此类规范的协议描述数据将无法写入物料中心,不支持流通。 | +| AA | 推荐规范,推荐实现;遵守此类规范有助于业务未来的扩展性和跨团队合作研发效率的提升。 | +| AAA | 参考规范,根据业务场景实际诉求实现;是集团层面鼓励的技术实现引导。 | + +## 1.6 名词术语 +- **物料**:能够被沉淀下来直接使用的前端能力,一般表现为业务组件、区块、模板。 +- **业务组件(Business Component)**:业务领域内基于基础组件之上定义的组件,可能会包含特定业务域的交互或者是业务数据,对外仅暴露可配置的属性,且必须发布到公域(如阿里 NPM);在同一个业务域内可以流通,但不需要确保可以跨业务域复用。 + - **低代码业务组件(Low-Code Business Component)**:通过低代码编辑器搭建而来,有别于源码开发的业务组件,属于业务组件中的一种类型,遵循业务组件的定义;同时低代码业务组件还可以通过低代码编辑器继续多次编辑。 +- **区块(Block)**:通过低代码搭建的方式,将一系列业务组件、布局组件进行嵌套组合而成,不对外提供可配置的属性。可通过区块容器组件的包裹,实现区块内部具备有完整的样式、事件、生命周期管理、状态管理、数据流转机制。能独立存在和运行,可通过复制 schema 实现跨页面、跨应用的快速复用,保障功能和数据的正常。 +- **模板(Template)**:特定垂直业务领域内的业务组件、区块可组合为单个页面,或者是再配合路由组合为多个页面集,统称为模板。 + +## 1.7 物料规范背景 +目前集团业务融合频繁,而物料规范的不统一给业务融合带来额外的高成本,另一方面集团各个 BU 的前端物料也存在不同程度的重复建设。我们期望通过集团层面的物料通不阻碍业务融合的发展,同时通过集团层面的物料流通来提升物料丰富度,通过丰富物料的复用来提效中后台系统研发,同时也能给新业务场景提供高质量的启动物料。 + +## 1.8 物料规范定义 + +- **源码物料规范**:一套面向开发者的目录规范,用于规范化约束开发过程中的代码、文档、接口规范,以方便物料在集团内的流通。 +- **搭建物料规范**:一套面向开发者的 Schema 规范,用于规范化约束开发过程中的代码、文档、接口规范,以方便物料在集团内的流通。 + +# 2. 物料规范 - 业务组件规范 + +## 2.1 源码规范 + +### 2.1.1 目录规范(A) + + +``` +component // 组件名称, 比如 biz-button + ├── build // 【编译生成】【必选】 + │ └── index.html // 【编译生成】【必选】可直接预览文件 + ├── lib // 【编译生成】【必选】 + │ ├── index.js // 【编译生成】【必选】js 入口文件 + │ ├── index.scss // 【编译生成】【必选】css 入口文件 + │ └── style.js // 【编译生成】【必选】js 版本 css 入口文件,方便去重 + ├── demo // 【必选】组件文档目录,可以有多个 md 文件 + │ └── basic.md // 【必选】组件文档示例,用于生成组件开发预览,以及生成组件文档 + ├── src // 【必选】组件源码 + │ ├── index.js // 【必选】组件出口文件 + │ └── index.scss // 【必选】仅包含组件自身样式的源码文件 + ├── README.md // 【必选】组件说明及 API + └── package.json // 【必选】组件 package.json +``` + + +#### README.md + +- README.md 应该包含业务组件的源信息、使用说明以及 API,示例如下: + +``` +# 按钮 // 这一行是标题 + +按钮用于开始一个即时操作。 // 这一行是描述 + +{这段通过工程能力自动注入, 开发者无需编写 +## 安装方法 +npm install @alifd/ice-layout -S +} + +## API + +| 参数 | 说明 | 类型 | 可选值 | 默认值 | +| ---- | ---- | ------ | ------------------- | ------ | +| type | 类型 | String | `primary`、`normal` | `normal` | +``` + + + +- README.en-US.md(文件命名采取 [bcp47 规范](http://www.rfc-editor.org/rfc/bcp/bcp47.txt))多语言的情况,可选 + +``` +# Button + +Button use to trigger an action. + +{这段通过工程能力自动注入, 开发者无需编写 +## Install +npm install @alifd/ice-layout -S +} + +## API + +| Param | Description | Type | Enum | Default | +| ----- | ----------- | ------ | ------------------- | ------- | +| type | type | String | `primray`、`normal` | normal | +``` + +#### package.json +`package.json` 中包含了一些依赖信息和配置信息,示例如下: + +```json +{ + "name": "@alife/1688-button", + "description": "业务组件描述", + "version": "0.0.1", + "main": "lib/index.js", + "stylePath": "lib/style.js", // 【私有字段】样式文件地址,webpack 插件引用 + "files": [ + "demo/", + "lib/", + "build/" // 存放编译后的 demo,发布前应该编译生成该目录 + ], + "dependencies": { + "@alifd/next": "1.x" // 【可选】可以是一个 util 类型的组件,如果依赖 next,请务必写语义化版本号,不要写*这种 + }, + "devDependencies": { + "react": "^16.5.0", + "react-dom": "^16.5.0" + }, + "peerDependencies": { + "react": "^16.5.0" + }, + "componentConfig": { // 【私有字段】组件配置信息 + "name": "button", // 组件英文名 + "title": "按钮", // 组件中文名 + "category": "form" // 组件分类 + } +} +``` + +#### src/index.js + +包含组件的出口文件,示例如下: + +```javascript +import Button from './Button.jsx'; +import ButtonGroup from './ButtonGroup.jsx'; + +export const Group = ButtonGroup; // 子组件推荐写法 + +export default Button; +``` + +推荐用法 + +```javascript +import Button, { Group } form '@scope/button'; +``` + +#### src/index.scss + +```css +/* 不引入依赖组件的样式,比如组件 import { Button } from '@alifd/next'; */ +/* 不需要在 index.scss 中引入 @import '~@alifd/next/lib/button/index.scss'; */ + +/* 如果需要引入主题变量引入此段 */ +@import '~@alifd/next/variables.scss'; + +/* 组件自身样式 */ +.custom-component { + color: $color-brand1-1; +} +``` + +#### demo +demo 目录存放的是组件的文档,无文档的业务组件无法带来任何价值,因此 demo 是必选项。demo 目录下的文件采取 markdown 的写法,可以是多个文件,示例(demo/basic.md)如下: + +demo/basic.md + +~~~ +--- +title: {按钮类型} +order: {文档的排序,数字,0 最小,从小到大排序} +--- + +按钮有三种视觉层次:主按钮、次按钮、普通按钮。不同的类型可以用来区别按钮的重要程度。 + +:::lang=en-US +--- +title: Container +order: 3 +--- + +Change the default container by passing a function to `container`; +enable `useAbsolute` to use `absolute position` to implement affix component; + +::: + +```jsx // 以下建议用英文编写 +import Button from '@alife/1688-button'; + +ReactDOM.render(
+ +
, mountNode); +``` + +```css +.test { + background: #CCC; +} +``` +~~~ + +### 2.1.2 API 规范(A) + +API 是组件的属性解释,给开发者作为组件属性配置的参考。为了保持 API 的一致性,我们制定这个 API 命名规范。对于业界通用的,约定俗成的命名,我们遵循社区的约定。对于业界有多种规则难以确定的,我们确定其中一种,大家共同遵守。 + +#### 通用规则 + +- 所有的 API 采用小驼峰的书写规则,如 `onChange`、`direction`、`defaultVisible`。 +- 标签名采用大驼峰书写规则,如 `Menu`、`Slider`、`DatePicker`。 + +#### 通用命名 + +| API 名称 | 类型 | 描述 | 常见变量 | +| :------------- | :------------- | :----------------------------------------------------------- | :---------------------------------------------------- | +| shape | string | 形状,从组件的外形来看有区别的时候,使用 shape | | +| direction | enum | 方向,取值采用缩写的方式。 | hoz(水平), ver(垂直) | +| align | enum | 对齐方式 | tl, tc, tr, cl, cc, cr, bl, bc, br | +| status | enum | 状态 | normal, success, error, warning | +| size | enum | 大小 | small, medium, large 更大或更小可用(xxs, xs, xl, xxl) | +| type | enum or string | 分类:1. dom 结构不变、只有皮肤的变化 2.组件类型只有并列的几类 | normal, primary, secondary | +| visible | boolean | 是否显示 | | +| defaultVisible | boolean | 是否显示(非受控) | | +| disabled | boolean | 禁用组件 | | +| closable | bool/string | 允许关闭的方式 | | +| htmlType | string | 当原生组件与 Fusion 组件的 type 产生冲突时,原生组件使用 `htmlType` | | +| link | string | 链接 | | +| dataSource | array | 列表数据源 | [{label, value}, {label, value}] | +| has+'属性' | boolean | 拥有某个属性 | 例如 `hasArrow`, `hasHeader`, `hasClose` 等等 | + + +#### 多选枚举 + +当某个 API 的接口,允许用户指定多个枚举值的时候,我们把这个接口定义为多选枚举。一个很典型的例子是某个弹层组件的 `closable` 属性,我们会允许:键盘 esc 按键、点击 mask、点击 close 按钮、点击组件以外的任何区域进行关闭。 + +不要有一个 API 值,支持多种类型。例如某个弹层的组件,我们会允许 esc、点击 mask、点击 close 按钮等进行关闭。此时 API 设计可以通过多个 API 承载,例如: + +```js +closable?: boolean; // 默认为 true +closeMode?: CM[] | string; // 默认值是 ['close', 'mask', 'esc'] +``` + +true 表示触发规则都会关闭,false 表示触发规则不会关闭。 + +示例: + +- ``,所有合法条件都会关闭 +- ``,任何情况下都不关闭,只能通过受控设置 visible +- ``,用户按 esc 或者点击关闭按钮会关闭 + +#### 事件 + +- 标准事件或者自定义的符合 w3c 标准的事件,命名必须 on 开头, 即 `on` + 事件名,如 onExpand。 + +#### 表单规范 + +- 支持[受控模式](https://reactjs.org/docs/forms.html#controlled-components)(value + onChange) (A) + - value 控制组件数据展现 + - onChange 组件发生变化时候的回调函数(第一个参数可以给到 value) +- `value={undefined}` 的时候清空数据, field 的 reset 函数会给所有组件下发 undefined 数据 (AA) +- 一次完整操作抛一次 onChange 事件 `建议` 比如有 Process 表示进展中的状态,建议增加 API `onProcess`;如果有 Start 表示启动状态,建议增加 API `onStart`  (AA) + +#### 属性的传递 +**1. 原子组件(Atomic Component)** +> 最小粒子,不能再拆分的组件 + +举例:Input/Button/NumberPicker + +期望使用起来像普通的 html 标签一样,能够把用户传入的参数,透传到真正的节点上。 + +```jsx + +``` + +渲染后的 dom 结构: + +```jsx + + + +``` + +**2. 复合组件(Composite component)** + +复合组件一般由两个及以上的原子组件/复合组件构成,比如:Select 由 Inupt + 弹窗组成,Search 由 Select + Button 组成,TreeSelect 由 Tree + Select 组成。 + +为了提高组件使用的便利性,对 API 属性的要求如下: +1. 复合组件核心的原子组件(比如 Search 的核心原子组件是 Input)的属性以及使用频率高的属性建议扁平化,让复合组件可以直接使用其属性; +2. 复合组件内的非核心原子组件,则通过 `xxxProps` (如 inputProps/btnProps)的方式,将参数传递到相应原子组件上。 + + +**属性扁平化例子**: + +比如 `Search` 组件由 `Input` 和 `Button` 构成,但是 `Search` 更像是 `Input` ,因此把 `Input` 作为主要组件,将属性扁平化。即在 `Search` 组件上直接使用一些 `Input` 的属性。 `` + +比如 `Select` `TreeSelect` 都有弹层部分,`Overlay` `Overlay.Popup` 的 `visible` 属性使用率较高,一般用于 fixed 布局下的弹窗滚动跟随。因此把该属性暴露到最外层,简化使用 ` +``` + +渲染后的 dom 结构: + +```jsx + + + +``` + +**2. 复合组件(Composite component)** + +复合组件一般由两个及以上的原子组件/复合组件构成,比如:Select 由 Inupt + 弹窗组成,Search 由 Select + Button 组成,TreeSelect 由 Tree + Select 组成。 + +为了提高组件使用的便利性,对 API 属性的要求如下: +1. 复合组件核心的原子组件(比如 Search 的核心原子组件是 Input)的属性以及使用频率高的属性建议扁平化,让复合组件可以直接使用其属性; +2. 复合组件内的非核心原子组件,则通过 `xxxProps` (如 inputProps/btnProps)的方式,将参数传递到相应原子组件上。 + + +**属性扁平化例子**: + +比如 `Search` 组件由 `Input` 和 `Button` 构成,但是 `Search` 更像是 `Input` ,因此把 `Input` 作为主要组件,将属性扁平化。即在 `Search` 组件上直接使用一些 `Input` 的属性。 `` + +比如 `Select` `TreeSelect` 都有弹层部分,`Overlay` `Overlay.Popup` 的 `visible` 属性使用率较高,一般用于 fixed 布局下的弹窗滚动跟随。因此把该属性暴露到最外层,简化使用 `
+ ), + }; +}; +``` + +### 高级配置 + +#### 不展现一个 prop 配置 + +- 始终隐藏当前 prop + +```tsx +{ + // 始终隐藏当前 prop 配置 + condition: () => false +} +``` + +- 根据其它 prop 的值展示/隐藏当前 prop + +```tsx +{ + // direction 为 hoz 则展示当前 prop 配置 + condition: (target) => { + return target.getProps().getPropValue('direction') === 'hoz'; + } +} +``` + +#### props 联动 + +```tsx +// 根据当前 prop 的值动态设置其它 prop 的值 +{ + name: 'labelAlign', + // ... + extraProps: { + setValue: (target, value) => { + if (value === 'inset') { + target.getProps().setPropValue('labelCol', null); + target.getProps().setPropValue('wrapperCol', null); + } else if (value === 'left') { + target.getProps().setPropValue('labelCol', { fixedSpan: 4 }); + target.getProps().setPropValue('wrapperCol', null); + } + return target.getProps().setPropValue('labelAlign', value); + }, + }, +} +// 根据其它 prop 的值来设置当前 prop 的值 +{ + name: 'status', + // ... + extraProps: { + getValue: (target) => { + const isPreview = target.getProps().getPropValue('isPreview'); + return isPreview ? 'readonly' : 'editable'; + } + } +} +``` + +#### 动态 setter 配置 + +可以通过 DynamicSetter 传入的 target 获取一些引擎暴露的数据,例如当前有哪些组件被加载到引擎中,将这个数据作为 SelectSetter 的选项,让用户选择: + +```tsx +{ + setter: (target) => { + return { + componentName: 'SelectSetter', + props: { + options: target.designer.props.componentMetadatas.filter( + (item) => item.isFormItemComponent).map( + (item) => { + return { + title: item.title || item.componentName, + value: item.componentName, + }; + } + ), + ), + } + }; + } +} +``` diff --git a/docs/docs/guide/expand/editor/partsIntro.md b/docs/docs/guide/expand/editor/partsIntro.md new file mode 100644 index 0000000000..6e56ae1e64 --- /dev/null +++ b/docs/docs/guide/expand/editor/partsIntro.md @@ -0,0 +1,100 @@ +--- +title: 利用Parts造物快速使用react组件 +sidebar_position: 3 +--- +## 介绍 +大家在使用[低代码引擎](https://lowcode-engine.cn/)构建低代码应用平台时,遇到的一个主要问题是如何让已有的 React 组件能够快速低成本地接入进来。这个问题拆解下来主要包括两个子问题:1. 如何给已有组件[配置物料描述](https://lowcode-engine.cn/material),2. 如何构建出一个低代码引擎能够识别的资产包(Assets)。 +我们的产品 「[Parts·造物](https://parts.lowcode-engine.cn/)」 可以帮助大家解决这个问题。我们通过在线可视化的方式完成物料描述配置,并且提供一键打包的功能生成引擎可以识别的资产包。 + +## 导入物料 +首先,我们需要在 [物料管理](https://parts.lowcode-engine.cn/material#/) 页面导入我们需要进行在线物料描述配置的物料。 +![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434800993-0fbf5ed5-63e5-492b-85ab-feafd663ad2d.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=196&id=u918deb34&margin=%5Bobject%20Object%5D&name=image.png&originHeight=342&originWidth=1399&originalType=binary&ratio=1&rotation=0&showTitle=false&size=33102&status=done&style=stroke&taskId=u95c39b84-836c-45f8-aee6-0effc1ccfd1&title=&width=800) + +- 点击列表左上方的 导入已有物料 按钮 +- 在弹框中输入 npm包名 +- 点击 获取包信息 按钮,获取npm包基本信息 +- 点击确定,导入成功 + +![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434801003-7bd783f0-8804-445e-b508-8601501dfa60.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u825d698a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=315&originWidth=640&originalType=binary&ratio=1&rotation=0&showTitle=false&size=21969&status=done&style=stroke&taskId=ued992c2e-822b-4c32-81b5-9c9add84954&title=) +## 配置管理 +第二步:物料导入以后,我们就可以为导入的物料新增[物料描述配置](https://lowcode-engine.cn/material),点击右侧的组件配置开始配置。 + +![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434801125-979e6348-b78a-47b4-bb2e-fa8f1bb4ff90.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=216&id=u7fb954eb&margin=%5Bobject%20Object%5D&name=image.png&originHeight=261&originWidth=965&originalType=binary&ratio=1&rotation=0&showTitle=false&size=15305&status=done&style=stroke&taskId=uc1e18ffd-fe76-4fe4-83a4-c907f308b14&title=&width=800) +### 新增配置 + +- 点击配置管理右上角的 新增配置 + - 选择组件的版本号 + - 填写组件路径,一般和 npm 包的 package.json 里的 main 字段相同 (如果填写错误,后面会渲染不出来) + - 描述字段用于给这份配置增加一些备注信息。 + +![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434801095-1957da7f-5d9d-4c17-a762-c576bf0f763f.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=380&id=u9ad0ec47&margin=%5Bobject%20Object%5D&name=image.png&originHeight=418&originWidth=596&originalType=binary&ratio=1&rotation=0&showTitle=false&size=26130&status=done&style=stroke&taskId=u2b592498-195a-4fec-9853-ec5c3b95ef7&title=&width=541.8181700745893) +为了降低配置成本,第一次新增配置的时候会自动解析组件代码,生成一份初始化组件物料描述。所以需要等待片刻,用于代码解析。解析完成后,点击配置按钮即可进入在线配置界面。 +![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434801053-1a48b598-e987-4cd5-b657-030d345e0a99.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=193&id=ud384a13d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=232&originWidth=963&originalType=binary&ratio=1&rotation=0&showTitle=false&size=23541&status=done&style=stroke&taskId=ud2efc4d3-6d52-4b77-adbd-14dd5ee4b11&title=&width=800) +### 组件描述配置 +操作界面如下,接下来讲具体的配置流程 +![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434802081-6546d0f5-19da-475e-8dec-93ea324cc4e3.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=522&id=uf73c4753&margin=%5Bobject%20Object%5D&name=image.png&originHeight=938&originWidth=1438&originalType=binary&ratio=1&rotation=0&showTitle=false&size=111984&status=done&style=stroke&taskId=u0ce37d2b-8ca3-48b5-ac67-8fb461d17b5&title=&width=800) +#### 新增组件 +如果新增配置的过程中,代码自动解析失败或者解析出来的组件列表不满足开发要求,我们可以点击左侧组件列表插件 新增 按钮,添加新的组件,具体的字段描述可以参考提示内容,以 [react-color](https://github.com/casesandberg/react-color) 为例: +![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434802087-eaf4e2f1-2028-4415-b696-9788a6b2d0ed.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=560&id=u4341eb1b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1005&originWidth=1436&originalType=binary&ratio=1&rotation=0&showTitle=false&size=147918&status=done&style=stroke&taskId=ud921b52d-1961-4be9-b4ec-77d6364b213&title=&width=800) +![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434802555-bbd14a55-89a6-42cd-a4b3-76c98febf00c.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=472&id=u06e0b78f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=704&originWidth=1193&originalType=binary&ratio=1&rotation=0&showTitle=false&size=240470&status=done&style=stroke&taskId=u77603c5d-9d14-4379-86d2-deb4deaba50&title=&width=800) +#### 给组件增加物料描述 +选中刚刚新增的BlockPicker组件,然后给它增加描述: + +- 打开左侧 Sette r面板 +- 按照组件的属性拖入需要 Setter 类型 (如图中组件的width属性,拖入数字Setter) +- 各种 Setter 的介绍可以参看这篇文档:[https://www.yuque.com/lce/doc/grfylu](https://www.yuque.com/lce/doc/grfylu) +- 配置属性的基本信息(如图所示) +- 配置完成后点击右上角的保存 + +![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434802458-b0fb8a0e-307e-458c-a9f9-af3d2697024c.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=539&id=udeb647da&margin=%5Bobject%20Object%5D&name=image.png&originHeight=967&originWidth=1434&originalType=binary&ratio=1&rotation=0&showTitle=false&size=158958&status=done&style=stroke&taskId=u2950484f-659b-4643-af5e-75d04f14346&title=&width=800) +![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434802443-cdc533bf-1b08-4c11-b3d2-7cfd7fe0a5dd.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=311&id=uaaaa88fb&margin=%5Bobject%20Object%5D&name=image.png&originHeight=360&originWidth=925&originalType=binary&ratio=1&rotation=0&showTitle=false&size=64587&status=done&style=stroke&taskId=u7139e8ef-eee3-468b-833c-a42d8f3cb56&title=&width=800) +#### 高级配置(属性联动) +举个栗子:如图所示,如果期望 “设置器” 这个配置项的值 “被修改”的时候,下面的 “默认值” 跟着变化。 +![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434803379-009a9783-ec24-4a08-8a46-55ae775ce7ba.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=520&id=u005ad05e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=572&originWidth=371&originalType=binary&ratio=1&rotation=0&showTitle=false&size=96588&status=done&style=stroke&taskId=u97330f9d-6728-4a05-a842-55df114ccee&title=&width=337.27271996253796) +如何使用 +组件的属性配置目前支持3个基本的联动函数: + +- 显示状态:返回true | false,如果返回true,表示组件配置显示,否则配置时不显示 +- 获取值:当调用该配置节点的getValue方法时触发的方法 +- 值变化:当调用该配置节点的setValue方法时触发的方法 + +![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434803522-85aed489-4e00-4787-a496-54cc73e25bc5.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=129&id=u0a782260&margin=%5Bobject%20Object%5D&name=image.png&originHeight=142&originWidth=316&originalType=binary&ratio=1&rotation=0&showTitle=false&size=29086&status=done&style=stroke&taskId=u95864da5-4ccf-4e4b-b903-1ce26af4f66&title=&width=287.2727210462587) +方法的第一个参数都是当前配置节点的对象,常用到的有以下几个: + +- getValue(): 获取当前节点的值,如果当前节点是子节点的话,否则为undefined +- setValue(): 设置当前节点的值,如果当前节点是子节点的话 +- parent: 当前节点的父节点 +- getPropValue(propName): 父节点获取子节点的属性值,propName为子节点的属性名称 +- setPropValue(propName, value): 父节点设置子节点的属性值,propName为子节点的属性名称, value 为设置的值 +- getConfig: 获取当前节点的配置,如title、setter等 +#### 调试物料描述 +点击右上角的预览按钮,开始调试我们刚刚配置的属性,如果是组件的首次预览,会有一段组件构建的过程(构建出umd包的过程),构建完成后就可以调试我们的配置了。 +![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434804408-717e49bd-26b3-4a28-b3e5-bd1d67cdab00.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=209&id=ucf92cc3e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=373&originWidth=1431&originalType=binary&ratio=1&rotation=0&showTitle=false&size=46363&status=done&style=stroke&taskId=u501edca5-bbef-4fde-b341-b42c28b125a&title=&width=800) +#### 发布物料描述 +物料描述调试没问题后,就可以到项目中去使用了,使用前需要先发布物料描述 + +- 点击右上角的发布按钮 +- 选择需要发布的组件 +- 点击确定发布完成 + +![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434804305-276f03e2-4dd2-41e9-9375-1c3bd0c7092a.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=410&id=uf879e7fd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=734&originWidth=1431&originalType=binary&ratio=1&rotation=0&showTitle=false&size=103858&status=done&style=stroke&taskId=udc267585-ffb7-4247-b1f5-b7aca386e10&title=&width=800) +## 资产包构建 +第三步:物料描述发布完成后,接下来我们就需要构建出可用的资产包用于低代码应用中。 +#### 资产包构建 + +- 选择需要构建的组件 +- 点击构建资产包按钮 +- 选择刚刚的物料描述配置 +- 开始构建,构建完成后你将得到一份json文件(里面包含了物料描述和umd包),就可以到项目中使用了 + +![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434804769-6f6f60f1-9ee3-4561-972d-610f0616576e.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=430&id=ue119fa2b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=770&originWidth=1431&originalType=binary&ratio=1&rotation=0&showTitle=false&size=93492&status=done&style=stroke&taskId=ubfd97421-964b-4823-adc8-b056a588924&title=&width=800) +#### 资产包使用 +**方式一、在 **[**lowcode-demo**](https://github.com/alibaba/lowcode-demo)**中直接引用,可直接替换demo中原来的资产包文件:** +例如,在basic-fusion demo中,直接用你的资产包文件替换文件[assets.json](https://github.com/alibaba/lowcode-demo/blob/main/src/scenarios/basic-fusion/assets.json),即可快速使用自己的物料了。 +**方式二、将新的资产包内容和现有的资产包内容融合:** +将上面构建完成的资产包与你项目中的[assets.json文件](https://github.com/alibaba/lowcode-demo/blob/main/src/scenarios/basic-fusion/assets.json)合并,主要合并packages 和 components + +- packages中是构建好的umd包 +- components中是上面配置好的[物料描述](https://lowcode-engine.cn/material),你也可以在基础上二次加工 + +![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434804944-860abc0c-057c-46d5-a6e5-8d33fde8a762.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=676&id=u5499b1c9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=744&originWidth=1140&originalType=binary&ratio=1&rotation=0&showTitle=false&size=116233&status=done&style=stroke&taskId=u7be27934-77ce-4dd7-a406-1d402acef2c&title=&width=1036.36361390106) diff --git a/docs/docs/guide/expand/editor/pluginContextMenu.md b/docs/docs/guide/expand/editor/pluginContextMenu.md new file mode 100644 index 0000000000..603aa09c0f --- /dev/null +++ b/docs/docs/guide/expand/editor/pluginContextMenu.md @@ -0,0 +1,69 @@ +--- +title: 插件扩展-编排扩展 +sidebar_position: 6 +--- +## 场景一:扩展选中节点操作项 +### 增加节点操作项 +![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1647693318212-173890bc-b0b5-437b-9802-4b1fd9f74c5a.png#clientId=u2eca2bba-d284-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=254&id=u55228975&margin=%5Bobject%20Object%5D&name=image.png&originHeight=292&originWidth=1240&originalType=binary&ratio=1&rotation=0&showTitle=false&size=38144&status=done&style=none&taskId=u426cac9f-24ad-4d06-adbe-faca1896eaa&title=&width=1080) +选中节点后,在选中框的右上角有操作按钮,编排模块默认实现了查看组件直系父节点、复制节点和删除节点按钮外,还可以通过相关 API 来扩展更多操作,如下代码: +```typescript +import { plugins } from '@alilc/lowcode-engine'; +import { Icon, Message } from '@alifd/next'; + +const addHelloAction = (ctx: ILowCodePluginContext) => { + return { + async init() { + const { addBuiltinComponentAction } = ctx.material; + addBuiltinComponentAction({ + name: 'hello', + content: { + icon: , + title: 'hello', + action(node: Node) { + Message.show('Welcome to Low-Code engine'); + }, + }, + condition: (node: Node) => { + return node.componentMeta.componentName === 'NextTable'; + }, + important: true, + }); + } + }; +} +addHelloAction.pluginName = 'addHelloAction'; +await plugins.register(addHelloAction); +``` +**_效果如下:_** +![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1647694920149-b8d9a534-b943-45d2-b67e-cc42b906f827.png#clientId=u2eca2bba-d284-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=282&id=ua20a09c8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=343&originWidth=1315&originalType=binary&ratio=1&rotation=0&showTitle=false&size=35131&status=done&style=none&taskId=u3f47b55d-15ff-495c-8615-31e3ccb0222&title=&width=1080) +具体 API 参考:[https://www.yuque.com/lce/doc/mu7lml#ieJzi](https://www.yuque.com/lce/doc/mu7lml#ieJzi) +### 删除节点操作项 +```typescript +import { plugins } from '@alilc/lowcode-engine'; + +const removeCopyAction = (ctx: ILowCodePluginContext) => { + return { + async init() { + const { removeBuiltinComponentAction } = ctx.material; + removeBuiltinComponentAction('copy'); + } + } +} +removeCopyAction.pluginName = 'removeCopyAction'; +await plugins.register(removeCopyAction); +``` +**_效果如下:_** +![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1647695353667-e22bef51-3c6a-4b6a-87d2-c144ddb68115.png#clientId=u2eca2bba-d284-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=237&id=ufa1f9434&margin=%5Bobject%20Object%5D&name=image.png&originHeight=290&originWidth=1319&originalType=binary&ratio=1&rotation=0&showTitle=false&size=22495&status=done&style=none&taskId=u73e01acc-96e8-45e7-9d42-a31edca193e&title=&width=1080) +具体 API 参考:[https://www.yuque.com/lce/doc/mu7lml#va9mb](https://www.yuque.com/lce/doc/mu7lml#va9mb) +## 实际案例 +### 区块管理 + +- 仓库地址:[https://github.com/alibaba/lowcode-plugins](https://github.com/alibaba/lowcode-plugins) +- 具体代码:[https://github.com/alibaba/lowcode-plugins/tree/main/packages/action-block](https://github.com/alibaba/lowcode-plugins/tree/main/packages/action-block) +- 直播回放: + - [低代码引擎项目实战(9)-区块管理(1)-保存为区块](https://www.bilibili.com/video/BV1YF411M7RK/) + - [低代码引擎项目实战(10)-区块管理-区块面板](https://www.bilibili.com/video/BV1FB4y1S7tu/) + - [阿里巴巴低代码引擎项目实战(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/) diff --git a/docs/docs/guide/expand/editor/pluginWidget.md b/docs/docs/guide/expand/editor/pluginWidget.md new file mode 100644 index 0000000000..fd63167e93 --- /dev/null +++ b/docs/docs/guide/expand/editor/pluginWidget.md @@ -0,0 +1,170 @@ +--- +title: 插件扩展-面板扩展 +sidebar_position: 5 +--- +## 插件简述 +插件功能赋予低代码引擎更高的灵活性,低代码引擎的生态提供了一些官方的插件,但是无法满足所有人的需求,所以提供了强大的插件定制功能。 +通过定制插件,在和低代码引擎解耦的基础上,我们可以和引擎核心模块进行交互,从而满足多样化的功能。不仅可以自定义插件的 UI,还可以实现一些非 UI 的逻辑: +1)调用编辑器框架提供的 API 进行编辑器操作或者 schema 操作; +2)通过插件类的生命周期函数实现一些插件初始化的逻辑; +3)通过实现监听编辑器内的消息实现特定的切片逻辑(例如面板打开、面板关闭等) +> 本文仅介绍面板层面的扩展,编辑器插件层面的扩展可以参考 "插件扩展 - 编排扩展" 章节。 + +## 注册插件 API +```typescript +import { plugins, ILowCodePluginContext } from '@alilc/lowcode-engine'; + +const pluginA = (ctx: ILowCodePluginContext, options: any) => { + return { + init() { + console.log(options.key); + // 往引擎增加面板 + ctx.skeleton.add({ + // area 配置见下方说明 + area: 'leftArea', + // type 配置见下方说明 + type: 'PanelDock', + content:
demo
, + }); + ctx.logger.log('打个日志'); + }, + destroy() { + console.log('我被销毁了~'); + } + } +} + +pluginA.pluginName = 'pluginA'; + +plugins.register(pluginA, { key: 'test' }); +``` +> 如果您想了解抽取出来的插件如何封装成为一个 npm 包并提供给社区,可以参考“扩展低代码应用 - 扩展低代码编辑器 - 低代码插件脚手架”章节。 +插件系统的详细设计,可参考“参与低代码引擎开发 - 低代码引擎设计文档 - 插件”章节。 + +## 面板插件配置说明 +面板插件是作用于设计器的,主要是通过按钮、图标等展示在设计器的骨架中。设计器的骨架我们分为下面的几个区域,而我们的插件大多数都是作用于这几个区域的。 +![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644393006009-165e36cd-fa7b-4ee0-b3e3-dc7ba9d80d55.png#averageHue=%237cac76&clientId=u45843f36-7f71-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=608&id=u9e018f89&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1080&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=149463&status=done&style=stroke&taskId=u74f952e4-c783-47ae-b11c-be48d3c52be&title=&width=1080) +![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644320581783-b8fcd29c-45c2-48df-be2c-7101b12474e3.png#averageHue=%23edf6d4&clientId=u221f0bd4-c19e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=580&id=ixlrN&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1648&originWidth=3068&originalType=binary&ratio=1&rotation=0&showTitle=false&size=165621&status=done&style=stroke&taskId=u030d9faf-015f-4475-b34a-ba1fbf8868b&title=&width=1080) +### 展示区域 area +#### topArea +展示在设计器的顶部区域,常见的相关区域的插件主要是: +1)注册设计器 Logo; +2)设计器操作回退和撤销按钮; +3)全局操作按钮,例如:保存、预览等; +#### leftArea +左侧区域的展示形式大多数是 Icon 和对应的面板,通过点击 Icon 可以展示对应的面板并隐藏其他的面板。 +该区域相关插件的主要有: +1)大纲树展示,展示该设计器设计页面的大纲。 +2)组件库,展示注册到设计器中的组件,点击之后,可以从组件库面板中拖拽到设计器的画布中。 +3)数据源面板 +4)JS 等代码面板。 +可以发现,这个区域的面板大多数操作时是不需要同时并存的,且交互比较复杂的,需要一个更整块的区域来进行操作。 +#### centerArea +画布区域,由于画布大多数是展示作用,所以一般扩展的种类比较少。常见的扩展有: +1)画布大小修改 +2)物料选中扩展区域修改 +#### rightArea +右侧区域,常用于组件的配置。常见的扩展有:统一处理组件的配置项,例如统一删除某一个配置项,统一添加某一个配置项的。 +#### toolbar +跟 topArea 类似,按需放置面板插件~ +### 展示形式 type +#### PanelDock +PanelDock 是以面板的形式展示在设计器的左侧区域的。其中主要有两个部分组成,一个是图标,一个是面板。当点击图标时可以控制面板的显示和隐藏。 +下图是组件库插件的展示效果。 +![Feb-08-2022 19-44-15.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644320663827-ee9c54a1-f684-40e2-8a6b-875103d04b31.gif#averageHue=%23eaf6d2&clientId=u221f0bd4-c19e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=555&id=u5292d9cc&margin=%5Bobject%20Object%5D&name=Feb-08-2022%2019-44-15.gif&originHeight=790&originWidth=1536&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1381641&status=done&style=stroke&taskId=ub28a13a4-3d80-4a02-bcaa-cc9d6127243&title=&width=1080) +其中右上角可以进行固定,可以对弹出的宽度做设定 +接入可以参考代码 +```javascript +import { skeleton } from "@alilc/lowcode-engine"; + +skeleton.add({ + area: "leftArea", // 插件区域 + type: "PanelDock", // 插件类型,弹出面板 + name: "sourceEditor", + content: SourceEditor, // 插件组件实例 + props: { + align: "left", + icon: "wenjian", + description: "JS面板", + }, + panelProps: { + floatable: true, // 是否可浮动 + height: 300, + hideTitleBar: false, + maxHeight: 800, + maxWidth: 1200, + title: "JS面板", + width: 600, + }, +}); +``` +#### Widget +Widget 形式是直接渲染在当前编辑器的对应位置上。如 demo 中在设计器顶部的所有组件都是这种展现形式。 +![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644320068765-47efc836-30c2-452f-8104-b98b1ea3533d.png#averageHue=%23fefefb&clientId=u221f0bd4-c19e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=51&id=u68c58cad&margin=%5Bobject%20Object%5D&name=image.png&originHeight=94&originWidth=1988&originalType=binary&ratio=1&rotation=0&showTitle=false&size=58410&status=done&style=stroke&taskId=u4eadd643-2e63-4be7-8736-b27b9c82b81&title=&width=1080) +接入可以参考代码: +```javascript +import {skeleton} from "@alilc/lowcode-engine"; +// 注册 logo 面板 +skeleton.add({ + area: "topArea", + type: "Widget", + name: "logo", + content: Logo, // Widget 组件实例 + contentProps: { // Widget 插件props + logo: + "https://img.alicdn.com/tfs/TB1_SocGkT2gK0jSZFkXXcIQFXa-66-66.png", + href: "/", + }, + props: { + align: "left", + width: 100, + }, +}); +``` +#### Dock +一个图标的表现形式,可以用于语言切换、跳转到外部链接、打开一个 widget 等场景 +```javascript +import { skeleton } from "@alilc/lowcode-engine"; + +skeleton.add({ + area: "leftArea", + type: "Dock", + name: "opener", + content: Opener, // Widget 组件实例 + contentProps: { // Widget 插件props + xxx: "1", + }, + props: { + align: "bottom", + }, + onClick: function() { + // 打开外部链接 + window.open('https://lowcode-engine.cn'); + // 显示 widget + skeleton.showWidget('xxx'); + } +}); +``` +#### Panel +一般不建议单独使用,通过 PanelDock 使用~ +## 实际案例 +### 页面管理面板 + +- 仓库地址:[https://github.com/mark-ck/lowcode-portal](https://github.com/mark-ck/lowcode-portal) +- 具体代码:[https://github.com/mark-ck/lowcode-portal/blob/master/src/plugins/pages-plugin/index.tsx](https://github.com/mark-ck/lowcode-portal/blob/master/src/plugins/pages-plugin/index.tsx) +- 直播回放: + - [低代码引擎项目实战(4)-自定义插件-页面管理](https://www.bilibili.com/video/BV17a411i73f/) + - [低代码引擎项目实战(4)-自定义插件-页面管理-后端](https://www.bilibili.com/video/BV1uZ4y1U7Ly/) + - [低代码引擎项目实战(4)-自定义插件-页面管理-前端](https://www.bilibili.com/video/BV1Yq4y1a74P/) + - [低代码引擎项目实战(4)-自定义插件-页面管理-完结](https://www.bilibili.com/video/BV13Y4y1e7EV/) +### 区块面板 + +- 仓库地址:[https://github.com/alibaba/lowcode-plugins](https://github.com/alibaba/lowcode-plugins) +- 具体代码:[https://github.com/alibaba/lowcode-plugins/tree/main/packages/plugin-block](https://github.com/alibaba/lowcode-plugins/tree/main/packages/plugin-block) +- 直播回放: + - [低代码引擎项目实战(9)-区块管理(1)-保存为区块](https://www.bilibili.com/video/BV1YF411M7RK/) + - [低代码引擎项目实战(10)-区块管理-区块面板](https://www.bilibili.com/video/BV1FB4y1S7tu/) + - [阿里巴巴低代码引擎项目实战(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/) diff --git a/docs/docs/guide/expand/editor/setter.md b/docs/docs/guide/expand/editor/setter.md new file mode 100644 index 0000000000..846c60b3e5 --- /dev/null +++ b/docs/docs/guide/expand/editor/setter.md @@ -0,0 +1,202 @@ +--- +title: 设置器扩展 +sidebar_position: 4 +--- +## 设置器简述 +设置器主要用于低代码组件属性值的设置,顾名思义叫"设置器",又称为 Setter。由于组件的属性有各种类型,需要有与之对应的设置器支持,每一个设置器对应一个值的类型。 +### 设计器展示位置 +设置器展示在编辑器的右边区域,如下图: +![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644387351052-0be9546e-9e46-41ff-bbb4-a1effe650d7f.png#clientId=u39aebc41-90a1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=487&id=pi5XH&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1730&originWidth=3836&originalType=binary&ratio=1&rotation=0&showTitle=false&size=947162&status=done&style=stroke&taskId=u4d4deed8-40f5-40a6-b20d-d092c90775c&title=&width=1080) +其中包含四类设置器: + +- 属性:展示该物料常规的属性 +- 样式:展示该物料样式的属性 +- 事件:如果该物料有声明事件,则会出现事件面板,用于绑定事件。 +- 高级:两个逻辑相关的属性,**条件渲染**和**循环** +### 设置器类型 +上述区域中是有多项设置器的,对于一个组件来说,每一项配置都对应一个设置器,比如我们的配置是一个文本,我们需要的是文本设置器,我们需要配置的是数字,我们需要的就是数字设置器。 +下图中的标题和按钮类型配置就分别是文本设置器和下拉框设置器。 +![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644387350762-7337e729-53e9-4a6c-8da1-8f17260e1347.png#clientId=u39aebc41-90a1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=744&id=ztLvk&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1460&originWidth=2120&originalType=binary&ratio=1&rotation=0&showTitle=false&size=489840&status=done&style=stroke&taskId=u7375a322-b6c8-43f1-a096-07b204656aa&title=&width=1080) +我们提供了常用的设置器作为内置设置器,也提供了定制能力帮助大家开发特定需求的设置器。 +## 为物料配置设置器 +我们提供了[常用的设置器](https://www.yuque.com/lce/doc/oc220p?view=doc_embed&from=kb&from=kb&outline=1&title=1)作为内置设置器。 +我们可以将目标组件的属性值类型值配置到物料资源配置文件中: +```json +{ + "componentName": "Message", + "title": "Message", + "configure": { + "props": [ + { + "name": "type", + "setter": "InputSetter" + } + ] + } +} +``` +props 字段是入料模块扫描自动填入的类型,用户可以通过 configure 节点进行配置通过 override 节点对属性的声明重新定义,setter 就是注册在引擎中的 setter。 +为物料配置引擎内置的 setter 时,均可以使用对应 setter 的高级功能,对应功能参考“全部内置设置器”章节下的对应 setter 文章。 +**_对高级功能的配置如下:_** +例如我们需要在NumberSetter中配置units属性,可以在asset.json中声明 +```json +"configure": { + "component": { + "isContainer": true, + "nestingRule": { + "parentWhitelist": [ + "NextP" + ] + } + }, + "props": [ + { + "name": "width", + "title": "宽度", + "initialValue": "auto", + "defaultValue": "auto", + "condition": { + "type": "JSFunction", + "value": "() => false" + }, + "setter": { + "componentName": "NumberSetter", + "props": { + "units": [ + { + "type": "px", + "list": true + }, + { + "type": "%", + "list": true + } + ] + } + } + }, + ], + "supports": { + "style": true + } +}, +``` +## 自定义设置器 +### 编写 AltStringSetter +我们编写一个简单的 Setter,它的功能如下: +![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1644764687180-0121f0c0-d113-4907-a86d-e4f3a04ff221.png#clientId=ucb27c83c-48cf-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=45&id=u32dc8cd0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=90&originWidth=720&originalType=binary&ratio=1&rotation=0&showTitle=false&size=17539&status=done&style=stroke&taskId=u0f886bda-a93e-4b10-ad7e-9ba9a38a3fb&title=&width=360) +**_代码如下:_** +```typescript +import * as React from "react"; +import { Input } from "@alifd/next"; + +import "./index.scss"; +interface AltStringSetterProps { + // 当前值 + value: string; + // 默认值 + defaultValue: 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)} + > + ); + } +} +``` +#### setter 和 setter/plugin 之间的联动 +我们采用 emit 来进行相互之前的通信,首先我们在 A setter 中进行事件注册: +```javascript +import { event } from '@alilc/lowcode-engine'; + +componentDidMount() { + // 这里由于面板上会有多个setter,这里我用field.id来标记setter名 + this.emitEventName = `${SETTER_NAME}-${this.props.field.id}`; + event.on(`${this.emitEventName}.bindEvent`, this.bindEvent) +} + +bindEvent = (eventName) => { + // do someting +} + +componentWillUnmount() { + // setter是以实例为单位的,每个setter注销的时候需要把事件也注销掉,避免事件池过多 + event.off(`${this.emitEventName}.bindEvent`, this.bindEvent) +} +``` +在 B setter 中触发事件,来完成通信: +```javascript +import { event } from '@alilc/lowcode-engine'; + +bindFunction = () => { + const { field, value } = this.props; + // 这里展示的和插件进行通信,事件规则是插件名+方法 + event.emit('eventBindDialog.openDialog', field.name, this.emitEventName); +} +``` +#### 修改同级 props 的其他属性值 +setter 本身只影响其中一个 props 的值,如果需要影响其他组件的 props 的值,需要使用 field 的 props: +```json +bindFunction = () => { + const { field, value } = this.props; + const propsField = field.parent; + // 获取同级其他属性showJump的值 + const otherValue = propsField.getPropValue('showJump'); + // set同级其他属性showJump的值 + propsField.setPropValue('showJump', false); +} +``` +### 注册 AltStringSetter +我们需要在低代码引擎中注册 Setter,这样就可以通过 AltStringSetter 的名字在物料中使用了。 +```typescript +import AltStringSetter from './AltStringSetter'; +const registerSetter = window.AliLowCodeEngine.setters.registerSetter; +registerSetter('AltStringSetter', AltStringSetter); +``` +### 物料中使用 +我们需要将目标组件的属性值类型值配置到物料资源配置文件中,其中核心配置如下: +```json +{ + "props": [ + { + "name": "type", + "setter": "AltStringSetter" + } + ] +} +``` +在物料中的相关配置如下: +```json +{ + "componentName": "Message", + "title": "Message", + "configure": { + "props": [ + { + "name": "type", + "setter": "AltStringSetter" + } + ] + } +} +``` diff --git a/docs/docs/guide/expand/editor/summary.md b/docs/docs/guide/expand/editor/summary.md new file mode 100644 index 0000000000..e8487213cd --- /dev/null +++ b/docs/docs/guide/expand/editor/summary.md @@ -0,0 +1,90 @@ +--- +title: 低代码扩展简述 +sidebar_position: 0 +--- +## 扩展点简述 + +我们可以从 Demo 的项目中看到页面中有很多的区块: +![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643447049972-e324320a-7f97-4e48-bef3-a4c5d2b06517.png#clientId=udea0fe9a-4e7e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1080&id=rGr7U&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2160&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=518455&status=done&style=none&taskId=u872d1136-0f18-41b3-900d-710e9fc9eea&title=&width=1920) +这些功能点背后都是可扩展项目,如下图所示: +![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643447052089-8e340da7-3c2c-4a88-9ed8-c89516dccf75.png#clientId=udea0fe9a-4e7e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=957&id=lL1sN&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1914&originWidth=3838&originalType=binary&ratio=1&rotation=0&showTitle=false&size=538736&status=done&style=none&taskId=u43e8a14e-0d52-4a22-bd19-e5083814daf&title=&width=1919) + +- 插件定制:可以配置低代码编辑器的功能和面板 +- 物料定制:可以配置能够拖入的物料 +- 操作辅助区定制:可以配置编辑器画布中的操作辅助区功能 +- 设置器定制:可以配置编辑器中组件的配置表单 + +我们从可扩展项目的视角,可以把低代码引擎架构理解为下图: + +![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643447051959-7abb91ea-44af-46e0-b73a-dd2127648b32.png#clientId=udea0fe9a-4e7e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1080&id=M07o7&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2160&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=779021&status=done&style=none&taskId=u640e4616-d38d-45fb-a560-e4a98cd1605&title=&width=1920) +(注:引擎内核中大量数据交互的细节被简化,这张图仅仅强调编辑器和外部扩展的交互) + +## 配置扩展点 + +### 配置物料 +通过配置注入物料,这里的配置是物料中心根据物料资产包协议生成的,后面“物料扩展”章节会有详细说明。 +```typescript +import { material } from '@alilc/lowcode-engine' +// 假设您已把物料配置在本地 +import assets from './assets.json' + +// 静态加载 assets +material.setAssets(assets) +``` + +也可以通过异步加载物料中心上的物料。 +```typescript +import { ILowCodePluginContext, material, plugins } from '@alilc/lowcode-engine' + +// 动态加载 assets +plugins.register((ctx: ILowCodePluginContext) => { + 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) + } catch (err) { + console.error(err) + } + }, + } +}).catch(err => console.error(err)) +``` + +### 配置插件 +可以通过 npm 包的方式引入社区插件,配置如下所示: +```typescript +import { ILowCodePluginContext, plugins } from '@alilc/lowcode-engine' +import PluginIssueTracker from '@alilc/lowcode-plugin-issue-tracker' + +// 注册一个提 issue 组件到您的编辑器中,方位默认在左栏下侧 +plugins.register(PluginIssueTracker) + .catch(err => console.error(err)) +``` +后续“插件扩展”章节会详细说明。 + +### 配置设置器 +低代码引擎默认内置了设置器(详见“配置设置器”章节)。您可以通过 npm 包的方式引入自定义的设置器,配置如下所示: +```typescript +import { setters } from '@alilc/lowcode-engine' +// 假设您自定义了一个 setter +import MuxMonacoEditorSetter from './components/setters/MuxMonacoEditorSetter' + +// 注册设置器 +setters.registerSetter({ + MuxMonacoEditorSetter: { + component: MuxMonacoEditorSetter, + title: 'Textarea', + condition: (field) => { + const v = field.getValue() + return typeof v === 'string' + }, + }, +}) +``` +后续“设置器扩展”章节会详细说明。 + +> 本章节所有可扩展配置内容在 demo 中均可找到:[https://github.com/alibaba/lowcode-demo/blob/main/src/universal/plugin.tsx](https://github.com/alibaba/lowcode-demo/blob/main/src/universal/plugin.tsx) diff --git a/docs/docs/guide/expand/runtime/_category_.json b/docs/docs/guide/expand/runtime/_category_.json new file mode 100644 index 0000000000..14aafc9395 --- /dev/null +++ b/docs/docs/guide/expand/runtime/_category_.json @@ -0,0 +1,4 @@ +{ + "label": "扩展低代码运行时", + "position": 2 +} diff --git a/docs/docs/guide/expand/runtime/codeGeneration.md b/docs/docs/guide/expand/runtime/codeGeneration.md new file mode 100644 index 0000000000..e1d9dc3d88 --- /dev/null +++ b/docs/docs/guide/expand/runtime/codeGeneration.md @@ -0,0 +1,132 @@ +--- +title: 使用出码功能 +sidebar_position: 1 +--- + +## 出码简述 +所谓出码,即将低代码编排出的 schema 进行解析并转换成最终可执行的代码的过程。 +## 出码的适用范围 +出码是为了更高效的运行和更灵活地定制渲染,相对而言,基于 Schema 的运行时渲染,有着能实时响应内容的变化和接入成本低的优点,但是也存在着实时解析运行的性能开销比较大和包大小比较大的问题,而且无法自由地进行扩展二次开发,功能自由度受到一定程度限制。 +当然,出码也会存在一些限制:一方面需要额外的接入成本,另一方面通常需要额外的生成代码和打包构建的时间,难以做到基于 Schema 的运行时渲染那样保存即预览的效果。 + +所以不是所有场景都建议做出码,一般来说以下 3 个场景可以考虑使用出码进行优化。 + +### 场景一:想要极致的打开速度,降低 LCP/FID +这种场景比较常见的是 C 端应用,比如手淘上的页面和手机钉钉上的页面,要求能够尽快得响应用户操作,不要出现卡死的情况。当一个流入协议大小比较大的时候,前端进行解析时的开销也比较大。如果能把这部分负担转移到编译时去完成的话,前端依赖包大小就会减少许多。从而也提升了加载速度,降低了带宽消耗。页面越简单,这其中的 gap 就会越明显。 + +### 场景二:老项目 + 新需求,想用搭建产出 +这是一个很常见的场景,毕竟迁移或者重构都是有一个过程的,阿里的业务都是一边跑一边换发动机。在这种场景中,我们不可能要求使用运行时方案来做实现,因为运行时是一个项目级别的能力,最好是项目中统一使用他这一种方式,保证体验的一致性与连贯性。所以我们可以只在低代码平台上搭建新的业务页面,然后通过出码模块导出这些页面的源码,连同一些全局依赖模块,一起 Merge 到老项目中。完成开发体验的优化。 + +### 场景三:协议不能描述部分代码逻辑(协议功能不足或特别定制化的逻辑) +当我们发现一些逻辑诉求不能在目前协议中很好地表达的时候,这其实是项目复杂度较高的一个信号。比较好的方式就是将低代码研发和源码研发结合起来。这种模式下最大的诉求点之一就是,需要将搭建的内容输出为可读性和确定性都比较良好的代码模块。这也就是出码模块需要支持好的使用场景了。 + +## 如何使用 +### 1) 通过命令行快速体验 + +欢迎使用命令行工具快速体验:`npx @alilc/lowcode-code-generator -i example-schema.json -o generated -s icejs` + +--其中 example-schema.json 可以从[这里下载](https://unpkg.com/@alilc/lowcode-code-generator@beta/example-schema.json) + +### 2) 通过设计器插件快速体验 + +1. 安装依赖: `npm install --save @alilc/lowcode-plugin-code-generator` +2. 注册插件: + +```typescript +import { plugins } from '@alilc/lowcode-engine'; +import CodeGenPlugin from '@alilc/lowcode-plugin-code-generator'; + +// 在你的初始化函数中: +await plugins.register(CodeGenPlugin); + +// 如果您不希望自动加上出码按钮,则可以这样注册 +await plugins.register(CodeGenPlugin, { disableCodeGenActionBtn: true }); +``` + +然后运行你的低代码编辑器项目即可 -- 在设计器的右上角会出现一个“出码”按钮,点击即可在浏览器中出码并预览。 + +### 3)服务端出码接入 + +此代码生成器一开始就是为服务端出码设计的,你可以直接这样来在 node.js 环境中使用: + +1. 安装依赖: `npm install --save @alilc/lowcode-code-generator` +2. 引入代码生成器: + +```javascript +import CodeGenerator from '@alilc/lowcode-code-generator'; +``` + +3. 创建项目构建器: + +```javascript +const projectBuilder = CodeGenerator.solutions.icejs(); +``` + +4. 生成代码 + +```javascript +const project = await projectBuilder.generateProject( + schema, // 编排搭建出来的 schema +); +``` + +5. 将生成的代码写入到磁盘中(也可以生成一个 zip 包) + +```javascript +// 写入磁盘 +await CodeGenerator.publishers.disk().publish({ + project, // 上一步生成的 project + outputPath: '/path/to/your/output/dir', // 输出目录 + projectSlug: 'your-project-slug', // 项目标识 +}); + +// 写入到 zip 包 +await CodeGenerator.publishers.zip().publish({ + project, // 上一步生成的 project + outputPath: '/path/to/your/output/dir', // 输出目录 + projectSlug: 'your-project-slug', // 项目标识 -- 对应生成 your-project-slug.zip 文件 +}); +``` + +注:一般来说在服务端出码可以跟 github/gitlab, CI 和 CD 流程等一起串起来使用,通常用于优化性能。 + +### 4)浏览器中出码接入 + +随着现在电脑性能和浏览器技术的发展,出码其实已经不必非得在服务端做了,借助于 Web Worker 特性,可以在浏览器中进行出码: + +1. 安装依赖: `npm install --save @alilc/lowcode-code-generator` +2. 引入代码生成器: + +```javascript +import * as CodeGenerator from '@alilc/lowcode-code-generator/standalone-loader'; +``` + +3. 【可选】提前初始化代码生成器: + +```javascript +// 提前初始化下,这样后面用的时候更快(这个 init 内部会提前准备好创建 worker 的一些资源) +await CodeGenerator.init(); +``` + +4. 出码 + +```javascript +const result = await CodeGenerator.generateCode({ + solution: 'icejs', // 出码方案 (目前内置有 icejs 和 rax ) + schema, // 编排搭建出来的 schema +}); + +console.log(result); // 出码结果(默认是递归结构描述的,可以传 flattenResult: true 以生成扁平结构的结果) +``` + +注:一般来说在浏览器中出码适合做即时预览功能。 + +### 5)自定义出码 +前端框架灵活多变,默认内置的出码方案很难满足所有人的需求,好在此代码生成器支持非常灵活的插件机制 -- 内置功能大多都是通过插件完成的(在 `src/plugins`下),比如: +![image.png](https://cdn.nlark.com/yuque/0/2022/png/263300/1644824565650-584c2be5-4be3-4c9a-96d9-e27990111b0b.png#averageHue=%232b2b2e&clientId=u8b65d964-7bef-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=376&id=u3e0a61a8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=376&originWidth=457&originalType=binary&ratio=1&rotation=0&showTitle=false&size=151355&status=done&style=none&taskId=ueef52494-2e18-45a2-8409-7f68e200f63&title=&width=457) +所以您可以通过添加自己的插件或替换掉默认内置的插件来实现您的自定义功能。 +为了方便自定义出码方案,出码模块还提供自定义出码方案的脚手架功能,即执行下面脚本即可生成一个自定义出码方案: +```shell +npx @alilc/lowcode-code-generator init-solution +``` +里面内置了一个示例的插件(在 `src/plugins/example.ts`中),您可以根据注释引导来完善相关插件,从而组合生成您的专属出码方案(`src/index.ts`)。您所生成的出码方案可以发布成 NPM 包,从而能按上文 1~4 中的使用方案进行使用。 diff --git a/docs/docs/guide/expand/runtime/renderer.md b/docs/docs/guide/expand/runtime/renderer.md new file mode 100644 index 0000000000..20cc35baef --- /dev/null +++ b/docs/docs/guide/expand/runtime/renderer.md @@ -0,0 +1,349 @@ +--- +title: 使用渲染模块 +sidebar_position: 0 +--- +## 快速使用 +渲染依赖于 schema 和 components。其中 schema 和 components 需要一一对应,schema 中使用到的组件都需要在 components 中进行声明,否则无法正常渲染。 +### 简单示例 + +```jsx +import ReactRenderer from '@alilc/lowcode-react-renderer'; +import ReactDOM from 'react-dom'; +import { Button } from '@alifd/next'; + +const schema = { + componentName: 'Page', + props: {}, + children: [ + { + componentName: 'Button', + props: { + type: 'primary', + style: { + color: '#2077ff' + }, + }, + children: '确定', + }, + ], +}; + +const components = { + Button, +}; + +ReactDOM.render(( + +), document.getElementById('root')); +``` + +- rax-renderer:npm 包替换为 @alilc/lowcode-rax-renderer +#### +### 项目使用示例 +> 设计器 demo:[https://lowcode-engine.cn/demo](https://lowcode-engine.cn/demo) +> 项目代码完整示例:[https://github.com/alibaba/lowcode-demo](https://github.com/alibaba/lowcode-demo) + +**step 1:在设计器中获取组件列表** +```typescript +import { material, project } from '@alilc/lowcode-engine'; +const packages = material.getAssets().packages +``` +**step 2:在设计器中获取当前配置页面的 schema** +```typescript +import { material, project } from '@alilc/lowcode-engine'; + +const schema = project.exportSchema(); +``` + + +**step 3:以某种方式存储 schema 和 packages** +这里用 localStorage 作为存储示例,真实项目中使用数据库或者其他存储方式。 +```typescript +window.localStorage.setItem( + 'projectSchema', + JSON.stringify(project.exportSchema()) +); +const packages = await filterPackages(material.getAssets().packages); +window.localStorage.setItem( + 'packages', + JSON.stringify(packages) +); +``` +**step 4:预览时,获取存储的 schema 和 packages** +```typescript +const packages = JSON.parse(window.localStorage.getItem('packages') || ''); +const projectSchema = JSON.parse(window.localStorage.getItem('projectSchema') || ''); +const { componentsMap: componentsMapArray, componentsTree } = projectSchema; +``` +**step 5:通过整合 schema 和 packages 信息,进行渲染** +```typescript +import ReactDOM from 'react-dom'; +import React, { useState } from 'react'; +import { Loading } from '@alifd/next'; +import { buildComponents, assetBundle, AssetLevel, AssetLoader } from '@alilc/lowcode-utils'; +import ReactRenderer from '@alilc/lowcode-react-renderer'; +import { injectComponents } from '@alilc/lowcode-plugin-inject'; + +const SamplePreview = () => { + const [data, setData] = useState({}); + + async function init() { + // 渲染前置处理,初始化项目 schema 和资产包为渲染模块所需的 schema prop 和 components prop + const packages = JSON.parse(window.localStorage.getItem('packages') || ''); + const projectSchema = JSON.parse(window.localStorage.getItem('projectSchema') || ''); + const { componentsMap: componentsMapArray, componentsTree } = projectSchema; + const componentsMap: any = {}; + componentsMapArray.forEach((component: any) => { + componentsMap[component.componentName] = component; + }); + const schema = componentsTree[0]; + + const libraryMap = {}; + const libraryAsset = []; + packages.forEach(({ package: _package, library, urls, renderUrls }) => { + libraryMap[_package] = library; + if (renderUrls) { + libraryAsset.push(renderUrls); + } else if (urls) { + libraryAsset.push(urls); + } + }); + + const vendors = [assetBundle(libraryAsset, AssetLevel.Library)]; + + const assetLoader = new AssetLoader(); + await assetLoader.load(libraryAsset); + const components = await injectComponents(buildComponents(libraryMap, componentsMap)); + + setData({ + schema, + components, + }); + } + + const { schema, components } = data; + + if (!schema || !components) { + init(); + return ; + } + + return ( +
+ +
+ ); +}; + +ReactDOM.render(, document.getElementById('ice-container')); + +``` +### 国际化示例 +```typescript +class Demo extends PureComponent { + static displayName = 'renderer-demo'; + render() { + return ( +
+ +
+ ); + } +} +``` + +## API + +| 参数 | 说明 | 类型 | 必选 | +| --- | --- | --- | --- | +| schema | 符合[搭建协议](https://lowcode-engine.cn/lowcode)的数据 | Object | 是 | +| components | 组件依赖的实例 | Object | 是 | +| componentsMap | 组件的配置信息 | Object | 否 | +| appHelper | 渲染模块全局上下文 | Object | 否 | +| designMode | 设计模式,可选值:extend、border、preview | String | 否 | +| suspended | 是否挂起 | Boolean | 否 | +| onCompGetRef | 组件 ref 回调(schema, ref)=> {} | Function | 否 | +| onCompGetCtx | 组件 ctx 更新回调 (schema, ctx) => {} | Function | 否 | +| rendererName | 渲染类型,标识当前模块是以什么类型进行渲染的 | string | 否 | +| customCreateElement | 自定义创建 element 的钩子 +(Component, props, children) => {} | Function | 否 | +| notFoundComponent | 当组件找不到时,可以通过这个参数自定义展示文案。 | Component | 否 | +| thisRequiredInJSE | 为 true 的情况下 JSExpression 仅支持通过 this 来访问。假如需要兼容原来的 'state.xxx',则设置为 false,推荐使用 true。 | Boolean | 否 | +| locale | 国际化语言类型 | string | 否 | +| messages | 国际化语言对象 | Object | 否 | + + +### schema + +搭建基础协议数据,渲染模块将基于 schema 中的内容进行实时渲染。 + +### messages +国际化内容,需要配合 locale 使用 +messages 格式示例: +```typescript +{ + 'zh-CN': { + 'hello-world': '你好,世界!', + }, + 'en-US': { + 'hello-world': 'Hello world!', + }, +} +``` + +### locale +当前语言类型 +示例:'zh-CN' | 'en-US' + +### components + +渲染模块渲染页面需要用到的组件依赖的实例,`components` 对象中的 Key 需要和搭建 schema 中的`componentName` 字段对应。 + +### componentsMap + +> 在生产环境下不需要设置。 + + +配置规范参见[《低代码引擎搭建协议规范》](https://lowcode-engine.cn/lowcode),主要在搭建场景中使用,用于提升用户搭建体验。 + +- 属性配置校验:用户可以配置组件特定属性的 `propTypes`,在搭建场景中用户输入的属性值不满足 `propType` 配置时,渲染模块会将当前属性设置为 `undefined`,避免组件抛错导致编辑器崩溃; +- `isContainer` 标记:当组件被设置为容器组件且当前容器组件内没有其他组件时,用户可以通过拖拽方式将组件直接添加到容器组件内部; +- `parentRule` 校验:当用户使用的组件未出现在组件配置的 `parentRule` 组件内部时,渲染模块会使用 `visualDom` 组件进行占位,避免组件抛错的同时在下钻编辑场景也能够不阻塞用户配置,典型的场景如`Step.Item`、`Table.Column`、`Tab.Item` 等等。 + +### appHelper + +appHelper 主要用于设置渲染模块的全局上下文,目前 appHelper 支持设置以下上下文: + +- `utils`:全局公共函数 +- `constants`:全局常量 +- `location`:react-router 的 `location` 实例 +- `history`:react-router 的 `history` 实例 + +设置了 appHelper 以后,上下文会直接挂载到容器组件的 this 上,用户可以在搭建协议中的 function 及变量表达式场景使用上下文,具体使用方式如下所示: +**schema:** + +```javascript +export default { + "componentName": "Page", + "fileName": "test", + "props": {}, + "children": [{ + "componentName": "Div", + "props": {}, + "children": [{ + "componentName": "Text", + "props": { + "text": { + "type": "JSExpression", + "value": "this.location.pathname" + } + } + }, { + "componentName": "Button", + "props": { + "type": "primary", + "style": { + "marginLeft": 10 + }, + "onClick": { + "type": "JSExpression", + "value": "function onClick(e) { this.utils.xxx(this.constants.yyy);}" + } + }, + "children": "click me" + }] + }] +} +``` + +```typescript +import ReactRenderer from '@alilc/lowcode-react-renderer'; +import ReactDOM from 'react-dom'; +import { Button } from '@alifd/next'; +import schema from './schema' + +const components = { + Button, +}; + +ReactDOM.render(( + {} + } + }} + /> +), document.getElementById('root')); +``` +### designMode + +> 在生产环境下不需要设置。 + + +designMode 属性主要在搭建场景中使用,主要有以下作用: + +- 当 `designMode` 改变时,触发当前 schema 中所有组件重新渲染 +- 当 `designMode` 设置为 `design` 时,渲染模块会为 `Dialog`、`Overlay` 等初始状态无 dom 渲染的组件外层包裹一层 div,使其在画布中能够展示边框供用户选中 + +### suspended + +渲染模块是否挂起,当设置为 `true` 时,渲染模块最外层容器的 `shouldComponentUpdate` 将始终返回false,在下钻编辑或者多引擎渲染的场景会用到该参数。 + +### onCompGetRef + +组件 ref 的回调,在搭建场景下编排模块可以根据该回调获取组件实例并实现生命周期注入或者组件 DOM 操作等功能,回调函数主要包含两个参数: + +- `schema`: 当前组件的 schema 模型结构 +- `ref`:当前组件的 ref 实例 + +### onCompGetCtx +组件 ctx 更新的回调,在组件每次 render 渲染周期我们都会为组件构造新的上下文环境,因此该回调函数会在组件每次 render 过程中触发,主要包含两个参数: + +- `schema`:当前组件的 schema 模型结构 +- `ctx`:当前组件的上下文信息,主要包含以下内容: + - `page`:当前页面容器实例 + - `this`: 当前组件所属的容器组件实例 + - `item`/`index`: 循环上下文(属性 key 可以根据 loopArgs 进行定制) + - `form`: 表单上下文 + +### rendererName +渲染类型,标识当前模块是以什么类型进行渲染的 + +- `LowCodeRenderer`: 低代码组件 +- `PageRenderer`: 页面 + +### customCreateElement +自定义创建 element 的钩子,用于在渲染前后对组件进行一些处理,包括但不限于增加 props、删除部分 props。主要包含三个参数: + +- `Component`:要渲染的组件 +- `props`:要渲染的组件的 props +- `children`:要渲染的组件的子元素 + +### thisRequiredInJSE +> 版本 >= 1.0.11 + +默认值:true +为 true 的情况下 JSExpression 仅支持通过 this 来访问。假如需要兼容原来的 'state.xxx',则设置为 false,推荐使用 true。 diff --git a/docs/docs/guide/quickStart/_category_.json b/docs/docs/guide/quickStart/_category_.json new file mode 100644 index 0000000000..0a47c9da50 --- /dev/null +++ b/docs/docs/guide/quickStart/_category_.json @@ -0,0 +1,6 @@ +{ + "label": "入门", + "position": 0, + "collapsed": false, + "collapsible": true +} diff --git a/docs/docs/guide/quickStart/demo.md b/docs/docs/guide/quickStart/demo.md new file mode 100644 index 0000000000..536c8efab6 --- /dev/null +++ b/docs/docs/guide/quickStart/demo.md @@ -0,0 +1,47 @@ +--- +title: 试用低代码引擎 Demo +sidebar_position: 1 +--- +# 访问地址 + +低代码引擎的 Demo 可以通过如下永久链接访问到: + +[https://lowcode-engine.cn/demo](https://lowcode-engine.cn/demo) + +> 注意我们会经常更新 demo,所以您可以通过上述链接得到最新版地址。 + + +# 低代码引擎 Demo 功能概览 + +我们可以从 Demo 的项目中看到页面中有很多的区块:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643447049972-e324320a-7f97-4e48-bef3-a4c5d2b06517.png#clientId=udea0fe9a-4e7e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1080&id=rGr7U&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2160&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=518455&status=done&style=none&taskId=u872d1136-0f18-41b3-900d-710e9fc9eea&title=&width=1920)
它主要包含这些功能点:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643447051103-de714f27-ec70-4982-b180-e1ebe444b0fe.png#clientId=udea0fe9a-4e7e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1080&id=lD0YM&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2160&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=616472&status=done&style=none&taskId=u61de17fa-6df0-43c8-9171-96388fda32e&title=&width=1920) + +- 顶部:操作区 + - 右侧:撤回和重做、保存到本地、重置页面、预览、异步加载资源 +- 左侧:面板与操作区 + - 大纲面板:可以调整页面内的组件树结构 + - 物料面板:可以查找组件,并在此拖动组件到编辑器画布中 + - 源码面板:可以编辑页面级别的 JavaScript 代码和 CSS 配置 + - 提交 Issue:可以给引擎开发提 bug + - Schema 编辑:可以编辑页面的底层数据 + - 中英文切换:可以切换编辑器的语言 +- 中部:可视化页面编辑画布区域 + - 点击组件在右侧面板中能够显示出对应组件的属性配置选项 + - 拖拽修改组件的排列顺序 + - 将组件拖拽到容器类型的组件中 + - 复制组件:点击组件右上角的复制按钮 + - 删除组件:点击组件右上角的 X 或者直接使用 `Delete` 键 +- 右侧:组件级别配置 + - 选中的组件:从页面开始一直到当前选中的组件位置,点击对应的名称可以切换到对应的组件上 + - 选中组件的配置:当前组件的大类目选项,根据组件类型不同,包含如下子类目: + - 属性:组件的基础属性值设置 + - 样式:组件的样式配置 + - 事件:绑定组件对外暴露的事件 + - 高级:循环、条件渲染与 key 设置 + +# 深入使用低代码引擎 Demo + +我们在低代码引擎 Demo 中直接内置了产品使用文档,对常见场景中的使用进行了向导,它的入口如下: + +![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1647163471895-a12d0f5d-e09e-462d-bd0b-b633c64afb15.png#clientId=uecc3752b-3539-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=825&id=u86d6fa24&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1650&originWidth=3070&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1040703&status=done&style=none&taskId=u54aeddda-78e0-4259-b184-d06e2dba10b&title=&width=1535) + +如果暂时没有看到对应的产品使用文档,可以通过此永久链接直接访问:[https://www.yuque.com/lce/usage](https://www.yuque.com/lce/usage) diff --git a/docs/docs/guide/quickStart/intro.md b/docs/docs/guide/quickStart/intro.md new file mode 100644 index 0000000000..67750b2a94 --- /dev/null +++ b/docs/docs/guide/quickStart/intro.md @@ -0,0 +1,48 @@ +--- +title: 简介 +sidebar_position: 0 +--- + +# 阿里低代码引擎简介 + +## 低代码介绍 + +零代码、低代码的概念在整个全球行业内已经流行了很长一段时间。通常意义上的低代码定义会有三个关键点: + +1. 一个用于生产软件的可视化编辑器 +2. 中间包含了一些用于组装的物料,可以通过编排、组合和配置它们以生成丰富的功能或表现 +3. 最后的实施结果是成本降低 + +通常情况下低代码平台会具备以下的几个能力: + +- **可视化页面搭建**,通过简单的拖拽完成应用页面开发,对前端技能没有要求或不需要特别专业的了解; +- **可视化模型设计**,与业务相关的数据存储变得更容易理解,甚至大多数简单场景可以做到表单即模型,模型字段的类型更加业务化; +- **可视化流程设计**,不管是业务流程还是审批流程,都可以通过简单的点线连接来进行配置; +- **可视化报表及数据分析**,BI数据分析能力成为标配,随时随地通过拖拽选择来定义自定义分析报表; +- **可视化服务与数据开放、集成**,具备与其他系统互联互通的配置; +- **权限、角色设置标准化和业务化**,通过策略规则配置来将数据、操作的权限进行精细化管理; +- **无需关心服务器、数据库等底层运维、计算设施设备、网络等等复杂技术概念**,具备安全、性能的统一解决方案,开发者只需要专注于业务本身; + +有了上面这些,你会发现即使是个技术小白,只要你了解业务,就能不受束缚的完成大多数业务应用的搭建。但低代码本身也不仅仅是为技术小白准备的。在实践中,低代码因为通过组件化、模块化的思路让业务的抽象更加容易,而且在扩展及配置化上带来了更加新鲜的模式探索,技术人员的架构设计成本和实施成本也就降了很多。 + +市面上常见的低代码产品[可以看 Golden 的梳理](https://golden.com/wiki/No-code_%2F_low-code_development-NMGMEA6)。 + +## 低代码引擎介绍 + +**低代码引擎是一款为低代码平台开发者提供的,具备强大定制扩展能力的低代码设计器研发框架。** + +下面简单描述定义中的子部分: + +**低代码设计器** +现如今低代码平台越来越多,而每一个低代码平台中都会有的一个能力就是搭建和配置页面、模块的页面,这个页面我们称为设计器。例如,下图是中后台低代码平台的设计器。 +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01LunuQh23b5NtP8k86_!!6000000007273-2-tps-1682-969.png?originHeight=1914&originWidth=3838&originalType=binary&ratio=1&rotation=0&showTitle=false&size=538736&status=done&style=stroke&taskId=u9a19d4d1-4d87-4b4e-b7cc-3aedfb00aaa&title=&width=1080) +设计器承载着低代码平台的核心功能,包括入料、编排、组件配置、画布渲染等等。由于其功能多,打磨精细难,也是低代码平台建设最耗时的地方。 + +**定制扩展能力** + +什么是扩展能力呢,一方面我们可以快速拥有一份标准的低代码设计器,另外一方面如果有业务独特的功能需要,我们可以不用看它的源码、不用关心其实现,可以使用 API、插件等方式快速完成能力的开发。 +而低代码引擎对于设计器的扩展能力支持基本上覆盖了低代码设计器的所有功能点。下图是针对标准的设计器提供了扩展功能的区域。 +![](https://cdn.nlark.com/yuque/0/2022/png/242652/1643446752531-8b1493d4-ea8a-463b-9631-6bb4fc681719.png#clientId=u2b839b63-1827-4&crop=0&crop=0&crop=1&crop=1&from=drop&height=539&id=ucff2881c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1914&originWidth=3838&originalType=binary&ratio=1&rotation=0&showTitle=false&size=538736&status=done&style=stroke&taskId=u9a19d4d1-4d87-4b4e-b7cc-3aedfb00aaa&title=&width=1080) +**低代码设计器研发框架** + +低代码引擎的核心是设计器,通过扩展、周边生态等可以产出各式各样的设计器。它不是一套可以适合所有人的低代码平台,而是帮助低代码平台的开发者,快速生产低代码平台的工具。 diff --git a/docs/docs/guide/quickStart/start.md b/docs/docs/guide/quickStart/start.md new file mode 100644 index 0000000000..001e4e789b --- /dev/null +++ b/docs/docs/guide/quickStart/start.md @@ -0,0 +1,296 @@ +--- +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 版本推荐 14.17.0。 + +### 查看 Node 版本 +![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660653856191-128d8e3f-9636-4b73-94ab-c03cf6965365.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=35&id=u44a9af04&margin=%5Bobject%20Object%5D&name=image.png&originHeight=70&originWidth=238&originalType=binary&ratio=1&rotation=0&showTitle=false&size=11948&status=done&style=none&taskId=udb616117-a27c-409d-9e1c-1b89931a714&title=&width=119) + +### 变更 node 版本 +可以安装 [n](https://www.npmjs.com/package/n) 来管理和变更 node 版本。 + +#### 安装 +```json +npm install -g n +``` + +#### 变更 node 版本 +```json +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 下载到本地。 + +### git clone +#### HTTPS +需要使用到 git 工具 +```json +git clone https://github.com/alibaba/lowcode-demo.git +``` +#### SSH +需要配置 SSH key,如果没有配置可以 +```json +git clone git@github.com:alibaba/lowcode-demo.git +``` + +### 下载 Zip 包 +![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660653725650-ab734ba4-64a7-4801-9d2f-5c496879054f.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=897&id=uc1b07458&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1794&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1306258&status=done&style=stroke&taskId=ubaa4eb12-0e87-464e-b3da-306ed9685b7&title=&width=1792) + +## 安装依赖 +在 lowcode-demo 目录下执行: +```json +npm install +``` + +## 启动 demo +在 lowcode-demo 目录下执行: +```json +npm run start +``` + +之后就可以通过 [http://localhost:5556/](http://localhost:5556/) 来访问我们的 DEMO 了。 +# 认识 Demo +我们的 Demo 是一个**低代码平台的设计器**。它是一个低代码平台中最重要的一环,用户可以在这里通过拖拽、配置、写代码等等来完成一个页面的开发。由于用户的人群不同、场景不同、诉求不同等等,这个页面的功能就会有所差异。
这里记住**设计器**这个词,它描述的就是下面的这个页面,后面我们会经常看到它。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660654189055-45fd0c7e-75cb-4072-a4d4-7cf244405c7d.png#clientId=ubcf63daf-5747-4&crop=0&crop=0.008&crop=1&crop=1&from=paste&height=904&id=LBi2j&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1808&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=763122&status=done&style=stroke&taskId=u82753ad5-3b5d-43b2-b309-a99c2a7bb24&title=&width=1792) + +## 场景介绍 +![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660654738730-490fc94a-8b42-4c48-b21e-4c0694416b07.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=903&id=ub700edc2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1806&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=802013&status=done&style=stroke&taskId=u317bff98-636d-402a-98f2-f9e0b08293b&title=&width=1792) + +Demo 根据**不同的设计器所需要的物料不同**,分为了下面的 8 个场景: + +- 综合场景 +- 基础 fusion 组件 +- 基础 fusion 组件 + 单自定义组件 +- 基础 antd 组件 +- 自定义初始化引擎 +- 扩展节点操作项 +- 基于next实现的高级表单低代码物料 +- antd 高级组件 + formily 表单组件 + +可以点开不同的场景,看看他们使用的物料。 + +## 目录介绍 +仓库下的 src/scenarios 目录就对应刚刚介绍的场景。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660655237007-fddd8534-d4ed-4a25-ba2f-f335f8ac3c36.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=348&id=ubf68019d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=696&originWidth=696&originalType=binary&ratio=1&rotation=0&showTitle=false&size=148777&status=done&style=stroke&taskId=u68648c51-7648-494e-bd41-4f29fb144f9&title=&width=348) + +不同场景的目录结构实际上都是类似的,这里我们主要介绍一下综合场景的目录结构即可。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660655399364-b40d206a-977d-4000-9be1-681823f8a995.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=ub727a7fa&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1373541&status=done&style=stroke&taskId=ue55dc86f-375d-4c7f-a63f-d5208683035&title=&width=1792)
综合场景目录下只有一个文件,这个文件做了几个事情: + +- 通过 plugins.register 注册「切换场景」的插件,也就是上面介绍的切换场景的功能。 +- 通过 registerPlugins 注册更多的插件: + - ManualPlugin:增加弹出「低代码产品使用文档」按钮 + - Inject:支持调试功能 + - registerRefProp:支持给每个组件注入 ref + - ... +- 通过 init 初始化低代码设计器 + +做了这些事情之后,我们的低代码设计器就已经有了基本的能力了。也就是最开始我们看到的这样。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660654189055-45fd0c7e-75cb-4072-a4d4-7cf244405c7d.png#clientId=ubcf63daf-5747-4&crop=0&crop=0.008&crop=1&crop=1&from=paste&height=904&id=MZdfk&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1808&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=763122&status=done&style=stroke&taskId=u82753ad5-3b5d-43b2-b309-a99c2a7bb24&title=&width=1792) + +接下来我们就根据我们自己的诉求通过对设计器进行扩展,改动成我们需要的设计器功能。 +# 开发一个插件 +## 方式1:在 DEMO 中直接新增插件 +![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660656064139-8da57c37-7e0b-4e8d-9f2d-8ea86d5af134.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=280&id=uc7f75c37&margin=%5Bobject%20Object%5D&name=image.png&originHeight=560&originWidth=820&originalType=binary&ratio=1&rotation=0&showTitle=false&size=125690&status=done&style=stroke&taskId=u53c07118-a2ca-4a77-a27f-3b2b20085ac&title=&width=410) + +可以在 demo/sample-plugins 直接新增插件,这里我新增的插件目录是 plugin-demo。并且新增了 index.tsx 文件,将下面的代码粘贴到 index.tsx 中。 +```javascript +import * as React from 'react'; +import { ILowCodePluginContext } from '@alilc/lowcode-engine'; + +const LowcodePluginPluginDemo = (ctx: ILowCodePluginContext) => { + return { + // 插件对外暴露的数据和方法 + exports() { + return { + data: '你可以把插件的数据这样对外暴露', + func: () => { + console.log('方法也是一样'); + }, + } + }, + // 插件的初始化函数,在引擎初始化之后会立刻调用 + init() { + // 你可以拿到其他插件暴露的方法和属性 + // const { data, func } = ctx.plugins.pluginA; + // func(); + + // console.log(options.name); + + // 往引擎增加面板 + ctx.skeleton.add({ + area: 'leftArea', + name: 'LowcodePluginPluginDemoPane', + type: 'PanelDock', + props: { + description: 'Demo', + }, + content:
这是一个 Demo 面板
, + }); + + ctx.logger.log('打个日志'); + }, + }; +}; + +// 插件名,注册环境下唯一 +LowcodePluginPluginDemo.pluginName = 'LowcodePluginPluginDemo'; +LowcodePluginPluginDemo.meta = { + // 依赖的插件(插件名数组) + dependencies: [], + engines: { + lowcodeEngine: '^1.0.0', // 插件需要配合 ^1.0.0 的引擎才可运行 + }, +} + +export default LowcodePluginPluginDemo; +``` + +在 src/scenarios/index/index.ts 中新增下面代码
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660656497051-49e08633-2d78-428c-becc-c282905cdb90.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=u426edc7b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1458910&status=done&style=stroke&taskId=uf1e42399-caf7-4d82-a797-698fa730486&title=&width=1792) + +这样在我们的设计器中就新增了一个 Demo 面板。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660656566260-86dfed37-60d0-45ca-967e-5df8ea7a34d0.png#clientId=ubcf63daf-5747-4&crop=0&crop=0.0053&crop=1&crop=1&from=paste&height=903&id=u17565cd3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1806&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=734227&status=done&style=stroke&taskId=u5dbe00f3-447b-451e-ac48-9b02281afc3&title=&width=1792) +## 方式2:在新的仓库下开发插件 +初始化 +```json +npm init @alilc/element your-plugin-name +``` + +选择设计器插件(plugin)
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660702297326-ccfe60f9-ee22-4a24-a293-26351d107663.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=107&id=ub2bf5248&margin=%5Bobject%20Object%5D&name=image.png&originHeight=214&originWidth=730&originalType=binary&ratio=1&rotation=0&showTitle=false&size=82091&status=done&style=stroke&taskId=u82628265-73f0-4d57-b4ba-1b18600a1f0&title=&width=365) + +根据操作完善信息
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660702439529-867a893f-f27a-4e48-8a5a-ee45aa97e355.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=109&id=uc9b09fec&margin=%5Bobject%20Object%5D&name=image.png&originHeight=218&originWidth=866&originalType=binary&ratio=1&rotation=0&showTitle=false&size=102705&status=done&style=stroke&taskId=ue4a95f21-43d3-4da8-9c0e-b21dfe239bf&title=&width=433) + +插件项目就初始化完成了
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660702464438-3d7e07eb-53c7-417c-9e6d-06fdf9acfb86.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=280&id=u0ee65b4e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1197702&status=done&style=stroke&taskId=u5f9fdae3-1adc-4b02-969c-5c43c3d4c9c&title=&width=496) + +在插件项目下安装依赖 +```json +npm install +``` + +启动项目 +```json +npm run start +``` + +调试项目
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660705712773-f2446689-2b5f-42e7-9e85-30857270dfbb.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=346&id=u448649c5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1936&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=757713&status=done&style=stroke&taskId=u0b617456-826e-4993-951e-303da417172&title=&width=641) + +在 Demo 中调试项目
在 build.json 下面新增 "inject": true,就可以在 [https://lowcode-engine.cn/demo/index.html?debug](https://lowcode-engine.cn/demo/index.html?debug) 页面下进行调试了。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660705860117-5a11a5fa-9215-4b94-84b7-497899cafe10.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=u3a36c42f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=887101&status=done&style=stroke&taskId=u747bc337-5212-4a8b-a88f-127c53ea621&title=&width=1792) +# 开发一个自定义物料 +## 初始化物料 +```json +npm init @alilc/element your-material-demo +``` +选择组件/物料栏
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706045985-db73ca55-925a-446b-ace4-b59fa1e18469.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=104&id=kuWIf&margin=%5Bobject%20Object%5D&name=image.png&originHeight=208&originWidth=824&originalType=binary&ratio=1&rotation=0&showTitle=false&size=88910&status=done&style=stroke&taskId=u92f5fa65-386a-4f52-a093-bcbbebdc2d7&title=&width=412) + +配置其他信息
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706116845-9b3b938f-c132-426b-81bd-d49283ebf9e8.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=124&id=u941c9808&margin=%5Bobject%20Object%5D&name=image.png&originHeight=248&originWidth=800&originalType=binary&ratio=1&rotation=0&showTitle=false&size=111864&status=done&style=stroke&taskId=ue4ff4dab-3a53-4811-bf70-7fa6fc0c8b6&title=&width=400) + +这样我们就初始化好了一个 React 物料。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706173968-3e5db25a-e08d-4852-90c9-ffaa0968fd62.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=u854b37cc&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1080400&status=done&style=stroke&taskId=u10e21350-23d4-4d8f-8c16-0c5a221fc2e&title=&width=1792) +## 启动并调试物料 +### 安装依赖 +```json +npm i +``` +### 启动 +```json +npm run lowcode:dev +``` + +我们就可以通过 [http://localhost:3333/](http://localhost:3333/) 看到我们的研发的物料了。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706484894-73798e35-1e58-4ffe-bb3c-bfba7b014433.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=895&id=zVMiy&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1790&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=678753&status=done&style=stroke&taskId=u241f50c0-1a43-4854-8443-7e972f15623&title=&width=1792) +### 在 Demo 中调试 +```json +npm i @alilc/build-plugin-alt +``` + +修改 build.lowcode.js
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706733149-0170b2fb-88de-40e3-8204-f510d7e42f77.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=311&id=u8a1a8bea&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1046&originWidth=1388&originalType=binary&ratio=1&rotation=0&showTitle=false&size=291155&status=done&style=stroke&taskId=u61ede7d2-f92d-43b9-8582-a2362a9ea14&title=&width=413) + +如图,新增如下代码 +```json +[ + '@alilc/build-plugin-alt', + { + type: 'component', + inject: true, + library, + // 配置要打开的页面,在注入调试模式下,不配置此项的话不会打开浏览器 + // 支持直接使用官方 demo 项目:https://lowcode-engine.cn/demo/index.html + openUrl: 'https://lowcode-engine.cn/demo/index.html?debug', + }, +], +``` + +我们重新启动项目,就可以在 Demo 中找到我们的自定义组件。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706823666-ca28a08d-6241-4112-bc78-b9078c81fb75.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=906&id=u31bdc31a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1812&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=788013&status=done&style=stroke&taskId=uaa4789a2-452f-4b04-8894-759989e4568&title=&width=1792) + +## 发布 +首先进行构建 +```json +npm run lowcode:build +``` + +发布组件 +```json +npm publish +``` + +这里我发布的组件是 [my-material-demo](https://www.npmjs.com/package/my-material-demo)。在发布之后我们就会有两个重要的文件: + +- 低代码描述:[https://unpkg.com/my-material-demo@0.1.0/build/lowcode/meta.js](https://unpkg.com/my-material-demo@0.1.0/build/lowcode/meta.js) +- 组件代码:[https://unpkg.com/my-material-demo@0.1.0/build/lowcode/render/default/view.js](https://unpkg.com/my-material-demo@0.1.0/build/lowcode/render/default/view.js) + +我们也可以从 [https://unpkg.com/my-material-demo@0.1.0/build/lowcode/assets-prod.json](https://unpkg.com/my-material-demo@0.1.0/build/lowcode/assets-prod.json) 找到我们的资产包描述。 +```json +{ + "packages": [ + { + "package": "my-material-demo", + "version": "0.1.0", + "library": "BizComp", + "urls": [ + "https://unpkg.com/my-material-demo@0.1.0/build/lowcode/render/default/view.js", + "https://unpkg.com/my-material-demo@0.1.0/build/lowcode/render/default/view.css" + ], + "editUrls": [ + "https://unpkg.com/my-material-demo@0.1.0/build/lowcode/view.js", + "https://unpkg.com/my-material-demo@0.1.0/build/lowcode/view.css" + ], + "advancedUrls": { + "default": [ + "https://unpkg.com/my-material-demo@0.1.0/build/lowcode/render/default/view.js", + "https://unpkg.com/my-material-demo@0.1.0/build/lowcode/render/default/view.css" + ] + }, + "advancedEditUrls": {} + } + ], + "components": [ + { + "exportName": "MyMaterialDemoMeta", + "npm": { + "package": "my-material-demo", + "version": "0.1.0" + }, + "url": "https://unpkg.com/my-material-demo@0.1.0/build/lowcode/meta.js", + "urls": { + "default": "https://unpkg.com/my-material-demo@0.1.0/build/lowcode/meta.js" + }, + "advancedUrls": { + "default": [ + "https://unpkg.com/my-material-demo@0.1.0/build/lowcode/meta.js" + ] + } + } + ], +} +``` + +## 使用 +我们将刚刚发布的组件的 assets-prod.json 的内容放到 demo 的 src/universal/assets.json 中。
*最好放到最后,防止因为资源加载顺序问题导致出现报错。
如图,新增 packages 配置
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660707789785-ea75a399-6845-45a8-8c53-08402749c9a8.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=uf0f75c17&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1327766&status=done&style=stroke&taskId=ub053d846-69fd-4a55-8e9e-b41d1e06e47&title=&width=1792)
如图,新增 components 配置
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660707811725-a0e36f48-910d-45b5-b162-3aa4e2f87e9b.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=uf8c9506f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1222080&status=done&style=stroke&taskId=u10147f1f-27ed-4cec-bfc9-2cb3d61d6a2&title=&width=1792) + +这时候再启动 DEMO 项目,就会有新的低代码物料了。接下来就按照你们的需求,继续扩展物料吧。 +# 总结 +这里只是简单的介绍了一些低代码引擎的基础能力,带大家简单的对低代码 DEMO 进行扩展,定制一些新的功能。低代码引擎的能力还有很多很多,可以继续去探索更多的功能。 diff --git a/docs/docs/participate/config.md b/docs/docs/participate/config.md new file mode 100644 index 0000000000..4e032ad1be --- /dev/null +++ b/docs/docs/participate/config.md @@ -0,0 +1,80 @@ +--- +title: 引擎的工程化配置 +sidebar_position: 3 +--- +目前引擎体系共包含 3 个 js 文件,即: +```html + + + + +``` + +工程化配置我们进行了统一,具体如下: +```shell +{ + "entry": { + ... + }, + "library": "...", + "libraryTarget": "umd", + "externals": { + "react": "var window.React", + "react-dom": "var window.ReactDOM", + "prop-types": "var window.PropTypes", + "rax": "var window.Rax", + "@alilc/lowcode-engine": "var window.AliLowCodeEngine", + "@alilc/lowcode-engine-ext": "var window.AliLowCodeEngineExt", + "moment": "var moment", + "lodash": "var _", + "@alifd/next": "var Next" + }, + "polyfill": false, + "outputDir": "dist", + "vendor": false, + "ignoreHtmlTemplate": true, + "sourceMap": true, + "plugins": [ + "build-plugin-react-app", + ["build-plugin-fusion", { + }], + ["build-plugin-moment-locales", { + "locales": ["zh-cn"] + }], + "./build.plugin.js" + ] +} + +``` +总结一下,有 2 点: + +1. **都不包含 polyfill,**需要应用级别单独引入 polyfill,推荐动态 polyfill +2. **都不包含 lodash / moment / next** + + +#### 前置依赖资源: +```html + + + + + + +``` + + +#### 所有资源: +```html + + + + + + + + + + + + +``` diff --git a/docs/docs/participate/flow.md b/docs/docs/participate/flow.md new file mode 100644 index 0000000000..d80e779ee6 --- /dev/null +++ b/docs/docs/participate/flow.md @@ -0,0 +1,96 @@ +--- +title: 关于引擎的研发协作流程 +sidebar_position: 2 +--- +## 代码风格 +引擎项目配置了 eslint 和 stylelint,在每次 git commit 前都会检查代码风格,假如有报错,请修改后再提交。(**严禁 -n 提交,-n 也逃脱不了 github workflow 的 lint 检查,放弃吧,骚年~**) + +## 测试机制 +每次提交代码前,务必本地跑一次单元测试,通过后再提交 MR。 +假如涉及新的功能,需要**补充相应的单元测试,**目前引擎核心模块的单测覆盖率都在 80%+,假如降低了覆盖率,将会不予以通过。 + +跑单测流程: + +1. 项目根目录下执行 npm run build +2. 只改了一个包,比如 designer,则在 designer 目录下,执行 npm test +3. (or)改了多个包,则在根目录下执行 npm test +## commit 风格 +几点要求: + +1. commit message 格式遵循 [ConvensionalCommits](https://www.conventionalcommits.org/en/v1.0.0/#summary) +![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645066644352-4de1c64c-bff6-4482-90d1-1fb610aa91f2.png#averageHue=%23eceef0&clientId=u6dcee4f0-35df-4&crop=0&crop=0&crop=1&crop=1&height=297&id=CfpQy&margin=%5Bobject%20Object%5D&name=image.png&originHeight=594&originWidth=2070&originalType=binary&ratio=1&rotation=0&showTitle=false&size=341605&status=done&style=none&taskId=u4499b752-5e24-42f6-9186-280fd5a51aa&title=&width=1035) +2. 请按照一个 bugfix / feature 对应一个 commit,假如不是,请 rebase 后再提交 MR,不要一堆无用的、试验性的 commit + +好处:从引擎的整体 commit 历史来看,会很清晰,**每个 commit 完成一件确定的事,changelog 也能自动生成。**另外,假如因为某个 commit 导致了 bug,也很容易通过 rebase drop 等方式快速修复。 +## 引擎发布机制 +日常迭代先从 develop 拉分支,然后自测、单测通过后,提交 MR 到 develop 分支,由发布负责人基于 develop 拉 release/1.0.z 分支~ + +### 分支用途 + +- main 分支,最稳定的分支,跟 npm latest 包的内容保持一致 +- develop 分支,开发分支,拥有最新的、已经验证过的 feature / bugfix,Pull Request 的**目标合入分支** +- release 分支 + - 正式发布分支,命名规则为 release/x.y.z,一般从 develop 拉出来进行发布,x.y.z 为待发布的版本号 + - beta 发布分支,命名规则为 release/x.y.z-beta(\.\d+)?,可以快速验证修改,发布 npm beta 版本。 +验证通过后,因为 beta 发布分支上会存在无用的 commit(比如 lerna 修改 package.json 这种),所以不直接 PR 到 develop,而是从 develop 拉分支,从 beta 发布分支 cherry pick 有用的 commit 到新分支,然后 PR 到 develop。 + +### 发布步骤 +> **发布需要权限,如果提 PR 之后着急发布可以**[**加入贡献者交流群**](https://www.yuque.com/lce/doc/pctr1f#d5WKy)**。** + +如果是发布正式版本,步骤如下(以发布 1.0.0 版本为例): + +1. git checkout develop +2. git checkout -b release/1.0.0 +3. npm run build +4. npm run pub +5. tnpm run sync(此步骤将发布在 npm 源的包同步到阿里内网源,因为 alifd cdn 将依赖内网 npm 源) +6. 更新[发布日志](https://github.com/alibaba/lowcode-engine/releases) +7. 合并 release/x.x.x 到 main 分支 +8. 合并 main 分支到 develop 分支 + +如果是发布beta 版本,步骤如下(以发布 1.0.1 版本为例): + +1. git checkout develop +2. git checkout -b release/1.0.1-beta +3. npm run build +4. npm run pub:prepatch(将 lerna 版本号从 1.0.0 改到 1.0.1-beta.0,若是从 1.0.1-beta.0 改到 1.0.1-beta.1,则用 npm run pub:prerelease) +5. tnpm run sync + +注:在 release/1.0.1-beta 上可以直接提交,以便快速测试和验证,不过如何合入 develop,参考 [分支用途](#uem7W) 一节说明。 + +### 发布周期 +**发布周期暂时不固定,按需发布~** + +## 物料发布机制 + + +## DEMO 发布机制 +**修改版本号** +手动修改 package.json 的版本号 + +**build** +```typescript +npm run build +``` + +**publish** +```typescript +npm run pub +``` +需要权限 + +*发布 beta 版本 +```typescript +npm publish --tag beta +``` + +**同步** +```typescript +tnpm run sync +``` +缺少这一步相关的 cdn 地址可能 404 + + + +**官网生效** +需要在通过阿里内部系统更新 demo 版本 diff --git a/docs/docs/participate/index.md b/docs/docs/participate/index.md new file mode 100644 index 0000000000..7a652e59a4 --- /dev/null +++ b/docs/docs/participate/index.md @@ -0,0 +1,26 @@ +--- +title: 低代码引擎贡献者指南 +sidebar_position: 0 +--- +### 首个 Pull Request +在写第一个 Pull Request?你可以从这一系列视频中学习怎么做: +[How to Contribute to an Open Source Project on GitHub](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github) +为了使你能够快速上手和熟悉贡献流程,我们这里有个列表 [good first issues](https://github.com/alibaba/lowcode-engine/issues?q=is:open+is:issue+label:%22good+first+issue%22),里面有相对没那么笼统的漏洞,从这开始是个不错的选择。 +如果你想解决一个 issue,请确定检查了该 issue 下的评论以防有人正在处理它。如果目前没人在处理该 issue,那么请留下评论去表明你想处理该 issue 以便其他人不会意外重复你的工作。 +如果有人留言表明要处理该 issue 但是超过两周没有跟进,你可以接手工作,不过也应该留言说明。 + +### 提交 Pull Request +核心团队时刻关注 pull requests,我们会先评审你的 pull request,之后可能会合并,可能会要求再次更改,也可能会关闭该 pull request 并对此作出解释。我们会尽力全程更新和反馈。 + +**提交 pull request 前**,请确保完成以下步骤: + +1. Fork [此仓库](https://github.com/alibaba/lowcode-engine),从 main 创建分支。 +2. 在仓库根目录下执行 yarn。 +3. 如果你修复了 bug 或者添加了代码,而这些内容需要测试,请添加测试! +4. 确保通过测试套件(yarn test)。 +5. 请签订贡献者许可证协议(Contributor License Agreement)。 + +### 核心贡献者交流 +如果你想长期参与到项目维护中,我们提供了一个核心贡献者交流群。 +1.可以通过[填写问卷](https://survey.taobao.com/apps/zhiliao/4YEtu9gHF)的方式,参与到其中。 +2.填写问卷后加微信号 wxidvlalalalal,说明一下 diff --git a/docs/docs/participate/prepare.md b/docs/docs/participate/prepare.md new file mode 100644 index 0000000000..f0fbeb3948 --- /dev/null +++ b/docs/docs/participate/prepare.md @@ -0,0 +1,61 @@ +--- +title: 如何配置引擎调试环境 +sidebar_position: 1 +--- +低代码引擎的核心仓库是不包含任何物料、插件、setter 的,它本身用于生成低代码引擎的主包。 +如果您需要对低代码的主包进行开发和调试,需要用到本文里介绍的知识。 +如果您需要对低代码编辑器进行定制,您可能只需要 clone [lowcode-demo 项目](https://github.com/alibaba/lowcode-demo)并进行修改,参考“[配置低代码扩展点](https://www.yuque.com/lce/doc/srdo3s#oPhoE)”章节。 + +> 前置条件: +> node >= 14 + +### 1. 拉取代码,启动项目 +```bash +git clone git@github.com:alibaba/lowcode-engine.git +cd lowcode-engine +npm install && npm run setup +npm start + + +git clone git@github.com:alibaba/lowcode-demo.git +cd lowcode-demo +npm install && npm start +``` + +### 2. 配置资源代理 +本质上是将 demo 页面引入的几个 js/css 代理到 engine 项目,可以使用趁手的代理工具,这里推荐 [XSwitch](https://chrome.google.com/webstore/detail/xswitch/idkjhjggpffolpidfkikidcokdkdaogg?hl=en-US)。 + +本地开发代理规则如下: +```json +{ + "proxy": [ + [ + "https://alifd.alicdn.com/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", + "http://localhost:5555/css/engine-core.css" + ], + [ + "https?://alifd.alicdn.com/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", + "http://localhost:5555/css/react-simulator-renderer.css" + ], + [ + "https?://alifd.alicdn.com/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", + "http://localhost:5555/css/rax-simulator-renderer.css" + ], + ] +} +``` + +### 3. 本地调试物料/插件/设置器 +[详见](https://www.yuque.com/lce/doc/ulvlkz#Ioc87) diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js new file mode 100644 index 0000000000..68728ca21e --- /dev/null +++ b/docs/docusaurus.config.js @@ -0,0 +1,132 @@ +/* eslint-disable @typescript-eslint/no-require-imports */ +// Note: type annotations allow type checking and IDEs autocompletion + +const lightCodeTheme = require('prism-react-renderer/themes/github'); +const darkCodeTheme = require('prism-react-renderer/themes/dracula'); +const navbar = require('./config/navbar'); + +/** @type {import('@docusaurus/types').Config} */ +const config = { + title: 'Low-Code Engine', + tagline: 'Low-Code Engine is awesome!', + url: 'https://lowcode-engine.cn', + baseUrl: '/site/', + onBrokenLinks: 'throw', + onBrokenMarkdownLinks: 'warn', + favicon: + 'https://img.alicdn.com/imgextra/i2/O1CN01TNJDDg20pKniPOkN4_!!6000000006898-2-tps-66-78.png', + + organizationName: 'alibaba', // Usually your GitHub org/user name. + projectName: 'lowcode-engine', // Usually your repo name. + + i18n: { + defaultLocale: 'zh-Hans', + locales: ['zh-Hans'], + }, + + plugins: [ + [ + '@docusaurus/plugin-content-docs', + { + id: 'community', + path: 'community', + routeBasePath: 'community', + sidebarPath: require.resolve('./config/sidebarsCommunity.js'), + }, + ], + ], + + presets: [ + [ + 'classic', + /** @type {import('@docusaurus/preset-classic').Options} */ + ({ + docs: { + sidebarPath: require.resolve('./config/sidebars.js'), + // lastVersion: 'current', + editUrl: + 'https://github.com/alibaba/lowcode-engine/tree/develop/docs/', + }, + theme: { + customCss: require.resolve('./src/css/custom.css'), + }, + }), + ], + ], + + themeConfig: + /** @type {import('@docusaurus/preset-classic').ThemeConfig} */ + ({ + docs: { + sidebar: { + hideable: true, + }, + }, + navbar, + footer: { + // style: 'dark', + links: [ + {}, + { + title: '低代码引擎协议栈', + items: [ + { + label: '《低代码引擎搭建协议规范》', + href: 'https://lowcode-engine.cn/lowcode', + }, + { + label: '《低代码引擎物料协议规范》', + href: 'https://lowcode-engine.cn/material', + }, + { + label: '《低代码引擎资产包协议规范》', + href: 'https://lowcode-engine.cn/assets', + }, + ], + }, + {}, + { + title: '案例产品', + items: [ + { + label: '钉钉宜搭', + href: 'https://www.aliwork.com/', + }, + { + label: 'Parts 造物', + href: 'https://parts.lowcode-engine.cn/', + }, + { + label: 'UIPaaS 低代码平台孵化器', + href: 'https://uipaas.net', + }, + ], + }, + {}, + ], + copyright: `Copyright © ${new Date().getFullYear()} 阿里巴巴集团, Inc. Built with Docusaurus.`, + }, + // 主题切换 + prism: { + theme: lightCodeTheme, + darkTheme: darkCodeTheme, + }, + // 语雀文档导出的图片,会进行 referrer 校验,这里设置关闭,不然加载不了语雀的图片 + metadata: [{ name: 'referrer', content: 'no-referrer' }], + }), + + themes: [ + [ + require.resolve('@easyops-cn/docusaurus-search-local'), + { + hashed: true, + // For Docs using Chinese, The `language` is recommended to set to: + // ``` + language: ['en', 'zh'], + // ``` + }, + ], + ], +}; + +module.exports = config; diff --git a/docs/package.json b/docs/package.json new file mode 100644 index 0000000000..306b58cacd --- /dev/null +++ b/docs/package.json @@ -0,0 +1,62 @@ +{ + "name": "@alilc/lowcode-engine-docs", + "version": "0.0.1-beta.3", + "description": "低代码引擎版本化文档", + "license": "MIT", + "files": [ + "build" + ], + "scripts": { + "docusaurus": "docusaurus", + "start": "docusaurus start --host 0.0.0.0", + "build": "docusaurus build", + "swizzle": "docusaurus swizzle", + "deploy": "docusaurus deploy", + "clear": "docusaurus clear", + "serve": "docusaurus serve", + "write-translations": "docusaurus write-translations", + "write-heading-ids": "docusaurus write-heading-ids", + "typecheck": "tsc" + }, + "dependencies": { + "@docusaurus/core": "^2.2.0", + "@docusaurus/preset-classic": "^2.2.0", + "@easyops-cn/docusaurus-search-local": "^0.32.0", + "@mdx-js/react": "^1.6.22", + "axios": "^1.1.3", + "clsx": "^1.2.1", + "fs-extra": "^10.1.0", + "prism-react-renderer": "^1.3.5", + "react": "^17.0.2", + "react-dom": "^17.0.2" + }, + "devDependencies": { + "@docusaurus/module-type-aliases": "^2.2.0", + "@tsconfig/docusaurus": "^1.0.5", + "typescript": "^4.7.4" + }, + "browserslist": { + "production": [ + ">0.5%", + "not dead", + "not op_mini all" + ], + "development": [ + "last 1 chrome version", + "last 1 firefox version", + "last 1 safari version" + ] + }, + "engines": { + "node": ">=16.14" + }, + "publishConfig": { + "access": "public", + "registry": "https://registry.npmjs.org/" + }, + "repository": { + "type": "http", + "url": "https://github.com/alibaba/lowcode-engine/tree/main" + }, + "gitHead": "2669f179e6f899d395ce1942d0fe04f9c5ed48a6" +} diff --git a/docs/scripts/getDocsFromDir.js b/docs/scripts/getDocsFromDir.js new file mode 100644 index 0000000000..1d3236fe69 --- /dev/null +++ b/docs/scripts/getDocsFromDir.js @@ -0,0 +1,60 @@ +const fs = require('fs'); +const path = require('path'); +const glob = require('glob'); +const matter = require('gray-matter'); + +module.exports = function getDocsFromDir(dir, cateList) { + // docs/ + const baseDir = path.join(__dirname, '../docs/'); + const docsDir = path.join(baseDir, dir); + + function getMarkdownOrder(filepath) { + return (matter(fs.readFileSync(filepath, 'utf-8')).data || {}).order || 100; + } + + const docs = glob.sync('*.md?(x)', { + cwd: docsDir, + // ignore: 'README.md', + }); + + const result = docs + .filter(doc => !/^index.md(x)?$/.test(doc)) + .map(doc => { + return path.join(docsDir, doc); + }) + .sort((a, b) => { + const orderA = getMarkdownOrder(a); + const orderB = getMarkdownOrder(b); + + return orderA - orderB; + }) + .map(filepath => { + // /Users/xxx/site/docs/guide/basic/router.md => guide/basic/router + const id = path + .relative(baseDir, filepath) + .replace(/\\/g, '/') + .replace(/\.mdx?/, ''); + return id; + }); + + (cateList || []).forEach(item => { + const { dir, subCategory, ...otherConfig } = item; + const indexList = glob.sync('index.md?(x)', { + cwd: path.join(baseDir, dir), + }); + if (indexList.length > 0) { + otherConfig.link = { + type: 'doc', + id: `${dir}/index`, + }; + } + result.push({ + type: 'category', + collapsed: false, + ...otherConfig, + items: getDocsFromDir(dir, subCategory), + }); + }); + + return result; +}; diff --git a/docs/src/css/custom.css b/docs/src/css/custom.css new file mode 100644 index 0000000000..9b929baae6 --- /dev/null +++ b/docs/src/css/custom.css @@ -0,0 +1,103 @@ + +/** + * Any CSS included here will be global. The classic template + * bundles Infima by default. Infima is a CSS framework designed to + * work well for content-centric websites. + */ + +/* You can override the default Infima variables here. */ +:root { + --ifm-font-size-base: 14px; + --ifm-color-primary: #0089ff; + --ifm-color-primary-dark: #007be6; + --ifm-color-primary-darker: #0074d9; + --ifm-color-primary-darkest: #0060b3; + --ifm-color-primary-light: #1a95ff; + --ifm-color-primary-lighter: #269bff; + --ifm-color-primary-lightest: #4dacff; + --ifm-code-font-size: 95%; + --ifm-container-width-xl: 2000px; + --aa-search-input-height: 32px; + --ifm-font-family-base: -apple-system, Segoe UI, Roboto, Ubuntu, Cantarell, Noto Sans, sans-serif, BlinkMacSystemFont, + 'Segoe UI', Helvetica, Arial, sans-serif, 'Apple Color Emoji'; + --ifm-font-family-monospace: Menlo, Monaco, Consolas, "Courier New", monospace; + --ifm-global-spacing: 1.5rem; + --ifm-line-height-base: 1.85; + /* --ifm-font-color-base: #333; */ +} + +.header-github-link::before { + content: ''; + width: 24px; + height: 24px; + display: flex; + background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") + no-repeat; +} + +[data-theme='dark'] .header-github-link::before { + background: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath fill='white' d='M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12'/%3E%3C/svg%3E") + no-repeat; +} + +.docusaurus-highlight-code-line { + background-color: rgba(0, 0, 0, 0.1); + display: block; + margin: 0 calc(-1 * var(--ifm-pre-padding)); + padding: 0 var(--ifm-pre-padding); +} + +html[data-theme='dark'] .docusaurus-highlight-code-line { + background-color: rgba(0, 0, 0, 0.3); +} + +.navbar__logo, +.navbar__search { + margin-right: 2rem; +} + +.hero { + padding: 5rem 0 !important; + box-shadow: var(--ifm-navbar-shadow); +} + +.homepage-content { + max-width: 1400px; + margin: 0 auto; +} + +.heroBanner { + padding: 4rem 0; + text-align: center; + position: relative; + overflow: hidden; +} + +.hero__title{ + font-size: 2.4rem; + background: -webkit-linear-gradient(315deg,#0089ff 25%,#30e724); + background-clip: text; + -webkit-background-clip: text; + -webkit-text-fill-color: transparent; + display: inline-block; +} + +.pagination-nav__link { + padding: 0.5rem 1.5rem; +} + +.markdown h1:first-child { + --ifm-h1-font-size: 2rem; +} + +.markdown > h2{ + --ifm-h2-font-size: 1.5rem; +} + +.markdown > h3{ + --ifm-h3-font-size: 1.25rem; +} + +.markdown img { + box-shadow: 9px 8px 10px 0px rgb(0 0 0 / 15%); +} diff --git a/docs/src/pages/index.module.css b/docs/src/pages/index.module.css new file mode 100644 index 0000000000..ac3d449967 --- /dev/null +++ b/docs/src/pages/index.module.css @@ -0,0 +1,29 @@ +/** + * CSS files with the .module.css suffix will be treated as CSS modules + * and scoped locally. + */ + +.heroBanner { + padding: 4rem 0; + text-align: center; + position: relative; + overflow: hidden; + height: 60rem; +} + +.heroTitle { + color: #30e724; + font-size: 3rem; +} + +@media screen and (max-width: 996px) { + .heroBanner { + padding: 2rem; + } +} + +.buttons { + display: flex; + align-items: center; + justify-content: center; +} \ No newline at end of file diff --git a/docs/src/pages/index.tsx b/docs/src/pages/index.tsx new file mode 100644 index 0000000000..13be38e6e2 --- /dev/null +++ b/docs/src/pages/index.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import Layout from '@theme/Layout'; + +import styles from './index.module.css'; + +function HomepageHeader() { + const { siteConfig } = useDocusaurusContext(); + return ( +
+
+

{siteConfig.title}

+

欢迎光临 低代码引擎文档站

+

{siteConfig.tagline}

+
+ + 快速开始 + +
+
+
+ ); +} + +export default function Home(): JSX.Element { + const { siteConfig } = useDocusaurusContext(); + return ( + + + + ); +} diff --git a/docs/src/pages/markdown-page.md b/docs/src/pages/markdown-page.md new file mode 100644 index 0000000000..7d2421c8a6 --- /dev/null +++ b/docs/src/pages/markdown-page.md @@ -0,0 +1,15 @@ + + +# 文档能力介绍 + +这是一个使用 Markdown 编写的任意页面,访问地址为 /markdown-page + +Product Docs Capability Introduction. + +## 功能 + +- ✅ 支持本地离线搜搜 +- ✅ 版本化文档管理 +- ✅ 离线静态部署 diff --git a/docs/static/img/docusaurus.png b/docs/static/img/docusaurus.png new file mode 100644 index 0000000000000000000000000000000000000000..f458149e3c8f53335f28fbc162ae67f55575c881 GIT binary patch literal 5142 zcma)=cTf{R(}xj7f`AaDml%oxrAm_`5IRVc-jPtHML-0kDIiip57LWD@4bW~(nB|) z34|^sbOZqj<;8ct`Tl-)=Jw`pZtiw=e$UR_Mn2b8rM$y@hlq%XQe90+?|Mf68-Ux_ zzTBiDn~3P%oVt>{f$z+YC7A)8ak`PktoIXDkpXod+*gQW4fxTWh!EyR9`L|fi4YlH z{IyM;2-~t3s~J-KF~r-Z)FWquQCfG*TQy6w*9#k2zUWV-+tCNvjrtl9(o}V>-)N!) ziZgEgV>EG+b(j@ex!dx5@@nGZim*UfFe<+e;(xL|j-Pxg(PCsTL~f^br)4{n5?OU@ z*pjt{4tG{qBcDSa3;yKlopENd6Yth=+h9)*lkjQ0NwgOOP+5Xf?SEh$x6@l@ZoHoYGc5~d2>pO43s3R|*yZw9yX^kEyUV2Zw1%J4o`X!BX>CwJ zI8rh1-NLH^x1LnaPGki_t#4PEz$ad+hO^$MZ2 ziwt&AR}7_yq-9Pfn}k3`k~dKCbOsHjvWjnLsP1{)rzE8ERxayy?~{Qz zHneZ2gWT3P|H)fmp>vA78a{0&2kk3H1j|n59y{z@$?jmk9yptqCO%* zD2!3GHNEgPX=&Ibw?oU1>RSxw3;hhbOV77-BiL%qQb1(4J|k=Y{dani#g>=Mr?Uyd z)1v~ZXO_LT-*RcG%;i|Wy)MvnBrshlQoPxoO*82pKnFSGNKWrb?$S$4x+24tUdpb= zr$c3K25wQNUku5VG@A=`$K7%?N*K+NUJ(%%)m0Vhwis*iokN#atyu(BbK?+J+=H z!kaHkFGk+qz`uVgAc600d#i}WSs|mtlkuwPvFp) z1{Z%nt|NwDEKj1(dhQ}GRvIj4W?ipD76jZI!PGjd&~AXwLK*98QMwN&+dQN1ML(6< z@+{1`=aIc z9Buqm97vy3RML|NsM@A>Nw2=sY_3Ckk|s;tdn>rf-@Ke1m!%F(9(3>V%L?w#O&>yn z(*VIm;%bgezYB;xRq4?rY})aTRm>+RL&*%2-B%m; zLtxLTBS=G!bC$q;FQ|K3{nrj1fUp`43Qs&V!b%rTVfxlDGsIt3}n4p;1%Llj5ePpI^R} zl$Jhx@E}aetLO!;q+JH@hmelqg-f}8U=XnQ+~$9RHGUDOoR*fR{io*)KtYig%OR|08ygwX%UqtW81b@z0*`csGluzh_lBP=ls#1bwW4^BTl)hd|IIfa zhg|*M%$yt@AP{JD8y!7kCtTmu{`YWw7T1}Xlr;YJTU1mOdaAMD172T8Mw#UaJa1>V zQ6CD0wy9NEwUsor-+y)yc|Vv|H^WENyoa^fWWX zwJz@xTHtfdhF5>*T70(VFGX#8DU<^Z4Gez7vn&4E<1=rdNb_pj@0?Qz?}k;I6qz@| zYdWfcA4tmI@bL5JcXuoOWp?ROVe*&o-T!><4Ie9@ypDc!^X&41u(dFc$K$;Tv$c*o zT1#8mGWI8xj|Hq+)#h5JToW#jXJ73cpG-UE^tsRf4gKw>&%Z9A>q8eFGC zG@Iv(?40^HFuC_-%@u`HLx@*ReU5KC9NZ)bkS|ZWVy|_{BOnlK)(Gc+eYiFpMX>!# zG08xle)tntYZ9b!J8|4H&jaV3oO(-iFqB=d}hGKk0 z%j)johTZhTBE|B-xdinS&8MD=XE2ktMUX8z#eaqyU?jL~PXEKv!^) zeJ~h#R{@O93#A4KC`8@k8N$T3H8EV^E2 z+FWxb6opZnX-av5ojt@`l3TvSZtYLQqjps{v;ig5fDo^}{VP=L0|uiRB@4ww$Eh!CC;75L%7|4}xN+E)3K&^qwJizphcnn=#f<&Np$`Ny%S)1*YJ`#@b_n4q zi%3iZw8(I)Dzp0yY}&?<-`CzYM5Rp+@AZg?cn00DGhf=4|dBF8BO~2`M_My>pGtJwNt4OuQm+dkEVP4 z_f*)ZaG6@t4-!}fViGNd%E|2%ylnzr#x@C!CrZSitkHQ}?_;BKAIk|uW4Zv?_npjk z*f)ztC$Cj6O<_{K=dPwO)Z{I=o9z*lp?~wmeTTP^DMP*=<-CS z2FjPA5KC!wh2A)UzD-^v95}^^tT<4DG17#wa^C^Q`@f@=jLL_c3y8@>vXDJd6~KP( zurtqU1^(rnc=f5s($#IxlkpnU=ATr0jW`)TBlF5$sEwHLR_5VPTGiO?rSW9*ND`bYN*OX&?=>!@61{Z4)@E;VI9 zvz%NmR*tl>p-`xSPx$}4YcdRc{_9k)>4Jh&*TSISYu+Y!so!0JaFENVY3l1n*Fe3_ zRyPJ(CaQ-cNP^!3u-X6j&W5|vC1KU!-*8qCcT_rQN^&yqJ{C(T*`(!A=))=n%*-zp_ewRvYQoJBS7b~ zQlpFPqZXKCXUY3RT{%UFB`I-nJcW0M>1^*+v)AxD13~5#kfSkpWys^#*hu)tcd|VW zEbVTi`dbaM&U485c)8QG#2I#E#h)4Dz8zy8CLaq^W#kXdo0LH=ALhK{m_8N@Bj=Um zTmQOO*ID(;Xm}0kk`5nCInvbW9rs0pEw>zlO`ZzIGkB7e1Afs9<0Z(uS2g*BUMhp> z?XdMh^k}k<72>}p`Gxal3y7-QX&L{&Gf6-TKsE35Pv%1 z;bJcxPO+A9rPGsUs=rX(9^vydg2q`rU~otOJ37zb{Z{|)bAS!v3PQ5?l$+LkpGNJq zzXDLcS$vMy|9sIidXq$NE6A-^v@)Gs_x_3wYxF%y*_e{B6FvN-enGst&nq0z8Hl0< z*p6ZXC*su`M{y|Fv(Vih_F|83=)A6ay-v_&ph1Fqqcro{oeu99Y0*FVvRFmbFa@gs zJ*g%Gik{Sb+_zNNf?Qy7PTf@S*dTGt#O%a9WN1KVNj`q$1Qoiwd|y&_v?}bR#>fdP zSlMy2#KzRq4%?ywXh1w;U&=gKH%L~*m-l%D4Cl?*riF2~r*}ic9_{JYMAwcczTE`!Z z^KfriRf|_YcQ4b8NKi?9N7<4;PvvQQ}*4YxemKK3U-7i}ap8{T7=7`e>PN7BG-Ej;Uti2$o=4T#VPb zm1kISgGzj*b?Q^MSiLxj26ypcLY#RmTPp+1>9zDth7O?w9)onA%xqpXoKA-`Jh8cZ zGE(7763S3qHTKNOtXAUA$H;uhGv75UuBkyyD;eZxzIn6;Ye7JpRQ{-6>)ioiXj4Mr zUzfB1KxvI{ZsNj&UA`+|)~n}96q%_xKV~rs?k=#*r*7%Xs^Hm*0~x>VhuOJh<2tcb zKbO9e-w3zbekha5!N@JhQm7;_X+J!|P?WhssrMv5fnQh$v*986uWGGtS}^szWaJ*W z6fLVt?OpPMD+-_(3x8Ra^sX~PT1t5S6bfk@Jb~f-V)jHRul#Hqu;0(+ER7Z(Z4MTR z+iG>bu+BW2SNh|RAGR2-mN5D1sTcb-rLTha*@1@>P~u;|#2N{^AC1hxMQ|(sp3gTa zDO-E8Yn@S7u=a?iZ!&&Qf2KKKk7IT`HjO`U*j1~Df9Uxz$~@otSCK;)lbLSmBuIj% zPl&YEoRwsk$8~Az>>djrdtp`PX z`Pu#IITS7lw07vx>YE<4pQ!&Z^7L?{Uox`CJnGjYLh1XN^tt#zY*0}tA*a=V)rf=&-kLgD|;t1D|ORVY}8 F{0H{b<4^zq literal 0 HcmV?d00001 diff --git a/docs/static/img/logo.svg b/docs/static/img/logo.svg new file mode 100644 index 0000000000..9db6d0d066 --- /dev/null +++ b/docs/static/img/logo.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/docs/static/img/undraw_docusaurus_mountain.svg b/docs/static/img/undraw_docusaurus_mountain.svg new file mode 100644 index 0000000000..af961c49a8 --- /dev/null +++ b/docs/static/img/undraw_docusaurus_mountain.svg @@ -0,0 +1,171 @@ + + Easy to Use + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/static/img/undraw_docusaurus_react.svg b/docs/static/img/undraw_docusaurus_react.svg new file mode 100644 index 0000000000..94b5cf08f8 --- /dev/null +++ b/docs/static/img/undraw_docusaurus_react.svg @@ -0,0 +1,170 @@ + + Powered by React + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/static/img/undraw_docusaurus_tree.svg b/docs/static/img/undraw_docusaurus_tree.svg new file mode 100644 index 0000000000..d9161d3392 --- /dev/null +++ b/docs/static/img/undraw_docusaurus_tree.svg @@ -0,0 +1,40 @@ + + Focus on What Matters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/docs/tsconfig.json b/docs/tsconfig.json new file mode 100644 index 0000000000..6f4756980d --- /dev/null +++ b/docs/tsconfig.json @@ -0,0 +1,7 @@ +{ + // This file is not used in compilation. It is here just for a nice editor experience. + "extends": "@tsconfig/docusaurus/tsconfig.json", + "compilerOptions": { + "baseUrl": "." + } +} From 3e485b07dae2dd6f440fcdeea6f1a5e9ee9a62c0 Mon Sep 17 00:00:00 2001 From: "xiaoxian.xlf" Date: Mon, 28 Nov 2022 16:05:36 +0800 Subject: [PATCH 206/823] feat: add index rediect --- docs/package.json | 2 +- docs/src/pages/index-old.tsx | 40 +++++++++++++++++++++++++++++++ docs/src/pages/index.tsx | 46 +++++++++--------------------------- 3 files changed, 52 insertions(+), 36 deletions(-) create mode 100644 docs/src/pages/index-old.tsx diff --git a/docs/package.json b/docs/package.json index 306b58cacd..8bbab34d89 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "0.0.1-beta.3", + "version": "0.0.1-beta.4", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ diff --git a/docs/src/pages/index-old.tsx b/docs/src/pages/index-old.tsx new file mode 100644 index 0000000000..13be38e6e2 --- /dev/null +++ b/docs/src/pages/index-old.tsx @@ -0,0 +1,40 @@ +import React from 'react'; +import clsx from 'clsx'; +import Link from '@docusaurus/Link'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import Layout from '@theme/Layout'; + +import styles from './index.module.css'; + +function HomepageHeader() { + const { siteConfig } = useDocusaurusContext(); + return ( +
+
+

{siteConfig.title}

+

欢迎光临 低代码引擎文档站

+

{siteConfig.tagline}

+
+ + 快速开始 + +
+
+
+ ); +} + +export default function Home(): JSX.Element { + const { siteConfig } = useDocusaurusContext(); + return ( + + + + ); +} diff --git a/docs/src/pages/index.tsx b/docs/src/pages/index.tsx index 13be38e6e2..cdf826a64a 100644 --- a/docs/src/pages/index.tsx +++ b/docs/src/pages/index.tsx @@ -1,40 +1,16 @@ import React from 'react'; -import clsx from 'clsx'; -import Link from '@docusaurus/Link'; -import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; -import Layout from '@theme/Layout'; +import BrowserOnly from '@docusaurus/BrowserOnly'; -import styles from './index.module.css'; - -function HomepageHeader() { - const { siteConfig } = useDocusaurusContext(); - return ( -
-
-

{siteConfig.title}

-

欢迎光临 低代码引擎文档站

-

{siteConfig.tagline}

-
- - 快速开始 - -
-
-
- ); -} - -export default function Home(): JSX.Element { - const { siteConfig } = useDocusaurusContext(); +export default function ToIndex(): JSX.Element { return ( - - - + + {() => { + /** + * 跳转到首页 + */ + window.location.href = '/index'; + return <>; + }} + ); } From 3a0ab6d4419afc5841ac5197d84eee0758d4fe28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Mon, 28 Nov 2022 16:40:44 +0800 Subject: [PATCH 207/823] fix: componentName can contain dot notation --- modules/code-generator/src/plugins/common/esmodule.ts | 4 ++-- modules/code-generator/src/utils/validate.ts | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/modules/code-generator/src/plugins/common/esmodule.ts b/modules/code-generator/src/plugins/common/esmodule.ts index ee28083d15..04dfd1ce21 100644 --- a/modules/code-generator/src/plugins/common/esmodule.ts +++ b/modules/code-generator/src/plugins/common/esmodule.ts @@ -16,7 +16,7 @@ import { IWithDependency, } from '../../types'; -import { isValidIdentifier } from '../../utils/validate'; +import { isValidIdentifier, isValidComponentName } from '../../utils/validate'; // TODO: main 这个信息到底怎么用,是不是外部包不需要使用? const DEP_MAIN_BLOCKLIST = ['lib', 'lib/index', 'es', 'es/index', 'main']; @@ -261,7 +261,7 @@ function buildPackageImport( if (!isValidIdentifier(name)) { throw new CodeGeneratorError(`Invalid Identifier [${name}]`); } - if (info.nodeIdentifier && !isValidIdentifier(info.nodeIdentifier)) { + if (info.nodeIdentifier && !isValidComponentName(info.nodeIdentifier)) { throw new CodeGeneratorError(`Invalid Identifier [${info.nodeIdentifier}]`); } }); diff --git a/modules/code-generator/src/utils/validate.ts b/modules/code-generator/src/utils/validate.ts index 4ee0d5b2a3..8d6f9c0d1c 100644 --- a/modules/code-generator/src/utils/validate.ts +++ b/modules/code-generator/src/utils/validate.ts @@ -2,6 +2,10 @@ export const isValidIdentifier = (name: string) => { return /^[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*$/.test(name); }; +export const isValidComponentName = (name: string) => { + return /^[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF.]*$/.test(name); +}; + export const ensureValidClassName = (name: string) => { if (!isValidIdentifier(name)) { return `$${name.replace(/[^_$a-zA-Z0-9]/g, '')}`; From cff86c492ae3999b87503a750e014ebdb34e2098 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Mon, 28 Nov 2022 16:41:24 +0800 Subject: [PATCH 208/823] chore(release): code-generator - 1.0.7-beta.3 --- modules/code-generator/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/code-generator/package.json b/modules/code-generator/package.json index 4abacc7ffe..3e7898e390 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.2", + "version": "1.0.7-beta.3", "description": "出码引擎 for LowCode Engine", "license": "MIT", "main": "lib/index.js", From b2af5b29d57066b021a3f027003c23855bd239b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E7=86=A0?= Date: Tue, 29 Nov 2022 10:20:37 +0800 Subject: [PATCH 209/823] Update issue templates --- .github/ISSUE_TEMPLATE/bug-report.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/ISSUE_TEMPLATE/bug-report.md b/.github/ISSUE_TEMPLATE/bug-report.md index 193cab77eb..c72471ee28 100644 --- a/.github/ISSUE_TEMPLATE/bug-report.md +++ b/.github/ISSUE_TEMPLATE/bug-report.md @@ -1,6 +1,6 @@ --- name: Bug report / 提交 bug -about: Create a report to help us improve / 提交一个好的 issue 帮助我们优化引擎,[引擎的 issue 说明](https://www.yuque.com/lce/doc/yvlxhs) +about: Create a report to help us improve / 提交一个好的 issue 帮助我们优化引擎,[引擎的 issue 说明](https://lowcode-engine.cn/site/community/issue) title: '' labels: '' assignees: '' From 5f14347903f0d25f78a338262dc35b38f95e9fa7 Mon Sep 17 00:00:00 2001 From: JackLian Date: Tue, 29 Nov 2022 08:39:41 +0800 Subject: [PATCH 210/823] feat: move specs to docs --- docs/config/navbar.js | 6 ++ docs/config/sidebars.js | 6 ++ docs/docs/api/common.md | 14 +++ {specs => docs/docs/specs}/assets-spec.md | 58 ++++++----- {specs => docs/docs/specs}/lowcode-spec.md | 105 +++++++++++--------- {specs => docs/docs/specs}/material-spec.md | 102 ++++++++++--------- docs/docusaurus.config.js | 39 -------- docs/package.json | 2 +- 8 files changed, 167 insertions(+), 165 deletions(-) rename {specs => docs/docs/specs}/assets-spec.md (94%) rename {specs => docs/docs/specs}/lowcode-spec.md (97%) rename {specs => docs/docs/specs}/material-spec.md (97%) diff --git a/docs/config/navbar.js b/docs/config/navbar.js index efbe88ec0f..0f0486398b 100644 --- a/docs/config/navbar.js +++ b/docs/config/navbar.js @@ -21,6 +21,12 @@ module.exports = { position: 'left', label: 'API', }, + { + type: 'doc', + docId: 'specs/lowcode-spec', + position: 'left', + label: '协议', + }, { type: 'doc', docId: 'faq/index', diff --git a/docs/config/sidebars.js b/docs/config/sidebars.js index fc14767a3c..e2de2d49cd 100644 --- a/docs/config/sidebars.js +++ b/docs/config/sidebars.js @@ -33,6 +33,12 @@ module.exports = { dirName: 'api', }, ], + specs: [ + { + type: 'autogenerated', + dirName: 'specs', + }, + ], faq: [ { type: 'autogenerated', diff --git a/docs/docs/api/common.md b/docs/docs/api/common.md index 886ae925ab..46b4d7f034 100644 --- a/docs/docs/api/common.md +++ b/docs/docs/api/common.md @@ -42,6 +42,20 @@ common.utils.startTransaction(() => { }, TransitionType.repaint); ``` +### createIntl +i18n相关工具 +*引擎版本 >= 1.0.17 +```typescript +import { common } from '@alilc/lowcode-engine'; +import enUS from './en-US.json'; +import zhCN from './zh-CN.json'; + +const { intl, getLocale, setLocale } = common.utils.createIntl({ + 'en-US': enUS, + 'zh-CN': zhCN, +}); + +``` ## designerCabin ### isSettingField 是否是 SettingField 实例 diff --git a/specs/assets-spec.md b/docs/docs/specs/assets-spec.md similarity index 94% rename from specs/assets-spec.md rename to docs/docs/specs/assets-spec.md index ab0e1abc02..5c7df0163f 100644 --- a/specs/assets-spec.md +++ b/docs/docs/specs/assets-spec.md @@ -1,8 +1,12 @@ +--- +title: 《低代码引擎资产包协议规范》 +sidebar_position: 2 +--- # 《低代码引擎资产包协议规范》 -# 1 介绍 +## 1 介绍 -## 1.1 本协议规范涉及的问题域 +### 1.1 本协议规范涉及的问题域 - 定义本协议版本号规范 - 定义本协议中每个子规范需要被支持的 Level @@ -12,16 +16,16 @@ - 定义低代码资产包协议组件描述资源加载规范(A) - 定义低代码资产包协议组件在面板展示规范(AA) -## 1.2 协议草案起草人 +### 1.2 协议草案起草人 - 撰写:金禅、璿玑、彼洋 - 审阅:力皓、絮黎、光弘、戊子、潕量、游鹿 -## 1.3 版本号 +### 1.3 版本号 1.1.0 -## 1.4 协议版本号规范(A) +### 1.4 协议版本号规范(A) 本协议采用语义版本号,版本号格式为 `major.minor.patch` 的形式。 @@ -29,7 +33,7 @@ - minor 是小版本号:用于发布向下兼容的协议功能新增 - patch 是补丁号:用于发布向下兼容的协议问题修正 -## 1.5 协议中子规范 Level 定义 +### 1.5 协议中子规范 Level 定义 | 规范等级 | 实现要求 | | -------- | ------------------------------------------------------------ | @@ -37,19 +41,19 @@ | AA | 推荐规范,由低代码引擎官方插件、setter 支持。 | | AAA | 参考规范,需由基于引擎的上层搭建平台支持,实现可参考该规范。 | -## 1.6 名词术语 +### 1.6 名词术语 - **资产包**: 低代码引擎加载资源的动态数据集合,主要包含组件及其依赖的资源、组件低代码描述、动态插件/设置器资源等。 -## 1.7 背景 +### 1.7 背景 根据低代码引擎的实现,一个组件要在引擎上渲染和配置,需要提供组件的 umd 资源以及组件的`低代码描述`,并且组件通常都是以集合的形式被引擎消费的;除了组件之外,还有组件的依赖资源、引擎的动态插件/设置器等资源也需要注册到引擎中;因此我们定义了“低代码资产包”这个数据结构,来描述引擎所需加载的动态资源的集合。 -## 1.8 受众 +### 1.8 受众 本协议适用于使用“低代码引擎”构建搭建平台的开发者,通过本协议的定义来进行资源的分类和加载。阅读及使用本协议,需要对低代码搭建平台的交互和实现有一定的了解,对前端开发相关技术栈的熟悉也会有帮助,协议中对通用的前端相关术语不会做进一步的解释说明。 -# 2 协议结构 +## 2 协议结构 协议最顶层结构如下,包含 7 方面的描述内容: @@ -61,7 +65,7 @@ - setters { Array } 设计器中设置器描述协议列表 - extConfig { Object } 平台自定义扩展字段 -## 2.1 version(A) +### 2.1 version(A) 定义当前协议 schema 的版本号; @@ -69,7 +73,7 @@ | ---------- | ------ | ---------- | -------- | ------ | | version | String | 协议版本号 | - | 1.1.0 | -## 2.2 packages(A) +### 2.2 packages(A) 定义低代码编辑器中加载的资源列表,包含公共库和组件(库) cdn 资源等; @@ -81,18 +85,18 @@ | packages[].version | npm 包版本号 | String | A | 组件资源版本号 | | packages[].type | 资源包类型 | String | AA | 取值为: proCode(源码)、lowCode(低代码,默认为 proCode | | packages[].schema | 低代码组件 schema 内容 | object | AA | 取值为: proCode(源码)、lowCode(低代码) | -| packages[].deps | 当前资源包的依赖资源的唯一标识列表 | Array | A | 唯一标识为 id 或者 package 对应的值 | +| packages[].deps | 当前资源包的依赖资源的唯一标识列表 | Array | A | 唯一标识为 id 或者 package 对应的值 | | packages[].library | 作为全局变量引用时的名称,用来定义全局变量名 | String | A | 低代码引擎通过该字段获取组件实例 | -| packages[].editUrls | 组件编辑态视图打包后的 CDN url 列表,包含 js 和 css | Array | A | 低代码引擎编辑器会加载这些 url | -| packages[].urls | 组件渲染态视图打包后的 CDN url 列表,包含 js 和 css | Array | AA | 低代码引擎渲染模块会加载这些 url | +| packages[].editUrls | 组件编辑态视图打包后的 CDN url 列表,包含 js 和 css | Array | A | 低代码引擎编辑器会加载这些 url | +| packages[].urls | 组件渲染态视图打包后的 CDN url 列表,包含 js 和 css | Array | AA | 低代码引擎渲染模块会加载这些 url | | packages[].advancedEditUrls | 组件多个编辑态视图打包后的 CDN url 列表集合,包含 js 和 css | Object | AAA | 上层平台根据特定标识提取某个编辑态的资源,低代码引擎编辑器会加载这些资源,优先级高于 packages[].editUrls | | packages[].advancedUrls | 组件多个端的渲染态视图打包后的 CDN url 列表集合,包含 js 和 css | Object | AAA | 上层平台根据特定标识提取某个渲染态的资源, 低代码引擎渲染模块会加载这些资源,优先级高于 packages[].urls | | packages[].external | 当前资源在作为其他资源的依赖,在其他依赖打包时时是否被排除了(同 webpack 中 external 概念) | Boolean | AAA | 某些资源会被单独提取出来,是其他依赖的前置依赖,根据这个字段决定是否提前加载该资源 | -| packages[].loadEnv | 指定当前资源加载的环境 | Array | AAA | 主要用于指定 external 资源加载的环境,取值为 design(设计态)、runtime(预览态)中的一个或多个 | +| packages[].loadEnv | 指定当前资源加载的环境 | Array | AAA | 主要用于指定 external 资源加载的环境,取值为 design(设计态)、runtime(预览态)中的一个或多个 | | packages[].exportSourceId | 标识当前 package 内容是从哪个 package 导出来的 | String | AAA | 此时 urls 无效 | | packages[].exportSourceLibrary | 标识当前 package 是从 window 上的哪个属性导出来的 | String | AAA | exportSourceId 的优先级高于exportSourceLibrary ,此时 urls 无效 | | packages[].async | 标识当前 package 资源加载在 window.library 上的是否是一个异步对象 | Boolean | A | async 为 true 时,需要通过 await 才能拿到真正内容 | -| packages[].exportMode | 标识当前 package 从其他 package 的导出方式 | String | A | 目前只支持 `"functionCall"`, exportMode等于 `"functionCall"` 时,当前package 的内容以函数的方式从其他 package 中导出,具体导出接口如: (library: string, packageName: string, isRuntime?: boolean) => any | Promise, library 为当前 package 的 library, packageName 为当前的包名,返回值为当前 package 的导出内容 | +| packages[].exportMode | 标识当前 package 从其他 package 的导出方式 | String | A | 目前只支持 `"functionCall"`, exportMode等于 `"functionCall"` 时,当前package 的内容以函数的方式从其他 package 中导出,具体导出接口如: (library: string, packageName: string, isRuntime?: boolean) => any | Promise, library 为当前 package 的 library, packageName 为当前的包名,返回值为当前 package 的导出内容 | 描述举例: @@ -294,14 +298,14 @@ } ``` -## 2.3 components (A) +### 2.3 components (A) 定义资产包中包含的所有组件的低代码描述的集合,分为“ComponentDescription”和“RemoteComponentDescription”(详见 2.6 TypeScript 定义): - ComponentDescription: 符合“组件描述协议”的数据,详见物料规范中`2.2.2 组件描述协议`部分; - RemoteComponentDescription 是将一个或多个 ComponentDescription 构建打包的 js 资源的描述,在浏览器中加载该资源后可获取到其中包含的每个组件的 ComponentDescription 的具体内容; -## 2.4 sort (AA) +### 2.4 sort (AA) 定义组件列表分组 @@ -310,7 +314,7 @@ | sort.groupList | String[] | 组件分组,用于组件面板 tab 展示 | - | ['精选组件', '原子组件'] | | sort.categoryList | String[] | 组件面板中同一个 tab 下的不同区间用 category 区分,category 的排序依照 categoryList 顺序排列 | - | ['通用', '数据展示', '表格类', '表单类'] | -## 2.5 plugins (AAA) +### 2.5 plugins (AAA) 自定义设计器插件列表 @@ -325,7 +329,7 @@ | plugins[].keywords | String[] | 插件检索关键字 | - | - | | plugins[].reference | Reference | 插件引用的资源包信息 | - | - | -## 2.6 setters (AAA) +### 2.6 setters (AAA) 自定义设置器列表 @@ -340,11 +344,11 @@ | setters[].keywords | String[] | 设置器检索关键字 | - | - | | setters[].reference | Reference | 设置器引用的资源包信息 | - | - | -## 2.7 extConfig (AAA) +### 2.7 extConfig (AAA) 定义平台相关的扩展内容,用于存放平台自身实现的一些私有协议, 以允许存量平台能够平滑地迁移至标准协议。 extConfig 是一个 key-value 结构的对象,协议不会规定 extConfig 中的字段名称以及类型, 完全自定义 -## 2.8 TypeScript 定义 +### 2.8 TypeScript 定义 _组件低代码描述相关部分字段含义详见物料规范中`2.2.2 组件描述协议`部分;_ @@ -463,7 +467,7 @@ export interface Package { */ exportName?: string; /** - * 标识当前 package 资源加载在 window.library 上的是否是一个异步对象 + * 标识当前 package 资源加载在 window.library 上的是否是一个异步对象 */ async?: boolean; /** @@ -471,11 +475,11 @@ export interface Package { */ exportMode?: string; /** - * 标识当前 package 内容是从哪个 package 导出来的 + * 标识当前 package 内容是从哪个 package 导出来的 */ exportSourceId?: string; /** - * 标识当前 package 是从 window 上的哪个属性导出来的 + * 标识当前 package 是从 window 上的哪个属性导出来的 */ exportSourceLibrary?: string; } @@ -684,4 +688,4 @@ export interface ComponentSchema { ``` -`ComponentSchema` 的定义见[低代码业务组件描述](./1.material-spec.md#221-组件规范) +`ComponentSchema` 的定义见[低代码业务组件描述](./material-spec.md#221-组件规范) diff --git a/specs/lowcode-spec.md b/docs/docs/specs/lowcode-spec.md similarity index 97% rename from specs/lowcode-spec.md rename to docs/docs/specs/lowcode-spec.md index 043ad81bfe..e1d57daa04 100644 --- a/specs/lowcode-spec.md +++ b/docs/docs/specs/lowcode-spec.md @@ -1,6 +1,13 @@ +--- +title: 《低代码引擎搭建协议规范》 +sidebar_position: 0 +--- # 《低代码引擎搭建协议规范》 -## 1.1 本协议规范涉及的问题域 + +## 1 介绍 + +### 1.1 本协议规范涉及的问题域 - 定义本协议版本号规范 - 定义本协议中每个子规范需要被支持的 Level @@ -12,17 +19,17 @@ - 定义搭建基础协议无障碍访问规范(AAA) -## 1.2 协议草案起草人 +### 1.2 协议草案起草人 - 撰写:月飞、康为、林熠 - 审阅:大果、潕量、九神、元彦、戊子、屹凡、金禅、前道、天晟、戊子、游鹿、光弘、力皓 -## 1.3 版本号 +### 1.3 版本号 1.0.0 -## 1.4 协议版本号规范(A) +### 1.4 协议版本号规范(A) 本协议采用语义版本号,版本号格式为 `major.minor.patch` 的形式。 @@ -31,7 +38,7 @@ - patch 是补丁号:用于发布向下兼容的协议问题修正 -## 1.5 协议中子规范 Level 定义 +### 1.5 协议中子规范 Level 定义 | 规范等级 | 实现要求 | | -------- | ---------------------------------------------------------------------------------- | @@ -40,9 +47,9 @@ | AAA | 参考规范,根据业务场景实际诉求实现;是集团层面鼓励的技术实现引导。 | -## 1.6 名词术语 +### 1.6 名词术语 -### 1.6.1 物料系统名词 +#### 1.6.1 物料系统名词 - **基础组件(Basic Component)**:前端领域通用的基础组件,阿里巴巴前端委员会官方指定的基础组件库是 Fusion Next/AntD。 - **图表组件(Chart Component)**:前端领域通用的图表组件,有代表性的图表组件库有 BizCharts。 @@ -54,7 +61,7 @@ - **模板(Template)**:特定垂直业务领域内的业务组件、区块可组合为单个页面,或者是再配合路由组合为多个页面集,统称为模板。 -### 1.6.2 低代码搭建系统名词 +#### 1.6.2 低代码搭建系统名词 - **搭建编辑器**:使用可视化的方式实现页面搭建,支持组件 UI 编排、属性编辑、事件绑定、数据绑定,最终产出符合搭建基础协议规范的数据。 - **属性面板**:低代码编辑器内部用于组件、区块、页面的属性编辑、事件绑定、数据绑定的操作面板。 @@ -69,7 +76,7 @@ - **数据绑定**:是指为某个组件的某个属性绑定用于该属性使用的数据。 - **生命周期**: 一般指某个对象的生老病死,本文中指某个实体(组件、容器、区块等等)的创建、加载、显示、销毁等关键生命阶段的统称。 -## 1.7 背景 +### 1.7 背景 - **协议目标**: 通过约束低代码引擎的搭建协议规范,让上层低代码编辑器的产出物(低代码业务组件、区块、应用)保持一致性,可跨低代码研发平台进行流通而提效,亦不阻碍集团业务间融合的发展。  - **协议通**: @@ -83,19 +90,19 @@ - 事件描述,包含统一事件上下文、统一搭建 API; - **物料通**:指在相同领域内的不同搭建产品,可直接使用的物料。比如模版、区块、组件; -## 1.8 受众 +### 1.8 受众 本协议适用于所有使用低代码搭建平台来开发页面或组件的开发者,以及围绕此协议的相关工具或工程化方案的开发者。阅读及使用本协议,需要对低代码搭建平台的交互和实现有一定的了解,对前端开发相关技术栈的熟悉也会有帮助,协议中对通用的前端相关术语不会做进一步的解释说明。 -## 1.9 使用范围 +### 1.9 使用范围 本协议描述的是低代码搭建平台产物(应用、页面、区块、组件)的 schema 结构,以及实现其数据状态更新(内置 api)、能力扩展、国际化等方面完整,只在低代码搭建场景下可用; -## 1.10 协议目标 +### 1.10 协议目标 一套面向开发者的 schema 规范,用于规范化约束搭建编辑器的输出,以及渲染模块和出码模块的输入,将搭建编辑器、渲染模块、出码模块解耦,保障搭建编辑器、渲染模块、出码模块的独立升级。 -## 1.11 设计说明 +### 1.11 设计说明 - **语义化**:语义清晰,简明易懂,可读性强。 - **渐进性描述**:搭建的本质是通过 源码组件 进行嵌套组合,从小往大、依次组合生成 组件、区块、页面,最终通过云端构建生成 应用 的过程。因此在搭建基础协议中,我们需要知道如何去渐进性的描述组件、区块、页面、应用这 4 个实体概念。 @@ -105,7 +112,7 @@ - **支持国际化&无障碍访问标准的实现** -# 2 协议结构 +## 2 协议结构 协议最顶层结构如下: @@ -249,7 +256,7 @@ } ``` -## 2.1 协议版本号(A) +### 2.1 协议版本号(A) 定义当前协议 schema 的版本号,不同的版本号对应不同的渲染 SDK,以保障不同版本搭建协议产物的正常渲染; @@ -267,7 +274,7 @@ } ``` -## 2.2 组件映射关系(A) +### 2.2 组件映射关系(A) 协议中用于描述 componentName 到公域组件映射关系的规范。 @@ -358,7 +365,7 @@ import { Input as CustomInput } from '@ali/custom/lib/input'; ``` -## 2.3 组件树描述(A) +### 2.3 组件树描述(A) 协议中用于描述搭建出来的组件树结构的规范,整个组件树的描述由**组件结构**&**容器结构**两种结构嵌套构成。 @@ -371,13 +378,13 @@ import { Input as CustomInput } from '@ali/custom/lib/input'; - 组件结构:转换成一个 .jsx 文件内 React Class 类 render 函数返回的 **jsx** 代码。 - 容器结构:将转换成一个标准文件,如 React 的 jsx 文件, export 一个 React Class,包含生命周期定义、自定义方法、事件属性绑定、异步数据请求等。 -### 2.3.1 基础结构描述 (A) +#### 2.3.1 基础结构描述 (A) 此部分定义了组件结构、容器结构的公共基础字段。 > 阅读时可先跳到后续章节,待需要时回来参考阅读 -#### 2.3.1.1 Props 结构描述 +##### 2.3.1.1 Props 结构描述 | 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | | ----------- | ------------ | ------ | -------- | ------ | ------------------------------------- | @@ -388,7 +395,7 @@ import { Input as CustomInput } from '@ali/custom/lib/input'; | extendProps | 组件继承属性 | 变量 | ✅ | - | 仅支持变量绑定,常用于继承属性对象 | | ... | 组件私有属性 | - | - | - | | -#### 2.3.1.2 css/less/scss 样式描述 +##### 2.3.1.2 css/less/scss 样式描述 | 参数 | 说明 | 类型 | 支持变量 | 默认值 | | ------------- | -------------------------------------------------------------------------- | ------ | -------- | ------ | @@ -402,14 +409,14 @@ import { Input as CustomInput } from '@ali/custom/lib/input'; } ``` -#### 2.3.1.3 ComponentDataSource 对象描述 +##### 2.3.1.3 ComponentDataSource 对象描述 | 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | | ----------- | ---------------------- | -------------------------------------- | -------- | ------ | ----------------------------------------------------------------------------------------------------------- | | list[] | 数据源列表 | Array\<**ComponentDataSourceItem**\> | - | - | 成为为单个请求配置, 内容定义详见 [ComponentDataSourceItem 对象描述](#2314-componentdatasourceitem-对象描述) | | dataHandler | 所有请求数据的处理函数 | Function | - | - | 详见 [dataHandler Function 描述](#2317-datahandler-function 描述) | -#### 2.3.1.4 ComponentDataSourceItem 对象描述 +##### 2.3.1.4 ComponentDataSourceItem 对象描述 | 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | | -------------- | ---------------------------- | ---------------------------------------------------- | -------- | --------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------- | @@ -446,7 +453,7 @@ try { - dataHandler 会有默认值,考虑到返回结果入参都是 response 完整对象,默认值会返回 `response.data`,errorHandler 没有默认值 -#### 2.3.1.5 ComponentDataSourceItemOptions 对象描述 +##### 2.3.1.5 ComponentDataSourceItemOptions 对象描述 | 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | | ------- | ------------ | ------- | -------- | ------ | ----------------------------------------------------------------------------------------------------------- | @@ -459,7 +466,7 @@ try { -#### 2.3.1.6 ComponentLifeCycles 对象描述 +##### 2.3.1.6 ComponentLifeCycles 对象描述 生命周期对象,schema 面向多端,不同 DSL 有不同的生命周期方法: @@ -499,14 +506,14 @@ try { ``` -#### 2.3.1.7 dataHandler Function 描述 +##### 2.3.1.7 dataHandler Function 描述 - 参数:为 dataMap 对象,包含字段如下: - key: 数据 id - value: 单个请求结果 - 返回值:数据对象 data,将会在渲染引擎和 schemaToCode 中通过调用 `this.setState(...)` 将返回的数据对象生效到 state 中;支持返回一个 Promise,通过 `resolve(返回数据)`,常用于串行发送请求场景。 -#### 2.3.1.8 ComponentPropDefinition 对象描述 +##### 2.3.1.8 ComponentPropDefinition 对象描述 | 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | | ------------ | ---------- | -------------- | -------- | --------- | ----------------------------------------------------------------------------------------------------------------- | @@ -530,7 +537,7 @@ try { }, ``` -### 2.3.2 组件结构描述(A) +#### 2.3.2 组件结构描述(A) 对应生成源码开发体系中 render 函数返回的 jsx 代码,主要描述有以下属性: @@ -576,7 +583,7 @@ try { ``` -### 2.3.3 容器结构描述 (A)  +#### 2.3.3 容器结构描述 (A)  容器是一类特殊的组件,在组件能力基础上增加了对生命周期对象、自定义方法、样式文件、数据源等信息的描述。包含**低代码业务组件容器 Component**、**区块容器 Block**、**页面容器 Page** 3 种。主要描述有以下属性: @@ -731,11 +738,11 @@ try { } ``` -### 2.3.4 属性值类型描述(A) +#### 2.3.4 属性值类型描述(A) 在上述**组件结构**和**容器结构**描述中,每一个属性所对应的值,除了传统的 JS 值类型(String、Number、Object、Array、Boolean)外,还包含有**节点类型**、**事件函数类型**、**变量类型**等多种复杂类型;接下来将对于复杂类型的详细描述方式进行详细介绍。 -#### 2.3.4.1 节点类型(A) +##### 2.3.4.1 节点类型(A) 通常用于描述组件的某一个属性为 **ReactNode** 或 **Function-Return-ReactNode** 的场景。该类属性的描述均以 **JSSlot** 的方式进行描述,详细描述如下: @@ -799,7 +806,7 @@ try { ``` -#### 2.3.4.2 事件函数类型(A) +##### 2.3.4.2 事件函数类型(A) 协议内的事件描述,主要包含**容器结构**的**生命周期**和**自定义方法**,以及**组件结构**的**事件函数类属性**三类。所有事件函数的描述,均以 **JSFunction** 的方式进行描述,保留与原组件属性、生命周期(React / 小程序)一致的输入参数,并给所有事件函数 binding 统一一致的上下文(当前组件所在容器结构的 **this** 对象)。 @@ -861,7 +868,7 @@ try { } ``` -#### 2.3.4.3 变量类型(A) +##### 2.3.4.3 变量类型(A) 在上述**组件结构** 或**容器结构**中,有多个属性的值类型是支持变量类型的,通常会通过变量形式来绑定某个数据,所有的变量表达式均通过 JSExpression 表达式,上下文与事件函数描述一致,表达式内通过 **this** 对象获取上下文; @@ -952,7 +959,7 @@ try { } ``` -#### 2.3.4.4 国际化多语言类型(AA) +##### 2.3.4.4 国际化多语言类型(AA) 协议内的一些文本值内容,我们希望是和协议全局的国际化多语言语料是关联的,会按照全局国际化语言环境的不同使用对应的语料。所有国际化多语言值均以 **i18n** 结构描述。这样可以更为清晰且结构化得表达使用场景。 @@ -1020,11 +1027,11 @@ type Ti18n = { ``` -### 2.3.5 上下文 API 描述(A) +#### 2.3.5 上下文 API 描述(A) 在上述**事件类型描述**和**变量类型描述**中,在函数或 JS 表达式内,均可以通过 **this** 对象获取当前组件所在容器(React Class)的实例化对象,在搭建场景下的渲染模块和出码模块实现上,统一约定了该实例化 **this** 对象下所挂载的最小 API 集合,以保障搭建协议具备有一致的**数据流**和**事件上下文**。  -#### 2.3.5.1 容器 API: +##### 2.3.5.1 容器 API: | 参数 | 说明 | 类型 | 备注 | | ----------------------------------- | --------------------------------------- | ---------------------------- | -------------------------------------------------------------------------------------------------------------- | @@ -1083,7 +1090,7 @@ this.setState((prevState) => ({ count: prevState.count + 1 })); 备注: 如果组件没有在区块容器内,而是直接在页面内,那么 `this === this.page` -#### 2.3.5.2 循环数据 API +##### 2.3.5.2 循环数据 API 获取在循环场景下的数据对象。举例:上层组件设置了 loop 循环数据,且设置了 `loopArgs:["item", "index"]`,当前组件的属性表达式或绑定的事件函数中,可以通过 this 上下文获取所在循环的数据环境;默认值为 `['item','index']` ,如有多层循环,需要自定义不同 loopArgs,同样通过 `this[自定义循环别名]` 获取对应的循环数据和序号; @@ -1093,7 +1100,7 @@ this.setState((prevState) => ({ count: prevState.count + 1 })); | this.item | 获取当前 index 对应的循环体数据; | Any | - | | this.index | 当前物料在循环体中的 index | Number | - | -## 2.4 工具类扩展描述(AA) +### 2.4 工具类扩展描述(AA) 用于描述物料开发过程中,自定义扩展或引入的第三方工具类(例如:lodash 及 moment),增强搭建基础协议的扩展性,提供通用的工具类方法的配置方案及调用 API。 @@ -1168,7 +1175,7 @@ export const recordEvent = function(logkey, gmkey, gokey, reqMethod) { } ``` -## 2.5 国际化多语言支持(AA) +### 2.5 国际化多语言支持(AA) 协议中用于描述国际化语料和组件引用国际化语料的规范,遵循集团国际化中台关于国际化语料规范定义。 @@ -1237,34 +1244,34 @@ export const recordEvent = function(logkey, gmkey, gokey, reqMethod) { } ``` -## 2.6 应用范围内的全局常量(AA) +### 2.6 应用范围内的全局常量(AA) 用于描述在整个应用内通用的全局常量,比如请求 API 的域名、环境等。 -## 2.7 应用范围内的全局样式(AA) +### 2.7 应用范围内的全局样式(AA) 用于描述在应用范围内的全局样式,比如 reset.css 等。 -## 2.8 当前应用配置信息(AA) +### 2.8 当前应用配置信息(AA) 用于描述当前应用的配置信息,比如当前应用的路由模式、Shell/Layout、主题等。 > 注意:该字段为扩展字段,消费方式由各自场景自己决定,包括运行时和出码。 -## 2.9 当前应用元数据信息(AA) +### 2.9 当前应用元数据信息(AA) 用于描述当前应用的元数据信息,比如当前应用的名称、Git 信息、版本号等等。 > 注意:该字段为扩展字段,消费方式由各自场景自己决定,包括运行时和出码。 -## 2.10 当前应用的公共数据源(AA) +### 2.10 当前应用的公共数据源(AA) 用于描述当前应用的公共数据源,数据结构跟容器结构里的 ComponentDataSource 保持一致。 在运行时 / 出码使用时,API 和应用级数据源 API 保持一致,都是 `this.dataSourceMap['globalDSName'].load()` -# 3 应用描述 +## 3 应用描述 -## 3.1 文件目录 +### 3.1 文件目录 以下是推荐的应用目录结构,与标准源码 build-scripts 对齐,这里的目录结构是帮助理解应用级协议的设计,不做强约束 @@ -1312,17 +1319,17 @@ export const recordEvent = function(logkey, gmkey, gokey, reqMethod) { └── .stylelintrc.js ``` -## 3.2 应用级别 APIs +### 3.2 应用级别 APIs > 下文中 `xxx` 代指任意 API -### 3.2.1 路由 Router API +#### 3.2.1 路由 Router API - this.location.`xxx` - this.history.`xxx` - this.match.`xxx` -### 3.2.2 应用级别的公共函数或第三方扩展 +#### 3.2.2 应用级别的公共函数或第三方扩展 - this.utils.`xxx` -### 3.2.3 国际化相关 API +#### 3.2.3 国际化相关 API | API | 函数签名 | 说明 | | -------------- | ---------------------------------------------------------------------- | ------------------------------------------------------------------ | | this.i18n | (i18nKey: string, params?: { [paramName: string]: string; }) => string | i18nKey 是语料的标识符,params 可选,是用来做模版字符串替换的。返回语料字符串 | diff --git a/specs/material-spec.md b/docs/docs/specs/material-spec.md similarity index 97% rename from specs/material-spec.md rename to docs/docs/specs/material-spec.md index 1d2375a112..f7687114b6 100644 --- a/specs/material-spec.md +++ b/docs/docs/specs/material-spec.md @@ -1,8 +1,12 @@ +--- +title: 《低代码引擎物料协议规范》 +sidebar_position: 1 +--- # 《低代码引擎物料协议规范》 -# 1 介绍 +## 1 介绍 -## 1.1 本协议规范涉及的问题域 +### 1.1 本协议规范涉及的问题域 - 定义本协议版本号规范 - 定义本协议中每个子规范需要被支持的 Level @@ -14,16 +18,16 @@ - 定义中后台物料无障碍访问规范(AAA) -## 1.2 协议草案起草人 +### 1.2 协议草案起草人 - 撰写:九神、大果、元彦、戊子、林熠、屹凡、金禅 - 审阅:潕量、月飞、康为、力皓、荣彬、暁仙、度城、金禅、戊子、林熠、絮黎 -## 1.3 版本号 +### 1.3 版本号 1.0.0 -## 1.4 协议版本号规范(A) +### 1.4 协议版本号规范(A) 本协议采用语义版本号,版本号格式为 `major.minor.patch` 的形式。 @@ -32,7 +36,7 @@ - patch 是补丁号:用于发布向下兼容的协议问题修正 -## 1.5 协议中子规范 Level 定义 +### 1.5 协议中子规范 Level 定义 | 规范等级 | 实现要求 | | -------- | ---------------------------------------------------------------------------------- | @@ -41,26 +45,26 @@ | AAA | 参考规范,根据业务场景实际诉求实现;是集团层面鼓励的技术实现引导。 | -## 1.6 名词术语 +### 1.6 名词术语 - **物料**:能够被沉淀下来直接使用的前端能力,一般表现为业务组件、区块、模板。 - **业务组件(Business Component)**:业务领域内基于基础组件之上定义的组件,可能会包含特定业务域的交互或者是业务数据,对外仅暴露可配置的属性,且必须发布到公域(如阿里 NPM);在同一个业务域内可以流通,但不需要确保可以跨业务域复用。 - **低代码业务组件(Low-Code Business Component)**:通过低代码编辑器搭建而来,有别于源码开发的业务组件,属于业务组件中的一种类型,遵循业务组件的定义;同时低代码业务组件还可以通过低代码编辑器继续多次编辑。 - **区块(Block)**:通过低代码搭建的方式,将一系列业务组件、布局组件进行嵌套组合而成,不对外提供可配置的属性。可通过区块容器组件的包裹,实现区块内部具备有完整的样式、事件、生命周期管理、状态管理、数据流转机制。能独立存在和运行,可通过复制 schema 实现跨页面、跨应用的快速复用,保障功能和数据的正常。 - **模板(Template)**:特定垂直业务领域内的业务组件、区块可组合为单个页面,或者是再配合路由组合为多个页面集,统称为模板。 -## 1.7 物料规范背景 +### 1.7 物料规范背景 目前集团业务融合频繁,而物料规范的不统一给业务融合带来额外的高成本,另一方面集团各个 BU 的前端物料也存在不同程度的重复建设。我们期望通过集团层面的物料通不阻碍业务融合的发展,同时通过集团层面的物料流通来提升物料丰富度,通过丰富物料的复用来提效中后台系统研发,同时也能给新业务场景提供高质量的启动物料。 -## 1.8 物料规范定义 +### 1.8 物料规范定义 - **源码物料规范**:一套面向开发者的目录规范,用于规范化约束开发过程中的代码、文档、接口规范,以方便物料在集团内的流通。 - **搭建物料规范**:一套面向开发者的 Schema 规范,用于规范化约束开发过程中的代码、文档、接口规范,以方便物料在集团内的流通。 -# 2. 物料规范 - 业务组件规范 +## 2. 物料规范 - 业务组件规范 -## 2.1 源码规范 +### 2.1 源码规范 -### 2.1.1 目录规范(A) +#### 2.1.1 目录规范(A) ``` @@ -229,7 +233,7 @@ ReactDOM.render(
``` ~~~ -### 2.1.2 API 规范(A) +#### 2.1.2 API 规范(A) API 是组件的属性解释,给开发者作为组件属性配置的参考。为了保持 API 的一致性,我们制定这个 API 命名规范。对于业界通用的,约定俗成的命名,我们遵循社区的约定。对于业界有多种规则难以确定的,我们确定其中一种,大家共同遵守。 @@ -327,7 +331,7 @@ true 表示触发规则都会关闭,false 表示触发规则不会关闭。 **xxxProps 例子**: 比如 `Search` 组件由 `Input` 和 `Button` 构成,`Button` 的属性通过 `buttonProps` 传递给内部的 `Button`。`` -### 2.1.3 入库方式 (A) +#### 2.1.3 入库方式 (A) 入库是指:发布组件,并且存储到集团物料中心,方便统一管理和流通。 @@ -347,7 +351,7 @@ $ iceworks sync ``` -### 2.1.4 国际化多语言支持规范(AA) +#### 2.1.4 国际化多语言支持规范(AA) 文件命名采取 [bcp47](https://tools.ietf.org/html/bcp47) 规范 @@ -444,7 +448,7 @@ export default ConfigProvider.config(BizHello, { }); ``` -### 2.1.5 主题切换规范(AA) +#### 2.1.5 主题切换规范(AA) 业务组件中如果有自定义的需要跟随主题色的 UI,一定要引入变量的形式,增加组件的流通性。 @@ -461,7 +465,7 @@ export default ConfigProvider.config(BizHello, { ``` -### 2.1.6 [Deprecated]支持转设计稿(AAA) +#### 2.1.6 [Deprecated]支持转设计稿(AAA) 对接 sketch 插件(FusionCool)的目的是为了让开发产出的业务组件能够直接给设计师使用,用法类似现在 Fusion Next 基础组件。 @@ -495,7 +499,7 @@ export default { api 属性标准参考 [https://fusion.design/help.html#/dev-biz](https://fusion.design/help.html#/dev-biz) -### 2.1.7 无障碍访问规范(AAA) +#### 2.1.7 无障碍访问规范(AAA) 无障碍需要符合 [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) 章节等。 @@ -537,9 +541,9 @@ component - 传参数 - 有些组件需要根据具体的业务,实现不同的可访问性,这里为开发者内置一些参数,想使用无障碍的时候,用户只需要根据现有的需求,选择对应的内置参数,例如设置 aria-label,以下组件需要用户传参数才支持无障碍组件如下:`NumberPicker`、`Transfer` -## 2.2 低代码规范 +### 2.2 低代码规范 -### 2.2.1 组件规范 +#### 2.2.1 组件规范 通过低代码编辑器搭建而来,有别于源码开发的业务组件,属于业务组件中的一种类型,遵循业务组件的定义;同时低代码业务组件还可以通过低代码编辑器继续多次编辑。 @@ -594,10 +598,10 @@ component } ``` -### 2.2.2 组件描述协议 +#### 2.2.2 组件描述协议 对源码组件在低代码搭建平台中使用时所具备的配置能力和交互行为进行规范化描述,让不同平台对组件接入的实现保持一致,让组件针对不同的搭建平台接入时可以使用一份统一的描述内容,让组件在不同的业务中流通成为可能。 -#### 2.2.2.1 协议结构 +##### 2.2.2.1 协议结构 单个组件描述内容为 json 结构,主要包含以下三部分内容,分别为: @@ -607,7 +611,7 @@ component 整体结构概览: [http://lowcode-engine.cn/doc?url=sde3wf](http://lowcode-engine.cn/doc?url=sde3wf) -#### 2.2.2.2 基础信息(A) +##### 2.2.2.2 基础信息(A) | 字段 | 字段描述 | 字段类型 | 允许空 | | ----------------- | --------------------- | ------------------------- | ------ | @@ -633,7 +637,7 @@ component | priority | 用于描述组件在同一 category 中的排序 | String | 否 | -#### 2.2.2.3 组件属性信息 props (A) +##### 2.2.2.3 组件属性信息 props (A) 描述组件属性信息,通常包含名称、类型、描述、默认值 4 项内容。 @@ -804,7 +808,7 @@ export default class FusionForm extends PureComponent { ``` -#### 2.2.2.4 编辑体验增强 configure +##### 2.2.2.4 编辑体验增强 configure 推荐用于优化搭建产品的编辑体验,定制编辑能力的配置信息,通过能力抽象分类,主要包含如下几个维度的配置项: @@ -818,7 +822,7 @@ export default class FusionForm extends PureComponent { | 【已废弃】experimental (AAA) | 将引擎的一些实验性特性放在这个配置里 | Object | 用户可以提前体验这些特性 | -##### 2.2.2.4.1 属性面板配置 props (A) +###### 2.2.2.4.1 属性面板配置 props (A) props 数组下对象字段描述: @@ -842,7 +846,7 @@ props 数组下对象字段描述: 根据属性值类型 propType,确定对应控件类型 (setter) ,详见 [https://lowcode-engine.cn/docV2/grfylu](https://lowcode-engine.cn/docV2/grfylu) -##### 2.2.2.4.2 通用扩展面板支持性配置 supports (AA) +###### 2.2.2.4.2 通用扩展面板支持性配置 supports (AA) 样式配置面板能力描述,描述是否支持行业样式编辑、是否支持类名设置等。 @@ -865,7 +869,7 @@ props 数组下对象字段描述: ``` -##### 2.2.2.4.3 组件能力配置 component +###### 2.2.2.4.3 组件能力配置 component 与组件相关的能力、约束、行为等描述,有些信息可从组件视图实例上直接获取,包含如下字段: @@ -914,7 +918,7 @@ props 数组下对象字段描述: } ``` -##### 2.2.2.4.4 高级功能配置 advanced (AAA) +###### 2.2.2.4.4 高级功能配置 advanced (AAA) 组件在低代码引擎设计器中的事件回调和 hooks 等高级功能配置,包含如下字段: @@ -963,7 +967,7 @@ props 数组下对象字段描述: } ``` -#### 2.2.2.5 TypeScript 定义 +##### 2.2.2.5 TypeScript 定义 ```TypeScript @@ -1196,9 +1200,9 @@ export interface ComponentDescription { // 组件描述协议,通过 npm 中 } ``` -### 2.2.3 资产包协议 +#### 2.2.3 资产包协议 -#### 2.2.3.1 协议结构 +##### 2.2.3.1 协议结构 协议最顶层结构如下,包含 5 方面的描述内容: @@ -1207,7 +1211,7 @@ export interface ComponentDescription { // 组件描述协议,通过 npm 中 - components { Array } 所有组件的描述协议列表 - sort { Object } 用于描述组件面板中的 tab 和 category -#### 2.2.3.2 version(A) +##### 2.2.3.2 version(A) 定义当前协议 schema 的版本号; @@ -1215,7 +1219,7 @@ export interface ComponentDescription { // 组件描述协议,通过 npm 中 | ---------- | ------ | ---------- | -------- | ------ | | version | String | 协议版本号 | - | 1.0.0 | -#### 2.2.3.3 packages(A) +##### 2.2.3.3 packages(A) 定义低代码编辑器中加载的资源列表,包含公共库和组件(库) cdn 资源等; @@ -1288,11 +1292,11 @@ export interface ComponentDescription { // 组件描述协议,通过 npm 中 } ``` -#### 2.2.3.4 components (A) +##### 2.2.3.4 components (A) 定义所有组件的描述协议列表,组件描述协议遵循本规范章节 2.2.2 的定义; -#### 2.2.3.5 sort (A) +##### 2.2.3.5 sort (A) 定义组件列表分组 @@ -1301,7 +1305,7 @@ export interface ComponentDescription { // 组件描述协议,通过 npm 中 | sort.groupList | String[] | 组件分组,用于组件面板 tab 展示 | - | ['精选组件', '原子组件'] | | sort.categoryList | String[] | 组件面板中同一个 tab 下的不同区间用 category 区分,category 的排序依照 categoryList 顺序排列 | - | ['通用', '数据展示', '表格类', '表单类'] | -#### 2.2.3.6 TypeScript 定义 +##### 2.2.3.6 TypeScript 定义 ```TypeScript export interface ComponentSort { @@ -1326,13 +1330,13 @@ export interface RemoteComponentDescription { } ``` -# 3 物料规范-区块规范 +## 3 物料规范-区块规范 -## 3.1 源码规范 +### 3.1 源码规范 英文 block, 可复用的代码片段,每个区块对应一个 npm。 -### 3.1.1 目录 (A) +#### 3.1.1 目录 (A) ```html @@ -1352,7 +1356,7 @@ block/ ``` -### 3.1.2 package.json (A) +#### 3.1.2 package.json (A) ```json @@ -1370,9 +1374,9 @@ block/ } ``` -### 3.1.3 html2sketch (3A) +#### 3.1.3 html2sketch (3A) -#### 3.1.3.1 package.json 内 blockConfig 结构 +##### 3.1.3.1 package.json 内 blockConfig 结构 ```json { @@ -1400,7 +1404,7 @@ block/ } ``` -## 3.2 低代码规范 +### 3.2 低代码规范 由业务组件、布局组件进行嵌套组合而成。不对外提供可配置的属性。可通过**区块容器组件**的包裹,实现容器内部具备有完整的样式、事件、生命周期管理、状态管理、数据流转机制。能独立存在和运行,可实现跨页面、跨应用的快速复用,保障功能和数据的正常。 @@ -1479,11 +1483,11 @@ block/ } ``` -# 4 物料规范 - 模板规范 +## 4 物料规范 - 模板规范 -## 4.1 源码规范 +### 4.1 源码规范 -### 4.1.1 目录规范(A) +#### 4.1.1 目录规范(A) 与标准源码 build-scripts 对齐 @@ -1642,9 +1646,9 @@ a { } ``` -### 4.1.2 html2sketch (AAA) +#### 4.1.2 html2sketch (AAA) -#### 4.1.2.1 package.json 内 scaffoldConfig 结构 +##### 4.1.2.1 package.json 内 scaffoldConfig 结构 ```json { diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 68728ca21e..04c99067ee 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -65,45 +65,6 @@ const config = { navbar, footer: { // style: 'dark', - links: [ - {}, - { - title: '低代码引擎协议栈', - items: [ - { - label: '《低代码引擎搭建协议规范》', - href: 'https://lowcode-engine.cn/lowcode', - }, - { - label: '《低代码引擎物料协议规范》', - href: 'https://lowcode-engine.cn/material', - }, - { - label: '《低代码引擎资产包协议规范》', - href: 'https://lowcode-engine.cn/assets', - }, - ], - }, - {}, - { - title: '案例产品', - items: [ - { - label: '钉钉宜搭', - href: 'https://www.aliwork.com/', - }, - { - label: 'Parts 造物', - href: 'https://parts.lowcode-engine.cn/', - }, - { - label: 'UIPaaS 低代码平台孵化器', - href: 'https://uipaas.net', - }, - ], - }, - {}, - ], copyright: `Copyright © ${new Date().getFullYear()} 阿里巴巴集团, Inc. Built with Docusaurus.`, }, // 主题切换 diff --git a/docs/package.json b/docs/package.json index 8bbab34d89..81b032d177 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "0.0.1-beta.4", + "version": "1.0.0", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From f49c6299d8e26975b5ccd1c4e57635487e38a761 Mon Sep 17 00:00:00 2001 From: JackLian Date: Tue, 29 Nov 2022 17:30:29 +0800 Subject: [PATCH 211/823] feat: add doc for how-to-edit-doc, and some minor doc fix --- docs/docs/participate/config.md | 2 +- docs/docs/participate/doc.md | 17 ++++ docs/docs/participate/flow.md | 157 +++++++++++++++++++++---------- docs/docs/participate/index.md | 10 +- docs/docs/participate/prepare.md | 9 +- docs/package.json | 2 +- 6 files changed, 139 insertions(+), 58 deletions(-) create mode 100644 docs/docs/participate/doc.md diff --git a/docs/docs/participate/config.md b/docs/docs/participate/config.md index 4e032ad1be..e300400100 100644 --- a/docs/docs/participate/config.md +++ b/docs/docs/participate/config.md @@ -1,5 +1,5 @@ --- -title: 引擎的工程化配置 +title: 工程化配置 sidebar_position: 3 --- 目前引擎体系共包含 3 个 js 文件,即: diff --git a/docs/docs/participate/doc.md b/docs/docs/participate/doc.md new file mode 100644 index 0000000000..c1ef26f8d4 --- /dev/null +++ b/docs/docs/participate/doc.md @@ -0,0 +1,17 @@ +--- +title: 官网文档协作流程 +sidebar_position: 3 +--- + +## 基本原则 + +### 维护方式 + +- 官方文档通过 github 管理文档源, 官网文档与[主仓库 develop 分支](https://github.com/alibaba/lowcode-engine/tree/develop/docs)保持同步。 +- 点击每篇文档下发的 `编辑此页` 可直接定位到 github 中位置。 +- 欢迎 PR, 文档 PR 也会作为贡献者贡献,会用于贡献度统计。 +- 文档同步到官方网站由官方人员进行操作,如有需要可以通过 issue 或 贡献者群与相关人员沟通。 + +### PR 方式 + +- 操作与代码贡献一致,指向 develop 分支。 \ No newline at end of file diff --git a/docs/docs/participate/flow.md b/docs/docs/participate/flow.md index d80e779ee6..24ebd3629d 100644 --- a/docs/docs/participate/flow.md +++ b/docs/docs/participate/flow.md @@ -1,5 +1,5 @@ --- -title: 关于引擎的研发协作流程 +title: 研发协作流程 sidebar_position: 2 --- ## 代码风格 @@ -7,7 +7,8 @@ sidebar_position: 2 ## 测试机制 每次提交代码前,务必本地跑一次单元测试,通过后再提交 MR。 -假如涉及新的功能,需要**补充相应的单元测试,**目前引擎核心模块的单测覆盖率都在 80%+,假如降低了覆盖率,将会不予以通过。 + +假如涉及新的功能,需要**补充相应的单元测试**,目前引擎核心模块的单测覆盖率都在 80%+,假如降低了覆盖率,将会不予以通过。 跑单测流程: @@ -19,78 +20,134 @@ sidebar_position: 2 1. commit message 格式遵循 [ConvensionalCommits](https://www.conventionalcommits.org/en/v1.0.0/#summary) ![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645066644352-4de1c64c-bff6-4482-90d1-1fb610aa91f2.png#averageHue=%23eceef0&clientId=u6dcee4f0-35df-4&crop=0&crop=0&crop=1&crop=1&height=297&id=CfpQy&margin=%5Bobject%20Object%5D&name=image.png&originHeight=594&originWidth=2070&originalType=binary&ratio=1&rotation=0&showTitle=false&size=341605&status=done&style=none&taskId=u4499b752-5e24-42f6-9186-280fd5a51aa&title=&width=1035) -2. 请按照一个 bugfix / feature 对应一个 commit,假如不是,请 rebase 后再提交 MR,不要一堆无用的、试验性的 commit +2. 请按照一个 bugfix / feature 对应一个 commit,假如不是,请 rebase 后再提交 MR,不要一堆无用的、试验性的 commit。 -好处:从引擎的整体 commit 历史来看,会很清晰,**每个 commit 完成一件确定的事,changelog 也能自动生成。**另外,假如因为某个 commit 导致了 bug,也很容易通过 rebase drop 等方式快速修复。 -## 引擎发布机制 -日常迭代先从 develop 拉分支,然后自测、单测通过后,提交 MR 到 develop 分支,由发布负责人基于 develop 拉 release/1.0.z 分支~ +好处:从引擎的整体 commit 历史来看,会很清晰,**每个 commit 完成一件确定的事,changelog 也能自动生成**。另外,假如因为某个 commit 导致了 bug,也很容易通过 rebase drop 等方式快速修复。 -### 分支用途 +## 分支用途 - main 分支,最稳定的分支,跟 npm latest 包的内容保持一致 - develop 分支,开发分支,拥有最新的、已经验证过的 feature / bugfix,Pull Request 的**目标合入分支** - release 分支 - 正式发布分支,命名规则为 release/x.y.z,一般从 develop 拉出来进行发布,x.y.z 为待发布的版本号 - beta 发布分支,命名规则为 release/x.y.z-beta(\.\d+)?,可以快速验证修改,发布 npm beta 版本。 + 验证通过后,因为 beta 发布分支上会存在无用的 commit(比如 lerna 修改 package.json 这种),所以不直接 PR 到 develop,而是从 develop 拉分支,从 beta 发布分支 cherry pick 有用的 commit 到新分支,然后 PR 到 develop。 +## 引擎发布机制 + +日常迭代先从 develop 拉分支,然后自测、单测通过后,提交 PR 到 develop 分支,由发布负责人基于 develop 拉 release/1.0.z 分支~ + +### 版本规划 + +> 此处是理想节奏,实际情况可能会有调整 + +- 日常迭代 2 周,一般月中或月底 +- 特殊情况紧急迭代随时发 +- 大Feature迭代,每年 2 - 4 次 + + ### 发布步骤 -> **发布需要权限,如果提 PR 之后着急发布可以**[**加入贡献者交流群**](https://www.yuque.com/lce/doc/pctr1f#d5WKy)**。** +> **发布需要权限,如果提 PR 之后着急发布可以**[**加入贡献者交流群**](../participate/#核心贡献者交流)**。** -如果是发布正式版本,步骤如下(以发布 1.0.0 版本为例): +#### 发正式版 +步骤如下(以发布 1.0.0 版本为例): 1. git checkout develop -2. git checkout -b release/1.0.0 -3. npm run build -4. npm run pub -5. tnpm run sync(此步骤将发布在 npm 源的包同步到阿里内网源,因为 alifd cdn 将依赖内网 npm 源) + ```bash + git checkout develop + ``` +2. 创建release分支 + ```bash + git checkout -b release/1.0.0 + ``` +3. build + ```bash + npm run build + ``` +4. 发布到npm + ```bash + npm run pub + ``` +5. 同步到 tnpm 源 & alifd CDN(此步骤将发布在 npm 源的包同步到阿里内网源,因为 alifd cdn 将依赖内网 npm 源) + ```bash + tnpm run sync + ``` 6. 更新[发布日志](https://github.com/alibaba/lowcode-engine/releases) 7. 合并 release/x.x.x 到 main 分支 8. 合并 main 分支到 develop 分支 如果是发布beta 版本,步骤如下(以发布 1.0.1 版本为例): -1. git checkout develop -2. git checkout -b release/1.0.1-beta -3. npm run build -4. npm run pub:prepatch(将 lerna 版本号从 1.0.0 改到 1.0.1-beta.0,若是从 1.0.1-beta.0 改到 1.0.1-beta.1,则用 npm run pub:prerelease) -5. tnpm run sync - -注:在 release/1.0.1-beta 上可以直接提交,以便快速测试和验证,不过如何合入 develop,参考 [分支用途](#uem7W) 一节说明。 - -### 发布周期 -**发布周期暂时不固定,按需发布~** +#### 发某版本首个 beta ,如 1.0.1-beta.0 +1. 拉 develop 分支 + ```bash + git checkout develop + ``` + 更新到最新(如需) + ```bash + git pull + ``` +2. 拉 release 分支,此处以 1.0.1 版本做示例 + ```bash + git checkout -b release/1.0.1-beta + ``` +3. build + ```bash + npm run build + ``` +4. 发布,此处需有 @alilc scope 发包权限 + ```bash + npm run pub:prepatch + ``` +5. 同步到 tnpm 源 & alifd CDN + ```bash + tnpm run sync + ``` + +#### 发某版本非首个 beta ,如 1.0.1-beta.0 -> 1.0.1-beta.1 +1. 切换到 release 分支 + ```bash + git checkout release/1.0.1-beta + ``` +2. 更新到 develop 分支最新代码 + ```bash + git rebase origin/develop + ``` +3. build + ```bash + npm run build + ``` +4. 发布,此处需有 @alilc scope 发包权限 ***此处命令与发首个 beta 时有变化*** + ```bash + npm run pub:prerelease + ``` +5. 同步到 tnpm 源 & alifd CDN + ```bash + tnpm run sync + ``` -## 物料发布机制 ## DEMO 发布机制 -**修改版本号** -手动修改 package.json 的版本号 - -**build** -```typescript -npm run build -``` - -**publish** -```typescript -npm run pub -``` -需要权限 - -*发布 beta 版本 -```typescript -npm publish --tag beta -``` - -**同步** -```typescript -tnpm run sync -``` -缺少这一步相关的 cdn 地址可能 404 - - +1. **修改版本号** + 手动修改 package.json 的版本号 +2. **build** + ```bash + npm run build + ``` +3. publish (此步骤需要 npm 发包权限) + ```bash + npm run pub + ``` + 如发 beta 版 + ```bash + npm publish --tag beta + ``` +4. 同步到 tnpm 源 & alifd CDN + ```bash + tnpm run sync + ``` **官网生效** 需要在通过阿里内部系统更新 demo 版本 diff --git a/docs/docs/participate/index.md b/docs/docs/participate/index.md index 7a652e59a4..854da7e183 100644 --- a/docs/docs/participate/index.md +++ b/docs/docs/participate/index.md @@ -1,12 +1,15 @@ --- -title: 低代码引擎贡献者指南 +title: 贡献者指南 sidebar_position: 0 --- ### 首个 Pull Request 在写第一个 Pull Request?你可以从这一系列视频中学习怎么做: [How to Contribute to an Open Source Project on GitHub](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github) + 为了使你能够快速上手和熟悉贡献流程,我们这里有个列表 [good first issues](https://github.com/alibaba/lowcode-engine/issues?q=is:open+is:issue+label:%22good+first+issue%22),里面有相对没那么笼统的漏洞,从这开始是个不错的选择。 + 如果你想解决一个 issue,请确定检查了该 issue 下的评论以防有人正在处理它。如果目前没人在处理该 issue,那么请留下评论去表明你想处理该 issue 以便其他人不会意外重复你的工作。 + 如果有人留言表明要处理该 issue 但是超过两周没有跟进,你可以接手工作,不过也应该留言说明。 ### 提交 Pull Request @@ -22,5 +25,6 @@ sidebar_position: 0 ### 核心贡献者交流 如果你想长期参与到项目维护中,我们提供了一个核心贡献者交流群。 -1.可以通过[填写问卷](https://survey.taobao.com/apps/zhiliao/4YEtu9gHF)的方式,参与到其中。 -2.填写问卷后加微信号 wxidvlalalalal,说明一下 + +1. 可以通过[填写问卷](https://survey.taobao.com/apps/zhiliao/4YEtu9gHF)的方式,参与到其中。 +2. 填写问卷后加微信号 `wxidvlalalalal` 说明一下 diff --git a/docs/docs/participate/prepare.md b/docs/docs/participate/prepare.md index f0fbeb3948..dd962cd647 100644 --- a/docs/docs/participate/prepare.md +++ b/docs/docs/participate/prepare.md @@ -1,10 +1,12 @@ --- -title: 如何配置引擎调试环境 +title: 调试环境配置 sidebar_position: 1 --- 低代码引擎的核心仓库是不包含任何物料、插件、setter 的,它本身用于生成低代码引擎的主包。 + 如果您需要对低代码的主包进行开发和调试,需要用到本文里介绍的知识。 -如果您需要对低代码编辑器进行定制,您可能只需要 clone [lowcode-demo 项目](https://github.com/alibaba/lowcode-demo)并进行修改,参考“[配置低代码扩展点](https://www.yuque.com/lce/doc/srdo3s#oPhoE)”章节。 + +如果您需要对低代码编辑器进行定制,您可能只需要 clone [lowcode-demo 项目](https://github.com/alibaba/lowcode-demo)并进行修改,参考“[配置低代码扩展点](/site/docs/guide/expand/editor/summary)”章节。 > 前置条件: > node >= 14 @@ -58,4 +60,5 @@ npm install && npm start ``` ### 3. 本地调试物料/插件/设置器 -[详见](https://www.yuque.com/lce/doc/ulvlkz#Ioc87) + +详见[低代码生态脚手架 & 调试机制](/site/docs/guide/expand/editor/cli) diff --git a/docs/package.json b/docs/package.json index 81b032d177..93b2c43193 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.0.0", + "version": "1.0.1", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From b664663890fd9fa5e41ac4998e38e85a4a3f2a03 Mon Sep 17 00:00:00 2001 From: JackLian Date: Mon, 28 Nov 2022 15:57:48 +0800 Subject: [PATCH 212/823] refactor: move common to shell --- packages/engine/src/engine-core.ts | 34 ++-- packages/engine/src/modules/designer-cabin.ts | 50 ----- packages/engine/src/modules/editor-cabin.ts | 15 -- .../engine/src/modules/skeleton-cabin.tsx | 16 -- packages/engine/src/modules/utils.ts | 17 -- packages/shell/src/common.tsx | 183 ++++++++++++++++++ packages/shell/src/index.ts | 5 +- 7 files changed, 201 insertions(+), 119 deletions(-) delete mode 100644 packages/engine/src/modules/designer-cabin.ts delete mode 100644 packages/engine/src/modules/editor-cabin.ts delete mode 100644 packages/engine/src/modules/skeleton-cabin.tsx delete mode 100644 packages/engine/src/modules/utils.ts create mode 100644 packages/shell/src/common.tsx diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index aad924324b..7045816e50 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -6,7 +6,6 @@ import { LowCodePluginManager, ILowCodePluginContext, PluginPreference, - TransformStage, } from '@alilc/lowcode-designer'; import { Skeleton as InnerSkeleton, @@ -16,15 +15,21 @@ import { import Outline, { OutlineBackupPane, getTreeMaster } from '@alilc/lowcode-plugin-outline-pane'; import DesignerPlugin from '@alilc/lowcode-plugin-designer'; -import { Hotkey, Project, Skeleton, Setters, Material, Event, DocumentModel } from '@alilc/lowcode-shell'; +import { + Hotkey, + Project, + Skeleton, + Setters, + Material, + Event, + DocumentModel, + Common, +} from '@alilc/lowcode-shell'; import { getLogger, isPlainObject } from '@alilc/lowcode-utils'; import './modules/live-editing'; -import utils from './modules/utils'; -import * as editorCabin from './modules/editor-cabin'; -import getSkeletonCabin from './modules/skeleton-cabin'; -import getDesignerCabin from './modules/designer-cabin'; import classes from './modules/classes'; import symbols from './modules/symbols'; + export * from './modules/editor-types'; export * from './modules/skeleton-types'; export * from './modules/designer-types'; @@ -46,8 +51,6 @@ const plugins = new LowCodePluginManager(editor).toProxy(); editor.set('plugins' as any, plugins); const { project: innerProject } = designer; -const skeletonCabin = getSkeletonCabin(innerSkeleton); -const { Workbench } = skeletonCabin; const hotkey = new Hotkey(); const project = new Project(innerProject); @@ -57,17 +60,7 @@ const material = new Material(editor); const config = engineConfig; const event = new Event(editor, { prefix: 'common' }); const logger = getLogger({ level: 'warn', bizName: 'common' }); -const designerCabin = getDesignerCabin(editor); -const objects = { - TransformStage, -}; -const common = { - utils, - objects, - editorCabin, - designerCabin, - skeletonCabin, -}; +const common = new Common(editor, innerSkeleton); export { skeleton, @@ -189,6 +182,7 @@ let engineContainer: HTMLElement; // @ts-ignore webpack Define variable export const version = VERSION_PLACEHOLDER; engineConfig.set('ENGINE_VERSION', version); + export async function init( container?: HTMLElement, options?: EngineOptions, @@ -213,6 +207,8 @@ export async function init( engineConfig.setEngineOptions(engineOptions as any); await plugins.init(pluginPreference as any); + + const { Workbench } = common.skeletonCabin; render( createElement(Workbench, { skeleton: innerSkeleton, diff --git a/packages/engine/src/modules/designer-cabin.ts b/packages/engine/src/modules/designer-cabin.ts deleted file mode 100644 index 0ba28c701c..0000000000 --- a/packages/engine/src/modules/designer-cabin.ts +++ /dev/null @@ -1,50 +0,0 @@ -import { - SettingField, - isSettingField, - Designer, - TransformStage, - LiveEditing, - isDragNodeDataObject, - isDragNodeObject, - isDragAnyObject, - DragObjectType, - isNode, - isShaken, - contains, - LocationDetailType, - isLocationChildrenDetail, - ScrollTarget, -} from '@alilc/lowcode-designer'; -import { Editor } from '@alilc/lowcode-editor-core'; -import { designerCabinSymbol, Dragon } from '@alilc/lowcode-shell'; - -export default function getDesignerCabin(editor: Editor) { - const designer = editor.get('designer') as Designer; - - return { - SettingField, - isSettingField, - dragon: Dragon.create(designer.dragon), - TransformStage, - LiveEditing, - DragObjectType, - isDragNodeDataObject, - isNode, - [designerCabinSymbol]: { - isDragNodeObject, - isDragAnyObject, - isShaken, - contains, - LocationDetailType, - isLocationChildrenDetail, - ScrollTarget, - isSettingField, - TransformStage, - SettingField, - LiveEditing, - DragObjectType, - isDragNodeDataObject, - isNode, - }, - }; -} \ No newline at end of file diff --git a/packages/engine/src/modules/editor-cabin.ts b/packages/engine/src/modules/editor-cabin.ts deleted file mode 100644 index 3f2874a10a..0000000000 --- a/packages/engine/src/modules/editor-cabin.ts +++ /dev/null @@ -1,15 +0,0 @@ -export { - Title, - Tip, - shallowIntl, - createIntl, - intl, - createSetterContent, - obx, - observable, - makeObservable, - untracked, - computed, - observer, - globalLocale, -} from '@alilc/lowcode-editor-core'; \ No newline at end of file diff --git a/packages/engine/src/modules/skeleton-cabin.tsx b/packages/engine/src/modules/skeleton-cabin.tsx deleted file mode 100644 index 1d8363ab1b..0000000000 --- a/packages/engine/src/modules/skeleton-cabin.tsx +++ /dev/null @@ -1,16 +0,0 @@ -import { - Skeleton as InnerSkeleton, - createSettingFieldView, - PopupContext, - PopupPipe, - Workbench as InnerWorkbench, -} from '@alilc/lowcode-editor-skeleton'; - -export default function getSkeletonCabin(skeleton: InnerSkeleton) { - return { - createSettingFieldView, - PopupContext, - PopupPipe, - Workbench: (props: any) => , // hijack skeleton - }; -} \ No newline at end of file diff --git a/packages/engine/src/modules/utils.ts b/packages/engine/src/modules/utils.ts deleted file mode 100644 index 5283eb4f5f..0000000000 --- a/packages/engine/src/modules/utils.ts +++ /dev/null @@ -1,17 +0,0 @@ -import { isFormEvent, compatibleLegaoSchema, getNodeSchemaById, transactionManager } from '@alilc/lowcode-utils'; -import { isNodeSchema } from '@alilc/lowcode-types'; -import { getConvertedExtraKey, getOriginalExtraKey } from '@alilc/lowcode-designer'; -import { createIntl } from '@alilc/lowcode-editor-core'; - -const utils = { - isNodeSchema, - isFormEvent, - compatibleLegaoSchema, - getNodeSchemaById, - getConvertedExtraKey, - getOriginalExtraKey, - executeTransaction: transactionManager.executeTransaction.bind(transactionManager), - createIntl, -}; - -export default utils; \ No newline at end of file diff --git a/packages/shell/src/common.tsx b/packages/shell/src/common.tsx new file mode 100644 index 0000000000..d6511edef4 --- /dev/null +++ b/packages/shell/src/common.tsx @@ -0,0 +1,183 @@ +import { editorSymbol, skeletonSymbol, designerCabinSymbol } from './symbols'; +import { + isFormEvent as innerIsFormEvent, + compatibleLegaoSchema as innerCompatibleLegaoSchema, + getNodeSchemaById as innerGetNodeSchemaById, + transactionManager, +} from '@alilc/lowcode-utils'; +import { + isNodeSchema as innerIsNodeSchema, + NodeSchema, + TransitionType, +} from '@alilc/lowcode-types'; +import { + SettingField, + isSettingField, + Designer, + TransformStage, + LiveEditing, + isDragNodeDataObject, + isDragNodeObject, + isDragAnyObject, + DragObjectType, + isNode, + isShaken, + contains, + LocationDetailType, + isLocationChildrenDetail, + ScrollTarget, + getConvertedExtraKey as innerGetConvertedExtraKey, + getOriginalExtraKey as innerGetOriginalExtraKey, +} from '@alilc/lowcode-designer'; +import { + Skeleton as InnerSkeleton, + createSettingFieldView, + PopupContext, + PopupPipe, + Workbench as InnerWorkbench, +} from '@alilc/lowcode-editor-skeleton'; +import Dragon from './dragon'; +import { + Editor, + Title as InnerTitle, + Tip as InnerTip, + shallowIntl, + createIntl as innerCreateIntl, + intl, + createSetterContent, + obx, + observable, + makeObservable, + untracked, + computed, + observer, + globalLocale, +} from '@alilc/lowcode-editor-core'; +import { ReactNode } from 'react'; + + +const getDesignerCabin = (editor: Editor) => { + const designer = editor.get('designer') as Designer; + + return { + SettingField, + isSettingField, + dragon: Dragon.create(designer.dragon), + TransformStage, + LiveEditing, + DragObjectType, + isDragNodeDataObject, + isNode, + [designerCabinSymbol]: { + isDragNodeObject, + isDragAnyObject, + isShaken, + contains, + LocationDetailType, + isLocationChildrenDetail, + ScrollTarget, + isSettingField, + TransformStage, + SettingField, + LiveEditing, + DragObjectType, + isDragNodeDataObject, + isNode, + }, + }; +}; + +const getSkeletonCabin = (skeleton: InnerSkeleton) => { + return { + createSettingFieldView, + PopupContext, + PopupPipe, + Workbench: (props: any) => , // hijack skeleton + }; +}; + +class Utils { + isNodeSchema(data: any): data is NodeSchema { + return innerIsNodeSchema(data); + } + + isFormEvent(e: KeyboardEvent | MouseEvent): boolean { + return innerIsFormEvent(e); + } + + compatibleLegaoSchema(props: any): any { + return innerCompatibleLegaoSchema(props); + } + + getNodeSchemaById(schema: NodeSchema, nodeId: string): NodeSchema | undefined { + return innerGetNodeSchemaById(schema, nodeId); + } + + getConvertedExtraKey(key: string): string { + return innerGetConvertedExtraKey(key); + } + + getOriginalExtraKey(key: string): string { + return innerGetOriginalExtraKey(key); + } + + executeTransaction(fn: () => void, type: TransitionType = TransitionType.REPAINT): void { + transactionManager.executeTransaction(fn, type); + } + + createIntl(instance: string | object): { + intlNode(id: string, params?: object): ReactNode; + intl(id: string, params?: object): string; + getLocale(): string; + setLocale(locale: string): void; + } { + return innerCreateIntl(instance); + } +} + +export default class Common { + private readonly [editorSymbol]: Editor; + private readonly [skeletonSymbol]: InnerSkeleton; + private readonly __designerCabin: any; + private readonly __skeletonCabin: any; + private readonly __editorCabin: any; + private readonly __utils: Utils; + + constructor(editor: Editor, skeleton: InnerSkeleton) { + this[editorSymbol] = editor; + this[skeletonSymbol] = skeleton; + this.__designerCabin = getDesignerCabin(this[editorSymbol]); + this.__skeletonCabin = getSkeletonCabin(this[skeletonSymbol]); + this.__utils = new Utils(); + } + + get utils(): any { + return this.__utils; + } + + get editorCabin(): any { + return { + Title: InnerTitle, + Tip: InnerTip, + shallowIntl, + createIntl: innerCreateIntl, + intl, + createSetterContent, + obx, + observable, + makeObservable, + untracked, + computed, + observer, + globalLocale, + }; + } + + get designerCabin(): any { + return this.__designerCabin; + } + + get skeletonCabin(): any { + return this.__skeletonCabin; + } +} \ No newline at end of file diff --git a/packages/shell/src/index.ts b/packages/shell/src/index.ts index 07a0c83a75..8b6096e9bb 100644 --- a/packages/shell/src/index.ts +++ b/packages/shell/src/index.ts @@ -1,5 +1,4 @@ import Detecting from './detecting'; -// import Dragon from './dragon'; import DocumentModel from './document-model'; import Event, { getEvent } from './event'; import History from './history'; @@ -15,6 +14,8 @@ import Skeleton from './skeleton'; import Dragon from './dragon'; import SettingPropEntry from './setting-prop-entry'; import SettingTopEntry from './setting-top-entry'; +import Common from './common'; + export * from './symbols'; /** @@ -27,7 +28,6 @@ export * from './symbols'; export { DocumentModel, Detecting, - // Dragon, Event, History, Material, @@ -42,5 +42,6 @@ export { SettingPropEntry, SettingTopEntry, Dragon, + Common, getEvent, }; \ No newline at end of file From abe7f40325d8156cb1fb200f18e10da7020efdae Mon Sep 17 00:00:00 2001 From: liujuping Date: Wed, 26 Oct 2022 15:39:53 +0800 Subject: [PATCH 213/823] feat: support onMouseDownHook, onChildMoveHook hooks --- .../designer/src/builtin-simulator/host.ts | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index edb823002a..5129c91634 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -542,6 +542,11 @@ export class BuiltinSimulatorHost implements ISimulatorHost Date: Thu, 1 Dec 2022 11:10:45 +0800 Subject: [PATCH 214/823] chore(release): publish 1.0.17 --- lerna.json | 2 +- packages/designer/package.json | 10 +++++----- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 16 ++++++++-------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 10 +++++----- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 12 ++++++------ packages/types/package.json | 2 +- packages/utils/package.json | 5 ++--- 16 files changed, 60 insertions(+), 61 deletions(-) diff --git a/lerna.json b/lerna.json index aff0e850f4..506c77a040 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.0.16", + "version": "1.0.17", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index aca5e7365f..830d2fa04b 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.0.16", + "version": "1.0.17", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,10 +15,10 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.0.16", - "@alilc/lowcode-shell": "1.0.16", - "@alilc/lowcode-types": "1.0.16", - "@alilc/lowcode-utils": "1.0.16", + "@alilc/lowcode-editor-core": "1.0.17", + "@alilc/lowcode-shell": "1.0.17", + "@alilc/lowcode-types": "1.0.17", + "@alilc/lowcode-utils": "1.0.17", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 7ff7f8a860..208f932d69 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.0.16", + "version": "1.0.17", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.0.16", - "@alilc/lowcode-utils": "1.0.16", + "@alilc/lowcode-types": "1.0.17", + "@alilc/lowcode-utils": "1.0.17", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 2ed3136dc0..705c418b26 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.0.16", + "version": "1.0.17", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -18,10 +18,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.0.16", - "@alilc/lowcode-editor-core": "1.0.16", - "@alilc/lowcode-types": "1.0.16", - "@alilc/lowcode-utils": "1.0.16", + "@alilc/lowcode-designer": "1.0.17", + "@alilc/lowcode-editor-core": "1.0.17", + "@alilc/lowcode-types": "1.0.17", + "@alilc/lowcode-utils": "1.0.17", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index c980c46293..c91ec27e5a 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.0.16", + "version": "1.0.17", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,14 +19,14 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.0.16", - "@alilc/lowcode-editor-core": "1.0.16", - "@alilc/lowcode-editor-skeleton": "1.0.16", + "@alilc/lowcode-designer": "1.0.17", + "@alilc/lowcode-editor-core": "1.0.17", + "@alilc/lowcode-editor-skeleton": "1.0.17", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.0.16", - "@alilc/lowcode-plugin-outline-pane": "1.0.16", - "@alilc/lowcode-shell": "1.0.16", - "@alilc/lowcode-utils": "1.0.16", + "@alilc/lowcode-plugin-designer": "1.0.17", + "@alilc/lowcode-plugin-outline-pane": "1.0.17", + "@alilc/lowcode-shell": "1.0.17", + "@alilc/lowcode-utils": "1.0.17", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index dd5801cc5f..1da63595ca 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.0.16", + "version": "1.0.17", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 4eb5b6d2d0..5e06b8cd86 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.0.16", + "version": "1.0.17", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.0.16", - "@alilc/lowcode-editor-core": "1.0.16", - "@alilc/lowcode-utils": "1.0.16", + "@alilc/lowcode-designer": "1.0.17", + "@alilc/lowcode-editor-core": "1.0.17", + "@alilc/lowcode-utils": "1.0.17", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index 640b577301..a5129db9dc 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.0.16", + "version": "1.0.17", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,10 +13,10 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-designer": "1.0.16", - "@alilc/lowcode-editor-core": "1.0.16", - "@alilc/lowcode-types": "1.0.16", - "@alilc/lowcode-utils": "1.0.16", + "@alilc/lowcode-designer": "1.0.17", + "@alilc/lowcode-editor-core": "1.0.17", + "@alilc/lowcode-types": "1.0.17", + "@alilc/lowcode-utils": "1.0.17", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index 85ff789d70..e98d8511fd 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.0.16", + "version": "1.0.17", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.0.16", - "@alilc/lowcode-utils": "1.0.16", + "@alilc/lowcode-renderer-core": "1.0.17", + "@alilc/lowcode-utils": "1.0.17", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index ee543d391a..87134571b9 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.0.16", + "version": "1.0.17", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.0.16", - "@alilc/lowcode-rax-renderer": "1.0.16", - "@alilc/lowcode-types": "1.0.16", - "@alilc/lowcode-utils": "1.0.16", + "@alilc/lowcode-designer": "1.0.17", + "@alilc/lowcode-rax-renderer": "1.0.17", + "@alilc/lowcode-types": "1.0.17", + "@alilc/lowcode-utils": "1.0.17", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 5cb1986a36..7d1ebf1121 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.0.16", + "version": "1.0.17", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.0.16" + "@alilc/lowcode-renderer-core": "1.0.17" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index c1af3e72b9..c91dec079c 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.0.16", + "version": "1.0.17", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -17,10 +17,10 @@ "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { - "@alilc/lowcode-designer": "1.0.16", - "@alilc/lowcode-react-renderer": "1.0.16", - "@alilc/lowcode-types": "1.0.16", - "@alilc/lowcode-utils": "1.0.16", + "@alilc/lowcode-designer": "1.0.17", + "@alilc/lowcode-react-renderer": "1.0.17", + "@alilc/lowcode-types": "1.0.17", + "@alilc/lowcode-utils": "1.0.17", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 416e820745..6c818991f5 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.0.16", + "version": "1.0.17", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.0.16", - "@alilc/lowcode-utils": "1.0.16", + "@alilc/lowcode-types": "1.0.17", + "@alilc/lowcode-utils": "1.0.17", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -33,7 +33,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.26.0", - "@alilc/lowcode-designer": "1.0.16", + "@alilc/lowcode-designer": "1.0.17", "@alilc/lowcode-test-mate": "^1.0.1", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", diff --git a/packages/shell/package.json b/packages/shell/package.json index b29ec0be6f..9d0e0b62fd 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.0.16", + "version": "1.0.17", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.0.16", - "@alilc/lowcode-editor-core": "1.0.16", - "@alilc/lowcode-editor-skeleton": "1.0.16", - "@alilc/lowcode-types": "1.0.16", - "@alilc/lowcode-utils": "1.0.16", + "@alilc/lowcode-designer": "1.0.17", + "@alilc/lowcode-editor-core": "1.0.17", + "@alilc/lowcode-editor-skeleton": "1.0.17", + "@alilc/lowcode-types": "1.0.17", + "@alilc/lowcode-utils": "1.0.17", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index 7e046d340b..39d3e7c49b 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.0.16", + "version": "1.0.17", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index 4faae40ab9..5555f84573 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.0.16", + "version": "1.0.17", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,11 +14,10 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.0.16", + "@alilc/lowcode-types": "1.0.17", "lodash": "^4.17.21", "mobx": "^6.3.0", "react": "^16", - "mobx": "^6.3.0", "zen-logger": "^1.1.0" }, "devDependencies": { From 7674e27f833d2edc823e1be9d41c3788ee96458c Mon Sep 17 00:00:00 2001 From: JackLian Date: Thu, 1 Dec 2022 16:58:35 +0800 Subject: [PATCH 215/823] fix: doc format issues, replace wrong links, replace image cdn --- docs/community/issue.md | 2 +- docs/docs/api/common.md | 2 +- docs/docs/api/datasource.md | 4 +- docs/docs/api/event.md | 2 +- docs/docs/api/init.md | 2 +- docs/docs/api/logger.md | 2 +- docs/docs/api/material.md | 2 +- docs/docs/api/setters.md | 4 +- docs/docs/api/skeleton.md | 97 ++++++-- docs/docs/article/index.md | 24 +- docs/docs/demoUsage/appendix/loop.md | 8 +- docs/docs/demoUsage/intro.md | 2 +- docs/docs/demoUsage/makeStuff/dialog.md | 22 +- docs/docs/demoUsage/makeStuff/table.md | 78 +++--- docs/docs/demoUsage/panels/component.md | 3 +- docs/docs/demoUsage/panels/datasource.md | 32 +-- docs/docs/demoUsage/panels/settings.md | 24 +- docs/docs/faq/faq003.md | 6 +- docs/docs/faq/faq005.md | 4 +- docs/docs/faq/faq006.md | 2 +- docs/docs/faq/faq007.md | 4 +- docs/docs/faq/faq008.md | 4 +- docs/docs/faq/faq009.md | 2 +- docs/docs/faq/faq012.md | 2 +- docs/docs/faq/faq013.md | 2 +- docs/docs/faq/faq015.md | 4 +- docs/docs/faq/faq016.md | 2 +- docs/docs/guide/appendix/glossary.md | 2 +- docs/docs/guide/appendix/metaSpec.md | 4 +- docs/docs/guide/appendix/npms.md | 2 +- docs/docs/guide/appendix/repos.md | 16 +- .../guide/appendix/setterDetails/array.md | 35 ++- .../docs/guide/appendix/setterDetails/bool.md | 13 +- .../guide/appendix/setterDetails/color.md | 12 +- .../guide/appendix/setterDetails/event.md | 69 +++--- .../docs/guide/appendix/setterDetails/icon.md | 25 +- .../guide/appendix/setterDetails/mixed.md | 12 +- .../guide/appendix/setterDetails/number.md | 17 +- .../appendix/setterDetails/radioGroup.md | 24 +- .../guide/appendix/setterDetails/select.md | 26 +- .../docs/guide/appendix/setterDetails/slot.md | 100 ++++---- .../guide/appendix/setterDetails/string.md | 14 +- .../guide/appendix/setterDetails/style.md | 47 +--- .../guide/appendix/setterDetails/textArea.md | 14 +- .../guide/appendix/setterDetails/variable.md | 18 +- docs/docs/guide/appendix/setters.md | 58 ++--- docs/docs/guide/create/_category_.json | 2 +- docs/docs/guide/create/useEditor.md | 109 +++++---- docs/docs/guide/create/useRenderer.md | 34 +-- docs/docs/guide/design/datasourceEngine.md | 26 +- docs/docs/guide/design/editor.md | 227 ++++++++++++------ docs/docs/guide/design/generator.md | 74 +++--- docs/docs/guide/design/materialParser.md | 32 ++- docs/docs/guide/design/renderer.md | 46 ++-- docs/docs/guide/design/setter.md | 22 +- docs/docs/guide/design/specs.md | 89 ++++--- docs/docs/guide/design/summary.md | 52 ++-- docs/docs/guide/expand/_category_.json | 2 +- docs/docs/guide/expand/editor/cli.md | 227 +++++++++--------- docs/docs/guide/expand/editor/material.md | 99 ++++---- docs/docs/guide/expand/editor/metaSpec.md | 175 ++++++++------ docs/docs/guide/expand/editor/partsIntro.md | 120 +++++---- .../guide/expand/editor/pluginContextMenu.md | 38 +-- docs/docs/guide/expand/editor/pluginWidget.md | 125 ++++++---- docs/docs/guide/expand/editor/setter.md | 83 +++++-- docs/docs/guide/expand/editor/summary.md | 30 +-- .../guide/expand/runtime/codeGeneration.md | 24 +- docs/docs/guide/expand/runtime/renderer.md | 6 +- docs/docs/guide/quickStart/demo.md | 73 +++--- docs/docs/guide/quickStart/intro.md | 6 +- docs/docs/guide/quickStart/start.md | 226 ++++++++++------- docs/docs/participate/config.md | 2 +- docs/docs/participate/doc.md | 16 +- docs/docs/participate/flow.md | 14 +- docs/docs/specs/assets-spec.md | 16 +- docs/docs/specs/lowcode-spec.md | 50 ++-- docs/docs/specs/material-spec.md | 96 ++++---- docs/docusaurus.config.js | 4 + docs/package.json | 2 +- 79 files changed, 1757 insertions(+), 1240 deletions(-) diff --git a/docs/community/issue.md b/docs/community/issue.md index f0afc90d2a..ebda01afcf 100644 --- a/docs/community/issue.md +++ b/docs/community/issue.md @@ -65,7 +65,7 @@ window.AliLowCodeEngine.project.openDocument('docl4xkca5b') 期望: -- 页面中的xxx部分和预期不符合,期望的效果是 xxx +- 页面中的 xxx 部分和预期不符合,期望的效果是 xxx #### 【支持稍慢】通过线上 demo + 完整操作步骤可复现 **示例** diff --git a/docs/docs/api/common.md b/docs/docs/api/common.md index 46b4d7f034..c16d220432 100644 --- a/docs/docs/api/common.md +++ b/docs/docs/api/common.md @@ -43,7 +43,7 @@ common.utils.startTransaction(() => { ``` ### createIntl -i18n相关工具 +i18n 相关工具 *引擎版本 >= 1.0.17 ```typescript import { common } from '@alilc/lowcode-engine'; diff --git a/docs/docs/api/datasource.md b/docs/docs/api/datasource.md index cadf9cb581..994e1ee180 100644 --- a/docs/docs/api/datasource.md +++ b/docs/docs/api/datasource.md @@ -4,7 +4,7 @@ sidebar_position: 12 --- ### 请求数据源 ```javascript -// 请求userList (userList在数据源面板中定义) +// 请求 userList(userList 在数据源面板中定义) this.dataSourceMap['userList'].load({ data: {} @@ -22,7 +22,7 @@ const { userList } = this.state; // 获取数据源面板中定义的值 const { user } = this.state; -// 修改state值 +// 修改 state 值 this.setState({ user: {} }); diff --git a/docs/docs/api/event.md b/docs/docs/api/event.md index 26232b7c1f..b24c91054a 100644 --- a/docs/docs/api/event.md +++ b/docs/docs/api/event.md @@ -74,7 +74,7 @@ import { event } from '@alilc/lowcode-engine'; class SetterB extends React.Component { bindFunction = () => { const { field, value } = this.props; - // 这里展示的和插件进行通信, 事件规则是插件名 + 方法 + // 这里展示的和插件进行通信,事件规则是插件名 + 方法 event.emit('eventBindDialog.openDialog', field.name, this.emitEventName); } } diff --git a/docs/docs/api/init.md b/docs/docs/api/init.md index 50c5cf7013..13eacaaf8e 100644 --- a/docs/docs/api/init.md +++ b/docs/docs/api/init.md @@ -41,7 +41,7 @@ interface EngineOptions { */ enableCanvasLock?: boolean; /** - * 容器锁定后,容器本身是否可以设置属性,仅当画布锁定特性开启时生效, 默认值为:false + * 容器锁定后,容器本身是否可以设置属性,仅当画布锁定特性开启时生效,默认值为:false */ enableLockedNodeSetting?: boolean; /** diff --git a/docs/docs/api/logger.md b/docs/docs/api/logger.md index 3fbb7b7fcc..d523622d80 100644 --- a/docs/docs/api/logger.md +++ b/docs/docs/api/logger.md @@ -35,7 +35,7 @@ import { logger } from '@alilc/lowcode-engine'; // 内部实现:logger = getLogger({ level: 'warn', bizName: 'designer:pluginManager' }) -// 若在url query中增加 `__logConf__` 可改变打印日志级别和限定业务类型日志 +// 若在 url query 中增加 `__logConf__` 可改变打印日志级别和限定业务类型日志 // 默认:__logConf__=warn:* logger.log('log'); // 不输出 logger.warn('warn'); // 输出 diff --git a/docs/docs/api/material.md b/docs/docs/api/material.md index 852287f649..69a2c76cd5 100644 --- a/docs/docs/api/material.md +++ b/docs/docs/api/material.md @@ -12,7 +12,7 @@ sidebar_position: 2 # 方法签名(functions) ## 资产包 ### setAssets -设置「[资产包](https://www.yuque.com/lce/doc/vgcyf1)」结构 +设置「[资产包](/site/docs/specs/lowcode-spec#2-协议结构)」结构 **类型定义** ```typescript diff --git a/docs/docs/api/setters.md b/docs/docs/api/setters.md index ac45831be1..41c992e16d 100644 --- a/docs/docs/api/setters.md +++ b/docs/docs/api/setters.md @@ -83,7 +83,7 @@ interface AltStringSetterProps { value: string; // 默认值 initialValue: string; - // setter唯一输出 + // setter 唯一输出 onChange: (val: string) => void; // AltStringSetter 特殊配置 placeholder: string; @@ -254,7 +254,7 @@ interface AltStringSetterProps { value: string; // 默认值 initialValue: string; - // setter唯一输出 + // setter 唯一输出 onChange: (val: string) => void; // AltStringSetter 特殊配置 placeholder: string; diff --git a/docs/docs/api/skeleton.md b/docs/docs/api/skeleton.md index 80e3220f6f..38850b09f0 100644 --- a/docs/docs/api/skeleton.md +++ b/docs/docs/api/skeleton.md @@ -3,23 +3,57 @@ title: skeleton - 面板 API sidebar_position: 1 --- ## 模块简介 -面板 API 提供了面板扩展和管理的能力,如下图蓝色内容都是扩展出来的。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645442085447-d1822e7f-9e5a-4e06-a770-04b1023d5daf.png#clientId=u9aca70b6-1a98-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=498&id=u2dd3deb2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=996&originWidth=1780&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1549904&status=done&style=none&taskId=u28659b69-981c-416e-bed6-b2f06b8e6fc&title=&width=890)
页面上可以扩展的区域共 5 个,具体如下:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645431386085-2710d33d-0652-450a-a993-c804368da1ce.png#clientId=u1724eb73-4c0c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=487&id=ud138f866&margin=%5Bobject%20Object%5D&name=image.png&originHeight=974&originWidth=1892&originalType=binary&ratio=1&rotation=0&showTitle=false&size=228235&status=done&style=none&taskId=u265d50a5-3700-406e-84b2-0158ebadaae&title=&width=946) +面板 API 提供了面板扩展和管理的能力,如下图蓝色内容都是扩展出来的。 + +![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645442085447-d1822e7f-9e5a-4e06-a770-04b1023d5daf.png#clientId=u9aca70b6-1a98-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=498&id=u2dd3deb2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=996&originWidth=1780&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1549904&status=done&style=none&taskId=u28659b69-981c-416e-bed6-b2f06b8e6fc&title=&width=890) + +页面上可以扩展的区域共 5 个,具体如下: +![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645431386085-2710d33d-0652-450a-a993-c804368da1ce.png#clientId=u1724eb73-4c0c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=487&id=ud138f866&margin=%5Bobject%20Object%5D&name=image.png&originHeight=974&originWidth=1892&originalType=binary&ratio=1&rotation=0&showTitle=false&size=228235&status=done&style=none&taskId=u265d50a5-3700-406e-84b2-0158ebadaae&title=&width=946) ### 基本概念 -#### 扩展区域位置(area) +#### 扩展区域位置 (area) ##### topArea -展示在设计器的顶部区域,常见的相关区域的插件主要是:
1)注册设计器 Logo;
2)设计器操作回退和撤销按钮;
3)全局操作按钮,例如:保存、预览等; + +展示在设计器的顶部区域,常见的相关区域的插件主要是: +1. 注册设计器 Logo; +2. 设计器操作回退和撤销按钮; +3. 全局操作按钮,例如:保存、预览等; ##### leftArea -左侧区域的展示形式大多数是 Icon 和对应的面板,通过点击 Icon 可以展示对应的面板并隐藏其他的面板。
该区域相关插件的主要有:
1)大纲树展示,展示该设计器设计页面的大纲。
2)组件库,展示注册到设计器中的组件,点击之后,可以从组件库面板中拖拽到设计器的画布中。
3)数据源面板
4)JS 等代码面板。
可以发现,这个区域的面板大多数操作时是不需要同时并存的,且交互比较复杂的,需要一个更整块的区域来进行操作。 + +左侧区域的展示形式大多数是 Icon 和对应的面板,通过点击 Icon 可以展示对应的面板并隐藏其他的面板。 + +该区域相关插件的主要有: +1. 大纲树展示,展示该设计器设计页面的大纲。 +2. 组件库,展示注册到设计器中的组件,点击之后,可以从组件库面板中拖拽到设计器的画布中。 +3. 数据源面板 +4. JS 等代码面板。 + +可以发现,这个区域的面板大多数操作时是不需要同时并存的,且交互比较复杂的,需要一个更整块的区域来进行操作。 + ##### centerArea -画布区域,由于画布大多数是展示作用,所以一般扩展的种类比较少。常见的扩展有:
1)画布大小修改
2)物料选中扩展区域修改 + +画布区域,由于画布大多数是展示作用,所以一般扩展的种类比较少。常见的扩展有: +1. 画布大小修改 +2. 物料选中扩展区域修改 ##### rightArea + 右侧区域,常用于组件的配置。常见的扩展有:统一处理组件的配置项,例如统一删除某一个配置项,统一添加某一个配置项的。 ##### toolbar + 跟 topArea 类似,按需放置面板插件~ -#### 展示类型(type) -展示类型用于区分插件在设计器内可操作的几种不同界面类型。主要的几种类型为PanelDock、Widget、Dock,另有Panel类型目前不推荐使用。 +#### 展示类型 (type) + +展示类型用于区分插件在设计器内可操作的几种不同界面类型。主要的几种类型为 PanelDock、Widget、Dock,另有 Panel 类型目前不推荐使用。 ##### PanelDock -PanelDock 是以面板的形式展示在设计器的左侧区域的。其中主要有两个部分组成,一个是图标,一个是面板。当点击图标时可以控制面板的显示和隐藏。
下图是组件库插件的展示效果。
![Feb-08-2022 19-44-15.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644320663827-ee9c54a1-f684-40e2-8a6b-875103d04b31.gif#clientId=u221f0bd4-c19e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=555&id=u5292d9cc&margin=%5Bobject%20Object%5D&name=Feb-08-2022%2019-44-15.gif&originHeight=790&originWidth=1536&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1381641&status=done&style=stroke&taskId=ub28a13a4-3d80-4a02-bcaa-cc9d6127243&title=&width=1080)
其中右上角可以进行固定,可以对弹出的宽度做设定
接入可以参考代码 + +PanelDock 是以面板的形式展示在设计器的左侧区域的。其中主要有两个部分组成,一个是图标,一个是面板。当点击图标时可以控制面板的显示和隐藏。 + +下图是组件库插件的展示效果。 + +![Feb-08-2022 19-44-15.gif](https://img.alicdn.com/imgextra/i2/O1CN01i66G5O27bK37nlpxV_!!6000000007815-1-tps-1536-790.gif) + +其中右上角可以进行固定,可以对弹出的宽度做设定 + +接入可以参考代码 ```javascript import { skeleton } from "@alilc/lowcode-engine"; @@ -31,7 +65,7 @@ skeleton.add({ props: { align: "left", icon: "wenjian", - description: "JS面板", + description: "JS 面板", }, panelProps: { floatable: true, // 是否可浮动 @@ -39,13 +73,18 @@ skeleton.add({ hideTitleBar: false, maxHeight: 800, maxWidth: 1200, - title: "JS面板", + title: "JS 面板", width: 600, }, }); ``` ##### Widget -Widget 形式是直接渲染在当前编辑器的对应位置上。如 demo 中在设计器顶部的所有组件都是这种展现形式。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644320068765-47efc836-30c2-452f-8104-b98b1ea3533d.png#clientId=u221f0bd4-c19e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=51&id=P60UE&margin=%5Bobject%20Object%5D&name=image.png&originHeight=94&originWidth=1988&originalType=binary&ratio=1&rotation=0&showTitle=false&size=58410&status=done&style=stroke&taskId=u4eadd643-2e63-4be7-8736-b27b9c82b81&title=&width=1080)
接入可以参考代码: +Widget 形式是直接渲染在当前编辑器的对应位置上。如 demo 中在设计器顶部的所有组件都是这种展现形式。 + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01IRQIZp1m5AJPwBKDv_!!6000000004902-2-tps-1988-94.png) + +接入可以参考代码: + ```javascript import {skeleton} from "@alilc/lowcode-engine"; // 注册 logo 面板 @@ -53,8 +92,8 @@ skeleton.add({ area: "topArea", type: "Widget", name: "logo", - content: Logo, // Widget 组件实例 - contentProps: { // Widget 插件props + content: Logo, // Widget 组件实例 + contentProps: { // Widget 插件 props logo: "https://img.alicdn.com/tfs/TB1_SocGkT2gK0jSZFkXXcIQFXa-66-66.png", href: "/", @@ -66,7 +105,9 @@ skeleton.add({ }); ``` ##### Dock -一个图标的表现形式,可以用于语言切换、跳转到外部链接、打开一个 widget 等场景 + +一个图标的表现形式,可以用于语言切换、跳转到外部链接、打开一个 widget 等场景。 + ```javascript import { skeleton } from "@alilc/lowcode-engine"; @@ -75,7 +116,7 @@ skeleton.add({ type: "Dock", name: "opener", content: Opener, // Widget 组件实例 - contentProps: { // Widget 插件props + contentProps: { // Widget 插件 props xxx: "1", }, props: { @@ -89,11 +130,14 @@ skeleton.add({ } }); ``` -####
+ ## 变量(variables) + 无 ## 方法签名(functions) + ### 1. add + ```tsx add(config: IWidgetBaseConfig & { area?: string; @@ -116,8 +160,6 @@ IWidgetBaseConfig 定义如下: | index | 面板的位置,不传默认按插件注册顺序 | | - - ### 2. remove remove(config: IWidgetBaseConfig) @@ -150,13 +192,17 @@ hideWidget(name: string) enableWidget(name: string) -将 widget 启用。
注:该函数将会触发全局事件 'skeleton.widget.enable' +将 widget 启用。 + +注:该函数将会触发全局事件 'skeleton.widget.enable' ### 8. disableWidget disableWidget(name: string) -将 widget 禁用掉,禁用后,所有鼠标事件都会被禁止掉。
适用场景:在该面板还在进行初始化构造时,可以先禁止掉,防止用户点击报错,待初始化完成,重新启用。 +将 widget 禁用掉,禁用后,所有鼠标事件都会被禁止掉。 + +适用场景:在该面板还在进行初始化构造时,可以先禁止掉,防止用户点击报错,待初始化完成,重新启用。 ## 事件(events) ### 1. onShowPanel @@ -166,7 +212,8 @@ onShowPanel(listener: (...args: unknown[]) => void) 监听 Panel 实例显示事件 ### 2. onHidePanel -
onHidePanel(listener: (...args: unknown[]) => void) + +onHidePanel(listener: (...args: unknown[]) => void) 监听 Panel 实例隐藏事件 @@ -177,10 +224,12 @@ onShowWidget(listener: (...args: unknown[]) => void) 监听 Widget 实例显示事件 ### 4. onHideWidget -
onHideWidget(listener: (...args: unknown[]) => void) + +onHideWidget(listener: (...args: unknown[]) => void) 监听 Widget 实例隐藏事件 ## 使用示例 + ```typescript import { skeleton } from '@alilc/lowcode-engine'; @@ -199,7 +248,7 @@ skeleton.add({ props: { align: 'top', icon: 'wenjian', - description: 'JS面板', + description: 'JS 面板', }, panelProps: { floatable: true, @@ -208,7 +257,7 @@ skeleton.add({ hideTitleBar: false, maxHeight: 800, maxWidth: 1200, - title: 'JS面板', + title: 'JS 面板', width: 600, }, content: SourceEditor, diff --git a/docs/docs/article/index.md b/docs/docs/article/index.md index d0a65524c4..fd09a59a34 100644 --- a/docs/docs/article/index.md +++ b/docs/docs/article/index.md @@ -13,13 +13,13 @@ title: 低代码引擎相关文章资料 - [2B 领域下的低代码探索之路](https://mp.weixin.qq.com/s/HAxrMHLT43dPH488RiEIdw) - [阿里低代码引擎 LowCodeEngine 正式开源!](https://mp.weixin.qq.com/s/T66LghtWLz2Oh048XqaniA) -## Portal设计项目实战 +## Portal 设计项目实战 #### 直播回放 [https://www.bilibili.com/video/BV1AS4y1K7DP/](https://www.bilibili.com/video/BV1AS4y1K7DP/) #### 示例项目 -- 前端: [https://github.com/mark-ck/lowcode-portal](https://github.com/mark-ck/lowcode-portal) -- 后端: [https://github.com/mark-ck/document-solution-site](https://github.com/mark-ck/document-solution-site) +- 前端: [https://github.com/mark-ck/lowcode-portal](https://github.com/mark-ck/lowcode-portal) +- 后端: [https://github.com/mark-ck/document-solution-site](https://github.com/mark-ck/document-solution-site) - 组件库:[https://github.com/mark-ck/portal-components](https://github.com/mark-ck/portal-components) **注意** @@ -27,12 +27,12 @@ title: 低代码引擎相关文章资料 2. 后端项目要把 config.default.js 里的 yuque 和 oss 配置补全; #### 视频链接 -- [阿里低代码引擎项目实战(1)-引擎 demo 部署到 faas 服务](https://www.bilibili.com/video/BV1B44y1P7GM/) -- [【有翻车】阿里低代码引擎项目实战(2)-保存页面到远端存储](https://www.bilibili.com/video/BV1AS4y1K7DP/) -- [阿里巴巴低代码引擎项目实战(3)-自定义组件接入](https://www.bilibili.com/video/BV1dZ4y1m76S/) -- [阿里低代码引擎项目实战(4)-自定义插件-页面管理](https://www.bilibili.com/video/BV17a411i73f/) -- [阿里低代码引擎项目实战(4)-用户登录](https://www.bilibili.com/video/BV1Wu411e7EQ/) -- [【有翻车】阿里低代码引擎项目实战(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 +- [阿里低代码引擎项目实战 (1)-引擎 demo 部署到 faas 服务](https://www.bilibili.com/video/BV1B44y1P7GM/) +- [【有翻车】阿里低代码引擎项目实战 (2)-保存页面到远端存储](https://www.bilibili.com/video/BV1AS4y1K7DP/) +- [阿里巴巴低代码引擎项目实战 (3)-自定义组件接入](https://www.bilibili.com/video/BV1dZ4y1m76S/) +- [阿里低代码引擎项目实战 (4)-自定义插件 - 页面管理](https://www.bilibili.com/video/BV17a411i73f/) +- [阿里低代码引擎项目实战 (4)-用户登录](https://www.bilibili.com/video/BV1Wu411e7EQ/) +- [【有翻车】阿里低代码引擎项目实战 (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 diff --git a/docs/docs/demoUsage/appendix/loop.md b/docs/docs/demoUsage/appendix/loop.md index 0afb5c9310..8b364ecf4f 100644 --- a/docs/docs/demoUsage/appendix/loop.md +++ b/docs/docs/demoUsage/appendix/loop.md @@ -3,15 +3,15 @@ title: 如何使用循环值 sidebar_position: 0 --- 1.设置循环数据 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1655975447215-026bd3ae-ae2a-4f90-805e-df0d5c4bb7d2.png#clientId=ubd100ffc-952a-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=950&id=u6413eee5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1900&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=339030&status=done&style=none&taskId=ued46d732-83a2-441f-a80f-23061587689&title=&width=1920) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01Gw1kXO1qaXulQCWap_!!6000000005512-2-tps-3840-1900.png) 2.给需要的变量绑定 this.item -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1655975499246-f9d14ef4-6736-46a5-8b24-8eedd4477617.png#clientId=ubd100ffc-952a-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=946&id=u0b50f02a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1892&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=451804&status=done&style=none&taskId=uf4916102-2e3d-4277-ac81-604c6761615&title=&width=1920) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01RpP2Ev24lRxjqpHdY_!!6000000007431-2-tps-3840-1892.png) 绑定之后的效果如下: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1655975540038-ccf3aabc-3f7c-4e33-a701-a9b005b1cf25.png#clientId=uc887596b-8aed-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=942&id=u32901b3a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1884&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=333998&status=done&style=none&taskId=u2853d459-4432-4d0a-ba12-494e79e892a&title=&width=1920) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN019qa1J31m7ugsXcnaA_!!6000000004908-2-tps-3840-1884.png) 其中 this.item 的 item 是可以配置的。配置不同的 key 可以方便在多层循环中使用不同层级的循环 item 值。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1655975569197-33d90389-7394-4e65-bc6a-582b7ceb9fee.png#clientId=uc887596b-8aed-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=948&id=u6e6741d2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1896&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=311961&status=done&style=none&taskId=u14bbcfbb-e7cf-4307-a58d-3cb58afe8f7&title=&width=1920) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01XQfnYL1P4wxn01oXv_!!6000000001788-2-tps-3840-1896.png) this.index 是当前循环的索引值。 diff --git a/docs/docs/demoUsage/intro.md b/docs/docs/demoUsage/intro.md index 5154f0ea7f..c8b23dc27d 100644 --- a/docs/docs/demoUsage/intro.md +++ b/docs/docs/demoUsage/intro.md @@ -29,7 +29,7 @@ sidebar_position: 0 它们操作的数据关系是: -- 页面中的 Schema 数据:保存在低代码引擎中的 Schema,点击 Schema 面板中的“保存 Schema” 时将修改引擎中的值,此外低代码引擎中的所有操作都可能修改到 Schema +- 页面中的 Schema 数据:保存在低代码引擎中的 Schema,点击 Schema 面板中的“保存 Schema”时将修改引擎中的值,此外低代码引擎中的所有操作都可能修改到 Schema - localStorage 数据:由“保存到本地”保存到 localStorage 中,页面初始化时将读取,预览页面时也会读取 - 默认 Schema:保存在 Demo 项目中的默认 Schema(`public/schema.json`),初始化页面时如果不存在 localStorage 数据即会读取,点击“重置页面”时,也会读取 diff --git a/docs/docs/demoUsage/makeStuff/dialog.md b/docs/docs/demoUsage/makeStuff/dialog.md index 772bd56475..56303067cb 100644 --- a/docs/docs/demoUsage/makeStuff/dialog.md +++ b/docs/docs/demoUsage/makeStuff/dialog.md @@ -2,28 +2,28 @@ title: 3. 如何通过按钮展示/隐藏弹窗 sidebar_position: 1 --- -### 1.拖拽一个按钮 +## 1.拖拽一个按钮 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652355202273-1a84b1e5-e33c-4686-b92b-633936423141.png#clientId=udd01ff56-e3fe-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=906&id=u81f6abfa&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1812&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=749009&status=done&style=none&taskId=u6f4bf7e1-db67-4fca-8107-04021936c00&title=&width=1792) -### 2.拖拽一个弹窗 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652355233863-6d65ee77-b2fa-4d51-a04c-f0582c99eb72.png#clientId=udd01ff56-e3fe-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=811&id=u848a34e1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1622&originWidth=3578&originalType=binary&ratio=1&rotation=0&showTitle=false&size=774132&status=done&style=none&taskId=ue713e331-7ce0-4bd8-b41d-3ae1e07c69b&title=&width=1789) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01kLaWA31D6WwTui9VW_!!6000000000167-2-tps-3584-1812.png) +## 2.拖拽一个弹窗 +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01rfRzLa1quEwUyulPc_!!6000000005555-2-tps-3578-1622.png) -### 3.查看弹窗 refId -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652355269097-3e5282ed-2fdd-4a3b-b9b8-d78fac69c42e.png#clientId=udd01ff56-e3fe-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=794&id=ufd9346c1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1588&originWidth=3574&originalType=binary&ratio=1&rotation=0&showTitle=false&size=843332&status=done&style=none&taskId=ubc630826-e577-4dee-a2c3-5478bdf266a&title=&width=1787) +## 3.查看弹窗 refId +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01rEgPnW1cSqdWpG0YE_!!6000000003600-2-tps-3574-1588.png) - 点击弹窗 - 点击右侧面板中的高级 - 找到 refId -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652355320821-dd2c85f7-a75e-495d-896a-67e4761561ac.png#clientId=udd01ff56-e3fe-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=898&id=u4bf6b721&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1796&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=993930&status=done&style=none&taskId=u8c648fa2-c660-4979-8991-1cf138d2372&title=&width=1792) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01MXMfqn1rj4uKzlOh2_!!6000000005666-2-tps-3584-1796.png) 这里我们的 refId 是 "pro-dialog-entryl32xgrus" -### 4.隐藏弹窗 +## 4.隐藏弹窗 点击工具栏的隐藏小图标,将弹窗在画布中隐藏 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652355400766-f7bdca37-7ba9-497d-a7e2-ad1d92233a26.png#clientId=udd01ff56-e3fe-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=784&id=ucbbe5086&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1568&originWidth=3578&originalType=binary&ratio=1&rotation=0&showTitle=false&size=774518&status=done&style=none&taskId=u2c8e73cd-10c5-47d3-b96e-30e6840d1af&title=&width=1789) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN017Kamt71HFvWkpeK8j_!!6000000000729-2-tps-3578-1568.png) -### 5.按钮绑定事件 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652355486231-172c5797-c376-4f6f-94f7-8c3c593caa02.png#clientId=udd01ff56-e3fe-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=907&id=ufcf7d50e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1814&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=845218&status=done&style=none&taskId=u7c2c54ce-9c18-4b29-a066-f3024a95443&title=&width=1792) +## 5.按钮绑定事件 +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01SwJ0xx1u3LfX2h8yt_!!6000000005981-2-tps-3584-1814.png) **通过下面的代码即可打开弹窗** diff --git a/docs/docs/demoUsage/makeStuff/table.md b/docs/docs/demoUsage/makeStuff/table.md index 06999010d2..96a894890e 100644 --- a/docs/docs/demoUsage/makeStuff/table.md +++ b/docs/docs/demoUsage/makeStuff/table.md @@ -2,30 +2,33 @@ title: 2. 如何制作表格 sidebar_position: 0 --- -# 步骤详解 -## 拖入组件 +## 步骤详解 +### 拖入组件 + 一个常见的表格页面会包含查询框、表格和分页按钮。这些都在 Fusion UI 中进行了相应的封装,我们可以在左侧组件面板处找到他们。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645011856718-ed2aa0b1-0c5c-4ec0-a72b-377bc500faf3.png#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=824&id=ue90ea461&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1648&originWidth=3032&originalType=binary&ratio=1&rotation=0&showTitle=false&size=963971&status=done&style=stroke&taskId=u3b1dfd98-44b7-4a13-be2a-e0124084288&title=&width=1516) + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01UU8pVT26XN1A0ExVG_!!6000000007671-2-tps-3032-1648.png) 将他们拖到画布之中: ![Feb-16-2022 16-58-59.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645002115004-4f01eb8d-cf68-4a7c-b0db-bc5aaf2604a3.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=uf69dc239&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2016-58-59.gif&originHeight=792&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7510570&status=done&style=stroke&taskId=ua6ea2651-6c6c-4762-98cc-cc3ab5734cd&title=&width=767) -## 配置组件 +### 配置组件 选中刚拖入的“查询筛选”组件,您可以配置此组件: -![Feb-14-2022 17-59-47.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644832912542-4b2e66ae-ba15-4e38-ab79-9f83e413a493.gif#clientId=uec0ffd6f-d4e1-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=u83c491b2&margin=%5Bobject%20Object%5D&name=Feb-14-2022%2017-59-47.gif&originHeight=792&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=2147213&status=done&style=stroke&taskId=uffd7092e-a247-4f48-b831-aaffe3646f7&title=) +![Feb-14-2022 17-59-47.gif](https://img.alicdn.com/imgextra/i2/O1CN01RiDUy31aufSeVk8IN_!!6000000003390-1-tps-1532-792.gif) 对于形如 Array 的配置项目,我们可以增删项目、修改常用项、修改顺序。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645012184644-444d82fa-a226-4784-b0df-92a5a52748bc.png#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=738&id=uc4ea8ded&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1476&originWidth=3060&originalType=binary&ratio=1&rotation=0&showTitle=false&size=375890&status=done&style=none&taskId=u7a1f43d8-eac4-405e-a3c9-38d3047f452&title=&width=1530) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01eWOK0d1fOfsF9PZu9_!!6000000003997-2-tps-3060-1476.png) 掌握组件配置功能,我们就可以完成一个常用的查询框的配置: ![Feb-21-2022 18-05-52.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645437973453-1fd1dc10-99ad-4c18-af49-2741bd81c4ae.gif#clientId=u022fc577-71a7-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=395&id=u964ae52f&margin=%5Bobject%20Object%5D&name=Feb-21-2022%2018-05-52.gif&originHeight=790&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7210902&status=done&style=stroke&taskId=u9e39c54a-7467-4a96-b716-681cf598f09&title=&width=766) -## 绑定数据 +### 绑定数据 低代码场景下,我们需要绑定动态的数据。通过左侧的源码编辑面板,我们可以创建动态数据和它的相关处理函数: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645012532562-596d4a96-908e-4094-836c-974bda61d8a2.png#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=739&id=ufa7b81f8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1478&originWidth=2976&originalType=binary&ratio=1&rotation=0&showTitle=false&size=816197&status=done&style=none&taskId=u5ab9656e-26b6-427a-a52e-5e11dbc4a7a&title=&width=1488) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN015Bw2aQ1jaMRWoYzv5_!!6000000004564-2-tps-2976-1478.png) + 如图,我们配入如下自定义值进 state 里: ```json "companies": [ @@ -35,18 +38,25 @@ sidebar_position: 0 ] ``` 定义动态数据以后,我们需要绑定它到组件的属性中,我们找到相关属性的配置: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645012714358-f3f39d5f-1790-4196-9f16-b45f51fa8f28.png#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=896&id=u1126fd65&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1792&originWidth=3546&originalType=binary&ratio=1&rotation=0&showTitle=false&size=413958&status=done&style=none&taskId=u976689ac-18a1-4f15-9fc2-60681670fc7&title=&width=1773) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645012791356-4fed1bea-bec2-4be9-85ea-b366d0acb4ab.png#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=820&id=ub81b6dc8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1640&originWidth=3428&originalType=binary&ratio=1&rotation=0&showTitle=false&size=354847&status=done&style=none&taskId=uc645e654-b293-4c18-86da-a6637083e55&title=&width=1714) + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN013Cu5OE1CXGRhyEmbJ_!!6000000000090-2-tps-3546-1792.png) + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01iaK15j1bgIeO65svI_!!6000000003494-2-tps-3428-1640.png) + 如图,输入表达式: -```json + +```javascript this.state.companies ``` + 再结合上一节的“配置组件”操作,我们已经可以把表格的主体配置出来了: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645013130950-4219cf27-760c-4749-8d4e-013dd53dbc83.png#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=820&id=u73c837e3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1640&originWidth=3058&originalType=binary&ratio=1&rotation=0&showTitle=false&size=408420&status=done&style=stroke&taskId=u23f7f045-8077-4e9d-9335-fea3ba54273&title=&width=1529) -## 动态请求 +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01p8QJ5C1buxKDTS1cU_!!6000000003526-2-tps-3058-1640.png) + +### 动态请求 我们进入代码区块,使用生命周期方法来完成动态数据的请求。假设提供数据的接口是:[http://rap2api.taobao.org/app/mock/250089/testCompanies](http://rap2api.taobao.org/app/mock/250089/testCompanies),那么,我们可以在源码面板进行如下配置: + ```typescript class LowcodeComponent extends Component { state = { @@ -54,9 +64,9 @@ class LowcodeComponent extends Component { "isShowDialog": false, "loading": false, "companies": [ - { company: '测试公司1', id: 1, createTime: +new Date() }, - { company: '测试公司2', id: 2, createTime: +new Date() }, - { company: '测试公司3', id: 3, createTime: +new Date() }, + { company: '测试公司 1', id: 1, createTime: +new Date() }, + { company: '测试公司 2', id: 2, createTime: +new Date() }, + { company: '测试公司 3', id: 3, createTime: +new Date() }, ] } componentDidMount() { @@ -75,36 +85,46 @@ class LowcodeComponent extends Component { } } ``` + 在 `componentDidMount` 生命周期,将请求接口并设置 loading 和数据字段。 + 点击保存或叉关闭源码面板后,我们可以看到代码已经生效了: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645013883960-ca217c38-5c40-4ecc-9e05-277098fef16a.png#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=817&id=u1a3f852b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1634&originWidth=3058&originalType=binary&ratio=1&rotation=0&showTitle=false&size=427572&status=done&style=stroke&taskId=ubd2291b7-36c3-48c1-b489-9c61f0f6230&title=&width=1529) -## 配置插槽 +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01lqjW8e1f39G8Zm7hQ_!!6000000003950-2-tps-3058-1634.png) + +### 配置插槽 我们可以用绑定数据的方法把 loading 绑在加载指示上: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645014111323-c45f9b9a-77dd-4724-b6ee-78572863a871.png#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=952&id=u3bdd353b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1904&originWidth=3170&originalType=binary&ratio=1&rotation=0&showTitle=false&size=503197&status=done&style=none&taskId=u1faed9f0-3c68-4385-8d08-e59e2a1600a&title=&width=1585) + +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01K3Pwjo1PKWQcoBl5K_!!6000000001822-2-tps-3170-1904.png) + ![Feb-16-2022 20-24-35.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645014292272-68e07740-47dc-4c94-8437-beded0b07c63.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u4506fc72&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-24-35.gif&originHeight=792&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=6960677&status=done&style=stroke&taskId=u9fe02184-e6dc-4886-b371-c48ca1e2832&title=&width=766) + 将 Loading 的“是否显示”字段绑定 `this.state.loading` 后,我们可以看到,这里暴露了一个插槽。插槽是可以任意扩展的预设部分,我们可以把其他的部分拖进插槽: -![Feb-16-2022 20-27-03.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645014436894-9b975ae6-76cc-412b-829a-fae3605277dc.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u407467ac&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-27-03.gif&originHeight=792&originWidth=1528&originalType=binary&ratio=1&rotation=0&showTitle=false&size=3443266&status=done&style=stroke&taskId=u0a091444-8b12-49a0-a57a-bfa758d351a&title=&width=764) + +![Feb-16-2022 20-27-03.gif](https://img.alicdn.com/imgextra/i2/O1CN01HSBncU1XWRfPdwlPK_!!6000000002931-1-tps-1528-792.gif) + 点击右上角的预览,我们能够看到完整的动态请求效果了: -![Feb-16-2022 20-28-36.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645014527841-b621f38f-2c03-40f1-aa41-19293f96b08f.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u6ee6beea&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-28-36.gif&originHeight=792&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1968612&status=done&style=stroke&taskId=u2bdcee3f-91c5-4cb3-8405-f44f995cc78&title=&width=767) +![Feb-16-2022 20-28-36.gif](https://img.alicdn.com/imgextra/i3/O1CN01o5THZf1fkesw2nZEC_!!6000000004045-1-tps-1534-792.gif) -## 列挂钩浮层 +### 列挂钩浮层 为了能够让表格里的操作挂钩浮层,我们先拖入一个浮层: ![Feb-16-2022 20-32-09.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645014772471-0fce9b50-0f70-492e-bb53-5f875c00f5b4.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u4d33cd05&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-32-09.gif&originHeight=792&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7475148&status=done&style=stroke&taskId=u9dc26cba-41eb-4fe8-b96f-fe391968861&title=&width=766) + 使用大纲树能够临时显示和隐藏此浮层: ![Feb-16-2022 20-32-39.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645014828329-b2de4db6-9032-4280-b886-db17070eea21.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=ue27e6676&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-32-39.gif&originHeight=792&originWidth=1530&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7335022&status=done&style=stroke&taskId=u73554a5d-5ebe-48d1-a861-426ba8501b1&title=&width=765) -我们给表格增加一个数据列: -![Feb-16-2022 20-39-41.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645015242447-3e019714-4b86-4c10-9bf7-01e19201bf0c.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=uc2c35de3&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-39-41.gif&originHeight=792&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=3415710&status=done&style=stroke&taskId=u5aedc5dd-f361-4e45-88b0-be09af09a6a&title=&width=766) + +我们给表格增加一个数据列: +![Feb-16-2022 20-39-41.gif](https://img.alicdn.com/imgextra/i2/O1CN012K6qWI1hgCG6KwRF7_!!6000000004306-1-tps-1532-792.gif) 然后配置它的行为为“弹窗”: ![Feb-16-2022 20-40-05.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645015223838-7f180e28-43e0-442b-a47e-ea5ff69d4900.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u80f44f38&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-40-05.gif&originHeight=792&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7261162&status=done&style=stroke&taskId=u3828503a-ecac-452a-8d20-02e4a46ad02&title=&width=766) 实现的效果如下: -![Feb-16-2022 20-42-51.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645015379808-7d7852b1-5902-42d0-b951-c9c5d8f4c893.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=ua2e7ceda&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-42-51.gif&originHeight=792&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=588625&status=done&style=stroke&taskId=uf0466dde-ca4c-41d9-bf42-1ff443d02c5&title=&width=767) +![Feb-16-2022 20-42-51.gif](https://img.alicdn.com/imgextra/i4/O1CN018iana91j4l71QTmpE_!!6000000004495-1-tps-1534-792.gif) -## 事件回调 +### 事件回调 上述功能点中,我们是把操作行为绑定在数据列上的,这一节我们绑定到操作列中。在操作列按钮处,点击下方的“添加一项”: ![Feb-23-2022 11-58-02.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645588703676-2a36cab4-52f4-4f31-9018-d56b41a55283.gif#clientId=u74bf469f-47f0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=395&id=u18d8ea0b&margin=%5Bobject%20Object%5D&name=Feb-23-2022%2011-58-02.gif&originHeight=790&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=8440133&status=done&style=stroke&taskId=u73e25800-c0fa-486b-9b68-4df7db9b9f1&title=&width=767) @@ -119,10 +139,10 @@ onClick_new(e, { rowKey, rowIndex, rowRecord }){ } ``` 保存。预览时我们可以看到效果了: -![Feb-23-2022 12-05-25.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645589138764-d6514256-2a1f-4127-9591-747b4808848e.gif#clientId=u74bf469f-47f0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=395&id=u9f09d078&margin=%5Bobject%20Object%5D&name=Feb-23-2022%2012-05-25.gif&originHeight=790&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=2238638&status=done&style=stroke&taskId=u460c90f3-d692-45f9-9028-cf45d4cea98&title=&width=766) -# 研究本例的 schema +![Feb-23-2022 12-05-25.gif](https://img.alicdn.com/imgextra/i3/O1CN01CXi1zJ1N302paKUre_!!6000000001513-1-tps-1532-790.gif) +## 研究本例的 schema 我们把本例的 schema 保存在云端,您可以自行下载研究:[https://mo.m.taobao.com/marquex/lowcode-showcase-table](https://mo.m.taobao.com/marquex/lowcode-showcase-table) 您可以通过左下角的 Schema 面板直接导入本例子的 Schema。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645589288482-0ce8ea2f-c4e1-4956-be9c-143c9b71654b.png#clientId=u74bf469f-47f0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=810&id=u713729c6&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1620&originWidth=3054&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1074154&status=done&style=stroke&taskId=u783f33a5-241d-43ec-8b46-8385b733810&title=&width=1527) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01z2LXgW1iFSklNRzTN_!!6000000004383-2-tps-3054-1620.png) diff --git a/docs/docs/demoUsage/panels/component.md b/docs/docs/demoUsage/panels/component.md index 8147927418..eff0e82c8b 100644 --- a/docs/docs/demoUsage/panels/component.md +++ b/docs/docs/demoUsage/panels/component.md @@ -3,7 +3,8 @@ title: 4. 组件面板详解 sidebar_position: 0 --- ## 概述 -组件面板顾名思义就是承载组件的面板,组件面板会获取并解析传入给低代码引擎的资产包数据(数据结构[点此查看](https://lowcode-engine.cn/assets)),得到需要被展示的组件列表,并根据分类、排序规则对组件进行排列,同时也提供了搜索功能。 +组件面板顾名思义就是承载组件的面板,组件面板会获取并解析传入给低代码引擎的资产包数据 (数据结构[点此查看](https://lowcode-engine.cn/assets)),得到需要被展示的组件列表,并根据分类、排序规则对组件进行排列,同时也提供了搜索功能。 + ![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647964501932-33676243-c42b-4e7c-8663-77c5898d3343.png#clientId=uf38e3cbf-9388-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=438&id=ubb9e4616&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1672&originWidth=3056&originalType=binary&ratio=1&rotation=0&showTitle=true&size=451947&status=done&style=stroke&taskId=u0fc240e1-a792-4bd1-b84d-5bbc8e8fc8b&title=%E7%BB%84%E4%BB%B6%E9%9D%A2%E6%9D%BF&width=800 "组件面板") ## 组件信息 组件面板承载的组件信息有: diff --git a/docs/docs/demoUsage/panels/datasource.md b/docs/docs/demoUsage/panels/datasource.md index 3116f19398..9fbf38f6a1 100644 --- a/docs/docs/demoUsage/panels/datasource.md +++ b/docs/docs/demoUsage/panels/datasource.md @@ -3,8 +3,10 @@ title: 8. 数据源面板详解 sidebar_position: 4 --- ## 🪚 概述 -数据源面板主要负责管理低代码中远程数据源内容,通过可视化编辑的方式操作低代码协议中的数据源Schema,配合 [数据源引擎](https://www.yuque.com/lce/doc/datasource-engine) 即可实现低代码中数据源的生产和消费; +数据源面板主要负责管理低代码中远程数据源内容,通过可视化编辑的方式操作低代码协议中的数据源 Schema,配合 [数据源引擎](/site/docs/guide/design/datasourceEngine) 即可实现低代码中数据源的生产和消费; + ![image.png](https://cdn.nlark.com/yuque/0/2022/png/84508/1648397674378-aec10892-5ee4-414d-807e-39f55f3a5be5.png#clientId=u38847497-05f3-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=821&id=u07e82f8a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1642&originWidth=2878&originalType=binary&ratio=1&rotation=0&showTitle=false&size=246032&status=done&style=none&taskId=uc18acbc5-1404-4266-a499-e952d1084c4&title=&width=1439) + 数据源面板 ## ❓如何使用 > 面板内包含了数据源创建、删除、编辑、排序、导入导出、复制以及搜索等能力,内置支持了 `fecth` & `JSONP`两种常用远程请求类型; @@ -24,11 +26,13 @@ TODO ### 如何定制数据源 #### 定制数据源类型(设计态) #### 定制数据源请求实现(运行态) + > 当出现以下两种情况的时,我们需要定制数据源请求实现, > - 当你默认提供的 `handler`无法满足你的需求 > - 定制了数据源类型,比如 `GraphQL`,需要实现一个对应的 `handler` 接下来我们来看一个例子,如何实现一个 `handler` + ```javascript import { RuntimeOptionsConfig } from '@alilc/lowcode-datasource-types'; @@ -50,9 +54,9 @@ export function createFetchHandler(config?: Record) { }; } ``` -低代码fetch-handler默认实现 +低代码 fetch-handler 默认实现 -以上代码是低代码内置的fetch-handler默认实现,内部使用了 `universal-request`,假如你们内部使用的 `axios`,你完全重新实现一个; +以上代码是低代码内置的 fetch-handler 默认实现,内部使用了 `universal-request`,假如你们内部使用的 `axios`,你完全重新实现一个; ```javascript import axios from 'axios'; export function createAxiosFetchHandler(config?: Record) { @@ -71,10 +75,10 @@ export function createAxiosFetchHandler(config?: Record) { } ``` -##### 注册到render -完成一个Handler后你可以通过以下方式接入到render或者出码中使用 +##### 注册到 render +完成一个 Handler 后你可以通过以下方式接入到 render 或者出码中使用 -###### 渲染Render +###### 渲染 Render ```tsx import React, { memo } from 'react'; import ReactRenderer from '@alilc/lowcode-react-renderer'; @@ -95,11 +99,11 @@ const SamplePreview = memo(() => { }); ``` ###### 出码 -> 目前自定义只能通过重新定义类型来完成,接下来我们会给出码添加requestHandlersMap映射能力;如有需求请联系 荣彬(github-id:xingmolu) +> 目前自定义只能通过重新定义类型来完成,接下来我们会给出码添加 requestHandlersMap 映射能力;如有需求请联系 荣彬 (github-id:xingmolu) ### 设计态启用数据源引擎 -> 默认情况下设计态没有开启数据源引擎,我们可以在设计器init的时候来传递`requstHandlersMap`来开启;具体代码如下: +> 默认情况下设计态没有开启数据源引擎,我们可以在设计器 init 的时候来传递`requstHandlersMap`来开启;具体代码如下: ```javascript import { init, plugins } from '@alilc/lowcode-engine'; @@ -139,12 +143,12 @@ const preference = new Map(); | isInit | 是否为初始数据 | Boolean | ✅ | true | 值为 true 时,将在组件初始化渲染时自动发送当前数据请求 | | isSync | 是否需要串行执行 | Boolean | ✅ | false | 值为 true 时,当前请求将被串行执行 | | type | 数据请求类型 | String | - | fetch | 支持四种类型:fetch/mtop/jsonp/custom | -| shouldFetch | 本次请求是否可以正常请求 | (options: ComponentDataSourceItemOptions) => boolean | - | () => true | function 参数参考 [ComponentDataSourceItemOptions 对象描述](https://lowcode-engine.cn/lowcode#2315-componentdatasourceitemoptions-%E5%AF%B9%E8%B1%A1%E6%8F%8F%E8%BF%B0) | +| shouldFetch | 本次请求是否可以正常请求 | (options: ComponentDataSourceItemOptions) => boolean | - | () => true | function 参数参考 [ComponentDataSourceItemOptions 对象描述](/site/docs/specs/lowcode-spec#2315-componentdatasourceitemoptions-对象描述) | | willFetch | 单个数据结果请求参数处理函数 | Function | - | options => options | 只接受一个参数(options),返回值作为请求的 options,当处理异常时,使用原 options。也可以返回一个 Promise,resolve 的值作为请求的 options,reject 时,使用原 options | -| requestHandler | 自定义扩展的外部请求处理器 | Function | - | - | 仅 type=‘custom’ 时生效 | -| dataHandler | request 成功后的回调函数 | Function | - | response => response.data | 参数: 请求成功后 promise 的 value 值 | -| errorHandler | request 失败后的回调函数 | Function | - | - | 参数: 请求出错 promise 的 error 内容 | -| options {} | 请求参数 | **ComponentDataSourceItemOptions** | - | - | 每种请求类型对应不同参数, 详见 [ComponentDataSourceItemOptions 对象描述](https://lowcode-engine.cn/lowcode#2315-componentdatasourceitemoptions-%E5%AF%B9%E8%B1%A1%E6%8F%8F%E8%BF%B0) | +| requestHandler | 自定义扩展的外部请求处理器 | Function | - | - | 仅 type=‘custom’时生效 | +| dataHandler | request 成功后的回调函数 | Function | - | response => response.data | 参数:请求成功后 promise 的 value 值 | +| errorHandler | request 失败后的回调函数 | Function | - | - | 参数:请求出错 promise 的 error 内容 | +| options {} | 请求参数 | **ComponentDataSourceItemOptions**| - | - | 每种请求类型对应不同参数,详见见 [ComponentDataSourceItemOptions 对象描述](/site/docs/specs/lowcode-spec#2315-componentdatasourceitemoptions-对象描述) | ### 运行时实现层:数据源引擎设计 -[https://www.yuque.com/lce/doc/datasource-engine](https://www.yuque.com/lce/doc/datasource-engine) +[数据源引擎设计](/site/docs/guide/design/datasourceEngine) diff --git a/docs/docs/demoUsage/panels/settings.md b/docs/docs/demoUsage/panels/settings.md index 03c28eabf2..3c62553455 100644 --- a/docs/docs/demoUsage/panels/settings.md +++ b/docs/docs/demoUsage/panels/settings.md @@ -28,23 +28,23 @@ sidebar_position: 2 | BoolSetter | 布尔型数据设置器, | | SelectSetter | 枚举型数据设置器,采用下拉的形式展现 | | VariableSetter | 变量型数据设置器, | -| RadioGroupSetter | 枚举型数据设置器,采用tab选择的形式展现 | +| RadioGroupSetter | 枚举型数据设置器,采用 tab 选择的形式展现 | | TextAreaSetter | 长文本型数据设置器,可换行 | | DateSetter | 日期型数据设置器 | | TimePicker | 时间型数据设置器 | -| DateYearSetter | 日期型-年数据设置器 | -| DateMonthSetter | 日期型-月数据设置器 | +| DateYearSetter | 日期型 - 年数据设置器 | +| DateMonthSetter | 日期型 - 月数据设置器 | | DateRangeSetter | 日期型数据设置器,可选择时间区间 | | EventsSetter | 事件绑定设置器 | | ColorSetter | 颜色设置器 | -| JsonSetter | json型数据设置器 | +| JsonSetter | json 型数据设置器 | | StyleSetter | 样式设置器 | | ClassNameSetter | 样式名设置器 | | FunctionSetter | 函数型数据设置器 | | MixedSetter | 混合型数据设置器 | | SlotSetter | 节点型数据设置器 | | ArraySetter | 列表数组行数据设置器 | -| ObjectSetter | 对象数据设置器,一般内嵌在ArraySetter中 | +| ObjectSetter | 对象数据设置器,一般内嵌在 ArraySetter 中 | # 设置器定制 @@ -60,7 +60,7 @@ interface AltStringSetterProps { value: string; // 默认值 defaultValue: string; - // setter唯一输出 + // setter 唯一输出 onChange: (val: string) => void; // AltStringSetter 特殊配置 placeholder: string; @@ -73,7 +73,7 @@ export default class AltStringSetter extends React.PureComponent { } componentWillUnmount() { - // setter是以实例为单位的,每个setter注销的时候需要把事件也注销掉,避免事件池过多 + // setter 是以实例为单位的,每个 setter 注销的时候需要把事件也注销掉,避免事件池过多 event.off(`${this.emitEventName}.bindEvent`, this.bindEvent) } ``` @@ -115,7 +115,7 @@ import { event } from '@ali/lowcode-engine'; bindFunction = () => { const { field, value } = this.props; - // 这里展示的和插件进行通信,事件规则是插件名+方法 + // 这里展示的和插件进行通信,事件规则是插件名 + 方法 event.emit('eventBindDialog.openDialog', field.name, this.emitEventName); } ``` @@ -125,9 +125,9 @@ setter 本身只影响其中一个 props 的值,如果需要影响其他组件 bindFunction = () => { const { field, value } = this.props; const propsField = field.parent; - // 获取同级其他属性showJump的值 + // 获取同级其他属性 showJump 的值 const otherValue = propsField.getPropValue('showJump'); - // set同级其他属性showJump的值 + // set 同级其他属性 showJump 的值 propsField.setPropValue('showJump', false); } ``` diff --git a/docs/docs/faq/faq003.md b/docs/docs/faq/faq003.md index 96e01c1fd0..74f24b86c4 100644 --- a/docs/docs/faq/faq003.md +++ b/docs/docs/faq/faq003.md @@ -6,12 +6,12 @@ tags: [FAQ] 背景: - [Antd Table 下 button 点击事件怎么拿到行数据?](https://github.com/alibaba/lowcode-engine/issues/341) -## 方式1 +## 方式 1 ![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1657593243427-fb5641b2-4987-475e-88ab-c68d2085edbd.png#clientId=u31b40d04-56f2-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=563&id=u5167bf33&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1126&originWidth=3342&originalType=binary&ratio=1&rotation=0&showTitle=false&size=225551&status=done&style=none&taskId=ud1b89a63-4b6a-4986-a6df-2a463fcf08a&title=&width=1671) -参考 fusion protable , 将操作列直接耦合 button 组件,因为 col.render 函数能拿到 行数据record,那么 pro-table 组件封装的时候,就可以在渲染操作列按钮的时候,将 col.render 参数透传给 button 组件 +参考 fusion protable,将操作列直接耦合 button 组件,因为 col.render 函数能拿到 行数据 record,那么 pro-table 组件封装的时候,就可以在渲染操作列按钮的时候,将 col.render 参数透传给 button 组件 -## 方式2 +## 方式 2 slot + 扩展参数 ![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1657593299698-9628db14-7b48-4c06-9e6f-bda637c209a8.png#clientId=u31b40d04-56f2-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=574&id=u20b07439&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1148&originWidth=3284&originalType=binary&ratio=1&rotation=0&showTitle=false&size=232140&status=done&style=none&taskId=ubc80905d-0607-4e73-9386-5dde706e572&title=&width=1642) diff --git a/docs/docs/faq/faq005.md b/docs/docs/faq/faq005.md index 03efb55b49..6558a67ac2 100644 --- a/docs/docs/faq/faq005.md +++ b/docs/docs/faq/faq005.md @@ -5,7 +5,7 @@ tags: [FAQ] --- ## 设计器 ### 通过引擎 API 配置 -[https://www.yuque.com/lce/doc/dffghx](https://www.yuque.com/lce/doc/dffghx) +[API-init](/site/docs/api/init) ### 通过资产包 @@ -20,4 +20,4 @@ PS:需要在 packages 中有相关的资源配置,例如: 否则在画布中可能会访问不到对应的资源。 ## 预览态 -参考:[https://www.yuque.com/lce/doc/nhilce#appHelper](https://www.yuque.com/lce/doc/nhilce#appHelper) +[参考资料](/site/docs/guide/expand/runtime/renderer#apphelper) diff --git a/docs/docs/faq/faq006.md b/docs/docs/faq/faq006.md index 0553d5122c..5a6334c04d 100644 --- a/docs/docs/faq/faq006.md +++ b/docs/docs/faq/faq006.md @@ -3,4 +3,4 @@ title: 如何通过 API 手动调用数据源请求 sidebar_position: 6 tags: [FAQ] --- -参考:[https://www.yuque.com/lce/doc/erckcn](https://www.yuque.com/lce/doc/erckcn) \ No newline at end of file +参考:[DataSource API](/site/docs/api/datasource) \ No newline at end of file diff --git a/docs/docs/faq/faq007.md b/docs/docs/faq/faq007.md index 175d8c73f2..072444e9a7 100644 --- a/docs/docs/faq/faq007.md +++ b/docs/docs/faq/faq007.md @@ -1,9 +1,9 @@ --- -title: 设置面板中的高级tab如何配置 +title: 设置面板中的高级 tab 如何配置 sidebar_position: 7 tags: [FAQ] --- ![93DC003C-D9A1-4F4F-98A1-F22C0A89EA92.png](https://cdn.nlark.com/yuque/0/2022/png/1053439/1657161085153-a26657ae-2c6e-4124-b9ab-6f8cf8126d1f.png#clientId=u300df630-5bbe-4&crop=0&crop=0&crop=1&crop=1&from=ui&height=591&id=u2ff7824e&margin=%5Bobject%20Object%5D&name=93DC003C-D9A1-4F4F-98A1-F22C0A89EA92.png&originHeight=1714&originWidth=960&originalType=binary&ratio=1&rotation=0&showTitle=false&size=107040&status=done&style=none&taskId=ub377dc1d-db5a-4234-980f-66f7143950d&title=&width=331) -默认这个tab下的内容为引擎内置,如需要定制,可以使用以下API +默认这个 tab 下的内容为引擎内置,如需要定制,可以使用以下 API [https://lowcode-engine.cn/docV2/mu7lml#lIK37](https://lowcode-engine.cn/docV2/mu7lml#lIK37) diff --git a/docs/docs/faq/faq008.md b/docs/docs/faq/faq008.md index c64a09ae22..6fe0780cb6 100644 --- a/docs/docs/faq/faq008.md +++ b/docs/docs/faq/faq008.md @@ -1,7 +1,7 @@ --- -title: 某某npm包对应的源码在哪里? +title: 某某 npm 包对应的源码在哪里? sidebar_position: 8 tags: [FAQ] --- -详见 [NPM包对应源码位置汇总](https://www.yuque.com/lce/doc/ngm44i) \ No newline at end of file +详见 [NPM 包对应源码位置汇总](/site/docs/guide/appendix/npms) \ No newline at end of file diff --git a/docs/docs/faq/faq009.md b/docs/docs/faq/faq009.md index 131dcba6f9..2fe3fa8f63 100644 --- a/docs/docs/faq/faq009.md +++ b/docs/docs/faq/faq009.md @@ -9,7 +9,7 @@ tags: [FAQ] **解决方案** LowCodeEngine 升级到 1.0.8 -> 相关PR:[https://github.com/alibaba/lowcode-engine/pull/383](https://github.com/alibaba/lowcode-engine/pull/383) +> 相关 PR:[https://github.com/alibaba/lowcode-engine/pull/383](https://github.com/alibaba/lowcode-engine/pull/383) ## 编辑态,snippets 和注入组件不对应 diff --git a/docs/docs/faq/faq012.md b/docs/docs/faq/faq012.md index 6c0e61db0b..95dd7d5337 100644 --- a/docs/docs/faq/faq012.md +++ b/docs/docs/faq/faq012.md @@ -87,4 +87,4 @@ const snippets: Snippet[] = [ ``` ### 如何全局生效 -通过 [https://www.yuque.com/lce/doc/mu7lml#LRXhp](https://www.yuque.com/lce/doc/mu7lml#LRXhp) 来修改元数据信息,注意如果有 snippets 相关配置也需要修改相关的配置。 +通过 [registerMetadataTransducer API](/site/docs/api/material#registermetadatatransducer) 来修改元数据信息,注意如果有 snippets 相关配置也需要修改相关的配置。 diff --git a/docs/docs/faq/faq013.md b/docs/docs/faq/faq013.md index 2d8f6f703d..bf073e7334 100644 --- a/docs/docs/faq/faq013.md +++ b/docs/docs/faq/faq013.md @@ -4,7 +4,7 @@ sidebar_position: 13 tags: [FAQ] --- ## 注意 -弹窗的正确弹出方式请参考:[https://www.yuque.com/lce/usage/ozsg2m](https://www.yuque.com/lce/usage/ozsg2m) +弹窗的正确弹出方式请参考:[如何通过按钮展示/隐藏弹窗](/site/docs/demoUsage/makeStuff/dialog) ## 问题原因 由于 hidden 属性,导致 Modal 组件在预览的时候不渲染,也就无法获取到实例。 ## 处理方式 diff --git a/docs/docs/faq/faq015.md b/docs/docs/faq/faq015.md index 02ca139155..48e97bc22f 100644 --- a/docs/docs/faq/faq015.md +++ b/docs/docs/faq/faq015.md @@ -3,5 +3,5 @@ title: 已有组件如何快速接入引擎 sidebar_position: 15 tags: [FAQ] --- -你可以通过在线工具 「Parts造物」生产物料描述协议,然后使用到你的项目中去。 -文档地址:[https://www.yuque.com/lce/xhk5hf/qa9pbx](https://www.yuque.com/lce/xhk5hf/qa9pbx) +你可以通过在线工具「Parts 造物」生产物料描述协议,然后使用到你的项目中去。 +文档地址:[利用 Parts 造物快速使用 react 组件](/site/docs/guide/expand/editor/partsIntro) diff --git a/docs/docs/faq/faq016.md b/docs/docs/faq/faq016.md index bb72e17eca..001a3e9216 100644 --- a/docs/docs/faq/faq016.md +++ b/docs/docs/faq/faq016.md @@ -7,7 +7,7 @@ tags: [FAQ] 需要在资产包中检查是否有下列代码: ```typescript { - "title": "fusion组件库", + "title": "fusion 组件库", "package": "@alifd/next", "version": "1.23.0", "urls": [ diff --git a/docs/docs/guide/appendix/glossary.md b/docs/docs/guide/appendix/glossary.md index e044f3e74d..6c71e99e76 100644 --- a/docs/docs/guide/appendix/glossary.md +++ b/docs/docs/guide/appendix/glossary.md @@ -2,4 +2,4 @@ title: 名词解释 sidebar_position: 0 --- -![glossary](https://cdn.nlark.com/yuque/0/2022/jpeg/2622706/1648103397469-00227a70-e7ab-4a90-8378-c4da977250b2.jpeg) +![glossary](https://img.alicdn.com/imgextra/i2/O1CN01vPZjCM1jT26YujpGk_!!6000000004548-0-tps-2284-4301.jpg) diff --git a/docs/docs/guide/appendix/metaSpec.md b/docs/docs/guide/appendix/metaSpec.md index 6adcc5907e..59bf5e6333 100644 --- a/docs/docs/guide/appendix/metaSpec.md +++ b/docs/docs/guide/appendix/metaSpec.md @@ -2,6 +2,6 @@ title: 搭建组件协议结构 sidebar_position: 1 --- -完整协议请查看:[http://lowcode-engine.cn/material](http://lowcode-engine.cn/material) +完整协议[查看](/site/docs/specs/material-spec) -![](https://cdn.nlark.com/yuque/0/2022/jpeg/2622706/1646040400808-9a4a4d7d-6ad2-43be-8c97-d88f0cab7cc6.jpeg) +![](https://img.alicdn.com/imgextra/i4/O1CN01hozDem1apAhnvdESN_!!6000000003378-0-tps-2474-4128.jpg) diff --git a/docs/docs/guide/appendix/npms.md b/docs/docs/guide/appendix/npms.md index 9334140f48..ce25283e68 100644 --- a/docs/docs/guide/appendix/npms.md +++ b/docs/docs/guide/appendix/npms.md @@ -1,5 +1,5 @@ --- -title: NPM包对应源码位置汇总 +title: NPM 包对应源码位置汇总 sidebar_position: 3 --- | 包名 | 仓库 | 路径 | diff --git a/docs/docs/guide/appendix/repos.md b/docs/docs/guide/appendix/repos.md index b4dbca7ac8..4fbfdc12cb 100644 --- a/docs/docs/guide/appendix/repos.md +++ b/docs/docs/guide/appendix/repos.md @@ -2,7 +2,7 @@ title: 低代码仓库列表 sidebar_position: 2 --- -### 1. 引擎主包 +## 1. 引擎主包 包含引擎的 4 大模块,入料、编排、渲染和出码。 仓库地址:[https://github.com/alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine) @@ -25,7 +25,7 @@ sidebar_position: 2 15. material-parser 16. code-generator -### 2. 引擎官方扩展包 +## 2. 引擎官方扩展包 包含了常用的设置器(setter)、跟 setter 绑定的插件等 仓库地址:[https://github.com/alibaba/lowcode-engine-ext](https://github.com/alibaba/lowcode-engine-ext) @@ -56,7 +56,7 @@ sidebar_position: 2 - 插件 plugin - plugin-event-bind-dialog 事件绑定浮层 - plugin-variable-bind-dialog 变量绑定浮层 -### 3. 低代码插件 +## 3. 低代码插件 包含了常用的插件等 仓库地址:[https://github.com/alibaba/lowcode-plugins](https://github.com/alibaba/lowcode-plugins) @@ -70,18 +70,18 @@ sidebar_position: 2 - plugin-undo-redo 前进/后退功能 - plugin-zh-cn 中英文切换功能 -### 4. 引擎 demo +## 4. 引擎 demo 展示使用引擎编排和渲染等模块以及相应的依赖资源配置基础 demo 仓库地址:[https://github.com/alibaba/lowcode-demo](https://github.com/alibaba/lowcode-demo) -### 5. 工具链包 +## 5. 工具链包 包含生成引擎生态元素(setter、物料、插件)的脚手架,启动脚本,调试插件等 仓库地址:[https://github.com/alibaba/lowcode-tools](https://github.com/alibaba/lowcode-tools) -### 6. 低代码数据源引擎 +## 6. 低代码数据源引擎 负责在渲染&出码两种运行时实现数据源管理,承担低代码搭建数据请求的能力; 仓库地址:[https://github.com/alibaba/lowcode-datasource](https://github.com/alibaba/lowcode-datasource) -### 7. 基础物料 & 物料描述 +## 7. 基础物料 & 物料描述 仓库地址:[https://github.com/alibaba/lowcode-materials](https://github.com/alibaba/lowcode-materials) -### 8. 出码 demo +## 8. 出码 demo 仓库地址:[https://github.com/alibaba/lowcode-code-generator-demo](https://github.com/alibaba/lowcode-code-generator-demo) diff --git a/docs/docs/guide/appendix/setterDetails/array.md b/docs/docs/guide/appendix/setterDetails/array.md index bbbd4498ba..517292e2c2 100644 --- a/docs/docs/guide/appendix/setterDetails/array.md +++ b/docs/docs/guide/appendix/setterDetails/array.md @@ -2,12 +2,12 @@ title: ArraySetter --- -#### 简介 -用来展示属性类型为数组的setter -#### 展示 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395220128-b5d948e3-6a5a-420f-9a7a-a29be25c507d.png#clientId=ud56bf956-0414-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=181&id=u27259ecd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=362&originWidth=584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=27221&status=done&style=none&taskId=u72065990-9557-4dbc-a0ba-eada448e228&title=&width=292) -#### 配置示例 -```javascript +## 简介 +用来展示属性类型为数组的 setter +## 展示 +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01BXCpnh1OFebSSyeDQ_!!6000000001676-2-tps-584-362.png) +## 配置示例 +```json "setter": { "componentName": "ArraySetter", "props": { @@ -18,7 +18,7 @@ title: ArraySetter "items": [{ "name": "title", "description": "标题", - "setter": "StringSetter", + "setter": "StringSetter" }, { "name": "callback", @@ -32,37 +32,36 @@ title: ArraySetter }, "initialValue": { "title": "I am title", - "callback": null, + "callback": null } } } } ``` -#### ArraySetter 配置 +## ArraySetter 配置 + | **属性名** | **类型** | **说明** | | --- | --- | --- | -| itemSetter | ObjectSetter | ArraySetter的子节点内容必须用ObjectSetter包裹 | +| itemSetter | ObjectSetter | ArraySetter 的子节点内容必须用 ObjectSetter 包裹 | + +## itemSetter 配置 -#### itemSetter 配置 | **属性名** | **类型** | **说明** | | --- | --- | --- | -| componentName | String | - | +| componentName | String || | props | | | | initialValue | Object | 新增一项的初始值 | -#### ObjectSetter 配置 +## ObjectSetter 配置 | **属性名** | **类型** | **说明** | | --- | --- | --- | -| descriptor | String | Item在列表中展示的item.key名,需要和 config.items[] 中key对应 默认为 “项目X” -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448651683-6c44787a-cb6c-4066-9a47-2b22f862cb9c.png#clientId=u05af0495-3e67-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=186&id=ufb6e3681&margin=%5Bobject%20Object%5D&name=image.png&originHeight=372&originWidth=640&originalType=binary&ratio=1&rotation=0&showTitle=false&size=103250&status=done&style=none&taskId=u7a61b6f7-4e26-4d8b-a9e6-a30b5e9e73d&title=&width=320) | +| descriptor | String | Item 在列表中展示的 item.key 名,需要和 config.items[] 中key对应 默认为 “项目X” ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01Okz1DY1Q17GGJBPDf_!!6000000001915-2-tps-640-372.png) | | config | Object | 配置项 | | config.items | Array | 子属性列表数据 | | config.items[].name | String | 子属性名称 | | config.items[].description | String | 子属性描述 | | config.items[].setter | Object | String | 子属性setter配置 | 子属性setter组件名 | -| config.items[].isRequired | Boolean | 子属性是否开启快捷编辑,最多开启4个 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448651860-f4f80e87-4e80-463d-a1e0-99be8bf2a84f.png#clientId=u6ba2ab37-e0fb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=211&id=ueea652b0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=422&originWidth=614&originalType=binary&ratio=1&rotation=0&showTitle=false&size=32465&status=done&style=none&taskId=u343405fd-5773-4ebd-b6fc-1367a769fe2&title=&width=307) | +| config.items[].isRequired | Boolean | 子属性是否开启快捷编辑,最多开启4个 ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01EflYAK1IPpiChvjHz_!!6000000000886-2-tps-614-422.png) | | config.items[].condition | Boolean | () => Boolean | 是否展示 | | config.items[].getValue | (target, value) => value | 数据获取的 hook,可修改获取数据 | | config.items[].setValue | (target, value) => value | 数据获取的 hook,可修改设置数据 | diff --git a/docs/docs/guide/appendix/setterDetails/bool.md b/docs/docs/guide/appendix/setterDetails/bool.md index d29274893f..a2851e707b 100644 --- a/docs/docs/guide/appendix/setterDetails/bool.md +++ b/docs/docs/guide/appendix/setterDetails/bool.md @@ -1,15 +1,18 @@ --- title: BoolSetter --- -#### 简介 +## 简介 开关选择器 -#### 展示 -![](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448646757-b61019f4-d502-473a-8a11-4974479c55dc.png#from=url&id=dnn2b&margin=%5Bobject%20Object%5D&originHeight=82&originWidth=320&originalType=binary&ratio=1&status=done&style=none) -#### setter 配置 +## 展示 + +![](https://img.alicdn.com/imgextra/i3/O1CN01KS7ndr1mHX0MITGPH_!!6000000004929-2-tps-320-82.png) +## setter 配置 + | 属性名 | 说明 | | --- | --- | | disabled | 是否可选 | | defaultValue | 默认值 | -#### 返回类型 +## 返回类型 + Boolean diff --git a/docs/docs/guide/appendix/setterDetails/color.md b/docs/docs/guide/appendix/setterDetails/color.md index 8c09f58835..b0b158b901 100644 --- a/docs/docs/guide/appendix/setterDetails/color.md +++ b/docs/docs/guide/appendix/setterDetails/color.md @@ -2,13 +2,15 @@ title: ColorSetter --- 用来选择颜色。 -#### 展示 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448646203-3eb11d27-0195-4608-91f3-0f3cfb6b7140.png#clientId=u09a8f665-5383-4&from=paste&height=416&id=u417e185d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=728&originWidth=590&originalType=binary&ratio=1&size=230281&status=done&style=none&taskId=u3d246b17-94ab-4eb3-af66-3ffb7fd3145&width=337) -#### setter 配置 +## 展示 + + +## setter 配置 | 属性名 | 说明 | | --- | --- | | defaultValue | 默认值 | -#### 返回类型 +## 返回类型 String -会返回options中的value值 + +会返回 options 中的 value 值 diff --git a/docs/docs/guide/appendix/setterDetails/event.md b/docs/docs/guide/appendix/setterDetails/event.md index 26405e9081..b690b308f1 100644 --- a/docs/docs/guide/appendix/setterDetails/event.md +++ b/docs/docs/guide/appendix/setterDetails/event.md @@ -1,20 +1,23 @@ --- title: EventSetter --- -#### 简介 +## 简介 可以将事件绑定在物料上 -#### 展示 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394906292-0eb3ab0e-0bb0-4c8d-bbc5-7217b33cdcab.png#clientId=ub4e2d6f6-4877-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=507&id=u2a295c86&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1014&originWidth=1202&originalType=binary&ratio=1&rotation=0&showTitle=false&size=293824&status=done&style=none&taskId=u37e95d95-4425-450a-b4aa-9805d9dcf97&title=&width=601) +## 展示 + + + +## 组件自带事件列表 + +在物料协议的 configure.supports.events 中声明 -#### 组件自带事件列表 -在物料协议的configure.supports.events 中声明 ```json { "configure ": { "supports": { "style": true, "events": [{ - "name": "onChange", + "name": "onChange" }, { "name": "onExpand" }, { @@ -25,34 +28,38 @@ title: EventSetter } ``` -#### 事件绑定 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448650540-8b403233-44a5-4b1f-9379-2c55d4694f12.png#clientId=uf9b6db87-aae9-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=621&id=u95bb9c9a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1242&originWidth=2540&originalType=binary&ratio=1&rotation=0&showTitle=false&size=356836&status=done&style=none&taskId=u13bc14bd-d85c-46c9-aebd-586dcb32f96&title=&width=1270) -可以选择已有的事件(schema中的**methods**节点)进行绑定,也可以选择新建事件,选择新建事件默认会增加_new的事件后缀命名,点确定以后会跳转到对应代码插件对应区块 -#### -#### 参数设置 -如果需要额外传参,需要将扩展参数设置打开,在代码面板中,编辑参数内容 +## 事件绑定 +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01Q5gHFy1uSzqUeEqQK_!!6000000006037-2-tps-2540-1242.png) + +可以选择已有的事件 (schema 中的**methods**节点) 进行绑定,也可以选择新建事件,选择新建事件默认会增加_new 的事件后缀命名,点确定以后会跳转到对应代码插件对应区块。 + +## 参数设置 + +如果需要额外传参,需要将扩展参数设置打开,在代码面板中,编辑参数内容。 + 注意: - 额外参数必须被包装成一个对象,如参数模板中所示 - 可以使用动态变量例如 (this.items,this.state.xxx) -```json -{ - "testKey":this.state.text -} -``` + ```javascript + { + testKey: this.state.text, + } + ``` -- 该参数是额外参数,会加在原有参数后面,例如在onClick中加入扩展传参,最终函数消费的时候应该如下所示 -```javascript -// e为onClick原有函数传参,extParams为自定义传参 -onClick(e, extParams) { - this.setState({ - isShowDialog: extParams.isShowDialog - }) -} -``` -#### 事件新建函数模板 -有时候我们创建的函数会有用到一些通用的函数模板,我们可以在物料协议的events.template中创建一个模板,如下 -```javascript +- 该参数是额外参数,会加在原有参数后面,例如在 onClick 中加入扩展传参,最终函数消费的时候应该如下所示 + ```javascript + // e 为 onClick 原有函数传参,extParams 为自定义传参 + onClick(e, extParams) { + this.setState({ + isShowDialog: extParams.isShowDialog, + }); + } + ``` +## 事件新建函数模板 +有时候我们创建的函数会有用到一些通用的函数模板,我们可以在物料协议的 events.template 中创建一个模板,如下 + +```json { "configure ": { "supports": { @@ -69,5 +76,7 @@ onClick(e, extParams) { } } ``` + 其中 ${extParams} 为扩展参数占位符,如果用户没有声明扩展参数,会移除对应的参数声明,定义模板后,每次创建完函数会自动生成模板函数,如下图 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448650786-62270a89-65d5-42b1-8efd-90b090155c82.png#clientId=uf9b6db87-aae9-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=141&id=u4bb4387b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=282&originWidth=1292&originalType=binary&ratio=1&rotation=0&showTitle=false&size=84790&status=done&style=none&taskId=u2b911f77-a018-4f17-a5df-36c2c142d18&title=&width=646) + +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01XUoXnS1XiLxlxXniw_!!6000000002957-2-tps-1292-282.png) diff --git a/docs/docs/guide/appendix/setterDetails/icon.md b/docs/docs/guide/appendix/setterDetails/icon.md index 1e98059c3a..ee425f7935 100644 --- a/docs/docs/guide/appendix/setterDetails/icon.md +++ b/docs/docs/guide/appendix/setterDetails/icon.md @@ -1,25 +1,28 @@ --- title: IconSetter --- -#### 简介 +## 简介 用来选择图标 -#### 展示 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394747068-9b8f47e1-06f7-48de-ba73-9ed3d389f913.png#clientId=u144a54e7-b111-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=290&id=uae8bb869&margin=%5Bobject%20Object%5D&name=image.png&originHeight=579&originWidth=1172&originalType=binary&ratio=1&rotation=0&showTitle=false&size=148927&status=done&style=none&taskId=ud281e100-e277-493d-8d4a-0e7b2c1b8f2&title=&width=586) -#### setter 配置 +## 展示 + + +## setter 配置 + | **属性名** | **类型** | **说明** | | --- | --- | --- | -| type | String | 选择器返回类型 -**可选值**: -"string" | "node" | +| type | String | 选择器返回类型 **可选值**: "string" \| "node" | | defaultValue | String | ReactNode | 默认值 | | hasClear | Boolean | 选择器是否显示清除按钮 | -| icons | Array | 自定义icon集合;默认值详见[图标可选值](#SWnNn) | +| icons | Array | 自定义 icon 集合;默认值详见[图标可选值](#图标可选值) | | placeholder | String | 没有值的时候的占位符 | -#### 返回类型 +## 返回类型 + String | ReactNode -#### 图标可选值 -```json + +## 图标可选值 + +```javascript [ 'smile', 'cry', diff --git a/docs/docs/guide/appendix/setterDetails/mixed.md b/docs/docs/guide/appendix/setterDetails/mixed.md index 6ce3df0248..aa8d8ff420 100644 --- a/docs/docs/guide/appendix/setterDetails/mixed.md +++ b/docs/docs/guide/appendix/setterDetails/mixed.md @@ -1,13 +1,15 @@ --- title: MixedSetter --- -#### 简介 -可以让属性同时支持多个setter +## 简介 +可以让属性同时支持多个 setter -#### 展示 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394866233-4b9127cd-3825-4763-9e2a-526ea2b48140.png#clientId=u7c96c5f7-4dd4-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=240&id=u7ca1df47&margin=%5Bobject%20Object%5D&name=image.png&originHeight=480&originWidth=1552&originalType=binary&ratio=1&rotation=0&showTitle=false&size=272344&status=done&style=none&taskId=u07037884-fbf4-411a-be82-29296ad1fb2&title=&width=776) +## 展示 + + + +## 配置 -#### 配置 | **属性名** | **类型** | **说明** | | --- | --- | --- | | setters | Array | SetterName | diff --git a/docs/docs/guide/appendix/setterDetails/number.md b/docs/docs/guide/appendix/setterDetails/number.md index cd4d95ab03..31a05fe0d7 100644 --- a/docs/docs/guide/appendix/setterDetails/number.md +++ b/docs/docs/guide/appendix/setterDetails/number.md @@ -1,11 +1,13 @@ --- title: NumberSetter --- -#### 简介 +## 简介 用于输入数字。 -#### 展示 -![](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448648108-fae36b4c-fb3d-4a4e-b83e-c5233e8bae5d.png#from=url&id=czSyt&margin=%5Bobject%20Object%5D&originHeight=402&originWidth=576&originalType=binary&ratio=1&status=done&style=none) -#### setter 配置 +## 展示 + + + +## setter 配置 | 属性名 | 说明 | | --- | --- | | min, max | 指定最大最小值 | @@ -14,6 +16,7 @@ title: NumberSetter | units | 指定单位 string | | precision | 设置小数位数 number | -#### 返回类型 -#### Number -会返回value值 +## 返回类型 +Number + +会返回 value 值 diff --git a/docs/docs/guide/appendix/setterDetails/radioGroup.md b/docs/docs/guide/appendix/setterDetails/radioGroup.md index 10bbc13f4e..44fb47e981 100644 --- a/docs/docs/guide/appendix/setterDetails/radioGroup.md +++ b/docs/docs/guide/appendix/setterDetails/radioGroup.md @@ -1,24 +1,18 @@ --- title: RadioGroupSetter --- -#### 简介 +## 简介 用于直观的展示选择并选择。 -#### 展示 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395469783-17a5f8b5-112a-420b-a64f-09fffea55067.png#clientId=u8044d585-4c1d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=49&id=ucafe75f2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=98&originWidth=564&originalType=binary&ratio=1&rotation=0&showTitle=false&size=9843&status=done&style=none&taskId=ud3ff8182-f29c-4b81-b4de-e23baa325c1&title=&width=282) -#### setter 配置 +## 展示 + + + +## setter 配置 | 属性名 | 说明 | | --- | --- | | defaultValue | 默认值 | -| options | 传入的数据源, -**参数格式**: -[ -{img: 'url', -value: 'text', -label/title: 'text'}, ... -] -|| -[ 'text', 'text', ...] | +| options | 传入的数据源,**参数格式**: [{img: 'url', value: 'text', label/title: 'text'}, ...] \| [ 'text', 'text', ...] | -#### 返回类型 +## 返回类型 String | Number | Boolean -会返回options中的value值 +会返回 options 中的 value 值 diff --git a/docs/docs/guide/appendix/setterDetails/select.md b/docs/docs/guide/appendix/setterDetails/select.md index 296bafebf1..2e50391941 100644 --- a/docs/docs/guide/appendix/setterDetails/select.md +++ b/docs/docs/guide/appendix/setterDetails/select.md @@ -1,24 +1,20 @@ --- title: SelectSetter --- -#### 简介 +## 简介 用来选择组件。在限定的可选性内进行选择,核心能力是选择 -#### 展示 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395925308-538eb962-f035-43b9-bdb3-ecc5bc9d1e85.png#clientId=u8b43103b-f292-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=301&id=u7a9a7786&margin=%5Bobject%20Object%5D&name=image.png&originHeight=602&originWidth=574&originalType=binary&ratio=1&rotation=0&showTitle=false&size=36601&status=done&style=none&taskId=u089007a6-76ec-44e8-94b5-127a8ba1a51&title=&width=287) -#### setter 配置 +## 展示 + + + +## setter 配置 | 属性名 | 说明 | | --- | --- | -| mode | 选择器模式 - -可选值: -'single', 'multiple', 'tag' | +| mode | 选择器模式 可选值: 'single', 'multiple', 'tag' | | defaultValue | 默认值 | -| options | 传入的数据源, -**参数格式**: -[ -{label/title: '文字', value: 'text'}, ... -] | +| options | 传入的数据源,**参数格式**: [ {label/title: '文字', value: 'text'}, ...] | + +## 返回类型 -#### 返回类型 String | Number | Boolean -会返回options中的value值 +会返回 options 中的 value 值 diff --git a/docs/docs/guide/appendix/setterDetails/slot.md b/docs/docs/guide/appendix/setterDetails/slot.md index 52e3f9f3b4..7559343d52 100644 --- a/docs/docs/guide/appendix/setterDetails/slot.md +++ b/docs/docs/guide/appendix/setterDetails/slot.md @@ -2,92 +2,92 @@ title: SlotSetter --- ## 简介 -通过一个开启一个slot(插槽),可以在物料特定的一个位置渲染一个或者多个节点。slot比较适合物料的局部自定义渲染。 +通过一个开启一个 slot(插槽),可以在物料特定的一个位置渲染一个或者多个节点。slot 比较适合物料的局部自定义渲染。 ## 展示 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448654034-6f527cc2-cf65-4e79-b904-21416800b5b8.png#clientId=u091bb73f-2e93-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=227&id=gAVIU&margin=%5Bobject%20Object%5D&name=image.png&originHeight=454&originWidth=588&originalType=binary&ratio=1&rotation=0&showTitle=false&size=103838&status=done&style=none&taskId=u45d2e179-54ea-40d1-a654-66151c337ff&title=&width=294) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395677385-84c39b6d-2356-4d86-a741-edbb7daffd6c.png#clientId=udcc199c0-6236-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=82&id=u999c2367&margin=%5Bobject%20Object%5D&name=image.png&originHeight=164&originWidth=644&originalType=binary&ratio=1&rotation=0&showTitle=false&size=18486&status=done&style=none&taskId=u6c13f469-173f-4ba0-9bfa-866122ef7a4&title=&width=322) + + +
+
+ + ## setter 配置 | 属性名 | 类型 | 说明 | | --- | --- | --- | -| initialValue | Object | 默认值 -{ -"type": "JSSlot", -"params": [ -"module" - ], -"value": [] -} - -params:接收函数的入参,可以直接在slot节点中消费,通过this.module (这里module是示例值,可根据实际函数入参更改) -value:可以定义一个节点,每次打开插槽的时候默认填充一个节点 - - | -| hideParams | boolean | 是否隐藏入参,注意该值只能隐藏入参的输入框,适合单行展示,实际渲染的时候,还是会传入params的参数,和params:[]不同 | -| checkedText | string | switch选中文案,默认显示"启用" | -| unCheckedText | string | switch取消文案,默认显示"关闭" | +| initialValue | Object | 默认值 { "type": "JSSlot", "params": [ "module" ], "value": [] } params:接收函数的入参,可以直接在slot节点中消费,通过this.module (这里module是示例值,可根据实际函数入参更改) value:可以定义一个节点,每次打开插槽的时候默认填充一个节点 | +| hideParams | boolean | 是否隐藏入参,注意该值只能隐藏入参的输入框,适合单行展示,实际渲染的时候,还是会传入 params 的参数,和 params:[]不同 | +| checkedText | string | switch 选中文案,默认显示"启用" | +| unCheckedText | string | switch 取消文案,默认显示"关闭" | ## 配置示例 -### 普通示例 -#### 配置 +### 配置 + ```typescript { - name: "propName", - title: "propTitle", + name: 'propName', + title: 'propTitle', setter: { - componentName: "SlotSetter", + componentName: 'SlotSetter', isRequired: true, - title: "组件坑位", + title: '组件坑位', initialValue: { - type: "JSSlot", - value: [] + type: 'JSSlot', + value: [], }, } } ``` -#### 组件 +### 组件 + ```typescript function A(props) { return props.propName; } ``` -### 带参数的插槽示例 -#### 配置 +## 带参数的插槽示例 +### 配置 + ```typescript { - name: "propName", - title: "propTitle", - setter: { - componentName: "SlotSetter", - isRequired: true, - title: "组件坑位", - initialValue: { - type: "JSSlot", - params: [ - "module" - ], - value: [] - }, - } + name: 'propName', + title: 'propTitle', + setter: { + componentName: 'SlotSetter', + isRequired: true, + title: '组件坑位', + initialValue: { + type: 'JSSlot', + params: [ 'module'], + value: [], + }, } +} ``` -#### 组件 +### 组件 + 组件需要传参数进行渲染,和普通示例的使用不一样。 + ```typescript function A(props) { - const module = [] + const module = []; return props.propName(module); } ``` -#### param 使用示例 +### param 使用示例 + 1.开启插槽 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652877673290-7a377a36-7da9-40c1-baff-1c7c8ad04a67.png#clientId=udd177887-e136-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=900&id=u9ba2344a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1800&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1291582&status=done&style=none&taskId=u60418282-46e2-46b4-95d2-156288bcbd7&title=&width=1792) + +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01RlOXAV1TbFMBZa6xq_!!6000000002400-2-tps-3584-1800.png) + 2.拖拽组件到插槽中 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652877759606-6de16048-a5d9-477c-b38b-962690a39254.png#clientId=udd177887-e136-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=903&id=u43b38264&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1806&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1230647&status=done&style=none&taskId=u96d44a1e-033f-4cd0-ac81-df6cac8ea18&title=&width=1792) + +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01NNiWLs26961orvk9i_!!6000000007618-2-tps-3584-1806.png) 3.在插槽内组件中使用变量绑定,绑定 this.xxx + xxx 入参的配置 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652877586491-904d6b18-a41a-4ba2-8664-088cd5feca72.png#clientId=udd177887-e136-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=903&id=u165f1564&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1806&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1278387&status=done&style=none&taskId=uc060e73a-b190-480a-8aad-8c20b27290c&title=&width=1792) + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01cBn2ym1XF2cDZo5Yp_!!6000000002893-2-tps-3584-1806.png) diff --git a/docs/docs/guide/appendix/setterDetails/string.md b/docs/docs/guide/appendix/setterDetails/string.md index 77e5aacf49..c30bba7701 100644 --- a/docs/docs/guide/appendix/setterDetails/string.md +++ b/docs/docs/guide/appendix/setterDetails/string.md @@ -1,14 +1,18 @@ --- title: StringSetter --- -#### 简介 +## 简介 + 用来展示和修改字符串类型的属性值,不可换行 -#### 展示 -![](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448645493-4a30f02e-1869-4963-8d39-40501891ae84.png#from=url&id=mEkyy&margin=%5Bobject%20Object%5D&originHeight=88&originWidth=714&originalType=binary&ratio=1&status=done&style=none) -#### setter 配置 +## 展示 + + + +## setter 配置 + | 属性名 | 说明 | | --- | --- | | placeholder | 输入提示 | -#### 返回类型 +## 返回类型 String diff --git a/docs/docs/guide/appendix/setterDetails/style.md b/docs/docs/guide/appendix/setterDetails/style.md index f733baaa36..c58f062f52 100644 --- a/docs/docs/guide/appendix/setterDetails/style.md +++ b/docs/docs/guide/appendix/setterDetails/style.md @@ -2,48 +2,27 @@ title: StyleSetter --- ## 简介 -通过开启StyleSetter,我们可以将样式配置面板来配置样式属性。 +通过开启 StyleSetter,我们可以将样式配置面板来配置样式属性。 ## 展示 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1658650544358-3d97f6b1-6269-4627-ab4a-62a43219fd08.png#clientId=u5d06f6c0-ba35-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=739&id=u3f141635&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1478&originWidth=596&originalType=binary&ratio=1&rotation=0&showTitle=false&size=75996&status=done&style=none&taskId=u16f49c5d-a32e-4cf8-95ab-e0c1059fbef&title=&width=298) + + ## setter 配置 | 属性名 | 类型 | 说明 | | --- | --- | --- | -| unit | String | 默认值 px -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1658650635878-fd920e86-ea28-4e08-8676-238ac367a0ee.png#clientId=u5d06f6c0-ba35-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=49&id=u3f243c11&margin=%5Bobject%20Object%5D&name=image.png&originHeight=98&originWidth=576&originalType=binary&ratio=1&rotation=0&showTitle=false&size=9796&status=done&style=none&taskId=ucc541aa4-0765-4da9-820c-cee48ed0635&title=&width=288) - | -| placeholderScale | Number | 默认计算尺寸缩放 默认值为1 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1658650773475-7ecba070-c81e-4a6c-b346-7aad7dd6a897.png#clientId=u5d06f6c0-ba35-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=49&id=u27842257&margin=%5Bobject%20Object%5D&name=image.png&originHeight=98&originWidth=250&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7116&status=done&style=none&taskId=u8ac18c79-d14b-49a6-8788-476524e69da&title=&width=125) -在没有设定数值的时候,系统会通过window.getComputedStyle来计算展示的数值。 -在某些场景下,例如手机场景,在编辑器展示的是375的实际宽度,但是实际设计尺寸是750的宽度,这个时候需要对这个计算尺寸设成2 | -| showModuleList | String[] | 默认值 -['background', 'border', 'font', 'layout', 'position'] -分别对应背景、边框、文字、布局、位置五个区块,可以针对不同的场景按需进行展示。 -例如文字的组件,我不需要修改边框的样式,就可以把边框模块隐藏掉 | +| unit | String | 默认值 px | +| placeholderScale | Number | 默认计算尺寸缩放 默认值为 1 在没有设定数值的时候,系统会通过 window.getComputedStyle 来计算展示的数值。在某些场景下,例如手机场景,在编辑器展示的是 375 的实际宽度,但是实际设计尺寸是 750 的宽度,这个时候需要对这个计算尺寸设成 2 | +| showModuleList | String[] | 默认值 ['background', 'border', 'font', 'layout', 'position'] 分别对应背景、边框、文字、布局、位置五个区块,可以针对不同的场景按需进行展示。 例如文字的组件,我不需要修改边框的样式,就可以把边框模块隐藏掉 | | isShowCssCode | Boolean | 默认值: true, 是否展示css源码编辑 | | layoutPropsConfig | Object | 布局样式设置 | -| layoutPropsConfig.showDisPlayList | String[] | 默认值 ['inline', 'flex', 'block', 'inline-block', 'none'] -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1658651295786-48ca3773-1b4e-4f2e-9521-0ebbfcfe5361.png#clientId=u5d06f6c0-ba35-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=36&id=u50dae00c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=72&originWidth=474&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7621&status=done&style=none&taskId=ub5804835-d0b2-45d7-a419-66ac1005afa&title=&width=237) -可按需展示 - | -| layoutPropsConfig.isShowPadding | String | 默认值 true -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1658651496157-c84348d4-a47f-44b4-b2c5-74b21e97747a.png#clientId=u5d06f6c0-ba35-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=191&id=u70235603&margin=%5Bobject%20Object%5D&name=image.png&originHeight=382&originWidth=548&originalType=binary&ratio=1&rotation=0&showTitle=false&size=20439&status=done&style=none&taskId=udae33336-ce05-41a9-89c5-361a63d061a&title=&width=274) -是否展示内边距 (四个边) | -| layoutPropsConfig.isShowMargin | Boolean | 默认值 true -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1658651539776-090de3e1-6293-4660-b74f-9bcf027381c6.png#clientId=u5d06f6c0-ba35-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=241&id=uab3771c7&margin=%5Bobject%20Object%5D&name=image.png&originHeight=482&originWidth=536&originalType=binary&ratio=1&rotation=0&showTitle=false&size=29325&status=done&style=none&taskId=uc287d55d-5363-4b37-978b-6e150f36141&title=&width=268) -是否展示外边距 (四个边) | -| layoutPropsConfig.isShowWidthHeight | Boolean | 默认值 true -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1658651621765-06e81934-9a90-4290-89dd-75ffb56808a5.png#clientId=u5d06f6c0-ba35-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=51&id=u02aa5918&margin=%5Bobject%20Object%5D&name=image.png&originHeight=102&originWidth=546&originalType=binary&ratio=1&rotation=0&showTitle=false&size=9945&status=done&style=none&taskId=u394451ef-266c-440d-a86e-fc1a01320ea&title=&width=273) -是否展示宽高 | +| layoutPropsConfig.showDisPlayList | String[] | 默认值 ['inline', 'flex', 'block', 'inline-block', 'none'] 可按需展示 | +| layoutPropsConfig.isShowPadding | String | 默认值 true 是否展示内边距(四个边) || +| layoutPropsConfig.isShowMargin | Boolean | 默认值 true 是否展示外边距(四个边) || +| layoutPropsConfig.isShowWidthHeight | Boolean | 默认值 true 是否展示宽高 | | fontPropsConfig | Object | 文字样式设置 | -| fontPropsConfig.fontFamilyList | Array | [ - { value: 'Helvetica', label: 'Helvetica' }, - { value: 'Arial', label: 'Arial' }, - { value: 'serif', label: 'serif' }, - ] -可以定制文字字体选项 | +| fontPropsConfig.fontFamilyList | Array | [ { value: 'Helvetica', label: 'Helvetica' }, { value: 'Arial', label: 'Arial' },] 可以定制文字字体选项 | | positionPropsConfig | Object | 位置样式设置 | -| positionPropsConfig.isShowFloat | Boolean | 默认true 是否展示浮动 | -| positionPropsConfig.isShowClear | Boolean | 默认true 是否展示清除浮动 | +| positionPropsConfig.isShowFloat | Boolean | 默认 true 是否展示浮动 | +| positionPropsConfig.isShowClear | Boolean | 默认 true 是否展示清除浮动 | diff --git a/docs/docs/guide/appendix/setterDetails/textArea.md b/docs/docs/guide/appendix/setterDetails/textArea.md index 9188012f85..eff698b3da 100644 --- a/docs/docs/guide/appendix/setterDetails/textArea.md +++ b/docs/docs/guide/appendix/setterDetails/textArea.md @@ -1,14 +1,16 @@ --- -title: StyleSetter +title: TextAreaSetter --- -#### 简介 +## 简介 表单输入组件。 -#### 展示 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395839676-9feaa4d6-dbec-40c0-a93c-6014006a50c5.png#clientId=u01f23b13-e688-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=146&id=u29c456c5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=292&originWidth=1026&originalType=binary&ratio=1&rotation=0&showTitle=false&size=304205&status=done&style=none&taskId=u83ca85c2-3a04-4c41-a055-31d1bb86d84&title=&width=513) -#### setter 配置 +## 展示 + + + +## setter 配置 | **属性名** | **类型** | **说明** | | --- | --- | --- | | placeholder | String | 输入提示 | -#### 返回类型 +## 返回类型 String diff --git a/docs/docs/guide/appendix/setterDetails/variable.md b/docs/docs/guide/appendix/setterDetails/variable.md index 88e46e0cda..ed7d78c5b2 100644 --- a/docs/docs/guide/appendix/setterDetails/variable.md +++ b/docs/docs/guide/appendix/setterDetails/variable.md @@ -1,12 +1,16 @@ --- title: VariableSetter --- -#### 简介 +## 简介 + 用来给属性值设定变量 -#### 展示 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395534301-67aaf74b-2561-4682-a0b2-dcde642a8d7c.png#clientId=u46178fa3-bc0c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=46&id=ucd7e6f91&margin=%5Bobject%20Object%5D&name=image.png&originHeight=92&originWidth=578&originalType=binary&ratio=1&rotation=0&showTitle=false&size=10671&status=done&style=none&taskId=u854e606f-bbd1-42f4-81a2-d161aa4e2d3&title=&width=289) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643448653288-1b5b46c8-5ea1-455d-9ce4-19abade13b31.png#clientId=udec6352b-e220-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=595&id=u2395a6a5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1190&originWidth=1564&originalType=binary&ratio=1&rotation=0&showTitle=false&size=256705&status=done&style=none&taskId=u3f3418f8-b6ad-464e-8fe6-89586fbc07d&title=&width=782) -#### -#### 变量列表 -包含所有的在协议中的**state**(state属性)节点数据和**methods**(自定义处理函数)节点数据 +## 展示 + + +
+ + + +## 变量列表 +包含所有的在协议中的**state**(state 属性) 节点数据和**methods**(自定义处理函数) 节点数据 diff --git a/docs/docs/guide/appendix/setters.md b/docs/docs/guide/appendix/setters.md index 381ef8198d..fe578eee68 100644 --- a/docs/docs/guide/appendix/setters.md +++ b/docs/docs/guide/appendix/setters.md @@ -4,38 +4,26 @@ sidebar_position: 4 --- | 预置 Setter | 返回类型 | 用途 | 截图 | | --- | --- | --- | --- | -| [ArraySetter](https://www.yuque.com/lce/doc/eiegwf?view=doc_embed&from=kb&from=kb&outline=1&title=1) | T[] | 列表数组行数据设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395227012-97d27c4d-e053-4aae-9de1-726015081a4d.png#crop=0&crop=0&crop=1&crop=1&from=url&id=MHREr&margin=%5Bobject%20Object%5D&originHeight=362&originWidth=584&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | -| [BoolSetter](https://www.yuque.com/lce/doc/mdxryw?view=doc_embed&from=kb&from=kb&outline=1&title=1) | boolean | 布尔型数据设置器, | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394538926-81adaab2-fe44-4cf4-93a0-4f46d790cfc6.png#crop=0&crop=0&crop=1&crop=1&from=url&id=yVcL4&margin=%5Bobject%20Object%5D&originHeight=82&originWidth=320&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | -| ClassNameSetter | string | 样式名设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/2553587/1644417220734-fd13e249-43f0-4caa-8122-9c1a791cd30f.png#crop=0&crop=0&crop=1&crop=1&from=url&id=RNQQQ&margin=%5Bobject%20Object%5D&originHeight=180&originWidth=502&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | -| [ColorSetter](https://www.yuque.com/lce/doc/hu5ir6?view=doc_embed&from=kb&from=kb&outline=1&title=1) | string | 颜色设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394553552-2c8c3982-1671-47b3-a569-297bcb838b79.png#crop=0&crop=0&crop=1&crop=1&from=url&id=CxWyj&margin=%5Bobject%20Object%5D&originHeight=728&originWidth=590&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | -| DateMonthSetter | - | 日期型-月数据设置器 | - | -| DateRangeSetter | - | 日期型数据设置器,可选择时间区间 | - | -| DateSetter | - | 日期型数据设置器 | - | -| DateYearSetter | - | 日期型-年数据设置器 | - | -| [EventSetter](https://www.yuque.com/lce/doc/fiu8cz?view=doc_embed&from=kb&from=kb&outline=1&title=1) | function | 事件绑定设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394913684-e50d5fb4-50f4-4f6a-b5f8-5a6269b56676.png#crop=0&crop=0&crop=1&crop=1&from=url&id=lCP5h&margin=%5Bobject%20Object%5D&originHeight=1014&originWidth=1202&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | -| [IconSetter](https://www.yuque.com/lce/doc/ry138x?view=doc_embed&from=kb&from=kb&outline=1&title=1) | string | 图标设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394768487-d7b9a492-254e-46bd-a755-f8f73d76b932.png#crop=0&crop=0&crop=1&crop=1&from=url&id=pbQvJ&margin=%5Bobject%20Object%5D&originHeight=579&originWidth=1172&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | -| FunctionSetter | any | 函数型数据设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/2553587/1644417386132-50215eb0-ca7e-499b-8ca8-bd0b19ce89e1.png#crop=0&crop=0&crop=1&crop=1&from=url&id=YZ16c&margin=%5Bobject%20Object%5D&originHeight=110&originWidth=794&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | -| JsonSetter | object | json型数据设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/2553587/1644418044457-a50b1621-090a-440d-9735-b3e9b7b3abd8.png#crop=0&crop=0&crop=1&crop=1&from=url&id=OywYO&margin=%5Bobject%20Object%5D&originHeight=1068&originWidth=1076&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | -| [MixedSetter](https://www.yuque.com/lce/doc/ah6o2c?view=doc_embed&from=kb&from=kb&outline=1&title=1) | any | 混合型数据设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394872594-bb8f8de1-824a-4ba7-8b83-e408434a7d29.png#crop=0&crop=0&crop=1&crop=1&from=url&id=it6Xz&margin=%5Bobject%20Object%5D&originHeight=480&originWidth=1552&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | -| [NumberSetter](https://www.yuque.com/lce/doc/hk65u5?view=doc_embed&from=kb&from=kb&outline=1&title=1) | number | 数值型数据设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644394982613-b1a43863-fd63-4bb4-b5fe-2f36109c449b.png#crop=0&crop=0&crop=1&crop=1&from=url&id=bEZjH&margin=%5Bobject%20Object%5D&originHeight=328&originWidth=1152&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | -| ObjectSetter | Record | 对象数据设置器,一般内嵌在ArraySetter中 | - | -| [RadioGroupSetter](https://www.yuque.com/lce/doc/cmpf0b?view=doc_embed&from=kb&from=kb&outline=1&title=1) | string | number | boolean | 枚举型数据设置器,采用tab选择的形式展现 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395460363-1fdb034c-69d7-404d-9226-37f1d4562210.png#crop=0&crop=0&crop=1&crop=1&from=url&id=XSyl3&margin=%5Bobject%20Object%5D&originHeight=98&originWidth=564&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | -| [SelectSetter](https://www.yuque.com/lce/doc/po1t1r?view=doc_embed&from=kb&from=kb&outline=1&title=1) | string | number | boolean | 枚举型数据设置器,采用下拉的形式展现 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395970016-dfe95495-53b1-4f86-afc6-a0c621917440.png#crop=0&crop=0&crop=1&crop=1&from=url&id=NPzvg&margin=%5Bobject%20Object%5D&originHeight=282&originWidth=582&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | -| [SlotSetter](https://www.yuque.com/lce/doc/af5vba?view=doc_embed&from=kb&from=kb&outline=1&title=1) | Element | Element[] | 节点型数据设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395692198-ca0cb611-0b7b-43b2-9f3b-3f6983cc3b37.png#crop=0&crop=0&crop=1&crop=1&from=url&id=SLNSR&margin=%5Bobject%20Object%5D&originHeight=164&originWidth=644&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | -| [StringSetter](https://www.yuque.com/lce/doc/qogni4?view=doc_embed&from=kb&from=kb&outline=1&title=1) | string | 短文本型数据设置器,不可换行 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395613012-e7e5db32-9281-4f19-a18d-284765cd1184.png#crop=0&crop=0&crop=1&crop=1&from=url&id=OySEz&margin=%5Bobject%20Object%5D&originHeight=102&originWidth=414&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | -| StyleSetter | - | 样式设置器 | ![](https://cdn.nlark.com/yuque/0/2022/png/2553587/1644416984306-00aca829-3611-4f4c-b6b6-a20d0da0bfe7.png#crop=0&crop=0&crop=1&crop=1&from=url&id=aWlAc&margin=%5Bobject%20Object%5D&originHeight=1214&originWidth=788&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | -| [TextAreaSetter](https://www.yuque.com/lce/doc/gp36z6?view=doc_embed&from=kb&from=kb&outline=1&title=1) | string | 长文本型数据设置器,可换行 | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395843901-4d9c3e04-f6fc-4d50-93ed-44e6d8a99b9a.png#crop=0&crop=0&crop=1&crop=1&from=url&id=grvEZ&margin=%5Bobject%20Object%5D&originHeight=292&originWidth=1026&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | -| TimePicker | - | 时间型数据设置器 | - | -| [VariableSetter](https://www.yuque.com/lce/doc/lkvb36?view=doc_embed&from=kb&from=kb&outline=1&title=1) | any | 变量型数据设置器, | ![](https://cdn.nlark.com/yuque/0/2022/png/242652/1644395524553-dba00e02-f44c-429f-a8f4-c0e5f6d8b35f.png#crop=0&crop=0&crop=1&crop=1&from=url&id=L5BHL&margin=%5Bobject%20Object%5D&originHeight=92&originWidth=578&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) | +| [ArraySetter](./setterDetails/array) | T[] | 列表数组行数据设置器 | ![](https://img.alicdn.com/imgextra/i1/O1CN01UNmb7429mtHsbTHg3_!!6000000008111-2-tps-584-362.png) | +| [BoolSetter](./setterDetails/behavior) | boolean | 布尔型数据设置器, | ![](https://img.alicdn.com/imgextra/i2/O1CN01gZlHyx24MiZfjU61A_!!6000000007377-2-tps-320-82.png) | +| ClassNameSetter | string | 样式名设置器 | ![](https://img.alicdn.com/imgextra/i3/O1CN01ResoVi1PtKWxwuww8_!!6000000001898-2-tps-502-180.png) | +| [ColorSetter](./setterDetails/color) | string | 颜色设置器 | ![](https://img.alicdn.com/imgextra/i4/O1CN018gsNdw1Qt9zsZWP9K_!!6000000002033-2-tps-590-728.png) | +| DateMonthSetter | | 日期型 - 月数据设置器 | | +| DateRangeSetter | | 日期型数据设置器,可选择时间区间 | | +| DateSetter | | 日期型数据设置器 | | +| DateYearSetter || 日期型 - 年数据设置器 | | +| [EventSetter](./setterDetails/event) | function | 事件绑定设置器 | ![](https://img.alicdn.com/imgextra/i4/O1CN01qxIYiO1ksVknhTpnW_!!6000000004739-2-tps-1202-1014.png) | +| [IconSetter](./setterDetails/icon) | string | 图标设置器 | ![](https://img.alicdn.com/imgextra/i3/O1CN01zsOMxo1TXaBmjHCRc_!!6000000002392-2-tps-1172-579.png) | +| FunctionSetter | any | 函数型数据设置器 | ![](https://img.alicdn.com/imgextra/i4/O1CN01jLiJBo1ZIp7OmDLp0_!!6000000003172-2-tps-794-110.png) | +| JsonSetter | object | json 型数据设置器 | ![](https://img.alicdn.com/imgextra/i2/O1CN01mQTFjY1YiBQzWYj64_!!6000000003092-2-tps-1076-1068.png) | +| [MixedSetter](./setterDetails/mixed) | any | 混合型数据设置器 | ![](https://img.alicdn.com/imgextra/i1/O1CN01ZxomFY1JW4j7wIGuQ_!!6000000001035-2-tps-1552-480.png) | +| [NumberSetter](./setterDetails/number) | number | 数值型数据设置器 | ![](https://img.alicdn.com/imgextra/i3/O1CN01dSfSgg1WS2EpbqJIO_!!6000000002786-2-tps-1152-328.png) | +| ObjectSetter | Record | 对象数据设置器,一般内嵌在 ArraySetter 中 || +| [RadioGroupSetter](./setterDetails/radioGroup)| string | number | boolean | 枚举型数据设置器,采用 tab 选择的形式展现 || ![](https://img.alicdn.com/imgextra/i4/O1CN01Z0Zgi51W10s5L2Hce_!!6000000002727-2-tps-564-98.png) | +| [SelectSetter](./setterDetails/select) | string | number | boolean | 枚举型数据设置器,采用下拉的形式展现 | ![](https://img.alicdn.com/imgextra/i1/O1CN01sfUEgZ1I0BXCl60LM_!!6000000000830-2-tps-582-282.png) | +| [SlotSetter](./setterDetails/slot) | Element | Element[] | 节点型数据设置器 | ![](https://img.alicdn.com/imgextra/i3/O1CN01wulNGt1qNip0IlEsF_!!6000000005484-2-tps-644-164.png) | +| [StringSetter](./setterDetails/string) | string | 短文本型数据设置器,不可换行 | ![](https://img.alicdn.com/imgextra/i4/O1CN01iYalzO1xVh1ikLvSr_!!6000000006449-2-tps-414-102.png) | +| StyleSetter || 样式设置器 | ![](https://img.alicdn.com/imgextra/i4/O1CN01ZwX2pO26UAFKuYfuF_!!6000000007664-2-tps-788-1214.png) | +| [TextAreaSetter](./setterDetails/textArea) | string | 长文本型数据设置器,可换行 | ![](https://img.alicdn.com/imgextra/i4/O1CN01GMu8YJ1nqAZoYQ3xi_!!6000000005140-2-tps-1026-292.png) | +| TimePicker | | 时间型数据设置器 || +| [VariableSetter](./setterDetails/variable) | any | 变量型数据设置器, | ![](https://img.alicdn.com/imgextra/i1/O1CN015V5AAY1v3B8XxQ75k_!!6000000006116-2-tps-578-92.png) | diff --git a/docs/docs/guide/create/_category_.json b/docs/docs/guide/create/_category_.json index a5b30e0636..a4ace0accd 100644 --- a/docs/docs/guide/create/_category_.json +++ b/docs/docs/guide/create/_category_.json @@ -1,5 +1,5 @@ { - "label": "创建低代码应用", + "label": "创建低代码编辑器", "position": 1, "collapsed": false, "collapsible": true diff --git a/docs/docs/guide/create/useEditor.md b/docs/docs/guide/create/useEditor.md index aca9faf682..992827eb12 100644 --- a/docs/docs/guide/create/useEditor.md +++ b/docs/docs/guide/create/useEditor.md @@ -8,39 +8,50 @@ sidebar_position: 0 1. clone 低代码项目的官方 demo,直接启动项目。适合普通人。 2. 手工引入低代码 UMD 包,手工配置、打包和启动。适合 Webpack 配置工程师。 -# 方法 1: Clone 并启动 +## 方法 1: 以官方 Demo 为基础使用 可以通过两种方式之一获取低代码编辑器的示例代码: 1. 直接[在 github 仓库下](https://github.com/alibaba/lowcode-demo)进行下载 -![Rectangle 2.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645178084931-b81f6960-f0be-4695-ae38-e2632c859629.png#clientId=u6721b06e-9fb2-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=259&id=ud829c08c&margin=%5Bobject%20Object%5D&name=Rectangle%202.png&originHeight=517&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&size=163331&status=done&style=none&taskId=ua56b6104-b23f-4dd6-a95c-4fa8ac8cb3c&title=&width=750) + ![](https://img.alicdn.com/imgextra/i3/O1CN01PfGV3h1oJ1Wv3sakc_!!6000000005203-2-tps-1500-517.png) 2. 如果本地安装了 git,可以通过 git clone 方式进行下载 (这个方法的好处是 demo 有了更新,可以通过 merge 方式跟上) -```typescript -git clone https://github.com/alibaba/lowcode-demo.git -``` + ```bash + git clone https://github.com/alibaba/lowcode-demo.git + ``` 拉取仓库代码后,需要进行如下配置或安装过程: 1. 确保本地安装了 Node.js 和 npm,如果没有,[您可以通过 nvm 进行快捷的安装](https://github.com/nvm-sh/nvm) 2. 确保为 npm [设置了可以访问的 npm 源,保证安装过程无网络问题](https://npmmirror.com/) -3. 执行 `npm install` - -依赖完全安装完成后,执行 `npm start`,如果看到这个界面,说明项目启动成功。您可以继续看后续章节了。本章节后续内容均为高级配置方式。 - -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644982015764-35bb5f58-fbd6-4838-9792-3c5b2136162d.png#clientId=ub335956d-fdf2-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=817&id=u01bca493&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1634&originWidth=3060&originalType=binary&ratio=1&rotation=0&showTitle=false&size=216709&status=done&style=stroke&taskId=u467c43dc-35c5-4c84-907d-d6db9a0b839&title=&width=1530) - -# 方法 2: 手工引入低代码 UMD 包,手工配置打包和启动 +3. 选择目录下其中一个 demo 工程进入,建议选择 `demo-general` + ```bash + cd demo-general + ``` +4. 安装依赖 + ```bash + npm install + ``` +5. 安装依赖成功后,启动项目 (注意观察上一步的输出,如有 error 等失败信息,请先进行排查) + ```bash + npm start + ``` + 执行后如果看到这个界面,说明项目启动成功。您可以继续看后续章节了。本章节后续内容均为高级配置方式。 + + ![image.png](https://img.alicdn.com/imgextra/i4/O1CN013qJVoV1OAcFNKFrIQ_!!6000000001665-2-tps-3060-1634.png) + +## 方法 2: 使用 UMD 包方式配置 如果您不是从零开始的项目,您可能需要手工引入低代码引擎。 -## 引入 UMD 包资源 +### 引入 UMD 包资源 我们需要在启动前,正确在项目中通过 UMD 包方式直接依赖如下内容: -(亦可使用异步加载工具,如果您按照正确的顺序进行加载) +> 亦可使用异步加载工具,如果您按照正确的顺序进行加载 + ```html @@ -72,9 +83,9 @@ git clone https://github.com/alibaba/lowcode-demo.git > 注:如果 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) -## 配置打包 +### 配置打包 -因为这些资源已经通过 UMD 方式引入,所以在 Webpack 等构建工具中需要配置它们为 external,不再重复打包: +因为这些资源已经通过 UMD 方式引入,所以在 webpack 等构建工具中需要配置它们为 external,不再重复打包: ```javascript { @@ -84,20 +95,16 @@ git clone https://github.com/alibaba/lowcode-demo.git "prop-types": "var window.PropTypes", "@alifd/next": "var window.Next", "@alilc/lowcode-engine": "var window.AliLowCodeEngine", - "@alilc/lowcode-editor-core": "var window.AliLowCodeEngine.common.editorCabin", - "@alilc/lowcode-editor-skeleton": "var window.AliLowCodeEngine.common.skeletonCabin", - "@alilc/lowcode-designer": "var window.AliLowCodeEngine.common.designerCabin", "@alilc/lowcode-engine-ext": "var window.AliLowCodeEngineExt", - "@ali/lowcode-engine": "var window.AliLowCodeEngine", "moment": "var window.moment", "lodash": "var window._" } } ``` -## 初始化低代码编辑器 +### 初始化低代码编辑器 -### 方法 2.1 使用 init 进行初始化 +#### 方法 2.1 使用 init 进行初始化 正确引入后,我们可以直接通过 window 上的变量进行引用,如 `window.AliLowCodeEngine.init`。您可以直接通过此方式初始化低代码引擎: @@ -114,11 +121,12 @@ window.AliLowCodeEngine.init(document.getElementById('lce-container'), { // package.json { "devDependencies": { - "@alilc/lowcode-engine": "beta" + "@alilc/lowcode-engine": "^1.0.0" } } ``` ```javascript +// src/index.tsx import { init } from '@alilc/lowcode-engine'; init(document.getElementById('lce-container'), { @@ -133,52 +141,61 @@ init 的功能包括但不限于: 2. 传递 preference 并设置 plugins 入参; 3. 初始化 Workbench; -> 本节中的低代码编辑器例子可以在 demo 中找到:[https://github.com/alibaba/lowcode-demo/blob/main/src/index.ts#L21-L34](https://github.com/alibaba/lowcode-demo/blob/main/src/index.ts#L21-L34) +> 本节中的低代码编辑器例子可以在 demo 中找到:[https://github.com/alibaba/lowcode-demo/blob/main/demo-general/src/index.ts](https://github.com/alibaba/lowcode-demo/blob/main/demo-general/src/index.ts) -### 方法 2.2 使用 skeletonCabin.Workbench 方式初始化 +#### 方法 2.2 使用 skeletonCabin.Workbench 方式初始化 `init()` 内部会调用 `ReactDOM.render()` 函数,因此这样初始化的内容没有办法与外部的 React 组件进行通信,也就没有办法在一些自定义的 plugin 中获取 redux 上的全局数据等内容。 + 因此,这种场景下您可以通过 `skeletonCabin.Workbench` 进行初始化。 -> 注:您不需要同时使用 2.1 和 2.2 的方法。根据使用场景,只有需要低代码引擎插件和外界进行一定通信时,2.2 提供的方法才是必要的。 +> 注:**不需要**同时使用 2.1 和 2.2 的方法。根据使用场景,当且只当有需要插件和外界进行一定通信时,才需要使用 2.2 提供的方法。 ```javascript -import React, { useState, useEffect } from 'react' -import { project, plugins, common, skeleton } from '@alilc/lowcode-engine' +import React, { useState, useEffect } from 'react'; +import { project, plugins, common, skeleton } from '@alilc/lowcode-engine'; -// 此 schema 参考 demo 中的默认 schema 书写 -import userSchema from './schema.json' +// 此处略去若干依赖引用 -export default function EditorView() { +async function registerPlugins() { + // 此处略去若干插件注册 +} +function EditorView() { /** 插件是否已初始化成功,因为必须要等插件初始化后才能渲染 Workbench */ const [hasPluginInited, setHasPluginInited] = useState(false); useEffect(() => { plugins.init().then(() => { - setHasPluginInited(true) - }).catch(err => console.error(err)) + setHasPluginInited(true); + }).catch(err => console.error(err)); }, []); - useEffect(() => { - project.importSchema(userSchema) - }, [userSchema]); - if (!hasPluginInited) { return null; } - - return ( - - ); + const Workbench = common.skeletonCabin.Workbench; + return ; } + +(async function main() { + await registerPlugins(); + config.setConfig({ + enableCondition: true, + enableCanvasLock: true, + supportVariableGlobally: true, + requestHandlersMap: { + fetch: createFetchHandler() + } + }); + + ReactDOM.render(, document.getElementById('lce-container')!); +})(); ``` -> 本节中的低代码编辑器类似的例子可以在 demo 中找到:[https://github.com/alibaba/lowcode-demo/blob/main/src/scenarios/custom-initialization/index.tsx](https://github.com/alibaba/lowcode-demo/blob/main/src/scenarios/custom-initialization/index.tsx) +> 本节中的低代码编辑器类似的例子可以在 demo 中找到:[https://github.com/alibaba/lowcode-demo/blob/main/demo-custom-initialization/src/index.tsx](https://github.com/alibaba/lowcode-demo/blob/main/demo-custom-initialization/src/index.tsx) -# 配置低代码编辑器 -详见“低代码扩展简述“章节。 +## 配置低代码编辑器 +详见[低代码扩展简述](/site/docs/guide/expand/editor/summary)章节。 diff --git a/docs/docs/guide/create/useRenderer.md b/docs/docs/guide/create/useRenderer.md index 4f7a0a08b5..a9fc79909e 100644 --- a/docs/docs/guide/create/useRenderer.md +++ b/docs/docs/guide/create/useRenderer.md @@ -5,18 +5,20 @@ sidebar_position: 1 低代码引擎的编辑器将产出两份数据: -- 资产包数据 assets:包含物料名称、包名及其获取方式,对应协议中的[《低代码引擎资产包协议规范》](https://lowcode-engine.cn/assets) -- 页面数据 schema:包含页面结构信息、生命周期和代码信息,对应协议中的[《低代码引擎搭建协议规范》](https://lowcode-engine.cn/lowcode) +- 资产包数据 assets:包含物料名称、包名及其获取方式,对应协议中的[《低代码引擎资产包协议规范》](/site/docs/specs/assets-spec) +- 页面数据 schema:包含页面结构信息、生命周期和代码信息,对应协议中的[《低代码引擎搭建协议规范》](/site/docs/specs/lowcode-spec) 经过上述两份数据,可以直接交由渲染模块或者出码模块来运行,二者的区别在于: -- 渲染模块:使用资产包数据、页面数据和低代码运行时,并且允许维护者在低代码编辑器中用 Low Code 的方式继续维护; -- 出码模块:不依赖低代码运行时和页面数据,直接生成可直接运行的代码,并且允许维护者用 Pro Code 的方式继续维护,但无法再利用用低代码编辑器; +- 渲染模块:使用资产包数据、页面数据和低代码运行时,并且允许维护者在低代码编辑器中用 `低代码(LowCode)`的方式继续维护; +- 出码模块:不依赖低代码运行时和页面数据,直接生成可直接运行的代码,并且允许维护者用 `源码(ProCode)` 的方式继续维护,但无法再利用低代码编辑器; + +> 渲染和出码的详细阐述可参考此文:[低代码技术在研发团队的应用模式探讨](https://mp.weixin.qq.com/s/Ynk_wjJbmNw7fEG6UtGZbQ) ## 渲染模块 -[在 Demo 中](https://lowcode-engine.cn/demo),右上角有渲染模块的示例使用方式: -![Mar-13-2022 16-52-49.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1647161579197-20c72ea4-6d9a-4692-9b23-005182f6387e.gif#clientId=u244806d0-100a-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=u9b403d3d&margin=%5Bobject%20Object%5D&name=Mar-13-2022%2016-52-49.gif&originHeight=514&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=755539&status=done&style=stroke&taskId=u14f0f4c2-4d6c-4296-b2df-ccda870faff&title=) +[在 Demo 中](https://lowcode-engine.cn/demo/demo-general/index.html),右上角有渲染模块的示例使用方式: +![Mar-13-2022 16-52-49.gif](https://img.alicdn.com/imgextra/i2/O1CN01PRsEl61o7Zct5fJML_!!6000000005178-1-tps-1534-514.gif) 基于官方提供的渲染模块 [@alifd/lowcode-react-renderer](https://github.com/alibaba/lowcode-engine/tree/main/packages/react-renderer),你可以在 React 上下文渲染低代码编辑器产出的页面。 @@ -28,6 +30,7 @@ sidebar_position: 1 - components:需要根据编辑器产出的资产包 assets 中,根据页面 projectSchema 中声明依赖的 componentsMap,来加载所有依赖的资产包,最后获取资产包的实例并生成物料 - 资产包的键值对 components。 这个过程可以参考 demo 项目中的 `src/preview.tsx`: + ```typescript async function getSchemaAndComponents() { const packages = JSON.parse(window.localStorage.getItem('packages') || ''); @@ -76,25 +79,28 @@ const SamplePreview = () => { schema={schema} components={components} /> - ) + ); } ``` -> 注:您可以注意到,此处是依赖了 React 进行渲染的,对于 Vue 形态的渲染或编辑器支持,详见[对应公告](https://github.com/alibaba/lowcode-engine/issues/236)。 -> 本节示例可在 Demo 代码里找到:[https://github.com/alibaba/lowcode-demo/blob/main/src/preview.tsx](https://github.com/alibaba/lowcode-demo/blob/main/src/preview.tsx#L54-L58) +> 注 1:您可以注意到,此处是依赖了 React 进行渲染的,对于 Vue 形态的渲染或编辑器支持,详见[对应公告](https://github.com/alibaba/lowcode-engine/issues/236)。 +> +> 注 2:本节示例可在 Demo 代码里找到更完整的版本:[https://github.com/alibaba/lowcode-demo/blob/main/demo-general/src/preview.tsx](https://github.com/alibaba/lowcode-demo/blob/main/demo-general/src/preview.tsx) ## 出码模块 -[在 Demo 中](https://lowcode-engine.cn/demo),右上角有出码模块的示例使用方式: -![Mar-13-2022 16-55-56.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1647161777243-b16045c4-3cac-4920-8e68-ce064a90fe26.gif#clientId=u244806d0-100a-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=ud7bfd5a2&margin=%5Bobject%20Object%5D&name=Mar-13-2022%2016-55-56.gif&originHeight=514&originWidth=1536&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1727314&status=done&style=stroke&taskId=u4e079100-d6a0-4ad2-ac0c-938ab8e7759&title=) +[在 Demo 中](https://lowcode-engine.cn/demo/demo-general/index.html),右上角有出码模块的示例使用方式: + +![Mar-13-2022 16-55-56.gif](https://img.alicdn.com/imgextra/i3/O1CN017CVeka27p3vwrGI1D_!!6000000007845-1-tps-1536-514.gif) > 本节示例可在出码插件里找到:[https://github.com/alibaba/lowcode-code-generator-demo](https://github.com/alibaba/lowcode-code-generator-demo) -## 低代码的生产和消费 +## 低代码的生产和消费流程总览 + +经过“接入编辑器” - “接入运行时”这两节的介绍,我们已经可以了解到低代码所构建的生产和消费流程了,梳理如下图: -经过“接入编辑器” - “接入运行时” 这两节的介绍,我们已经可以了解到低代码所构建的生产和消费流程了,梳理如下图: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644405393410-1c54fa37-74de-4c48-a4a9-1cbce359feeb.png#clientId=ua752ee55-c225-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u4ceefadb&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1786&originWidth=3206&originalType=binary&ratio=1&rotation=0&showTitle=false&size=312489&status=done&style=none&taskId=uae8eacd1-4c05-4689-bb6a-24ceb76327d&title=&width=710) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01yiFiUc1rT32o9HpnW_!!6000000005631-2-tps-3206-1786.png) 如上述流程所示,您一般需要一个后端项目来保存页面数据信息,如果资产包信息是动态的,也需要保存资产包信息。 diff --git a/docs/docs/guide/design/datasourceEngine.md b/docs/docs/guide/design/datasourceEngine.md index 1ea076866b..f382d9facd 100644 --- a/docs/docs/guide/design/datasourceEngine.md +++ b/docs/docs/guide/design/datasourceEngine.md @@ -6,19 +6,19 @@ sidebar_position: 7 考虑之后的扩展性和兼容性,核心分为了 2 类包,一个是 **datasource-engine** ,另一个是 **datasource-engine-x-handler** ,x 的意思其实是对应数据源的 type,比如说 **datasource-engine-mtop-handler**,也就是说我们会将真正的请求工具放在 handler 里面去处理,engine 在使用的时候由使用方自身来决定需要注册哪些 handler,这样的目的有 2 个,一个是如果将所有的 handler 都放到一个包,对于端上来说这个包过大,有一些浪费资源和损耗性能的问题,另一个是如果有新的类型的数据源出现,只需要按照既定的格式去新增一个对应的 handler 处理器即可,达到了高扩展性的目的; -![](https://intranetproxy.alipay.com/skylark/lark/0/2020/png/275191/1599545889374-73acbe09-3bb6-4df9-b6f9-80a86764afa2.png?x-oss-process=image%2Fresize%2Cw_720#crop=0&crop=0&crop=1&crop=1&id=zq0Rr&originHeight=370&originWidth=720&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&title=) +![](https://img.alicdn.com/imgextra/i3/O1CN011ep9No2ACzrgzgtk0_!!6000000008168-2-tps-720-370.png) ### DataSourceEngine -- engine: engine 主要分 2 类,一类是面向 render 引擎的,可以从 engine/interpret 引入,一类是面向出码或者说直接单纯使用数据源引擎的场景,可以从 engine/runtime 引入,代码如下 +- engine:engine 主要分 2 类,一类是面向 render 引擎的,可以从 engine/interpret 引入,一类是面向出码或者说直接单纯使用数据源引擎的场景,可以从 engine/runtime 引入,代码如下 -```javascript +```typescript import { createInterpret, createRuntime } from '@alilc/lowcode-datasource-engine'; ``` create 方法定义如下 -```javascript +```typescript interface IDataSourceEngineFactory { create(dataSource: DataSource, context: Omit, extraConfig?: { requestHandlersMap: RequestHandlersMap; @@ -29,7 +29,7 @@ interface IDataSourceEngineFactory { create 接收三个参数,第一个是 DataSource,对于运行时渲染和出码来说,DataSource 的定义分别如下: -```javascript +```typescript /** * 数据源对象--运行时渲染 * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 @@ -38,6 +38,7 @@ export interface DataSource { list: DataSourceConfig[]; dataHandler?: JSFunction; } + /** * 数据源对象 * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 @@ -63,7 +64,7 @@ export interface DataSourceConfig { 但是对于出码来说,create 和 DataSource 定义如下: -```javascript +```typescript export interface IRuntimeDataSourceEngineFactory { create(dataSource: RuntimeDataSource, context: Omit, extraConfig?: { requestHandlersMap: RequestHandlersMap; @@ -92,6 +93,7 @@ export interface RuntimeDataSourceConfig { options?: RuntimeOptions; [otherKey: string]: unknown; } + /** * 数据源对象 * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 @@ -106,18 +108,18 @@ export interface RuntimeDataSource { - context:数据源引擎内部有一些使用了 this 的表达式,这些表达式需要求值的时候依赖上下文,因此需要将当前的上下文丢给数据源引擎,另外在 handler 里面去赋值的时候,也会用到诸如 setState 这种上下文里面的 api,当然,这个是可选的,我们后面再说。 -```javascript +```typescript /** * 运行时上下文--暂时是参考 react,当然可以自己构建,完全没问题 */ export interface IRuntimeContext> { /** 当前容器的状态 */ readonly state: TState; - /** 设置状态(浅合并) */ + /** 设置状态 (浅合并) */ setState(state: Partial): void; /** 自定义的方法 */ [customMethod: string]: any; - /** 数据源, key 是数据源的 ID */ + /** 数据源,key 是数据源的 ID */ dataSourceMap: Record; /** 重新加载所有的数据源 */ reloadDataSource(): Promise; @@ -134,7 +136,7 @@ export interface IRuntimeContext - extraConfig:这个字段是为了留着扩展用的,除了一个必填的字段 **requestHandlersMap** -```javascript +```typescript export declare type RequestHandler = (ds: RuntimeDataSourceConfig, context: IRuntimeContext) => Promise>; export declare type RequestHandlersMap = Record; ``` @@ -143,9 +145,9 @@ RequestHandlersMap 是一个把数据源以及对应的数据源 handler 关联 create 调用结束后,可以获取到一个 DataSourceEngine 实例 -```javascript +```typescript export interface IDataSourceEngine { - /** 数据源, key 是数据源的 ID */ + /** 数据源,key 是数据源的 ID */ dataSourceMap: Record; /** 重新加载所有的数据源 */ reloadDataSource(): Promise; diff --git a/docs/docs/guide/design/editor.md b/docs/docs/guide/design/editor.md index d861ae7d63..b04cb4eb69 100644 --- a/docs/docs/guide/design/editor.md +++ b/docs/docs/guide/design/editor.md @@ -4,18 +4,22 @@ sidebar_position: 3 --- 本篇重点介绍如何从零开始设计编排模块,设计思路是什么?思考编排的本质是什么?围绕着本质,如何设计并实现对应的功能模块。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644397577227-99a77c7d-6a6e-4d92-b222-eaac0ee7988e.png#clientId=u45d0137b-8a6f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=540&id=u4613aa03&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1080&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=911801&status=done&style=none&taskId=u449864e5-516f-41eb-b86a-7c026b797a8&title=&width=960) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01fGzyI41bqpl6AavNp_!!6000000003517-2-tps-1920-1080.png) + +## 编排是什么 + +所谓编排,即将设计器中的所有物料,进行布局设置、组件设置、交互设置(JS 编写/逻辑编排)后,形成符合业务诉求的 schema 描述。 +## 编排的本质 -# 编排是什么 -所谓编排,即将设计器中的所有物料,进行布局设置、组件设置、交互设置(JS编写/逻辑编排)后,形成符合业务诉求的 schema 描述。 -# 编排的本质 首先,思考编排的本质是什么? + 编排的本质是生产符合《阿里巴巴中后台前端搭建协议规范》的数据**,**在这个场景里,协议是通过 JSON 来承载的。如: + ```json { "componentName": "Page", "props": { - "layout": "wide", + "layout": "wide" }, "children": [ { @@ -29,35 +33,52 @@ sidebar_position: 3 ``` 可是在真实场景,节点数可能有成百上千,每个节点都具有新增、删除、修改、移动、插入子节点等操作,同时还有若干约束,JSON 结构操作起来不是很便利,于是我们仿 DOM 设计了 **节点模型 & 属性模型,**用更具可编程性的方式来编排,这是**编排系统的基石**。 + 其次,每次编排动作后(CRUD),都需要实时的渲染出视图。广义的视图应该包括各种平台上的展现,浏览器、Rax、小程序、Flutter 等等,所以使用何种渲染器去渲染 JSON 结构应该可以由用户去扩展,我们定义一种机制去衔接设计态和渲染态。 + 至此,我们已经完成了**编排模块最基础的功能**,接下来,就是完善细节,逐步丰满功能。比如: -1)编排面板的整体功能区划分设计; -2)节点属性设计;节点删除、移动等操作设计;容器节点设计; -3)节点拖拽功能、拖拽定位设计和实现; -4)节点在画布上的辅助功能,比如 hover、选中、选中时的操作项、resize、拖拽占位符等; -5)设计态和渲染态的坐标系转换,滚动监听等; -6)快捷键机制; -7)历史功能,撤销和重做; -8)结构化的插件扩展机制; -9)原地编辑功能; +1. 编排面板的整体功能区划分设计; +2. 节点属性设计;节点删除、移动等操作设计;容器节点设计; +3. 节点拖拽功能、拖拽定位设计和实现; +4. 节点在画布上的辅助功能,比如 hover、选中、选中时的操作项、resize、拖拽占位符等; +5. 设计态和渲染态的坐标系转换,滚动监听等; +6. 快捷键机制; +7. 历史功能,撤销和重做; +8. 结构化的插件扩展机制; +9. 原地编辑功能; + 有非常多模块,但只要记住一点,这些功能的目的都是辅助用户在画布上有更好的编排体验、扩展能力而逐个增加设计的。 -# 编排功能模块 -## 模型设计 + +## 编排功能模块 +### 模型设计 + 编排实际上操作 schema,但是实际代码运行的过程中,我们将 schema 分成了很多层,每一层有各自的职责,他们所负责的功能是明确清晰的。这就是低代码引擎中的模型设计。 + 我们通过将 schema 和常用的操作等结合起来,最终将低代码引擎的模型分为节点模型、属性模型、文档模型和项目模型。 -### 项目模型(`Project`) + +#### 项目模型(`Project`) + 项目模型提供项目管理能力。通常一个引擎启动会默认创建一个 `Project` 实例,有且只有一个。项目模型实例下可以持有多个文档模型的实例,而当前处于设计器设计状态的文档模型,我们将其添加 active 标识,也将其称为 `currentDocument`,可以通过 `project.currentDocument` 获得。 + 一个 `Project` 包含若干个 `DocumentModel` 实例,即项目模型和文档模型的关系是 1 对 n,如下图所示: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644397244733-2492a7bf-20bf-4610-a335-99cc047037b7.png#clientId=u45d0137b-8a6f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=824&id=uadf98e25&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1648&originWidth=1226&originalType=url&ratio=1&rotation=0&showTitle=false&size=1260603&status=done&style=none&taskId=u50b01e40-96f2-4629-a1b9-1b5a22967fc&title=&width=613) -### 文档模型(`DocumentModel`) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01G28BKC1RvHRvhhiDf_!!6000000002173-2-tps-1226-1648.png) + +#### 文档模型(`DocumentModel`) + 文档模型提供文档管理的能力,每一个页面即一个文档流,对应一个文档模型。文档模型包含了一组 Node 组成的一颗树,类似于 DOM。我们可以通过文档模型来操作 `Node` 树,来达到管理文档模型的能力。每一个文档模型对应多个 `Node`,但是根 `Node` 只有一个,即 `rootNode` 和 `nodes`。 + 文档模型可以通过 `Node` 树,通过 `doc.schema` 来导出文档的 `schema`,并使用其进行渲染。 + 他们的关系如下图: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644397244327-d931aff8-40d4-47df-8b1c-b81c06c40c48.png#clientId=u45d0137b-8a6f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=745&id=L5LAf&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1490&originWidth=960&originalType=url&ratio=1&rotation=0&showTitle=false&size=1110316&status=done&style=none&taskId=u7d873681-f61a-40ea-baaa-8f7b76c769c&title=&width=480) -### 节点模型(`Node`) + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01NYVhN61nab6hsw5ZK_!!6000000005106-2-tps-960-1490.png) + +#### 节点模型(`Node`) + 我们先看一下一个 `Node` 在 `schema` 中对应的示例: -```json + +```javascript { componentName: 'Text', id: 'node_k1ow3cbf', @@ -76,7 +97,9 @@ sidebar_position: 3 condition: true, } ``` + 上面的示例是一个 `Text` 的 `Node` 节点,而我们的 `Node` 节点模型就是负责这一层级的 `Schema` 管理。它的功能聚焦于单层级的 schema 相关操作。我们可以看一下节点模型的一些方法,了解其功能。 + ```typescript declare class Node { // Props @@ -111,15 +134,22 @@ declare class Node { replaceWith(schema: Schema, migrate?: boolean): any; } ``` -这里没有展示全部的方法,但是我们可以发现,`Node` 节点模型核心功能点有三个 -1)`Props` 管理:通过 `Props` 实例管理所有的 `Prop`,包括新增、设置、删除等 `Prop` 相关操作。 -2)`Node` 管理:管理 `Node` 树的关系,修改当前 `Node` 节点或者 `Node` 子节点等。 -3)`Schema` 管理:可以通过 `Node` 获取当前层级的 `Schema` 描述协议内容,并且也可以修改它。 + +这里没有展示全部的方法,但是我们可以发现,`Node` 节点模型核心功能点有三个: + +1. `Props` 管理:通过 `Props` 实例管理所有的 `Prop`,包括新增、设置、删除等 `Prop` 相关操作。 +2. `Node` 管理:管理 `Node` 树的关系,修改当前 `Node` 节点或者 `Node` 子节点等。 +3. `Schema` 管理:可以通过 `Node` 获取当前层级的 `Schema` 描述协议内容,并且也可以修改它。 + 通过 `Node` 这一层级,对 `Props`、`Node` 树和 `Schema` 的管理粒度控制到最低,这样扩展性也就更强。 -### 属性模型(Prop) + +#### 属性模型(Prop) + 一个 `Props` 对应多个 `Prop`,每一个 `Prop` 对应 schema 的 `props` 下的一个字段。 + `Props` 管理的是 `Node` 节点模型中的 `props` 字段下的内容。而 `Prop` 管理的是 `props` 下的每一个 `key` 的内容,例如下面的示例中,一个 `Props` 管理至少 6 个 `Prop`,而其中一个 `Prop` 管理的是 `showTitle` 的结果。 -```typescript + +```javascript { props: { showTitle: false, @@ -135,17 +165,27 @@ declare class Node { }, } ``` -### 组件描述模型(ComponentMeta) +#### 组件描述模型(ComponentMeta) + 编排已经等价于直接操作节点 & 属性了,而一个节点和一组对应的属性相当于一个真实的组件,而真实的组件一定是有约束的,比如组件名、组件类型、支持哪些属性以及属性类型、组件能否拖动、支持哪些扩展操作、组件是否是容器型组件、A 组件中能否放入 B 组件等等。 + 于是,我们设计了一份协议专门负责组件描述,即《中后台搭建组件描述协议》,而编排模块中也有负责解析和使用符合描述协议规范的模块。 + 每一个组件对应一个 `ComponentMeta` 的实例,其属性和方法就是描述协议中的所有字段,所有 `ComponentMeta` 都由设计器器的 `designer` 模块进行创建和管理,其他模块通过 `designer` 来获取指定的 `ComponentMeta` 实例,尤其是每个 `Node` 实例上都会挂载对应的 `ComponentMeta` 实例。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644397244032-8aa176d5-a74e-49c9-a309-251dba81b37c.png#clientId=u45d0137b-8a6f-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u044bdacd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=756&originWidth=998&originalType=url&ratio=1&rotation=0&showTitle=false&size=294191&status=done&style=none&taskId=uee9dfeef-f646-41db-afd4-a0b1acf8019&title=) + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01NSh0LI1b150RUzOUc_!!6000000003404-2-tps-998-756.png) + 组件描述模型是后续编排辅助的基础,包括设置面板、拖拽定位机制等。 -### 项目、文档、节点和属性模型关系 +#### 项目、文档、节点和属性模型关系 + 整体来看,一个 Project 包含若干个 DocumentModel 实例,每个 DocumentModel 包含一组 Node 构成一颗树(类似 DOM 树),每个 Node 通过 Props 实例管理所有 Prop。整体的关系图如下。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645066478805-57802de7-382e-4105-99cb-161b8c07f117.png#clientId=uf22d1b91-761d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=678&id=uc2db9afa&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1356&originWidth=1694&originalType=binary&ratio=1&rotation=0&showTitle=false&size=285816&status=done&style=none&taskId=u6526eafb-f082-46dd-8584-9dd9b1bb395&title=&width=847) + +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01mufxpY1qCGvDTSdw9_!!6000000005459-2-tps-1694-1356.png) + 节点 & 属性模型是引擎基石,几乎贯穿所有模块,相信从上面的类图已经能看出几个基础类的职责以及依赖关系。 + 节点 & 属性模型等价于 JSON 数据结构,而编排的本质是产出 JSON 数据结构,现在可以重新表述为编排的本质是操作节点 & 属性模型了。 + ```typescript // 一段编排的示例代码 rootNode.insertAfter({ componentName: 'Button', props: { size: 'medium' } }); @@ -156,33 +196,51 @@ rootNode.export(); // => 产出 schema ``` -## 画布渲染 -画布渲染使用了设计态与渲染态的双层架构。![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644397244328-61bb9ce7-a27c-4917-baee-c0a93bd0fd36.png#clientId=u45d0137b-8a6f-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u3c9164cd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=710&originWidth=1416&originalType=url&ratio=1&rotation=0&showTitle=false&size=287707&status=done&style=none&taskId=u6c993606-238b-478f-9317-397eb0708eb&title=) +### 画布渲染 + +画布渲染使用了设计态与渲染态的双层架构。 + +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01cZ6Q32260qtiDofwi_!!6000000007600-2-tps-1416-710.png) + 如上图,设计器和渲染器其实处在不同的 Frame 下,渲染器以单独的 `iframe` 嵌入。这样做的好处,一是为了给渲染器一个更纯净的运行环境,更贴近生产环境,二是扩展性考虑,让用户基于接口约束自定义自己的渲染器。 -### xxx-renderer +#### xxx-renderer + xxx-renderer 是一个纯 renderer,即一个渲染器,通过给定输入 schema、依赖组件和配置参数之后完成渲染。 -### xxx-simulator-renderer -xxx-simulator-renderer 通过和 host进行通信来和设计器打交道,提供了 `DocumentModel` 获取 schema 和组件。将其传入 xxx-renderer 来完成渲染。 +#### xxx-simulator-renderer + +xxx-simulator-renderer 通过和 host 进行通信来和设计器打交道,提供了 `DocumentModel` 获取 schema 和组件。将其传入 xxx-renderer 来完成渲染。 + 另外其提供了一些必要的接口,来帮助设计器完成交互,比如点击渲染画布任意一个位置,需要能计算出点击的组件实例,继而找到设计器对应的 Node 实例,以及组件实例的位置/尺寸信息,让设计器完成辅助 UI 的绘制,如节点选中。 -### react-simulator-renderer +#### react-simulator-renderer + 以官方提供的 react-simulator-renderer 为例,我们看一下点击一个 DOM 节点后编排模块是如何处理的。 + 首先在初始化的时候,renderer 渲染的时候会给每一个元素添加 ref,通过 ref 机制在组件创建时将其存储起来。在存储的时候我们给实例添加 `Symbol('_LCNodeId')` 的属性。 + 当点击之后,会去根据 `__reactInternalInstance$` 查找相应的 fiberNode,通过递归查找到对应的 React 组件实例。找到一个挂载着 `Symbol('_LCNodeId')` 的实例,也就是上面我们初始化添加的属性。 + 通过 `Symbol('_LCNodeId')` 属性,我们可以获取 Node 的 id,这样我们就可以找到 Node 实例。 + 通过 `getBoundingClientRect` 我们可以获取到 Node 渲染出来的 DOM 的相关信息,包括 `x`、`y`、`width`、`height` 等。 + 通过 DOM 信息,我们将 focus 节点所需的标志渲染到对应的地方。hover、拖拽占位符、resize handler 等辅助 UI 都是类似逻辑。 -### 通信机制 +#### 通信机制 + 既然设计器和渲染器处于两个 Frame,它们之间的事件通信、方法调用是通过各自的代理对象进行的,不允许其他方式,避免代码耦合。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644397245794-927fa812-ea1c-4bc1-967b-4c1dff924fd1.png#clientId=u45d0137b-8a6f-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u22088dc8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=648&originWidth=1290&originalType=url&ratio=1&rotation=0&showTitle=false&size=223251&status=done&style=none&taskId=uf720b921-07c2-4cda-a101-74e863ce10d&title=) -**host** -host 可以访问设计器的所有模块,由于 renderer 层不负责与设计器相关的交互。所以增加了一层 host,作为通信的中间层。host 可以访问到设计器中所有模块,并提供相关方法供 simulator-renderer 层调用。例如schema 的获取、组件获取等。 + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01hxtg7X1M3AZsAdt83_!!6000000001378-2-tps-1290-648.png) + +##### host +host 可以访问设计器的所有模块,由于 renderer 层不负责与设计器相关的交互。所以增加了一层 host,作为通信的中间层。host 可以访问到设计器中所有模块,并提供相关方法供 simulator-renderer 层调用。例如 schema 的获取、组件获取等。 + simulator-renderer 通过调用 host 的方法,将 schema、components 等参数传给 renderer,让 renderer 进行渲染。 -**xxx-simulator-renderer** +##### xxx-simulator-renderer + 为了完成双向交互,simulator-renderer 也需要提供一些方法来供 host 层调用,之后当设计器和用户有交互,例如上述提到的节点选中。这里需要提供的方法有: - getClientRects @@ -196,12 +254,16 @@ simulator-renderer 通过调用 host 的方法,将 schema、components 等参 这样,host 和 simulator-renderer 之间便通过相关方法实现了双向通信,能在隔离设计器的基础上完成设计器到画布和画布到设计器的通信流程。 -## 编排辅助的核心 -### 设置面板与设置器 +### 编排辅助的核心 +#### 设置面板与设置器 当在渲染画布上点击一个 DOM 节点,我们可以通过 xxx-simulator-renderer 获取 `Node` 节点,我们在 `Node` 上挂载了 `ComponentMeta` 实例。通过 `ComponentMeta` 我们获取到当前组件的描述模型。通过描述模型,我们即可获得组件、即当前 Node 支持的所有属性配置。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644397246381-ed265cc3-b6c1-4a38-985a-df1898862fe8.png#clientId=u45d0137b-8a6f-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u1422ee5e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=985&originWidth=1500&originalType=url&ratio=1&rotation=0&showTitle=false&size=332497&status=done&style=none&taskId=u2bbbb9ae-7834-48ba-b87f-fa5ccf8fa39&title=) -#### 设置面板 + +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01c7nkoo1OXyRhVAFlK_!!6000000001716-2-tps-1500-985.png) + +##### 设置面板 + 设置面板对于配置项的呈现结构是通过 `ComponentMeta.configure` 来确定的。 + ```json { "component": { @@ -231,14 +293,22 @@ simulator-renderer 通过调用 host 的方法,将 schema、components 等参 } } ``` + 上述的 `component.isContainer` 描述了这个组件是否是一个容器组件。而 props 下的属性就是我们在设置面板中展示的属性,包含了这个属性的名称、使用的设置器、配置之后影响的是哪个属性等。 + 而这只是描述,编排模块的 `SettingTopEntry` 便是管理设置面板的实现模块。 + `SettingTopEntry` 包含了 n 个 `SettingField`,每一个 `SettingField` 就对应下面要将的设置器。即 `SettingTopEntry` 负责管理多个 `SettingField`。 -#### 设置器 + +##### 设置器 选中节点可供配置的属性都有相应的设置器配置,比如文本、数字、颜色、JSON、Choice、I18N、表达式 等等,或者混合多种。 + 设置器本质上是一个 React 组件,但是设置面板在渲染时会传入当前配置项对应的 `SettingField` 实例,`SettingField` 本质上就是包裹了 `Prop` 实例,设置器内部的行为以及 UI 变化都由设置器自己把控,但当属性值发生变化时需要通过 `SettingField` 下的 `Prop` 来修改值,因为修改 `Prop` 实例就相当于修改了 schema。一方面这样的设置器设置之后,保存的 schema 才是正确的,另外一方面,只有 schema 变化了,才能触发渲染画布重新渲染。 -### 拖拽引擎 & 拖拽定位机制 -![](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644397245744-af8b951c-ee22-4fcb-9175-6f1b0eb2ba37.gif#clientId=u45d0137b-8a6f-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=uf8b286a2&margin=%5Bobject%20Object%5D&originHeight=917&originWidth=1425&originalType=url&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u9b4475cb-bb5c-4c86-9b03-b824bc46b12&title=) + +#### 拖拽引擎 & 拖拽定位机制 + +![](https://img.alicdn.com/imgextra/i4/O1CN01G8zyBw1OkL8m0FG4J_!!6000000001743-1-tps-1425-917.gif) + 拖拽引擎(`Dragon`)核心完成的工作是将被拖拽对象拖拽到目标位置,涉及到几个概念: - 被拖拽对象 - `DragObject` @@ -246,38 +316,53 @@ simulator-renderer 通过调用 host 的方法,将 schema、components 等参 - 拖拽感应区 - `ISensor` - 定位事件 - `LocateEvent` -#### Sensor +##### Sensor + 在引擎初始化的时候,我们监听 `document` 和 iframe `contentDocument` 的 `mouse`、`keyboard`、`drag` 事件来感知拖拽的发生。而这些监听的区域我们又称为拖拽感应区,也就是 `Sensor`。`Sensor` 会有多个,因为感应器有多个,默认设置器和设置面板是没有 `Sensor`,但是他们是可以注册 `Sensor` 来增加感应区域,例如大纲树就注册了自己的 `Sensor`。 `Sensor` 有两个关键职责: -1)用于事件对象转换,比如坐标系换算 -2)根据拖拽过程中提供的位置信息,结合每一层 `Node` 也就是组件包含的描述信息,知道其是否能作为容器等限制条件,来进行进一步的定位,最后计算出精准信息来进行视图渲染。 +1. 用于事件对象转换,比如坐标系换算。 +2. 根据拖拽过程中提供的位置信息,结合每一层 `Node` 也就是组件包含的描述信息,知道其是否能作为容器等限制条件,来进行进一步的定位,最后计算出精准信息来进行视图渲染。 **拖拽流程** -在引擎初始化的时候,初始化多个 `Sensor`。 -当拖拽开始的时候,开启 `mousemove`、`mouseleave`、`mouseover` 等事件的监听。 -拖拽过程中根据 `mousemove` 的 `MouseEvent` 对象封装出 `LocateEvent` 对象,继而交给相应 `sensor` 做进一步定位处理。 -拖拽结束时,根据拖拽的结果进行 schema 变更和视图渲染。 -最后关闭拖拽开始时的事件监听。 +1. 在引擎初始化的时候,初始化多个 `Sensor`。 +2. 当拖拽开始的时候,开启 `mousemove`、`mouseleave`、`mouseover` 等事件的监听。 +3. 拖拽过程中根据 `mousemove` 的 `MouseEvent` 对象封装出 `LocateEvent` 对象,继而交给相应 `sensor` 做进一步定位处理。 +4. 拖拽结束时,根据拖拽的结果进行 schema 变更和视图渲染。 +5. 最后关闭拖拽开始时的事件监听。 -#### 拖拽方式 +##### 拖拽方式 根据拖拽的对象不同,我们将拖拽分为几种方式: -1)**画布内拖拽:**此时 sensor 是 simulatorHost,拖拽完成之后,会根据拖拽的位置来完成节点的精确插入。 -2)**从组件面板拖拽到画布**:此时的 sensor 还是 simulatorHost,因为拖拽结束的目标还是画布。 -3)**大纲树面板拖拽到画布中**:此时有两个 sensor,一个是大纲树,当我们拖拽到画布区域时,画布区域内的 simulatorHost 开始接管。 -4)画布拖拽到画布中:从画布中开始拖拽时,最新生效的是 simulatorHost,当离开画布到大纲树时,大纲树 sensor 开始接管生效。当拖拽到大纲树的某一个节点下时,大纲树会将大纲树中的信息转化为 schema,然后渲染到画布中。 -## 其他 +1. **画布内拖拽:**此时 sensor 是 simulatorHost,拖拽完成之后,会根据拖拽的位置来完成节点的精确插入。 +2. **从组件面板拖拽到画布**:此时的 sensor 还是 simulatorHost,因为拖拽结束的目标还是画布。 +3. **大纲树面板拖拽到画布中**:此时有两个 sensor,一个是大纲树,当我们拖拽到画布区域时,画布区域内的 simulatorHost 开始接管。 +4. **画布拖拽到画布中**:从画布中开始拖拽时,最新生效的是 simulatorHost,当离开画布到大纲树时,大纲树 sensor 开始接管生效。当拖拽到大纲树的某一个节点下时,大纲树会将大纲树中的信息转化为 schema,然后渲染到画布中。 +### 其他 + 引擎的编排能力远远不止上述所描述的功能,这里只描述了其核心和关键的功能。在整个引擎的迭代和设计过程中还有很多细节来使我们的引擎更好用、更容易扩展。 -**schema 处理的管道机制** -通过PropsReducer 的管道机制,用户可以定制自己需要的逻辑,来修改 Schema。 -**组件 metadata 处理的管道机制** + +#### schema 处理的管道机制 + +通过 PropsReducer 的管道机制,用户可以定制自己需要的逻辑,来修改 Schema。 + +#### 组件 metadata 处理的管道机制 + 组件的描述信息都收拢在各自的 ComponentMeta 实例内,涉及到的消费方几乎遍及整个编排过程,包括但不限于 组件拖拽、拖拽辅助 UI、设置区、原地编辑、大纲树 等等。 + 在用户需要自定义的场景,开放 ComponentMeta 的修改能力至关重要,因此我们设计了 metadata 初始化/修改的管道机制。 -**hotkey & builtin-hotkey** + +#### hotkey & builtin-hotkey + 快捷键的实现,以及引擎内核默认绑定的快捷键行为。 -**drag resize 引擎** + +#### drag resize 引擎 + 对于布局等类型的组件,支持拖拽改变大小。resize 拖拽引擎根据组件 ComponentMeta 声明来开启,拖拽后,触发组件的钩子函数(`onResizeStart` / `onResize` / `onResizeEnd`),完成 resize 过程。 -**OffsetObserver** + +#### OffsetObserver + 设计态的辅助 UI 需要根据渲染态的视图变化而变化,比如渲染容器滚动了,此时通过 OffsetObserver 做一个动态的监听。 -**插件机制** + +#### 插件机制 + 我们希望保持引擎内核足够小,但拥有足够强的扩展能力,所有扩展功能都通过插件机制来承载。 diff --git a/docs/docs/guide/design/generator.md b/docs/docs/guide/design/generator.md index 19d34560be..2310cb7a5f 100644 --- a/docs/docs/guide/design/generator.md +++ b/docs/docs/guide/design/generator.md @@ -2,18 +2,20 @@ title: 出码模块设计 sidebar_position: 5 --- -本篇主要讲解了出码模块实现的基本思路与一些概念。如需接入出码和定制出码方案,可以参考《[使用出码功能](https://www.yuque.com/lce/doc/cplfv0)》一节。 -# npm 包与仓库信息 + +本篇主要讲解了出码模块实现的基本思路与一些概念。如需接入出码和定制出码方案,可以参考《[使用出码功能](/site/docs/guide/expand/runtime/codeGeneration)》一节。 + +## npm 包与仓库信息 + | **NPM 包** | **代码仓库** | **说明** | | --- | --- | --- | -| [@alilc/lowcode-code-generator](https://www.npmjs.com/package/@alilc/lowcode-code-generator) | [alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine) -(子目录:modules/code-generator) | 出码模块核心库,支持在 node 环境下运行,也提供了浏览器下运行的 standalone 模式 | +| [@alilc/lowcode-code-generator](https://www.npmjs.com/package/@alilc/lowcode-code-generator) | [alibaba/lowcode-engine](https://github.com/alibaba/lowcode-engine)(子目录:modules/code-generator)| 出码模块核心库,支持在 node 环境下运行,也提供了浏览器下运行的 standalone 模式 | | [@alilc/lowcode-plugin-code-generator](https://www.npmjs.com/package/@alilc/lowcode-plugin-code-generator) | [alibaba/lowcode-code-generator-demo](https://github.com/alibaba/lowcode-code-generator-demo) | 出码示例 -- 浏览器端出码插件 | -# 出码模块原理 +## 出码模块原理 出码模块的输入和输出很简单: -![](https://cdn.nlark.com/yuque/0/2022/jpeg/263300/1644825891969-1777dbe4-5ffc-4c94-a022-3aba0c116021.jpeg) +![](https://img.alicdn.com/imgextra/i3/O1CN01OkDmKq1xMX6Xxv6co_!!6000000006429-0-tps-1262-346.jpg) 这里有几个概念: @@ -23,19 +25,23 @@ sidebar_position: 5 可以看出,这是一个与用户基本没有交互,通过既定的流程完成整个功能链路的模块。其核心暴露的是一个将搭建协议 schema 按既定的 solution 转换为代码的函数。对于使用者来说就是一个输入输出都确定的黑盒系统。 -## 出码流程概述 +### 出码流程概述 + 出码模块和编译器很类似,都是将代码的一种表现形式转换成另一种表现形式,如: -**编译器流程** -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644403720547-e5021c3c-0c63-47ea-b8f0-1af79bbae3ef.png#clientId=u70bc6751-fff0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=246&id=u3b3e3126&margin=%5Bobject%20Object%5D&name=image.png&originHeight=492&originWidth=3228&originalType=binary&ratio=1&rotation=0&showTitle=false&size=110319&status=done&style=none&taskId=u32f55257-a18c-4caa-9334-0b3ca5b0bc0&title=&width=1614) +#### 编译器流程 +![image.png](https://img.alicdn.com/imgextra/i3/O1CN019F21Lb1bsCwvNcWRq_!!6000000003520-2-tps-3228-492.png) + +#### 出码模块流程 +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01SEcVta1uLD72W0URZ_!!6000000006020-2-tps-1536-182.png) -**出码模块流程** -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644402753768-02d402da-dd1a-4783-9021-606e276d4c68.png#clientId=u70bc6751-fff0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=182&id=GlAz4&margin=%5Bobject%20Object%5D&name=image.png&originHeight=182&originWidth=1536&originalType=binary&ratio=1&rotation=0&showTitle=false&size=23743&status=done&style=none&taskId=ubbea9289-cb03-4fcf-9ce7-22da1ce077b&title=&width=1536) +### 出码流程详解 +#### 协议解析 -## 出码流程详解 -### 协议解析 协议解析主要是将输入的 schema 解析成更适合出码模块内部使用的数据结构的过程。这样在后面的代码生成过程中就可以直接用这些数据,不必重复解析了。 -![](https://intranetproxy.alipay.com/skylark/lark/0/2021/jpeg/154771/1636960093808-624b5e50-18d6-476d-a951-556912832cdb.jpeg) + +![](https://img.alicdn.com/imgextra/i3/O1CN016EeitG1giCNCNTLVF_!!6000000004175-0-tps-1282-515.jpg) + 主要步骤如下: - 解析三方组件依赖 @@ -46,21 +52,30 @@ sidebar_position: 5 - 分析 utils 和 NPM 包依赖关系 - 其他兼容处理 -### 前置优化 +#### 前置优化 + 前置优化是计划基于策略对 schema 做一些优化。 + 主要逻辑分为分析、规则和优化三个部分,组合为一个支持通过配置进行一定程度定制化的策略包。每个策略包会先执行分析器,对输入进行特征提取,然后通过规则对特征进行判断,决定是否执行优化动作: -![](https://intranetproxy.alipay.com/skylark/lark/0/2021/jpeg/154771/1636960832211-0db6925b-c4b5-4be4-a883-fdd52a47e19a.jpeg) -### 代码生成 +![](https://img.alicdn.com/imgextra/i4/O1CN01P0Lw7v1lfyWtfQTuR_!!6000000004847-2-tps-994-278.png) + +#### 代码生成 代码生成的流程如下: -![](https://intranetproxy.alipay.com/skylark/lark/0/2021/jpeg/154771/1636975834791-e3fe89f9-cd2d-446f-aa9f-fca0bb1d56c3.jpeg) +![](https://img.alicdn.com/imgextra/i1/O1CN01lhcWBg1RG3nsoSoY2_!!6000000002083-2-tps-1468-464.png) + 如果简单粗暴地拼字符串生成源代码将难以扩展和维护,因此出码模块在代码生成过程中将代码进行了一些抽象化。 + 日常开发中,我们常常是基于某一个特定的项目框架,将一些配置、UI 代码、逻辑代码放到他们应该在的地方,最终形成一套可以 run 起来的业务系统。那么其实对于出码这件事,我们也可以层层拆解,**项目 -> 插槽 -> 模块 -> 文件 -> 代码块**(代码片段)。这样就能将复杂的项目产出问题,拆分为一个个相对专注且单一的代码块产出问题,同时也支持组合复用。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644402753919-1f063db3-5ad9-406b-9b45-6eeef79ea38b.png#clientId=u70bc6751-fff0-4&crop=0&crop=0&crop=1&crop=1&height=305&id=LgGUo&margin=%5Bobject%20Object%5D&name=image.png&originHeight=454&originWidth=892&originalType=binary&ratio=1&rotation=0&showTitle=false&size=230321&status=done&style=none&taskId=u50d38d84-3a3e-4c77-af05-8bc5f794643&title=&width=600) + +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01vOGmBT1JaegccXDt8_!!6000000001045-2-tps-892-454.png) + 注:中间表达结构即为对 Schema 解析后的结构化产物 -**插槽** +##### 插槽 + 首先来看下插槽,插槽描述了对应模块在项目中相对路径,并且可以对模块做固定的命名。每个插槽都有一系列插件来完成代码产出工作。生成的一个或多个文件,最终会依照插槽的描述放入项目中。 + ```typescript // 项目模版 export interface IProjectTemplate { @@ -78,20 +93,23 @@ interface IProjectPlugins { [slotName: string]: BuilderComponentPlugin[]; } ``` -**代码块** +##### 代码块 + 代码块是出码产物的最小单元,由出码模块插件产出,多个代码块最后会被组装为代码文件。每个代码块通过 name 描述自己,再通过 linkAfter 描述应该跟在哪些 name 的代码块后面。 + ```typescript interface ICodeChunk { - type: ChunkType; // 处理类型 ast | string | json - fileType: string; // 文件类型 js | css | ts ... - name: string; // 代码块名称,与 linkAfter 相关 - subModule?: string; // 模块内文件名,默认是 index - content: ChunkContent; // 代码块内容,数据格式与 type 相关 - linkAfter: string[]; // + type: ChunkType; // 处理类型 ast | string | json + fileType: string; // 文件类型 js | css | ts ... + name: string; // 代码块名称,与 linkAfter 相关 + subModule?: string; // 模块内文件名,默认是 index + content: ChunkContent; // 代码块内容,数据格式与 type 相关 + linkAfter: string[]; } ``` -### 后置优化 +#### 后置优化 + 后置优化分为文件级别和项目级别两种: - 文件级别:在生成完一个文件后进行处理 diff --git a/docs/docs/guide/design/materialParser.md b/docs/docs/guide/design/materialParser.md index 42aaadcf08..78936011fd 100644 --- a/docs/docs/guide/design/materialParser.md +++ b/docs/docs/guide/design/materialParser.md @@ -3,7 +3,7 @@ title: 入料模块设计 sidebar_position: 2 --- ## 介绍 -入料模块负责物料接入,通过自动扫描、解析源码组件,产出一份符合《中后台低代码组件描述协议》的** **JSON Schema。这份 Schema 包含基础信息和属性描述信息部分,低代码引擎会基于它们在运行时自动生成一份configure 配置,用作设置面板展示。 +入料模块负责物料接入,通过自动扫描、解析源码组件,产出一份符合《中后台低代码组件描述协议》的** **JSON Schema。这份 Schema 包含基础信息和属性描述信息部分,低代码引擎会基于它们在运行时自动生成一份 configure 配置,用作设置面板展示。 ## npm 包与仓库信息 @@ -15,7 +15,7 @@ sidebar_position: 2 ### 整体流程 大体分为本地化、扫描、解析、转换、校验 5 部分,如下图所示。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644396777217-58246e52-b5b9-4509-8bac-db2820535c39.png#clientId=u41c9ba96-15b6-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u8b5a70fd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=206&originWidth=2116&originalType=url&ratio=1&rotation=0&showTitle=false&size=51634&status=done&style=none&taskId=u76c5b45a-6fa8-404e-8d8b-f1d6f38438e&title=) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01sXf5fL1E5RcRxAlM1_!!6000000000300-2-tps-2116-206.png) ### 静态解析 在静态分析时,分为 JS 和 TS 两种情况。 @@ -23,48 +23,58 @@ sidebar_position: 2 #### 静态解析 JS 在 JS 情况下,基于 react-docgen 进行扩展,自定义了 resolver 及 handler,前者用于寻找组件定义,后者用于解析 propTypes、defaultProps 等信息,整体流程图如下: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644396777192-c9d3c3b3-c7d2-4780-b7dc-632349b00edb.png#clientId=u41c9ba96-15b6-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u3edfb33c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=478&originWidth=2176&originalType=url&ratio=1&rotation=0&showTitle=false&size=93513&status=done&style=none&taskId=ua23bd89a-3d0c-43cf-936b-13080cdc5ef&title=) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01VrhkEb1R6tsntvGhV_!!6000000002063-2-tps-2176-478.png) -react-docgen 使用 babel 生成语法树,再使用 ast-types 进行遍历去寻找组件节点及其属性类型定义。原本的 react-docgen 只能解析单文件,且不能解析 IIFE、逗号表达式等语法结构(一般出现在转码后的代码中)。笔者对其进行改造,使之可以递归解析多文件去查找组件定义,且能够解开 IIFE,以及对逗号表达式进行转换,以方便后续的组件解析。另外,还增加了子组件解析的功能,即类似 `Button.Group = Group` 这种定义。 +react-docgen 使用 babel 生成语法树,再使用 ast-types 进行遍历去寻找组件节点及其属性类型定义。原本的 react-docgen 只能解析单文件,且不能解析 IIFE、逗号表达式等语法结构 (一般出现在转码后的代码中)。笔者对其进行改造,使之可以递归解析多文件去查找组件定义,且能够解开 IIFE,以及对逗号表达式进行转换,以方便后续的组件解析。另外,还增加了子组件解析的功能,即类似 `Button.Group = Group` 这种定义。 #### 静态解析 TS 在 TS 情况下,还要再细分为 TS 源码和 TS 编译后的代码。 -TS 源码中,React 组件具有类型签名;TS 编译后的代码中,dts 文件(如有)包含全部的 class / interface / type 类型信息。可以从这些类型信息中获取组件属性描述。整体流程图如下: +TS 源码中,React 组件具有类型签名;TS 编译后的代码中,dts 文件 (如有) 包含全部的 class / interface / type 类型信息。可以从这些类型信息中获取组件属性描述。整体流程图如下: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644396777193-14c74287-d0cb-4864-ba64-9259a88c8b99.png#clientId=u41c9ba96-15b6-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=ud7fc6e1a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=240&originWidth=2280&originalType=url&ratio=1&rotation=0&showTitle=false&size=59331&status=done&style=none&taskId=u711959ae-241a-48c9-a446-59b9fcdc52e&title=) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN014lOIIy1FUvGW6wcYZ_!!6000000000491-2-tps-2280-240.png) -react-docgen 内置了 TypeScript 的 babel 插件,所以也具备解析 interface 的能力,可惜能力有限,babel 只能解析 TS 代码,但没法做类型检查,类型处理是由 react-docgen 实现的,它对于extends/implements/utility 的情况处理不好,并且没有类型推断,虽然可以对其功能进行完善,不过这种情况下,应该借助 TypeScript Compiler 的能力,而非自己造轮子。通过调研,发现市面上有 typescript-react-docgen 这个项目。它在底层依赖了 TypeScript,且产出的数据格式与 react-docgen 一致,所以我们选择基于它进行解析。 +react-docgen 内置了 TypeScript 的 babel 插件,所以也具备解析 interface 的能力,可惜能力有限,babel 只能解析 TS 代码,但没法做类型检查,类型处理是由 react-docgen 实现的,它对于 extends/implements/utility 的情况处理不好,并且没有类型推断,虽然可以对其功能进行完善,不过这种情况下,应该借助 TypeScript Compiler 的能力,而非自己造轮子。通过调研,发现市面上有 typescript-react-docgen 这个项目。它在底层依赖了 TypeScript,且产出的数据格式与 react-docgen 一致,所以我们选择基于它进行解析。 TypeScript Compiler 会递归解析某个文件中出现及引用的全部类型,当然,前提是已经定义或安装了相应的类型声明。typescript-react-docgen 会调用 TypeScript Compiler 的 API,获取每个文件输出的类型,判断其是否为 React 组件。满足下列条件之一的,会被判定为 React 组件: -1. 获取其函数签名,如果只有一个入参,或者第一个入参名称为 props ,会被判定为函数式组件; +1. 获取其函数签名,如果只有一个入参,或者第一个入参名称为 props,会被判定为函数式组件; 2. 获取其 `constructor` 方法,如果其返回值包含 props 属性,会被判定为有状态组件。 然后,遍历组件的 props 类型,获取每个属性的类型签名字符串,比如 `(a: string) => void`。typescript-react-docgen 可以克服 react-docgen 解析 TypeScirpt 类型的问题,但是每个类型都以字符串的形式来呈现,不利于后续的解析。所以,笔者对其进行了扩展,递归解析每一层的属性值。此外,在函数式组件的判定上,笔者做了完善,会看函数的返回值是否为 `ReactElement` ,若是,才为函数式组件。 下面讲对于一些特殊情况的处理。 + **循环定义** + TypeScript 类型可以循环定义,比如下面的 JSON 类型: + ```typescript interface Json { [x: string]: string | number | boolean | Json | JsonArray; } type JsonArray = Array; ``` + 因为低代码组件描述协议中没有引用功能,而且也不方便在界面上展示出来,所以这种循环定义无需完全解析,入料模块会在检测到循环定义的时候,把类型简化为 `object` 。对于特殊的类型,如 JSON,可以用相应的 Setter 来编辑。 **复杂类型** TypeScript Compiler 会将合成类型的所有属性展开,比如 `boolean | string`,会被展开为 `true | false | string`,这带来了不必要的精确,我们需要的只是 `boolean | string` 而已。当然,对于这个例子,我们很容易把它还原回 `boolean | string`,然而,对于诸如 `React.ButtonHTMLAttributes & {'data-name': string}` 这种类型,它会把 `ButtonHTMLAttributes` 中众多的属性和 `data-name` 混杂在一起,完全无法分辨,只能以展开的形式提供。这 100 多个属性,如果都放在设置面板,绝对是使用者的噩梦,所以,其结果会被简化为 `object` 。当然,即使没有 `{'data-name': string}`,`ButtonHTMLAttributes` 也是没有单独的 Setter 的,同样会被简化为 `object` 。 ### 动态解析 + 当一个组件,使用静态解析无法入料时,会使用动态解析。 + 整体流程图如下: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644396776984-d390ec0c-33c6-4468-b68c-555a263b097e.png#clientId=u41c9ba96-15b6-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=ube12dcbd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=449&originWidth=2516&originalType=url&ratio=1&rotation=0&showTitle=false&size=84334&status=done&style=none&taskId=ube349a5b-94c0-4a77-9bf3-ffe453226e1&title=) + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01dJ62Dm1u5de8GihG6_!!6000000005986-2-tps-2516-449.png) + 基本思想很简单,require 组件进来,然后读取其组件类上定义的 propTypes 和 defaultProps 属性。这里使用了 parse-prop-types 库,使用它的时候必须在组件之前引用,因为它会先对 prop-types 库进行修改,在每个 PropTypes 透出的函数上挂上类型,比如 string, number 等等,然后再去遍历。动态解析可以解析出全部的类型信息,因为 PropTypes 有可能引入依赖组件的一些类型定义,这在静态解析中很难做到,或者成本较高,而对于动态解析来说,都由运行时完成了。 ##### 技术细节 -值得注意的是,有些 js 文件里还会引入 css 文件,而且从笔者了解的情况来看,这种情况在集团内部不在少数。这种组件不配合 webpack 使用,肯定会报错,但是使用 webpack 会明显拖慢速度,所以笔者采用了sandbox 的方式,对 require 进来的类 css 文件进行 mock。这里,笔者使用了 vm2 这个库,它对 node 自带的 vm 进行了封装,可以劫持文件中的 require 方法。因为 parse-prop-types 的修改在沙箱中会失效,所以笔者也 mock 了组件中的 prop-types 库。 + +值得注意的是,有些 js 文件里还会引入 css 文件,而且从笔者了解的情况来看,这种情况在集团内部不在少数。这种组件不配合 webpack 使用,肯定会报错,但是使用 webpack 会明显拖慢速度,所以笔者采用了 sandbox 的方式,对 require 进来的类 css 文件进行 mock。这里,笔者使用了 vm2 这个库,它对 node 自带的 vm 进行了封装,可以劫持文件中的 require 方法。因为 parse-prop-types 的修改在沙箱中会失效,所以笔者也 mock 了组件中的 prop-types 库。 ### 整体大图 把上述的静态解析和动态解析流程结合起来,可以得到以下大图。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644396777248-9e26dd26-51ac-473e-ae66-c08f8bed3aeb.png#clientId=u41c9ba96-15b6-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=ue6806530&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1072&originWidth=2658&originalType=url&ratio=1&rotation=0&showTitle=false&size=184784&status=done&style=none&taskId=u0d982b36-25b8-442f-8d98-43b9e1629bb&title=) + +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01TA9lQp27QmwVT7WUC_!!6000000007792-2-tps-2658-1072.png) diff --git a/docs/docs/guide/design/renderer.md b/docs/docs/guide/design/renderer.md index 74674bcdbb..417c50de83 100644 --- a/docs/docs/guide/design/renderer.md +++ b/docs/docs/guide/design/renderer.md @@ -2,12 +2,13 @@ title: 渲染模块设计 sidebar_position: 4 --- -# 低代码渲染介绍 +## 低代码渲染介绍 + + -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644398134750-7b352564-a400-460e-a189-e72ef551624f.png#clientId=udd4eb4ee-bdb1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=198&id=OSLhL&margin=%5Bobject%20Object%5D&name=image.png&originHeight=872&originWidth=1440&originalType=binary&ratio=1&rotation=0&showTitle=false&size=193396&status=done&style=none&taskId=ua5d2ae84-0117-4744-a49c-bd3dd1b8a5e&title=&width=327) 基于 Schema 和物料组件,如何渲染出我们的页面?这一节描述的就是这个。 -# npm 包与仓库信息 +## npm 包与仓库信息 - React 框架渲染 npm 包:@alilc/lowcode-react-renderer - Rax 框架渲染 npm 包:@alilc/lowcode-rax-renderer @@ -16,22 +17,25 @@ sidebar_position: 4 - packages/react-renderer - packages/react-simulator-renderer -# 渲染框架原理 -## 整体架构 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644398135242-d83a9d48-c244-4869-b61e-70e825006727.png#clientId=udd4eb4ee-bdb1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=531&id=udb49df4c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1062&originWidth=1686&originalType=binary&ratio=1&rotation=0&showTitle=false&size=821823&status=done&style=none&taskId=u90381546-a7a8-4099-b24f-844b8489f4d&title=&width=843) +## 渲染框架原理 +### 整体架构 + +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01i4IiSR1cMtUFXaWQq_!!6000000003587-2-tps-1686-1062.png) -- 协议层:基于标准的《阿里巴巴中后台前端搭建协议规范》产出的 Schema 作为我们的规范协议。 +- 协议层:基于《低代码引擎搭建协议规范》](/site/docs/specs/lowcode-spec) 产出的 Schema 作为我们的规范协议。 - 能力层:提供组件、区块、页面等渲染所需的核心能力,包括 Props 解析、样式注入、条件渲染等。 - 适配层:由于我们使用的运行时框架不是统一的,所以统一使用适配层将不同运行框架的差异部分,通过接口对外,让渲染层注册/适配对应所需的方法。能保障渲染层和能力层直接通过适配层连接起来,能起到独立可扩展的作用。 - 渲染层:提供核心的渲染方法,由于不同运行时框架提供的渲染方法是不同的,所以其通过适配层进行注入,只需要提供适配层所需的接口,即可实现渲染。 - 应用层:根据渲染层所提供的方法,可以应用到项目中,根据使用的方法和规模即可实现应用、页面、区块的渲染。 -## 核心解析 +### 核心解析 + 这里主要解析一下刚刚提到的架构中的适配层和渲染层。 -### 适配层 + +#### 适配层 适配层提供的是各个框架之间的差异项。比如 `React.createElement` 和 `Rax.createElement` 方法是不同的。所以需要在适配层对 API 进行抹平。 -#### React +##### React ```typescript import { createElement } from 'react'; import { @@ -42,7 +46,7 @@ adapter.setRuntime({ createElement, }); ``` -#### Rax +##### Rax ```typescript import { createElement } from 'rax'; import { @@ -69,10 +73,12 @@ adapter.setRuntime({ - `ComponentRenderer`:组件渲染的方法。 - `BlockRenderer`:区块渲染的方法。 -### 渲染层 -#### React Renderer +#### 渲染层 +##### React Renderer 内部的技术栈统一都是 React,大多数适配层的 API 都是按照 React 来设计的,所以对于 React Renderer 来说,需要做的不多。 + React Renderer 的代码量很少,主要是将 React API 注册到适配层中。 + ```typescript import React, { Component, PureComponent, createElement, createContext, forwardRef, ReactInstance, ContextType } from 'react'; import ReactDOM from 'react-dom'; @@ -112,7 +118,7 @@ adapter.setRenderers({ adapter.setConfigProvider(ConfigProvider); ``` -#### Rax Renderer +##### Rax Renderer Rax 的大多数 API 和 React 基本也是一致的,差异点在于重写了一些方法。 ```typescript import { Component, PureComponent, createElement, createContext, forwardRef } from 'rax'; @@ -146,8 +152,8 @@ adapter.setRenderers({ }); ``` -## 多模式渲染 -### 预览模式渲染 +### 多模式渲染 +#### 预览模式渲染 预览模式的渲染,主要是通过 Schema、components 即可完成上述的页面渲染能力。 ```typescript import ReactRenderer from '@ali/lowcode-react-renderer'; @@ -183,11 +189,11 @@ ReactDOM.render(( ), document.getElementById('root')); ``` -### 设计模式渲染(Simulator) +#### 设计模式渲染(Simulator) 设计模式渲染就是将编排生成的《搭建协议》渲染成视图的过程,视图是可以交互的,所以必须要处理好内部数据流、生命周期、事件绑定、国际化等等。也称为画布的渲染,画布是 UI 编排的核心,它一般融合了页面的渲染以及组件/区块的拖拽、选择、快捷配置。 画布的渲染和预览模式的渲染的区别在于,画布的渲染和设计器之间是有交互的。所以在这里我们新增了一层 `Simulator` 作为设计器和渲染的连接器。 `Simulator` 是将设计器传入的 `DocumentModel` 和组件/库描述转成相应的 Schema 和 组件类。再调用 Render 层完成渲染。我们这里介绍一下它提供的能力。 -#### 整体架构 +##### 整体架构 ![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644398136330-0f48202b-b581-4b1f-af79-72a667a194d9.png#clientId=udd4eb4ee-bdb1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=432&id=u734b5c16&margin=%5Bobject%20Object%5D&name=image.png&originHeight=864&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&size=572012&status=done&style=none&taskId=u7d7cf569-d5a9-4bea-9b2d-1121b85728f&title=&width=750) - `Project`:位于顶层的 Project,保留了对所有文档模型的引用,用于管理应用级 Schema 的导入与导出。 @@ -200,11 +206,11 @@ ReactDOM.render(( - `SettingField`:它连接属性设置器 `Setter` 与属性模型 `Prop`,它是实现多节点属性批处理的关键。 - 通用交互模型:内置了拖拽、活跃追踪、悬停探测、剪贴板、滚动、快捷键绑定。 -#### 模拟器介绍 +##### 模拟器介绍 ![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644398137096-260646a0-f264-48af-9600-6f7141a6a1d8.png#clientId=udd4eb4ee-bdb1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=370&id=ubfb08f11&margin=%5Bobject%20Object%5D&name=image.png&originHeight=740&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&size=353179&status=done&style=none&taskId=u3cd764bb-52f6-47a6-8026-fee6a36d08d&title=&width=750) - 运行时环境:从运行时环境来看,目前我们有 React 生态、Rax 生态。而在对外的历程中,我们也会拥有 Vue 生态、Angular 生态等。 - 布局模式:不同于 C 端营销页的搭建,中后台场景大多是表单、表格,流式布局是主流的选择。对于设计师、产品来说,是需要绝对布局的方式来进行页面研发的。 - 研发场景:从研发场景来看,低代码搭建不仅有页面编排,还有诸如逻辑编排、业务编排的场景。 -基于以上思考,我们通过基于沙箱隔离的模拟器技术来实现了多运行时环境(如 React、Rax、小程序、Vue)、多模式(如流式布局、自由布局)、多场景(如页面编排、关系图编排)的 UI 编排。通过注册不同的运行时环境的渲染模块,能够实现编辑器从 React 页面搭建到 Rax 页面搭建的迁移。通过注册不同的模拟器画布,你可以基于 G6或者 mxgraph 来做关系图编排。你可以定制一个流式布局的画布,也可以定制一个自由布局的画布。 +基于以上思考,我们通过基于沙箱隔离的模拟器技术来实现了多运行时环境(如 React、Rax、小程序、Vue)、多模式(如流式布局、自由布局)、多场景(如页面编排、关系图编排)的 UI 编排。通过注册不同的运行时环境的渲染模块,能够实现编辑器从 React 页面搭建到 Rax 页面搭建的迁移。通过注册不同的模拟器画布,你可以基于 G6 或者 mxgraph 来做关系图编排。你可以定制一个流式布局的画布,也可以定制一个自由布局的画布。 diff --git a/docs/docs/guide/design/setter.md b/docs/docs/guide/design/setter.md index 66de03bb1c..968e7bbf8c 100644 --- a/docs/docs/guide/design/setter.md +++ b/docs/docs/guide/design/setter.md @@ -2,22 +2,27 @@ title: 设置器设计 sidebar_position: 6 --- + 设置器,又称为 Setter,是作为物料属性和用户交互的重要途径,在编辑器日常使用中有着非常重要的作用,本文重点介绍 Setter 的设计原理和使用方式,帮助用户更好的理解 Setter。 + 在编辑器的右边区域,Setter 的区块就展现在这里,如下图: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644404887956-8ffc8c8c-380c-4843-8bc9-512be77a9b18.png#clientId=u4cc5b992-0df5-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=865&id=wNOuZ&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1730&originWidth=3836&originalType=binary&ratio=1&rotation=0&showTitle=false&size=947162&status=done&style=none&taskId=ue623b488-8774-401a-b80c-c102e8aac8f&title=&width=1918) + +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01qEjjoQ24QNkD42wzl_!!6000000007385-2-tps-3836-1730.png) + 其中包含 属性、样式、事件、高级: - 属性:展示该物料常规的属性; - 样式:展示该物料样式的属性; - 事件:如果该物料有声明事件,则会出现事件面板,用于绑定事件; - 高级:两个逻辑相关的属性,**条件渲染**和**循环。** -# npm 包与仓库信息 +## npm 包与仓库信息 - npm 包:@alilc/lowcode-engine-ext - 仓库:[https://github.com/alibaba/lowcode-engine-ext](https://github.com/alibaba/lowcode-engine-ext) -# 设置器模块原理 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644404909143-eede0a27-e990-4333-816a-d2d0cf2594b3.png#clientId=u4cc5b992-0df5-4&crop=0&crop=0&crop=1&crop=1&height=482&id=PyO6v&name=image.png&originHeight=964&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=273494&status=done&style=none&taskId=ufb317b56-de50-4693-8c39-8faa9b38307&title=&width=767) +## 设置器模块原理 + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01EAmitQ1U5TUws63AV_!!6000000002466-2-tps-1534-964.png) 设置面板依赖于以下三块抽象 @@ -25,7 +30,8 @@ sidebar_position: 6 - 设置对象 `settingTarget`,主要包含:选中的节点、是否同一值、值的储存等 - 设置列 `settingField`,主要和当前设置视图相关,包含视图的 `ref`、以及设置对象 `settingTarget` -#### SettingTarget 抽象 +### SettingTarget 抽象 + 如果不是多选,可以直接暴露 `Node` 给到这,但涉及多选编辑的时候,大家的值时通常是不一样的,设置的时候需要批量设置进去,这里主要封装这些逻辑,把多选编辑的复杂性屏蔽掉。 所选节点所构成的**设置对象**抽象如下: @@ -49,7 +55,7 @@ interface SettingTarget { } ``` -基于设置对象所派生的**设置目标属性**抽象如下: +基于设置对象所派生的**设置目标属性**抽象如下: ```typescript interface SettingTargetProp extends SettingTarget { @@ -68,8 +74,8 @@ interface SettingTargetProp extends SettingTarget { } ``` -#### SettingField 抽象 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644396933393-779423e2-29a7-4e97-9ef9-e3c7964a5412.png#clientId=u41c9ba96-15b6-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=201&id=uc71z&margin=%5Bobject%20Object%5D&name=image.png&originHeight=402&originWidth=2022&originalType=binary&ratio=1&rotation=0&showTitle=false&size=218611&status=done&style=none&taskId=u534089f2-363d-464e-8c69-ac79f268f5a&title=&width=1011) +### SettingField 抽象 +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01D855j01j8sg9GdtJr_!!6000000004504-2-tps-2022-402.png) ```typescript interface SettingField extends SettingTarget { diff --git a/docs/docs/guide/design/specs.md b/docs/docs/guide/design/specs.md index be449e3dc1..3e2b1342c8 100644 --- a/docs/docs/guide/design/specs.md +++ b/docs/docs/guide/design/specs.md @@ -1,31 +1,51 @@ --- -title: 低代码引擎协议栈简介 +title: 协议栈简介 sidebar_position: 1 --- -# 什么是低代码协议 -这是两份中后台低代码领域的标准协议,即《低代码引擎物料协议规范》和《低代码引擎搭建协议规范》。它们保障了低代码领域的标准化,成为了生态建设和流通的基石。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1648642508161-64dd3a2c-d2d2-43ed-92e4-ead40ab62498.png#clientId=ub4563dfd-c5b1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=532&id=u60966832&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1064&originWidth=1928&originalType=binary&ratio=1&rotation=0&showTitle=false&size=974317&status=done&style=none&taskId=u88a8512e-a57c-43f6-a01f-19f6878b7a0&title=&width=964) -# 为什么需要协议 +## 什么是低代码协议 +低代码引擎体系基于三份协议来构建,分别是 [《低代码引擎搭建协议规范》](/site/docs/specs/lowcode-spec)、[《低代码引擎物料协议规范》](/site/docs/specs/material-spec)和[《低代码引擎资产包协议规范》](/site/docs/specs/assets-spec), 它们保障了低代码领域的标准化,成为了生态建设和流通的基石。 + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01axsOyW1s01YgXnT8z_!!6000000005703-2-tps-1888-1000.png) + +## 为什么需要协议 + 首先,我们做一个不恰当的类比,我们将低代码引擎和 JavaScript 语言做一下类别。还记得之前,大家都被浏览器兼容性支配的恐惧,特别是 IE 和其他浏览器,对上层 API 实现的不一致,导致一份代码需要运行在两端需要做适配。当浏览器 / JavaScript 相关的标准出现之后,各个浏览器进行了 API 的统一,使得我们终于可以从这部分工作中解放出来(PS:Babel 对于语言特性的转换是另一个方面的问题)。 + 而在《低代码引擎搭建协议规范》出现之前,低代码领域也有类似的问题。 -## 概念不通 + +### 概念不通 + 在交流的过程中,一些对于搭建产品的术语的不一致,导致了一些沟通成本,不管是在文章分享、技术分享、交流会上,都会有这个问题。 -## 物料孤岛 + +### 物料孤岛 + 由于低代码产品实现的方式不同,物料的消费方式也各不相同。这里分为两种物料,低代码物料和 ProCode 物料。 + 对于低代码物料来说,A 平台创建的物料无法使用到 B 平台上,如果想在 B 平台实现同样的物料,需要按照 B 平台的标准搭建一份物料。 + 对于 ProCode 物料来说,需要在低代码平台进行消费,是需要进行转换的,包括搭建配置项的生成、物料搭建试图等,可能还需要特殊的描述文件进行描述。由于这一层没有统一,同一份 ProCode 物料每接入一个低代码,可能需要的描述文件格式不同,转换的代码不同,使用的工具也不同。 -## 生态隔离 -不同低代码平台的生态体系也不相同,有的低代码平台的物料生态不错,有的低代码平台的搭建体验生态不错。但是这些利好的生态,都是无法互通的,甚至就算知道了代码,也无法复用,因为底层是不一致的。对于集团来说,每一个平台都创建一份自己的生态,这并不是利好的。 -## 技术深度不够 + +### 生态隔离 + +不同低代码平台的生态体系也不相同,有的低代码平台的物料生态不错,有的低代码平台的搭建体验生态不错。但是这些利好的生态,都是无法互通的,甚至就算知道了代码也无法复用,因为底层是不一致的。对于阿里巴巴集团来说,每一个平台都创建一份自己的生态,这并不是利好的。 + +### 低水平重复建设 + 大家可能觉得,以上问题对于自己造轮子来说,其实也是有利的,因为自己得到了技术上的成长。 -但是对于低代码的平台方,实际上更多的工作,在物料的转化、物料的生成、搭建体验的小优化、部分其他平台生态的实现。这些的技术深度其实并不高。 -## 价值不高 + +但是对于低代码的平台方,实际上更多的工作,在物料的转化、物料的生成、搭建体验的小优化、部分其他平台生态的实现。这些的技术深度其实并不高,属于低水平重复建设部分。 + +### 价值不高 + 如果每个业务都要从 0 开始做,做自己的平台,会花费大量的时间来构建底层基础设施,对业务本身而言并不是一件好事;而且前端领域的底层基础设施都大同小异,不同团队重复构建造成了极大的资源浪费。 + 这样的建设,会导致从 0 到 1 都需要花费大量的时间,往往在内部人力不足、投入有限时,产品很容易在未发展壮大的时候就面临了死亡相关的决策。 + 设想一下,如果可以开发一份全集团低代码平台都可以使用的物料,是否更有成就感呢?如果可以基于已有生态进行低代码平台的快速落地,而不是花费 1-2 年搭建一个可用的低代码平台,再验证市场。在快速的验证之后,再进行更深入的打磨,这其中的思考和技术含量是否更优于之前的模式呢? -比如不同平台的低代码物料 -1. vc-deep — vc 协议 + Deep 组件库(企业智能基于 Fusion Next 定制); +以 2019 年的阿里巴巴的情况举例,不同平台的低代码物料但不限于: + +1. vc-deep — vc 协议 + Deep 组件库 (阿里巴巴企业智能团队基于 Fusion Next 定制); 2. Iceluna 协议 + Fusion Next; 3. AIMake 物料; 4. vc-fusion-basic + 业务改造 — vc 协议 + Fusion Next(各业务 Fork 定制); @@ -33,28 +53,37 @@ sidebar_position: 1 6. vc 协议 + antd; 可以看到,各个搭建平台都需要维护一套自己的基础组件库,这是非常不合理的,对基础组件库的维护会分散开发同学完成业务目标的精力。 -建立统一的低代码领域标准化,是百利而无一害的。于是,在阿里巴巴集团2020财年进行了讨论,建立了搭建治理&物料流通战役,此战役便产出了《低代码引擎物料协议规范》、《低代码引擎搭建协议规范》两份规范,成为了低代码引擎和其生态的基础。 -# 协议的作用 -基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,集团各类中后台研发系统生产的物料可借助物料中心进行跨系统流通,通过丰富物料生态的共享提升阿里巴巴中后台研发系统的效率。同时完成低代码引擎的标准统一以及低代码搭建中台能力的输出,帮助业务方快速孵化本业务域中后台研发系统。 -## 打破物料孤岛 -### 物料中心 -在《低代码引擎物料协议规范》成立了之后,规范先行建立了阿里巴巴各个中后台研发平台沟通、对话的基础,物料流通的先决条件已经成熟,这个时候我们还需要一个统一的物料源,用于管理物料的上传、存储、检索、分发,一个典型的中心化架构,类似 npm 的管理,这便是我们物料中心。 +建立统一的低代码领域标准化,是百利而无一害的。于是,在阿里巴巴集团 2020 年进行了讨论,建立了搭建治理&物料流通战役,此战役便产出了上文中的协议规范,成为了低代码引擎和其生态的基础。 + +## 协议的作用 + +基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,基于统一的协议,我们完成业务组件、区块、模板等各类物料的标准统一,各类中后台研发系统生产的物料可借助物料中心进行跨系统流通,通过丰富物料生态的共享提升各平台研发系统的效率。同时完成低代码引擎的标准统一以及低代码搭建中台能力的输出,帮助业务方快速孵化本业务域中后台研发系统。 + +### 打破物料孤岛 + +#### 物料中心 + +这里以阿里集团的前端物料中间建设为例,在《低代码引擎物料协议规范》落地之后,建立了阿里巴巴各个中后台研发平台沟通、对话的基础,物料流通的先决条件已经成熟,这个时候我们还需要一个统一的物料源,用于管理物料的上传、存储、检索、分发,一个典型的中心化架构,类似 npm 的管理,这便是我们物料中心。 + Fusion Market 是物料中心的前身,它提供了业务组件的存储、文档展示和全局透出的功能,由于 fusion 体系在集团内的广泛使用,Fusion Market 沉淀了不少的业务组件,但是这个项目却一直不温不火,只看到业务组件数量的增加,却未看到物料流通起来。其中一个原因是,没有阿里巴巴前端委员会的背书,规范很难统一,规范如果不统一,物料就很难流通; + 在规范成立之后,物料中心也将有了建设的基础,最终于 2019 年建立了物料中心,提供了物料流通的平台能力。 -### 低代码基础物料 + +#### 低代码基础物料 + 就像 AntD、Element 之于源码研发模式,在低代码研发模式下各个搭建平台也需要一套统一的、开箱即用的低代码基础组件库。基于低代码描述协议完成了两份低代码基础物料的建设,即“Fusion 低代码基础组件库”和“AntD 低代码基础组件库”。 -### 源码组件低代码化 + +#### 源码组件低代码化 + 将源码组件一键转化为低代码物料,符合低代码物料规范,可以在低代码平台进行流通。 ### 低代码物料中心 -当低代码物料积累到一定的量级之后,所有的搭建平台的业务物料越来越多。这些物料通过低代码物料中心进行统一的管理和消费。 -## Setter 生态的基础 -Snippet(组件默认搭建 schema )由《低代码引擎搭建协议规范》定义,低代码引擎会按照规范对组件进行渲染,Configure 由《低代码引擎物料协议规范》定义,它描述了组件的 props 以及每个 prop 对应的 setter (Prop 配置面板),低代码引擎提供了 14 个内置 Setter,但如果我们组件的 props 超出了引擎内置 setter 的范围,就需要我们自己来开发对应 Setter。 -setter 最终也慢慢形成了自己的生态,这使得开发物料更加容易,可以使用已有的 setter 生态,进行物料配置描述。 -## 低代码引擎实现标准 -低代码引擎是以上生态的消费端,它是实现了标准协议的低代码引擎。这是不可或缺的部分,低代码引擎这里就相当于一个标准浏览器,一方面给其他的低代码平台提供了一个 Demo,其他平台可以参考低代码引擎进行实现,满足官方协议,便也可以消费相关的物料生态和其他生态。 -通过物料中心实现集团各业务域物料跨系统流通是第一步,通过低代码引擎快速搭建出来的各业务域低代码平台平滑高效地使用各业务域物料,提升集团中后台研发系统的效率是关键的第二步。 +当低代码物料积累到一定的量级之后,所有的搭建平台的业务物料越来越多。这些物料通过低代码物料中心进行统一的管理和消费。 +### 设置器生态的基础 +Snippet(组件默认搭建 schema ) 由《低代码引擎搭建协议规范》定义,低代码引擎会按照规范对组件进行渲染,Configure 由《低代码引擎物料协议规范》定义,它描述了组件的 props 以及每个 prop 对应的设置器 (Prop 配置面板),低代码引擎提供了 20+ 个内置设置器,但如果我们组件的 props 超出了引擎内置设置器的范围,就需要我们自己来开发对应设置器。 +设置器最终也慢慢形成了自己的生态,这使得开发物料更加容易,可以使用已有的生态中的设置器,进行物料配置描述。 +### 低代码引擎实现标准 -其中入料模块,使得任意符合物料协议的物料都可以被消费,也就打破了物料孤岛,实现物料之间的流通。 +低代码引擎是以上生态的消费端,它是实现了标准协议的低代码引擎。这是不可或缺的部分,低代码引擎这里就相当于一个标准浏览器,一方面给其他的低代码平台提供了一个 Demo,其他平台可以参考低代码引擎进行实现,满足官方协议,便也可以消费相关的物料生态和其他生态。 diff --git a/docs/docs/guide/design/summary.md b/docs/docs/guide/design/summary.md index 604886e8b7..cd5edfd886 100644 --- a/docs/docs/guide/design/summary.md +++ b/docs/docs/guide/design/summary.md @@ -1,46 +1,55 @@ --- -title: 低代码引擎架构综述 +title: 架构综述 sidebar_position: 0 --- ## 分层架构描述 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644392855407-44040c3e-f98e-4e93-a7ba-7efc0a7927fb.png#clientId=ue3f00c22-d0cc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=540&id=u0d1fdc91&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1080&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=177518&status=done&style=none&taskId=u0ac7d0a3-e838-4982-ad41-e830af33545&title=&width=960) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN016l8gDo1z7zlRlW1P0_!!6000000006668-2-tps-1920-1080.png) + 我们设计了这样一套分层架构,自下而上分别是协议 - 引擎 - 生态 - 平台。 -底层协议栈定义的是标准,**标准的统一让上层产物的互通成为可能**, -**引擎是对协议的实现,同时通过能力的输出,向上支撑生态开放体系,提供各种生态扩展能力,** -那么生态就好理解了,是基于引擎核心能力上扩展出来的,比如物料、设置器、插件等,还有工具链支撑开发体系, -最后,各个平台基于引擎内核以及生态中的产品组合、衔接形成满足其需求的低代码平台。 + +- 底层协议栈定义的是标准,**标准的统一让上层产物的互通成为可能**。 +- 引擎是**对协议的实现**,同时通过能力的输出,向上**支撑生态开放体系**,提供各种生态扩展能力。 +- 生态就好理解了,是基于引擎核心能力上扩展出来的,比如物料、设置器、插件等,还有工具链支撑开发体系。 +- 最后,各个平台基于引擎内核以及生态中的产品组合、衔接形成满足其需求的低代码平台。 + **每一层都明确自身的定位,各司其职,协议不会去思考引擎如何实现,引擎也不会实现具体上层平台功能,上层平台的定制化均通过插件来实现,这些理念将会贯穿我们体系设计、实现的过程。** ## 引擎内核简述 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644393521380-2b5dda70-cd35-4cc2-aeae-6d0ba98deccd.png#clientId=ue3f00c22-d0cc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=540&id=u6b0dd5f3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1080&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=330340&status=done&style=none&taskId=u39127ebd-dbac-4636-9cb5-5c4833146a1&title=&width=960) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01QUUVu21LjTXqY6H8I_!!6000000001335-2-tps-1920-1080.png) + +低代码引擎分为 4 大模块,入料 - 编排 - 渲染 - 出码: -低代码引擎分为 4 大模块,入料 - 编排 - 渲染 - 出码。 -入料模块就是将外部的物料,比如海量的 npm 组件,按照《物料描述协议》进行描述。 -**注意,这里仅是增加描述,而非重写一套,这样我们能最大程度复用ProCode体系已沉淀的组件。** -将描述后的数据通过引擎 API 注册后,在编辑器中使用。 -编排,本质上来讲,就是**不断在生成符合《搭建协议》的页面描述,将编辑器中的所有物料,进行布局设置、组件 CRUD 操作、以及 JS/CSS编写/逻辑编排**等,最终转换成页面描述,技术细节待会儿我们再展开讲讲。 -渲染,顾名思义,就是**将编排生成的页面描述结构渲染成视图的过程**,视图是面向用户的,所以必须处理好内部数据流、生命周期、事件绑定、国际化等。 -出码,就是**将页面描述结构解析和转换成应用代码的机制**。 +- 入料模块就是将外部的物料,比如海量的 npm 组件,按照《物料描述协议》进行描述。将描述后的数据通过引擎 API 注册后,在编辑器中使用。 + > **注意,这里仅是增加描述,而非重写一套,这样我们能最大程度复用 ProCode 体系已沉淀的组件。** +- 编排,本质上来讲,就是**不断在生成符合[《低代码引擎搭建协议规范》](/site/docs/specs/lowcode-spec)的页面描述,将编辑器中的所有物料,进行布局设置、组件 CRUD 操作、以及 JS / CSS 编写/ 逻辑编排 **等,最终转换成页面描述,技术细节后文会展开。 +- 渲染,顾名思义,就是**将编排生成的页面描述结构渲染成视图的过程**,视图是面向用户的,所以必须处理好内部数据流、生命周期、事件绑定、国际化等。 +- 出码,就是**将编排过程产生的符合[《低代码引擎搭建协议规范》](/site/docs/specs/lowcode-spec)的页面描述转换成另一种 DSL 或 编程语言代码的过程**。 ## 引擎生态简述 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644393489755-b9a6a471-c099-480b-b40b-3094b793394d.png#clientId=ue3f00c22-d0cc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=540&id=u81ccc9e2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1080&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=504671&status=done&style=none&taskId=u52008ac0-e9c6-407b-a59e-7dbf4c02c0c&title=&width=960) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01LkRseZ23W31l8DPzS_!!6000000007262-2-tps-1920-1080.png) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644397483218-2b58bfca-94b1-474e-8983-afc757f20e59.png#clientId=uafdaa655-f89e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=540&id=u3aeacdac&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1080&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=394834&status=done&style=none&taskId=udcd28484-1df2-484c-9f98-87175972d65&title=&width=960) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01PYBVfZ1hL82XPrXzX_!!6000000004260-2-tps-1920-1080.png) 引擎生态主要分为 3 部分,物料、设置器和插件。 + ### 物料生态 + 物料是低代码平台的生产资料,没有物料低代码平台则变成了无源之水无本之木。低代码平台的物料即低代码组件。因此低代码物料生态指的是: -1)低代码物料生产能力和规范。 -2)对低代码物料进行统一管理的物料中心。 -3)基于 Fusion Next 的低代码基础组件库。 +1. 低代码物料生产能力和规范。 +2. 对低代码物料进行统一管理的物料中心。 +3. 基于 Fusion Next 的低代码基础组件库。 ### 设置器生态 + 对于已接入物料的属性配置,需要不同的设置器。 + 比如配置数值类型的 age,需要一个数值设置器,配置对象类型的 hobby,需要一个对象设置器,依次类推。 + 每个设置器本质上都是一个 React 组件,接受由引擎传入的参数,比如 value 和 onChange,value 是初始传入的值,onChange 是在设置器的值变化时的回传函数,将值写回到引擎中。 -```json + +```typescript // 一个最简单的文本设置器示例 class TextSetter extends Component { render() { @@ -49,9 +58,12 @@ class TextSetter extends Component { } } ``` + 大多数组件所使用的设置器都是一致或相似的。如同建设低代码基础组件库一样,设置器生态是一组基础的设置器,供大多数组件配置场景使用。 + 同时提供了设置器的定制功能。 ### 插件生态 低代码引擎本身只包含了最小的内核,而我们所能看到的设计器上的按钮、面板等都是插件提供的。插件是组成设计器的必要部分。 + 因此我们提供了一套官方的插件生态,提供最基础的设计器功能。帮助用户通过使用插件,快速完成自己的设计器。 diff --git a/docs/docs/guide/expand/_category_.json b/docs/docs/guide/expand/_category_.json index 36116999b1..15aeb3dea1 100644 --- a/docs/docs/guide/expand/_category_.json +++ b/docs/docs/guide/expand/_category_.json @@ -1,5 +1,5 @@ { - "label": "扩展低代码应用", + "label": "扩展低代码编辑器", "position": 2, "collapsed": false, "collapsible": true diff --git a/docs/docs/guide/expand/editor/cli.md b/docs/docs/guide/expand/editor/cli.md index 7f46c7b2e7..390173adf1 100644 --- a/docs/docs/guide/expand/editor/cli.md +++ b/docs/docs/guide/expand/editor/cli.md @@ -7,15 +7,19 @@ sidebar_position: 7 在 fork 低代码编辑器 demo 项目后,您可以直接在项目中任意扩展低代码编辑器。如果您想要将自己的组件/插件/设置器封装成一个独立的 npm 包并提供给社区,您可以使用我们的低代码脚手架建立低代码扩展。 > Windows 开发者请在 WSL 环境下使用开发工具 +> > WSL 中文 doc:[https://docs.microsoft.com/zh-cn/windows/wsl/install](https://docs.microsoft.com/zh-cn/windows/wsl/install) -中文教程:[https://blog.csdn.net/weixin_45027467/article/details/106862520](https://blog.csdn.net/weixin_45027467/article/details/106862520) +> +> 中文教程:[https://blog.csdn.net/weixin_45027467/article/details/106862520](https://blog.csdn.net/weixin_45027467/article/details/106862520) ## 脚手架功能 ### 脚手架初始化 + ```shell $ npm init @alilc/element your-element-name ``` + 不写 your-element-name 的情况下,则在当前目录创建。 > 觉得安装速度比较慢的同学,可以设置 npm 国内镜像,如 @@ -25,157 +29,166 @@ $ npm init @alilc/element your-element-name --registry=https://registry.npmmirro ``` 选择对应的元素类型,并填写对应的问题,即可完成创建。 -![截屏2022-02-09 下午8.15.07.png](https://cdn.nlark.com/yuque/0/2022/png/134449/1644408912640-ae7a9a9b-54a4-49c3-a5d8-ccac1db7da0b.png#averageHue=%23f0f0ef&clientId=ue2be1de5-5d30-4&crop=0&crop=0&crop=1&crop=1&errorMessage=unknown%20error&from=drop&height=82&id=uaff32f98&margin=%5Bobject%20Object%5D&name=%E6%88%AA%E5%B1%8F2022-02-09%20%E4%B8%8B%E5%8D%888.15.07.png&originHeight=148&originWidth=688&originalType=binary&ratio=1&rotation=0&showTitle=false&size=72918&status=error&style=none&taskId=uf08c7e98-b502-416d-be39-0029f765203&title=&width=382) + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01SNaXUg1g4LurKuBHs_!!6000000004088-2-tps-688-148.png) + ### 脚手架本地环境调试 -```shell + +```bash cd your-element-name npm install npm start ``` ### 脚手架构建 -```shell + +```bash $ npm run build ``` + ### 脚手架发布 + 修改版本号后,执行如下指令即可: -```shell + +```bash $ npm publish ``` # 🔥🔥🔥 调试物料/插件/设置器 -> 📢📢 📢 低代码生态脚手架提供的调试利器,在启动 setter/插件/物料 项目后,直接在已有的低代码平台就可以调试,不需要 npm link / 手改 npm main 入口等传统方式,轻松上手,强烈推荐使用!! +> 📢📢📢 低代码生态脚手架提供的调试利器,在启动 setter/插件/物料 项目后,直接在已有的低代码平台就可以调试,不需要 npm link / 手改 npm main 入口等传统方式,轻松上手,强烈推荐使用!! 注:若控制台出现如下错误,直接访问一次该 url 即可~ -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1652408638502-0509191d-1cd6-435c-9196-5c7abac7cc4d.png#averageHue=%23c8e1be&clientId=u0b1196f0-7f06-4&crop=0&crop=0&crop=1&crop=1&errorMessage=unknown%20error&from=paste&height=113&id=tjF5F&margin=%5Bobject%20Object%5D&name=image.png&originHeight=226&originWidth=1418&originalType=binary&ratio=1&rotation=0&showTitle=false&size=180782&status=error&style=none&taskId=u57eb2bdc-6dfd-4332-b176-c453947be2d&title=&width=709) + +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01cvKmeK1saCqpIxbLW_!!6000000005782-2-tps-1418-226.png) ## 组件/插件/Setter 侧 1. 插件/setter 在原有 alt 的配置中添加相关的调试配置 -```json -// build.json 中 -{ - "plugins": [ - [ - "@alilc/build-plugin-alt", - { - "type": "plugin", - "inject": true, // 开启注入调试 - // 配置要打开的页面,在注入调试模式下,不配置此项的话不会打开浏览器 - // 支持直接使用官方 demo 项目:https://lowcode-engine.cn/demo/index.html - "openUrl": "https://lowcode-engine.cn/demo/index.html?debug" - } - ], - ] -} -``` + ```json + // build.json 中 + { + "plugins": [ + [ + "@alilc/build-plugin-alt", + { + "type": "plugin", + "inject": true, // 开启注入调试 + // 配置要打开的页面,在注入调试模式下,不配置此项的话不会打开浏览器 + // 支持直接使用官方 demo 项目:https://lowcode-engine.cn/demo/index.html + "openUrl": "https://lowcode-engine.cn/demo/index.html?debug" + } + ], + ] + } + ``` 2. 组件需先安装 @alilc/build-plugin-alt,再将组件内的 `build.lowcode.js`文件修改如下 -```javascript -const { library } = require('./build.json'); - -module.exports = { - alias: { - '@': './src', - }, - plugins: [ - [ - // lowcode 的配置保持不变,这里仅为示意。 - '@alifd/build-plugin-lowcode', - { - library, - engineScope: "@alilc" - }, - ], - [ - '@alilc/build-plugin-alt', - { - type: 'component', - inject: true, - library, - // 配置要打开的页面,在注入调试模式下,不配置此项的话不会打开浏览器 - // 支持直接使用官方 demo 项目:https://lowcode-engine.cn/demo/index.html - openUrl: "https://lowcode-engine.cn/demo/index.html?debug" - } - ]], -}; -``` + ```javascript + const { library } = require('./build.json'); + + module.exports = { + alias: { + '@': './src', + }, + plugins: [ + [ + // lowcode 的配置保持不变,这里仅为示意。 + '@alifd/build-plugin-lowcode', + { + library, + engineScope: "@alilc" + }, + ], + [ + '@alilc/build-plugin-alt', + { + type: 'component', + inject: true, + library, + // 配置要打开的页面,在注入调试模式下,不配置此项的话不会打开浏览器 + // 支持直接使用官方 demo 项目:https://lowcode-engine.cn/demo/index.html + openUrl: "https://lowcode-engine.cn/demo/index.html?debug" + } + ]], + }; + ``` 3. 本地组件/插件/Setter正常启动调试,在项目的访问地址增加 debug,即可开启注入调试。 -```typescript -https://lowcode-engine.cn/demo/index.html?debug -``` + ```url + https://lowcode-engine.cn/demo/demo-general/index.html?debug + ``` + ## 项目侧的准备 + > 如果你的低代码项目 fork 自官方 demo,那么项目侧的准备已经就绪,不用再看以下内容~ 1. 安装 @alilc/lowcode-plugin-inject -```shell -npm i @alilc/lowcode-plugin-inject --save-dev -``` + ```bash + npm i @alilc/lowcode-plugin-inject --save-dev + ``` 2. 在引擎初始化侧引入插件 -```json -import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject'; - -export default async () => { - // 注意 Inject 插件必须在其他插件前注册,且所有插件的注册必须 await - await plugins.register(Inject); - await plugins.register(OtherPlugin); - await plugins.register((ctx: ILowCodePluginContext) => { - return { - name: "editor-init", - async init() { - // 设置物料描述前,使用插件提供的 injectAssets 进行处理 - const { material, project } = ctx; - material.setAssets(await injectAssets(assets)); - }, - }; - }); -} -``` - -3. 在 saveSchema 时过滤掉插入的url,避免影响渲染态 -```javascript -import { filterPackages } from '@alilc/lowcode-plugin-inject'; -export const saveSchema = async () => { - // ... - const packages = await filterPackages(editor.get('assets').packages); - window.localStorage.setItem( - 'packages', - JSON.stringify(packages), - ); - // ... -}; - -``` + ```typescript + import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject'; + + export default async () => { + // 注意 Inject 插件必须在其他插件前注册,且所有插件的注册必须 await + await plugins.register(Inject); + await plugins.register(OtherPlugin); + await plugins.register((ctx: ILowCodePluginContext) => { + return { + name: "editor-init", + async init() { + // 设置物料描述前,使用插件提供的 injectAssets 进行处理 + const { material, project } = ctx; + material.setAssets(await injectAssets(assets)); + }, + }; + }); + } + ``` + +3. 在 saveSchema 时过滤掉插入的 url,避免影响渲染态 + ```typescript + import { filterPackages } from '@alilc/lowcode-plugin-inject'; + export const saveSchema = async () => { + // ... + const packages = await filterPackages(editor.get('assets').packages); + window.localStorage.setItem( + 'packages', + JSON.stringify(packages), + ); + // ... + }; + ``` 4. 如果希望预览态也可以注入调试组件,则需要在 preview 逻辑里插入组件 -```javascript -import { injectComponents } from '@alilc/lowcode-plugin-inject'; + ```javascript + import { injectComponents } from '@alilc/lowcode-plugin-inject'; -async function init() { - // 在传递给 ReactRenderer 前,先通过 injectComponents 进行处理 - const components = await injectComponents(buildComponents(libraryMap, componentsMap)); - // ... -} -``` + async function init() { + // 在传递给 ReactRenderer 前,先通过 injectComponents 进行处理 + const components = await injectComponents(buildComponents(libraryMap, componentsMap)); + // ... + } + ``` # Meta 信息 meta 信息是放在生态元素 package.json 中的一小段 json,用户可以通过 meta 了解到这个元素的一些基本信息,如元素类型,一些入口信息等。 ```typescript interface LcMeta { - type: 'plugin' | 'setter' | 'component'; // 元素类型,尚未实现 - pluginName: string; // 插件名,仅插件包含 + type: 'plugin' | 'setter' | 'component'; // 元素类型,尚未实现 + pluginName: string; // 插件名,仅插件包含 meta: { - dependencies: string[]; // 插件依赖的其他插件列表,仅插件包含 + dependencies: string[]; // 插件依赖的其他插件列表,仅插件包含 engines: { - lowcodeEngine: string; // 适配的引擎版本 + lowcodeEngine: string; // 适配的引擎版本 } - prototype: string; // 物料描述入口,仅组件包含,尚未实现 - prototypeView: string; // 物料设计态入口,仅组件包含,尚未实现 + prototype: string; // 物料描述入口,仅组件包含,尚未实现 + prototypeView: string; // 物料设计态入口,仅组件包含,尚未实现 } } ``` diff --git a/docs/docs/guide/expand/editor/material.md b/docs/docs/guide/expand/editor/material.md index 88ea8b908b..fa51730fc6 100644 --- a/docs/docs/guide/expand/editor/material.md +++ b/docs/docs/guide/expand/editor/material.md @@ -12,14 +12,14 @@ sidebar_position: 1 低代码编辑器中的物料需要进行一定的配置和处理,才能让用户在低代码平台使用起来。这个过程中,需要一份一份配置文件,也就是资产包。资产包文件中,针对每个物料定义了它们在低代码编辑器中的使用描述。 ## 资产包配置 ### 什么是低代码资产包 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1647671718994-e013a162-37be-4fa7-bd3b-3af06878c3c2.png#clientId=uf20508c2-6786-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=579&id=u7a0c3dae&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1646&originWidth=3068&originalType=binary&ratio=1&rotation=0&showTitle=false&size=635660&status=done&style=stroke&taskId=uc304cc2b-24bf-449d-8e2e-fd25c88b189&title=&width=1080) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01SQJfxh1Y8uwDXksaK_!!6000000003015-2-tps-3068-1646.png) 在低代码 Demo 中,我们可以看到,组件面板不只提供一个组件,组件是以集合的形式提供给低代码平台的,而低代码资产包正是这些组件构成集合的形式。 **_它背后的 Interface,_**[**_在引擎中的定义摘抄如下_**](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/assets.ts)**_:_** ```typescript export interface Assets { version: string; // 资产包协议版本号 - packages?: Array; // 大包列表,external与package的概念相似,融合在一起 + packages?: Array; // 大包列表,external 与 package 的概念相似,融合在一起 components: Array | Array; // 所有组件的描述协议列表 sort: ComponentSort; // 新增字段,用于描述组件面板中的 tab 和 category } @@ -32,7 +32,7 @@ export interface ComponentSort { export interface RemoteComponentDescription { exportName: string; // 组件描述导出名字,可以通过 window[exportName] 获取到组件描述的 Object 内容; url: string; // 组件描述的资源链接; - package: { // 组件(库)的 npm 信息; + package: { // 组件 (库) 的 npm 信息; npm: string; } } @@ -40,14 +40,14 @@ export interface RemoteComponentDescription { 资产包协议 TS 描述 ### Demo 中的资产包 在 Demo 项目中,自带了一份默认的资产包: -> [https://github.com/alibaba/lowcode-demo/blob/main/src/universal/assets.json](https://github.com/alibaba/lowcode-demo/blob/main/src/universal/assets.json) +> [https://github.com/alibaba/lowcode-demo/blob/main/demo-general/src/services/assets.json](https://github.com/alibaba/lowcode-demo/blob/main/demo-general/src/services/assets.json) 这份资产包里的物料是我们内部沉淀出的,用户可以通过这套资产包体验引擎提供的搭建、配置能力。 **_在项目中正常注册资产包:_** -```json -import { material } from '@alilc/lowcode-engine' +```typescript +import { material } from '@alilc/lowcode-engine'; // 以任何方式引入 assets -material.setAssets(assets) +material.setAssets(assets); ``` **_以支持调试的方式注册资产包:_** > 这样启动并部署出来的项目,可以通过在预览地址加上 ?debug 来调试本地物料。 @@ -55,18 +55,18 @@ material.setAssets(assets) > - 通过插件初始化一个物料 > - 按照参考文章配置物料支持调试 > - 启动物料 -> - 访问:[https://lowcode-engine.cn/demo?debug](https://lowcode-engine.cn/demo?debug) +> - 访问:[https://lowcode-engine.cn/demo/demo-general/index.html?debug](https://lowcode-engine.cn/demo/demo-general/index.html) > -详细参考:[https://www.yuque.com/lce/doc/ulvlkz](https://www.yuque.com/lce/doc/ulvlkz) +详细参考:[低代码生态脚手架 & 调试机制](https://lowcode-engine.cn/site/docs/guide/expand/editor/cli) -```javascript -import { material } from '@alilc/lowcode-engine' +```typescript +import { material } from '@alilc/lowcode-engine'; import Inject, { injectAssets } from '@alilc/lowcode-plugin-inject'; await material.setAssets(await injectAssets(assets)); ``` ### 手工配置资产包 -参考 Demo 中的[基础 Fusion Assets 定义](https://github.com/alibaba/lowcode-demo/blob/main/src/scenarios/basic-fusion/assets.json),如果我们修改 assets.json,我们就能做到配置资产包: +参考 Demo 中的[基础 Fusion Assets 定义](https://github.com/alibaba/lowcode-demo/blob/main/demo-basic-fusion/src/services/assets.json),如果我们修改 assets.json,我们就能做到配置资产包: - packages 对象:我们需要在其中定义这个包的获取方式,如果不定义,就不会被低代码引擎动态加载并对应上组件实例。定义方式是 UMD 的包,低代码引擎会尝试在 window 上寻找对应 library 的实例; - components 对象:我们需要在其中定义物料描述,物料描述我们将在下一节继续讲解。 @@ -80,14 +80,14 @@ await material.setAssets(await injectAssets(assets)); 4. 画布更新生效。 **_当我们选中一个组件,我们可以看到面板右侧会显示组件的配置项。_** -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644312295732-5e0df2b5-065a-4d80-a66c-b5b20c8c32af.png#clientId=ue1d4eb8d-3b5c-4&crop=0&crop=0&crop=1&crop=1&from=url&height=535&id=ML9vP&margin=%5Bobject%20Object%5D&name=image.png&originHeight=743&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&size=212807&status=done&style=stroke&taskId=u2458e0f7-6bea-40d8-bb9b-9811562c6fe&title=&width=1080) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01T5hGcl25ABLpLIWKh_!!6000000007485-2-tps-1500-743.png) **_它包含以下内容:_** 1. 基础信息:描述组件的基础信息,通常包含包信息、组件名称、标题、描述等。 2. 组件属性信息:描述组件属性信息,通常包含参数、说明、类型、默认值 4 项内容。 3. 能力配置/体验增强:推荐用于优化搭建产品编辑体验,定制编辑能力的配置信息。 -因此,我们设计了[**《中后台低代码组件描述协议》**](http://lowcode-engine.cn/material)来描述一个低代码编辑器中可被配置的内容。 +因此,我们设计了[**《中后台低代码组件描述协议》**](/site/docs/specs/material-spec)来描述一个低代码编辑器中可被配置的内容。 ### Demo 中的物料描述 我们可以从 Demo 中的 assets.json 找到如下三个物料描述: @@ -97,13 +97,13 @@ await material.setAssets(await injectAssets(assets)); **_引擎中,会尝试调用对应 meta 文件,并注入到全局:_** ```tsx -const src = 'https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.5/build/lowcode/meta.js' -const script = document.createElement('script') -script.src = src -document.head.appendChild(script) +const src = 'https://alifd.alicdn.com/npm/@alifd/pro-layout@1.0.1-beta.5/build/lowcode/meta.js'; +const script = document.createElement('script'); +script.src = src; +document.head.appendChild(script); ``` 然后在 window 上就能拿到对应的物料描述内容了: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1647672326187-ec19ed1e-645a-4086-8384-ccca19b9f36c.png#clientId=uf20508c2-6786-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=648&id=ue7a84d56&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1138&originWidth=1896&originalType=binary&ratio=1&rotation=0&showTitle=false&size=582492&status=done&style=stroke&taskId=u11707d78-e1c5-4368-9de0-e98b7597815&title=&width=1080) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01DHSEOH1RwCEq19Ro9_!!6000000002175-2-tps-1896-1138.png) 手工配置物料描述时,可以用这样的方式参考一下 Demo 中的物料描述是如何实现的。 ### 手工配置物料描述 详见:“物料描述详解”章节。 @@ -113,18 +113,18 @@ document.head.appendChild(script) 您可以通过本节内容,完成一个组件在低代码编辑器中的配置和调试。 ### 前言(必读) 引擎提供的物料开发脚手架内置了**_入料模块_**,初始化的时候会自动根据源码解析出一份_**低代码描述**_,但是从源码解析出来的低代码描述让用户直接使用是不够精细的,因为源码包含的信息不够,它没办法完全包含配置项的交互; -![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1650539267595-c15e6200-9747-46bf-a61d-2a635d295406.png?x-oss-process=image/format,png#clientId=u97daa023-2ae2-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=856&id=u5b22ab2d&name=image.png&originHeight=1830&originWidth=802&originalType=binary&ratio=1&rotation=0&showTitle=false&size=4406602&status=done&style=stroke&taskId=ued90eb0c-b714-401a-bbfe-9f0b04794f6&title=&width=375) -比如设计师出了上面的设计稿,这里面除了有哪些 props 可被配置,通过哪个设置器配置,还包含了 props 之间的聚合、排序,甚至有自定义 setter ,这些信息源码里是不具备的,需要在低代码描述里进行开发; +![image.png](https://img.alicdn.com/imgextra/i1/O1CN010t0YzC1znDPQB1LUA_!!6000000006758-2-tps-802-1830.png) +比如设计师出了上面的设计稿,这里面除了有哪些 props 可被配置,通过哪个设置器配置,还包含了 props 之间的聚合、排序,甚至有自定义 setter,这些信息源码里是不具备的,需要在低代码描述里进行开发; **_因此我们建议只把 cli 初始化的低代码描述作为启动,要根据用户习惯对配置项进行设计,然后人工地去开发调试直接的低代码描述。_** ### 新开发组件 #### 组件项目初始化 -```json +```bash npm init @alilc/element your-material-name ``` #### 选择组件类型 > 组件 -> <组件组织方式> -![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647569723981-d0cb5f94-c137-4abf-8165-947b49595c8c.png#clientId=u6b9f3678-e2a3-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=174&id=ud7ad63de&margin=%5Bobject%20Object%5D&name=image.png&originHeight=464&originWidth=1596&originalType=binary&ratio=1&rotation=0&showTitle=false&size=298505&status=done&style=stroke&taskId=ud5e35ff9-c823-41bf-b441-db9e06a1f29&title=&width=600) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01BTiMt51iLPtzDbuh8_!!6000000004396-2-tps-1596-464.png) 这里我们选择 react-组件库,之后便生出我们的组件库项目,目录结构如下: ``` my-materials @@ -147,7 +147,7 @@ my-materials └── └── ExampleComponent2 // 业务组件2 ``` #### 组件开发与调试 -``` +```bash # 安装依赖 npm install @@ -157,15 +157,15 @@ npm run lowcode:dev # 构建低代码产物 npm run lowcode:build ``` -执行上述命令后会在组件(库)根目录生成一个 `lowcode` 文件夹,里面会包含每个组件的低代码描述: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644314663918-b2464be7-a65b-447c-af2a-12ea326a7558.png#clientId=ue1d4eb8d-3b5c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=376&id=AYq7T&margin=%5Bobject%20Object%5D&name=image.png&originHeight=906&originWidth=1446&originalType=binary&ratio=1&rotation=0&showTitle=false&size=347634&status=done&style=stroke&taskId=u25ffbb86-6681-427f-b199-69a22560a9c&title=&width=600) +执行上述命令后会在组件 (库) 根目录生成一个 `lowcode` 文件夹,里面会包含每个组件的低代码描述: +![image.png](https://img.alicdn.com/imgextra/i2/O1CN016m7gOK1DvpIcnlTvY_!!6000000000279-2-tps-1446-906.png) 在 src/components 目录新增一个组件并在 src/index.tsx 中导出,然后再执行 npm run lowcode:dev 时,低代码插件会在 lowcode/ 目录自动生成新增组件的低代码描述(meta.ts)。 用户可以直接修改低代码描述来修改组件的配置: -- 设置组件的 setter;(上一个章节介绍的设置器,也可以定制设置器用到物料中) -- 新增组件配置项 +- 设置组件的 setter(上一个章节介绍的设置器,也可以定制设置器用到物料中); +- 新增组件配置项; - 更改当前配置项; #### 配置示例 隐藏一个 prop @@ -179,24 +179,27 @@ npm run lowcode:build ```typescript { name: 'dataSource', - display: 'accordion' | 'inline' | 'block' | 'plain' | 'popup' | 'entry' // 常用的是 inline(默认), block、entry + display: 'accordion' | 'inline' | 'block' | 'plain' | 'popup' | 'entry', // 常用的是 inline(默认), block、entry } ``` 发布组件 -``` +```bash # 在组件根目录下,执行 $ npm publish ``` ### 现存组件低代码化 组件低代码化是指,在引入低代码平台之前,我们大多数都是使用源码开发的组件,也就是 ProCode 组件。 + 在引入低代码平台之后,原来的源码组件是需要转化为低代码物料,这样才能在低代码平台进行消费。 + 所以接下来会说明,对于已有的源码组件,我们如何把它低代码化。 #### 配置低代码开发环境 在您的组件开发环境中,安装 [build-scripts](https://github.com/ice-lab/build-scripts) 和它的低代码开发插件: -```shell +```bash npm install -D @alifd/build-plugin-lowcode @alib/build-scripts --save-dev ``` 新增 build-scripts 配置文件:build.lowcode.js + ```javascript module.exports = { alias: { @@ -218,39 +221,49 @@ module.exports = { "lowcode:dev": "build-scripts start --config ./build.lowcode.js", "lowcode:build": "build-scripts build --config ./build.lowcode.js", ``` -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644314665584-018b6675-ca7c-4bf5-b755-15a9b629f78f.png#clientId=ue1d4eb8d-3b5c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=270&id=brUY9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=822&originWidth=1830&originalType=binary&ratio=1&rotation=0&showTitle=false&size=972113&status=done&style=stroke&taskId=u09d05c9e-cf05-417e-bf32-8268d004134&title=&width=600) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN014iSa1P1dNdkUUtoMm_!!6000000003724-2-tps-1830-822.png) #### 开发调试 + ```bash # 启动低代码开发调试环境 npm run lowcode:dev ``` + 组件开发形式还和原来的保持一致,但是新增了一份组件的配置文件,其中配置方式和低代码物料的配置是一样的。 + #### 构建 + ```bash # 构建低代码产物 npm run lowcode:build ``` + #### 发布组件 ```bash # 在组件根目录下,执行 npm publish ``` -## 在项目中引入组件(库) -> 以下内容可观看[《阿里巴巴低代码引擎项目实战(3)-自定义组件接入》](https://www.bilibili.com/video/BV1dZ4y1m76S/)直播回放 + +## 在项目中引入组件 (库) +> 以下内容可观看[《阿里巴巴低代码引擎项目实战 (3)-自定义组件接入》](https://www.bilibili.com/video/BV1dZ4y1m76S/)直播回放 对于平台或者用户来说,可能所需要的组件集合是不同的。如果需要自定义组件集合,就需要定制资产包,定制的资产包是配置了一系列组件的,将这份资产包用于引擎即可在引擎中使用自定义的组件集合。 + ### 管理一份资产包 项目中使用的组件相关资源都需要在资产包中定义,那么我们自己开发的组件库如果要在项目中使用,只需要把组件构建好的相关资源 merge 到 assets.json 中就可以; + #### 自定义组件加入到资产包 通过官方脚手架自定义组件构建发布之后,npm 包里会出现一个 `build/lowcode/assets-prod.json`文件,我们只需要把该文件的内容 merge 到项目的 assets.json 中就可以; + #### 资产包托管 -- 最简单的方式就是类似[引擎 demo 项目](https://github.com/alibaba/lowcode-demo/blob/main/src/universal/assets.json)的做法,在项目中维护一份 assets.json,新增组件或者组件版本更新都需要修改这份资产包; -- 灵活一点的做法是通过 oss 等服务维护一份远程可配置的 assets.json ,新增组件或者组件更新只需要修改这份远程的资产包,项目无需更新; +- 最简单的方式就是类似[引擎 demo 项目](https://github.com/alibaba/lowcode-demo/blob/main/demo-general/src/services/assets.json)的做法,在项目中维护一份 assets.json,新增组件或者组件版本更新都需要修改这份资产包; +- 灵活一点的做法是通过 oss 等服务维护一份远程可配置的 assets.json,新增组件或者组件更新只需要修改这份远程的资产包,项目无需更新; - 再高级一点的做法是实现一个资产包管理的服务,能够通过用户界面去更新资产包的内容; + ### 在项目中引入资产包 -```javascript -import { ILowCodePluginContext, material, plugins } from '@alilc/lowcode-engine' +```typescript +import { ILowCodePluginContext, material, plugins } from '@alilc/lowcode-engine'; // 动态加载 assets plugins.register((ctx: ILowCodePluginContext) => { @@ -259,13 +272,13 @@ plugins.register((ctx: ILowCodePluginContext) => { 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)); ``` diff --git a/docs/docs/guide/expand/editor/metaSpec.md b/docs/docs/guide/expand/editor/metaSpec.md index b1c41dfd9f..2e70550ac7 100644 --- a/docs/docs/guide/expand/editor/metaSpec.md +++ b/docs/docs/guide/expand/editor/metaSpec.md @@ -4,13 +4,13 @@ sidebar_position: 2 --- ## 物料描述概述 -中后台前端体系中,存在大量的组件,程序员可以通过阅读文档,知悉组件的用法。可是搭建平台无法理解 README,而且很多时候,README 里并没有属性列表。这时,我们需要一份额外的描述,来告诉低代码搭建平台,组件接受哪些属性,又是该用怎样的方式来配置这些属性,于是,[**《中后台低代码组件描述协议》**](http://lowcode-engine.cn/material)应运而生。协议主要包含三部分:基础信息、属性信息 props、能力配置/体验增强 configure。 +中后台前端体系中,存在大量的组件,程序员可以通过阅读文档,知悉组件的用法。可是搭建平台无法理解 README,而且很多时候,README 里并没有属性列表。这时,我们需要一份额外的描述,来告诉低代码搭建平台,组件接受哪些属性,又是该用怎样的方式来配置这些属性,于是,[**《中后台低代码组件描述协议》**](/site/docs/specs/material-spec)应运而生。协议主要包含三部分:基础信息、属性信息 props、能力配置/体验增强 configure。 -物料配置,就是产出一份符合[**《中后台低代码组件描述协议》**](http://lowcode-engine.cn/material)的 JSON Schema。如果需要补充属性描述信息,或需要定制体验增强部分(如修改 Setter、调整展示顺序等),就可以通过修改这份 Schema 来实现。目前有自动生成、手工配置这两种方式生成物料描述配置。 +物料配置,就是产出一份符合[**《中后台低代码组件描述协议》**](/site/docs/specs/material-spec)的 JSON Schema。如果需要补充属性描述信息,或需要定制体验增强部分(如修改 Setter、调整展示顺序等),就可以通过修改这份 Schema 来实现。目前有自动生成、手工配置这两种方式生成物料描述配置。 ## 可视化生成物料描述 -使用Parts造物平台:[https://www.yuque.com/lce/xhk5hf/qa9pbx](https://www.yuque.com/lce/xhk5hf/qa9pbx) +使用 Parts 造物平台:[使用文档](/site/docs/guide/expand/editor/partsIntro) ## 自动生成物料描述 @@ -28,7 +28,7 @@ export default class FusionForm extends PureComponent { static defaultProps = { name: '张三', age: 18, - friends: ['李四','王五','赵六'] + friends: ['李四','王五','赵六'], } static propTypes = { @@ -47,11 +47,13 @@ export default class FusionForm extends PureComponent { }; render() { - return
dumb
+ return
dumb
; } } ``` + 引入 parse 工具自动解析 + ```typescript import parse from '@alilc/lowcode-material-parser'; (async () => { @@ -59,7 +61,9 @@ import parse from '@alilc/lowcode-material-parser'; console.log(JSON.stringify(result, null, 2)); })(); ``` + 因为一个组件可能输出多个子组件,所以解析结果是个数组。 + ```json [ { @@ -103,6 +107,7 @@ import parse from '@alilc/lowcode-material-parser'; } ] ``` + ## 手工配置物料描述 如果自动生成的物料无法满足需求,我们就需要手动配置物料描述。本节将分场景描述物料配置的内容。 @@ -113,7 +118,8 @@ import parse from '@alilc/lowcode-material-parser'; 增加一个 size 属性,只能从 'large'、'normal'、'small' 这个候选值中选择。 -以上面自动解析的物料为例,在此基础上手工加上 size 属性: +以上面自动解析的物料为例,在此基础上手工加上 size 属性: + ```json [ { @@ -168,7 +174,7 @@ import parse from '@alilc/lowcode-material-parser'; "options": [ { "title": "大", "value": "large" }, { "title": "中", "value": "normal" }, - { "title": "小", "value": "small" }, + { "title": "小", "value": "small" } ] }, } @@ -180,18 +186,20 @@ import parse from '@alilc/lowcode-material-parser'; ``` #### 组件的属性既可以设置固定值,也可以绑定到变量 -我们知道一种属性形式就需要一种 setter 来设置,如果想要将 value 属性允许输入字符串,那就需要设置为 `StringSetter`,如果允许绑定变量,就需要设置为 `VariableSetter`,具体设置器请参考[预置 Setter 列表](https://www.yuque.com/lce/doc/oc220p) -那如果都想要呢?可以使用 `MixedSetter` 来实现 -```json +我们知道一种属性形式就需要一种 setter 来设置,如果想要将 value 属性允许输入字符串,那就需要设置为 `StringSetter`,如果允许绑定变量,就需要设置为 `VariableSetter`,具体设置器请参考[预置设置器列表](/site/docs/guide/appendix/setters)。 + +那如果都想要呢?可以使用 `MixedSetter` 来实现。 + +```javascript { - ..., + // ... configure: { isExtend: true, props: [ { - title: "输入框的值", - name: "activeValue", + title: '输入框的值', + name: 'activeValue', setter: { componentName: 'MixedSetter', isRequired: true, @@ -208,14 +216,18 @@ import parse from '@alilc/lowcode-material-parser'; } } ``` -设置后,就会出现 “切换设置器” 的操作项了 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/189077/1647590065530-b50ed66a-8d24-40fc-91a9-13561663537b.png#clientId=ubd9972cd-765c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=126&id=ub0e036f6&margin=%5Bobject%20Object%5D&name=image.png&originHeight=252&originWidth=598&originalType=binary&ratio=1&rotation=0&showTitle=false&size=62314&status=done&style=none&taskId=u6545c47c-0fed-44eb-bfab-03694941981&title=&width=299) ![image.png](https://cdn.nlark.com/yuque/0/2022/png/189077/1647590197192-cd0071cf-a90c-4882-9b65-4b46bff13ce9.png#clientId=ubd9972cd-765c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=154&id=u67de127d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=308&originWidth=244&originalType=binary&ratio=1&rotation=0&showTitle=false&size=24027&status=done&style=none&taskId=u1a44a2d7-3680-4018-8709-9832cd03ad0&title=&width=122) + +设置后,就会出现“切换设置器”的操作项了 + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01jBqcuK1xYRP00WyVx_!!6000000006455-2-tps-598-252.png) + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01944xqq1PYihvYQb4v_!!6000000001853-2-tps-244-308.png) #### 开启组件样式设置 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571003600-48ef05cd-dbac-4aad-b7a5-012727fe1c6f.png#clientId=uad16fa90-b520-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u467d584c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=772&originWidth=820&originalType=url&ratio=1&rotation=0&showTitle=false&size=128316&status=done&style=none&taskId=ub01cb8bb-e784-485b-b2a6-aead3302c4f&title=) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01EBStyl24EvqJkAdh1_!!6000000007360-2-tps-820-772.png) -```tsx +```javascript { configure: { // ..., @@ -229,12 +241,12 @@ import parse from '@alilc/lowcode-material-parser'; #### 设置组件的默认事件 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571003649-c0da562f-220c-415e-83ea-e07b71c07552.png#clientId=uad16fa90-b520-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u7b452a11&margin=%5Bobject%20Object%5D&name=image.png&originHeight=800&originWidth=776&originalType=url&ratio=1&rotation=0&showTitle=false&size=120022&status=done&style=none&taskId=u6805e481-897b-4929-86c8-9321791a21a&title=) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN012gijqt1NERwqF5f6Y_!!6000000001538-2-tps-776-800.png) -```tsx +```javascript { configure: { - // ..., + // ... supports: { events: ['onPressEnter', 'onClear', 'onChange', 'onKeyDown', 'onFocus', 'onBlur'], }, @@ -245,9 +257,9 @@ import parse from '@alilc/lowcode-material-parser'; #### 设置 prop 标题的 tip -![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571003618-4a1bb1c4-da39-437b-8510-a121329aa91d.png#clientId=uad16fa90-b520-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u7fe57bc7&margin=%5Bobject%20Object%5D&name=image.png&originHeight=176&originWidth=908&originalType=url&ratio=1&rotation=0&showTitle=false&size=39688&status=done&style=none&taskId=u7e9e26eb-a4c3-423c-b7f1-f096d654d4e&title=) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01d8TdsY1jhENsKvwAv_!!6000000004579-2-tps-908-176.png) -```tsx +```javascript { name: 'label', setter: 'StringSetter', @@ -259,7 +271,7 @@ import parse from '@alilc/lowcode-material-parser'; }, tip: { type: 'i18n', - zh_CN: '属性: label | 说明: 标签文本内容', + zh_CN: '属性:label | 说明:标签文本内容', en_US: 'prop: label | description: label content', }, }, @@ -268,72 +280,79 @@ import parse from '@alilc/lowcode-material-parser'; #### 配置 prop 对应 setter 在配置面板的展示方式 -inline:![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571004529-c879ec4c-18af-46fd-8231-4ab80c937399.png#clientId=uad16fa90-b520-4&crop=0.0174&crop=0.0597&crop=0.9933&crop=0.3909&from=paste&height=260&id=u8cdcc718&margin=%5Bobject%20Object%5D&name=image.png&originHeight=266&originWidth=790&originalType=url&ratio=1&rotation=0&showTitle=false&size=40667&status=done&style=none&taskId=u9390a3bb-0290-46c7-b487-7380f162fd0&title=&width=771) +##### inline + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01z1sXj420vkP7vbeHj_!!6000000006912-2-tps-790-266.png) -```tsx +```javascript { configure: { props: [{ description: '标签文本', - display: 'inline' + display: 'inline', }] } } ``` -block: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571004690-22e7dc4f-db0d-43fe-b837-48ed1145bde7.png#clientId=uad16fa90-b520-4&crop=0&crop=0&crop=0.996&crop=1&from=paste&height=273&id=ua1717366&margin=%5Bobject%20Object%5D&name=image.png&originHeight=274&originWidth=792&originalType=url&ratio=1&rotation=0&showTitle=false&size=31246&status=done&style=none&taskId=u9e678772-1217-4c64-ac75-c5928b48834&title=&width=789) -```tsx +##### block + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01i3MVKF299xchs6kMX_!!6000000008026-2-tps-792-274.png) + +```javascript { configure: { props: [{ description: '高级', - display: 'block' + display: 'block', }] } } ``` -accordion +##### accordion -![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571005189-552ef14d-6043-48fa-a526-4565d42fa581.png#clientId=uad16fa90-b520-4&crop=0&crop=0.0159&crop=1&crop=1&from=paste&height=740&id=u53a75049&margin=%5Bobject%20Object%5D&name=image.png&originHeight=740&originWidth=798&originalType=url&ratio=1&rotation=0&showTitle=false&size=163685&status=done&style=none&taskId=ub42fca77-545e-435f-bafe-88e2b2ddfd1&title=&width=798) -```tsx +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01RePeyy1nhvRiBMm2w_!!6000000005122-2-tps-798-740.png) + +```javascript { configure: { props: [{ description: '表单项配置', - display: 'accordion' + display: 'accordion', }] } } ``` -entry +##### entry + +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01zkjBak1YY6igYUO1n_!!6000000003070-2-tps-796-424.png) + -![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571005244-fb508efb-a2d8-4064-8ff3-d6140e4c20a1.png#clientId=uad16fa90-b520-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u16645b5c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=424&originWidth=796&originalType=url&ratio=1&rotation=0&showTitle=false&size=91418&status=done&style=none&taskId=u38c7b284-f480-4440-baac-9f7c985104f&title=) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571005468-1c7f4b24-4330-45e2-b6c9-5bf5362874b4.png#clientId=uad16fa90-b520-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u2fad6ab5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=632&originWidth=794&originalType=url&ratio=1&rotation=0&showTitle=false&size=158094&status=done&style=none&taskId=u7c356adc-4286-46b8-9a2c-d33b4268ddc&title=) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01lmuRTl1LOPKMnsfLJ_!!6000000001289-2-tps-794-632.png) -```tsx +```javascript { configure: { props: [{ description: '风格与样式', - display: 'entry' + display: 'entry', }] } } ``` -plain +##### plain -![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571005702-ad979f93-cc47-4c6f-8de7-454cc6305614.png#clientId=uad16fa90-b520-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u6aa6d230&margin=%5Bobject%20Object%5D&name=image.png&originHeight=438&originWidth=776&originalType=url&ratio=1&rotation=0&showTitle=false&size=133070&status=done&style=none&taskId=u1db8205a-79ed-4d60-91b4-6e7f5bfaff3&title=) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01G0DOfV1jGD0v049gk_!!6000000004520-2-tps-776-438.png) -```tsx +```javascript { configure: { props: [{ description: '返回上级', - display: 'plain' + display: 'plain', }] } } @@ -343,14 +362,18 @@ plain ### 进阶配置 #### 组件的 children 属性允许传入 ReactNode + 例如有一个如下的 Tab 选项卡组件,每个 TabPane 的 children 都是一个组件 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/189077/1647588145478-fb8b7296-a8ee-4698-9851-846c78de301e.png#clientId=ubd9972cd-765c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=167&id=bi43p&margin=%5Bobject%20Object%5D&name=image.png&originHeight=334&originWidth=2332&originalType=binary&ratio=1&rotation=0&showTitle=false&size=55470&status=done&style=none&taskId=ub8c8b04a-e2e9-4b5d-9be7-c7ad7154864&title=&width=1166) + +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01Cu09HV1m8pTucSc7Q_!!6000000004910-2-tps-2332-334.png) + 只需要增加 `isContainer` 配置即可 -```json + +```javascript { - ..., + // ... configure: { - ..., + // ... component: { // 新增,设置组件为容器组件,可拖入组件 isContainer: true, @@ -358,12 +381,14 @@ plain } } ``` + 假设我们希望只允许拖拽 Table、Button 等内容放在 TabPane 里。配置白名单 `childWhitelist` 即可 -```json + +```javascript { - ..., + // ... configure: { - ..., + // ... component: { isContainer: true, nestingRule: { @@ -377,17 +402,20 @@ plain } ``` #### 组件的非 children 属性允许传入 ReactNode + 这就需要使用 `SlotSetter` 开启插槽了,如下面示例,给 Tab 的 title 开启插槽,允许拖拽组件 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/189077/1647590398244-479c820e-3b2f-4d7e-8742-37cf896bcafb.png#clientId=ubd9972cd-765c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=290&id=Utp8Y&margin=%5Bobject%20Object%5D&name=image.png&originHeight=580&originWidth=3016&originalType=binary&ratio=1&rotation=0&showTitle=false&size=254405&status=done&style=none&taskId=u0c8f777c-3559-455a-b136-c884312bb67&title=&width=1508) + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01P77m5m1pKEBXTk9Yt_!!6000000005341-2-tps-3016-580.png) + ```json { - // ..., + // ... configure: { isExtend: true, props: [ { - title: "选项卡标题", - name: "title", + title: '选项卡标题', + name: 'title', setter: { componentName: 'MixedSetter', props: { @@ -397,35 +425,38 @@ plain 'VariableSetter', ], }, - } - } - ] - } + }, + }, + ], + }, } ``` #### 屏蔽组件在设计器中的操作按钮 正常情况下,组件允许复制: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647571003626-06d80381-4d97-4d5b-8621-331674832c82.png#clientId=uad16fa90-b520-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=Sp6IN&margin=%5Bobject%20Object%5D&name=image.png&originHeight=226&originWidth=1158&originalType=url&ratio=1&rotation=0&showTitle=false&size=54949&status=done&style=none&taskId=u7e4b2cbe-5acf-467f-950b-ee48deb9502&title=) + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01925Nyl1a2AKNQ1XCP_!!6000000003271-2-tps-1158-226.png) + 如果希望禁止组件的复制行为,我们可以这样做: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1647673808399-2708ff56-70d1-4c58-b93b-aa65269fb179.png#clientId=ufbfe731c-4217-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=150&id=A304J&margin=%5Bobject%20Object%5D&name=image.png&originHeight=300&originWidth=1176&originalType=binary&ratio=1&rotation=0&showTitle=false&size=90147&status=done&style=none&taskId=uf8da0392-c584-4d27-b664-95b3e908103&title=&width=588) -```tsx +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01IoLKUu1CXGRb0ileB_!!6000000000090-2-tps-1176-300.png) + +```javascript { configure: { component: { disableBehaviors: ['copy'], - } - } + }, + }, } ``` #### 实现一个 BackwardSetter -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1647674621328-6b0a5afc-eafc-43cc-95ce-bbe00981ac20.png#clientId=ufbfe731c-4217-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=219&id=u9c11597c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=438&originWidth=776&originalType=binary&ratio=1&rotation=0&showTitle=false&size=125336&status=done&style=none&taskId=u01853245-46a8-42dd-9c62-6cdbb909afa&title=&width=388) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01GI4VfT23ga8TUCjIh_!!6000000007285-2-tps-776-438.png) -```tsx +```javascript { name: 'back', title: ' ', @@ -457,16 +488,16 @@ const BackwardSetter: DynamicSetter = (target: SettingTarget) => { - 始终隐藏当前 prop -```tsx +```javascript { // 始终隐藏当前 prop 配置 - condition: () => false + condition: () => false, } ``` - 根据其它 prop 的值展示/隐藏当前 prop -```tsx +```javascript { // direction 为 hoz 则展示当前 prop 配置 condition: (target) => { @@ -477,7 +508,7 @@ const BackwardSetter: DynamicSetter = (target: SettingTarget) => { #### props 联动 -```tsx +```javascript // 根据当前 prop 的值动态设置其它 prop 的值 { name: 'labelAlign', @@ -510,9 +541,9 @@ const BackwardSetter: DynamicSetter = (target: SettingTarget) => { #### 动态 setter 配置 -可以通过 DynamicSetter 传入的 target 获取一些引擎暴露的数据,例如当前有哪些组件被加载到引擎中,将这个数据作为 SelectSetter 的选项,让用户选择: +可以通过 DynamicSetter 传入的 target 获取一些引擎暴露的数据,例如当前有哪些组件被加载到引擎中,将这个数据作为 SelectSetter 的选项,让用户选择: -```tsx +```javascript { setter: (target) => { return { @@ -528,7 +559,7 @@ const BackwardSetter: DynamicSetter = (target: SettingTarget) => { } ), ), - } + }, }; } } diff --git a/docs/docs/guide/expand/editor/partsIntro.md b/docs/docs/guide/expand/editor/partsIntro.md index 6e56ae1e64..174afc37ad 100644 --- a/docs/docs/guide/expand/editor/partsIntro.md +++ b/docs/docs/guide/expand/editor/partsIntro.md @@ -1,75 +1,99 @@ --- -title: 利用Parts造物快速使用react组件 +title: 利用 Parts 造物快速使用 react 组件 sidebar_position: 3 --- ## 介绍 -大家在使用[低代码引擎](https://lowcode-engine.cn/)构建低代码应用平台时,遇到的一个主要问题是如何让已有的 React 组件能够快速低成本地接入进来。这个问题拆解下来主要包括两个子问题:1. 如何给已有组件[配置物料描述](https://lowcode-engine.cn/material),2. 如何构建出一个低代码引擎能够识别的资产包(Assets)。 -我们的产品 「[Parts·造物](https://parts.lowcode-engine.cn/)」 可以帮助大家解决这个问题。我们通过在线可视化的方式完成物料描述配置,并且提供一键打包的功能生成引擎可以识别的资产包。 +大家在使用[低代码引擎](https://lowcode-engine.cn/)构建低代码应用平台时,遇到的一个主要问题是如何让已有的 React 组件能够快速低成本地接入进来。这个问题拆解下来主要包括两个子问题: +1. 如何给已有组件[配置物料描述](/site/docs/specs/material-spec), +2. 如何构建出一个低代码引擎能够识别的资产包 (Assets)。 + +我们的产品「[Parts·造物](https://parts.lowcode-engine.cn/)」可以帮助大家解决这个问题。我们通过在线可视化的方式完成物料描述配置,并且提供一键打包的功能生成引擎可以识别的资产包。 ## 导入物料 -首先,我们需要在 [物料管理](https://parts.lowcode-engine.cn/material#/) 页面导入我们需要进行在线物料描述配置的物料。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434800993-0fbf5ed5-63e5-492b-85ab-feafd663ad2d.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=196&id=u918deb34&margin=%5Bobject%20Object%5D&name=image.png&originHeight=342&originWidth=1399&originalType=binary&ratio=1&rotation=0&showTitle=false&size=33102&status=done&style=stroke&taskId=u95c39b84-836c-45f8-aee6-0effc1ccfd1&title=&width=800) +首先,我们需要在 [物料管理](/site/docs/specs/material-spec) 页面导入我们需要进行在线物料描述配置的物料。 +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01IyZdZf1L1VWWU3dnp_!!6000000001239-2-tps-1399-342.png) - 点击列表左上方的 导入已有物料 按钮 -- 在弹框中输入 npm包名 -- 点击 获取包信息 按钮,获取npm包基本信息 +- 在弹框中输入 npm 包名 +- 点击 获取包信息 按钮,获取 npm 包基本信息 - 点击确定,导入成功 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434801003-7bd783f0-8804-445e-b508-8601501dfa60.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&id=u825d698a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=315&originWidth=640&originalType=binary&ratio=1&rotation=0&showTitle=false&size=21969&status=done&style=stroke&taskId=ued992c2e-822b-4c32-81b5-9c9add84954&title=) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN019FwWgs1kqgAXq5UNJ_!!6000000004735-2-tps-640-315.png) ## 配置管理 -第二步:物料导入以后,我们就可以为导入的物料新增[物料描述配置](https://lowcode-engine.cn/material),点击右侧的组件配置开始配置。 +第二步:物料导入以后,我们就可以为导入的物料新增[物料描述配置](/site/docs/specs/material-spec),点击右侧的组件配置开始配置。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434801125-979e6348-b78a-47b4-bb2e-fa8f1bb4ff90.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=216&id=u7fb954eb&margin=%5Bobject%20Object%5D&name=image.png&originHeight=261&originWidth=965&originalType=binary&ratio=1&rotation=0&showTitle=false&size=15305&status=done&style=stroke&taskId=uc1e18ffd-fe76-4fe4-83a4-c907f308b14&title=&width=800) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01kqymdB1nkDQclPk7F_!!6000000005127-2-tps-965-261.png) ### 新增配置 - 点击配置管理右上角的 新增配置 - 选择组件的版本号 - - 填写组件路径,一般和 npm 包的 package.json 里的 main 字段相同 (如果填写错误,后面会渲染不出来) + - 填写组件路径,一般和 npm 包的 package.json 里的 main 字段相同(如果填写错误,后面会渲染不出来) - 描述字段用于给这份配置增加一些备注信息。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434801095-1957da7f-5d9d-4c17-a762-c576bf0f763f.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=380&id=u9ad0ec47&margin=%5Bobject%20Object%5D&name=image.png&originHeight=418&originWidth=596&originalType=binary&ratio=1&rotation=0&showTitle=false&size=26130&status=done&style=stroke&taskId=u2b592498-195a-4fec-9853-ec5c3b95ef7&title=&width=541.8181700745893) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01i78OhT1cKbVWnXRNu_!!6000000003582-2-tps-596-418.png) + 为了降低配置成本,第一次新增配置的时候会自动解析组件代码,生成一份初始化组件物料描述。所以需要等待片刻,用于代码解析。解析完成后,点击配置按钮即可进入在线配置界面。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434801053-1a48b598-e987-4cd5-b657-030d345e0a99.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=193&id=ud384a13d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=232&originWidth=963&originalType=binary&ratio=1&rotation=0&showTitle=false&size=23541&status=done&style=stroke&taskId=ud2efc4d3-6d52-4b77-adbd-14dd5ee4b11&title=&width=800) + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01R24mTl1tJY3oJ5DCi_!!6000000005881-2-tps-963-232.png) + ### 组件描述配置 操作界面如下,接下来讲具体的配置流程 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434802081-6546d0f5-19da-475e-8dec-93ea324cc4e3.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=522&id=uf73c4753&margin=%5Bobject%20Object%5D&name=image.png&originHeight=938&originWidth=1438&originalType=binary&ratio=1&rotation=0&showTitle=false&size=111984&status=done&style=stroke&taskId=u0ce37d2b-8ca3-48b5-ac67-8fb461d17b5&title=&width=800) + +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01XjSW9I1u662raRg8E_!!6000000005987-2-tps-1438-938.png) + #### 新增组件 + 如果新增配置的过程中,代码自动解析失败或者解析出来的组件列表不满足开发要求,我们可以点击左侧组件列表插件 新增 按钮,添加新的组件,具体的字段描述可以参考提示内容,以 [react-color](https://github.com/casesandberg/react-color) 为例: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434802087-eaf4e2f1-2028-4415-b696-9788a6b2d0ed.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=560&id=u4341eb1b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1005&originWidth=1436&originalType=binary&ratio=1&rotation=0&showTitle=false&size=147918&status=done&style=stroke&taskId=ud921b52d-1961-4be9-b4ec-77d6364b213&title=&width=800) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434802555-bbd14a55-89a6-42cd-a4b3-76c98febf00c.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=472&id=u06e0b78f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=704&originWidth=1193&originalType=binary&ratio=1&rotation=0&showTitle=false&size=240470&status=done&style=stroke&taskId=u77603c5d-9d14-4379-86d2-deb4deaba50&title=&width=800) + +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01A9VFfQ1m9kH2Qliz4_!!6000000004912-2-tps-1436-1005.png) + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01klci7y1IUPflKpeVB_!!6000000000896-2-tps-1193-704.png) #### 给组件增加物料描述 -选中刚刚新增的BlockPicker组件,然后给它增加描述: -- 打开左侧 Sette r面板 -- 按照组件的属性拖入需要 Setter 类型 (如图中组件的width属性,拖入数字Setter) -- 各种 Setter 的介绍可以参看这篇文档:[https://www.yuque.com/lce/doc/grfylu](https://www.yuque.com/lce/doc/grfylu) +选中刚刚新增的 BlockPicker 组件,然后给它增加描述: + +- 打开左侧 Setter 面板 +- 按照组件的属性拖入需要 Setter 类型(如图中组件的 width 属性,拖入数字 Setter) +- 各种 Setter 的介绍可以参看这篇文档:[预置设置器列表](/site/docs/guide/appendix/setters) - 配置属性的基本信息(如图所示) - 配置完成后点击右上角的保存 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434802458-b0fb8a0e-307e-458c-a9f9-af3d2697024c.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=539&id=udeb647da&margin=%5Bobject%20Object%5D&name=image.png&originHeight=967&originWidth=1434&originalType=binary&ratio=1&rotation=0&showTitle=false&size=158958&status=done&style=stroke&taskId=u2950484f-659b-4643-af5e-75d04f14346&title=&width=800) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434802443-cdc533bf-1b08-4c11-b3d2-7cfd7fe0a5dd.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=311&id=uaaaa88fb&margin=%5Bobject%20Object%5D&name=image.png&originHeight=360&originWidth=925&originalType=binary&ratio=1&rotation=0&showTitle=false&size=64587&status=done&style=stroke&taskId=u7139e8ef-eee3-468b-833c-a42d8f3cb56&title=&width=800) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01gxLKBp1RaDEMPS54O_!!6000000002127-2-tps-1434-967.png) + +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01uReCQ825yYuwIfj2J_!!6000000007595-2-tps-925-360.png) + #### 高级配置(属性联动) -举个栗子:如图所示,如果期望 “设置器” 这个配置项的值 “被修改”的时候,下面的 “默认值” 跟着变化。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434803379-009a9783-ec24-4a08-8a46-55ae775ce7ba.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=520&id=u005ad05e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=572&originWidth=371&originalType=binary&ratio=1&rotation=0&showTitle=false&size=96588&status=done&style=stroke&taskId=u97330f9d-6728-4a05-a842-55df114ccee&title=&width=337.27271996253796) + +举个栗子:如图所示,如果期望“设置器”这个配置项的值“被修改”的时候,下面的“默认值”跟着变化。 + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01bg7X571bpSZdnXTBW_!!6000000003514-2-tps-371-572.png) + 如何使用 -组件的属性配置目前支持3个基本的联动函数: -- 显示状态:返回true | false,如果返回true,表示组件配置显示,否则配置时不显示 -- 获取值:当调用该配置节点的getValue方法时触发的方法 -- 值变化:当调用该配置节点的setValue方法时触发的方法 +组件的属性配置目前支持 3 个基本的联动函数: + +- 显示状态:返回 true | false,如果返回 true,表示组件配置显示,否则配置时不显示 +- 获取值:当调用该配置节点的 getValue 方法时触发的方法 +- 值变化:当调用该配置节点的 setValue 方法时触发的方法 + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN018ZJAJO21q57TdWfjM_!!6000000007035-2-tps-316-142.png) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434803522-85aed489-4e00-4787-a496-54cc73e25bc5.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=129&id=u0a782260&margin=%5Bobject%20Object%5D&name=image.png&originHeight=142&originWidth=316&originalType=binary&ratio=1&rotation=0&showTitle=false&size=29086&status=done&style=stroke&taskId=u95864da5-4ccf-4e4b-b903-1ce26af4f66&title=&width=287.2727210462587) 方法的第一个参数都是当前配置节点的对象,常用到的有以下几个: -- getValue(): 获取当前节点的值,如果当前节点是子节点的话,否则为undefined +- getValue(): 获取当前节点的值,如果当前节点是子节点的话,否则为 undefined - setValue(): 设置当前节点的值,如果当前节点是子节点的话 - parent: 当前节点的父节点 -- getPropValue(propName): 父节点获取子节点的属性值,propName为子节点的属性名称 -- setPropValue(propName, value): 父节点设置子节点的属性值,propName为子节点的属性名称, value 为设置的值 -- getConfig: 获取当前节点的配置,如title、setter等 +- getPropValue(propName): 父节点获取子节点的属性值,propName 为子节点的属性名称 +- setPropValue(propName, value): 父节点设置子节点的属性值,propName 为子节点的属性名称,value 为设置的值 +- getConfig: 获取当前节点的配置,如 title、setter 等 + + #### 调试物料描述 -点击右上角的预览按钮,开始调试我们刚刚配置的属性,如果是组件的首次预览,会有一段组件构建的过程(构建出umd包的过程),构建完成后就可以调试我们的配置了。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434804408-717e49bd-26b3-4a28-b3e5-bd1d67cdab00.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=209&id=ucf92cc3e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=373&originWidth=1431&originalType=binary&ratio=1&rotation=0&showTitle=false&size=46363&status=done&style=stroke&taskId=u501edca5-bbef-4fde-b341-b42c28b125a&title=&width=800) + +点击右上角的预览按钮,开始调试我们刚刚配置的属性,如果是组件的首次预览,会有一段组件构建的过程(构建出 umd 包的过程),构建完成后就可以调试我们的配置了。 + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN012biqEn1uGAl650nb2_!!6000000006009-2-tps-1431-373.png) + #### 发布物料描述 物料描述调试没问题后,就可以到项目中去使用了,使用前需要先发布物料描述 @@ -77,24 +101,32 @@ sidebar_position: 3 - 选择需要发布的组件 - 点击确定发布完成 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434804305-276f03e2-4dd2-41e9-9375-1c3bd0c7092a.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=410&id=uf879e7fd&margin=%5Bobject%20Object%5D&name=image.png&originHeight=734&originWidth=1431&originalType=binary&ratio=1&rotation=0&showTitle=false&size=103858&status=done&style=stroke&taskId=udc267585-ffb7-4247-b1f5-b7aca386e10&title=&width=800) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01uwa8RH1QDwM7FN31k_!!6000000001943-2-tps-1431-734.png) + ## 资产包构建 + 第三步:物料描述发布完成后,接下来我们就需要构建出可用的资产包用于低代码应用中。 + #### 资产包构建 - 选择需要构建的组件 - 点击构建资产包按钮 - 选择刚刚的物料描述配置 -- 开始构建,构建完成后你将得到一份json文件(里面包含了物料描述和umd包),就可以到项目中使用了 +- 开始构建,构建完成后你将得到一份 json 文件(里面包含了物料描述和 umd 包),就可以到项目中使用了 + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01Oc73aw1TH5vlJx9oj_!!6000000002356-2-tps-1431-770.png) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/12718919/1652434804769-6f6f60f1-9ee3-4561-972d-610f0616576e.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=430&id=ue119fa2b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=770&originWidth=1431&originalType=binary&ratio=1&rotation=0&showTitle=false&size=93492&status=done&style=stroke&taskId=ubfd97421-964b-4823-adc8-b056a588924&title=&width=800) #### 资产包使用 -**方式一、在 **[**lowcode-demo**](https://github.com/alibaba/lowcode-demo)**中直接引用,可直接替换demo中原来的资产包文件:** -例如,在basic-fusion demo中,直接用你的资产包文件替换文件[assets.json](https://github.com/alibaba/lowcode-demo/blob/main/src/scenarios/basic-fusion/assets.json),即可快速使用自己的物料了。 + +**方式一、在 **[**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/src/scenarios/basic-fusion/assets.json)合并,主要合并packages 和 components -- packages中是构建好的umd包 -- components中是上面配置好的[物料描述](https://lowcode-engine.cn/material),你也可以在基础上二次加工 +将上面构建完成的资产包与你项目中的[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://cdn.nlark.com/yuque/0/2022/png/12718919/1652434804944-860abc0c-057c-46d5-a6e5-8d33fde8a762.png#clientId=u0f780a28-b8dc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=676&id=u5499b1c9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=744&originWidth=1140&originalType=binary&ratio=1&rotation=0&showTitle=false&size=116233&status=done&style=stroke&taskId=u7be27934-77ce-4dd7-a406-1d402acef2c&title=&width=1036.36361390106) +![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 603aa09c0f..9dc75ce656 100644 --- a/docs/docs/guide/expand/editor/pluginContextMenu.md +++ b/docs/docs/guide/expand/editor/pluginContextMenu.md @@ -1,11 +1,13 @@ --- -title: 插件扩展-编排扩展 +title: 插件扩展 - 编排扩展 sidebar_position: 6 --- ## 场景一:扩展选中节点操作项 ### 增加节点操作项 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1647693318212-173890bc-b0b5-437b-9802-4b1fd9f74c5a.png#clientId=u2eca2bba-d284-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=254&id=u55228975&margin=%5Bobject%20Object%5D&name=image.png&originHeight=292&originWidth=1240&originalType=binary&ratio=1&rotation=0&showTitle=false&size=38144&status=done&style=none&taskId=u426cac9f-24ad-4d06-adbe-faca1896eaa&title=&width=1080) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01J7PrJc1S86XNDBIFQ_!!6000000002201-2-tps-1240-292.png) + 选中节点后,在选中框的右上角有操作按钮,编排模块默认实现了查看组件直系父节点、复制节点和删除节点按钮外,还可以通过相关 API 来扩展更多操作,如下代码: + ```typescript import { plugins } from '@alilc/lowcode-engine'; import { Icon, Message } from '@alifd/next'; @@ -30,14 +32,18 @@ const addHelloAction = (ctx: ILowCodePluginContext) => { }); } }; -} +}; addHelloAction.pluginName = 'addHelloAction'; await plugins.register(addHelloAction); ``` + **_效果如下:_** -![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1647694920149-b8d9a534-b943-45d2-b67e-cc42b906f827.png#clientId=u2eca2bba-d284-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=282&id=ua20a09c8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=343&originWidth=1315&originalType=binary&ratio=1&rotation=0&showTitle=false&size=35131&status=done&style=none&taskId=u3f47b55d-15ff-495c-8615-31e3ccb0222&title=&width=1080) -具体 API 参考:[https://www.yuque.com/lce/doc/mu7lml#ieJzi](https://www.yuque.com/lce/doc/mu7lml#ieJzi) + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01O8W2H61ybw2b7K5nV_!!6000000006598-2-tps-1315-343.png) + +具体 API 参考:[API 文档](/site/docs/api/material#addbuiltincomponentaction) ### 删除节点操作项 + ```typescript import { plugins } from '@alilc/lowcode-engine'; @@ -48,22 +54,26 @@ const removeCopyAction = (ctx: ILowCodePluginContext) => { removeBuiltinComponentAction('copy'); } } -} +}; removeCopyAction.pluginName = 'removeCopyAction'; await plugins.register(removeCopyAction); ``` + **_效果如下:_** -![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1647695353667-e22bef51-3c6a-4b6a-87d2-c144ddb68115.png#clientId=u2eca2bba-d284-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=237&id=ufa1f9434&margin=%5Bobject%20Object%5D&name=image.png&originHeight=290&originWidth=1319&originalType=binary&ratio=1&rotation=0&showTitle=false&size=22495&status=done&style=none&taskId=u73e01acc-96e8-45e7-9d42-a31edca193e&title=&width=1080) -具体 API 参考:[https://www.yuque.com/lce/doc/mu7lml#va9mb](https://www.yuque.com/lce/doc/mu7lml#va9mb) + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01Gfnu8J1O7PTRdoFQZ_!!6000000001658-2-tps-1319-290.png) + +具体 API 参考:[API 文档](/site/docs/api/material#removebuiltincomponentaction) + ## 实际案例 ### 区块管理 - 仓库地址:[https://github.com/alibaba/lowcode-plugins](https://github.com/alibaba/lowcode-plugins) - 具体代码:[https://github.com/alibaba/lowcode-plugins/tree/main/packages/action-block](https://github.com/alibaba/lowcode-plugins/tree/main/packages/action-block) - 直播回放: - - [低代码引擎项目实战(9)-区块管理(1)-保存为区块](https://www.bilibili.com/video/BV1YF411M7RK/) - - [低代码引擎项目实战(10)-区块管理-区块面板](https://www.bilibili.com/video/BV1FB4y1S7tu/) - - [阿里巴巴低代码引擎项目实战(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/) + - [低代码引擎项目实战 (9)-区块管理 (1)-保存为区块](https://www.bilibili.com/video/BV1YF411M7RK/) + - [低代码引擎项目实战 (10)-区块管理 - 区块面板](https://www.bilibili.com/video/BV1FB4y1S7tu/) + - [阿里巴巴低代码引擎项目实战 (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/) diff --git a/docs/docs/guide/expand/editor/pluginWidget.md b/docs/docs/guide/expand/editor/pluginWidget.md index fd63167e93..f1494bf2ae 100644 --- a/docs/docs/guide/expand/editor/pluginWidget.md +++ b/docs/docs/guide/expand/editor/pluginWidget.md @@ -1,16 +1,21 @@ --- -title: 插件扩展-面板扩展 +title: 插件扩展 - 面板扩展 sidebar_position: 5 --- ## 插件简述 + 插件功能赋予低代码引擎更高的灵活性,低代码引擎的生态提供了一些官方的插件,但是无法满足所有人的需求,所以提供了强大的插件定制功能。 + 通过定制插件,在和低代码引擎解耦的基础上,我们可以和引擎核心模块进行交互,从而满足多样化的功能。不仅可以自定义插件的 UI,还可以实现一些非 UI 的逻辑: -1)调用编辑器框架提供的 API 进行编辑器操作或者 schema 操作; -2)通过插件类的生命周期函数实现一些插件初始化的逻辑; -3)通过实现监听编辑器内的消息实现特定的切片逻辑(例如面板打开、面板关闭等) -> 本文仅介绍面板层面的扩展,编辑器插件层面的扩展可以参考 "插件扩展 - 编排扩展" 章节。 + +1. 调用编辑器框架提供的 API 进行编辑器操作或者 schema 操作; +2. 通过插件类的生命周期函数实现一些插件初始化的逻辑; +3. 通过实现监听编辑器内的消息实现特定的切片逻辑(例如面板打开、面板关闭等); + +> 本文仅介绍面板层面的扩展,编辑器插件层面的扩展可以参考 ["插件扩展 - 编排扩展"](./pluginContextMenu.md) 章节。 ## 注册插件 API + ```typescript import { plugins, ILowCodePluginContext } from '@alilc/lowcode-engine'; @@ -38,42 +43,67 @@ pluginA.pluginName = 'pluginA'; plugins.register(pluginA, { key: 'test' }); ``` -> 如果您想了解抽取出来的插件如何封装成为一个 npm 包并提供给社区,可以参考“扩展低代码应用 - 扩展低代码编辑器 - 低代码插件脚手架”章节。 -插件系统的详细设计,可参考“参与低代码引擎开发 - 低代码引擎设计文档 - 插件”章节。 + +> 如果您想了解抽取出来的插件如何封装成为一个 npm 包并提供给社区,可以参考[“低代码生态脚手架 & 调试机制”](./cli)章节。 ## 面板插件配置说明 + 面板插件是作用于设计器的,主要是通过按钮、图标等展示在设计器的骨架中。设计器的骨架我们分为下面的几个区域,而我们的插件大多数都是作用于这几个区域的。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644393006009-165e36cd-fa7b-4ee0-b3e3-dc7ba9d80d55.png#averageHue=%237cac76&clientId=u45843f36-7f71-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=608&id=u9e018f89&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1080&originWidth=1920&originalType=binary&ratio=1&rotation=0&showTitle=false&size=149463&status=done&style=stroke&taskId=u74f952e4-c783-47ae-b11c-be48d3c52be&title=&width=1080) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644320581783-b8fcd29c-45c2-48df-be2c-7101b12474e3.png#averageHue=%23edf6d4&clientId=u221f0bd4-c19e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=580&id=ixlrN&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1648&originWidth=3068&originalType=binary&ratio=1&rotation=0&showTitle=false&size=165621&status=done&style=stroke&taskId=u030d9faf-015f-4475-b34a-ba1fbf8868b&title=&width=1080) + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01Bkfm9E1MQWmBWeIOh_!!6000000001429-2-tps-1920-1080.png) + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01y05ZHC1Gix0p4nXxH_!!6000000000657-2-tps-3068-1648.png) + ### 展示区域 area #### topArea -展示在设计器的顶部区域,常见的相关区域的插件主要是: -1)注册设计器 Logo; -2)设计器操作回退和撤销按钮; -3)全局操作按钮,例如:保存、预览等; + +展示在设计器的顶部区域,常见的相关区域的插件主要是:、 + +1. 注册设计器 Logo; +2. 设计器操作回退和撤销按钮; +3. 全局操作按钮,例如:保存、预览等; + #### leftArea + 左侧区域的展示形式大多数是 Icon 和对应的面板,通过点击 Icon 可以展示对应的面板并隐藏其他的面板。 + 该区域相关插件的主要有: -1)大纲树展示,展示该设计器设计页面的大纲。 -2)组件库,展示注册到设计器中的组件,点击之后,可以从组件库面板中拖拽到设计器的画布中。 -3)数据源面板 -4)JS 等代码面板。 + +1. 大纲树展示,展示该设计器设计页面的大纲。 +2. 组件库,展示注册到设计器中的组件,点击之后,可以从组件库面板中拖拽到设计器的画布中。 +3. 数据源面板 +4. JS 等代码面板。 + 可以发现,这个区域的面板大多数操作时是不需要同时并存的,且交互比较复杂的,需要一个更整块的区域来进行操作。 #### centerArea + 画布区域,由于画布大多数是展示作用,所以一般扩展的种类比较少。常见的扩展有: -1)画布大小修改 -2)物料选中扩展区域修改 + +1. 画布大小修改 +2. 物料选中扩展区域修改 + #### rightArea + 右侧区域,常用于组件的配置。常见的扩展有:统一处理组件的配置项,例如统一删除某一个配置项,统一添加某一个配置项的。 + #### toolbar + 跟 topArea 类似,按需放置面板插件~ + ### 展示形式 type + #### PanelDock + PanelDock 是以面板的形式展示在设计器的左侧区域的。其中主要有两个部分组成,一个是图标,一个是面板。当点击图标时可以控制面板的显示和隐藏。 + 下图是组件库插件的展示效果。 -![Feb-08-2022 19-44-15.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644320663827-ee9c54a1-f684-40e2-8a6b-875103d04b31.gif#averageHue=%23eaf6d2&clientId=u221f0bd4-c19e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=555&id=u5292d9cc&margin=%5Bobject%20Object%5D&name=Feb-08-2022%2019-44-15.gif&originHeight=790&originWidth=1536&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1381641&status=done&style=stroke&taskId=ub28a13a4-3d80-4a02-bcaa-cc9d6127243&title=&width=1080) + +![Feb-08-2022 19-44-15.gif](https://img.alicdn.com/imgextra/i3/O1CN01XCrv5Q1hR5BgsyAiq_!!6000000004273-1-tps-1536-790.gif) + 其中右上角可以进行固定,可以对弹出的宽度做设定 + 接入可以参考代码 + ```javascript import { skeleton } from "@alilc/lowcode-engine"; @@ -85,7 +115,7 @@ skeleton.add({ props: { align: "left", icon: "wenjian", - description: "JS面板", + description: "JS 面板", }, panelProps: { floatable: true, // 是否可浮动 @@ -93,15 +123,20 @@ skeleton.add({ hideTitleBar: false, maxHeight: 800, maxWidth: 1200, - title: "JS面板", + title: "JS 面板", width: 600, }, }); ``` + #### Widget + Widget 形式是直接渲染在当前编辑器的对应位置上。如 demo 中在设计器顶部的所有组件都是这种展现形式。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644320068765-47efc836-30c2-452f-8104-b98b1ea3533d.png#averageHue=%23fefefb&clientId=u221f0bd4-c19e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=51&id=u68c58cad&margin=%5Bobject%20Object%5D&name=image.png&originHeight=94&originWidth=1988&originalType=binary&ratio=1&rotation=0&showTitle=false&size=58410&status=done&style=stroke&taskId=u4eadd643-2e63-4be7-8736-b27b9c82b81&title=&width=1080) + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01h89p5W1pfknnzwMqS_!!6000000005388-2-tps-1988-94.png) + 接入可以参考代码: + ```javascript import {skeleton} from "@alilc/lowcode-engine"; // 注册 logo 面板 @@ -110,7 +145,7 @@ skeleton.add({ type: "Widget", name: "logo", content: Logo, // Widget 组件实例 - contentProps: { // Widget 插件props + contentProps: { // Widget 插件 props logo: "https://img.alicdn.com/tfs/TB1_SocGkT2gK0jSZFkXXcIQFXa-66-66.png", href: "/", @@ -121,21 +156,24 @@ skeleton.add({ }, }); ``` + #### Dock -一个图标的表现形式,可以用于语言切换、跳转到外部链接、打开一个 widget 等场景 + +一个图标的表现形式,可以用于语言切换、跳转到外部链接、打开一个 widget 等场景。 + ```javascript import { skeleton } from "@alilc/lowcode-engine"; skeleton.add({ - area: "leftArea", - type: "Dock", - name: "opener", + area: 'leftArea', + type: 'Dock', + name: 'opener', content: Opener, // Widget 组件实例 - contentProps: { // Widget 插件props - xxx: "1", + contentProps: { // Widget 插件 props + xxx: '1', }, props: { - align: "bottom", + align: 'bottom', }, onClick: function() { // 打开外部链接 @@ -145,26 +183,31 @@ skeleton.add({ } }); ``` + #### Panel + 一般不建议单独使用,通过 PanelDock 使用~ + ## 实际案例 + ### 页面管理面板 - 仓库地址:[https://github.com/mark-ck/lowcode-portal](https://github.com/mark-ck/lowcode-portal) - 具体代码:[https://github.com/mark-ck/lowcode-portal/blob/master/src/plugins/pages-plugin/index.tsx](https://github.com/mark-ck/lowcode-portal/blob/master/src/plugins/pages-plugin/index.tsx) - 直播回放: - - [低代码引擎项目实战(4)-自定义插件-页面管理](https://www.bilibili.com/video/BV17a411i73f/) - - [低代码引擎项目实战(4)-自定义插件-页面管理-后端](https://www.bilibili.com/video/BV1uZ4y1U7Ly/) - - [低代码引擎项目实战(4)-自定义插件-页面管理-前端](https://www.bilibili.com/video/BV1Yq4y1a74P/) - - [低代码引擎项目实战(4)-自定义插件-页面管理-完结](https://www.bilibili.com/video/BV13Y4y1e7EV/) + - [低代码引擎项目实战 (4)-自定义插件 - 页面管理](https://www.bilibili.com/video/BV17a411i73f/) + - [低代码引擎项目实战 (4)-自定义插件 - 页面管理 - 后端](https://www.bilibili.com/video/BV1uZ4y1U7Ly/) + - [低代码引擎项目实战 (4)-自定义插件 - 页面管理 - 前端](https://www.bilibili.com/video/BV1Yq4y1a74P/) + - [低代码引擎项目实战 (4)-自定义插件 - 页面管理 - 完结](https://www.bilibili.com/video/BV13Y4y1e7EV/) + ### 区块面板 - 仓库地址:[https://github.com/alibaba/lowcode-plugins](https://github.com/alibaba/lowcode-plugins) - 具体代码:[https://github.com/alibaba/lowcode-plugins/tree/main/packages/plugin-block](https://github.com/alibaba/lowcode-plugins/tree/main/packages/plugin-block) - 直播回放: - - [低代码引擎项目实战(9)-区块管理(1)-保存为区块](https://www.bilibili.com/video/BV1YF411M7RK/) - - [低代码引擎项目实战(10)-区块管理-区块面板](https://www.bilibili.com/video/BV1FB4y1S7tu/) - - [阿里巴巴低代码引擎项目实战(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/) + - [低代码引擎项目实战 (9)-区块管理 (1)-保存为区块](https://www.bilibili.com/video/BV1YF411M7RK/) + - [低代码引擎项目实战 (10)-区块管理 - 区块面板](https://www.bilibili.com/video/BV1FB4y1S7tu/) + - [阿里巴巴低代码引擎项目实战 (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 diff --git a/docs/docs/guide/expand/editor/setter.md b/docs/docs/guide/expand/editor/setter.md index 846c60b3e5..6a720374f5 100644 --- a/docs/docs/guide/expand/editor/setter.md +++ b/docs/docs/guide/expand/editor/setter.md @@ -3,24 +3,37 @@ title: 设置器扩展 sidebar_position: 4 --- ## 设置器简述 + 设置器主要用于低代码组件属性值的设置,顾名思义叫"设置器",又称为 Setter。由于组件的属性有各种类型,需要有与之对应的设置器支持,每一个设置器对应一个值的类型。 + ### 设计器展示位置 + 设置器展示在编辑器的右边区域,如下图: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644387351052-0be9546e-9e46-41ff-bbb4-a1effe650d7f.png#clientId=u39aebc41-90a1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=487&id=pi5XH&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1730&originWidth=3836&originalType=binary&ratio=1&rotation=0&showTitle=false&size=947162&status=done&style=stroke&taskId=u4d4deed8-40f5-40a6-b20d-d092c90775c&title=&width=1080) + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01F0yBV91jNzkZKLzvJ_!!6000000004537-2-tps-3836-1730.png) + 其中包含四类设置器: - 属性:展示该物料常规的属性 - 样式:展示该物料样式的属性 - 事件:如果该物料有声明事件,则会出现事件面板,用于绑定事件。 - 高级:两个逻辑相关的属性,**条件渲染**和**循环** + ### 设置器类型 + 上述区域中是有多项设置器的,对于一个组件来说,每一项配置都对应一个设置器,比如我们的配置是一个文本,我们需要的是文本设置器,我们需要配置的是数字,我们需要的就是数字设置器。 下图中的标题和按钮类型配置就分别是文本设置器和下拉框设置器。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644387350762-7337e729-53e9-4a6c-8da1-8f17260e1347.png#clientId=u39aebc41-90a1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=744&id=ztLvk&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1460&originWidth=2120&originalType=binary&ratio=1&rotation=0&showTitle=false&size=489840&status=done&style=stroke&taskId=u7375a322-b6c8-43f1-a096-07b204656aa&title=&width=1080) + +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01uMd1zQ20fiXawR4IU_!!6000000006877-2-tps-2120-1460.png) + 我们提供了常用的设置器作为内置设置器,也提供了定制能力帮助大家开发特定需求的设置器。 + ## 为物料配置设置器 -我们提供了[常用的设置器](https://www.yuque.com/lce/doc/oc220p?view=doc_embed&from=kb&from=kb&outline=1&title=1)作为内置设置器。 + +我们提供了[常用的设置器](/site/docs/guide/appendix/setters)作为内置设置器。 + 我们可以将目标组件的属性值类型值配置到物料资源配置文件中: + ```json { "componentName": "Message", @@ -35,10 +48,15 @@ sidebar_position: 4 } } ``` + props 字段是入料模块扫描自动填入的类型,用户可以通过 configure 节点进行配置通过 override 节点对属性的声明重新定义,setter 就是注册在引擎中的 setter。 + 为物料配置引擎内置的 setter 时,均可以使用对应 setter 的高级功能,对应功能参考“全部内置设置器”章节下的对应 setter 文章。 -**_对高级功能的配置如下:_** -例如我们需要在NumberSetter中配置units属性,可以在asset.json中声明 + +### 对高级功能的配置如下: + +例如我们需要在 NumberSetter 中配置 units 属性,可以在 asset.json 中声明。 + ```json "configure": { "component": { @@ -81,27 +99,35 @@ props 字段是入料模块扫描自动填入的类型,用户可以通过 conf } }, ``` + ## 自定义设置器 ### 编写 AltStringSetter + 我们编写一个简单的 Setter,它的功能如下: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1644764687180-0121f0c0-d113-4907-a86d-e4f3a04ff221.png#clientId=ucb27c83c-48cf-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=45&id=u32dc8cd0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=90&originWidth=720&originalType=binary&ratio=1&rotation=0&showTitle=false&size=17539&status=done&style=stroke&taskId=u0f886bda-a93e-4b10-ad7e-9ba9a38a3fb&title=&width=360) -**_代码如下:_** -```typescript + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01fQ4GLd1RzrPSdULiw_!!6000000002183-2-tps-720-90.png) + +**代码如下:** +```tsx import * as React from "react"; import { Input } from "@alifd/next"; - import "./index.scss"; + interface AltStringSetterProps { // 当前值 value: string; // 默认值 defaultValue: string; - // setter唯一输出 + // setter 唯一输出 onChange: (val: string) => void; // AltStringSetter 特殊配置 placeholder: string; } + export default class AltStringSetter extends React.PureComponent { + // 声明 Setter 的 title + static displayName = 'AltStringSetter'; + componentDidMount() { const { onChange, value, defaultValue } = this.props; if (value == undefined && defaultValue) { @@ -109,9 +135,6 @@ export default class AltStringSetter extends React.PureComponent { @@ -140,41 +166,52 @@ bindEvent = (eventName) => { } componentWillUnmount() { - // setter是以实例为单位的,每个setter注销的时候需要把事件也注销掉,避免事件池过多 - event.off(`${this.emitEventName}.bindEvent`, this.bindEvent) + // setter 是以实例为单位的,每个 setter 注销的时候需要把事件也注销掉,避免事件池过多 + event.off(`${this.emitEventName}.bindEvent`, this.bindEvent); } ``` + 在 B setter 中触发事件,来完成通信: + ```javascript import { event } from '@alilc/lowcode-engine'; bindFunction = () => { const { field, value } = this.props; - // 这里展示的和插件进行通信,事件规则是插件名+方法 + // 这里展示的和插件进行通信,事件规则是插件名 + 方法 event.emit('eventBindDialog.openDialog', field.name, this.emitEventName); } ``` + #### 修改同级 props 的其他属性值 + setter 本身只影响其中一个 props 的值,如果需要影响其他组件的 props 的值,需要使用 field 的 props: -```json + +```javascript bindFunction = () => { const { field, value } = this.props; const propsField = field.parent; - // 获取同级其他属性showJump的值 + // 获取同级其他属性 showJump 的值 const otherValue = propsField.getPropValue('showJump'); - // set同级其他属性showJump的值 + // set 同级其他属性 showJump 的值 propsField.setPropValue('showJump', false); } ``` + ### 注册 AltStringSetter + 我们需要在低代码引擎中注册 Setter,这样就可以通过 AltStringSetter 的名字在物料中使用了。 + ```typescript import AltStringSetter from './AltStringSetter'; const registerSetter = window.AliLowCodeEngine.setters.registerSetter; registerSetter('AltStringSetter', AltStringSetter); ``` + ### 物料中使用 + 我们需要将目标组件的属性值类型值配置到物料资源配置文件中,其中核心配置如下: + ```json { "props": [ @@ -185,7 +222,9 @@ registerSetter('AltStringSetter', AltStringSetter); ] } ``` + 在物料中的相关配置如下: + ```json { "componentName": "Message", @@ -199,4 +238,4 @@ registerSetter('AltStringSetter', AltStringSetter); ] } } -``` +``` \ No newline at end of file diff --git a/docs/docs/guide/expand/editor/summary.md b/docs/docs/guide/expand/editor/summary.md index e8487213cd..bcb1e2b714 100644 --- a/docs/docs/guide/expand/editor/summary.md +++ b/docs/docs/guide/expand/editor/summary.md @@ -5,9 +5,9 @@ sidebar_position: 0 ## 扩展点简述 我们可以从 Demo 的项目中看到页面中有很多的区块: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643447049972-e324320a-7f97-4e48-bef3-a4c5d2b06517.png#clientId=udea0fe9a-4e7e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1080&id=rGr7U&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2160&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=518455&status=done&style=none&taskId=u872d1136-0f18-41b3-900d-710e9fc9eea&title=&width=1920) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01WkdvNi1TamxZblYFA_!!6000000002399-2-tps-3840-2160.png) 这些功能点背后都是可扩展项目,如下图所示: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643447052089-8e340da7-3c2c-4a88-9ed8-c89516dccf75.png#clientId=udea0fe9a-4e7e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=957&id=lL1sN&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1914&originWidth=3838&originalType=binary&ratio=1&rotation=0&showTitle=false&size=538736&status=done&style=none&taskId=u43e8a14e-0d52-4a22-bd19-e5083814daf&title=&width=1919) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01wZLOzm24hmnMTwXdF_!!6000000007423-2-tps-3838-1914.png) - 插件定制:可以配置低代码编辑器的功能和面板 - 物料定制:可以配置能够拖入的物料 @@ -16,7 +16,7 @@ sidebar_position: 0 我们从可扩展项目的视角,可以把低代码引擎架构理解为下图: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643447051959-7abb91ea-44af-46e0-b73a-dd2127648b32.png#clientId=udea0fe9a-4e7e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1080&id=M07o7&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2160&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=779021&status=done&style=none&taskId=u640e4616-d38d-45fb-a560-e4a98cd1605&title=&width=1920) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01fhZ3Q11hwE7RwSq7g_!!6000000004341-2-tps-3840-2160.png) (注:引擎内核中大量数据交互的细节被简化,这张图仅仅强调编辑器和外部扩展的交互) ## 配置扩展点 @@ -24,17 +24,17 @@ sidebar_position: 0 ### 配置物料 通过配置注入物料,这里的配置是物料中心根据物料资产包协议生成的,后面“物料扩展”章节会有详细说明。 ```typescript -import { material } from '@alilc/lowcode-engine' +import { material } from '@alilc/lowcode-engine'; // 假设您已把物料配置在本地 -import assets from './assets.json' +import assets from './assets.json'; // 静态加载 assets -material.setAssets(assets) +material.setAssets(assets); ``` 也可以通过异步加载物料中心上的物料。 ```typescript -import { ILowCodePluginContext, material, plugins } from '@alilc/lowcode-engine' +import { ILowCodePluginContext, material, plugins } from '@alilc/lowcode-engine'; // 动态加载 assets plugins.register((ctx: ILowCodePluginContext) => { @@ -51,27 +51,27 @@ plugins.register((ctx: ILowCodePluginContext) => { } }, } -}).catch(err => console.error(err)) +}).catch(err => console.error(err)); ``` ### 配置插件 可以通过 npm 包的方式引入社区插件,配置如下所示: ```typescript -import { ILowCodePluginContext, plugins } from '@alilc/lowcode-engine' -import PluginIssueTracker from '@alilc/lowcode-plugin-issue-tracker' +import { ILowCodePluginContext, plugins } from '@alilc/lowcode-engine'; +import PluginIssueTracker from '@alilc/lowcode-plugin-issue-tracker'; // 注册一个提 issue 组件到您的编辑器中,方位默认在左栏下侧 plugins.register(PluginIssueTracker) - .catch(err => console.error(err)) + .catch(err => console.error(err)); ``` 后续“插件扩展”章节会详细说明。 ### 配置设置器 低代码引擎默认内置了设置器(详见“配置设置器”章节)。您可以通过 npm 包的方式引入自定义的设置器,配置如下所示: ```typescript -import { setters } from '@alilc/lowcode-engine' +import { setters } from '@alilc/lowcode-engine'; // 假设您自定义了一个 setter -import MuxMonacoEditorSetter from './components/setters/MuxMonacoEditorSetter' +import MuxMonacoEditorSetter from './components/setters/MuxMonacoEditorSetter'; // 注册设置器 setters.registerSetter({ @@ -83,8 +83,8 @@ setters.registerSetter({ return typeof v === 'string' }, }, -}) +}); ``` 后续“设置器扩展”章节会详细说明。 -> 本章节所有可扩展配置内容在 demo 中均可找到:[https://github.com/alibaba/lowcode-demo/blob/main/src/universal/plugin.tsx](https://github.com/alibaba/lowcode-demo/blob/main/src/universal/plugin.tsx) +> 本章节所有可扩展配置内容在 demo 中均可找到:[https://github.com/alibaba/lowcode-demo/tree/main/demo-general](https://github.com/alibaba/lowcode-demo/tree/main/demo-general) diff --git a/docs/docs/guide/expand/runtime/codeGeneration.md b/docs/docs/guide/expand/runtime/codeGeneration.md index e1d9dc3d88..b773ca7196 100644 --- a/docs/docs/guide/expand/runtime/codeGeneration.md +++ b/docs/docs/guide/expand/runtime/codeGeneration.md @@ -29,8 +29,8 @@ sidebar_position: 1 ### 2) 通过设计器插件快速体验 -1. 安装依赖: `npm install --save @alilc/lowcode-plugin-code-generator` -2. 注册插件: +1. 安装依赖: `npm install --save @alilc/lowcode-plugin-code-generator` +2. 注册插件: ```typescript import { plugins } from '@alilc/lowcode-engine'; @@ -49,14 +49,14 @@ await plugins.register(CodeGenPlugin, { disableCodeGenActionBtn: true }); 此代码生成器一开始就是为服务端出码设计的,你可以直接这样来在 node.js 环境中使用: -1. 安装依赖: `npm install --save @alilc/lowcode-code-generator` -2. 引入代码生成器: +1. 安装依赖: `npm install --save @alilc/lowcode-code-generator` +2. 引入代码生成器: ```javascript import CodeGenerator from '@alilc/lowcode-code-generator'; ``` -3. 创建项目构建器: +3. 创建项目构建器: ```javascript const projectBuilder = CodeGenerator.solutions.icejs(); @@ -70,7 +70,7 @@ const project = await projectBuilder.generateProject( ); ``` -5. 将生成的代码写入到磁盘中(也可以生成一个 zip 包) +5. 将生成的代码写入到磁盘中 (也可以生成一个 zip 包) ```javascript // 写入磁盘 @@ -94,17 +94,17 @@ await CodeGenerator.publishers.zip().publish({ 随着现在电脑性能和浏览器技术的发展,出码其实已经不必非得在服务端做了,借助于 Web Worker 特性,可以在浏览器中进行出码: -1. 安装依赖: `npm install --save @alilc/lowcode-code-generator` -2. 引入代码生成器: +1. 安装依赖: `npm install --save @alilc/lowcode-code-generator` +2. 引入代码生成器: ```javascript import * as CodeGenerator from '@alilc/lowcode-code-generator/standalone-loader'; ``` -3. 【可选】提前初始化代码生成器: +3. 【可选】提前初始化代码生成器: ```javascript -// 提前初始化下,这样后面用的时候更快(这个 init 内部会提前准备好创建 worker 的一些资源) +// 提前初始化下,这样后面用的时候更快 (这个 init 内部会提前准备好创建 worker 的一些资源) await CodeGenerator.init(); ``` @@ -116,7 +116,7 @@ const result = await CodeGenerator.generateCode({ schema, // 编排搭建出来的 schema }); -console.log(result); // 出码结果(默认是递归结构描述的,可以传 flattenResult: true 以生成扁平结构的结果) +console.log(result); // 出码结果 (默认是递归结构描述的,可以传 flattenResult: true 以生成扁平结构的结果) ``` 注:一般来说在浏览器中出码适合做即时预览功能。 @@ -129,4 +129,4 @@ console.log(result); // 出码结果(默认是递归结构描述的,可以传 ```shell npx @alilc/lowcode-code-generator init-solution ``` -里面内置了一个示例的插件(在 `src/plugins/example.ts`中),您可以根据注释引导来完善相关插件,从而组合生成您的专属出码方案(`src/index.ts`)。您所生成的出码方案可以发布成 NPM 包,从而能按上文 1~4 中的使用方案进行使用。 +里面内置了一个示例的插件 (在 `src/plugins/example.ts`中),您可以根据注释引导来完善相关插件,从而组合生成您的专属出码方案 (`src/index.ts`)。您所生成的出码方案可以发布成 NPM 包,从而能按上文 1~4 中的使用方案进行使用。 diff --git a/docs/docs/guide/expand/runtime/renderer.md b/docs/docs/guide/expand/runtime/renderer.md index 20cc35baef..71eb755980 100644 --- a/docs/docs/guide/expand/runtime/renderer.md +++ b/docs/docs/guide/expand/runtime/renderer.md @@ -43,7 +43,7 @@ ReactDOM.render(( - rax-renderer:npm 包替换为 @alilc/lowcode-rax-renderer #### ### 项目使用示例 -> 设计器 demo:[https://lowcode-engine.cn/demo](https://lowcode-engine.cn/demo) +> [设计器 demo](https://lowcode-engine.cn/demo/demo-general/index.html) > 项目代码完整示例:[https://github.com/alibaba/lowcode-demo](https://github.com/alibaba/lowcode-demo) **step 1:在设计器中获取组件列表** @@ -310,13 +310,13 @@ designMode 属性主要在搭建场景中使用,主要有以下作用: ### suspended -渲染模块是否挂起,当设置为 `true` 时,渲染模块最外层容器的 `shouldComponentUpdate` 将始终返回false,在下钻编辑或者多引擎渲染的场景会用到该参数。 +渲染模块是否挂起,当设置为 `true` 时,渲染模块最外层容器的 `shouldComponentUpdate`将始终返回 false,在下钻编辑或者多引擎渲染的场景会用到该参数。 ### onCompGetRef 组件 ref 的回调,在搭建场景下编排模块可以根据该回调获取组件实例并实现生命周期注入或者组件 DOM 操作等功能,回调函数主要包含两个参数: -- `schema`: 当前组件的 schema 模型结构 +- `schema`:当前组件的 schema 模型结构 - `ref`:当前组件的 ref 实例 ### onCompGetCtx diff --git a/docs/docs/guide/quickStart/demo.md b/docs/docs/guide/quickStart/demo.md index 536c8efab6..a05a42486d 100644 --- a/docs/docs/guide/quickStart/demo.md +++ b/docs/docs/guide/quickStart/demo.md @@ -2,46 +2,55 @@ title: 试用低代码引擎 Demo sidebar_position: 1 --- -# 访问地址 +## 访问地址 低代码引擎的 Demo 可以通过如下永久链接访问到: -[https://lowcode-engine.cn/demo](https://lowcode-engine.cn/demo) +[设计器 demo](https://lowcode-engine.cn/demo/demo-general/index.html) > 注意我们会经常更新 demo,所以您可以通过上述链接得到最新版地址。 -# 低代码引擎 Demo 功能概览 - -我们可以从 Demo 的项目中看到页面中有很多的区块:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643447049972-e324320a-7f97-4e48-bef3-a4c5d2b06517.png#clientId=udea0fe9a-4e7e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1080&id=rGr7U&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2160&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=518455&status=done&style=none&taskId=u872d1136-0f18-41b3-900d-710e9fc9eea&title=&width=1920)
它主要包含这些功能点:
![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1643447051103-de714f27-ec70-4982-b180-e1ebe444b0fe.png#clientId=udea0fe9a-4e7e-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1080&id=lD0YM&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2160&originWidth=3840&originalType=binary&ratio=1&rotation=0&showTitle=false&size=616472&status=done&style=none&taskId=u61de17fa-6df0-43c8-9171-96388fda32e&title=&width=1920) - -- 顶部:操作区 - - 右侧:撤回和重做、保存到本地、重置页面、预览、异步加载资源 -- 左侧:面板与操作区 - - 大纲面板:可以调整页面内的组件树结构 - - 物料面板:可以查找组件,并在此拖动组件到编辑器画布中 - - 源码面板:可以编辑页面级别的 JavaScript 代码和 CSS 配置 - - 提交 Issue:可以给引擎开发提 bug - - Schema 编辑:可以编辑页面的底层数据 - - 中英文切换:可以切换编辑器的语言 -- 中部:可视化页面编辑画布区域 - - 点击组件在右侧面板中能够显示出对应组件的属性配置选项 - - 拖拽修改组件的排列顺序 - - 将组件拖拽到容器类型的组件中 - - 复制组件:点击组件右上角的复制按钮 - - 删除组件:点击组件右上角的 X 或者直接使用 `Delete` 键 -- 右侧:组件级别配置 - - 选中的组件:从页面开始一直到当前选中的组件位置,点击对应的名称可以切换到对应的组件上 - - 选中组件的配置:当前组件的大类目选项,根据组件类型不同,包含如下子类目: - - 属性:组件的基础属性值设置 - - 样式:组件的样式配置 - - 事件:绑定组件对外暴露的事件 - - 高级:循环、条件渲染与 key 设置 - -# 深入使用低代码引擎 Demo +## 低代码引擎 Demo 功能概览 + +我们可以从 Demo 的项目中看到页面中有很多的区块: + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01vlxdTD28c4JZcebbf_!!6000000007952-2-tps-3840-2160.png) + +它主要包含这些功能点: + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01QITHRY1sQaWzlvJv9_!!6000000005761-2-tps-3840-2160.png) + +### 顶部:操作区 + +- 右侧:撤回和重做、保存到本地、重置页面、预览、异步加载资源 +### 左侧:面板与操作区 +- 大纲面板:可以调整页面内的组件树结构 +- 物料面板:可以查找组件,并在此拖动组件到编辑器画布中 +- 源码面板:可以编辑页面级别的 JavaScript 代码和 CSS 配置 +- 提交 Issue:可以给引擎开发提 bug +- Schema 编辑:可以编辑页面的底层数据 +- 中英文切换:可以切换编辑器的语言 + +### 中部:可视化页面编辑画布区域 +- 点击组件在右侧面板中能够显示出对应组件的属性配置选项 +- 拖拽修改组件的排列顺序 +- 将组件拖拽到容器类型的组件中 +- 复制组件:点击组件右上角的复制按钮 +- 删除组件:点击组件右上角的 X 或者直接使用 `Delete` 键 + +### 右侧:组件级别配置 +- 选中的组件:从页面开始一直到当前选中的组件位置,点击对应的名称可以切换到对应的组件上 +- 选中组件的配置:当前组件的大类目选项,根据组件类型不同,包含如下子类目: + - 属性:组件的基础属性值设置 + - 样式:组件的样式配置 + - 事件:绑定组件对外暴露的事件 + - 高级:循环、条件渲染与 key 设置 + +## 深入使用低代码引擎 Demo 我们在低代码引擎 Demo 中直接内置了产品使用文档,对常见场景中的使用进行了向导,它的入口如下: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1647163471895-a12d0f5d-e09e-462d-bd0b-b633c64afb15.png#clientId=uecc3752b-3539-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=825&id=u86d6fa24&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1650&originWidth=3070&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1040703&status=done&style=none&taskId=u54aeddda-78e0-4259-b184-d06e2dba10b&title=&width=1535) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01YU2LYS29YEbuLTtLL_!!6000000008079-2-tps-3070-1650.png) -如果暂时没有看到对应的产品使用文档,可以通过此永久链接直接访问:[https://www.yuque.com/lce/usage](https://www.yuque.com/lce/usage) +如果暂时没有看到对应的产品使用文档,可以通过此永久链接直接访问:[https://lowcode-engine.cn/site/docs/demoUsage/intro](https://lowcode-engine.cn/site/docs/demoUsage/intro) diff --git a/docs/docs/guide/quickStart/intro.md b/docs/docs/guide/quickStart/intro.md index 67750b2a94..661f5912f7 100644 --- a/docs/docs/guide/quickStart/intro.md +++ b/docs/docs/guide/quickStart/intro.md @@ -18,7 +18,7 @@ sidebar_position: 0 - **可视化页面搭建**,通过简单的拖拽完成应用页面开发,对前端技能没有要求或不需要特别专业的了解; - **可视化模型设计**,与业务相关的数据存储变得更容易理解,甚至大多数简单场景可以做到表单即模型,模型字段的类型更加业务化; - **可视化流程设计**,不管是业务流程还是审批流程,都可以通过简单的点线连接来进行配置; -- **可视化报表及数据分析**,BI数据分析能力成为标配,随时随地通过拖拽选择来定义自定义分析报表; +- **可视化报表及数据分析**,BI 数据分析能力成为标配,随时随地通过拖拽选择来定义自定义分析报表; - **可视化服务与数据开放、集成**,具备与其他系统互联互通的配置; - **权限、角色设置标准化和业务化**,通过策略规则配置来将数据、操作的权限进行精细化管理; - **无需关心服务器、数据库等底层运维、计算设施设备、网络等等复杂技术概念**,具备安全、性能的统一解决方案,开发者只需要专注于业务本身; @@ -35,14 +35,14 @@ sidebar_position: 0 **低代码设计器** 现如今低代码平台越来越多,而每一个低代码平台中都会有的一个能力就是搭建和配置页面、模块的页面,这个页面我们称为设计器。例如,下图是中后台低代码平台的设计器。 -![image.png](https://img.alicdn.com/imgextra/i4/O1CN01LunuQh23b5NtP8k86_!!6000000007273-2-tps-1682-969.png?originHeight=1914&originWidth=3838&originalType=binary&ratio=1&rotation=0&showTitle=false&size=538736&status=done&style=stroke&taskId=u9a19d4d1-4d87-4b4e-b7cc-3aedfb00aaa&title=&width=1080) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01sXuwkK1j8sg4S53Dx_!!6000000004504-2-tps-1682-969.png) 设计器承载着低代码平台的核心功能,包括入料、编排、组件配置、画布渲染等等。由于其功能多,打磨精细难,也是低代码平台建设最耗时的地方。 **定制扩展能力** 什么是扩展能力呢,一方面我们可以快速拥有一份标准的低代码设计器,另外一方面如果有业务独特的功能需要,我们可以不用看它的源码、不用关心其实现,可以使用 API、插件等方式快速完成能力的开发。 而低代码引擎对于设计器的扩展能力支持基本上覆盖了低代码设计器的所有功能点。下图是针对标准的设计器提供了扩展功能的区域。 -![](https://cdn.nlark.com/yuque/0/2022/png/242652/1643446752531-8b1493d4-ea8a-463b-9631-6bb4fc681719.png#clientId=u2b839b63-1827-4&crop=0&crop=0&crop=1&crop=1&from=drop&height=539&id=ucff2881c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1914&originWidth=3838&originalType=binary&ratio=1&rotation=0&showTitle=false&size=538736&status=done&style=stroke&taskId=u9a19d4d1-4d87-4b4e-b7cc-3aedfb00aaa&title=&width=1080) +![](https://img.alicdn.com/imgextra/i1/O1CN01ZVgAE31wltQ4BVnCe_!!6000000006349-2-tps-3838-1914.png) **低代码设计器研发框架** 低代码引擎的核心是设计器,通过扩展、周边生态等可以产出各式各样的设计器。它不是一套可以适合所有人的低代码平台,而是帮助低代码平台的开发者,快速生产低代码平台的工具。 diff --git a/docs/docs/guide/quickStart/start.md b/docs/docs/guide/quickStart/start.md index 001e4e789b..dd5bbe48ec 100644 --- a/docs/docs/guide/quickStart/start.md +++ b/docs/docs/guide/quickStart/start.md @@ -2,70 +2,83 @@ 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 的编译结果。 +## 前置知识 +我们假定你已经对 HTML 和 JavaScript 都比较熟悉了。即便你之前使用其他编程语言,你也可以跟上这篇教程的。除此之外,我们假定你也已经熟悉了一些编程的概念,例如,函数、对象、数组,以及 class 的一些内容。 -# 环境准备 -## WSL(Window 电脑) +如果你想回顾一下 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 node 版本推荐 14.17.0。 -### 查看 Node 版本 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660653856191-128d8e3f-9636-4b73-94ab-c03cf6965365.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=35&id=u44a9af04&margin=%5Bobject%20Object%5D&name=image.png&originHeight=70&originWidth=238&originalType=binary&ratio=1&rotation=0&showTitle=false&size=11948&status=done&style=none&taskId=udb616117-a27c-409d-9e1c-1b89931a714&title=&width=119) +#### 查看 Node 版本 +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01oCZKNz290LIu8YUTk_!!6000000008005-2-tps-238-70.png) -### 变更 node 版本 +#### 通过 n 来管理 node 版本 可以安装 [n](https://www.npmjs.com/package/n) 来管理和变更 node 版本。 -#### 安装 -```json +##### 安装 n +```bash npm install -g n ``` -#### 变更 node 版本 -```json +##### 变更 node 版本 +```bash n 14.17.0 ``` -## React +### React 低代码引擎的扩展能力都是基于 React 来研发的,在继续阅读之前最好有一定的 React 基础,React 学习教程 ➡️ [React 快速开始教程](https://zh-hans.reactjs.org/docs/getting-started.html)。 -## 下载 Demo +### 下载 Demo 可以前往 github(https://github.com/alibaba/lowcode-demo)将 DEMO 下载到本地。 -### git clone -#### HTTPS +#### git clone +##### HTTPS 需要使用到 git 工具 -```json +```bash git clone https://github.com/alibaba/lowcode-demo.git ``` -#### SSH +##### SSH 需要配置 SSH key,如果没有配置可以 -```json +```bash git clone git@github.com:alibaba/lowcode-demo.git ``` -### 下载 Zip 包 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660653725650-ab734ba4-64a7-4801-9d2f-5c496879054f.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=897&id=uc1b07458&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1794&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1306258&status=done&style=stroke&taskId=ubaa4eb12-0e87-464e-b3da-306ed9685b7&title=&width=1792) +#### 下载 Zip 包 +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01iYC7E11phaNwLFUrN_!!6000000005392-2-tps-3584-1794.png) + +### 选择一个 demo 项目 +在 以 `demo-general` 为例: +```bash +cd demo-general +``` -## 安装依赖 -在 lowcode-demo 目录下执行: -```json +### 安装依赖 +在 `lowcode-demo/demo-general` 目录下执行: +```bash npm install ``` -## 启动 demo -在 lowcode-demo 目录下执行: -```json +### 启动 demo +在 `lowcode-demo/demo-general` 目录下执行: +```bash npm run start ``` 之后就可以通过 [http://localhost:5556/](http://localhost:5556/) 来访问我们的 DEMO 了。 -# 认识 Demo -我们的 Demo 是一个**低代码平台的设计器**。它是一个低代码平台中最重要的一环,用户可以在这里通过拖拽、配置、写代码等等来完成一个页面的开发。由于用户的人群不同、场景不同、诉求不同等等,这个页面的功能就会有所差异。
这里记住**设计器**这个词,它描述的就是下面的这个页面,后面我们会经常看到它。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660654189055-45fd0c7e-75cb-4072-a4d4-7cf244405c7d.png#clientId=ubcf63daf-5747-4&crop=0&crop=0.008&crop=1&crop=1&from=paste&height=904&id=LBi2j&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1808&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=763122&status=done&style=stroke&taskId=u82753ad5-3b5d-43b2-b309-a99c2a7bb24&title=&width=1792) -## 场景介绍 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660654738730-490fc94a-8b42-4c48-b21e-4c0694416b07.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=903&id=ub700edc2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1806&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=802013&status=done&style=stroke&taskId=u317bff98-636d-402a-98f2-f9e0b08293b&title=&width=1792) +## 认识 Demo +我们的 Demo 是一个**低代码平台的设计器**。它是一个低代码平台中最重要的一环,用户可以在这里通过拖拽、配置、写代码等等来完成一个页面的开发。由于用户的人群不同、场景不同、诉求不同等等,这个页面的功能就会有所差异。 + +这里记住**设计器**这个词,它描述的就是下面的这个页面,后面我们会经常看到它。 +![image.png](https://img.alicdn.com/imgextra/i1/O1CN014nYXgF20pKrQIG2zV_!!6000000006898-2-tps-3584-1808.png) + +### 场景介绍 + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01nnP60l1dqUhUiNSx6_!!6000000003787-2-tps-2852-1156.png) Demo 根据**不同的设计器所需要的物料不同**,分为了下面的 8 个场景: @@ -75,30 +88,39 @@ Demo 根据**不同的设计器所需要的物料不同**,分为了下面的 8 - 基础 antd 组件 - 自定义初始化引擎 - 扩展节点操作项 -- 基于next实现的高级表单低代码物料 +- 基于 next 实现的高级表单低代码物料 - antd 高级组件 + formily 表单组件 可以点开不同的场景,看看他们使用的物料。 +![](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) -## 目录介绍 -仓库下的 src/scenarios 目录就对应刚刚介绍的场景。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660655237007-fddd8534-d4ed-4a25-ba2f-f335f8ac3c36.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=348&id=ubf68019d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=696&originWidth=696&originalType=binary&ratio=1&rotation=0&showTitle=false&size=148777&status=done&style=stroke&taskId=u68648c51-7648-494e-bd41-4f29fb144f9&title=&width=348) +不同场景的目录结构实际上都是类似的,这里我们主要介绍一下综合场景的目录结构即可。 -不同场景的目录结构实际上都是类似的,这里我们主要介绍一下综合场景的目录结构即可。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660655399364-b40d206a-977d-4000-9be1-681823f8a995.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=ub727a7fa&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1373541&status=done&style=stroke&taskId=ue55dc86f-375d-4c7f-a63f-d5208683035&title=&width=1792)
综合场景目录下只有一个文件,这个文件做了几个事情: +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01A50oW522S5zg2eDUH_!!6000000007118-2-tps-732-1384.png) -- 通过 plugins.register 注册「切换场景」的插件,也就是上面介绍的切换场景的功能。 -- 通过 registerPlugins 注册更多的插件: - - ManualPlugin:增加弹出「低代码产品使用文档」按钮 - - Inject:支持调试功能 - - registerRefProp:支持给每个组件注入 ref - - ... -- 通过 init 初始化低代码设计器 +介绍下其中主要的内容 +- 设计器入口文件 `source/index.ts` 这个文件做了下述几个事情: + - 通过 plugins.register 注册各种插件,包括官方插件 (已发布 npm 包形式的插件) 和 `plugins` 目录下内置的示例插件 + - 通过 init 初始化低代码设计器 +- plugins 目录,存放的都是示例插件,方便用户从中看到一个插件是如何实现的 +- services 目录,模拟数据请求、提供默认 schema、默认资产包等,此目录下内容在真是项目中应替换成真是的与服务端交互的服务。 +- 预览页面入口文件 `preview.tsx` -做了这些事情之后,我们的低代码设计器就已经有了基本的能力了。也就是最开始我们看到的这样。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660654189055-45fd0c7e-75cb-4072-a4d4-7cf244405c7d.png#clientId=ubcf63daf-5747-4&crop=0&crop=0.008&crop=1&crop=1&from=paste&height=904&id=MZdfk&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1808&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=763122&status=done&style=stroke&taskId=u82753ad5-3b5d-43b2-b309-a99c2a7bb24&title=&width=1792) +剩下的各位看官可以通过源码来进一步了解。 + +做了这些事情之后,我们的低代码设计器就已经有了基本的能力了。也就是最开始我们看到的这样。 + +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01YJVcOd1PiL1am6bz2_!!6000000001874-2-tps-3248-1970.png) 接下来我们就根据我们自己的诉求通过对设计器进行扩展,改动成我们需要的设计器功能。 -# 开发一个插件 -## 方式1:在 DEMO 中直接新增插件 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660656064139-8da57c37-7e0b-4e8d-9f2d-8ea86d5af134.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=280&id=uc7f75c37&margin=%5Bobject%20Object%5D&name=image.png&originHeight=560&originWidth=820&originalType=binary&ratio=1&rotation=0&showTitle=false&size=125690&status=done&style=stroke&taskId=u53c07118-a2ca-4a77-a27f-3b2b20085ac&title=&width=410) +## 开发一个插件 +### 方式 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 @@ -153,64 +175,94 @@ LowcodePluginPluginDemo.meta = { export default LowcodePluginPluginDemo; ``` -在 src/scenarios/index/index.ts 中新增下面代码
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660656497051-49e08633-2d78-428c-becc-c282905cdb90.png#clientId=ubcf63daf-5747-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=u426edc7b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1458910&status=done&style=stroke&taskId=uf1e42399-caf7-4d82-a797-698fa730486&title=&width=1792) +在 src/index.ts 中新增下面代码 + +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01pNTr4N1kldoYZRzgI_!!6000000004724-2-tps-1976-1250.png) -这样在我们的设计器中就新增了一个 Demo 面板。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660656566260-86dfed37-60d0-45ca-967e-5df8ea7a34d0.png#clientId=ubcf63daf-5747-4&crop=0&crop=0.0053&crop=1&crop=1&from=paste&height=903&id=u17565cd3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1806&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=734227&status=done&style=stroke&taskId=u5dbe00f3-447b-451e-ac48-9b02281afc3&title=&width=1792) -## 方式2:在新的仓库下开发插件 +这样在我们的设计器中就新增了一个 Demo 面板。 + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01wtPIOV1TQiFLz5Vkf_!!6000000002377-2-tps-3584-1806.png) +### 方式 2:在新的仓库下开发插件 初始化 -```json +```bash npm init @alilc/element your-plugin-name ``` -选择设计器插件(plugin)
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660702297326-ccfe60f9-ee22-4a24-a293-26351d107663.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=107&id=ub2bf5248&margin=%5Bobject%20Object%5D&name=image.png&originHeight=214&originWidth=730&originalType=binary&ratio=1&rotation=0&showTitle=false&size=82091&status=done&style=stroke&taskId=u82628265-73f0-4d57-b4ba-1b18600a1f0&title=&width=365) +选择设计器插件(plugin) + +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01sA6sYW1tijqVeQCuq_!!6000000005936-2-tps-730-214.png) -根据操作完善信息
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660702439529-867a893f-f27a-4e48-8a5a-ee45aa97e355.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=109&id=uc9b09fec&margin=%5Bobject%20Object%5D&name=image.png&originHeight=218&originWidth=866&originalType=binary&ratio=1&rotation=0&showTitle=false&size=102705&status=done&style=stroke&taskId=ue4a95f21-43d3-4da8-9c0e-b21dfe239bf&title=&width=433) +根据操作完善信息 -插件项目就初始化完成了
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660702464438-3d7e07eb-53c7-417c-9e6d-06fdf9acfb86.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=280&id=u0ee65b4e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1197702&status=done&style=stroke&taskId=u5f9fdae3-1adc-4b02-969c-5c43c3d4c9c&title=&width=496) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01BzM1Jb1RcxbiJ0tJi_!!6000000002133-2-tps-866-218.png) + +插件项目就初始化完成了 + +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01iVIAXD1XVWsOdKttI_!!6000000002929-2-tps-3584-2020.png) 在插件项目下安装依赖 -```json +```bash npm install ``` 启动项目 -```json +```bash npm run start ``` -调试项目
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660705712773-f2446689-2b5f-42e7-9e85-30857270dfbb.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=346&id=u448649c5&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1936&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=757713&status=done&style=stroke&taskId=u0b617456-826e-4993-951e-303da417172&title=&width=641) +调试项目 + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01A4vPqC1xbeAqNxBRM_!!6000000006462-2-tps-3584-1936.png) + +在 Demo 中调试项目 -在 Demo 中调试项目
在 build.json 下面新增 "inject": true,就可以在 [https://lowcode-engine.cn/demo/index.html?debug](https://lowcode-engine.cn/demo/index.html?debug) 页面下进行调试了。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660705860117-5a11a5fa-9215-4b94-84b7-497899cafe10.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=u3a36c42f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=887101&status=done&style=stroke&taskId=u747bc337-5212-4a8b-a88f-127c53ea621&title=&width=1792) -# 开发一个自定义物料 -## 初始化物料 -```json +在 build.json 下面新增 "inject": true,就可以在 [https://lowcode-engine.cn/demo/demo-general/index.html?debug](https://lowcode-engine.cn/demo/demo-general/index.html?debug) 页面下进行调试了。 + +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01uqSmrX1oqupxeGH1m_!!6000000005277-2-tps-3584-2020.png) + + +## 开发一个自定义物料 +### 初始化物料 +```bash npm init @alilc/element your-material-demo ``` -选择组件/物料栏
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706045985-db73ca55-925a-446b-ace4-b59fa1e18469.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=104&id=kuWIf&margin=%5Bobject%20Object%5D&name=image.png&originHeight=208&originWidth=824&originalType=binary&ratio=1&rotation=0&showTitle=false&size=88910&status=done&style=stroke&taskId=u92f5fa65-386a-4f52-a093-bcbbebdc2d7&title=&width=412) -配置其他信息
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706116845-9b3b938f-c132-426b-81bd-d49283ebf9e8.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=124&id=u941c9808&margin=%5Bobject%20Object%5D&name=image.png&originHeight=248&originWidth=800&originalType=binary&ratio=1&rotation=0&showTitle=false&size=111864&status=done&style=stroke&taskId=ue4ff4dab-3a53-4811-bf70-7fa6fc0c8b6&title=&width=400) +选择组件/物料栏 -这样我们就初始化好了一个 React 物料。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706173968-3e5db25a-e08d-4852-90c9-ffaa0968fd62.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=u854b37cc&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1080400&status=done&style=stroke&taskId=u10e21350-23d4-4d8f-8c16-0c5a221fc2e&title=&width=1792) -## 启动并调试物料 -### 安装依赖 -```json +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01qVJQvG1Yhj2PJhhvk_!!6000000003091-2-tps-824-208.png) + +配置其他信息 + +![image.png](https://img.alicdn.com/imgextra/i3/O1CN017fFT8O1IVmrLYg87F_!!6000000000899-2-tps-800-248.png) + +这样我们就初始化好了一个 React 物料。 + +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01SU2xn91TZPlzcARVI_!!6000000002396-2-tps-3584-2020.png) + +### 启动并调试物料 +#### 安装依赖 +```bash npm i ``` -### 启动 -```json +#### 启动 +```bash npm run lowcode:dev ``` -我们就可以通过 [http://localhost:3333/](http://localhost:3333/) 看到我们的研发的物料了。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706484894-73798e35-1e58-4ffe-bb3c-bfba7b014433.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=895&id=zVMiy&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1790&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=678753&status=done&style=stroke&taskId=u241f50c0-1a43-4854-8443-7e972f15623&title=&width=1792) -### 在 Demo 中调试 -```json +我们就可以通过 [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 ``` -修改 build.lowcode.js
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706733149-0170b2fb-88de-40e3-8204-f510d7e42f77.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=311&id=u8a1a8bea&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1046&originWidth=1388&originalType=binary&ratio=1&rotation=0&showTitle=false&size=291155&status=done&style=stroke&taskId=u61ede7d2-f92d-43b9-8582-a2362a9ea14&title=&width=413) +修改 build.lowcode.js + +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01K7u7ci1KCfYlBj2yf_!!6000000001128-2-tps-1388-1046.png) 如图,新增如下代码 -```json +```javascript [ '@alilc/build-plugin-alt', { @@ -224,16 +276,18 @@ npm i @alilc/build-plugin-alt ], ``` -我们重新启动项目,就可以在 Demo 中找到我们的自定义组件。
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660706823666-ca28a08d-6241-4112-bc78-b9078c81fb75.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=906&id=u31bdc31a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1812&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=788013&status=done&style=stroke&taskId=uaa4789a2-452f-4b04-8894-759989e4568&title=&width=1792) +我们重新启动项目,就可以在 Demo 中找到我们的自定义组件。 -## 发布 +![image.png](https://img.alicdn.com/imgextra/i1/O1CN0166WywE26Lv7NuJMus_!!6000000007646-2-tps-3584-1812.png) + +### 发布 首先进行构建 -```json +```bash npm run lowcode:build ``` 发布组件 -```json +```bash npm publish ``` @@ -243,7 +297,8 @@ npm publish - 组件代码:[https://unpkg.com/my-material-demo@0.1.0/build/lowcode/render/default/view.js](https://unpkg.com/my-material-demo@0.1.0/build/lowcode/render/default/view.js) 我们也可以从 [https://unpkg.com/my-material-demo@0.1.0/build/lowcode/assets-prod.json](https://unpkg.com/my-material-demo@0.1.0/build/lowcode/assets-prod.json) 找到我们的资产包描述。 -```json + +```bash { "packages": [ { @@ -288,9 +343,18 @@ npm publish } ``` -## 使用 -我们将刚刚发布的组件的 assets-prod.json 的内容放到 demo 的 src/universal/assets.json 中。
*最好放到最后,防止因为资源加载顺序问题导致出现报错。
如图,新增 packages 配置
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660707789785-ea75a399-6845-45a8-8c53-08402749c9a8.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=uf0f75c17&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1327766&status=done&style=stroke&taskId=ub053d846-69fd-4a55-8e9e-b41d1e06e47&title=&width=1792)
如图,新增 components 配置
![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1660707811725-a0e36f48-910d-45b5-b162-3aa4e2f87e9b.png#clientId=udb19495f-ea47-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1010&id=uf8c9506f&margin=%5Bobject%20Object%5D&name=image.png&originHeight=2020&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1222080&status=done&style=stroke&taskId=u10147f1f-27ed-4cec-bfc9-2cb3d61d6a2&title=&width=1792) +### 使用 +我们将刚刚发布的组件的 assets-prod.json 的内容放到 demo 的 src/universal/assets.json 中。 + +> 最好放到最后,防止因为资源加载顺序问题导致出现报错。 + +如图,新增 packages 配置 +![image.png](https://img.alicdn.com/imgextra/i1/O1CN018dnIB91XHmzeTrq3n_!!6000000002899-2-tps-3584-2020.png) + +如图,新增 components 配置 + +![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 e300400100..0694cdba34 100644 --- a/docs/docs/participate/config.md +++ b/docs/docs/participate/config.md @@ -2,7 +2,7 @@ title: 工程化配置 sidebar_position: 3 --- -目前引擎体系共包含 3 个 js 文件,即: +目前引擎体系共包含 2 个 js 文件,即: ```html diff --git a/docs/docs/participate/doc.md b/docs/docs/participate/doc.md index c1ef26f8d4..d2b86ff330 100644 --- a/docs/docs/participate/doc.md +++ b/docs/docs/participate/doc.md @@ -7,11 +7,19 @@ sidebar_position: 3 ### 维护方式 -- 官方文档通过 github 管理文档源, 官网文档与[主仓库 develop 分支](https://github.com/alibaba/lowcode-engine/tree/develop/docs)保持同步。 +- 官方文档通过 github 管理文档源,官网文档与[主仓库 develop 分支](https://github.com/alibaba/lowcode-engine/tree/develop/docs)保持同步。 - 点击每篇文档下发的 `编辑此页` 可直接定位到 github 中位置。 -- 欢迎 PR, 文档 PR 也会作为贡献者贡献,会用于贡献度统计。 +- 欢迎 PR,文档 PR 也会作为贡献者贡献,会用于贡献度统计。 - 文档同步到官方网站由官方人员进行操作,如有需要可以通过 issue 或 贡献者群与相关人员沟通。 +- 为了提供更好的阅读和使用体验,文档中的图片文件会定期转换成可信的 CDN 地址。 -### PR 方式 +### PR 提交注意事项 -- 操作与代码贡献一致,指向 develop 分支。 \ No newline at end of file +- 指向 develop 分支。 +- 涉及到图片的,需附在文档同级的 img 目录下,通过相对地址引用。 + +### 文档格式 + +本项目文档参考[文档编写指南](https://github.com/sparanoid/chinese-copywriting-guidelines)。 + +使用 vscode 进行编辑的朋友可以安装 vscode 插件 [huacnlee.autocorrect](https://github.com/huacnlee/autocorrect) 辅助文档 lint。 diff --git a/docs/docs/participate/flow.md b/docs/docs/participate/flow.md index 24ebd3629d..e346f7711b 100644 --- a/docs/docs/participate/flow.md +++ b/docs/docs/participate/flow.md @@ -44,7 +44,7 @@ sidebar_position: 2 - 日常迭代 2 周,一般月中或月底 - 特殊情况紧急迭代随时发 -- 大Feature迭代,每年 2 - 4 次 +- 大 Feature 迭代,每年 2 - 4 次 ### 发布步骤 @@ -57,7 +57,7 @@ sidebar_position: 2 ```bash git checkout develop ``` -2. 创建release分支 +2. 创建 release 分支 ```bash git checkout -b release/1.0.0 ``` @@ -65,7 +65,7 @@ sidebar_position: 2 ```bash npm run build ``` -4. 发布到npm +4. 发布到 npm ```bash npm run pub ``` @@ -77,9 +77,9 @@ sidebar_position: 2 7. 合并 release/x.x.x 到 main 分支 8. 合并 main 分支到 develop 分支 -如果是发布beta 版本,步骤如下(以发布 1.0.1 版本为例): +如果是发布 beta 版本,步骤如下(以发布 1.0.1 版本为例): -#### 发某版本首个 beta ,如 1.0.1-beta.0 +#### 发某版本首个 beta,如 1.0.1-beta.0 1. 拉 develop 分支 ```bash git checkout develop @@ -105,7 +105,7 @@ sidebar_position: 2 tnpm run sync ``` -#### 发某版本非首个 beta ,如 1.0.1-beta.0 -> 1.0.1-beta.1 +#### 发某版本非首个 beta,如 1.0.1-beta.0 -> 1.0.1-beta.1 1. 切换到 release 分支 ```bash git checkout release/1.0.1-beta @@ -136,7 +136,7 @@ sidebar_position: 2 ```bash npm run build ``` -3. publish (此步骤需要 npm 发包权限) +3. publish(此步骤需要 npm 发包权限) ```bash npm run pub ``` diff --git a/docs/docs/specs/assets-spec.md b/docs/docs/specs/assets-spec.md index 5c7df0163f..dc55b12c1a 100644 --- a/docs/docs/specs/assets-spec.md +++ b/docs/docs/specs/assets-spec.md @@ -65,7 +65,7 @@ sidebar_position: 2 - setters { Array } 设计器中设置器描述协议列表 - extConfig { Object } 平台自定义扩展字段 -### 2.1 version(A) +### 2.1 version (A) 定义当前协议 schema 的版本号; @@ -73,9 +73,9 @@ sidebar_position: 2 | ---------- | ------ | ---------- | -------- | ------ | | version | String | 协议版本号 | - | 1.1.0 | -### 2.2 packages(A) +### 2.2 packages (A) -定义低代码编辑器中加载的资源列表,包含公共库和组件(库) cdn 资源等; +定义低代码编辑器中加载的资源列表,包含公共库和组件 (库) cdn 资源等; | 字段 | 字段描述 | 字段类型 | 规范等级 | 备注 | | -------------------- | --------------------------------------------------------------- | ------------- | -------- | -------------------------------------------------------------------------------------------------------- | @@ -92,13 +92,13 @@ sidebar_position: 2 | packages[].advancedEditUrls | 组件多个编辑态视图打包后的 CDN url 列表集合,包含 js 和 css | Object | AAA | 上层平台根据特定标识提取某个编辑态的资源,低代码引擎编辑器会加载这些资源,优先级高于 packages[].editUrls | | packages[].advancedUrls | 组件多个端的渲染态视图打包后的 CDN url 列表集合,包含 js 和 css | Object | AAA | 上层平台根据特定标识提取某个渲染态的资源, 低代码引擎渲染模块会加载这些资源,优先级高于 packages[].urls | | packages[].external | 当前资源在作为其他资源的依赖,在其他依赖打包时时是否被排除了(同 webpack 中 external 概念) | Boolean | AAA | 某些资源会被单独提取出来,是其他依赖的前置依赖,根据这个字段决定是否提前加载该资源 | -| packages[].loadEnv | 指定当前资源加载的环境 | Array | AAA | 主要用于指定 external 资源加载的环境,取值为 design(设计态)、runtime(预览态)中的一个或多个 | +| packages[].loadEnv | 指定当前资源加载的环境 | Array | AAA | 主要用于指定 external 资源加载的环境,取值为 design(设计态)、runtime(预览态) 中的一个或多个 | | packages[].exportSourceId | 标识当前 package 内容是从哪个 package 导出来的 | String | AAA | 此时 urls 无效 | | packages[].exportSourceLibrary | 标识当前 package 是从 window 上的哪个属性导出来的 | String | AAA | exportSourceId 的优先级高于exportSourceLibrary ,此时 urls 无效 | | packages[].async | 标识当前 package 资源加载在 window.library 上的是否是一个异步对象 | Boolean | A | async 为 true 时,需要通过 await 才能拿到真正内容 | | packages[].exportMode | 标识当前 package 从其他 package 的导出方式 | String | A | 目前只支持 `"functionCall"`, exportMode等于 `"functionCall"` 时,当前package 的内容以函数的方式从其他 package 中导出,具体导出接口如: (library: string, packageName: string, isRuntime?: boolean) => any | Promise, library 为当前 package 的 library, packageName 为当前的包名,返回值为当前 package 的导出内容 | -描述举例: +描述举例: ```json { @@ -298,14 +298,14 @@ sidebar_position: 2 } ``` -### 2.3 components (A) +### 2.3 components (A) 定义资产包中包含的所有组件的低代码描述的集合,分为“ComponentDescription”和“RemoteComponentDescription”(详见 2.6 TypeScript 定义): - ComponentDescription: 符合“组件描述协议”的数据,详见物料规范中`2.2.2 组件描述协议`部分; - RemoteComponentDescription 是将一个或多个 ComponentDescription 构建打包的 js 资源的描述,在浏览器中加载该资源后可获取到其中包含的每个组件的 ComponentDescription 的具体内容; -### 2.4 sort (AA) +### 2.4 sort (AA) 定义组件列表分组 @@ -346,7 +346,7 @@ sidebar_position: 2 ### 2.7 extConfig (AAA) -定义平台相关的扩展内容,用于存放平台自身实现的一些私有协议, 以允许存量平台能够平滑地迁移至标准协议。 extConfig 是一个 key-value 结构的对象,协议不会规定 extConfig 中的字段名称以及类型, 完全自定义 +定义平台相关的扩展内容,用于存放平台自身实现的一些私有协议,以允许存量平台能够平滑地迁移至标准协议。extConfig 是一个 key-value 结构的对象,协议不会规定 extConfig 中的字段名称以及类型,完全自定义 ### 2.8 TypeScript 定义 diff --git a/docs/docs/specs/lowcode-spec.md b/docs/docs/specs/lowcode-spec.md index e1d57daa04..6ad87caefe 100644 --- a/docs/docs/specs/lowcode-spec.md +++ b/docs/docs/specs/lowcode-spec.md @@ -78,7 +78,7 @@ sidebar_position: 0 ### 1.7 背景 -- **协议目标**: 通过约束低代码引擎的搭建协议规范,让上层低代码编辑器的产出物(低代码业务组件、区块、应用)保持一致性,可跨低代码研发平台进行流通而提效,亦不阻碍集团业务间融合的发展。  +- **协议目标**:通过约束低代码引擎的搭建协议规范,让上层低代码编辑器的产出物(低代码业务组件、区块、应用)保持一致性,可跨低代码研发平台进行流通而提效,亦不阻碍集团业务间融合的发展。  - **协议通**: - 协议顶层结构统一 - 协议 schema 具备有完整的描述能力,包含版本、国际化、组件树、组件映射关系等; @@ -179,10 +179,10 @@ sidebar_position: 0 "props": { "prop1": 1234, // 简单 json 数据 "prop2": [{ // 简单 json 数据 - "label": "选项1", + "label": "选项 1", "value": 1 }, { - "label": "选项2", + "label": "选项 2", "value": 2 }], "prop3": [{ @@ -232,8 +232,8 @@ sidebar_position: 0 "primary": "#ff9966" } }, - "meta": { // 应用元数据信息, key 为业务自定义 - "name": "demo 应用", // 应用中文名称, + "meta": { // 应用元数据信息,key 为业务自定义 + "name": "demo 应用", // 应用中文名称, "git_group": "appGroup", // 应用对应 git 分组名 "project_name": "app_demo", // 应用对应 git 的 project 名称 "description": "这是一个测试应用", // 应用描述 @@ -343,7 +343,7 @@ sidebar_position: 0 出码结果: ```javascript -// 使用解构方式, destructuring is true. +// 使用解构方式,destructuring is true. import { Button } from '@alifd/next'; // 使用解构方式,且 exportName 和 componentName 不同 @@ -376,7 +376,7 @@ import { Input as CustomInput } from '@ali/custom/lib/input'; 与源码对应的转换关系如下: - 组件结构:转换成一个 .jsx 文件内 React Class 类 render 函数返回的 **jsx** 代码。 -- 容器结构:将转换成一个标准文件,如 React 的 jsx 文件, export 一个 React Class,包含生命周期定义、自定义方法、事件属性绑定、异步数据请求等。 +- 容器结构:将转换成一个标准文件,如 React 的 jsx 文件,export 一个 React Class,包含生命周期定义、自定义方法、事件属性绑定、异步数据请求等。 #### 2.3.1 基础结构描述 (A) @@ -427,9 +427,9 @@ import { Input as CustomInput } from '@ali/custom/lib/input'; | shouldFetch | 本次请求是否可以正常请求 | (options: ComponentDataSourceItemOptions) => boolean | - | ```() => true``` | function 参数参考 [ComponentDataSourceItemOptions 对象描述](#2315-componentdatasourceitemoptions-对象描述) | | willFetch | 单个数据结果请求参数处理函数 | Function | - | options => options | 只接受一个参数(options),返回值作为请求的 options,当处理异常时,使用原 options。也可以返回一个 Promise,resolve 的值作为请求的 options,reject 时,使用原 options | | requestHandler | 自定义扩展的外部请求处理器 | Function | - | - | 仅 type='custom' 时生效 | -| dataHandler | request 成功后的回调函数 | Function | - | `response => response.data` | 参数: 请求成功后 promise 的 value 值 | -| errorHandler | request 失败后的回调函数 | Function | - | - | 参数: 请求出错 promise 的 error 内容 | -| options {} | 请求参数 | **ComponentDataSourceItemOptions** | - | - | 每种请求类型对应不同参数, 详见 [ComponentDataSourceItemOptions 对象描述](#2315-componentdatasourceitemoptions-对象描述) | +| dataHandler | request 成功后的回调函数 | Function | - | `response => response.data`| 参数:请求成功后 promise 的 value 值 || +| errorHandler | request 失败后的回调函数 | Function | - | - | 参数:请求出错 promise 的 error 内容 | +| options {} | 请求参数 | **ComponentDataSourceItemOptions**| - | - | 每种请求类型对应不同参数,详见 | 每种请求类型对应不同参数,详见 [ComponentDataSourceItemOptions 对象描述](#2315-componentdatasourceitemoptions-对象描述) | **关于 dataHandler 于 errorHandler 的细节说明:** @@ -518,7 +518,7 @@ try { | 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | | ------------ | ---------- | -------------- | -------- | --------- | ----------------------------------------------------------------------------------------------------------------- | | name | 属性名称 | String | - | - | | -| propType | 属性类型 | String\|Object | - | - | 具体值内容结构,参考《低代码引擎物料协议规范》 内的 “2.2.2.3 组件属性信息”中描述的**基本类型**和**复合类型** | +| propType | 属性类型 | String\|Object | - | - | 具体值内容结构,参考《低代码引擎物料协议规范》内的“2.2.2.3 组件属性信息”中描述的**基本类型**和**复合类型** | | description | 属性描述 | String | - | '' | | | defaultValue | 属性默认值 | Any | - | undefined | 当 defaultValue 和 defaultProps 中存在同一个 prop 的默认值时,优先使用 defaultValue。 | @@ -544,9 +544,9 @@ try { | 参数 | 说明 | 类型 | 支持变量 | 默认值 | 备注 | | ------------- | ---------------------- | ---------------- | -------- | ----------------- | ---------------------------------------------------------------------------------------------------------- | -| id | 组件唯一标识 | String | - | | 可选, 组件 id 由引擎随机生成(UUID),并保证唯一性,消费方为上层应用平台,在组件发生移动等场景需保持 id 不变 | -| componentName | 组件名称 | String | - | Div | 必填,首字母大写, 同 [componentsMap](#22-组件映射关系 a) 中的要求 | -| props {} | 组件属性对象 | **Props** | - | {} | 必填, 详见 [Props 结构描述](#2311-props-结构描述) | +| id | 组件唯一标识 | String | - | | 可选,组件 id 由引擎随机生成(UUID),并保证唯一性,消费方为上层应用平台,在组件发生移动等场景需保持 id 不变 | +| componentName | 组件名称 | String | - | Div | 必填,首字母大写,同 [componentsMap](#22-组件映射关系 a) 中的要求 | +| props {} | 组件属性对象 | **Props**| - | {} | 必填,详见 | 必填,详见 [Props 结构描述](#2311-props-结构描述) | | condition | 渲染条件 | Boolean | ✅ | true | 选填,根据表达式结果判断是否渲染物料;支持变量表达式 | | loop | 循环数据 | Array | ✅ | - | 选填,默认不进行循环渲染;支持变量表达式 | | loopArgs | 循环迭代对象、索引名称 | [String, String] | | ["item", "index"] | 选填,仅支持字符串 | @@ -611,10 +611,10 @@ try { | condition | 渲染条件 | Boolean | ✅ | true | 选填,根据表达式结果判断是否渲染物料;支持变量表达式 | | state | 容器初始数据 | Object | ✅ | - | 选填,支持变量表达式 | | children | 子组件 | Array | - | | 选填,支持变量表达式 | -| css/less/scss | 样式属性 | String | ✅ | - | 选填, 详见 [css/less/scss 样式描述](#2312-csslessscss 样式描述) | +| css/less/scss | 样式属性 | String | ✅ | - | 选填,详见 [css/less/scss 样式描述](#2312-csslessscss 样式描述) | | lifeCycles | 生命周期对象 | **ComponentLifeCycles** | - | - | 详见 [ComponentLifeCycles 对象描述](#2316-componentlifecycles-对象描述) | | methods | 自定义方法对象 | Object | - | - | 选填,对象成员为函数类型 | -| dataSource {} | 数据源对象 | **ComponentDataSource** | - | - | 选填,异步数据源, 详见 [ComponentDataSource 对象描述](#2313-componentdatasource-对象描述) | +| dataSource {} | 数据源对象 | **ComponentDataSource**| - | - | 选填,异步数据源,详见 | - | - | 选填,异步数据源,详见 [ComponentDataSource 对象描述](#2313-componentdatasource-对象描述) | @@ -891,7 +891,7 @@ try { "value": "this.state.num - this.state.num2" } ``` -- return "8万" 字符串类型 +- return "8 万" 字符串类型 ```json { @@ -899,7 +899,7 @@ try { "value": "`${this.state.num}万`" } ``` -- return "8万" 字符串类型 +- return "8 万" 字符串类型 ```json { @@ -1056,7 +1056,7 @@ type Ti18n = { 请将 `setState()` 视为请求而不是立即更新组件的命令。为了更好的感知性能,低代码引擎会延迟调用它,然后通过一次传递更新多个组件。低代码引擎并不会保证 state 的变更会立即生效。 -`setState()` 并不总是立即更新组件, 它会批量推迟更新。这使得在调用 `setState()` 后立即读取 `this.state` 成为了隐患。为了消除隐患,请使用 `setState` 的回调函数(`setState(updater, callback)`),`callback` 将在应用更新后触发。即,如下例所示: +`setState()`并不总是立即更新组件,它会批量推迟更新。这使得在调用用 `setState()` 后立即读取 `this.state` 成为了隐患。为了消除隐患,请使用 `setState` 的回调函数(`setState(updater, callback)`),`callback` 将在应用更新后触发。即,如下例所示: ```js this.setState(newState, () => { @@ -1087,7 +1087,7 @@ this.setState((prevState) => ({ count: prevState.count + 1 })); | data | 获取上次请求成功后的数据 | Any | | | error | 获取上次请求失败的错误对象 | Error 对象 | | -备注: 如果组件没有在区块容器内,而是直接在页面内,那么 `this === this.page` +备注:如果组件没有在区块容器内,而是直接在页面内,那么 `this === this.page` ##### 2.3.5.2 循环数据 API @@ -1108,7 +1108,7 @@ this.setState((prevState) => ({ count: prevState.count + 1 })); | ------------------ | ------------------ | ---------------------------------------------------------------------------------------------------------------- | -------- | ------ | | utils[] | 工具类扩展映射关系 | Array\<**UtilItem**\> | - | | | *UtilItem*.name | 工具类扩展项名称 | String | - | | -| *UtilItem*.type | 工具类扩展项类型 | 枚举, `'npm'` (代表公网 npm 类型) / `'tnpm'` (代表阿里巴巴内部 npm 类型) / `'function'` (代表 Javascript 函数类型) | - | | +| *UtilItem*.type | 工具类扩展项类型 | 枚举, `'npm'` (代表公网 npm 类型) / `'tnpm'` (代表阿里巴巴内部 npm 类型) / `'function'` (代表 Javascript 函数类型) | - | | | *UtilItem*.content | 工具类扩展项内容 | [ComponentMap 类型](#22-组件映射关系 a) 或 [JSFunction](#2432事件函数类型 a) | - | | 描述示例: @@ -1161,7 +1161,7 @@ export const recordEvent = function(logkey, gmkey, gokey, reqMethod) { ... ``` -扩展的工具类,用户可以通过统一的上下文 this.utils 方法获取所有扩展的工具类或自定义函数 ,例如:this.utils.moment、this.utils.clone。搭建协议中的使用方式如下所示: +扩展的工具类,用户可以通过统一的上下文 this.utils 方法获取所有扩展的工具类或自定义函数,例如:this.utils.moment、this.utils.clone。搭建协议中的使用方式如下所示: ```javascript { @@ -1202,7 +1202,7 @@ export const recordEvent = function(logkey, gmkey, gokey, reqMethod) { } ``` -使用举例: +使用举例: ```json { @@ -1303,11 +1303,11 @@ export const recordEvent = function(logkey, gmkey, gokey, reqMethod) { │ │ └── app.js # 应用配置文件 │ ├── utils/ # 工具库 │ │ └── index.js # 应用第三方扩展函数 -│ ├── locales/ # [可选]国际化资源 +│ ├── locales/ # [可选] 国际化资源 │ │ ├── en-US │ │ └── zh-CN │ ├── global.scss # 全局样式 -│ └── index.jsx # 应用入口脚本, 依赖 config/routes.js 的路由配置动态生成路由; +│ └── index.jsx # 应用入口脚本,依赖 config/routes.js 的路由配置动态生成路由; ├── webpack.config.js # 项目工程配置,包含插件配置及自定义 webpack 配置等 ├── README.md ├── package.json diff --git a/docs/docs/specs/material-spec.md b/docs/docs/specs/material-spec.md index f7687114b6..9d12da5262 100644 --- a/docs/docs/specs/material-spec.md +++ b/docs/docs/specs/material-spec.md @@ -250,7 +250,7 @@ API 是组件的属性解释,给开发者作为组件属性配置的参考。 | direction | enum | 方向,取值采用缩写的方式。 | hoz(水平), ver(垂直) | | align | enum | 对齐方式 | tl, tc, tr, cl, cc, cr, bl, bc, br | | status | enum | 状态 | normal, success, error, warning | -| size | enum | 大小 | small, medium, large 更大或更小可用(xxs, xs, xl, xxl) | +| size | enum | 大小 | small, medium, large 更大或更小可用 (xxs, xs, xl, xxl) | | type | enum or string | 分类:1. dom 结构不变、只有皮肤的变化 2.组件类型只有并列的几类 | normal, primary, secondary | | visible | boolean | 是否显示 | | | defaultVisible | boolean | 是否显示(非受控) | | @@ -266,7 +266,7 @@ API 是组件的属性解释,给开发者作为组件属性配置的参考。 当某个 API 的接口,允许用户指定多个枚举值的时候,我们把这个接口定义为多选枚举。一个很典型的例子是某个弹层组件的 `closable` 属性,我们会允许:键盘 esc 按键、点击 mask、点击 close 按钮、点击组件以外的任何区域进行关闭。 -不要有一个 API 值,支持多种类型。例如某个弹层的组件,我们会允许 esc、点击 mask、点击 close 按钮等进行关闭。此时 API 设计可以通过多个 API 承载,例如: +不要有一个 API 值,支持多种类型。例如某个弹层的组件,我们会允许 esc、点击 mask、点击 close 按钮等进行关闭。此时 API 设计可以通过多个 API 承载,例如: ```js closable?: boolean; // 默认为 true @@ -283,14 +283,14 @@ true 表示触发规则都会关闭,false 表示触发规则不会关闭。 #### 事件 -- 标准事件或者自定义的符合 w3c 标准的事件,命名必须 on 开头, 即 `on` + 事件名,如 onExpand。 +- 标准事件或者自定义的符合 w3c 标准的事件,命名必须 on 开头, 即 `on` + 事件名,如 onExpand。 #### 表单规范 - 支持[受控模式](https://reactjs.org/docs/forms.html#controlled-components)(value + onChange) (A) - value 控制组件数据展现 - onChange 组件发生变化时候的回调函数(第一个参数可以给到 value) -- `value={undefined}` 的时候清空数据, field 的 reset 函数会给所有组件下发 undefined 数据 (AA) +- `value={undefined}`的时候清空数据,field 的 reset 函数会给所有组件下发 undefined 数据 (AA)) - 一次完整操作抛一次 onChange 事件 `建议` 比如有 Process 表示进展中的状态,建议增加 API `onProcess`;如果有 Start 表示启动状态,建议增加 API `onStart`  (AA) #### 属性的传递 @@ -357,7 +357,7 @@ $ iceworks sync #### 目录规范 -在 `src` 目录新增 `locale` 目录用于管理不同语言的文案. +在 `src` 目录新增 `locale` 目录用于管理不同语言的文案。 ``` |- BizHello @@ -499,9 +499,9 @@ export default { api 属性标准参考 [https://fusion.design/help.html#/dev-biz](https://fusion.design/help.html#/dev-biz) -#### 2.1.7 无障碍访问规范(AAA) +#### 2.1.7 无障碍访问规范 (AAA) -无障碍需要符合 [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) 章节等。 +无障碍需要符合 [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 @@ -552,7 +552,7 @@ component | -------------- | ------------------------------------------------------------------------------------------------- | ------ | | version | 协议版本号 | String | | componentsMap | 描述组件映射关系的集合 | Array | -| componentsTree | 低代码业务组件树描述,是长度固定为1的数组, 即数组内仅包含根容器的描述(低代码业务组件容器类型) | Array | +| componentsTree | 低代码业务组件树描述,是长度固定为 1 的数组,即数组内仅包含根容器的描述(低代码业务组件容器类型) | Array | | utils | 工具类扩展映射关系 | Array | | i18n | 国际化语料 | Object | @@ -572,7 +572,7 @@ component "name": "lucy", }, "static": {}, // 用于定义自定组件的 static 属性 - "defaultProps": { // 默认 props: 选填仅用于定义低代码业务组件的默认属性固定对象 + "defaultProps": { // 默认 props:选填仅用于定义低代码业务组件的默认属性固定对象 "name": "xxx" }, "children": [{ @@ -609,8 +609,6 @@ component - **组件属性信息 (A):** 描述组件属性信息,通常包含参数、说明、类型、默认值 4 项内容。 - **能力配置/体验增强:** 推荐用于优化搭建产品编辑体验,定制编辑能力的配置信息。 -整体结构概览: [http://lowcode-engine.cn/doc?url=sde3wf](http://lowcode-engine.cn/doc?url=sde3wf) - ##### 2.2.2.2 基础信息(A) | 字段 | 字段描述 | 字段类型 | 允许空 | @@ -837,7 +835,7 @@ props 数组下对象字段描述: | defaultValue | 默认值 | Any(视字段类型而定) | type = 'field' 生效 | | supportVariable | 是否支持配置变量 | Boolean | type = 'field' 生效 | | condition | 配置当前 prop 是否展示 | (target: SettingTarget) => boolean; | - | -| setter | 单个控件(setter)描述,搭建基础协议组件的描述对象,支持 JSExpression / JSFunction / JSSlot | `String\|Object\|Function` | type = 'field' 生效 | +| setter | 单个控件 (setter) 描述,搭建基础协议组件的描述对象,支持 JSExpression / JSFunction / JSSlot | `String\|Object\|Function` | type = 'field' 生效 | | extraProps | 其他配置属性(不做流通要求) | Object | 其他配置 | | extraProps.getValue | setter 渲染时被调用,setter 会根据该函数的返回值设置 setter 当前值 | Function | (target: SettingTarget, value: any) => any; | | extraProps.setValue | setter 内容修改时调用,开发者可在该函数内部修改节点 schema 或者进行其他操作 | Function | (target: SettingTarget, value: any) => void; | @@ -885,7 +883,7 @@ props 数组下对象字段描述: | nestingRule.descendantBlacklist | 后裔节点类型黑名单 | `String\|Function` | | nestingRule.ancestorWhitelist | 祖父节点类型白名单 | `String\|Function` | | isNullNode(AAA) | 是否存在渲染的根节点 | Boolean | -| isLayout(AAA) | 是否是layout布局组件 | Boolean | +| isLayout(AAA) | 是否是 layout 布局组件 | Boolean | | rootSelector(AAA) | 组件选中框的 cssSelector | String | | disableBehaviors(AAA) | 用于屏蔽在设计器中选中组件时提供的操作项,默认操作项有 copy、hide、remove | String[] | | actions(AAA) | 用于详细配置上述操作项的内容 | Object | @@ -925,20 +923,20 @@ 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| - +|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.onResize| 调整容器尺寸时触发的事件回调,常常与 getResizingHandlers搭配使用| Function| 详见 Types 定义 -|callbacks.onResizeStart| 调整容器尺寸开始时触发的事件回调,常常与 getResizingHandlers搭配使用| Function| 详见 Types 定义 -|callbacks.onResizeEnd| 调整容器尺寸结束时触发的事件回调,常常与 getResizingHandlers搭配使用| Function| 详见 Types 定义 +|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.onMoveHook| 节点被拖动回调| Function| (currentNode: any) => boolean; -|callbacks.onHoverHook| 节点被 hover 回调| Function| (currentNode: any) => boolean; +|callbacks.onMoveHook| 节点被拖动回调 | Function| (currentNode: any) => boolean; +|callbacks.onHoverHook| 节点被 hover 回调 | Function| (currentNode: any) => boolean; |callbacks.onChildMoveHook| 容器节点的子节点被拖动回调| Function| (childNode: any, currentNode: any) => boolean; @@ -1211,7 +1209,7 @@ export interface ComponentDescription { // 组件描述协议,通过 npm 中 - components { Array } 所有组件的描述协议列表 - sort { Object } 用于描述组件面板中的 tab 和 category -##### 2.2.3.2 version(A) +##### 2.2.3.2 version (A) 定义当前协议 schema 的版本号; @@ -1219,9 +1217,9 @@ export interface ComponentDescription { // 组件描述协议,通过 npm 中 | ---------- | ------ | ---------- | -------- | ------ | | version | String | 协议版本号 | - | 1.0.0 | -##### 2.2.3.3 packages(A) +##### 2.2.3.3 packages (A) -定义低代码编辑器中加载的资源列表,包含公共库和组件(库) cdn 资源等; +定义低代码编辑器中加载的资源列表,包含公共库和组件 (库) cdn 资源等; | 字段 | 字段描述 | 字段类型 | 备注 | | --------------- | ---------------------- | -------- | ------------------------------------------------------------ | @@ -1232,7 +1230,7 @@ export interface ComponentDescription { // 组件描述协议,通过 npm 中 | packages[].editUrls (A) | 组件编辑态视图打包后的 CDN url 列表,包含 js 和 css | Array\ | 低代码引擎编辑器会加载这些 url | | packages[].urls (AA) | 组件渲染态视图打包后的 CDN url 列表,包含 js 和 css | Array\ | 低代码引擎渲染模块会加载这些 url | -描述举例: +描述举例: ```json { @@ -1253,7 +1251,7 @@ export interface ComponentDescription { // 组件描述协议,通过 npm 中 ] }, { - "title": "fusion组件库", + "title": "fusion 组件库", "package": "@alifd/next", "version": "1.24.18", "urls": [ @@ -1292,11 +1290,11 @@ export interface ComponentDescription { // 组件描述协议,通过 npm 中 } ``` -##### 2.2.3.4 components (A) +##### 2.2.3.4 components (A) 定义所有组件的描述协议列表,组件描述协议遵循本规范章节 2.2.2 的定义; -##### 2.2.3.5 sort (A) +##### 2.2.3.5 sort (A) 定义组件列表分组 @@ -1330,7 +1328,7 @@ export interface RemoteComponentDescription { } ``` -## 3 物料规范-区块规范 +## 3 物料规范 - 区块规范 ### 3.1 源码规范 @@ -1386,14 +1384,14 @@ block/ "category": "form", "screenshot": "https://unpkg.com/@icedesign/user-landing-block/screenshot.png", "views": [{ // 区块视图,配置此项后会进入 fusion cool - "title": "视图1标题", // 区块视图标题 + "title": "视图 1 标题", // 区块视图标题 "props": { // 区块支持的 props "type": "primary" }, "screenshot": "build/views/block_view1.png", // 【编译自动填充】视图截图,会在 build 时自动生成 "html": "build/views/block_view1.html", // 【编译自动填充】视图渲染后 html 结构,会在 build 时自动生成 },{ - "title": "视图2标题", // 区块视图标题 + "title": "视图 2 标题", // 区块视图标题 "props": { // 区块支持的 props "type": "sencondary" }, @@ -1417,7 +1415,7 @@ block/ | i18n | 国际化语料 | Object | -描述举例1: +描述举例 1: ```json { @@ -1425,7 +1423,7 @@ block/ "componentsMap": [{ }], "componentsTree": [{ // 区块组件树,顶层由区块容器组件包裹; "componentName": "Block", // 区块容器组件名 - "fileName": "block1", // 区块容器1 + "fileName": "block1", // 区块容器 1 "props": {}, "css": "body {font-size: 12px;}", "state": { @@ -1454,7 +1452,7 @@ block/ } ``` -描述举例2: +描述举例 2: ```json { @@ -1527,13 +1525,13 @@ block/ │ │ └── app.js # 应用配置文件 │ ├── utils/ # 工具库 │ │ └── index.js # 应用第三方扩展函数 -│ ├── stores/ # [可选]全局状态管理 +│ ├── stores/ # [可选] 全局状态管理 │ │ └── user.js -│ ├── locales/ # [可选]国际化资源 +│ ├── locales/ # [可选] 国际化资源 │ │ ├── en-US │ │ └── zh-CN │ ├── global.scss # 全局样式 -│ └── index.jsx # 应用入口脚本, 依赖 config/routes.js 的路由配置动态生成路由; +│ └── index.jsx # 应用入口脚本,依赖 config/routes.js 的路由配置动态生成路由; ├── webpack.config.js # 项目工程配置,包含插件配置及自定义 `webpack` 配置等 ├── README.md ├── package.json @@ -1567,11 +1565,11 @@ ReactDOM.render(, document.getElementById(pkg.config && pkg.config.target (/src/config/app.js) - 支持配置路由方式:historyMode - - 支持2种路由方式: - - 浏览器路由: browser - - 哈希路由:  hash + - 支持 2 种路由方式: + - 浏览器路由:browser + - 哈希路由:hash - 支持透传路由产生的参数到所有组件的上下文 this 对象上 - - history 对象: this.history + - history 对象:this.history - location 对象:this.location - 支持内置 query 参数的解析:this.location.query - match 对象:this.match @@ -1658,15 +1656,15 @@ a { "category": "form", "screenshot": "https://unpkg.com/@icedesign/user-landing-block/screenshot.png", "views": [{ // 模板视图,配置此项后会进入 fusion cool - "title": "视图1标题", // 模板视图标题 - "path": "#/dashboard/monitor", // 读取路由列表生成,hash 路由必须加# - "screenshot": "build/views/page0.png", // 【编译自动填充】视图截图,会在 build 时自动生成 - "html": "build/views/page0.html", // 【编译自动填充】视图渲染后 html 结构,会在 build 时自动生成 + "title": "视图 1 标题", // 模板视图标题 + "path": "#/dashboard/monitor", // 读取路由列表生成,hash 路由必须加# + "screenshot": "build/views/page0.png", // 【编译自动填充】视图截图,会在 build 时自动生成 + "html": "build/views/page0.html", // 【编译自动填充】视图渲染后 html 结构,会在 build 时自动生成 },{ - "title": "视图2标题", // 区块视图标题 - "path": "#/dashboard/list", // 读取路由列表生成,hash 路由必须加# - "screenshot": "build/views/page1.png", // 【编译自动填充】视图截图,会在 build 时自动生成 - "html": "build/views/page1.html", // 【编译自动填充】视图渲染后 html 结构,会在 build 时自动生成 + "title": "视图 2 标题", // 区块视图标题 + "path": "#/dashboard/list", // 读取路由列表生成,hash 路由必须加# + "screenshot": "build/views/page1.png", // 【编译自动填充】视图截图,会在 build 时自动生成 + "html": "build/views/page1.html", // 【编译自动填充】视图渲染后 html 结构,会在 build 时自动生成 }] } } diff --git a/docs/docusaurus.config.js b/docs/docusaurus.config.js index 04c99067ee..97a0237b47 100644 --- a/docs/docusaurus.config.js +++ b/docs/docusaurus.config.js @@ -74,6 +74,10 @@ const config = { }, // 语雀文档导出的图片,会进行 referrer 校验,这里设置关闭,不然加载不了语雀的图片 metadata: [{ name: 'referrer', content: 'no-referrer' }], + tableOfContents: { + minHeadingLevel: 2, + maxHeadingLevel: 5, + }, }), themes: [ diff --git a/docs/package.json b/docs/package.json index 93b2c43193..13a0c36c48 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.0.1", + "version": "1.0.2", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From e5011c3d167d8251edbc8f878a0329bb2a32b586 Mon Sep 17 00:00:00 2001 From: JackLian Date: Fri, 2 Dec 2022 17:19:14 +0800 Subject: [PATCH 216/823] docs: update cli related docs --- docs/docs/guide/create/useEditor.md | 38 ++++++++++++++-------------- docs/docs/guide/expand/editor/cli.md | 37 ++++++++++++++------------- 2 files changed, 39 insertions(+), 36 deletions(-) diff --git a/docs/docs/guide/create/useEditor.md b/docs/docs/guide/create/useEditor.md index 992827eb12..21de391080 100644 --- a/docs/docs/guide/create/useEditor.md +++ b/docs/docs/guide/create/useEditor.md @@ -8,34 +8,34 @@ sidebar_position: 0 1. clone 低代码项目的官方 demo,直接启动项目。适合普通人。 2. 手工引入低代码 UMD 包,手工配置、打包和启动。适合 Webpack 配置工程师。 -## 方法 1: 以官方 Demo 为基础使用 +## 方法 1:通过官方命令行工具创建编辑器 -可以通过两种方式之一获取低代码编辑器的示例代码: - -1. 直接[在 github 仓库下](https://github.com/alibaba/lowcode-demo)进行下载 - - ![](https://img.alicdn.com/imgextra/i3/O1CN01PfGV3h1oJ1Wv3sakc_!!6000000005203-2-tps-1500-517.png) - -2. 如果本地安装了 git,可以通过 git clone 方式进行下载 +1. 确保本地安装了 Node.js 和 npm,如果没有,[您可以通过 nvm 进行快捷的安装](https://github.com/nvm-sh/nvm) +2. 确保为 npm [设置了可以访问的 npm 源,保证安装过程无网络问题](https://npmmirror.com/) +3. 安装官方命令行工具 + ```bash + npm install -g @alilc/create-element@latest + ``` +4. 通过命令行工具创建 + ```bash + npm init @alilc/element editor-project-name + ``` + 这时会看到一个选项列表 -(这个方法的好处是 demo 有了更新,可以通过 merge 方式跟上) - ```bash - git clone https://github.com/alibaba/lowcode-demo.git - ``` + -拉取仓库代码后,需要进行如下配置或安装过程: + 选择`编辑器`,并填写对应的问题,即可完成创建。 -1. 确保本地安装了 Node.js 和 npm,如果没有,[您可以通过 nvm 进行快捷的安装](https://github.com/nvm-sh/nvm) -2. 确保为 npm [设置了可以访问的 npm 源,保证安装过程无网络问题](https://npmmirror.com/) -3. 选择目录下其中一个 demo 工程进入,建议选择 `demo-general` + > 注 @alilc/create-element 版本需 >= 1.0.4,若看不到`编辑器`选项,请重新执行步骤 3 +5. 进入创建后的目录 ```bash - cd demo-general + cd editor-project-name ``` -4. 安装依赖 +6. 安装依赖 ```bash npm install ``` -5. 安装依赖成功后,启动项目 (注意观察上一步的输出,如有 error 等失败信息,请先进行排查) +7. 安装依赖成功后,启动项目 (注意观察上一步的输出,如有 error 等失败信息,请先进行排查) ```bash npm start ``` diff --git a/docs/docs/guide/expand/editor/cli.md b/docs/docs/guide/expand/editor/cli.md index 390173adf1..aaadf09fe6 100644 --- a/docs/docs/guide/expand/editor/cli.md +++ b/docs/docs/guide/expand/editor/cli.md @@ -16,21 +16,24 @@ sidebar_position: 7 ## 脚手架功能 ### 脚手架初始化 -```shell -$ npm init @alilc/element your-element-name +```bash +npm init @alilc/element your-element-name ``` - 不写 your-element-name 的情况下,则在当前目录创建。 -> 觉得安装速度比较慢的同学,可以设置 npm 国内镜像,如 +> 注 1:如遇错误提示 `sh: create-element: command not found` 可先执行下述命令 +```bash +npm install -g @alilc/create-element +``` +> 注 2:觉得安装速度比较慢的同学,可以设置 npm 国内镜像,如 ```bash -$ npm init @alilc/element your-element-name --registry=https://registry.npmmirror.com +npm init @alilc/element your-element-name --registry=https://registry.npmmirror.com ``` 选择对应的元素类型,并填写对应的问题,即可完成创建。 -![image.png](https://img.alicdn.com/imgextra/i3/O1CN01SNaXUg1g4LurKuBHs_!!6000000004088-2-tps-688-148.png) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01LAaw2R1veHDYUzGB1_!!6000000006197-2-tps-676-142.png) ### 脚手架本地环境调试 @@ -43,7 +46,7 @@ npm start ### 脚手架构建 ```bash -$ npm run build +npm run build ``` ### 脚手架发布 @@ -51,19 +54,14 @@ $ npm run build 修改版本号后,执行如下指令即可: ```bash -$ npm publish +npm publish ``` -# 🔥🔥🔥 调试物料/插件/设置器 +## 🔥🔥🔥 调试物料/插件/设置器 > 📢📢📢 低代码生态脚手架提供的调试利器,在启动 setter/插件/物料 项目后,直接在已有的低代码平台就可以调试,不需要 npm link / 手改 npm main 入口等传统方式,轻松上手,强烈推荐使用!! - -注:若控制台出现如下错误,直接访问一次该 url 即可~ - -![image.png](https://img.alicdn.com/imgextra/i1/O1CN01cvKmeK1saCqpIxbLW_!!6000000005782-2-tps-1418-226.png) - -## 组件/插件/Setter 侧 +### 组件/插件/Setter 侧 1. 插件/setter 在原有 alt 的配置中添加相关的调试配置 ```json @@ -120,7 +118,7 @@ $ npm publish https://lowcode-engine.cn/demo/demo-general/index.html?debug ``` -## 项目侧的准备 +### 项目侧的准备 > 如果你的低代码项目 fork 自官方 demo,那么项目侧的准备已经就绪,不用再看以下内容~ @@ -175,7 +173,12 @@ $ npm publish } ``` -# Meta 信息 +注:若控制台出现如下错误,直接访问一次该 url 即可~ + +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01cvKmeK1saCqpIxbLW_!!6000000005782-2-tps-1418-226.png) + + +## Meta 信息 meta 信息是放在生态元素 package.json 中的一小段 json,用户可以通过 meta 了解到这个元素的一些基本信息,如元素类型,一些入口信息等。 ```typescript From 8e13f0cee18e6a7c8906efb0bc81132b1ad625ef Mon Sep 17 00:00:00 2001 From: JackLian Date: Fri, 2 Dec 2022 17:37:19 +0800 Subject: [PATCH 217/823] chore: set docs version to 1.0.3 --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 13a0c36c48..cb5c6df719 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.0.2", + "version": "1.0.3", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From e5a5c26de8c1ad97bac9047a0f2856447dcce8b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E7=86=A0?= Date: Sat, 3 Dec 2022 16:24:50 +0800 Subject: [PATCH 218/823] Update CODEOWNERS --- .github/CODEOWNERS | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bc889c3079..c2e49b783f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,13 +2,7 @@ # These owners will be the default owners for everything in # the repo. Unless a later match takes precedence -* @leoyuan @JackLian +* @liujuping @JackLian /modules/material-parser @akirakai -/modules/code-generator @Clarence-pan - -/packages/renderer-core/ @liujuping -/packages/react-renderer/ @liujuping -/packages/react-simulator-renderer/ @liujuping -/packages/rax-renderer/ @liujuping -/packages/rax-simulator-renderer/ @liujuping \ No newline at end of file +/modules/code-generator @leoyuan From 1f3c697a27d103f642d3b1c5bfeae26843e3112c Mon Sep 17 00:00:00 2001 From: JackLian Date: Sat, 3 Dec 2022 16:17:57 +0800 Subject: [PATCH 219/823] refactor: wrap cabins in order to mark deprecated apis --- packages/shell/src/common.tsx | 352 +++++++++++++++++++++++++--------- 1 file changed, 265 insertions(+), 87 deletions(-) diff --git a/packages/shell/src/common.tsx b/packages/shell/src/common.tsx index d6511edef4..dc25e46685 100644 --- a/packages/shell/src/common.tsx +++ b/packages/shell/src/common.tsx @@ -9,31 +9,31 @@ import { isNodeSchema as innerIsNodeSchema, NodeSchema, TransitionType, + TransformStage as InnerTransitionStage, } from '@alilc/lowcode-types'; import { - SettingField, - isSettingField, + SettingField as InnerSettingField, + isSettingField as innerIsSettingField, Designer, - TransformStage, - LiveEditing, - isDragNodeDataObject, - isDragNodeObject, - isDragAnyObject, - DragObjectType, - isNode, - isShaken, - contains, - LocationDetailType, - isLocationChildrenDetail, - ScrollTarget, + LiveEditing as InnerLiveEditing, + isDragNodeDataObject as innerIsDragNodeDataObject, + isDragNodeObject as innerIsDragNodeObject, + isDragAnyObject as innerIsDragAnyObject, + DragObjectType as InnerDragObjectType, + isNode as innerIsNode, + isShaken as innerIsShaken, + contains as innerContains, + LocationDetailType as InnerLocationDetailType, + isLocationChildrenDetail as innerIsLocationChildrenDetail, + ScrollTarget as InnerScrollTarget, getConvertedExtraKey as innerGetConvertedExtraKey, getOriginalExtraKey as innerGetOriginalExtraKey, } from '@alilc/lowcode-designer'; import { Skeleton as InnerSkeleton, - createSettingFieldView, - PopupContext, - PopupPipe, + createSettingFieldView as innerCreateSettingFieldView, + PopupContext as InnerPopupContext, + PopupPipe as InnerPopupPipe, Workbench as InnerWorkbench, } from '@alilc/lowcode-editor-skeleton'; import Dragon from './dragon'; @@ -41,60 +41,145 @@ import { Editor, Title as InnerTitle, Tip as InnerTip, - shallowIntl, + shallowIntl as innerShallowIntl, createIntl as innerCreateIntl, - intl, - createSetterContent, - obx, - observable, - makeObservable, - untracked, - computed, - observer, - globalLocale, + intl as innerIntl, + createSetterContent as innerCreateSetterContent, + globalLocale as innerGlobalLocale, + obx as innerObx, + observable as innerObservable, + makeObservable as innerMakeObservable, + untracked as innerUntracked, + computed as innerComputed, + observer as innerObserver, } from '@alilc/lowcode-editor-core'; import { ReactNode } from 'react'; -const getDesignerCabin = (editor: Editor) => { - const designer = editor.get('designer') as Designer; - - return { - SettingField, - isSettingField, - dragon: Dragon.create(designer.dragon), - TransformStage, - LiveEditing, - DragObjectType, - isDragNodeDataObject, - isNode, - [designerCabinSymbol]: { - isDragNodeObject, - isDragAnyObject, - isShaken, - contains, - LocationDetailType, - isLocationChildrenDetail, - ScrollTarget, - isSettingField, - TransformStage, - SettingField, - LiveEditing, - DragObjectType, - isDragNodeDataObject, - isNode, - }, - }; -}; - -const getSkeletonCabin = (skeleton: InnerSkeleton) => { - return { - createSettingFieldView, - PopupContext, - PopupPipe, - Workbench: (props: any) => , // hijack skeleton - }; -}; +class DesignerCabin { + private readonly [editorSymbol]: Editor; + /** + * @deprecated + */ + readonly [designerCabinSymbol]: any; + + constructor(editor: Editor) { + this[editorSymbol] = editor; + this[designerCabinSymbol] = { + isDragNodeObject: innerIsDragNodeObject, + isDragAnyObject: innerIsDragAnyObject, + isShaken: innerIsShaken, + contains: innerContains, + LocationDetailType: InnerLocationDetailType, + isLocationChildrenDetail: innerIsLocationChildrenDetail, + ScrollTarget: InnerScrollTarget, + isSettingField: innerIsSettingField, + TransformStage: InnerTransitionStage, + SettingField: InnerSettingField, + LiveEditing: InnerLiveEditing, + DragObjectType: InnerDragObjectType, + isDragNodeDataObject: innerIsDragNodeDataObject, + isNode: innerIsNode, + }; + } + + /** + * 是否是 SettingField 实例 + * + * @param {*} obj + * @returns {obj is SettingField} + * @memberof DesignerCabin + */ + isSettingField(obj: any): obj is InnerSettingField { + return innerIsSettingField(obj); + } + + /** + * 转换类型枚举对象,包含 init / upgrade / render 等类型 + * [参考](https://github.com/alibaba/lowcode-engine/blob/main/packages/types/src/transform-stage.ts) + * @deprecated use { TransformStage } from '@alilc/lowcode-types' instead + */ + get TransformStage() { + return InnerTransitionStage; + } + + /** + * @deprecated + */ + get SettingField() { + return InnerSettingField; + } + + /** + * @deprecated + */ + get dragon() { + const designer = this[editorSymbol].get('designer') as Designer; + return Dragon.create(designer.dragon); + } + + /** + * @deprecated + */ + get LiveEditing() { + return InnerLiveEditing; + } + + /** + * @deprecated + */ + get DragObjectType() { + return InnerDragObjectType; + } + + /** + * @deprecated + */ + isDragNodeDataObject(obj: any): boolean { + return innerIsDragNodeDataObject(obj); + } + + /** + * @deprecated + */ + isNode(node: any): boolean { + return innerIsNode(node); + } +} + +class SkeletonCabin { + private readonly [skeletonSymbol]: InnerSkeleton; + + constructor(skeleton: InnerSkeleton) { + this[skeletonSymbol] = skeleton; + } + + get Workbench(): any { + const innerSkeleton = this[skeletonSymbol]; + return (props: any) => ; + } + + /** + * @deprecated + */ + createSettingFieldView(item: any, field: any) { + return innerCreateSettingFieldView(item, field); + } + + /** + * @deprecated + */ + get PopupContext(): any { + return InnerPopupContext; + } + + /** + * @deprecated + */ + get PopupPipe(): any { + return InnerPopupPipe; + } +} class Utils { isNodeSchema(data: any): data is NodeSchema { @@ -135,19 +220,110 @@ class Utils { } } +class EditorCabin { + /** + * @deprecated + */ + get Title() { + return InnerTitle; + } + + /** + * @deprecated + */ + get Tip() { + return InnerTip; + } + + /** + * @deprecated + */ + shallowIntl(data: any): any { + return innerShallowIntl(data); + } + + /** + * @deprecated use common.utils.createIntl instead + */ + createIntl(instance: any): any { + return innerCreateIntl(instance); + } + + /** + * @deprecated + */ + intl(data: any, params?: object): any { + return innerIntl(data, params); + } + + /** + * @deprecated + */ + createSetterContent(setter: any, props: Record): ReactNode { + return innerCreateSetterContent(setter, props); + } + + /** + * @deprecated + */ + get globalLocale() { + return innerGlobalLocale; + } + + /** + * @deprecated + */ + get obx() { + return innerObx; + } + + /** + * @deprecated + */ + get observable() { + return innerObservable; + } + + /** + * @deprecated + */ + makeObservable(target: any, annotations: any, options: any) { + return innerMakeObservable(target, annotations, options); + } + + /** + * @deprecated + */ + untracked(action: any) { + return innerUntracked(action); + } + + /** + * @deprecated + */ + get computed() { + return innerComputed; + } + + /** + * @deprecated + */ + observer(component: any) { + return innerObserver(component); + } +} + + export default class Common { - private readonly [editorSymbol]: Editor; - private readonly [skeletonSymbol]: InnerSkeleton; private readonly __designerCabin: any; private readonly __skeletonCabin: any; private readonly __editorCabin: any; private readonly __utils: Utils; constructor(editor: Editor, skeleton: InnerSkeleton) { - this[editorSymbol] = editor; - this[skeletonSymbol] = skeleton; - this.__designerCabin = getDesignerCabin(this[editorSymbol]); - this.__skeletonCabin = getSkeletonCabin(this[skeletonSymbol]); + this.__designerCabin = new DesignerCabin(editor); + this.__skeletonCabin = new SkeletonCabin(skeleton); + this.__editorCabin = new EditorCabin(); this.__utils = new Utils(); } @@ -155,22 +331,13 @@ export default class Common { return this.__utils; } + /** + * 历史原因导致此处设计不合理,慎用。 + * this load of crap will be removed in some future versions, don`t use it. + * @deprecated + */ get editorCabin(): any { - return { - Title: InnerTitle, - Tip: InnerTip, - shallowIntl, - createIntl: innerCreateIntl, - intl, - createSetterContent, - obx, - observable, - makeObservable, - untracked, - computed, - observer, - globalLocale, - }; + return this.__editorCabin; } get designerCabin(): any { @@ -180,4 +347,15 @@ export default class Common { get skeletonCabin(): any { return this.__skeletonCabin; } + + /** + * 历史原因导致此处设计不合理,慎用。 + * this load of crap will be removed in some future versions, don`t use it. + * @deprecated use { TransformStage } from '@alilc/lowcode-types' instead + */ + get objects(): any { + return { + TransformStage: InnerTransitionStage, + }; + } } \ No newline at end of file From da010eef42050639970e6da06e7b629620187549 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E7=86=A0?= Date: Sat, 3 Dec 2022 16:24:50 +0800 Subject: [PATCH 220/823] Update CODEOWNERS --- .github/CODEOWNERS | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bc889c3079..c2e49b783f 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,13 +2,7 @@ # These owners will be the default owners for everything in # the repo. Unless a later match takes precedence -* @leoyuan @JackLian +* @liujuping @JackLian /modules/material-parser @akirakai -/modules/code-generator @Clarence-pan - -/packages/renderer-core/ @liujuping -/packages/react-renderer/ @liujuping -/packages/react-simulator-renderer/ @liujuping -/packages/rax-renderer/ @liujuping -/packages/rax-simulator-renderer/ @liujuping \ No newline at end of file +/modules/code-generator @leoyuan From 20c8419f220776c2647da4ff86bba721e65ca389 Mon Sep 17 00:00:00 2001 From: JackLian Date: Mon, 5 Dec 2022 11:47:04 +0800 Subject: [PATCH 221/823] feat: feat: remove circular dependency between designer and shell --- docs/docs/api/plugins.md | 19 ++++---- docs/docs/participate/flow.md | 1 + packages/designer/jest.config.js | 1 + .../designer/src/plugin/plugin-context.ts | 44 ++++++++----------- .../designer/src/plugin/plugin-manager.ts | 13 +++--- packages/designer/src/plugin/plugin-types.ts | 31 +++++++++---- .../tests/plugin/plugin-manager.test.ts | 9 +++- packages/engine/src/engine-core.ts | 22 ++++++++-- 8 files changed, 86 insertions(+), 54 deletions(-) diff --git a/docs/docs/api/plugins.md b/docs/docs/api/plugins.md index 8762dbacd6..f225386fc2 100644 --- a/docs/docs/api/plugins.md +++ b/docs/docs/api/plugins.md @@ -223,15 +223,16 @@ plugins.delete('builtinPluginRegistry'); **类型定义** ```typescript export interface ILowCodePluginContext { - skeleton: Skeleton; // 参考面板 API - hotkey: Hotkey; // 参考快捷键 API - logger: Logger; // 参考日志 API - plugins: ILowCodePluginManager; // 参考插件 API - setters: Setters; // 参考设置器 API - config: EngineConfig; // 参考配置 API - material: Material; // 参考物料 API - event: Event; // 参考事件 API - project: Project; // 参考模型 API + 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; } ``` diff --git a/docs/docs/participate/flow.md b/docs/docs/participate/flow.md index e346f7711b..e9675a387d 100644 --- a/docs/docs/participate/flow.md +++ b/docs/docs/participate/flow.md @@ -91,6 +91,7 @@ sidebar_position: 2 2. 拉 release 分支,此处以 1.0.1 版本做示例 ```bash git checkout -b release/1.0.1-beta + git push --set-upstream origin release/1.0.1-beta ``` 3. build ```bash diff --git a/packages/designer/jest.config.js b/packages/designer/jest.config.js index 70a1da03de..f77cf4c9f7 100644 --- a/packages/designer/jest.config.js +++ b/packages/designer/jest.config.js @@ -10,6 +10,7 @@ const jestConfig = { // // '^.+\\.(js|jsx)$': 'babel-jest', // }, // testMatch: ['**/node-children.test.ts'], + // testMatch: ['**/plugin-manager.test.ts'], // testMatch: ['**/history/history.test.ts'], // testMatch: ['**/host-view.test.tsx'], // testMatch: ['(/tests?/.*(test))\\.[jt]s$'], diff --git a/packages/designer/src/plugin/plugin-context.ts b/packages/designer/src/plugin/plugin-context.ts index becae741fe..24c7065604 100644 --- a/packages/designer/src/plugin/plugin-context.ts +++ b/packages/designer/src/plugin/plugin-context.ts @@ -1,7 +1,6 @@ /* eslint-disable no-multi-assign */ -import { Editor, EngineConfig, engineConfig } from '@alilc/lowcode-editor-core'; -import { Designer, ILowCodePluginManager } from '@alilc/lowcode-designer'; -import { Skeleton as InnerSkeleton } from '@alilc/lowcode-editor-skeleton'; +import { EngineConfig, engineConfig } from '@alilc/lowcode-editor-core'; +import { ILowCodePluginManager } from '@alilc/lowcode-designer'; import { Hotkey, Project, @@ -9,9 +8,7 @@ import { Setters, Material, Event, - editorSymbol, - designerSymbol, - skeletonSymbol, + Common, } from '@alilc/lowcode-shell'; import { getLogger, Logger } from '@alilc/lowcode-utils'; import { @@ -20,45 +17,40 @@ import { ILowCodePluginPreferenceDeclaration, PreferenceValueType, IPluginPreferenceMananger, + ILowCodePluginContextApiAssembler, + ILowCodePluginContextPrivate, } from './plugin-types'; import { isValidPreferenceKey } from './plugin-utils'; -export default class PluginContext implements ILowCodePluginContext { - private readonly [editorSymbol]: Editor; - private readonly [designerSymbol]: Designer; - private readonly [skeletonSymbol]: InnerSkeleton; + +export default class PluginContext implements ILowCodePluginContext, ILowCodePluginContextPrivate { hotkey: Hotkey; project: Project; skeleton: Skeleton; - logger: Logger; setters: Setters; material: Material; - config: EngineConfig; event: Event; + config: EngineConfig; + common: Common; + logger: Logger; plugins: ILowCodePluginManager; preference: IPluginPreferenceMananger; - constructor(plugins: ILowCodePluginManager, options: IPluginContextOptions) { - const editor = this[editorSymbol] = plugins.editor; - const designer = this[designerSymbol] = editor.get('designer')!; - const skeleton = this[skeletonSymbol] = editor.get('skeleton')!; - - const { pluginName = 'anonymous' } = options; - const project = designer?.project; - this.hotkey = new Hotkey(); - this.project = new Project(project); - this.skeleton = new Skeleton(skeleton); - this.setters = new Setters(); - this.material = new Material(editor); - this.config = engineConfig; + constructor( + plugins: ILowCodePluginManager, + options: IPluginContextOptions, + contextApiAssembler: ILowCodePluginContextApiAssembler, + ) { this.plugins = plugins; - this.event = new Event(editor, { prefix: 'common' }); + const { pluginName = 'anonymous' } = options; this.logger = getLogger({ level: 'warn', bizName: `designer:plugin:${pluginName}` }); const enhancePluginContextHook = engineConfig.get('enhancePluginContextHook'); if (enhancePluginContextHook) { enhancePluginContextHook(this); } + + contextApiAssembler.assembleApis(this); } setPreference( diff --git a/packages/designer/src/plugin/plugin-manager.ts b/packages/designer/src/plugin/plugin-manager.ts index dc803ddfec..13c7ea967d 100644 --- a/packages/designer/src/plugin/plugin-manager.ts +++ b/packages/designer/src/plugin/plugin-manager.ts @@ -1,4 +1,4 @@ -import { Editor, engineConfig } from '@alilc/lowcode-editor-core'; +import { engineConfig } from '@alilc/lowcode-editor-core'; import { getLogger } from '@alilc/lowcode-utils'; import { ILowCodePlugin, @@ -12,9 +12,11 @@ import { PluginPreference, ILowCodePluginPreferenceDeclaration, isLowCodeRegisterOptions, + ILowCodePluginContextApiAssembler, } from './plugin-types'; import { filterValidOptions } from './plugin-utils'; import { LowCodePlugin } from './plugin'; +// eslint-disable-next-line import/no-named-as-default import LowCodePluginContext from './plugin-context'; import { invariant } from '../utils'; import sequencify from './sequencify'; @@ -28,14 +30,15 @@ export class LowCodePluginManager implements ILowCodePluginManager { private pluginsMap: Map = new Map(); private pluginPreference?: PluginPreference = new Map(); - private editor: Editor; - constructor(editor: Editor) { - this.editor = editor; + contextApiAssembler: ILowCodePluginContextApiAssembler; + + constructor(contextApiAssembler: ILowCodePluginContextApiAssembler) { + this.contextApiAssembler = contextApiAssembler; } private _getLowCodePluginContext(options: IPluginContextOptions) { - return new LowCodePluginContext(this, options); + return new LowCodePluginContext(this, options, this.contextApiAssembler); } isEngineVersionMatched(versionExp: string): boolean { diff --git a/packages/designer/src/plugin/plugin-types.ts b/packages/designer/src/plugin/plugin-types.ts index f9a1ea1ddf..732803542c 100644 --- a/packages/designer/src/plugin/plugin-types.ts +++ b/packages/designer/src/plugin/plugin-types.ts @@ -1,6 +1,6 @@ import { CompositeObject, ComponentAction } from '@alilc/lowcode-types'; import Logger from 'zen-logger'; -import { Hotkey, Skeleton, Project, Event, Material } from '@alilc/lowcode-shell'; +import { Hotkey, Skeleton, Project, Event, Material, Common } from '@alilc/lowcode-shell'; import { EngineConfig } from '@alilc/lowcode-editor-core'; import { MetadataTransducer } from '@alilc/lowcode-designer'; import { Setters } from '../types'; @@ -96,17 +96,32 @@ export interface IPluginPreferenceMananger { } export interface ILowCodePluginContext { - skeleton: Skeleton; - hotkey: Hotkey; + get skeleton(): Skeleton; + get hotkey(): Hotkey; + get setters(): Setters; + get config(): EngineConfig; + get material(): Material; + get event(): Event; + get project(): Project; + get common(): Common; logger: Logger; plugins: ILowCodePluginManager; - setters: Setters; - config: EngineConfig; - material: Material; - event: Event; - project: Project; preference: IPluginPreferenceMananger; } +export interface ILowCodePluginContextPrivate { + set hotkey(hotkey: Hotkey); + set project(project: Project); + set skeleton(skeleton: Skeleton); + set setters(setters: Setters); + set material(material: Material); + set event(event: Event); + set config(config: EngineConfig); + set common(common: Common); +} +export interface ILowCodePluginContextApiAssembler { + assembleApis: (context: ILowCodePluginContextPrivate) => void; +} + interface ILowCodePluginManagerPluginAccessor { [pluginName: string]: ILowCodePlugin | any; diff --git a/packages/designer/tests/plugin/plugin-manager.test.ts b/packages/designer/tests/plugin/plugin-manager.test.ts index b0c40070a3..02bc696a80 100644 --- a/packages/designer/tests/plugin/plugin-manager.test.ts +++ b/packages/designer/tests/plugin/plugin-manager.test.ts @@ -1,14 +1,19 @@ import '../fixtures/window'; import { Editor, engineConfig } from '@alilc/lowcode-editor-core'; import { LowCodePluginManager } from '../../src/plugin/plugin-manager'; -import { ILowCodePluginContext, ILowCodePluginManager } from '../../src/plugin/plugin-types'; +import { ILowCodePluginContext, ILowCodePluginManager, ILowCodePluginContextApiAssembler } from '../../src/plugin/plugin-types'; const editor = new Editor(); +const contextApiAssembler = { + assembleApis(){ + // mock set apis + } +}; describe('plugin 测试', () => { let pluginManager: ILowCodePluginManager; beforeEach(() => { - pluginManager = new LowCodePluginManager(editor).toProxy(); + pluginManager = new LowCodePluginManager(contextApiAssembler).toProxy(); }); afterEach(() => { pluginManager.dispose(); diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index 7045816e50..9b3c393280 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -1,3 +1,4 @@ +/* eslint-disable no-param-reassign */ import { createElement } from 'react'; import { render, unmountComponentAtNode } from 'react-dom'; import { globalContext, Editor, engineConfig, EngineOptions } from '@alilc/lowcode-editor-core'; @@ -5,6 +6,8 @@ import { Designer, LowCodePluginManager, ILowCodePluginContext, + ILowCodePluginContextPrivate, + ILowCodePluginContextApiAssembler, PluginPreference, } from '@alilc/lowcode-designer'; import { @@ -46,10 +49,6 @@ editor.set('skeleton' as any, innerSkeleton); const designer = new Designer({ editor }); editor.set('designer' as any, designer); - -const plugins = new LowCodePluginManager(editor).toProxy(); -editor.set('plugins' as any, plugins); - const { project: innerProject } = designer; const hotkey = new Hotkey(); @@ -62,6 +61,21 @@ const event = new Event(editor, { prefix: 'common' }); const logger = getLogger({ level: 'warn', bizName: 'common' }); const common = new Common(editor, innerSkeleton); +const pluginContextApiAssembler: ILowCodePluginContextApiAssembler = { + assembleApis: (context: ILowCodePluginContextPrivate) => { + context.hotkey = hotkey; + context.project = project; + context.skeleton = skeleton; + context.setters = setters; + context.material = material; + context.event = event; + context.config = config; + context.common = common; + }, +}; +const plugins = new LowCodePluginManager(pluginContextApiAssembler).toProxy(); +editor.set('plugins' as any, plugins); + export { skeleton, plugins, From 0fbf4cda4cbc1367b888976f6ea46ae57fb5cd3c Mon Sep 17 00:00:00 2001 From: eternalsky Date: Mon, 5 Dec 2022 20:06:58 +0800 Subject: [PATCH 222/823] docs: add view.tsx guide in material.md --- docs/docs/guide/expand/editor/cli.md | 2 +- docs/docs/guide/expand/editor/material.md | 9 ++++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/docs/docs/guide/expand/editor/cli.md b/docs/docs/guide/expand/editor/cli.md index aaadf09fe6..0218e6f73d 100644 --- a/docs/docs/guide/expand/editor/cli.md +++ b/docs/docs/guide/expand/editor/cli.md @@ -57,7 +57,7 @@ npm run build npm publish ``` -## 🔥🔥🔥 调试物料/插件/设置器 +## 🔥🔥🔥 在低代码项目中调试物料/插件/设置器 > 📢📢📢 低代码生态脚手架提供的调试利器,在启动 setter/插件/物料 项目后,直接在已有的低代码平台就可以调试,不需要 npm link / 手改 npm main 入口等传统方式,轻松上手,强烈推荐使用!! diff --git a/docs/docs/guide/expand/editor/material.md b/docs/docs/guide/expand/editor/material.md index fa51730fc6..a5e374db91 100644 --- a/docs/docs/guide/expand/editor/material.md +++ b/docs/docs/guide/expand/editor/material.md @@ -182,7 +182,14 @@ npm run lowcode:build display: 'accordion' | 'inline' | 'block' | 'plain' | 'popup' | 'entry', // 常用的是 inline(默认), block、entry } ``` -发布组件 +#### 编辑态视图 +用户可以在 lowcode/ 目录下新增 view.tsx 来增加编辑态视图。编辑态视图用于在编辑态时展示与真实预览不一样的视图。 +view.tsx 输出的也是一个 React 组件。 + +注意:如果是单组件,而非组件库模式的话,view.tsx 应置于 lowcode 而非 lowcode/ 目录下 + + +#### 发布组件 ```bash # 在组件根目录下,执行 $ npm publish From aed94f1532692c040ac5048deb05ca8d55e3a1c9 Mon Sep 17 00:00:00 2001 From: JackLian Date: Mon, 5 Dec 2022 20:15:33 +0800 Subject: [PATCH 223/823] chore: doc version 1.0.4 --- docs/{community => docs/participate}/code-specification.md | 3 ++- docs/package.json | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) rename docs/{community => docs/participate}/code-specification.md (93%) diff --git a/docs/community/code-specification.md b/docs/docs/participate/code-specification.md similarity index 93% rename from docs/community/code-specification.md rename to docs/docs/participate/code-specification.md index f4378ee2cc..d6b387e305 100644 --- a/docs/community/code-specification.md +++ b/docs/docs/participate/code-specification.md @@ -1,5 +1,6 @@ --- title: 编码规约 +sidebar_position: 5 --- 编码规约 @@ -26,7 +27,7 @@ title: 编码规约 - 不要在全局命名空间内定义类型/值 - 共享的类型应该在 `types.ts` 里定义 - 在一个文件里,类型定义应该出现在顶部 - - interface 和 type 很类似,原则上能用 interface 实现,就用 interface , 如果不能才用 type + - interface 和 type 很类似,原则上能用 interface 实现,就用 interface , 如果不能才用 type ### 注释 diff --git a/docs/package.json b/docs/package.json index cb5c6df719..ef145d3c60 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.0.3", + "version": "1.0.4", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 55c3fc9e58d566edeabd1daa489ac83ba6b787d1 Mon Sep 17 00:00:00 2001 From: JackLian Date: Tue, 6 Dec 2022 10:09:25 +0800 Subject: [PATCH 224/823] feat: add types for shell, and move functions in types to utils --- docs/docs/api/project.md | 2 +- .../src/plugins/component/rax/jsx.ts | 2 +- .../bem-tools/border-container.tsx | 3 +- .../bem-tools/border-selecting.tsx | 6 +- .../designer/src/builtin-simulator/host.ts | 4 +- packages/designer/src/component-meta.ts | 26 +- packages/designer/src/designer/designer.ts | 19 +- packages/designer/src/designer/dragon.ts | 27 +- .../src/designer/setting/setting-field.ts | 5 +- .../designer/setting/setting-prop-entry.ts | 5 +- .../src/designer/setting/setting-top-entry.ts | 3 +- .../designer/src/designer/setting/utils.ts | 3 +- .../designer/src/document/document-model.ts | 6 +- .../src/document/node/node-children.ts | 10 +- packages/designer/src/document/node/node.ts | 6 +- .../designer/src/document/node/props/prop.ts | 4 +- packages/designer/src/plugin/plugin-types.ts | 3 +- packages/designer/src/project/project.ts | 3 +- packages/designer/src/types/index.ts | 22 +- .../tests/bugs/prop-variable-jse.test.ts | 4 +- .../tests/builtin-simulator/host.test.ts | 18 +- .../designer/tests/designer/designer.test.ts | 3 +- .../designer/tests/designer/dragon.test.ts | 2 +- .../designer/tests/designer/scroller.test.ts | 22 -- packages/editor-core/src/di/setter.ts | 21 +- packages/editor-core/src/hotkey.ts | 3 +- packages/editor-core/src/intl/index.ts | 2 +- .../editor-core/src/widgets/title/index.tsx | 4 +- .../src/components/settings/settings-pane.tsx | 5 +- .../src/components/stage-box/stage.tsx | 2 +- packages/editor-skeleton/src/skeleton.ts | 9 +- .../src/transducers/parse-func.ts | 8 +- packages/editor-skeleton/src/types.ts | 37 +- packages/editor-skeleton/src/widget/utils.ts | 3 +- packages/engine/src/engine-core.ts | 1 - packages/engine/src/modules/designer-types.ts | 5 +- packages/engine/src/modules/editor-types.ts | 3 - packages/engine/src/modules/live-editing.ts | 5 +- packages/plugin-outline-pane/src/tree-node.ts | 3 +- .../plugin-outline-pane/src/views/tree.tsx | 3 +- .../rax-simulator-renderer/src/renderer.ts | 4 +- packages/renderer-core/src/renderer/base.tsx | 5 +- packages/renderer-core/src/utils/common.ts | 3 +- .../renderer-core/src/utils/data-helper.ts | 2 +- .../renderer-core/src/utils/is-use-loop.ts | 3 +- packages/shell/src/canvas.ts | 9 +- packages/shell/src/common.tsx | 16 +- packages/shell/src/component-meta.ts | 38 ++- packages/shell/src/detecting.ts | 3 +- packages/shell/src/document-model.ts | 131 ++++---- packages/shell/src/drag-object.ts | 20 +- packages/shell/src/dragon.ts | 27 +- packages/shell/src/drop-location.ts | 9 +- packages/shell/src/event.ts | 5 +- packages/shell/src/history.ts | 21 +- packages/shell/src/hotkey.ts | 6 +- packages/shell/src/locate-event.ts | 25 +- packages/shell/src/material.ts | 20 +- packages/shell/src/modal-nodes-manager.ts | 24 +- packages/shell/src/node-children.ts | 64 ++-- packages/shell/src/node.ts | 164 +++++---- packages/shell/src/project.ts | 41 ++- packages/shell/src/prop.ts | 30 +- packages/shell/src/props.ts | 32 +- packages/shell/src/selection.ts | 28 +- packages/shell/src/setters.ts | 12 +- packages/shell/src/setting-prop-entry.ts | 84 +++-- packages/shell/src/setting-top-entry.ts | 13 +- packages/shell/src/simulator-host.ts | 21 +- packages/shell/src/skeleton.ts | 13 +- packages/types/src/deprecated/index.ts | 18 + .../src/deprecated/isActionContentObject.ts | 8 + packages/types/src/deprecated/isCustomView.ts | 10 + packages/types/src/deprecated/isDOMText.ts | 8 + .../types/src/deprecated/isDynamicSetter.ts | 9 + packages/types/src/deprecated/isI18nData.ts | 8 + packages/types/src/deprecated/isJSBlock.ts | 8 + .../types/src/deprecated/isJSExpression.ts | 8 + packages/types/src/deprecated/isJSFunction.ts | 8 + packages/types/src/deprecated/isJSSlot.ts | 8 + .../src/deprecated/isLowCodeComponentType.ts | 9 + packages/types/src/deprecated/isNodeSchema.ts | 8 + .../types/src/deprecated/isPlainObject.ts | 10 + .../src/deprecated/isProCodeComponentType.ts | 8 + .../types/src/deprecated/isProjectSchema.ts | 8 + packages/types/src/deprecated/isReactClass.ts | 8 + .../types/src/deprecated/isReactComponent.ts | 9 + .../types/src/deprecated/isSetterConfig.ts | 9 + .../types/src/deprecated/isTitleConfig.ts | 10 + packages/types/src/designer.ts | 23 ++ packages/types/src/dragon.ts | 29 ++ packages/types/src/editor-skeleton.ts | 27 ++ packages/types/src/editor.ts | 21 ++ packages/types/src/i18n.ts | 5 - packages/types/src/index.ts | 7 + packages/types/src/metadata.ts | 18 +- packages/types/src/npm.ts | 10 +- packages/types/src/props-transducer.ts | 12 + packages/types/src/schema.ts | 15 +- packages/types/src/setter-config.ts | 27 +- packages/types/src/shell/api/common.ts | 50 +++ packages/types/src/shell/api/event.ts | 26 ++ packages/types/src/shell/api/hotkey.ts | 16 + packages/types/src/shell/api/index.ts | 8 + packages/types/src/shell/api/material.ts | 90 +++++ packages/types/src/shell/api/project.ts | 115 +++++++ packages/types/src/shell/api/setters.ts | 31 ++ .../types/src/shell/api/simulator-host.ts | 41 +++ packages/types/src/shell/api/skeleton.ts | 95 ++++++ packages/types/src/shell/index.ts | 13 + packages/types/src/shell/model/canvas.ts | 4 + .../types/src/shell/model/component-meta.ts | 85 +++++ packages/types/src/shell/model/detecting.ts | 23 ++ .../types/src/shell/model/document-model.ts | 155 +++++++++ packages/types/src/shell/model/drag-object.ts | 8 + packages/types/src/shell/model/dragon.ts | 39 +++ .../types/src/shell/model/drop-location.ts | 3 + packages/types/src/shell/model/history.ts | 49 +++ packages/types/src/shell/model/index.ts | 17 + .../types/src/shell/model/locate-event.ts | 20 ++ .../src/shell/model/modal-nodes-manager.ts | 37 ++ .../types/src/shell/model/node-children.ts | 128 +++++++ packages/types/src/shell/model/node.ts | 316 ++++++++++++++++++ packages/types/src/shell/model/prop.ts | 59 ++++ packages/types/src/shell/model/props.ts | 82 +++++ packages/types/src/shell/model/selection.ts | 65 ++++ .../src/shell/model/setting-prop-entry.ts | 188 +++++++++++ .../src/shell/model/setting-top-entry.ts | 30 ++ packages/types/src/title.ts | 16 +- packages/types/src/value-type.ts | 28 +- packages/utils/src/check-types/index.ts | 16 + .../check-types/is-action-content-object.ts | 6 + .../utils/src/check-types/is-custom-view.ts | 8 + packages/utils/src/check-types/is-dom-text.ts | 5 + .../src/check-types/is-dynamic-setter.ts | 7 + .../utils/src/check-types/is-i18n-data.ts | 7 + .../utils/src/check-types/is-isfunction.ts | 5 + packages/utils/src/check-types/is-jsblock.ts | 5 + .../utils/src/check-types/is-jsexpression.ts | 15 + packages/utils/src/check-types/is-jsslot.ts | 5 + .../check-types/is-lowcode-component-type.ts | 7 + .../utils/src/check-types/is-node-schema.ts | 5 + .../check-types/is-procode-component-type.ts | 6 + .../src/check-types/is-project-schema.ts | 5 + .../utils/src/check-types/is-setter-config.ts | 7 + .../utils/src/check-types/is-title-config.ts | 8 + packages/utils/src/index.ts | 1 + packages/utils/src/schema.ts | 3 +- 148 files changed, 2808 insertions(+), 711 deletions(-) delete mode 100644 packages/engine/src/modules/editor-types.ts create mode 100644 packages/types/src/deprecated/index.ts create mode 100644 packages/types/src/deprecated/isActionContentObject.ts create mode 100644 packages/types/src/deprecated/isCustomView.ts create mode 100644 packages/types/src/deprecated/isDOMText.ts create mode 100644 packages/types/src/deprecated/isDynamicSetter.ts create mode 100644 packages/types/src/deprecated/isI18nData.ts create mode 100644 packages/types/src/deprecated/isJSBlock.ts create mode 100644 packages/types/src/deprecated/isJSExpression.ts create mode 100644 packages/types/src/deprecated/isJSFunction.ts create mode 100644 packages/types/src/deprecated/isJSSlot.ts create mode 100644 packages/types/src/deprecated/isLowCodeComponentType.ts create mode 100644 packages/types/src/deprecated/isNodeSchema.ts create mode 100644 packages/types/src/deprecated/isPlainObject.ts create mode 100644 packages/types/src/deprecated/isProCodeComponentType.ts create mode 100644 packages/types/src/deprecated/isProjectSchema.ts create mode 100644 packages/types/src/deprecated/isReactClass.ts create mode 100644 packages/types/src/deprecated/isReactComponent.ts create mode 100644 packages/types/src/deprecated/isSetterConfig.ts create mode 100644 packages/types/src/deprecated/isTitleConfig.ts create mode 100644 packages/types/src/designer.ts create mode 100644 packages/types/src/dragon.ts create mode 100644 packages/types/src/editor-skeleton.ts create mode 100644 packages/types/src/props-transducer.ts create mode 100644 packages/types/src/shell/api/common.ts create mode 100644 packages/types/src/shell/api/event.ts create mode 100644 packages/types/src/shell/api/hotkey.ts create mode 100644 packages/types/src/shell/api/index.ts create mode 100644 packages/types/src/shell/api/material.ts create mode 100644 packages/types/src/shell/api/project.ts create mode 100644 packages/types/src/shell/api/setters.ts create mode 100644 packages/types/src/shell/api/simulator-host.ts create mode 100644 packages/types/src/shell/api/skeleton.ts create mode 100644 packages/types/src/shell/index.ts create mode 100644 packages/types/src/shell/model/canvas.ts create mode 100644 packages/types/src/shell/model/component-meta.ts create mode 100644 packages/types/src/shell/model/detecting.ts create mode 100644 packages/types/src/shell/model/document-model.ts create mode 100644 packages/types/src/shell/model/drag-object.ts create mode 100644 packages/types/src/shell/model/dragon.ts create mode 100644 packages/types/src/shell/model/drop-location.ts create mode 100644 packages/types/src/shell/model/history.ts create mode 100644 packages/types/src/shell/model/index.ts create mode 100644 packages/types/src/shell/model/locate-event.ts create mode 100644 packages/types/src/shell/model/modal-nodes-manager.ts create mode 100644 packages/types/src/shell/model/node-children.ts create mode 100644 packages/types/src/shell/model/node.ts create mode 100644 packages/types/src/shell/model/prop.ts create mode 100644 packages/types/src/shell/model/props.ts create mode 100644 packages/types/src/shell/model/selection.ts create mode 100644 packages/types/src/shell/model/setting-prop-entry.ts create mode 100644 packages/types/src/shell/model/setting-top-entry.ts create mode 100644 packages/utils/src/check-types/index.ts create mode 100644 packages/utils/src/check-types/is-action-content-object.ts create mode 100644 packages/utils/src/check-types/is-custom-view.ts create mode 100644 packages/utils/src/check-types/is-dom-text.ts create mode 100644 packages/utils/src/check-types/is-dynamic-setter.ts create mode 100644 packages/utils/src/check-types/is-i18n-data.ts create mode 100644 packages/utils/src/check-types/is-isfunction.ts create mode 100644 packages/utils/src/check-types/is-jsblock.ts create mode 100644 packages/utils/src/check-types/is-jsexpression.ts create mode 100644 packages/utils/src/check-types/is-jsslot.ts create mode 100644 packages/utils/src/check-types/is-lowcode-component-type.ts create mode 100644 packages/utils/src/check-types/is-node-schema.ts create mode 100644 packages/utils/src/check-types/is-procode-component-type.ts create mode 100644 packages/utils/src/check-types/is-project-schema.ts create mode 100644 packages/utils/src/check-types/is-setter-config.ts create mode 100644 packages/utils/src/check-types/is-title-config.ts diff --git a/docs/docs/api/project.md b/docs/docs/api/project.md index 269184b537..b7dda45b26 100644 --- a/docs/docs/api/project.md +++ b/docs/docs/api/project.md @@ -248,7 +248,7 @@ onChangeNodeVisible(fn: (node: Node, visible: boolean) => void) ### onChangeNodeChildren -onChangeNodeChildren(fn: (info?: IOnChangeOptions) => void) +onChangeNodeChildren(fn: (info?: IPublicOnChangeOptions) => void) 当前 document 的节点 children 变更事件 diff --git a/modules/code-generator/src/plugins/component/rax/jsx.ts b/modules/code-generator/src/plugins/component/rax/jsx.ts index ebc72104f0..e0c6dd01f4 100644 --- a/modules/code-generator/src/plugins/component/rax/jsx.ts +++ b/modules/code-generator/src/plugins/component/rax/jsx.ts @@ -147,7 +147,7 @@ const pluginFactory: BuilderComponentPluginFactory = (config?) => function __$$eval(expr) { try { return expr(); - } catch (error) { + } catch (error) { ${evalErrorsHandler} } } diff --git a/packages/designer/src/builtin-simulator/bem-tools/border-container.tsx b/packages/designer/src/builtin-simulator/bem-tools/border-container.tsx index 63874b4ca4..05a164c98b 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/border-container.tsx +++ b/packages/designer/src/builtin-simulator/bem-tools/border-container.tsx @@ -2,7 +2,8 @@ import * as React from 'react'; import { Component, Fragment, ReactElement, PureComponent } from 'react'; import classNames from 'classnames'; import { computed, observer, Title, globalLocale } from '@alilc/lowcode-editor-core'; -import { I18nData, isI18nData, TitleContent } from '@alilc/lowcode-types'; +import { I18nData, TitleContent } from '@alilc/lowcode-types'; +import { isI18nData } from '@alilc/lowcode-utils'; import { DropLocation } from '../../designer'; import { BuiltinSimulatorHost } from '../../builtin-simulator/host'; import { ParentalNode } from '../../document/node'; diff --git a/packages/designer/src/builtin-simulator/bem-tools/border-selecting.tsx b/packages/designer/src/builtin-simulator/bem-tools/border-selecting.tsx index b990e045a5..e5c8ad98af 100644 --- a/packages/designer/src/builtin-simulator/bem-tools/border-selecting.tsx +++ b/packages/designer/src/builtin-simulator/bem-tools/border-selecting.tsx @@ -9,9 +9,9 @@ import { ComponentType, } from 'react'; import classNames from 'classnames'; -import { observer, computed, Tip, globalContext, makeObservable } from '@alilc/lowcode-editor-core'; -import { createIcon, isReactComponent } from '@alilc/lowcode-utils'; -import { ActionContentObject, isActionContentObject } from '@alilc/lowcode-types'; +import { observer, computed, Tip, globalContext } from '@alilc/lowcode-editor-core'; +import { createIcon, isReactComponent, isActionContentObject } from '@alilc/lowcode-utils'; +import { ActionContentObject } from '@alilc/lowcode-types'; import { BuiltinSimulatorHost } from '../host'; import { OffsetObserver } from '../../designer'; import { Node } from '../../document'; diff --git a/packages/designer/src/builtin-simulator/host.ts b/packages/designer/src/builtin-simulator/host.ts index 5129c91634..429755fb29 100644 --- a/packages/designer/src/builtin-simulator/host.ts +++ b/packages/designer/src/builtin-simulator/host.ts @@ -39,8 +39,6 @@ import { transactionManager, } from '@alilc/lowcode-utils'; import { - DragObjectType, - DragNodeObject, isShaken, LocateEvent, isDragAnyObject, @@ -62,6 +60,8 @@ import { ComponentSchema, Package, TransitionType, + DragObjectType, + DragNodeObject, } from '@alilc/lowcode-types'; import { BuiltinSimulatorRenderer } from './renderer'; import clipboard from '../designer/clipboard'; diff --git a/packages/designer/src/component-meta.ts b/packages/designer/src/component-meta.ts index 4e1a74c77d..95b974890d 100644 --- a/packages/designer/src/component-meta.ts +++ b/packages/designer/src/component-meta.ts @@ -8,12 +8,12 @@ import { TitleContent, TransformedComponentMetadata, NestingFilter, - isTitleConfig, I18nData, LiveTextEditingConfig, FieldConfig, + MetadataTransducer, } from '@alilc/lowcode-types'; -import { deprecate, isRegExp } from '@alilc/lowcode-utils'; +import { deprecate, isRegExp, isTitleConfig } from '@alilc/lowcode-utils'; import { computed, engineConfig } from '@alilc/lowcode-editor-core'; import EventEmitter from 'events'; import { componentDefaults, legacyIssues } from './transducers'; @@ -128,8 +128,8 @@ export class ComponentMeta { private _isTopFixed?: boolean; - get isTopFixed() { - return this._isTopFixed; + get isTopFixed(): boolean { + return !!(this._isTopFixed); } private parentWhitelist?: NestingFilter | null; @@ -279,7 +279,7 @@ export class ComponentMeta { return result as any; } - isRootComponent(includeBlock = true) { + isRootComponent(includeBlock = true): boolean { return ( this.componentName === 'Page' || this.componentName === 'Component' || @@ -326,7 +326,7 @@ export class ComponentMeta { return true; } - checkNestingDown(my: Node, target: Node | NodeSchema | NodeSchema[]) { + checkNestingDown(my: Node, target: Node | NodeSchema | NodeSchema[]): boolean { // 检查父子关系,直接约束型,在画布中拖拽直接掠过目标容器 if (this.childWhitelist) { const _target: any = !Array.isArray(target) ? [target] : target; @@ -375,19 +375,7 @@ function preprocessMetadata(metadata: ComponentMetadata): TransformedComponentMe }; } -export interface MetadataTransducer { - (prev: TransformedComponentMetadata): TransformedComponentMetadata; - /** - * 0 - 9 system - * 10 - 99 builtin-plugin - * 100 - app & plugin - */ - level?: number; - /** - * use to replace TODO - */ - id?: string; -} + const metadataTransducers: MetadataTransducer[] = []; export function registerMetadataTransducer( diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts index 9663574dbe..dcb361fa20 100644 --- a/packages/designer/src/designer/designer.ts +++ b/packages/designer/src/designer/designer.ts @@ -8,10 +8,10 @@ import { IEditor, CompositeObject, PropsList, - isNodeSchema, NodeSchema, + PropsTransducer, } from '@alilc/lowcode-types'; -import { megreAssets, AssetsJson } from '@alilc/lowcode-utils'; +import { megreAssets, AssetsJson, isNodeSchema } from '@alilc/lowcode-utils'; import { Project } from '../project'; import { Node, DocumentModel, insertChildren, ParentalNode, TransformStage } from '../document'; import { ComponentMeta } from '../component-meta'; @@ -494,7 +494,7 @@ export class Designer { getComponentMeta( componentName: string, generateMetadata?: () => ComponentMetadata | null, - ): ComponentMeta { + ) { if (this._componentMetasMap.has(componentName)) { return this._componentMetasMap.get(componentName)!; } @@ -536,7 +536,7 @@ export class Designer { return maps; } - private propsReducers = new Map(); + private propsReducers = new Map(); transformProps(props: CompositeObject | PropsList, node: Node, stage: TransformStage) { if (Array.isArray(props)) { @@ -560,7 +560,7 @@ export class Designer { }, props); } - addPropsReducer(reducer: PropsReducer, stage: TransformStage) { + addPropsReducer(reducer: PropsTransducer, stage: TransformStage) { const reducers = this.propsReducers.get(stage); if (reducers) { reducers.push(reducer); @@ -576,11 +576,4 @@ export class Designer { purge() { // TODO: } -} - -export type PropsReducerContext = { stage: TransformStage }; -export type PropsReducer = ( - props: CompositeObject, - node: Node, - ctx?: PropsReducerContext, -) => CompositeObject; +} \ No newline at end of file diff --git a/packages/designer/src/designer/dragon.ts b/packages/designer/src/designer/dragon.ts index d45d05c3c8..2e80b5dd45 100644 --- a/packages/designer/src/designer/dragon.ts +++ b/packages/designer/src/designer/dragon.ts @@ -1,6 +1,6 @@ import { EventEmitter } from 'events'; import { obx, makeObservable } from '@alilc/lowcode-editor-core'; -import { NodeSchema } from '@alilc/lowcode-types'; +import { DragNodeObject, DragAnyObject, DragObjectType, DragNodeDataObject, DragObject } from '@alilc/lowcode-types'; import { Node as ShellNode } from '@alilc/lowcode-shell'; import { setNativeSelection, cursor } from '@alilc/lowcode-utils'; import { DropLocation } from './location'; @@ -80,31 +80,6 @@ export interface ISensor { getNodeInstanceFromElement(e: Element | null): NodeInstance | null; } -export type DragObject = DragNodeObject | DragNodeDataObject | DragAnyObject; - -export enum DragObjectType { - // eslint-disable-next-line no-shadow - Node = 'node', - NodeData = 'nodedata', -} - -export interface DragNodeObject { - type: DragObjectType.Node; - nodes: (Node | ShellNode)[]; -} -export interface DragNodeDataObject { - type: DragObjectType.NodeData; - data: NodeSchema | NodeSchema[]; - thumbnail?: string; - description?: string; - [extra: string]: any; -} - -export interface DragAnyObject { - type: string; - [key: string]: any; -} - export function isDragNodeObject(obj: any): obj is DragNodeObject { return obj && obj.type === DragObjectType.Node; } diff --git a/packages/designer/src/designer/setting/setting-field.ts b/packages/designer/src/designer/setting/setting-field.ts index a38c1323d0..9b766519c9 100644 --- a/packages/designer/src/designer/setting/setting-field.ts +++ b/packages/designer/src/designer/setting/setting-field.ts @@ -1,10 +1,9 @@ -import { TitleContent, isDynamicSetter, SetterType, DynamicSetter, FieldExtraProps, FieldConfig, CustomView, isCustomView } from '@alilc/lowcode-types'; +import { TitleContent, SetterType, DynamicSetter, FieldExtraProps, FieldConfig, CustomView, ISetValueOptions } from '@alilc/lowcode-types'; import { Transducer } from './utils'; import { SettingPropEntry } from './setting-prop-entry'; import { SettingEntry } from './setting-entry'; import { computed, obx, makeObservable, action } from '@alilc/lowcode-editor-core'; -import { cloneDeep } from '@alilc/lowcode-utils'; -import type { ISetValueOptions } from '../../types'; +import { cloneDeep, isCustomView, isDynamicSetter } from '@alilc/lowcode-utils'; function getSettingFieldCollectorKey(parent: SettingEntry, config: FieldConfig) { let cur = parent; diff --git a/packages/designer/src/designer/setting/setting-prop-entry.ts b/packages/designer/src/designer/setting/setting-prop-entry.ts index cfd603ea47..6eb5680a1f 100644 --- a/packages/designer/src/designer/setting/setting-prop-entry.ts +++ b/packages/designer/src/designer/setting/setting-prop-entry.ts @@ -1,13 +1,12 @@ import { obx, computed, makeObservable, runInAction } from '@alilc/lowcode-editor-core'; -import { GlobalEvent, IEditor, isJSExpression } from '@alilc/lowcode-types'; -import { uniqueId } from '@alilc/lowcode-utils'; +import { GlobalEvent, IEditor, ISetValueOptions } from '@alilc/lowcode-types'; +import { uniqueId, isJSExpression } from '@alilc/lowcode-utils'; import { SettingPropEntry as ShellSettingPropEntry } from '@alilc/lowcode-shell'; import { SettingEntry } from './setting-entry'; import { Node } from '../../document'; import { ComponentMeta } from '../../component-meta'; import { Designer } from '../designer'; import { EventEmitter } from 'events'; -import { ISetValueOptions } from '../../types'; import { isSettingField } from './setting-field'; export class SettingPropEntry implements SettingEntry { diff --git a/packages/designer/src/designer/setting/setting-top-entry.ts b/packages/designer/src/designer/setting/setting-top-entry.ts index e51f762092..1444935245 100644 --- a/packages/designer/src/designer/setting/setting-top-entry.ts +++ b/packages/designer/src/designer/setting/setting-top-entry.ts @@ -1,5 +1,6 @@ import { EventEmitter } from 'events'; -import { CustomView, isCustomView, IEditor } from '@alilc/lowcode-types'; +import { CustomView, IEditor } from '@alilc/lowcode-types'; +import { isCustomView } from '@alilc/lowcode-utils'; import { computed } from '@alilc/lowcode-editor-core'; import { SettingEntry } from './setting-entry'; import { SettingField } from './setting-field'; diff --git a/packages/designer/src/designer/setting/utils.ts b/packages/designer/src/designer/setting/utils.ts index 0958b7a780..319c3af8d3 100644 --- a/packages/designer/src/designer/setting/utils.ts +++ b/packages/designer/src/designer/setting/utils.ts @@ -1,6 +1,7 @@ // all this file for polyfill vision logic import { isValidElement } from 'react'; -import { isSetterConfig, isDynamicSetter, FieldConfig, SetterConfig } from '@alilc/lowcode-types'; +import { FieldConfig, SetterConfig } from '@alilc/lowcode-types'; +import { isSetterConfig, isDynamicSetter } from '@alilc/lowcode-utils'; import { getSetter } from '@alilc/lowcode-editor-core'; import { SettingField } from './setting-field'; diff --git a/packages/designer/src/document/document-model.ts b/packages/designer/src/document/document-model.ts index 08d67d2386..a4ba37a683 100644 --- a/packages/designer/src/document/document-model.ts +++ b/packages/designer/src/document/document-model.ts @@ -1,15 +1,15 @@ import { makeObservable, obx, engineConfig, action, runWithGlobalEventOff, wrapWithEventSwitch } from '@alilc/lowcode-editor-core'; -import { NodeData, isJSExpression, isDOMText, NodeSchema, isNodeSchema, RootSchema, PageSchema, ComponentsMap } from '@alilc/lowcode-types'; +import { NodeData, NodeSchema, RootSchema, PageSchema, ComponentsMap, DragNodeObject, DragNodeDataObject } from '@alilc/lowcode-types'; import { EventEmitter } from 'events'; import { Project } from '../project'; import { ISimulatorHost } from '../simulator'; import { ComponentMeta } from '../component-meta'; -import { isDragNodeDataObject, DragNodeObject, DragNodeDataObject, DropLocation, Designer, isDragNodeObject } from '../designer'; +import { isDragNodeDataObject, DropLocation, Designer, isDragNodeObject } from '../designer'; import { Node, insertChildren, insertChild, isNode, RootNode, ParentalNode } from './node/node'; import { Selection } from './selection'; import { History } from './history'; import { TransformStage, ModalNodesManager } from './node'; -import { uniqueId, isPlainObject, compatStage } from '@alilc/lowcode-utils'; +import { uniqueId, isPlainObject, compatStage, isJSExpression, isDOMText, isNodeSchema } from '@alilc/lowcode-utils'; export type GetDataType = T extends undefined ? NodeType extends { diff --git a/packages/designer/src/document/node/node-children.ts b/packages/designer/src/document/node/node-children.ts index 728df7cb8a..6c7d1c835f 100644 --- a/packages/designer/src/document/node/node-children.ts +++ b/packages/designer/src/document/node/node-children.ts @@ -1,17 +1,15 @@ import { obx, computed, globalContext, makeObservable } from '@alilc/lowcode-editor-core'; import { Node, ParentalNode } from './node'; import { TransformStage } from './transform-stage'; -import { NodeData, isNodeSchema } from '@alilc/lowcode-types'; -import { shallowEqual, compatStage } from '@alilc/lowcode-utils'; +import { NodeData } from '@alilc/lowcode-types'; +import { shallowEqual, compatStage, isNodeSchema } from '@alilc/lowcode-utils'; import { EventEmitter } from 'events'; import { foreachReverse } from '../../utils/tree'; import { NodeRemoveOptions } from '../../types'; - export interface IOnChangeOptions { type: string; node: Node; } - export class NodeChildren { @obx.shallow private children: Node[]; @@ -350,7 +348,7 @@ export class NodeChildren { return this.children.find(fn); } - reduce(fn: (acc: any, cur: Node) => any, initialValue: any) { + reduce(fn: (acc: any, cur: Node) => any, initialValue: any): void { return this.children.reduce(fn, initialValue); } @@ -358,7 +356,7 @@ export class NodeChildren { remover: (node: Node, idx: number) => boolean, adder: (children: Node[]) => NodeData[] | null, sorter: (firstNode: Node, secondNode: Node) => number, - ) { + ): any { let changed = false; if (remover) { const willRemove = this.children.filter(remover); diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index 9fe98e4734..a20173a96d 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -2,8 +2,6 @@ import { ReactElement } from 'react'; import { EventEmitter } from 'events'; import { obx, computed, autorun, makeObservable, runInAction, wrapWithEventSwitch, action } from '@alilc/lowcode-editor-core'; import { - isDOMText, - isJSExpression, NodeSchema, PropsMap, PropsList, @@ -17,7 +15,7 @@ import { GlobalEvent, ComponentAction, } from '@alilc/lowcode-types'; -import { compatStage } from '@alilc/lowcode-utils'; +import { compatStage, isDOMText, isJSExpression } from '@alilc/lowcode-utils'; import { SettingTopEntry } from '@alilc/lowcode-designer'; import { Node as ShellNode } from '@alilc/lowcode-shell'; import { Props, getConvertedExtraKey } from './props/props'; @@ -94,7 +92,7 @@ export class Node { /** * 节点组件类型 - * 特殊节点: + * 特殊节点: * * Page 页面 * * Block 区块 * * Component 组件/元件 diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index 78349154f9..634a6b14bf 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -1,6 +1,6 @@ import { untracked, computed, obx, engineConfig, action, makeObservable, mobx, runInAction } from '@alilc/lowcode-editor-core'; -import { CompositeValue, GlobalEvent, isJSExpression, isJSSlot, JSSlot, SlotSchema } from '@alilc/lowcode-types'; -import { uniqueId, isPlainObject, hasOwnProperty, compatStage } from '@alilc/lowcode-utils'; +import { CompositeValue, GlobalEvent, JSSlot, SlotSchema } from '@alilc/lowcode-types'; +import { uniqueId, isPlainObject, hasOwnProperty, compatStage, isJSExpression, isJSSlot } from '@alilc/lowcode-utils'; import { valueToSource } from './value-to-source'; import { Props } from './props'; import { SlotNode, Node } from '../node'; diff --git a/packages/designer/src/plugin/plugin-types.ts b/packages/designer/src/plugin/plugin-types.ts index 732803542c..2317b11ac8 100644 --- a/packages/designer/src/plugin/plugin-types.ts +++ b/packages/designer/src/plugin/plugin-types.ts @@ -1,8 +1,7 @@ -import { CompositeObject, ComponentAction } from '@alilc/lowcode-types'; +import { CompositeObject, ComponentAction, MetadataTransducer } from '@alilc/lowcode-types'; import Logger from 'zen-logger'; import { Hotkey, Skeleton, Project, Event, Material, Common } from '@alilc/lowcode-shell'; import { EngineConfig } from '@alilc/lowcode-editor-core'; -import { MetadataTransducer } from '@alilc/lowcode-designer'; import { Setters } from '../types'; export type PreferenceValueType = string | number | boolean; diff --git a/packages/designer/src/project/project.ts b/packages/designer/src/project/project.ts index 2442cc09de..470ac2e1c8 100644 --- a/packages/designer/src/project/project.ts +++ b/packages/designer/src/project/project.ts @@ -7,9 +7,8 @@ import { RootSchema, ComponentsMap, TransformStage, - isLowCodeComponentType, - isProCodeComponentType, } from '@alilc/lowcode-types'; +import { isLowCodeComponentType, isProCodeComponentType } from '@alilc/lowcode-utils'; import { ISimulatorHost } from '../simulator'; export class Project { diff --git a/packages/designer/src/types/index.ts b/packages/designer/src/types/index.ts index 43b88bf285..c0fffcc50f 100644 --- a/packages/designer/src/types/index.ts +++ b/packages/designer/src/types/index.ts @@ -1,6 +1,5 @@ import { getSetter, registerSetter, getSettersMap } from '@alilc/lowcode-editor-core'; -import { isFormEvent, compatibleLegaoSchema, getNodeSchemaById } from '@alilc/lowcode-utils'; -import { isNodeSchema } from '@alilc/lowcode-types'; +import { isFormEvent, compatibleLegaoSchema, getNodeSchemaById, isNodeSchema } from '@alilc/lowcode-utils'; export type Setters = { getSetter: typeof getSetter; @@ -18,21 +17,4 @@ export const utils = { compatibleLegaoSchema, getNodeSchemaById, }; -export type Utils = typeof utils; - -export enum PROP_VALUE_CHANGED_TYPE { - /** - * normal set value - */ - SET_VALUE = 'SET_VALUE', - /** - * value changed caused by sub-prop value change - */ - SUB_VALUE_CHANGE = 'SUB_VALUE_CHANGE', -} - -export interface ISetValueOptions { - disableMutator?: boolean; - type?: PROP_VALUE_CHANGED_TYPE; - fromSetHotValue?: boolean; -} \ No newline at end of file +export type Utils = typeof utils; \ No newline at end of file diff --git a/packages/designer/tests/bugs/prop-variable-jse.test.ts b/packages/designer/tests/bugs/prop-variable-jse.test.ts index b39b5b54e7..6483701919 100644 --- a/packages/designer/tests/bugs/prop-variable-jse.test.ts +++ b/packages/designer/tests/bugs/prop-variable-jse.test.ts @@ -1,7 +1,7 @@ // @ts-nocheck import { Editor } from '@alilc/lowcode-editor-core'; -import { isJSBlock, TransformStage } from '@alilc/lowcode-types'; -import { isPlainObject, isVariable } from '@alilc/lowcode-utils'; +import { TransformStage } from '@alilc/lowcode-types'; +import { isPlainObject, isVariable, isJSBlock } from '@alilc/lowcode-utils'; import '../fixtures/window'; import { Designer } from '../../src/designer/designer'; import { DocumentModel } from '../../src/document/document-model'; diff --git a/packages/designer/tests/builtin-simulator/host.test.ts b/packages/designer/tests/builtin-simulator/host.test.ts index 746134c36b..37713f3304 100644 --- a/packages/designer/tests/builtin-simulator/host.test.ts +++ b/packages/designer/tests/builtin-simulator/host.test.ts @@ -1,30 +1,14 @@ // @ts-ignore -import React from 'react'; -import set from 'lodash/set'; -import cloneDeep from 'lodash/cloneDeep'; import '../fixtures/window'; import { Editor, globalContext } from '@alilc/lowcode-editor-core'; import { - AssetLevel, - Asset, - AssetList, - assetBundle, - assetItem, AssetType, } from '@alilc/lowcode-utils'; import { - Dragon, - isDragNodeObject, - isDragNodeDataObject, - isDragAnyObject, - isLocateEvent, DragObjectType, - isShaken, - setShaken, -} from '../../src/designer/dragon'; +} from '@alilc/lowcode-types'; import { Project } from '../../src/project/project'; import pageMetadata from '../fixtures/component-metadata/page'; -import { Node } from '../../src/document/node/node'; import { Designer } from '../../src/designer/designer'; import { DocumentModel } from '../../src/document/document-model'; import formSchema from '../fixtures/schema/form'; diff --git a/packages/designer/tests/designer/designer.test.ts b/packages/designer/tests/designer/designer.test.ts index 51fbabea7e..3dd4749cdb 100644 --- a/packages/designer/tests/designer/designer.test.ts +++ b/packages/designer/tests/designer/designer.test.ts @@ -3,7 +3,7 @@ import { Editor, globalContext } from '@alilc/lowcode-editor-core'; import { Project } from '../../src/project/project'; import { DocumentModel } from '../../src/document/document-model'; import { Designer } from '../../src/designer/designer'; -import { Dragon, DragObjectType } from '../../src/designer/dragon'; +import { Dragon } from '../../src/designer/dragon'; import { TransformStage } from '../../src/document/node/transform-stage'; import formSchema from '../fixtures/schema/form'; import buttonMetadata from '../fixtures/component-metadata/button'; @@ -11,6 +11,7 @@ import pageMetadata from '../fixtures/component-metadata/page'; import divMetadata from '../fixtures/component-metadata/div'; import { delayObxTick } from '../utils'; import { fireEvent } from '@testing-library/react'; +import { DragObjectType } from '@alilc/lowcode-types'; const mockNode = { internalToShellNode() { diff --git a/packages/designer/tests/designer/dragon.test.ts b/packages/designer/tests/designer/dragon.test.ts index eaa53bd5b5..42216f06d8 100644 --- a/packages/designer/tests/designer/dragon.test.ts +++ b/packages/designer/tests/designer/dragon.test.ts @@ -10,12 +10,12 @@ import { isDragNodeDataObject, isDragAnyObject, isLocateEvent, - DragObjectType, isShaken, setShaken, isInvalidPoint, isSameAs, } from '../../src/designer/dragon'; +import { DragObjectType } from '@alilc/lowcode-types'; import formSchema from '../fixtures/schema/form'; import { fireEvent } from '@testing-library/react'; diff --git a/packages/designer/tests/designer/scroller.test.ts b/packages/designer/tests/designer/scroller.test.ts index 00f0b86e89..5265596c6e 100644 --- a/packages/designer/tests/designer/scroller.test.ts +++ b/packages/designer/tests/designer/scroller.test.ts @@ -1,35 +1,13 @@ import '../fixtures/window'; -import { set } from '../utils'; import { Editor, globalContext } from '@alilc/lowcode-editor-core'; import { Project } from '../../src/project/project'; import { DocumentModel } from '../../src/document/document-model'; import { ScrollTarget, Scroller } from '../../src/designer/scroller'; -import { - isRootNode, - isNode, - comparePosition, - contains, - insertChild, - insertChildren, - PositionNO, -} from '../../src/document/node/node'; import { Designer } from '../../src/designer/designer'; import { Dragon, - isDragNodeObject, - isDragNodeDataObject, - isDragAnyObject, - isLocateEvent, - DragObjectType, - isShaken, - setShaken, } from '../../src/designer/dragon'; import formSchema from '../fixtures/schema/form'; -import divMetadata from '../fixtures/component-metadata/div'; -import formMetadata from '../fixtures/component-metadata/form'; -import otherMeta from '../fixtures/component-metadata/other'; -import pageMetadata from '../fixtures/component-metadata/page'; -import { fireEvent } from '@testing-library/react'; describe('Scroller 测试', () => { let editor: Editor; diff --git a/packages/editor-core/src/di/setter.ts b/packages/editor-core/src/di/setter.ts index 2dd350deb4..8220c71615 100644 --- a/packages/editor-core/src/di/setter.ts +++ b/packages/editor-core/src/di/setter.ts @@ -1,23 +1,8 @@ import { ReactNode } from 'react'; -import { CustomView, isCustomView, TitleContent } from '@alilc/lowcode-types'; -import { createContent } from '@alilc/lowcode-utils'; +import { CustomView, RegisteredSetter } from '@alilc/lowcode-types'; +import { createContent, isCustomView } from '@alilc/lowcode-utils'; + -export type RegisteredSetter = { - component: CustomView; - defaultProps?: object; - title?: TitleContent; - /** - * for MixedSetter to check this setter if available - */ - condition?: (field: any) => boolean; - /** - * for MixedSetter to manual change to this setter - */ - initialValue?: any | ((field: any) => any); - recommend?: boolean; - // 标识是否为动态setter,默认为true - isDynamic?: boolean; -}; const settersMap = new Map(); diff --git a/packages/editor-core/src/hotkey.ts b/packages/editor-core/src/hotkey.ts index 4375c98486..038438426c 100644 --- a/packages/editor-core/src/hotkey.ts +++ b/packages/editor-core/src/hotkey.ts @@ -1,6 +1,7 @@ import { isEqual } from 'lodash'; import { globalContext } from './di'; import { Editor } from './editor'; +import { HotkeyCallback } from '@alilc/lowcode-types'; interface KeyMap { [key: number]: string; @@ -22,8 +23,6 @@ interface HotkeyDirectMap { [key: string]: HotkeyCallback; } -export type HotkeyCallback = (e: KeyboardEvent, combo?: string) => any | false; - interface HotkeyCallbackCfg { callback: HotkeyCallback; modifiers: string[]; diff --git a/packages/editor-core/src/intl/index.ts b/packages/editor-core/src/intl/index.ts index 1af991e69b..6d9d840c3c 100644 --- a/packages/editor-core/src/intl/index.ts +++ b/packages/editor-core/src/intl/index.ts @@ -1,7 +1,7 @@ import { ReactNode, Component, createElement } from 'react'; import { IntlMessageFormat } from 'intl-messageformat'; import { globalLocale } from './global-locale'; -import { isI18nData } from '@alilc/lowcode-types'; +import { isI18nData } from '@alilc/lowcode-utils'; import { observer } from '../utils'; function generateTryLocales(locale: string) { diff --git a/packages/editor-core/src/widgets/title/index.tsx b/packages/editor-core/src/widgets/title/index.tsx index bacfee9f16..7359213896 100644 --- a/packages/editor-core/src/widgets/title/index.tsx +++ b/packages/editor-core/src/widgets/title/index.tsx @@ -1,7 +1,7 @@ import { Component, isValidElement, ReactNode } from 'react'; import classNames from 'classnames'; -import { createIcon } from '@alilc/lowcode-utils'; -import { TitleContent, isI18nData, I18nData } from '@alilc/lowcode-types'; +import { createIcon, isI18nData } from '@alilc/lowcode-utils'; +import { TitleContent, I18nData } from '@alilc/lowcode-types'; import { intl } from '../../intl'; import { Tip } from '../tip'; import './title.less'; diff --git a/packages/editor-skeleton/src/components/settings/settings-pane.tsx b/packages/editor-skeleton/src/components/settings/settings-pane.tsx index fc084628a5..8043c74847 100644 --- a/packages/editor-skeleton/src/components/settings/settings-pane.tsx +++ b/packages/editor-skeleton/src/components/settings/settings-pane.tsx @@ -1,13 +1,12 @@ import { Component, MouseEvent, Fragment } from 'react'; import { shallowIntl, createSetterContent, observer, obx, engineConfig, runInAction, globalContext } from '@alilc/lowcode-editor-core'; -import { createContent } from '@alilc/lowcode-utils'; +import { createContent, isJSSlot, isSetterConfig } from '@alilc/lowcode-utils'; import { Skeleton } from '@alilc/lowcode-editor-skeleton'; -import { isSetterConfig, CustomView, isJSSlot } from '@alilc/lowcode-types'; +import { CustomView } from '@alilc/lowcode-types'; import { SettingField, isSettingField, SettingTopEntry, SettingEntry, ComponentMeta } from '@alilc/lowcode-designer'; import { createField } from '../field'; import PopupService, { PopupPipe } from '../popup'; import { SkeletonContext } from '../../context'; -// import { Icon } from '@alifd/next'; import { intl } from '../../locale'; function isStandardComponent(componentMeta: ComponentMeta | null) { diff --git a/packages/editor-skeleton/src/components/stage-box/stage.tsx b/packages/editor-skeleton/src/components/stage-box/stage.tsx index 64209fbd5d..e4b0c0ef12 100644 --- a/packages/editor-skeleton/src/components/stage-box/stage.tsx +++ b/packages/editor-skeleton/src/components/stage-box/stage.tsx @@ -4,7 +4,7 @@ import classNames from 'classnames'; import { IconArrow } from '../../icons/arrow'; import { IconExit } from '../../icons/exit'; import { Stage as StageWidget } from '../../widget/stage'; -import { isTitleConfig } from '@alilc/lowcode-types'; +import { isTitleConfig } from '@alilc/lowcode-utils'; export const StageDefaultProps = { current: false, diff --git a/packages/editor-skeleton/src/skeleton.ts b/packages/editor-skeleton/src/skeleton.ts index bdca4e284c..4b3f428098 100644 --- a/packages/editor-skeleton/src/skeleton.ts +++ b/packages/editor-skeleton/src/skeleton.ts @@ -3,7 +3,6 @@ import { DockConfig, PanelConfig, WidgetConfig, - IWidgetBaseConfig, PanelDockConfig, DialogDockConfig, isDockConfig, @@ -11,7 +10,6 @@ import { isPanelConfig, DividerConfig, isDividerConfig, - IWidgetConfigArea, } from './types'; import Panel, { isPanel } from './widget/panel'; import WidgetContainer from './widget/widget-container'; @@ -23,7 +21,12 @@ import { Stage, StageConfig } from './widget/stage'; import { isValidElement } from 'react'; import { isPlainObject, uniqueId } from '@alilc/lowcode-utils'; import { Divider } from '@alifd/next'; -import { EditorConfig, PluginClassSet } from '@alilc/lowcode-types'; +import { + EditorConfig, + PluginClassSet, + IWidgetBaseConfig, + IWidgetConfigArea, +} from '@alilc/lowcode-types'; export enum SkeletonEvents { PANEL_DOCK_ACTIVE = 'skeleton.panel-dock.active', diff --git a/packages/editor-skeleton/src/transducers/parse-func.ts b/packages/editor-skeleton/src/transducers/parse-func.ts index 8dc0a4cd84..b1caa34534 100644 --- a/packages/editor-skeleton/src/transducers/parse-func.ts +++ b/packages/editor-skeleton/src/transducers/parse-func.ts @@ -1,9 +1,5 @@ -import { - FieldConfig, - TransformedComponentMetadata, - isJSFunction, -} from '@alilc/lowcode-types'; -import { isPlainObject } from '@alilc/lowcode-utils'; +import { TransformedComponentMetadata } from '@alilc/lowcode-types'; +import { isPlainObject, isJSFunction } from '@alilc/lowcode-utils'; const leadingFnRe = /^function/; const leadingFnNameRe = /^\w+\s*\(/; diff --git a/packages/editor-skeleton/src/types.ts b/packages/editor-skeleton/src/types.ts index cefe86c927..ef6b43875d 100644 --- a/packages/editor-skeleton/src/types.ts +++ b/packages/editor-skeleton/src/types.ts @@ -1,35 +1,14 @@ import { ReactElement, ComponentType } from 'react'; -import { TitleContent, IconType, I18nData, TipContent } from '@alilc/lowcode-types'; +import { + TitleContent, + IconType, + I18nData, + TipContent, + IWidgetConfigArea, + IWidgetBaseConfig, +} from '@alilc/lowcode-types'; import { IWidget } from './widget/widget'; -/** - * 所有可能的停靠位置 - */ -export type IWidgetConfigArea = - | 'leftArea' | 'left' | 'rightArea' - | 'right' | 'topArea' | 'top' - | 'toolbar' | 'mainArea' | 'main' - | 'center' | 'centerArea' | 'bottomArea' - | 'bottom' | 'leftFixedArea' - | 'leftFloatArea' | 'stages'; - -export interface IWidgetBaseConfig { - type: string; - name: string; - /** - * 停靠位置: - * - 当 type 为 'Panel' 时自动为 'leftFloatArea'; - * - 当 type 为 'Widget' 时自动为 'mainArea'; - * - 其他时候自动为 'leftArea'; - */ - area?: IWidgetConfigArea; - props?: Record; - content?: any; - contentProps?: Record; - // index?: number; - [extra: string]: any; -} - export interface WidgetConfig extends IWidgetBaseConfig { type: 'Widget'; props?: { diff --git a/packages/editor-skeleton/src/widget/utils.ts b/packages/editor-skeleton/src/widget/utils.ts index 73657d08f7..556a8cb2ab 100644 --- a/packages/editor-skeleton/src/widget/utils.ts +++ b/packages/editor-skeleton/src/widget/utils.ts @@ -1,4 +1,5 @@ -import { IconType, TitleContent, isI18nData, TipContent, isTitleConfig } from '@alilc/lowcode-types'; +import { IconType, TitleContent, TipContent } from '@alilc/lowcode-types'; +import { isI18nData, isTitleConfig } from '@alilc/lowcode-utils'; import { isValidElement } from 'react'; export function composeTitle(title?: TitleContent, icon?: IconType, tip?: TipContent, tipAsTitle?: boolean, noIcon?: boolean) { diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index 9b3c393280..55355f5745 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -33,7 +33,6 @@ import './modules/live-editing'; import classes from './modules/classes'; import symbols from './modules/symbols'; -export * from './modules/editor-types'; export * from './modules/skeleton-types'; export * from './modules/designer-types'; export * from './modules/lowcode-types'; diff --git a/packages/engine/src/modules/designer-types.ts b/packages/engine/src/modules/designer-types.ts index e2023ef6f3..9799f6b2ca 100644 --- a/packages/engine/src/modules/designer-types.ts +++ b/packages/engine/src/modules/designer-types.ts @@ -13,7 +13,4 @@ export type ILowCodePluginConfig = designerCabin.ILowCodePluginConfig; export type ILowCodePluginManager = designerCabin.ILowCodePluginManager; export type ILowCodePluginContext = designerCabin.ILowCodePluginContext; export type IPluginConfigCreator = designerCabin.IPluginConfigCreator; -export type PluginPreference = designerCabin.PluginPreference; -export type PropsReducerContext = designerCabin.PropsReducerContext; -export type DragObjectType = designerCabin.DragObjectType; -export type DragNodeDataObject = designerCabin.DragNodeDataObject; \ No newline at end of file +export type PluginPreference = designerCabin.PluginPreference; \ No newline at end of file diff --git a/packages/engine/src/modules/editor-types.ts b/packages/engine/src/modules/editor-types.ts deleted file mode 100644 index 1306712a74..0000000000 --- a/packages/engine/src/modules/editor-types.ts +++ /dev/null @@ -1,3 +0,0 @@ -import * as editorCabin from '@alilc/lowcode-editor-core'; - -export type RegisteredSetter = editorCabin.RegisteredSetter; diff --git a/packages/engine/src/modules/live-editing.ts b/packages/engine/src/modules/live-editing.ts index 620fef895a..b6e110a1c3 100644 --- a/packages/engine/src/modules/live-editing.ts +++ b/packages/engine/src/modules/live-editing.ts @@ -1,5 +1,5 @@ import { EditingTarget, Node as DocNode, SaveHandler, LiveEditing } from '@alilc/lowcode-designer'; -import { isJSExpression } from '@alilc/lowcode-types'; +import { isJSExpression } from '@alilc/lowcode-utils'; function getText(node: DocNode, prop: string) { const p = node.getProp(prop, false); @@ -53,8 +53,7 @@ function equalText(v: any, innerText: string) { export const liveEditingSaveHander: SaveHandler = { condition: (prop) => { - // const v = prop.getValue(); - return prop.type === 'expression'; // || isI18nData(v); + return prop.type === 'expression'; }, onSaveContent: (content, prop) => { const v = prop.getValue(); diff --git a/packages/plugin-outline-pane/src/tree-node.ts b/packages/plugin-outline-pane/src/tree-node.ts index 67efe5fbac..54627de2cf 100644 --- a/packages/plugin-outline-pane/src/tree-node.ts +++ b/packages/plugin-outline-pane/src/tree-node.ts @@ -1,4 +1,5 @@ -import { TitleContent, isI18nData } from '@alilc/lowcode-types'; +import { TitleContent } from '@alilc/lowcode-types'; +import { isI18nData } from '@alilc/lowcode-utils'; import { computed, obx, intl, makeObservable, action } from '@alilc/lowcode-editor-core'; import { Node, DocumentModel, isLocationChildrenDetail, LocationChildrenDetail, Designer } from '@alilc/lowcode-designer'; import { Tree } from './tree'; diff --git a/packages/plugin-outline-pane/src/views/tree.tsx b/packages/plugin-outline-pane/src/views/tree.tsx index 98cdd4233f..af86ed88fb 100644 --- a/packages/plugin-outline-pane/src/views/tree.tsx +++ b/packages/plugin-outline-pane/src/views/tree.tsx @@ -1,9 +1,10 @@ import { Component, MouseEvent as ReactMouseEvent } from 'react'; import { observer, Editor, globalContext } from '@alilc/lowcode-editor-core'; -import { Node, DragObjectType, isShaken } from '@alilc/lowcode-designer'; +import { Node, isShaken } from '@alilc/lowcode-designer'; import { isFormEvent, canClickNode } from '@alilc/lowcode-utils'; import { Tree } from '../tree'; import RootTreeNodeView from './root-tree-node'; +import { DragObjectType } from '@alilc/lowcode-types'; function getTreeNodeIdByEvent(e: ReactMouseEvent, stop: Element): null | string { let target: Element | null = e.target as Element; diff --git a/packages/rax-simulator-renderer/src/renderer.ts b/packages/rax-simulator-renderer/src/renderer.ts index a123dfc7e3..cebeffbb11 100644 --- a/packages/rax-simulator-renderer/src/renderer.ts +++ b/packages/rax-simulator-renderer/src/renderer.ts @@ -1,8 +1,8 @@ import { BuiltinSimulatorRenderer, Component, DocumentModel, Node, NodeInstance } from '@alilc/lowcode-designer'; -import { ComponentSchema, NodeSchema, NpmInfo, RootSchema, TransformStage } from '@alilc/lowcode-types'; +import { ComponentSchema, NodeSchema, NpmInfo, TransformStage } from '@alilc/lowcode-types'; import { Asset, compatibleLegaoSchema, cursor, isElement, isESModule, isPlainObject, isReactComponent, setNativeSelection } from '@alilc/lowcode-utils'; import LowCodeRenderer from '@alilc/lowcode-rax-renderer'; -import { computed, observable as obx, untracked, makeObservable, configure } from 'mobx'; +import { computed, observable as obx, makeObservable, configure } from 'mobx'; import DriverUniversal from 'driver-universal'; import { EventEmitter } from 'events'; import { createMemoryHistory, MemoryHistory } from 'history'; diff --git a/packages/renderer-core/src/renderer/base.tsx b/packages/renderer-core/src/renderer/base.tsx index afa3938e73..718a5d9c08 100644 --- a/packages/renderer-core/src/renderer/base.tsx +++ b/packages/renderer-core/src/renderer/base.tsx @@ -3,7 +3,8 @@ /* eslint-disable react/prop-types */ import classnames from 'classnames'; import { create as createDataSourceEngine } from '@alilc/lowcode-datasource-engine/interpret'; -import { isI18nData, isJSExpression, isJSFunction, NodeSchema, NodeData, JSONValue, CompositeValue } from '@alilc/lowcode-types'; +import { NodeSchema, NodeData, JSONValue, CompositeValue } from '@alilc/lowcode-types'; +import { isI18nData, isJSExpression, isJSFunction } from '@alilc/lowcode-utils'; import adapter from '../adapter'; import divFactory from '../components/Div'; import visualDomFactory from '../components/VisualDom'; @@ -29,7 +30,7 @@ import { isVariable, isJSSlot, } from '../utils'; -import { IBaseRendererProps, INodeInfo, IBaseRenderComponent, IBaseRendererContext, IGeneralConstructor, IRendererAppHelper, DataSource } from '../types'; +import { IBaseRendererProps, INodeInfo, IBaseRenderComponent, IBaseRendererContext, IRendererAppHelper, DataSource } from '../types'; import { compWrapper } from '../hoc'; import { IComponentConstruct, leafWrapper } from '../hoc/leaf'; import logger from '../utils/logger'; diff --git a/packages/renderer-core/src/utils/common.ts b/packages/renderer-core/src/utils/common.ts index d064b5593f..7f3deed437 100644 --- a/packages/renderer-core/src/utils/common.ts +++ b/packages/renderer-core/src/utils/common.ts @@ -1,7 +1,8 @@ /* eslint-disable no-console */ /* eslint-disable no-new-func */ import logger from './logger'; -import { isI18nData, RootSchema, NodeSchema, isJSExpression, JSSlot } from '@alilc/lowcode-types'; +import { RootSchema, NodeSchema, JSSlot } from '@alilc/lowcode-types'; +import { isI18nData, isJSExpression } from '@alilc/lowcode-utils'; import { isEmpty } from 'lodash'; import IntlMessageFormat from 'intl-messageformat'; import pkg from '../../package.json'; diff --git a/packages/renderer-core/src/utils/data-helper.ts b/packages/renderer-core/src/utils/data-helper.ts index 9eb152df9e..d884c13c97 100644 --- a/packages/renderer-core/src/utils/data-helper.ts +++ b/packages/renderer-core/src/utils/data-helper.ts @@ -1,7 +1,7 @@ /* eslint-disable no-console */ /* eslint-disable max-len */ /* eslint-disable object-curly-newline */ -import { isJSFunction } from '@alilc/lowcode-types'; +import { isJSFunction } from '@alilc/lowcode-utils'; import { transformArrayToMap, transformStringToFunction } from './common'; import { jsonp, request, get, post } from './request'; import logger from './logger'; diff --git a/packages/renderer-core/src/utils/is-use-loop.ts b/packages/renderer-core/src/utils/is-use-loop.ts index 913480f638..59d356f5d2 100644 --- a/packages/renderer-core/src/utils/is-use-loop.ts +++ b/packages/renderer-core/src/utils/is-use-loop.ts @@ -1,4 +1,5 @@ -import { isJSExpression, JSExpression } from '@alilc/lowcode-types'; +import { JSExpression } from '@alilc/lowcode-types'; +import { isJSExpression } from '@alilc/lowcode-utils'; // 1.渲染模式下,loop 是数组,则按照数组长度渲染组件 // 2.设计模式下,loop 需要长度大于 0,按照循环模式渲染,防止无法设计的情况 diff --git a/packages/shell/src/canvas.ts b/packages/shell/src/canvas.ts index 268dbc4a8f..a927f63d8a 100644 --- a/packages/shell/src/canvas.ts +++ b/packages/shell/src/canvas.ts @@ -1,16 +1,19 @@ import { Designer } from '@alilc/lowcode-designer'; import { designerSymbol } from './symbols'; import DropLocation from './drop-location'; +import { IPublicModelCanvas } from '@alilc/lowcode-types'; -export default class Canvas { +export default class Canvas implements IPublicModelCanvas { private readonly [designerSymbol]: Designer; constructor(designer: Designer) { this[designerSymbol] = designer; } - static create(designer: Designer) { - if (!designer) return null; + static create(designer: Designer): IPublicModelCanvas | null { + if (!designer) { + return null; + } return new Canvas(designer); } diff --git a/packages/shell/src/common.tsx b/packages/shell/src/common.tsx index dc25e46685..e5ef1ab379 100644 --- a/packages/shell/src/common.tsx +++ b/packages/shell/src/common.tsx @@ -4,12 +4,17 @@ import { compatibleLegaoSchema as innerCompatibleLegaoSchema, getNodeSchemaById as innerGetNodeSchemaById, transactionManager, + isNodeSchema as innerIsNodeSchema, } from '@alilc/lowcode-utils'; import { - isNodeSchema as innerIsNodeSchema, NodeSchema, TransitionType, TransformStage as InnerTransitionStage, + IPublicCommonDesignerCabin, + IPublicCommonSkeletonCabin, + IPublicCommonUtils, + IPublicApiCommon, + DragObjectType as InnerDragObjectType, } from '@alilc/lowcode-types'; import { SettingField as InnerSettingField, @@ -19,7 +24,6 @@ import { isDragNodeDataObject as innerIsDragNodeDataObject, isDragNodeObject as innerIsDragNodeObject, isDragAnyObject as innerIsDragAnyObject, - DragObjectType as InnerDragObjectType, isNode as innerIsNode, isShaken as innerIsShaken, contains as innerContains, @@ -56,7 +60,7 @@ import { import { ReactNode } from 'react'; -class DesignerCabin { +class DesignerCabin implements IPublicCommonDesignerCabin { private readonly [editorSymbol]: Editor; /** * @deprecated @@ -147,7 +151,7 @@ class DesignerCabin { } } -class SkeletonCabin { +class SkeletonCabin implements IPublicCommonSkeletonCabin { private readonly [skeletonSymbol]: InnerSkeleton; constructor(skeleton: InnerSkeleton) { @@ -181,7 +185,7 @@ class SkeletonCabin { } } -class Utils { +class Utils implements IPublicCommonUtils { isNodeSchema(data: any): data is NodeSchema { return innerIsNodeSchema(data); } @@ -314,7 +318,7 @@ class EditorCabin { } -export default class Common { +export default class Common implements IPublicApiCommon { private readonly __designerCabin: any; private readonly __skeletonCabin: any; private readonly __editorCabin: any; diff --git a/packages/shell/src/component-meta.ts b/packages/shell/src/component-meta.ts index e7752f6858..6dec94562a 100644 --- a/packages/shell/src/component-meta.ts +++ b/packages/shell/src/component-meta.ts @@ -2,19 +2,21 @@ import { ComponentMeta as InnerComponentMeta, ParentalNode, } from '@alilc/lowcode-designer'; -import Node from './node'; -import { NodeData, NodeSchema } from '@alilc/lowcode-types'; +import { NodeData, NodeSchema, IPublicModelComponentMeta, I18nData, IconType, NpmInfo, TransformedComponentMetadata, IPublicModelNode } from '@alilc/lowcode-types'; import { componentMetaSymbol, nodeSymbol } from './symbols'; +import { ReactElement } from 'react'; -export default class ComponentMeta { +export default class ComponentMeta implements IPublicModelComponentMeta { private readonly [componentMetaSymbol]: InnerComponentMeta; constructor(componentMeta: InnerComponentMeta) { this[componentMetaSymbol] = componentMeta; } - static create(componentMeta: InnerComponentMeta | null) { - if (!componentMeta) return null; + static create(componentMeta: InnerComponentMeta | null): IPublicModelComponentMeta | null { + if (!componentMeta) { + return null; + } return new ComponentMeta(componentMeta); } @@ -52,28 +54,28 @@ export default class ComponentMeta { /** * 元数据配置 */ - get configure() { + get configure(): any { return this[componentMetaSymbol].configure; } /** * 标题 */ - get title() { + get title(): string | I18nData | ReactElement { return this[componentMetaSymbol].title; } /** * 图标 */ - get icon() { + get icon(): IconType { return this[componentMetaSymbol].icon; } /** * 组件 npm 信息 */ - get npm() { + get npm(): NpmInfo { return this[componentMetaSymbol].npm; } @@ -84,7 +86,7 @@ export default class ComponentMeta { return this[componentMetaSymbol].prototype; } - get availableActions() { + get availableActions(): any { return this[componentMetaSymbol].availableActions; } @@ -92,7 +94,7 @@ export default class ComponentMeta { * 设置 npm 信息 * @param npm */ - setNpm(npm: any) { + setNpm(npm: NpmInfo): void { this[componentMetaSymbol].setNpm(npm); } @@ -100,7 +102,7 @@ export default class ComponentMeta { * 获取元数据 * @returns */ - getMetadata() { + getMetadata(): TransformedComponentMetadata { return this[componentMetaSymbol].getMetadata(); } @@ -110,8 +112,8 @@ export default class ComponentMeta { * @param parent * @returns */ - checkNestingUp(my: Node | NodeData, parent: ParentalNode) { - const curNode = my.isNode ? my[nodeSymbol] : my; + checkNestingUp(my: IPublicModelNode | NodeData, parent: ParentalNode): boolean { + const curNode = (my as any).isNode ? (my as any)[nodeSymbol] : my; return this[componentMetaSymbol].checkNestingUp(curNode as any, parent); } @@ -121,12 +123,12 @@ export default class ComponentMeta { * @param parent * @returns */ - checkNestingDown(my: Node | NodeData, target: NodeSchema | Node | NodeSchema[]) { - const curNode = my.isNode ? my[nodeSymbol] : my; - return this[componentMetaSymbol].checkNestingDown(curNode as any, target[nodeSymbol] || target); + checkNestingDown(my: IPublicModelNode | NodeData, target: NodeSchema | IPublicModelNode | NodeSchema[]) { + const curNode = (my as any)?.isNode ? (my as any)[nodeSymbol] : my; + return this[componentMetaSymbol].checkNestingDown(curNode as any, (target as any)[nodeSymbol] || target); } - refreshMetadata() { + refreshMetadata(): void { this[componentMetaSymbol].refreshMetadata(); } } diff --git a/packages/shell/src/detecting.ts b/packages/shell/src/detecting.ts index d8e6c7fbb7..2baf02801b 100644 --- a/packages/shell/src/detecting.ts +++ b/packages/shell/src/detecting.ts @@ -4,8 +4,9 @@ import { DocumentModel as InnerDocumentModel, } from '@alilc/lowcode-designer'; import { documentSymbol, detectingSymbol } from './symbols'; +import { IPublicModelDetecting } from '@alilc/lowcode-types'; -export default class Detecting { +export default class Detecting implements IPublicModelDetecting { private readonly [documentSymbol]: InnerDocumentModel; private readonly [detectingSymbol]: InnerDetecting; diff --git a/packages/shell/src/document-model.ts b/packages/shell/src/document-model.ts index 3f8f4e70ed..82fd243d60 100644 --- a/packages/shell/src/document-model.ts +++ b/packages/shell/src/document-model.ts @@ -2,16 +2,26 @@ import { Editor } from '@alilc/lowcode-editor-core'; import { DocumentModel as InnerDocumentModel, Node as InnerNode, - IOnChangeOptions as InnerIOnChangeOptions, - DragObject as InnerDragObject, - DragNodeObject, - DragNodeDataObject, isDragNodeObject, + IOnChangeOptions as InnerOnChangeOptions, } from '@alilc/lowcode-designer'; import { TransformStage, RootSchema, GlobalEvent, + IPublicModelDocumentModel, + IPublicOnChangeOptions, + DragObject, + DragNodeObject, + DragNodeDataObject, + IPublicModelNode, + IPublicModelSelection, + IPublicModelDetecting, + IPublicModelHistory, + IPublicModelCanvas, + IPublicApiProject, + IPublicModelModalNodesManager, + PropChangeOptions, } from '@alilc/lowcode-types'; import Node from './node'; import Selection from './selection'; @@ -23,33 +33,20 @@ import Canvas from './canvas'; import ModalNodesManager from './modal-nodes-manager'; import { documentSymbol, editorSymbol, nodeSymbol } from './symbols'; -type IOnChangeOptions = { - type: string; - node: Node; -}; - -type PropChangeOptions = { - key?: string | number; - prop?: Prop; - node: Node; - newValue: any; - oldValue: any; -}; - const Events = { IMPORT_SCHEMA: 'shell.document.importSchema', }; const shellDocSymbol = Symbol('shellDocSymbol'); -export default class DocumentModel { +export default class DocumentModel implements IPublicModelDocumentModel { private readonly [documentSymbol]: InnerDocumentModel; private readonly [editorSymbol]: Editor; - private _focusNode: Node; - public selection: Selection; - public detecting: Detecting; - public history: History; - public canvas: Canvas; + private _focusNode: IPublicModelNode | null; + selection: IPublicModelSelection; + detecting: IPublicModelDetecting; + history: IPublicModelHistory; + canvas: IPublicModelCanvas; constructor(document: InnerDocumentModel) { this[documentSymbol] = document; @@ -62,10 +59,14 @@ export default class DocumentModel { this._focusNode = Node.create(this[documentSymbol].focusNode); } - static create(document: InnerDocumentModel | undefined | null) { - if (!document) return null; + static create(document: InnerDocumentModel | undefined | null): IPublicModelDocumentModel | null { + if (!document) { + return null; + } // @ts-ignore 直接返回已挂载的 shell doc 实例 - if (document[shellDocSymbol]) return document[shellDocSymbol]; + if (document[shellDocSymbol]) { + return (document as any)[shellDocSymbol]; + } const shellDoc = new DocumentModel(document); // @ts-ignore 直接返回已挂载的 shell doc 实例 document[shellDocSymbol] = shellDoc; @@ -75,7 +76,7 @@ export default class DocumentModel { /** * id */ - get id() { + get id(): string { return this[documentSymbol].id; } @@ -87,7 +88,7 @@ export default class DocumentModel { * 获取当前文档所属的 project * @returns */ - get project() { + get project(): IPublicApiProject | null { return Project.create(this[documentSymbol].project); } @@ -95,15 +96,15 @@ export default class DocumentModel { * 获取文档的根节点 * @returns */ - get root(): Node | null { + get root(): IPublicModelNode | null { return Node.create(this[documentSymbol].getRoot()); } - get focusNode(): Node { + get focusNode(): IPublicModelNode | null { return this._focusNode || this.root; } - set focusNode(node: Node) { + set focusNode(node: IPublicModelNode | null) { this._focusNode = node; } @@ -111,8 +112,8 @@ export default class DocumentModel { * 获取文档下所有节点 * @returns */ - get nodesMap() { - const map = new Map(); + get nodesMap(): any { + const map = new Map(); for (let id of this[documentSymbol].nodesMap.keys()) { map.set(id, this.getNodeById(id)!); } @@ -122,12 +123,15 @@ export default class DocumentModel { /** * 模态节点管理 */ - get modalNodesManager() { + get modalNodesManager(): IPublicModelModalNodesManager | null { return ModalNodesManager.create(this[documentSymbol].modalNodesManager); } - // @TODO: 不能直接暴露 - get dropLocation() { + /** + * @TODO: 不能直接暴露 + * @deprecated + */ + get dropLocation(): any { return this[documentSymbol].dropLocation; } @@ -136,7 +140,7 @@ export default class DocumentModel { * @param nodeId * @returns */ - getNodeById(nodeId: string) { + getNodeById(nodeId: string): IPublicModelNode | null { return Node.create(this[documentSymbol].getNode(nodeId)); } @@ -144,7 +148,7 @@ export default class DocumentModel { * 导入 schema * @param schema */ - importSchema(schema: RootSchema) { + importSchema(schema: RootSchema): void { this[documentSymbol].import(schema); this[editorSymbol].emit(Events.IMPORT_SCHEMA, schema); } @@ -154,7 +158,7 @@ export default class DocumentModel { * @param stage * @returns */ - exportSchema(stage: TransformStage = TransformStage.Render) { + exportSchema(stage: TransformStage = TransformStage.Render): any { return this[documentSymbol].export(stage); } @@ -167,14 +171,14 @@ export default class DocumentModel { * @returns */ insertNode( - parent: Node, - thing: Node, + parent: IPublicModelNode, + thing: IPublicModelNode, at?: number | null | undefined, copy?: boolean | undefined, - ) { + ): IPublicModelNode | null { const node = this[documentSymbol].insertNode( - parent[nodeSymbol] ? parent[nodeSymbol] : parent, - thing?.[nodeSymbol] ? thing[nodeSymbol] : thing, + (parent as any)[nodeSymbol] ? (parent as any)[nodeSymbol] : parent, + (thing as any)?.[nodeSymbol] ? (thing as any)[nodeSymbol] : thing, at, copy, ); @@ -186,7 +190,7 @@ export default class DocumentModel { * @param data * @returns */ - createNode(data: any) { + createNode(data: any): IPublicModelNode | null { return Node.create(this[documentSymbol].createNode(data)); } @@ -194,7 +198,7 @@ export default class DocumentModel { * 移除指定节点/节点id * @param idOrNode */ - removeNode(idOrNode: string | Node) { + removeNode(idOrNode: string | IPublicModelNode): void { this[documentSymbol].removeNode(idOrNode as any); } @@ -203,7 +207,7 @@ export default class DocumentModel { * @param extraComps * @returns */ - getComponentsMap(extraComps?: string[]) { + getComponentsMap(extraComps?: string[]): any { return this[documentSymbol].getComponentsMap(extraComps); } @@ -213,13 +217,16 @@ export default class DocumentModel { * @param dragObject 拖拽的对象 * @returns boolean 是否可以放置 */ - checkNesting(dropTarget: Node, dragObject: DragNodeObject | DragNodeDataObject): boolean { - let innerDragObject: InnerDragObject = dragObject; + checkNesting( + dropTarget: IPublicModelNode, + dragObject: DragNodeObject | DragNodeDataObject, + ): boolean { + let innerDragObject: DragObject = dragObject; if (isDragNodeObject(dragObject)) { innerDragObject.nodes = innerDragObject.nodes.map((node: Node) => (node[nodeSymbol] || node)); } return this[documentSymbol].checkNesting( - (dropTarget[nodeSymbol] || dropTarget) as any, + ((dropTarget as any)[nodeSymbol] || dropTarget) as any, innerDragObject as any, ); } @@ -227,7 +234,7 @@ export default class DocumentModel { /** * 当前 document 新增节点事件 */ - onAddNode(fn: (node: Node) => void) { + onAddNode(fn: (node: IPublicModelNode) => void): () => void { return this[documentSymbol].onNodeCreate((node: InnerNode) => { fn(Node.create(node)!); }); @@ -236,7 +243,7 @@ export default class DocumentModel { /** * 当前 document 新增节点事件,此时节点已经挂载到 document 上 */ - onMountNode(fn: (payload: { node: Node }) => void) { + onMountNode(fn: (payload: { node: IPublicModelNode }) => void): () => void { this[editorSymbol].on('node.add', fn as any); return () => { this[editorSymbol].off('node.add', fn as any); @@ -246,7 +253,7 @@ export default class DocumentModel { /** * 当前 document 删除节点事件 */ - onRemoveNode(fn: (node: Node) => void) { + onRemoveNode(fn: (node: IPublicModelNode) => void): () => void { return this[documentSymbol].onNodeDestroy((node: InnerNode) => { fn(Node.create(node)!); }); @@ -255,7 +262,7 @@ export default class DocumentModel { /** * 当前 document 的 hover 变更事件 */ - onChangeDetecting(fn: (node: Node) => void) { + onChangeDetecting(fn: (node: IPublicModelNode) => void): () => void { return this[documentSymbol].designer.detecting.onDetectingChange((node: InnerNode) => { fn(Node.create(node)!); }); @@ -264,7 +271,7 @@ export default class DocumentModel { /** * 当前 document 的选中变更事件 */ - onChangeSelection(fn: (ids: string[]) => void) { + onChangeSelection(fn: (ids: string[]) => void): () => void { return this[documentSymbol].selection.onSelectionChange((ids: string[]) => { fn(ids); }); @@ -274,9 +281,9 @@ export default class DocumentModel { * 当前 document 的节点显隐状态变更事件 * @param fn */ - onChangeNodeVisible(fn: (node: Node, visible: boolean) => void) { + onChangeNodeVisible(fn: (node: IPublicModelNode, visible: boolean) => void): void { // TODO: history 变化时需要重新绑定 - this[documentSymbol].nodesMap.forEach((node) => { + this[documentSymbol].nodesMap?.forEach((node) => { node.onVisibleChange((flag: boolean) => { fn(Node.create(node)!, flag); }); @@ -287,10 +294,10 @@ export default class DocumentModel { * 当前 document 的节点 children 变更事件 * @param fn */ - onChangeNodeChildren(fn: (info?: IOnChangeOptions) => void) { + onChangeNodeChildren(fn: (info?: IPublicOnChangeOptions) => void): void { // TODO: history 变化时需要重新绑定 - this[documentSymbol].nodesMap.forEach((node) => { - node.onChildrenChange((info?: InnerIOnChangeOptions) => { + this[documentSymbol].nodesMap?.forEach((node) => { + node.onChildrenChange((info?: InnerOnChangeOptions) => { return info ? fn({ type: info.type, @@ -305,7 +312,7 @@ export default class DocumentModel { * 当前 document 节点属性修改事件 * @param fn */ - onChangeNodeProp(fn: (info: PropChangeOptions) => void) { + onChangeNodeProp(fn: (info: PropChangeOptions) => void): void { this[editorSymbol].on( GlobalEvent.Node.Prop.InnerChange, (info: GlobalEvent.Node.Prop.ChangeOptions) => { @@ -324,7 +331,7 @@ export default class DocumentModel { * import schema event * @param fn */ - onImportSchema(fn: (schema: RootSchema) => void) { + onImportSchema(fn: (schema: RootSchema) => void): void { this[editorSymbol].on(Events.IMPORT_SCHEMA, fn as any); } } diff --git a/packages/shell/src/drag-object.ts b/packages/shell/src/drag-object.ts index 1261b4d264..f09cedecbd 100644 --- a/packages/shell/src/drag-object.ts +++ b/packages/shell/src/drag-object.ts @@ -1,30 +1,34 @@ -import { DragObject as InnerDragObject, DragNodeDataObject } from '@alilc/lowcode-designer'; import { dragObjectSymbol } from './symbols'; +import { IPublicModelDragObject, DragObject as InnerDragObject, DragNodeDataObject } from '@alilc/lowcode-types'; import Node from './node'; -export default class DragObject { +export default class DragObject implements IPublicModelDragObject { private readonly [dragObjectSymbol]: InnerDragObject; constructor(dragObject: InnerDragObject) { this[dragObjectSymbol] = dragObject; } - static create(dragObject: InnerDragObject) { - if (!dragObject) return null; + static create(dragObject: InnerDragObject): IPublicModelDragObject | null { + if (!dragObject) { + return null; + } return new DragObject(dragObject); } - get type() { + get type(): any { return this[dragObjectSymbol].type; } - get nodes() { + get nodes(): any { const { nodes } = this[dragObjectSymbol]; - if (!nodes) return null; + if (!nodes) { + return null; + } return nodes.map(Node.create); } - get data() { + get data(): any { return (this[dragObjectSymbol] as DragNodeDataObject).data; } } \ No newline at end of file diff --git a/packages/shell/src/dragon.ts b/packages/shell/src/dragon.ts index a1e4a4dab9..9832c7439f 100644 --- a/packages/shell/src/dragon.ts +++ b/packages/shell/src/dragon.ts @@ -1,29 +1,36 @@ import { Dragon as InnerDragon, - DragObject as InnerDragObject, - DragNodeDataObject, LocateEvent as InnerLocateEvent, } from '@alilc/lowcode-designer'; import { dragonSymbol } from './symbols'; import LocateEvent from './locate-event'; import DragObject from './drag-object'; +import { + IPublicModelDragon, + IPublicModelLocateEvent, + IPublicModelDragObject, + DragObject as InnerDragObject, + DragNodeDataObject, +} from '@alilc/lowcode-types'; -export default class Dragon { +export default class Dragon implements IPublicModelDragon { private readonly [dragonSymbol]: InnerDragon; constructor(dragon: InnerDragon) { this[dragonSymbol] = dragon; } - static create(dragon: InnerDragon | null) { - if (!dragon) return null; + static create(dragon: InnerDragon | null): IPublicModelDragon | null { + if (!dragon) { + return null; + } return new Dragon(dragon); } /** * is dragging or not */ - get dragging() { + get dragging(): boolean { return this[dragonSymbol].dragging; } @@ -32,7 +39,7 @@ export default class Dragon { * @param func * @returns */ - onDragstart(func: (e: LocateEvent) => any) { + onDragstart(func: (e: IPublicModelLocateEvent) => any): () => void { return this[dragonSymbol].onDragstart((e: InnerLocateEvent) => func(LocateEvent.create(e)!)); } @@ -41,7 +48,7 @@ export default class Dragon { * @param func * @returns */ - onDrag(func: (e: LocateEvent) => any) { + onDrag(func: (e: IPublicModelLocateEvent) => any): () => void { return this[dragonSymbol].onDrag((e: InnerLocateEvent) => func(LocateEvent.create(e)!)); } @@ -50,7 +57,7 @@ export default class Dragon { * @param func * @returns */ - onDragend(func: (o: { dragObject: DragObject; copy?: boolean }) => any) { + onDragend(func: (o: { dragObject: IPublicModelDragObject; copy?: boolean }) => any): () => void { return this[dragonSymbol].onDragend( (o: { dragObject: InnerDragObject; copy?: boolean }) => func({ dragObject: DragObject.create(o.dragObject)!, @@ -64,7 +71,7 @@ export default class Dragon { * @param shell 拖拽监听的区域 * @param boost 拖拽转换函数 */ - from(shell: Element, boost: (e: MouseEvent) => DragNodeDataObject | null) { + from(shell: Element, boost: (e: MouseEvent) => DragNodeDataObject | null): any { return this[dragonSymbol].from(shell, boost); } } diff --git a/packages/shell/src/drop-location.ts b/packages/shell/src/drop-location.ts index 14eff23edb..42e8a30df9 100644 --- a/packages/shell/src/drop-location.ts +++ b/packages/shell/src/drop-location.ts @@ -3,16 +3,19 @@ import { } from '@alilc/lowcode-designer'; import { dropLocationSymbol } from './symbols'; import Node from './node'; +import { IPublicModelDropLocation } from '@alilc/lowcode-types'; -export default class DropLocation { +export default class DropLocation implements IPublicModelDropLocation { private readonly [dropLocationSymbol]: InnerDropLocation; constructor(dropLocation: InnerDropLocation) { this[dropLocationSymbol] = dropLocation; } - static create(dropLocation: InnerDropLocation | null) { - if (!dropLocation) return null; + static create(dropLocation: InnerDropLocation | null): DropLocation | null { + if (!dropLocation) { + return null; + } return new DropLocation(dropLocation); } diff --git a/packages/shell/src/event.ts b/packages/shell/src/event.ts index cb2242229f..6d5a62829e 100644 --- a/packages/shell/src/event.ts +++ b/packages/shell/src/event.ts @@ -1,6 +1,7 @@ -import { Editor as InnerEditor, globalContext } from '@alilc/lowcode-editor-core'; +import { Editor as InnerEditor } from '@alilc/lowcode-editor-core'; import { getLogger } from '@alilc/lowcode-utils'; import { editorSymbol } from './symbols'; +import { IPublicApiEvent } from '@alilc/lowcode-types'; const logger = getLogger({ level: 'warn', bizName: 'shell:event' }); @@ -8,7 +9,7 @@ type EventOptions = { prefix: string; }; -export default class Event { +export default class Event implements IPublicApiEvent { private readonly [editorSymbol]: InnerEditor; private readonly options: EventOptions; diff --git a/packages/shell/src/history.ts b/packages/shell/src/history.ts index 267c7fd997..06945a2d69 100644 --- a/packages/shell/src/history.ts +++ b/packages/shell/src/history.ts @@ -1,7 +1,8 @@ -import { History as InnerHistory, DocumentModel as InnerDocumentModel } from '@alilc/lowcode-designer'; +import { DocumentModel as InnerDocumentModel } from '@alilc/lowcode-designer'; import { historySymbol, documentSymbol } from './symbols'; +import { IPublicModelHistory } from '@alilc/lowcode-types'; -export default class History { +export default class History implements IPublicModelHistory { private readonly [documentSymbol]: InnerDocumentModel; private get [historySymbol]() { @@ -16,28 +17,28 @@ export default class History { * 历史记录跳转到指定位置 * @param cursor */ - go(cursor: number) { + go(cursor: number): void { this[historySymbol].go(cursor); } /** * 历史记录后退 */ - back() { + back(): void { this[historySymbol].back(); } /** * 历史记录前进 */ - forward() { + forward(): void { this[historySymbol].forward(); } /** * 保存当前状态 */ - savePoint() { + savePoint(): void { this[historySymbol].savePoint(); } @@ -45,7 +46,7 @@ export default class History { * 当前是否是「保存点」,即是否有状态变更但未保存 * @returns */ - isSavePoint() { + isSavePoint(): boolean { return this[historySymbol].isSavePoint(); } @@ -53,7 +54,7 @@ export default class History { * 获取 state,判断当前是否为「可回退」、「可前进」的状态 * @returns */ - getState() { + getState(): any { return this[historySymbol].getState(); } @@ -62,7 +63,7 @@ export default class History { * @param func * @returns */ - onChangeState(func: () => any) { + onChangeState(func: () => any): () => void { return this[historySymbol].onStateChange(func); } @@ -71,7 +72,7 @@ export default class History { * @param func * @returns */ - onChangeCursor(func: () => any) { + onChangeCursor(func: () => any): () => void { return this[historySymbol].onCursor(func); } } diff --git a/packages/shell/src/hotkey.ts b/packages/shell/src/hotkey.ts index a60be7dd9b..728a8bcf00 100644 --- a/packages/shell/src/hotkey.ts +++ b/packages/shell/src/hotkey.ts @@ -1,7 +1,7 @@ -import { hotkey, HotkeyCallback } from '@alilc/lowcode-editor-core'; -import { Disposable } from '@alilc/lowcode-types'; +import { hotkey } from '@alilc/lowcode-editor-core'; +import { Disposable, HotkeyCallback, IPublicApiHotkey } from '@alilc/lowcode-types'; -export default class Hotkey { +export default class Hotkey implements IPublicApiHotkey { get callbacks() { return hotkey.callBacks; } diff --git a/packages/shell/src/locate-event.ts b/packages/shell/src/locate-event.ts index 01c97edaec..d6ca596eee 100644 --- a/packages/shell/src/locate-event.ts +++ b/packages/shell/src/locate-event.ts @@ -1,48 +1,51 @@ import { LocateEvent as InnerLocateEvent } from '@alilc/lowcode-designer'; import { locateEventSymbol } from './symbols'; import DragObject from './drag-object'; +import { IPublicModelLocateEvent, IPublicModelDragObject } from '@alilc/lowcode-types'; -export default class LocateEvent { +export default class LocateEvent implements IPublicModelLocateEvent { private readonly [locateEventSymbol]: InnerLocateEvent; constructor(locateEvent: InnerLocateEvent) { this[locateEventSymbol] = locateEvent; } - static create(locateEvent: InnerLocateEvent) { - if (!locateEvent) return null; + static create(locateEvent: InnerLocateEvent): IPublicModelLocateEvent | null { + if (!locateEvent) { + return null; + } return new LocateEvent(locateEvent); } - get type() { + get type(): string { return this[locateEventSymbol].type; } - get globalX() { + get globalX(): number { return this[locateEventSymbol].globalX; } - get globalY() { + get globalY(): number { return this[locateEventSymbol].globalY; } - get originalEvent() { + get originalEvent(): MouseEvent | DragEvent { return this[locateEventSymbol].originalEvent; } - get target() { + get target(): Element | null | undefined { return this[locateEventSymbol].target; } - get canvasX() { + get canvasX(): number | undefined { return this[locateEventSymbol].canvasX; } - get canvasY() { + get canvasY(): number | undefined { return this[locateEventSymbol].canvasY; } - get dragObject() { + get dragObject(): IPublicModelDragObject | null { return DragObject.create(this[locateEventSymbol].dragObject); } } \ No newline at end of file diff --git a/packages/shell/src/material.ts b/packages/shell/src/material.ts index 46b25beab5..7942065c7f 100644 --- a/packages/shell/src/material.ts +++ b/packages/shell/src/material.ts @@ -2,7 +2,6 @@ import { Editor } from '@alilc/lowcode-editor-core'; import { Designer, registerMetadataTransducer, - MetadataTransducer, getRegisteredMetadataTransducers, addBuiltinComponentAction, removeBuiltinComponentAction, @@ -10,11 +9,17 @@ import { isComponentMeta, } from '@alilc/lowcode-designer'; import { AssetsJson } from '@alilc/lowcode-utils'; -import { ComponentAction, ComponentMetadata } from '@alilc/lowcode-types'; +import { + ComponentAction, + ComponentMetadata, + IPublicApiMaterial, + MetadataTransducer, + IPublicModelComponentMeta, +} from '@alilc/lowcode-types'; import { editorSymbol, designerSymbol } from './symbols'; import ComponentMeta from './component-meta'; -export default class Material { +export default class Material implements IPublicApiMaterial { private readonly [editorSymbol]: Editor; private readonly [designerSymbol]: Designer; @@ -83,8 +88,9 @@ export default class Material { * @param componentName * @returns */ - getComponentMeta(componentName: string) { - return ComponentMeta.create(this[designerSymbol].getComponentMeta(componentName)); + getComponentMeta(componentName: string): IPublicModelComponentMeta | null { + const innerMeta = this[designerSymbol].getComponentMeta(componentName); + return ComponentMeta.create(innerMeta); } /** @@ -109,8 +115,8 @@ export default class Material { * 获取所有已注册的物料元数据 * @returns */ - getComponentMetasMap() { - const map = new Map(); + getComponentMetasMap(): Map { + const map = new Map(); const originalMap = this[designerSymbol].getComponentMetasMap(); for (let componentName of originalMap.keys()) { map.set(componentName, this.getComponentMeta(componentName)!); diff --git a/packages/shell/src/modal-nodes-manager.ts b/packages/shell/src/modal-nodes-manager.ts index 739ca9406d..4e556607a1 100644 --- a/packages/shell/src/modal-nodes-manager.ts +++ b/packages/shell/src/modal-nodes-manager.ts @@ -1,24 +1,28 @@ import { ModalNodesManager as InnerModalNodesManager, Node as InnerNode } from '@alilc/lowcode-designer'; -import { NodeSchema, NodeData, TransformStage } from '@alilc/lowcode-types'; +import { IPublicModelModalNodesManager, IPublicModelNode } from '@alilc/lowcode-types'; import Node from './node'; import { nodeSymbol, modalNodesManagerSymbol } from './symbols'; -export default class ModalNodesManager { +export default class ModalNodesManager implements IPublicModelModalNodesManager { private readonly [modalNodesManagerSymbol]: InnerModalNodesManager; constructor(modalNodesManager: InnerModalNodesManager) { this[modalNodesManagerSymbol] = modalNodesManager; } - static create(modalNodesManager: InnerModalNodesManager | null) { - if (!modalNodesManager) return null; + static create( + modalNodesManager: InnerModalNodesManager | null, + ): IPublicModelModalNodesManager | null { + if (!modalNodesManager) { + return null; + } return new ModalNodesManager(modalNodesManager); } /** * 设置模态节点,触发内部事件 */ - setNodes() { + setNodes(): void { this[modalNodesManagerSymbol].setNodes(); } @@ -26,7 +30,7 @@ export default class ModalNodesManager { * 获取模态节点(们) * @returns */ - getModalNodes() { + getModalNodes(): any { return this[modalNodesManagerSymbol].getModalNodes().map((node) => Node.create(node)); } @@ -34,14 +38,14 @@ export default class ModalNodesManager { * 获取当前可见的模态节点 * @returns */ - getVisibleModalNode() { + getVisibleModalNode(): any { return Node.create(this[modalNodesManagerSymbol].getVisibleModalNode()); } /** * 隐藏模态节点(们) */ - hideModalNodes() { + hideModalNodes(): void { this[modalNodesManagerSymbol].hideModalNodes(); } @@ -49,7 +53,7 @@ export default class ModalNodesManager { * 设置指定节点为可见态 * @param node Node */ - setVisible(node: Node) { + setVisible(node: IPublicModelNode): void { this[modalNodesManagerSymbol].setVisible(node[nodeSymbol]); } @@ -57,7 +61,7 @@ export default class ModalNodesManager { * 设置指定节点为不可见态 * @param node Node */ - setInvisible(node: Node) { + setInvisible(node: IPublicModelNode): void { this[modalNodesManagerSymbol].setInvisible(node[nodeSymbol]); } } \ No newline at end of file diff --git a/packages/shell/src/node-children.ts b/packages/shell/src/node-children.ts index 2557e37acb..9ff2f93b61 100644 --- a/packages/shell/src/node-children.ts +++ b/packages/shell/src/node-children.ts @@ -1,31 +1,33 @@ import { NodeChildren as InnerNodeChildren, Node as InnerNode } from '@alilc/lowcode-designer'; -import { NodeSchema, NodeData, TransformStage } from '@alilc/lowcode-types'; +import { NodeSchema, NodeData, TransformStage, IPublicModelNodeChildren, IPublicModelNode } from '@alilc/lowcode-types'; import Node from './node'; import { nodeSymbol, nodeChildrenSymbol } from './symbols'; -export default class NodeChildren { +export default class NodeChildren implements IPublicModelNodeChildren { private readonly [nodeChildrenSymbol]: InnerNodeChildren; constructor(nodeChildren: InnerNodeChildren) { this[nodeChildrenSymbol] = nodeChildren; } - static create(nodeChldren: InnerNodeChildren | null) { - if (!nodeChldren) return null; + static create(nodeChldren: InnerNodeChildren | null): IPublicModelNodeChildren | null { + if (!nodeChldren) { + return null; + } return new NodeChildren(nodeChldren); } /** * 返回当前 children 实例所属的节点实例 */ - get owner(): Node | null { + get owner(): IPublicModelNode | null { return Node.create(this[nodeChildrenSymbol].owner); } /** * children 内的节点实例数 */ - get size() { + get size(): number { return this[nodeChildrenSymbol].size; } @@ -33,14 +35,14 @@ export default class NodeChildren { * 是否为空 * @returns */ - get isEmpty() { + get isEmpty(): boolean { return this[nodeChildrenSymbol].isEmpty(); } /** * judge if it is not empty */ - get notEmpty() { + get notEmpty(): boolean { return !this.isEmpty; } @@ -49,8 +51,8 @@ export default class NodeChildren { * @param node * @returns */ - delete(node: Node) { - return this[nodeChildrenSymbol].delete(node[nodeSymbol]); + delete(node: IPublicModelNode): boolean { + return this[nodeChildrenSymbol].delete((node as any)[nodeSymbol]); } /** @@ -59,8 +61,8 @@ export default class NodeChildren { * @param at 插入下标 * @returns */ - insert(node: Node, at?: number | null) { - return this[nodeChildrenSymbol].insert(node[nodeSymbol], at, true); + insert(node: IPublicModelNode, at?: number | null): void { + return this[nodeChildrenSymbol].insert((node as any)[nodeSymbol], at, true); } /** @@ -68,8 +70,8 @@ export default class NodeChildren { * @param node * @returns */ - indexOf(node: Node) { - return this[nodeChildrenSymbol].indexOf(node[nodeSymbol]); + indexOf(node: IPublicModelNode): number { + return this[nodeChildrenSymbol].indexOf((node as any)[nodeSymbol]); } /** @@ -78,8 +80,8 @@ export default class NodeChildren { * @param deleteCount * @param node */ - splice(start: number, deleteCount: number, node?: Node) { - this[nodeChildrenSymbol].splice(start, deleteCount, node?.[nodeSymbol]); + splice(start: number, deleteCount: number, node?: IPublicModelNode): any { + this[nodeChildrenSymbol].splice(start, deleteCount, (node as any)?.[nodeSymbol]); } /** @@ -87,7 +89,7 @@ export default class NodeChildren { * @param index * @returns */ - get(index: number) { + get(index: number): any { return Node.create(this[nodeChildrenSymbol].get(index)); } @@ -96,15 +98,15 @@ export default class NodeChildren { * @param node * @returns */ - has(node: Node) { - return this[nodeChildrenSymbol].has(node[nodeSymbol]); + has(node: IPublicModelNode): boolean { + return this[nodeChildrenSymbol].has((node as any)[nodeSymbol]); } /** * 类似数组的 forEach * @param fn */ - forEach(fn: (node: Node, index: number) => void) { + forEach(fn: (node: IPublicModelNode, index: number) => void): void { this[nodeChildrenSymbol].forEach((item: InnerNode, index: number) => { fn(Node.create(item)!, index); }); @@ -114,7 +116,7 @@ export default class NodeChildren { * 类似数组的 map * @param fn */ - map(fn: (node: Node, index: number) => T[]) { + map(fn: (node: IPublicModelNode, index: number) => T[]): any[] | null { return this[nodeChildrenSymbol].map((item: InnerNode, index: number) => { return fn(Node.create(item)!, index); }); @@ -124,7 +126,7 @@ export default class NodeChildren { * 类似数组的 every * @param fn */ - every(fn: (node: Node, index: number) => boolean) { + every(fn: (node: IPublicModelNode, index: number) => boolean): boolean { return this[nodeChildrenSymbol].every((item: InnerNode, index: number) => { return fn(Node.create(item)!, index); }); @@ -134,7 +136,7 @@ export default class NodeChildren { * 类似数组的 some * @param fn */ - some(fn: (node: Node, index: number) => boolean) { + some(fn: (node: IPublicModelNode, index: number) => boolean): boolean { return this[nodeChildrenSymbol].some((item: InnerNode, index: number) => { return fn(Node.create(item)!, index); }); @@ -144,7 +146,7 @@ export default class NodeChildren { * 类似数组的 filter * @param fn */ - filter(fn: (node: Node, index: number) => boolean) { + filter(fn: (node: IPublicModelNode, index: number) => boolean): any { return this[nodeChildrenSymbol] .filter((item: InnerNode, index: number) => { return fn(Node.create(item)!, index); @@ -156,7 +158,7 @@ export default class NodeChildren { * 类似数组的 find * @param fn */ - find(fn: (node: Node, index: number) => boolean) { + find(fn: (node: IPublicModelNode, index: number) => boolean): IPublicModelNode | null { return Node.create( this[nodeChildrenSymbol].find((item: InnerNode, index: number) => { return fn(Node.create(item)!, index); @@ -168,7 +170,7 @@ export default class NodeChildren { * 类似数组的 reduce * @param fn */ - reduce(fn: (acc: any, cur: Node) => any, initialValue: any) { + reduce(fn: (acc: any, cur: IPublicModelNode) => any, initialValue: any): void { return this[nodeChildrenSymbol].reduce((acc: any, cur: InnerNode) => { return fn(acc, Node.create(cur)!); }, initialValue); @@ -178,7 +180,7 @@ export default class NodeChildren { * 导入 schema * @param data */ - importSchema(data?: NodeData | NodeData[]) { + importSchema(data?: NodeData | NodeData[]): void { this[nodeChildrenSymbol].import(data); } @@ -187,7 +189,7 @@ export default class NodeChildren { * @param stage * @returns */ - exportSchema(stage: TransformStage = TransformStage.Render) { + exportSchema(stage: TransformStage = TransformStage.Render): any { return this[nodeChildrenSymbol].export(stage); } @@ -198,9 +200,9 @@ export default class NodeChildren { * @param sorter */ mergeChildren( - remover: (node: Node, idx: number) => boolean, - adder: (children: Node[]) => any, - sorter: (firstNode: Node, secondNode: Node) => number, + remover: (node: IPublicModelNode, idx: number) => boolean, + adder: (children: IPublicModelNode[]) => any, + sorter: (firstNode: IPublicModelNode, secondNode: IPublicModelNode) => number, ) { if (!sorter) { sorter = () => 0; diff --git a/packages/shell/src/node.ts b/packages/shell/src/node.ts index e12551b0c9..34faf5f57a 100644 --- a/packages/shell/src/node.ts +++ b/packages/shell/src/node.ts @@ -1,9 +1,23 @@ import { DocumentModel as InnerDocumentModel, Node as InnerNode, - getConvertedExtraKey, } from '@alilc/lowcode-designer'; -import { CompositeValue, NodeSchema, TransformStage } from '@alilc/lowcode-types'; +import { + CompositeValue, + NodeSchema, + TransformStage, + IPublicModelNode, + IconType, + I18nData, + IPublicModelComponentMeta, + IPublicModelDocumentModel, + IPublicModelNodeChildren, + IPublicModelProp, + IPublicModelProps, + PropsMap, + PropsList, + IPublicModelSettingTopEntry, +} from '@alilc/lowcode-types'; import Prop from './prop'; import Props from './props'; import DocumentModel from './document-model'; @@ -11,10 +25,11 @@ import NodeChildren from './node-children'; import ComponentMeta from './component-meta'; import SettingTopEntry from './setting-top-entry'; import { documentSymbol, nodeSymbol } from './symbols'; +import { ReactElement } from 'react'; const shellNodeSymbol = Symbol('shellNodeSymbol'); -export default class Node { +export default class Node implements IPublicModelNode { private readonly [documentSymbol]: InnerDocumentModel; private readonly [nodeSymbol]: InnerNode; @@ -27,10 +42,14 @@ export default class Node { this._id = this[nodeSymbol].id; } - static create(node: InnerNode | null | undefined) { - if (!node) return null; + static create(node: InnerNode | null | undefined): IPublicModelNode | null { + if (!node) { + return null; + } // @ts-ignore 直接返回已挂载的 shell node 实例 - if (node[shellNodeSymbol]) return node[shellNodeSymbol]; + if (node[shellNodeSymbol]) { + return (node as any)[shellNodeSymbol]; + } const shellNode = new Node(node); // @ts-ignore 挂载 shell node 实例 node[shellNodeSymbol] = shellNode; @@ -54,70 +73,70 @@ export default class Node { /** * 节点标题 */ - get title() { + get title(): string | I18nData | ReactElement { return this[nodeSymbol].title; } /** * 是否为「容器型」节点 */ - get isContainer() { + get isContainer(): boolean { return this[nodeSymbol].isContainer(); } /** * 是否为根节点 */ - get isRoot() { + get isRoot(): boolean { return this[nodeSymbol].isRoot(); } /** * 是否为空节点(无 children 或者 children 为空) */ - get isEmpty() { + get isEmpty(): boolean { return this[nodeSymbol].isEmpty(); } /** * 是否为 Page 节点 */ - get isPage() { + get isPage(): boolean { return this[nodeSymbol].isPage(); } /** * 是否为 Component 节点 */ - get isComponent() { + get isComponent(): boolean { return this[nodeSymbol].isComponent(); } /** * 是否为「模态框」节点 */ - get isModal() { + get isModal(): boolean { return this[nodeSymbol].isModal(); } /** * 是否为插槽节点 */ - get isSlot() { + get isSlot(): boolean { return this[nodeSymbol].isSlot(); } /** * 是否为父类/分支节点 */ - get isParental() { + get isParental(): boolean { return this[nodeSymbol].isParental(); } /** * 是否为叶子节点 */ - get isLeaf() { + get isLeaf(): boolean { return this[nodeSymbol].isLeaf(); } @@ -129,7 +148,7 @@ export default class Node { /** * 获取当前节点的锁定状态 */ - get isLocked() { + get isLocked(): boolean { return this[nodeSymbol].isLocked; } @@ -143,28 +162,28 @@ export default class Node { /** * 图标 */ - get icon() { + get icon(): IconType { return this[nodeSymbol].icon; } /** * 节点所在树的层级深度,根节点深度为 0 */ - get zLevel() { + get zLevel(): number { return this[nodeSymbol].zLevel; } /** * 节点 componentName */ - get componentName() { + get componentName(): string { return this[nodeSymbol].componentName; } /** * 节点的物料元数据 */ - get componentMeta() { + get componentMeta(): IPublicModelComponentMeta | null { return ComponentMeta.create(this[nodeSymbol].componentMeta); } @@ -172,7 +191,7 @@ export default class Node { * 获取节点所属的文档模型对象 * @returns */ - get document() { + get document(): IPublicModelDocumentModel | null { return DocumentModel.create(this[documentSymbol]); } @@ -180,7 +199,7 @@ export default class Node { * 获取当前节点的前一个兄弟节点 * @returns */ - get prevSibling(): Node | null { + get prevSibling(): IPublicModelNode | null { return Node.create(this[nodeSymbol].prevSibling); } @@ -188,7 +207,7 @@ export default class Node { * 获取当前节点的后一个兄弟节点 * @returns */ - get nextSibling(): Node | null { + get nextSibling(): IPublicModelNode | null { return Node.create(this[nodeSymbol].nextSibling); } @@ -196,7 +215,7 @@ export default class Node { * 获取当前节点的父亲节点 * @returns */ - get parent(): Node | null { + get parent(): IPublicModelNode | null { return Node.create(this[nodeSymbol].parent); } @@ -204,46 +223,46 @@ export default class Node { * 获取当前节点的孩子节点模型 * @returns */ - get children() { + get children(): IPublicModelNodeChildren | null { return NodeChildren.create(this[nodeSymbol].children); } /** * 节点上挂载的插槽节点们 */ - get slots(): Node[] { + get slots(): IPublicModelNode[] { return this[nodeSymbol].slots.map((node: InnerNode) => Node.create(node)!); } /** * 当前节点为插槽节点时,返回节点对应的属性实例 */ - get slotFor() { + get slotFor(): IPublicModelProp | null { return Prop.create(this[nodeSymbol].slotFor); } /** * 返回节点的属性集 */ - get props() { + get props(): IPublicModelProps | null { return Props.create(this[nodeSymbol].props); } /** * 返回节点的属性集 */ - get propsData() { + get propsData(): PropsMap | PropsList | null { return this[nodeSymbol].propsData; } /** - * 获取符合搭建协议-节点 schema 结构 + * 获取符合搭建协议 - 节点 schema 结构 */ - get schema(): any { + get schema(): NodeSchema { return this[nodeSymbol].schema; } - get settingEntry(): any { + get settingEntry(): IPublicModelSettingTopEntry { return SettingTopEntry.create(this[nodeSymbol].settingEntry as any); } @@ -256,6 +275,7 @@ export default class Node { /** * 获取节点实例对应的 dom 节点 + * @deprecated */ getDOMNode() { return this[nodeSymbol].getDOMNode(); @@ -268,10 +288,10 @@ export default class Node { * @param sorter */ mergeChildren( - remover: (node: Node, idx: number) => boolean, - adder: (children: Node[]) => any, - sorter: (firstNode: Node, secondNode: Node) => number, - ) { + remover: (node: IPublicModelNode, idx: number) => boolean, + adder: (children: IPublicModelNode[]) => any, + sorter: (firstNode: IPublicModelNode, secondNode: IPublicModelNode) => number, + ): any { return this.children?.mergeChildren(remover, adder, sorter); } @@ -279,7 +299,7 @@ export default class Node { * 返回节点的尺寸、位置信息 * @returns */ - getRect() { + getRect(): DOMRect | null { return this[nodeSymbol].getRect(); } @@ -287,7 +307,7 @@ export default class Node { * 是否有挂载插槽节点 * @returns */ - hasSlots() { + hasSlots(): boolean { return this[nodeSymbol].hasSlots(); } @@ -295,7 +315,7 @@ export default class Node { * 是否设定了渲染条件 * @returns */ - hasCondition() { + hasCondition(): boolean { return this[nodeSymbol].hasCondition(); } @@ -303,19 +323,19 @@ export default class Node { * 是否设定了循环数据 * @returns */ - hasLoop() { + hasLoop(): boolean { return this[nodeSymbol].hasLoop(); } - getVisible() { + getVisible(): boolean { return this[nodeSymbol].getVisible(); } - setVisible(flag: boolean) { + setVisible(flag: boolean): void { this[nodeSymbol].setVisible(flag); } - isConditionalVisible() { + isConditionalVisible(): boolean | undefined { return this[nodeSymbol].isConditionalVisible(); } @@ -323,7 +343,7 @@ export default class Node { * 设置节点锁定状态 * @param flag */ - lock(flag?: boolean) { + lock(flag?: boolean): void { this[nodeSymbol].lock(flag); } @@ -334,8 +354,8 @@ export default class Node { return this.props; } - contains(node: Node) { - return this[nodeSymbol].contains(node[nodeSymbol]); + contains(node: IPublicModelNode): boolean { + return this[nodeSymbol].contains((node as any)[nodeSymbol]); } /** @@ -343,7 +363,7 @@ export default class Node { * @param path 属性路径,支持 a / a.b / a.0 等格式 * @returns */ - getProp(path: string, createIfNone = true): Prop | null { + getProp(path: string, createIfNone = true): IPublicModelProp | null { return Prop.create(this[nodeSymbol].getProp(path, createIfNone)); } @@ -363,7 +383,7 @@ export default class Node { * @param createIfNone 当没有属性的时候,是否创建一个属性 * @returns */ - getExtraProp(path: string, createIfNone?: boolean): Prop | null { + getExtraProp(path: string, createIfNone?: boolean): IPublicModelProp | null { return Prop.create(this[nodeSymbol].getExtraProp(path, createIfNone)); } @@ -373,7 +393,7 @@ export default class Node { * @param path 属性路径,支持 a / a.b / a.0 等格式 * @returns */ - getExtraPropValue(path: string) { + getExtraPropValue(path: string): any { return this.getExtraProp(path)?.getValue(); } @@ -383,7 +403,7 @@ export default class Node { * @param value 值 * @returns */ - setPropValue(path: string, value: CompositeValue) { + setPropValue(path: string, value: CompositeValue): void { return this.getProp(path)?.setValue(value); } @@ -393,7 +413,7 @@ export default class Node { * @param value 值 * @returns */ - setExtraPropValue(path: string, value: CompositeValue) { + setExtraPropValue(path: string, value: CompositeValue): void { return this.getExtraProp(path)?.setValue(value); } @@ -401,7 +421,7 @@ export default class Node { * 导入节点数据 * @param data */ - importSchema(data: NodeSchema) { + importSchema(data: NodeSchema): void { this[nodeSymbol].import(data); } @@ -411,7 +431,7 @@ export default class Node { * @param options * @returns */ - exportSchema(stage: TransformStage = TransformStage.Render, options?: any) { + exportSchema(stage: TransformStage = TransformStage.Render, options?: any): NodeSchema { return this[nodeSymbol].export(stage, options); } @@ -421,8 +441,16 @@ export default class Node { * @param ref * @param useMutator */ - insertBefore(node: Node, ref?: Node | undefined, useMutator?: boolean) { - this[nodeSymbol].insertBefore(node[nodeSymbol] || node, ref?.[nodeSymbol], useMutator); + insertBefore( + node: IPublicModelNode, + ref?: IPublicModelNode | undefined, + useMutator?: boolean, + ): void { + this[nodeSymbol].insertBefore( + (node as any)[nodeSymbol] || node, + (ref as any)?.[nodeSymbol], + useMutator, + ); } /** @@ -431,8 +459,16 @@ export default class Node { * @param ref * @param useMutator */ - insertAfter(node: Node, ref?: Node | undefined, useMutator?: boolean) { - this[nodeSymbol].insertAfter(node[nodeSymbol] || node, ref?.[nodeSymbol], useMutator); + insertAfter( + node: IPublicModelNode, + ref?: IPublicModelNode | undefined, + useMutator?: boolean, + ): void { + this[nodeSymbol].insertAfter( + (node as any)[nodeSymbol] || node, + (ref as any)?.[nodeSymbol], + useMutator, + ); } /** @@ -441,22 +477,22 @@ export default class Node { * @param data 用作替换的节点对象或者节点描述 * @returns */ - replaceChild(node: Node, data: any) { - return Node.create(this[nodeSymbol].replaceChild(node[nodeSymbol], data)); + replaceChild(node: IPublicModelNode, data: any): IPublicModelNode | null { + return Node.create(this[nodeSymbol].replaceChild((node as any)[nodeSymbol], data)); } /** * 将当前节点替换成指定节点描述 * @param schema */ - replaceWith(schema: NodeSchema) { + replaceWith(schema: NodeSchema): any { this[nodeSymbol].replaceWith(schema); } /** * 选中当前节点实例 */ - select() { + select(): void { this[nodeSymbol].select(); } @@ -464,14 +500,14 @@ export default class Node { * 设置悬停态 * @param flag */ - hover(flag = true) { + hover(flag = true): void { this[nodeSymbol].hover(flag); } /** * 删除当前节点实例 */ - remove() { + remove(): void { this[nodeSymbol].remove(); } /** diff --git a/packages/shell/src/project.ts b/packages/shell/src/project.ts index 0bf5555713..752518079c 100644 --- a/packages/shell/src/project.ts +++ b/packages/shell/src/project.ts @@ -1,15 +1,22 @@ import { BuiltinSimulatorHost, Project as InnerProject, - PropsReducer as PropsTransducer, TransformStage, } from '@alilc/lowcode-designer'; -import { RootSchema, ProjectSchema, IEditor } from '@alilc/lowcode-types'; +import { + RootSchema, + ProjectSchema, + IEditor, + IPublicApiProject, + IPublicApiSimulatorHost, + IPublicModelDocumentModel, + PropsTransducer, +} from '@alilc/lowcode-types'; import DocumentModel from './document-model'; import SimulatorHost from './simulator-host'; import { editorSymbol, projectSymbol, simulatorHostSymbol, simulatorRendererSymbol, documentSymbol } from './symbols'; -export default class Project { +export default class Project implements IPublicApiProject { private readonly [projectSymbol]: InnerProject; private readonly [editorSymbol]: IEditor; private [simulatorHostSymbol]: BuiltinSimulatorHost; @@ -28,7 +35,7 @@ export default class Project { * 获取当前的 document * @returns */ - get currentDocument(): DocumentModel | null { + get currentDocument(): IPublicModelDocumentModel | null { return this.getCurrentDocument(); } @@ -36,14 +43,14 @@ export default class Project { * 获取当前 project 下所有 documents * @returns */ - get documents(): DocumentModel[] { + get documents(): IPublicModelDocumentModel[] { return this[projectSymbol].documents.map((doc) => DocumentModel.create(doc)!); } /** * 获取模拟器的 host */ - get simulatorHost() { + get simulatorHost(): IPublicApiSimulatorHost | null { return SimulatorHost.create(this[projectSymbol].simulator as any || this[simulatorHostSymbol]); } @@ -70,7 +77,7 @@ export default class Project { * @param data * @returns */ - createDocument(data?: RootSchema): DocumentModel | null { + createDocument(data?: RootSchema): IPublicModelDocumentModel | null { const doc = this[projectSymbol].createDocument(data); return DocumentModel.create(doc); } @@ -79,8 +86,8 @@ export default class Project { * 删除一个 document * @param doc */ - removeDocument(doc: DocumentModel) { - this[projectSymbol].removeDocument(doc[documentSymbol]); + removeDocument(doc: IPublicModelDocumentModel) { + this[projectSymbol].removeDocument((doc as any)[documentSymbol]); } /** @@ -88,7 +95,7 @@ export default class Project { * @param fileName * @returns */ - getDocumentByFileName(fileName: string): DocumentModel | null { + getDocumentByFileName(fileName: string): IPublicModelDocumentModel | null { return DocumentModel.create(this[projectSymbol].getDocumentByFileName(fileName)); } @@ -97,7 +104,7 @@ export default class Project { * @param id * @returns */ - getDocumentById(id: string): DocumentModel | null { + getDocumentById(id: string): IPublicModelDocumentModel | null { return DocumentModel.create(this[projectSymbol].getDocument(id)); } @@ -113,7 +120,7 @@ export default class Project { * 导入 project * @param schema 待导入的 project 数据 */ - importSchema(schema?: ProjectSchema) { + importSchema(schema?: ProjectSchema): void { this[projectSymbol].load(schema, true); } @@ -121,7 +128,7 @@ export default class Project { * 获取当前的 document * @returns */ - getCurrentDocument(): DocumentModel | null { + getCurrentDocument(): IPublicModelDocumentModel | null { return DocumentModel.create(this[projectSymbol].currentDocument); } @@ -130,7 +137,7 @@ export default class Project { * @param transducer * @param stage */ - addPropsTransducer(transducer: PropsTransducer, stage: TransformStage) { + addPropsTransducer(transducer: PropsTransducer, stage: TransformStage): void { this[projectSymbol].designer.addPropsReducer(transducer, stage); } @@ -139,14 +146,14 @@ export default class Project { * @param fn * @returns */ - onRemoveDocument(fn: (data: { id: string}) => void) { + onRemoveDocument(fn: (data: { id: string}) => void): any { return this[editorSymbol].on('designer.document.remove', (data: { id: string }) => fn(data)); } /** * 当前 project 内的 document 变更事件 */ - onChangeDocument(fn: (doc: DocumentModel) => void) { + onChangeDocument(fn: (doc: IPublicModelDocumentModel) => void) { const offFn = this[projectSymbol].onCurrentDocumentChange((originalDoc) => { fn(DocumentModel.create(originalDoc)!); }); @@ -159,7 +166,7 @@ export default class Project { /** * 当前 project 的模拟器 ready 事件 */ - onSimulatorHostReady(fn: (host: SimulatorHost) => void) { + onSimulatorHostReady(fn: (host: IPublicApiSimulatorHost) => void) { const offFn = this[projectSymbol].onSimulatorReady((simulator: BuiltinSimulatorHost) => { this[simulatorHostSymbol] = simulator; fn(SimulatorHost.create(simulator)!); diff --git a/packages/shell/src/prop.ts b/packages/shell/src/prop.ts index b386d05930..8cb6c9cdac 100644 --- a/packages/shell/src/prop.ts +++ b/packages/shell/src/prop.ts @@ -1,65 +1,69 @@ import { Prop as InnerProp } from '@alilc/lowcode-designer'; -import { CompositeValue, TransformStage } from '@alilc/lowcode-types'; +import { CompositeValue, TransformStage, IPublicModelProp, IPublicModelNode } from '@alilc/lowcode-types'; import { propSymbol } from './symbols'; import Node from './node'; -export default class Prop { +export default class Prop implements IPublicModelProp { private readonly [propSymbol]: InnerProp; constructor(prop: InnerProp) { this[propSymbol] = prop; } - static create(prop: InnerProp | undefined | null) { - if (!prop) return null; + static create(prop: InnerProp | undefined | null): IPublicModelProp | null { + if (!prop) { + return null; + } return new Prop(prop); } /** * id */ - get id() { + get id(): string { return this[propSymbol].id; } /** * key 值 */ - get key() { + get key(): string | number | undefined { return this[propSymbol].key; } /** * 返回当前 prop 的路径 */ - get path() { + get path(): any[] { return this[propSymbol].path; } /** * 返回所属的节点实例 */ - get node(): Node | null { + get node(): IPublicModelNode | null { return Node.create(this[propSymbol].getNode()); } /** * return the slot node (only if the current prop represents a slot) */ - get slotNode(): Node | null { + get slotNode(): IPublicModelNode | null { return Node.create(this[propSymbol].slotNode); } /** * judge if it is a prop or not */ - get isProp() { return true; } + get isProp(): boolean { + return true; + } /** * 设置值 * @param val */ - setValue(val: CompositeValue) { + setValue(val: CompositeValue): void { this[propSymbol].setValue(val); } @@ -67,14 +71,14 @@ export default class Prop { * 获取值 * @returns */ - getValue() { + getValue(): any { return this[propSymbol].getValue(); } /** * 移除值 */ - remove() { + remove(): void { this[propSymbol].remove(); } diff --git a/packages/shell/src/props.ts b/packages/shell/src/props.ts index 293fa60df8..10bcfaba24 100644 --- a/packages/shell/src/props.ts +++ b/packages/shell/src/props.ts @@ -1,39 +1,41 @@ import { Props as InnerProps, getConvertedExtraKey } from '@alilc/lowcode-designer'; -import { CompositeValue, TransformStage } from '@alilc/lowcode-types'; +import { CompositeValue, IPublicModelProps, IPublicModelNode, IPublicModelProp } from '@alilc/lowcode-types'; import { propsSymbol } from './symbols'; import Node from './node'; import Prop from './prop'; -export default class Props { +export default class Props implements IPublicModelProps { private readonly [propsSymbol]: InnerProps; constructor(props: InnerProps) { this[propsSymbol] = props; } - static create(props: InnerProps | undefined | null) { - if (!props) return null; + static create(props: InnerProps | undefined | null): IPublicModelProps | null { + if (!props) { + return null; + } return new Props(props); } /** * id */ - get id() { + get id(): string { return this[propsSymbol].id; } /** * 返回当前 props 的路径 */ - get path() { + get path(): any[] { return this[propsSymbol].path; } /** * 返回所属的 node 实例 */ - get node(): Node | null { + get node(): IPublicModelNode | null { return Node.create(this[propsSymbol].getNode()); } @@ -42,7 +44,7 @@ export default class Props { * @param path 属性路径,支持 a / a.b / a.0 等格式 * @returns */ - getProp(path: string): Prop | null { + getProp(path: string): IPublicModelProp | null { return Prop.create(this[propsSymbol].getProp(path)); } @@ -51,7 +53,7 @@ export default class Props { * @param path 属性路径,支持 a / a.b / a.0 等格式 * @returns */ - getPropValue(path: string) { + getPropValue(path: string): any { return this.getProp(path)?.getValue(); } @@ -61,7 +63,7 @@ export default class Props { * @param path 属性路径,支持 a / a.b / a.0 等格式 * @returns */ - getExtraProp(path: string): Prop | null { + getExtraProp(path: string): IPublicModelProp | null { return Prop.create(this[propsSymbol].getProp(getConvertedExtraKey(path))); } @@ -71,7 +73,7 @@ export default class Props { * @param path 属性路径,支持 a / a.b / a.0 等格式 * @returns */ - getExtraPropValue(path: string) { + getExtraPropValue(path: string): any { return this.getExtraProp(path)?.getValue(); } @@ -81,7 +83,7 @@ export default class Props { * @param value 值 * @returns */ - setPropValue(path: string, value: CompositeValue) { + setPropValue(path: string, value: CompositeValue): void { return this.getProp(path)?.setValue(value); } @@ -91,7 +93,7 @@ export default class Props { * @param value 值 * @returns */ - setExtraPropValue(path: string, value: CompositeValue) { + setExtraPropValue(path: string, value: CompositeValue): void { return this.getExtraProp(path)?.setValue(value); } @@ -100,7 +102,7 @@ export default class Props { * @param key * @returns */ - has(key: string) { + has(key: string): boolean { return this[propsSymbol].has(key); } @@ -110,7 +112,7 @@ export default class Props { * @param key * @returns */ - add(value: CompositeValue, key?: string | number | undefined) { + add(value: CompositeValue, key?: string | number | undefined): any { return this[propsSymbol].add(value, key); } } \ No newline at end of file diff --git a/packages/shell/src/selection.ts b/packages/shell/src/selection.ts index b5b9e7a160..43d2c3cccc 100644 --- a/packages/shell/src/selection.ts +++ b/packages/shell/src/selection.ts @@ -4,14 +4,13 @@ import { Selection as InnerSelection, } from '@alilc/lowcode-designer'; import Node from './node'; -import { documentSymbol, selectionSymbol } from './symbols'; +import { selectionSymbol } from './symbols'; +import { IPublicModelSelection, IPublicModelNode } from '@alilc/lowcode-types'; -export default class Selection { - private readonly [documentSymbol]: InnerDocumentModel; +export default class Selection implements IPublicModelSelection { private readonly [selectionSymbol]: InnerSelection; constructor(document: InnerDocumentModel) { - this[documentSymbol] = document; this[selectionSymbol] = document.selection; } @@ -25,15 +24,16 @@ export default class Selection { /** * return selected Node instance */ - get node(): Node { - return this.getNodes()[0]; + get node(): IPublicModelNode | null { + const nodes = this.getNodes(); + return nodes && nodes.length > 0 ? nodes[0] : null; } /** * 选中指定节点(覆盖方式) * @param id */ - select(id: string) { + select(id: string): void { this[selectionSymbol].select(id); } @@ -41,7 +41,7 @@ export default class Selection { * 批量选中指定节点们 * @param ids */ - selectAll(ids: string[]) { + selectAll(ids: string[]): void { this[selectionSymbol].selectAll(ids); } @@ -49,14 +49,14 @@ export default class Selection { * 移除选中的指定节点 * @param id */ - remove(id: string) { + remove(id: string): void { this[selectionSymbol].remove(id); } /** * 清除所有选中节点 */ - clear() { + clear(): void { this[selectionSymbol].clear(); } @@ -65,7 +65,7 @@ export default class Selection { * @param id * @returns */ - has(id: string) { + has(id: string): boolean { return this[selectionSymbol].has(id); } @@ -73,7 +73,7 @@ export default class Selection { * 选中指定节点(增量方式) * @param id */ - add(id: string) { + add(id: string): void { this[selectionSymbol].add(id); } @@ -81,7 +81,7 @@ export default class Selection { * 获取选中的节点实例 * @returns */ - getNodes(): Node[] { + getNodes(): Array { return this[selectionSymbol].getNodes().map((node: InnerNode) => Node.create(node)); } @@ -92,7 +92,7 @@ export default class Selection { * getTopNodes() will return [A, B], subA will be removed * @returns */ - getTopNodes(): Node[] { + getTopNodes(): Array { return this[selectionSymbol].getTopNodes().map((node: InnerNode) => Node.create(node)); } } diff --git a/packages/shell/src/setters.ts b/packages/shell/src/setters.ts index 000213883a..90290f457d 100644 --- a/packages/shell/src/setters.ts +++ b/packages/shell/src/setters.ts @@ -1,13 +1,13 @@ -import { getSetter, registerSetter, getSettersMap, RegisteredSetter } from '@alilc/lowcode-editor-core'; -import { CustomView } from '@alilc/lowcode-types'; +import { getSetter, registerSetter, getSettersMap } from '@alilc/lowcode-editor-core'; +import { CustomView, IPublicApiSetters, RegisteredSetter } from '@alilc/lowcode-types'; -export default class Setters { +export default class Setters implements IPublicApiSetters { /** * 获取指定 setter * @param type * @returns */ - getSetter(type: string) { + getSetter(type: string): RegisteredSetter | null { return getSetter(type); } @@ -15,7 +15,9 @@ export default class Setters { * 获取已注册的所有 settersMap * @returns */ - getSettersMap() { + getSettersMap(): Map { return getSettersMap(); } diff --git a/packages/shell/src/setting-prop-entry.ts b/packages/shell/src/setting-prop-entry.ts index 2c2bb6ce6a..ad07aa9632 100644 --- a/packages/shell/src/setting-prop-entry.ts +++ b/packages/shell/src/setting-prop-entry.ts @@ -1,106 +1,118 @@ -import { SettingField, ISetValueOptions } from '@alilc/lowcode-designer'; -import { CompositeValue, FieldConfig, CustomView, isCustomView } from '@alilc/lowcode-types'; +import { SettingField, SettingEntry } from '@alilc/lowcode-designer'; +import { + CompositeValue, + FieldConfig, + CustomView, + IPublicModelSettingPropEntry, + SetterType, + FieldExtraProps, + IPublicModelSettingTopEntry, + IPublicModelNode, + IPublicModelComponentMeta, + ISetValueOptions, +} from '@alilc/lowcode-types'; import { settingPropEntrySymbol } from './symbols'; import Node from './node'; import SettingTopEntry from './setting-top-entry'; import ComponentMeta from './component-meta'; +import { isCustomView } from '@alilc/lowcode-utils'; -export default class SettingPropEntry { +export default class SettingPropEntry implements IPublicModelSettingPropEntry { private readonly [settingPropEntrySymbol]: SettingField; constructor(prop: SettingField) { this[settingPropEntrySymbol] = prop; } - static create(prop: SettingField) { + static create(prop: SettingField): IPublicModelSettingPropEntry { return new SettingPropEntry(prop); } /** * 获取设置属性的 isGroup */ - get isGroup() { + get isGroup(): boolean { return this[settingPropEntrySymbol].isGroup; } /** * 获取设置属性的 id */ - get id() { + get id(): string { return this[settingPropEntrySymbol].id; } /** * 获取设置属性的 name */ - get name() { + get name(): string | number { return this[settingPropEntrySymbol].name; } /** * 获取设置属性的 key */ - get key() { + get key(): string | number { return this[settingPropEntrySymbol].getKey(); } /** * 获取设置属性的 path */ - get path() { + get path(): any[] { return this[settingPropEntrySymbol].path; } /** * 获取设置属性的 title */ - get title() { + get title(): any { return this[settingPropEntrySymbol].title; } /** * 获取设置属性的 setter */ - get setter() { + get setter(): SetterType | null { return this[settingPropEntrySymbol].setter; } /** * 获取设置属性的 expanded */ - get expanded() { + get expanded(): boolean { return this[settingPropEntrySymbol].expanded; } /** * 获取设置属性的 extraProps */ - get extraProps() { + get extraProps(): FieldExtraProps { return this[settingPropEntrySymbol].extraProps; } - get props() { + get props(): IPublicModelSettingTopEntry { return SettingTopEntry.create(this[settingPropEntrySymbol].props); } /** * 获取设置属性对应的节点实例 */ - get node(): Node | null { + get node(): IPublicModelNode | null { return Node.create(this[settingPropEntrySymbol].getNode()); } /** * 获取设置属性的父设置属性 */ - get parent(): SettingPropEntry { + get parent(): IPublicModelSettingPropEntry { return SettingPropEntry.create(this[settingPropEntrySymbol].parent as any); } /** * 获取顶级设置属性 */ - get top(): SettingTopEntry { + get top(): IPublicModelSettingTopEntry { return SettingTopEntry.create(this[settingPropEntrySymbol].top); } @@ -114,14 +126,14 @@ export default class SettingPropEntry { /** * componentMeta */ - get componentMeta(): ComponentMeta | null { + get componentMeta(): IPublicModelComponentMeta | null { return ComponentMeta.create(this[settingPropEntrySymbol].componentMeta); } /** * 获取设置属性的 items */ - get items(): Array { + get items(): Array { return this[settingPropEntrySymbol].items?.map((item) => { if (isCustomView(item)) { return item; @@ -134,7 +146,7 @@ export default class SettingPropEntry { * 设置 key 值 * @param key */ - setKey(key: string | number) { + setKey(key: string | number): void { this[settingPropEntrySymbol].setKey(key); } @@ -156,7 +168,7 @@ export default class SettingPropEntry { * 设置值 * @param val 值 */ - setValue(val: CompositeValue, extraOptions?: ISetValueOptions) { + setValue(val: CompositeValue, extraOptions?: ISetValueOptions): void { this[settingPropEntrySymbol].setValue(val, false, false, extraOptions); } @@ -165,7 +177,7 @@ export default class SettingPropEntry { * @param propName 子属性名 * @param value 值 */ - setPropValue(propName: string | number, value: any) { + setPropValue(propName: string | number, value: any): void { this[settingPropEntrySymbol].setPropValue(propName, value); } @@ -173,7 +185,7 @@ export default class SettingPropEntry { * 清空指定属性值 * @param propName */ - clearPropValue(propName: string | number) { + clearPropValue(propName: string | number): void { this[settingPropEntrySymbol].clearPropValue(propName); } @@ -181,7 +193,7 @@ export default class SettingPropEntry { * 获取配置的默认值 * @returns */ - getDefaultValue() { + getDefaultValue(): any { return this[settingPropEntrySymbol].getDefaultValue(); } @@ -189,7 +201,7 @@ export default class SettingPropEntry { * 获取值 * @returns */ - getValue() { + getValue(): any { return this[settingPropEntrySymbol].getValue(); } @@ -198,21 +210,21 @@ export default class SettingPropEntry { * @param propName 子属性名 * @returns */ - getPropValue(propName: string | number) { + getPropValue(propName: string | number): any { return this[settingPropEntrySymbol].getPropValue(propName); } /** * 获取顶层附属属性值 */ - getExtraPropValue(propName: string) { + getExtraPropValue(propName: string): any { return this[settingPropEntrySymbol].getExtraPropValue(propName); } /** * 设置顶层附属属性值 */ - setExtraPropValue(propName: string, value: any) { + setExtraPropValue(propName: string, value: any): void { this[settingPropEntrySymbol].setExtraPropValue(propName, value); } @@ -220,7 +232,7 @@ export default class SettingPropEntry { * 获取设置属性集 * @returns */ - getProps() { + getProps(): IPublicModelSettingTopEntry { return SettingTopEntry.create(this[settingPropEntrySymbol].getProps() as SettingEntry) as any; } @@ -228,7 +240,7 @@ export default class SettingPropEntry { * 是否绑定了变量 * @returns */ - isUseVariable() { + isUseVariable(): boolean { return this[settingPropEntrySymbol].isUseVariable(); } @@ -236,7 +248,7 @@ export default class SettingPropEntry { * 设置绑定变量 * @param flag */ - setUseVariable(flag: boolean) { + setUseVariable(flag: boolean): void { this[settingPropEntrySymbol].setUseVariable(flag); } @@ -245,7 +257,7 @@ export default class SettingPropEntry { * @param config * @returns */ - createField(config: FieldConfig) { + createField(config: FieldConfig): IPublicModelSettingPropEntry { return SettingPropEntry.create(this[settingPropEntrySymbol].createField(config)); } @@ -253,21 +265,21 @@ export default class SettingPropEntry { * 获取值,当为变量时,返回 mock * @returns */ - getMockOrValue() { + getMockOrValue(): any { return this[settingPropEntrySymbol].getMockOrValue(); } /** * 销毁当前 field 实例 */ - purge() { + purge(): void { this[settingPropEntrySymbol].purge(); } /** * 移除当前 field 实例 */ - remove() { + remove(): void { this[settingPropEntrySymbol].remove(); } @@ -276,7 +288,7 @@ export default class SettingPropEntry { * @param action * @returns */ - onEffect(action: () => void) { + onEffect(action: () => void): () => void { return this[settingPropEntrySymbol].onEffect(action); } diff --git a/packages/shell/src/setting-top-entry.ts b/packages/shell/src/setting-top-entry.ts index 6f5d888d42..d7693799c6 100644 --- a/packages/shell/src/setting-top-entry.ts +++ b/packages/shell/src/setting-top-entry.ts @@ -2,22 +2,23 @@ import { SettingEntry } from '@alilc/lowcode-designer'; import { settingTopEntrySymbol } from './symbols'; import Node from './node'; import SettingPropEntry from './setting-prop-entry'; +import { IPublicModelSettingTopEntry, IPublicModelNode, IPublicModelSettingPropEntry } from '@alilc/lowcode-types'; -export default class SettingTopEntry { +export default class SettingTopEntry implements IPublicModelSettingTopEntry { private readonly [settingTopEntrySymbol]: SettingEntry; constructor(prop: SettingEntry) { this[settingTopEntrySymbol] = prop; } - static create(prop: SettingEntry) { + static create(prop: SettingEntry): IPublicModelSettingTopEntry { return new SettingTopEntry(prop); } /** * 返回所属的节点实例 */ - get node(): Node | null { + get node(): IPublicModelNode | null { return Node.create(this[settingTopEntrySymbol].getNode()); } @@ -26,7 +27,7 @@ export default class SettingTopEntry { * @param propName * @returns */ - get(propName: string | number) { + get(propName: string | number): IPublicModelSettingPropEntry { return SettingPropEntry.create(this[settingTopEntrySymbol].get(propName) as any); } @@ -42,7 +43,7 @@ export default class SettingTopEntry { * @param propName * @returns */ - getPropValue(propName: string | number) { + getPropValue(propName: string | number): any { return this[settingTopEntrySymbol].getPropValue(propName); } @@ -51,7 +52,7 @@ export default class SettingTopEntry { * @param propName * @param value */ - setPropValue(propName: string | number, value: any) { + setPropValue(propName: string | number, value: any): void { this[settingTopEntrySymbol].setPropValue(propName, value); } } \ No newline at end of file diff --git a/packages/shell/src/simulator-host.ts b/packages/shell/src/simulator-host.ts index 077564550a..f9ebc36b55 100644 --- a/packages/shell/src/simulator-host.ts +++ b/packages/shell/src/simulator-host.ts @@ -2,16 +2,17 @@ import { BuiltinSimulatorHost, } from '@alilc/lowcode-designer'; import { simulatorHostSymbol, nodeSymbol } from './symbols'; +import { IPublicApiSimulatorHost, IPublicModelNode } from '@alilc/lowcode-types'; import type Node from './node'; -export default class SimulatorHost { +export default class SimulatorHost implements IPublicApiSimulatorHost { private readonly [simulatorHostSymbol]: BuiltinSimulatorHost; constructor(simulator: BuiltinSimulatorHost) { this[simulatorHostSymbol] = simulator; } - static create(host: BuiltinSimulatorHost) { + static create(host: BuiltinSimulatorHost): IPublicApiSimulatorHost | null { if (!host) return null; return new SimulatorHost(host); } @@ -19,18 +20,18 @@ export default class SimulatorHost { /** * 获取 contentWindow */ - get contentWindow() { + get contentWindow(): Window | undefined { return this[simulatorHostSymbol].contentWindow; } /** * 获取 contentDocument */ - get contentDocument() { + get contentDocument(): Document | undefined { return this[simulatorHostSymbol].contentDocument; } - get renderer() { + get renderer(): any { return this[simulatorHostSymbol].renderer; } @@ -39,7 +40,7 @@ export default class SimulatorHost { * @param key * @param value */ - set(key: string, value: any) { + set(key: string, value: any): void { this[simulatorHostSymbol].set(key, value); } @@ -48,7 +49,7 @@ export default class SimulatorHost { * @param key * @returns */ - get(key: string) { + get(key: string): any { return this[simulatorHostSymbol].get(key); } @@ -56,14 +57,14 @@ export default class SimulatorHost { * scroll to specific node * @param node */ - scrollToNode(node: Node) { - this[simulatorHostSymbol].scrollToNode(node[nodeSymbol]); + scrollToNode(node: IPublicModelNode): void { + this[simulatorHostSymbol].scrollToNode((node as any)[nodeSymbol]); } /** * 刷新渲染画布 */ - rerender() { + rerender(): void { this[simulatorHostSymbol].rerender(); } } diff --git a/packages/shell/src/skeleton.ts b/packages/shell/src/skeleton.ts index 2c8b178d5a..183ffde5a2 100644 --- a/packages/shell/src/skeleton.ts +++ b/packages/shell/src/skeleton.ts @@ -1,12 +1,11 @@ import { Skeleton as InnerSkeleton, - IWidgetBaseConfig, - IWidgetConfigArea, SkeletonEvents, } from '@alilc/lowcode-editor-skeleton'; import { skeletonSymbol } from './symbols'; +import { IPublicApiSkeleton, IWidgetBaseConfig, IWidgetConfigArea } from '@alilc/lowcode-types'; -export default class Skeleton { +export default class Skeleton implements IPublicApiSkeleton { private readonly [skeletonSymbol]: InnerSkeleton; constructor(skeleton: InnerSkeleton) { @@ -28,11 +27,13 @@ export default class Skeleton { * @param config * @returns */ - remove(config: IWidgetBaseConfig) { + remove(config: IWidgetBaseConfig): number | undefined { const { area, name } = config; const skeleton = this[skeletonSymbol]; - if (!normalizeArea(area)) return; - skeleton[normalizeArea(area)!].container.remove(name); + if (!normalizeArea(area)) { + return; + } + skeleton[normalizeArea(area)!].container?.remove(name); } /** diff --git a/packages/types/src/deprecated/index.ts b/packages/types/src/deprecated/index.ts new file mode 100644 index 0000000000..7e65173c0d --- /dev/null +++ b/packages/types/src/deprecated/index.ts @@ -0,0 +1,18 @@ +export * from './isActionContentObject'; +export * from './isCustomView'; +export * from './isDOMText'; +export * from './isDynamicSetter'; +export * from './isI18nData'; +export * from './isJSBlock'; +export * from './isJSExpression'; +export * from './isJSFunction'; +export * from './isJSSlot'; +export * from './isLowCodeComponentType'; +export * from './isNodeSchema'; +export * from './isPlainObject'; +export * from './isProCodeComponentType'; +export * from './isProjectSchema'; +export * from './isReactClass'; +export * from './isReactComponent'; +export * from './isSetterConfig'; +export * from './isTitleConfig'; \ No newline at end of file diff --git a/packages/types/src/deprecated/isActionContentObject.ts b/packages/types/src/deprecated/isActionContentObject.ts new file mode 100644 index 0000000000..f56ec1128a --- /dev/null +++ b/packages/types/src/deprecated/isActionContentObject.ts @@ -0,0 +1,8 @@ +import { ActionContentObject } from '../metadata'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isActionContentObject(obj: any): obj is ActionContentObject { + return obj && typeof obj === 'object'; +} diff --git a/packages/types/src/deprecated/isCustomView.ts b/packages/types/src/deprecated/isCustomView.ts new file mode 100644 index 0000000000..84ac84c935 --- /dev/null +++ b/packages/types/src/deprecated/isCustomView.ts @@ -0,0 +1,10 @@ +import { isValidElement } from 'react'; +import { isReactComponent } from './isReactComponent'; +import { CustomView } from '../setter-config'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isCustomView(obj: any): obj is CustomView { + return obj && (isValidElement(obj) || isReactComponent(obj)); +} diff --git a/packages/types/src/deprecated/isDOMText.ts b/packages/types/src/deprecated/isDOMText.ts new file mode 100644 index 0000000000..d590d5aa32 --- /dev/null +++ b/packages/types/src/deprecated/isDOMText.ts @@ -0,0 +1,8 @@ +import { DOMText } from '../schema'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isDOMText(data: any): data is DOMText { + return typeof data === 'string'; +} diff --git a/packages/types/src/deprecated/isDynamicSetter.ts b/packages/types/src/deprecated/isDynamicSetter.ts new file mode 100644 index 0000000000..7bfebd9a3c --- /dev/null +++ b/packages/types/src/deprecated/isDynamicSetter.ts @@ -0,0 +1,9 @@ +import { isReactClass } from './isReactClass'; +import { DynamicSetter } from '../setter-config'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isDynamicSetter(obj: any): obj is DynamicSetter { + return obj && typeof obj === 'function' && !isReactClass(obj); +} diff --git a/packages/types/src/deprecated/isI18nData.ts b/packages/types/src/deprecated/isI18nData.ts new file mode 100644 index 0000000000..1194b338ac --- /dev/null +++ b/packages/types/src/deprecated/isI18nData.ts @@ -0,0 +1,8 @@ +import { I18nData } from '../i18n'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isI18nData(obj: any): obj is I18nData { + return obj && obj.type === 'i18n'; +} diff --git a/packages/types/src/deprecated/isJSBlock.ts b/packages/types/src/deprecated/isJSBlock.ts new file mode 100644 index 0000000000..28878eb6ae --- /dev/null +++ b/packages/types/src/deprecated/isJSBlock.ts @@ -0,0 +1,8 @@ +import { JSBlock } from '../value-type'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isJSBlock(data: any): data is JSBlock { + return data && data.type === 'JSBlock'; +} diff --git a/packages/types/src/deprecated/isJSExpression.ts b/packages/types/src/deprecated/isJSExpression.ts new file mode 100644 index 0000000000..1e58c65383 --- /dev/null +++ b/packages/types/src/deprecated/isJSExpression.ts @@ -0,0 +1,8 @@ +import { JSExpression } from '../value-type'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isJSExpression(data: any): data is JSExpression { + return data && data.type === 'JSExpression' && data.extType !== 'function'; +} diff --git a/packages/types/src/deprecated/isJSFunction.ts b/packages/types/src/deprecated/isJSFunction.ts new file mode 100644 index 0000000000..8a98a8c5c9 --- /dev/null +++ b/packages/types/src/deprecated/isJSFunction.ts @@ -0,0 +1,8 @@ +import { JSFunction } from '../value-type'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isJSFunction(x: any): x is JSFunction { + return typeof x === 'object' && x && x.type === 'JSFunction'; +} diff --git a/packages/types/src/deprecated/isJSSlot.ts b/packages/types/src/deprecated/isJSSlot.ts new file mode 100644 index 0000000000..e2096034af --- /dev/null +++ b/packages/types/src/deprecated/isJSSlot.ts @@ -0,0 +1,8 @@ +import { JSSlot } from '../value-type'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isJSSlot(data: any): data is JSSlot { + return data && data.type === 'JSSlot'; +} diff --git a/packages/types/src/deprecated/isLowCodeComponentType.ts b/packages/types/src/deprecated/isLowCodeComponentType.ts new file mode 100644 index 0000000000..1ba2689ca3 --- /dev/null +++ b/packages/types/src/deprecated/isLowCodeComponentType.ts @@ -0,0 +1,9 @@ +import { isProCodeComponentType } from './isProCodeComponentType'; +import { ComponentMap, LowCodeComponentType } from '../npm'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isLowCodeComponentType(desc: ComponentMap): desc is LowCodeComponentType { + return !isProCodeComponentType(desc); +} diff --git a/packages/types/src/deprecated/isNodeSchema.ts b/packages/types/src/deprecated/isNodeSchema.ts new file mode 100644 index 0000000000..b3daf4e464 --- /dev/null +++ b/packages/types/src/deprecated/isNodeSchema.ts @@ -0,0 +1,8 @@ +import { NodeSchema } from '../schema'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isNodeSchema(data: any): data is NodeSchema { + return data && data.componentName; +} diff --git a/packages/types/src/deprecated/isPlainObject.ts b/packages/types/src/deprecated/isPlainObject.ts new file mode 100644 index 0000000000..549f497360 --- /dev/null +++ b/packages/types/src/deprecated/isPlainObject.ts @@ -0,0 +1,10 @@ +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isPlainObject(value: any): value is Record { + if (typeof value !== 'object') { + return false; + } + const proto = Object.getPrototypeOf(value); + return proto === Object.prototype || proto === null || Object.getPrototypeOf(proto) === null; +} diff --git a/packages/types/src/deprecated/isProCodeComponentType.ts b/packages/types/src/deprecated/isProCodeComponentType.ts new file mode 100644 index 0000000000..071a9dc7e8 --- /dev/null +++ b/packages/types/src/deprecated/isProCodeComponentType.ts @@ -0,0 +1,8 @@ +import { ComponentMap, ProCodeComponentType } from '../npm'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isProCodeComponentType(desc: ComponentMap): desc is ProCodeComponentType { + return 'package' in desc; +} diff --git a/packages/types/src/deprecated/isProjectSchema.ts b/packages/types/src/deprecated/isProjectSchema.ts new file mode 100644 index 0000000000..92e65041c2 --- /dev/null +++ b/packages/types/src/deprecated/isProjectSchema.ts @@ -0,0 +1,8 @@ +import { ProjectSchema } from '../schema'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isProjectSchema(data: any): data is ProjectSchema { + return data && data.componentsTree; +} diff --git a/packages/types/src/deprecated/isReactClass.ts b/packages/types/src/deprecated/isReactClass.ts new file mode 100644 index 0000000000..846c522d7b --- /dev/null +++ b/packages/types/src/deprecated/isReactClass.ts @@ -0,0 +1,8 @@ +import { ComponentClass, Component } from 'react'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isReactClass(obj: any): obj is ComponentClass { + return obj && obj.prototype && (obj.prototype.isReactComponent || obj.prototype instanceof Component); +} diff --git a/packages/types/src/deprecated/isReactComponent.ts b/packages/types/src/deprecated/isReactComponent.ts new file mode 100644 index 0000000000..1ed04427f3 --- /dev/null +++ b/packages/types/src/deprecated/isReactComponent.ts @@ -0,0 +1,9 @@ +import { ComponentType } from 'react'; +import { isReactClass } from './isReactClass'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isReactComponent(obj: any): obj is ComponentType { + return obj && (isReactClass(obj) || typeof obj === 'function'); +} diff --git a/packages/types/src/deprecated/isSetterConfig.ts b/packages/types/src/deprecated/isSetterConfig.ts new file mode 100644 index 0000000000..38121c355b --- /dev/null +++ b/packages/types/src/deprecated/isSetterConfig.ts @@ -0,0 +1,9 @@ +import { SetterConfig } from '../setter-config'; +import { isCustomView } from './isCustomView'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isSetterConfig(obj: any): obj is SetterConfig { + return obj && typeof obj === 'object' && 'componentName' in obj && !isCustomView(obj); +} diff --git a/packages/types/src/deprecated/isTitleConfig.ts b/packages/types/src/deprecated/isTitleConfig.ts new file mode 100644 index 0000000000..65f1403fcd --- /dev/null +++ b/packages/types/src/deprecated/isTitleConfig.ts @@ -0,0 +1,10 @@ +import { isI18nData } from './isI18nData'; +import { isPlainObject } from './isPlainObject'; +import { TitleConfig } from '../title'; + +/** + * @deprecated use same function from '@alilc/lowcode-utils' instead + */ +export function isTitleConfig(obj: any): obj is TitleConfig { + return isPlainObject(obj) && !isI18nData(obj); +} diff --git a/packages/types/src/designer.ts b/packages/types/src/designer.ts new file mode 100644 index 0000000000..0c69815780 --- /dev/null +++ b/packages/types/src/designer.ts @@ -0,0 +1,23 @@ +import { IPublicModelNode } from './shell'; + +export enum PROP_VALUE_CHANGED_TYPE { + /** + * normal set value + */ + SET_VALUE = 'SET_VALUE', + /** + * value changed caused by sub-prop value change + */ + SUB_VALUE_CHANGE = 'SUB_VALUE_CHANGE', +} + +export interface ISetValueOptions { + disableMutator?: boolean; + type?: PROP_VALUE_CHANGED_TYPE; + fromSetHotValue?: boolean; +} + +export interface IPublicOnChangeOptions { + type: string; + node: IPublicModelNode; +} diff --git a/packages/types/src/dragon.ts b/packages/types/src/dragon.ts new file mode 100644 index 0000000000..5047b07c97 --- /dev/null +++ b/packages/types/src/dragon.ts @@ -0,0 +1,29 @@ +import { NodeSchema } from './schema'; +import { IPublicModelNode } from './shell'; + +export interface DragAnyObject { + type: string; + [key: string]: any; +} + +export interface DragNodeDataObject { + type: DragObjectType.NodeData; + data: NodeSchema | NodeSchema[]; + thumbnail?: string; + description?: string; + [extra: string]: any; +} + +export type DragObject = DragNodeObject | DragNodeDataObject | DragAnyObject; + +// eslint-disable-next-line no-shadow +export enum DragObjectType { + // eslint-disable-next-line no-shadow + Node = 'node', + NodeData = 'nodedata', +} + +export interface DragNodeObject { + type: DragObjectType.Node; + nodes: (Node | IPublicModelNode)[]; +} \ No newline at end of file diff --git a/packages/types/src/editor-skeleton.ts b/packages/types/src/editor-skeleton.ts new file mode 100644 index 0000000000..e339c4c8a1 --- /dev/null +++ b/packages/types/src/editor-skeleton.ts @@ -0,0 +1,27 @@ +/** + * 所有可能的停靠位置 + */ + export type IWidgetConfigArea = + | 'leftArea' | 'left' | 'rightArea' + | 'right' | 'topArea' | 'top' + | 'toolbar' | 'mainArea' | 'main' + | 'center' | 'centerArea' | 'bottomArea' + | 'bottom' | 'leftFixedArea' + | 'leftFloatArea' | 'stages'; + +export interface IWidgetBaseConfig { + type: string; + name: string; + /** + * 停靠位置: + * - 当 type 为 'Panel' 时自动为 'leftFloatArea'; + * - 当 type 为 'Widget' 时自动为 'mainArea'; + * - 其他时候自动为 'leftArea'; + */ + area?: IWidgetConfigArea; + props?: Record; + content?: any; + contentProps?: Record; + // index?: number; + [extra: string]: any; +} diff --git a/packages/types/src/editor.ts b/packages/types/src/editor.ts index a11c7eaf7b..cf5d3ae488 100644 --- a/packages/types/src/editor.ts +++ b/packages/types/src/editor.ts @@ -3,6 +3,8 @@ import StrictEventEmitter from 'strict-event-emitter-types'; import { ReactNode, ComponentType } from 'react'; import { NpmInfo } from './npm'; import * as GlobalEvent from './event'; +import { CustomView } from './setter-config'; +import { TitleContent } from './title'; export type KeyType = (new (...args: any[]) => any) | symbol | string; export type ClassType = new (...args: any[]) => any; @@ -197,3 +199,22 @@ export interface PluginStatus { export interface PluginStatusSet { [key: string]: PluginStatus; } + +export type HotkeyCallback = (e: KeyboardEvent, combo?: string) => any | false; + +export interface RegisteredSetter { + component: CustomView; + defaultProps?: object; + title?: TitleContent; + /** + * for MixedSetter to check this setter if available + */ + condition?: (field: any) => boolean; + /** + * for MixedSetter to manual change to this setter + */ + initialValue?: any | ((field: any) => any); + recommend?: boolean; + // 标识是否为动态 setter,默认为 true + isDynamic?: boolean; +} \ No newline at end of file diff --git a/packages/types/src/i18n.ts b/packages/types/src/i18n.ts index 44f8ef8550..adcc724386 100644 --- a/packages/types/src/i18n.ts +++ b/packages/types/src/i18n.ts @@ -6,11 +6,6 @@ export interface I18nData { [key: string]: any; } -// type checks -export function isI18nData(obj: any): obj is I18nData { - return obj && obj.type === 'i18n'; -} - export interface I18nMap { [lang: string]: { [key: string]: string }; } diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 9b540cc5f7..708c34326a 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -22,3 +22,10 @@ export * from './assets'; export * as GlobalEvent from './event'; export * from './disposable'; export * from './start-transaction'; +export * from './props-transducer'; +export * from './editor-skeleton'; +export * from './designer'; +export * from './dragon'; +export * from './shell'; +// TODO: remove this in future versions +export * from './deprecated'; diff --git a/packages/types/src/metadata.ts b/packages/types/src/metadata.ts index dd93aea00f..394dd2909c 100644 --- a/packages/types/src/metadata.ts +++ b/packages/types/src/metadata.ts @@ -336,10 +336,6 @@ export interface ComponentAction { important?: boolean; } -export function isActionContentObject(obj: any): obj is ActionContentObject { - return obj && typeof obj === 'object'; -} - /** * 组件 meta 配置 */ @@ -473,3 +469,17 @@ export interface Callbacks { currentNode: any, ) => void; } + +export interface MetadataTransducer { + (prev: TransformedComponentMetadata): TransformedComponentMetadata; + /** + * 0 - 9 system + * 10 - 99 builtin-plugin + * 100 - app & plugin + */ + level?: number; + /** + * use to replace TODO + */ + id?: string; +} \ No newline at end of file diff --git a/packages/types/src/npm.ts b/packages/types/src/npm.ts index 88449f435c..f805158e52 100644 --- a/packages/types/src/npm.ts +++ b/packages/types/src/npm.ts @@ -1,3 +1,4 @@ + /** * npm 源引入完整描述对象 */ @@ -45,13 +46,4 @@ export interface LowCodeComponentType { export type ProCodeComponentType = NpmInfo; export type ComponentMap = ProCodeComponentType | LowCodeComponentType; - -export function isProCodeComponentType(desc: ComponentMap): desc is ProCodeComponentType { - return 'package' in desc; -} - -export function isLowCodeComponentType(desc: ComponentMap): desc is LowCodeComponentType { - return !isProCodeComponentType(desc); -} - export type ComponentsMap = ComponentMap[]; diff --git a/packages/types/src/props-transducer.ts b/packages/types/src/props-transducer.ts new file mode 100644 index 0000000000..2272475697 --- /dev/null +++ b/packages/types/src/props-transducer.ts @@ -0,0 +1,12 @@ +import { TransformStage } from './transform-stage'; +import { CompositeObject } from './value-type'; + +export type PropsReducerContext = { + stage: TransformStage; +}; + +export type PropsTransducer = ( + props: CompositeObject, + node: Node, + ctx?: PropsReducerContext, +) => CompositeObject; diff --git a/packages/types/src/schema.ts b/packages/types/src/schema.ts index 5d0fad4444..e320d6b510 100644 --- a/packages/types/src/schema.ts +++ b/packages/types/src/schema.ts @@ -75,11 +75,6 @@ export type PropsList = Array<{ export type NodeData = NodeSchema | JSExpression | DOMText; export type NodeDataType = NodeData | NodeData[]; - -export function isDOMText(data: any): data is DOMText { - return typeof data === 'string'; -} - export type DOMText = string; /** @@ -217,12 +212,4 @@ export interface ProjectSchema { * 当前应用元数据信息 */ meta?: Record; -} - -export function isNodeSchema(data: any): data is NodeSchema { - return data && data.componentName; -} - -export function isProjectSchema(data: any): data is ProjectSchema { - return data && data.componentsTree; -} +} \ No newline at end of file diff --git a/packages/types/src/setter-config.ts b/packages/types/src/setter-config.ts index d579240eff..5138e36498 100644 --- a/packages/types/src/setter-config.ts +++ b/packages/types/src/setter-config.ts @@ -1,18 +1,9 @@ -import { ComponentClass, Component, ComponentType, ReactElement, isValidElement } from 'react'; +import { ComponentType, ReactElement } from 'react'; import { TitleContent } from './title'; import { SettingTarget } from './setting-target'; import { CompositeValue } from './value-type'; -function isReactClass(obj: any): obj is ComponentClass { - return obj && obj.prototype && (obj.prototype.isReactComponent || obj.prototype instanceof Component); -} - -function isReactComponent(obj: any): obj is ComponentType { - return obj && (isReactClass(obj) || typeof obj === 'function'); -} - export type CustomView = ReactElement | ComponentType; - export type DynamicProps = (target: SettingTarget) => Record; export type DynamicSetter = (target: SettingTarget) => string | SetterConfig | CustomView; @@ -63,21 +54,9 @@ export interface SetterConfig { * @todo 物料协议推进 */ valueType?: CompositeValue[]; - // 标识是否为动态setter,默认为true + // 标识是否为动态 setter,默认为 true isDynamic?: boolean; } // if *string* passed must be a registered Setter Name, future support blockSchema -export type SetterType = SetterConfig | SetterConfig[] | string | CustomView; - -export function isSetterConfig(obj: any): obj is SetterConfig { - return obj && typeof obj === 'object' && 'componentName' in obj && !isCustomView(obj); -} - -export function isCustomView(obj: any): obj is CustomView { - return obj && (isValidElement(obj) || isReactComponent(obj)); -} - -export function isDynamicSetter(obj: any): obj is DynamicSetter { - return obj && typeof obj === 'function' && !isReactClass(obj); -} +export type SetterType = SetterConfig | SetterConfig[] | string | CustomView; \ No newline at end of file diff --git a/packages/types/src/shell/api/common.ts b/packages/types/src/shell/api/common.ts new file mode 100644 index 0000000000..0c59bbcada --- /dev/null +++ b/packages/types/src/shell/api/common.ts @@ -0,0 +1,50 @@ + +import { Component, ReactNode } from 'react'; +import { NodeSchema } from '../../schema'; +import { TransitionType } from '../../start-transaction'; + +export interface IPublicCommonUtils { + isNodeSchema(data: any): boolean; + + isFormEvent(e: KeyboardEvent | MouseEvent): boolean; + + compatibleLegaoSchema(props: any): any; + + getNodeSchemaById(schema: NodeSchema, nodeId: string): NodeSchema | undefined; + + getConvertedExtraKey(key: string): string; + + getOriginalExtraKey(key: string): string; + + executeTransaction(fn: () => void, type: TransitionType): void; + + createIntl(instance: string | object): { + intlNode(id: string, params?: object): ReactNode; + intl(id: string, params?: object): string; + getLocale(): string; + setLocale(locale: string): void; + }; +} +export interface IPublicCommonSkeletonCabin { + get Workbench(): Component; +} + +export interface IPublicCommonDesignerCabin { + /** + * 是否是 SettingField 实例 + * + * @param {*} obj + * @returns {obj is SettingField} + * @memberof DesignerCabin + */ + isSettingField(obj: any): boolean; +} + +export interface IPublicApiCommon { + + get utils(): IPublicCommonUtils; + + get designerCabin(): IPublicCommonDesignerCabin; + + get skeletonCabin(): IPublicCommonSkeletonCabin; +} diff --git a/packages/types/src/shell/api/event.ts b/packages/types/src/shell/api/event.ts new file mode 100644 index 0000000000..c7f35ff581 --- /dev/null +++ b/packages/types/src/shell/api/event.ts @@ -0,0 +1,26 @@ + +export interface IPublicApiEvent { + + /** + * 监听事件 + * @param event 事件名称 + * @param listener 事件回调 + */ + on(event: string, listener: (...args: unknown[]) => void): void; + + + /** + * 取消监听事件 + * @param event 事件名称 + * @param listener 事件回调 + */ + off(event: string, listener: (...args: unknown[]) => void): void; + + /** + * 触发事件 + * @param event 事件名称 + * @param args 事件参数 + * @returns + */ + emit(event: string, ...args: unknown[]): void; +} diff --git a/packages/types/src/shell/api/hotkey.ts b/packages/types/src/shell/api/hotkey.ts new file mode 100644 index 0000000000..983792f045 --- /dev/null +++ b/packages/types/src/shell/api/hotkey.ts @@ -0,0 +1,16 @@ +import { Disposable } from '../../disposable'; +import { HotkeyCallback } from '../../editor'; + + +export interface IPublicApiHotkey { + get callbacks(): any; + + /** + * 绑定快捷键 + * @param combos 快捷键,格式如:['command + s'] 、['ctrl + shift + s'] 等 + * @param callback 回调函数 + * @param action + * @returns + */ + bind(combos: string[] | string, callback: HotkeyCallback, action?: string): Disposable; +} diff --git a/packages/types/src/shell/api/index.ts b/packages/types/src/shell/api/index.ts new file mode 100644 index 0000000000..9e5152b9e9 --- /dev/null +++ b/packages/types/src/shell/api/index.ts @@ -0,0 +1,8 @@ +export * from './common'; +export * from './event'; +export * from './hotkey'; +export * from './material'; +export * from './project'; +export * from './setters'; +export * from './simulator-host'; +export * from './skeleton'; \ No newline at end of file diff --git a/packages/types/src/shell/api/material.ts b/packages/types/src/shell/api/material.ts new file mode 100644 index 0000000000..d46aa66bfa --- /dev/null +++ b/packages/types/src/shell/api/material.ts @@ -0,0 +1,90 @@ +import { AssetsJson } from '../../assets'; +import { MetadataTransducer, ComponentAction } from '../../metadata'; +import { IPublicModelComponentMeta } from '../model/component-meta'; + + +export interface IPublicApiMaterial { + + /** + * 设置「资产包」结构 + * @param assets + * @returns + */ + setAssets(assets: AssetsJson): void; + + /** + * 获取「资产包」结构 + * @returns + */ + getAssets(): any; + + /** + * 加载增量的「资产包」结构,该增量包会与原有的合并 + * @param incrementalAssets + * @returns + */ + loadIncrementalAssets(incrementalAssets: AssetsJson): void; + + /** + * 注册物料元数据管道函数 + * @param transducer + * @param level + * @param id + */ + registerMetadataTransducer( + transducer: MetadataTransducer, + level?: number, + id?: string | undefined + ): void; + + /** + * 获取所有物料元数据管道函数 + * @returns + */ + getRegisteredMetadataTransducers(): MetadataTransducer[]; + + /** + * 获取指定名称的物料元数据 + * @param componentName + * @returns + */ + getComponentMeta(componentName: string): IPublicModelComponentMeta | null; + + /** + * test if the given object is a ComponentMeta instance or not + * @param obj + * @returns + */ + isComponentMeta(obj: any): boolean; + + /** + * 获取所有已注册的物料元数据 + * @returns + */ + getComponentMetasMap(): Map; + + /** + * 在设计器辅助层增加一个扩展 action + * @param action + */ + addBuiltinComponentAction(action: ComponentAction): void; + + /** + * 移除设计器辅助层的指定 action + * @param name + */ + removeBuiltinComponentAction(name: string): void; + + /** + * 修改已有的设计器辅助层的指定 action + * @param actionName + * @param handle + */ + modifyBuiltinComponentAction(actionName: string, handle: (action: ComponentAction) => void): void; + + /** + * 监听 assets 变化的事件 + * @param fn + */ + onChangeAssets(fn: () => void): void; +} diff --git a/packages/types/src/shell/api/project.ts b/packages/types/src/shell/api/project.ts new file mode 100644 index 0000000000..398669c94f --- /dev/null +++ b/packages/types/src/shell/api/project.ts @@ -0,0 +1,115 @@ +import { RootSchema, ProjectSchema } from '../../schema'; +import { TransformStage } from '../../transform-stage'; +import { PropsTransducer } from '../../props-transducer'; +import { IPublicApiSimulatorHost } from './simulator-host'; +import { IPublicModelDocumentModel } from '../model'; + + +export interface IPublicApiProject { + /** + * 获取当前的 document + * @returns + */ + get currentDocument(): IPublicModelDocumentModel | null; + + /** + * 获取当前 project 下所有 documents + * @returns + */ + get documents(): IPublicModelDocumentModel[]; + + /** + * 获取模拟器的 host + */ + get simulatorHost(): IPublicApiSimulatorHost | null; + + /** + * 打开一个 document + * @param doc + * @returns + */ + openDocument(doc?: string | RootSchema | undefined): IPublicModelDocumentModel | null; + + /** + * 创建一个 document + * @param data + * @returns + */ + createDocument(data?: RootSchema): IPublicModelDocumentModel | null; + + + /** + * 删除一个 document + * @param doc + */ + removeDocument(doc: IPublicModelDocumentModel): void; + + /** + * 根据 fileName 获取 document + * @param fileName + * @returns + */ + getDocumentByFileName(fileName: string): IPublicModelDocumentModel | null; + + /** + * 根据 id 获取 document + * @param id + * @returns + */ + getDocumentById(id: string): IPublicModelDocumentModel | null; + + /** + * 导出 project + * @returns + */ + exportSchema(stage: TransformStage): ProjectSchema; + + /** + * 导入 project + * @param schema 待导入的 project 数据 + */ + importSchema(schema?: ProjectSchema): void; + + /** + * 获取当前的 document + * @returns + */ + getCurrentDocument(): IPublicModelDocumentModel | null; + + /** + * 增加一个属性的管道处理函数 + * @param transducer + * @param stage + */ + addPropsTransducer(transducer: PropsTransducer, stage: TransformStage): void; + + /** + * 绑定删除文档事件 + * @param fn + * @returns + */ + onRemoveDocument(fn: (data: { id: string }) => void): any; + + /** + * 当前 project 内的 document 变更事件 + */ + onChangeDocument(fn: (doc: IPublicModelDocumentModel) => void): () => void; + + /** + * 当前 project 的模拟器 ready 事件 + */ + onSimulatorHostReady(fn: (host: IPublicApiSimulatorHost) => void): () => void; + + /** + * 当前 project 的渲染器 ready 事件 + */ + onSimulatorRendererReady(fn: () => void): () => void; + + /** + * 设置多语言语料 + * 数据格式参考 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 + * @param value object + * @returns + */ + setI18n(value: object): void; +} diff --git a/packages/types/src/shell/api/setters.ts b/packages/types/src/shell/api/setters.ts new file mode 100644 index 0000000000..e133c29af7 --- /dev/null +++ b/packages/types/src/shell/api/setters.ts @@ -0,0 +1,31 @@ +import { RegisteredSetter } from '../../editor'; +import { CustomView } from '../../setter-config'; + + +export interface IPublicApiSetters { + /** + * 获取指定 setter + * @param type + * @returns + */ + getSetter(type: string): RegisteredSetter | null; + + /** + * 获取已注册的所有 settersMap + * @returns + */ + getSettersMap(): Map; + + /** + * 注册一个 setter + * @param typeOrMaps + * @param setter + * @returns + */ + registerSetter( + typeOrMaps: string | { [key: string]: CustomView | RegisteredSetter }, + setter?: CustomView | RegisteredSetter | undefined + ): void; +} diff --git a/packages/types/src/shell/api/simulator-host.ts b/packages/types/src/shell/api/simulator-host.ts new file mode 100644 index 0000000000..971e78a83a --- /dev/null +++ b/packages/types/src/shell/api/simulator-host.ts @@ -0,0 +1,41 @@ +import { IPublicModelNode } from '../model'; + + +export interface IPublicApiSimulatorHost { + /** + * 获取 contentWindow + */ + get contentWindow(): Window | undefined; + + /** + * 获取 contentDocument + */ + get contentDocument(): Document | undefined; + + get renderer(): any; + + /** + * 设置 host 配置值 + * @param key + * @param value + */ + set(key: string, value: any): void; + + /** + * 获取 host 配置值 + * @param key + * @returns + */ + get(key: string): any; + + /** + * scroll to specific node + * @param node + */ + scrollToNode(node: IPublicModelNode): void; + + /** + * 刷新渲染画布 + */ + rerender(): void; +} diff --git a/packages/types/src/shell/api/skeleton.ts b/packages/types/src/shell/api/skeleton.ts new file mode 100644 index 0000000000..5f81c64076 --- /dev/null +++ b/packages/types/src/shell/api/skeleton.ts @@ -0,0 +1,95 @@ +import { IWidgetBaseConfig } from '../../editor-skeleton'; + + +export interface IPublicApiSkeleton { + /** + * 增加一个面板实例 + * @param config + * @param extraConfig + * @returns + */ + add(config: IWidgetBaseConfig, extraConfig?: Record): any; + + /** + * 移除一个面板实例 + * @param config + * @returns + */ + remove(config: IWidgetBaseConfig): number | undefined; + + /** + * 显示面板 + * @param name + */ + showPanel(name: string): void; + + /** + * 隐藏面板 + * @param name + */ + hidePanel(name: string): void; + + /** + * 显示 widget + * @param name + */ + showWidget(name: string): void; + + /** + * enable widget + * @param name + */ + enableWidget(name: string): void; + + /** + * 隐藏 widget + * @param name + */ + hideWidget(name: string): void; + + /** + * disable widget,不可点击 + * @param name + */ + disableWidget(name: string): void; + + /** + * show area + * @param areaName name of area + */ + showArea(areaName: string): void; + + /** + * hide area + * @param areaName name of area + */ + hideArea(areaName: string): void; + + /** + * 监听 panel 显示事件 + * @param listener + * @returns + */ + onShowPanel(listener: (...args: unknown[]) => void): () => void; + + /** + * 监听 panel 隐藏事件 + * @param listener + * @returns + */ + onHidePanel(listener: (...args: unknown[]) => void): () => void; + + /** + * 监听 widget 显示事件 + * @param listener + * @returns + */ + onShowWidget(listener: (...args: unknown[]) => void): () => void; + + /** + * 监听 widget 隐藏事件 + * @param listener + * @returns + */ + onHideWidget(listener: (...args: unknown[]) => void): () => void; +} diff --git a/packages/types/src/shell/index.ts b/packages/types/src/shell/index.ts new file mode 100644 index 0000000000..c0b2d52808 --- /dev/null +++ b/packages/types/src/shell/index.ts @@ -0,0 +1,13 @@ +import { IPublicModelNode } from './model/node'; +import { IPublicModelProp } from './model/prop'; + +export interface PropChangeOptions { + key?: string | number; + prop?: IPublicModelProp; + node: IPublicModelNode; + newValue: any; + oldValue: any; +} + +export * from './api'; +export * from './model'; \ No newline at end of file diff --git a/packages/types/src/shell/model/canvas.ts b/packages/types/src/shell/model/canvas.ts new file mode 100644 index 0000000000..50c6d39055 --- /dev/null +++ b/packages/types/src/shell/model/canvas.ts @@ -0,0 +1,4 @@ + +export interface IPublicModelCanvas { + get dropLocation(): any; +} diff --git a/packages/types/src/shell/model/component-meta.ts b/packages/types/src/shell/model/component-meta.ts new file mode 100644 index 0000000000..f50081f142 --- /dev/null +++ b/packages/types/src/shell/model/component-meta.ts @@ -0,0 +1,85 @@ +import { NodeSchema, NodeData } from '../../schema'; +import { IconType } from '../../icon'; +import { TransformedComponentMetadata } from '../../metadata'; +import { ReactElement } from 'react'; +import { I18nData } from '../../i18n'; +import { NpmInfo } from '../../npm'; +import { IPublicModelNode } from './node'; + +export interface IPublicModelComponentMeta { + /** + * 组件名 + */ + get componentName(): string; + + /** + * 是否是「容器型」组件 + */ + get isContainer(): boolean; + + /** + * 是否是最小渲染单元。 + * 当组件需要重新渲染时: + * 若为最小渲染单元,则只渲染当前组件, + * 若不为最小渲染单元,则寻找到上层最近的最小渲染单元进行重新渲染,直至根节点。 + */ + get isMinimalRenderUnit(): boolean; + + /** + * 是否为「模态框」组件 + */ + get isModal(): boolean; + + /** + * 元数据配置 + */ + get configure(): any; + + /** + * 标题 + */ + get title(): string | I18nData | ReactElement; + + /** + * 图标 + */ + get icon(): IconType; + + /** + * 组件 npm 信息 + */ + get npm(): NpmInfo; + + get availableActions(): any; + + /** + * 设置 npm 信息 + * @param npm + */ + setNpm(npm: NpmInfo): void; + + /** + * 获取元数据 + * @returns + */ + getMetadata(): TransformedComponentMetadata; + + /** + * check if the current node could be placed in parent node + * @param my + * @param parent + * @returns + */ + checkNestingUp(my: IPublicModelNode | NodeData, parent: any): boolean; + + /** + * check if the target node(s) could be placed in current node + * @param my + * @param parent + * @returns + */ + checkNestingDown(my: IPublicModelNode | NodeData, target: NodeSchema | IPublicModelNode | NodeSchema[]): boolean; + + + refreshMetadata(): void; +} diff --git a/packages/types/src/shell/model/detecting.ts b/packages/types/src/shell/model/detecting.ts new file mode 100644 index 0000000000..a9a480b2e2 --- /dev/null +++ b/packages/types/src/shell/model/detecting.ts @@ -0,0 +1,23 @@ +export interface IPublicModelDetecting { + /** + * 当前 hover 的节点 + */ + get current(): any; + + /** + * hover 指定节点 + * @param id 节点 id + */ + capture(id: string): any; + + /** + * hover 离开指定节点 + * @param id 节点 id + */ + release(id: string): any; + + /** + * 清空 hover 态 + */ + leave(): any; +} diff --git a/packages/types/src/shell/model/document-model.ts b/packages/types/src/shell/model/document-model.ts new file mode 100644 index 0000000000..2407cdab12 --- /dev/null +++ b/packages/types/src/shell/model/document-model.ts @@ -0,0 +1,155 @@ +import { RootSchema } from '../../schema'; +import { TransformStage } from '../../transform-stage'; +import { DragNodeDataObject, DragNodeObject } from '../../dragon'; +import { IPublicApiProject } from '../api'; +import { PropChangeOptions } from '../index'; +import { IPublicModelModalNodesManager } from './modal-nodes-manager'; +import { IPublicModelNode } from './node'; + + +export interface IPublicModelDocumentModel { + + /** + * id + */ + get id(): string; + + set id(id); + + /** + * 获取当前文档所属的 project + * @returns + */ + get project(): IPublicApiProject | null; + + /** + * 获取文档的根节点 + * @returns + */ + get root(): IPublicModelNode | null; + + get focusNode(): IPublicModelNode | null; + + set focusNode(node: IPublicModelNode | null); + + /** + * 获取文档下所有节点 + * @returns + */ + get nodesMap(): any; + + /** + * 模态节点管理 + */ + get modalNodesManager(): IPublicModelModalNodesManager | null; + + /** + * 根据 nodeId 返回 Node 实例 + * @param nodeId + * @returns + */ + getNodeById(nodeId: string): IPublicModelNode | null; + + /** + * 导入 schema + * @param schema + */ + importSchema(schema: RootSchema): void; + + /** + * 导出 schema + * @param stage + * @returns + */ + exportSchema(stage: TransformStage): any; + + /** + * 插入节点 + * @param parent + * @param thing + * @param at + * @param copy + * @returns + */ + insertNode( + parent: IPublicModelNode, + thing: IPublicModelNode, + at?: number | null | undefined, + copy?: boolean | undefined + ): IPublicModelNode | null; + + /** + * 创建一个节点 + * @param data + * @returns + */ + createNode(data: any): IPublicModelNode | null; + + /** + * 移除指定节点/节点id + * @param idOrNode + */ + removeNode(idOrNode: string | IPublicModelNode): void; + + /** + * componentsMap of documentModel + * @param extraComps + * @returns + */ + getComponentsMap(extraComps?: string[]): any; + + /** + * 检查拖拽放置的目标节点是否可以放置该拖拽对象 + * @param dropTarget 拖拽放置的目标节点 + * @param dragObject 拖拽的对象 + * @returns boolean 是否可以放置 + */ + checkNesting( + dropTarget: IPublicModelNode, + dragObject: DragNodeObject | DragNodeDataObject + ): boolean; + + /** + * 当前 document 新增节点事件 + */ + onAddNode(fn: (node: IPublicModelNode) => void): () => void; + + /** + * 当前 document 新增节点事件,此时节点已经挂载到 document 上 + */ + onMountNode(fn: (payload: { node: IPublicModelNode }) => void): () => void; + + /** + * 当前 document 删除节点事件 + */ + onRemoveNode(fn: (node: IPublicModelNode) => void): () => void; + + /** + * 当前 document 的 hover 变更事件 + */ + onChangeDetecting(fn: (node: IPublicModelNode) => void): () => void; + + /** + * 当前 document 的选中变更事件 + */ + onChangeSelection(fn: (ids: string[]) => void): () => void; + + /** + * 当前 document 的节点显隐状态变更事件 + * @param fn + */ + onChangeNodeVisible(fn: (node: IPublicModelNode, visible: boolean) => void): void; + + + /** + * 当前 document 节点属性修改事件 + * @param fn + */ + onChangeNodeProp(fn: (info: PropChangeOptions) => void): void; + + /** + * import schema event + * @param fn + */ + onImportSchema(fn: (schema: RootSchema) => void): void; +} diff --git a/packages/types/src/shell/model/drag-object.ts b/packages/types/src/shell/model/drag-object.ts new file mode 100644 index 0000000000..9169ea8530 --- /dev/null +++ b/packages/types/src/shell/model/drag-object.ts @@ -0,0 +1,8 @@ +export interface IPublicModelDragObject { + + get type(): any; + + get nodes(): any; + + get data(): any; +} diff --git a/packages/types/src/shell/model/dragon.ts b/packages/types/src/shell/model/dragon.ts new file mode 100644 index 0000000000..f6f97ac083 --- /dev/null +++ b/packages/types/src/shell/model/dragon.ts @@ -0,0 +1,39 @@ +import { DragNodeDataObject } from '../../dragon'; +import { IPublicModelDragObject } from './drag-object'; +import { IPublicModelLocateEvent } from './locate-event'; + +export interface IPublicModelDragon { + /** + * is dragging or not + */ + get dragging(): boolean; + + /** + * 绑定 dragstart 事件 + * @param func + * @returns + */ + onDragstart(func: (e: IPublicModelLocateEvent) => any): () => void; + + /** + * 绑定 drag 事件 + * @param func + * @returns + */ + onDrag(func: (e: IPublicModelLocateEvent) => any): () => void; + + /** + * 绑定 dragend 事件 + * @param func + * @returns + */ + onDragend(func: (o: { dragObject: IPublicModelDragObject; copy?: boolean }) => any): () => void; + + + /** + * 设置拖拽监听的区域 shell,以及自定义拖拽转换函数 boost + * @param shell 拖拽监听的区域 + * @param boost 拖拽转换函数 + */ + from(shell: Element, boost: (e: MouseEvent) => DragNodeDataObject | null): any; +} diff --git a/packages/types/src/shell/model/drop-location.ts b/packages/types/src/shell/model/drop-location.ts new file mode 100644 index 0000000000..746850b1fb --- /dev/null +++ b/packages/types/src/shell/model/drop-location.ts @@ -0,0 +1,3 @@ +export interface IPublicModelDropLocation { + get target(): any; +} diff --git a/packages/types/src/shell/model/history.ts b/packages/types/src/shell/model/history.ts new file mode 100644 index 0000000000..1c0020de33 --- /dev/null +++ b/packages/types/src/shell/model/history.ts @@ -0,0 +1,49 @@ +export interface IPublicModelHistory { + + /** + * 历史记录跳转到指定位置 + * @param cursor + */ + go(cursor: number): void; + + /** + * 历史记录后退 + */ + back(): void; + + /** + * 历史记录前进 + */ + forward(): void; + + /** + * 保存当前状态 + */ + savePoint(): void; + + /** + * 当前是否是「保存点」,即是否有状态变更但未保存 + * @returns + */ + isSavePoint(): boolean; + + /** + * 获取 state,判断当前是否为「可回退」、「可前进」的状态 + * @returns + */ + getState(): any; + + /** + * 监听 state 变更事件 + * @param func + * @returns + */ + onChangeState(func: () => any): () => void; + + /** + * 监听历史记录游标位置变更事件 + * @param func + * @returns + */ + onChangeCursor(func: () => any): () => void; +} diff --git a/packages/types/src/shell/model/index.ts b/packages/types/src/shell/model/index.ts new file mode 100644 index 0000000000..27d3fcbb6d --- /dev/null +++ b/packages/types/src/shell/model/index.ts @@ -0,0 +1,17 @@ +export * from './canvas'; +export * from './component-meta'; +export * from './detecting'; +export * from './document-model'; +export * from './drag-object'; +export * from './dragon'; +export * from './drop-location'; +export * from './history'; +export * from './locate-event'; +export * from './modal-nodes-manager'; +export * from './node-children'; +export * from './node'; +export * from './prop'; +export * from './props'; +export * from './selection'; +export * from './setting-prop-entry'; +export * from './setting-top-entry'; \ No newline at end of file diff --git a/packages/types/src/shell/model/locate-event.ts b/packages/types/src/shell/model/locate-event.ts new file mode 100644 index 0000000000..bde1010340 --- /dev/null +++ b/packages/types/src/shell/model/locate-event.ts @@ -0,0 +1,20 @@ +import { IPublicModelDragObject } from './drag-object'; + +export interface IPublicModelLocateEvent { + + get type(): string; + + get globalX(): number; + + get globalY(): number; + + get originalEvent(): MouseEvent | DragEvent; + + get target(): Element | null | undefined; + + get canvasX(): number | undefined; + + get canvasY(): number | undefined; + + get dragObject(): IPublicModelDragObject | null; +} diff --git a/packages/types/src/shell/model/modal-nodes-manager.ts b/packages/types/src/shell/model/modal-nodes-manager.ts new file mode 100644 index 0000000000..07d598e2eb --- /dev/null +++ b/packages/types/src/shell/model/modal-nodes-manager.ts @@ -0,0 +1,37 @@ +import { IPublicModelNode } from './node'; + +export interface IPublicModelModalNodesManager { + /** + * 设置模态节点,触发内部事件 + */ + setNodes(): void; + + /** + * 获取模态节点(们) + * @returns + */ + getModalNodes(): any; + + /** + * 获取当前可见的模态节点 + * @returns + */ + getVisibleModalNode(): any; + + /** + * 隐藏模态节点(们) + */ + hideModalNodes(): void; + + /** + * 设置指定节点为可见态 + * @param node Node + */ + setVisible(node: IPublicModelNode): void; + + /** + * 设置指定节点为不可见态 + * @param node Node + */ + setInvisible(node: IPublicModelNode): void; +} diff --git a/packages/types/src/shell/model/node-children.ts b/packages/types/src/shell/model/node-children.ts new file mode 100644 index 0000000000..2044054545 --- /dev/null +++ b/packages/types/src/shell/model/node-children.ts @@ -0,0 +1,128 @@ +import { NodeSchema, NodeData } from '../../schema'; +import { TransformStage } from '../../transform-stage'; +import { IPublicModelNode } from './node'; + +export interface IPublicModelNodeChildren { + /** + * 返回当前 children 实例所属的节点实例 + */ + get owner(): IPublicModelNode | null; + + /** + * children 内的节点实例数 + */ + get size(): number; + + /** + * 是否为空 + * @returns + */ + get isEmpty(): boolean; + + /** + * judge if it is not empty + */ + get notEmpty(): boolean; + + /** + * 删除指定节点 + * @param node + * @returns + */ + delete(node: IPublicModelNode): boolean; + + /** + * 插入一个节点 + * @param node 待插入节点 + * @param at 插入下标 + * @returns + */ + insert(node: IPublicModelNode, at?: number | null): void; + + /** + * 返回指定节点的下标 + * @param node + * @returns + */ + indexOf(node: IPublicModelNode): number; + + /** + * 类似数组 splice 操作 + * @param start + * @param deleteCount + * @param node + */ + splice(start: number, deleteCount: number, node?: IPublicModelNode): any; + + /** + * 返回指定下标的节点 + * @param index + * @returns + */ + get(index: number): any; + + /** + * 是否包含指定节点 + * @param node + * @returns + */ + has(node: IPublicModelNode): boolean; + + /** + * 类似数组的 forEach + * @param fn + */ + forEach(fn: (node: IPublicModelNode, index: number) => void): void; + + /** + * 类似数组的 map + * @param fn + */ + map(fn: (node: IPublicModelNode, index: number) => T[]): any[] | null; + + /** + * 类似数组的 every + * @param fn + */ + every(fn: (node: IPublicModelNode, index: number) => boolean): boolean; + + /** + * 类似数组的 some + * @param fn + */ + some(fn: (node: IPublicModelNode, index: number) => boolean): boolean; + + /** + * 类似数组的 filter + * @param fn + */ + filter(fn: (node: IPublicModelNode, index: number) => boolean): any; + + /** + * 类似数组的 find + * @param fn + */ + find(fn: (node: IPublicModelNode, index: number) => boolean): IPublicModelNode | null; + + reduce(fn: (acc: any, cur: IPublicModelNode) => any, initialValue: any): void; + + /** + * 导入 schema + * @param data + */ + importSchema(data?: NodeData | NodeData[]): void; + + /** + * 导出 schema + * @param stage + * @returns + */ + exportSchema(stage: TransformStage): NodeSchema; + + mergeChildren( + remover: (node: IPublicModelNode, idx: number) => boolean, + adder: (children: IPublicModelNode[]) => NodeData[] | null, + sorter: (firstNode: IPublicModelNode, secondNode: IPublicModelNode) => number + ): any; + +} diff --git a/packages/types/src/shell/model/node.ts b/packages/types/src/shell/model/node.ts new file mode 100644 index 0000000000..f0aaf9506d --- /dev/null +++ b/packages/types/src/shell/model/node.ts @@ -0,0 +1,316 @@ +import { NodeSchema, PropsMap, PropsList } from '../../schema'; +import { TransformStage } from '../../transform-stage'; +import { IconType } from '../../icon'; +import { ReactElement } from 'react'; +import { I18nData } from '../../i18n'; +import { CompositeValue } from '../../value-type'; +import { IPublicModelDocumentModel } from './document-model'; +import { IPublicModelSettingTopEntry } from './setting-top-entry'; +import { IPublicModelProps } from './props'; +import { IPublicModelProp } from './prop'; +import { IPublicModelNodeChildren } from './node-children'; +import { IPublicModelComponentMeta } from './component-meta'; + +export interface IPublicModelNode { + + /** + * 节点 id + */ + id: string; + /** + * 节点标题 + */ + get title(): string | I18nData | ReactElement; + + /** + * 是否为「容器型」节点 + */ + get isContainer(): boolean; + + /** + * 是否为根节点 + */ + get isRoot(): boolean; + + /** + * 是否为空节点(无 children 或者 children 为空) + */ + get isEmpty(): boolean; + + /** + * 是否为 Page 节点 + */ + get isPage(): boolean; + + /** + * 是否为 Component 节点 + */ + get isComponent(): boolean; + + /** + * 是否为「模态框」节点 + */ + get isModal(): boolean; + + /** + * 是否为插槽节点 + */ + get isSlot(): boolean; + + /** + * 是否为父类/分支节点 + */ + get isParental(): boolean; + + /** + * 是否为叶子节点 + */ + get isLeaf(): boolean; + + /** + * 获取当前节点的锁定状态 + */ + get isLocked(): boolean; + + /** + * 下标 + */ + get index(): number; + + /** + * 图标 + */ + get icon(): IconType; + + /** + * 节点所在树的层级深度,根节点深度为 0 + */ + get zLevel(): number; + + /** + * 节点 componentName + */ + get componentName(): string; + + /** + * 节点的物料元数据 + */ + get componentMeta(): IPublicModelComponentMeta | null; + + /** + * 获取节点所属的文档模型对象 + * @returns + */ + get document(): IPublicModelDocumentModel | null; + + /** + * 获取当前节点的前一个兄弟节点 + * @returns + */ + get prevSibling(): IPublicModelNode | null; + + /** + * 获取当前节点的后一个兄弟节点 + * @returns + */ + get nextSibling(): IPublicModelNode | null; + + /** + * 获取当前节点的父亲节点 + * @returns + */ + get parent(): IPublicModelNode | null; + /** + * 获取当前节点的孩子节点模型 + * @returns + */ + get children(): IPublicModelNodeChildren | null; + + /** + * 节点上挂载的插槽节点们 + */ + get slots(): IPublicModelNode[]; + + /** + * 当前节点为插槽节点时,返回节点对应的属性实例 + */ + get slotFor(): IPublicModelProp | null; + + /** + * 返回节点的属性集 + */ + get props(): IPublicModelProps | null; + + /** + * 返回节点的属性集 + */ + get propsData(): PropsMap | PropsList | null; + + /** + * 获取符合搭建协议 - 节点 schema 结构 + */ + get schema(): NodeSchema; + + get settingEntry(): IPublicModelSettingTopEntry; + + /** + * 执行新增、删除、排序等操作 + * @param remover + * @param adder + * @param sorter + */ + mergeChildren( + remover: (node: IPublicModelNode, idx: number) => boolean, + adder: (children: IPublicModelNode[]) => any, + sorter: (firstNode: IPublicModelNode, secondNode: IPublicModelNode) => number + ): any; + + /** + * 返回节点的尺寸、位置信息 + * @returns + */ + getRect(): DOMRect | null; + + /** + * 是否有挂载插槽节点 + * @returns + */ + hasSlots(): boolean; + + /** + * 是否设定了渲染条件 + * @returns + */ + hasCondition(): boolean; + + /** + * 是否设定了循环数据 + * @returns + */ + hasLoop(): boolean; + + getVisible(): boolean; + + setVisible(flag: boolean): void; + + isConditionalVisible(): boolean | undefined; + + /** + * 设置节点锁定状态 + * @param flag + */ + lock(flag?: boolean): void; + + contains(node: IPublicModelNode): boolean; + + /** + * 获取指定 path 的属性模型实例 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @returns + */ + getProp(path: string, createIfNone: boolean): IPublicModelProp | null; + + /** + * 获取指定 path 的属性模型实例, + * 注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @param createIfNone 当没有属性的时候,是否创建一个属性 + * @returns + */ + getExtraProp(path: string, createIfNone?: boolean): IPublicModelProp | null; + + /** + * 获取指定 path 的属性模型实例, + * 注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @returns + */ + getExtraPropValue(path: string): any; + + /** + * 设置指定 path 的属性模型实例值 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @param value 值 + * @returns + */ + setPropValue(path: string, value: CompositeValue): void; + + /** + * 设置指定 path 的属性模型实例值 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @param value 值 + * @returns + */ + setExtraPropValue(path: string, value: CompositeValue): void; + + /** + * 导入节点数据 + * @param data + */ + importSchema(data: NodeSchema): void; + + /** + * 导出节点数据 + * @param stage + * @param options + * @returns + */ + exportSchema(stage: TransformStage, options?: any): NodeSchema; + + /** + * 在指定位置之前插入一个节点 + * @param node + * @param ref + * @param useMutator + */ + insertBefore(node: IPublicModelNode, ref?: IPublicModelNode | undefined, useMutator?: boolean): void; + + /** + * 在指定位置之后插入一个节点 + * @param node + * @param ref + * @param useMutator + */ + insertAfter(node: IPublicModelNode, ref?: IPublicModelNode | undefined, useMutator?: boolean): void; + + /** + * 替换指定节点 + * @param node 待替换的子节点 + * @param data 用作替换的节点对象或者节点描述 + * @returns + */ + replaceChild(node: IPublicModelNode, data: any): IPublicModelNode | null; + + /** + * 将当前节点替换成指定节点描述 + * @param schema + */ + replaceWith(schema: NodeSchema): any; + + /** + * 选中当前节点实例 + */ + select(): void; + + /** + * 设置悬停态 + * @param flag + */ + hover(flag: boolean): void; + + /** + * 删除当前节点实例 + */ + remove(): void; + + /** + * 设置为磁贴布局节点 + */ + set isRGLContainer(flag: boolean); + + /** + * 获取磁贴布局节点设置状态 + * @returns Boolean + */ + get isRGLContainer(); +} diff --git a/packages/types/src/shell/model/prop.ts b/packages/types/src/shell/model/prop.ts new file mode 100644 index 0000000000..982d22650f --- /dev/null +++ b/packages/types/src/shell/model/prop.ts @@ -0,0 +1,59 @@ +import { TransformStage } from '../../transform-stage'; +import { CompositeValue } from '../../value-type'; +import { IPublicModelNode } from './node'; + +export interface IPublicModelProp { + /** + * id + */ + get id(): string; + + /** + * key 值 + */ + get key(): string | number | undefined; + + /** + * 返回当前 prop 的路径 + */ + get path(): any[]; + + /** + * 返回所属的节点实例 + */ + get node(): IPublicModelNode | null; + + /** + * return the slot node (only if the current prop represents a slot) + */ + get slotNode(): IPublicModelNode | null; + + /** + * judge if it is a prop or not + */ + get isProp(): boolean; + + /** + * 设置值 + * @param val + */ + setValue(val: CompositeValue): void; + + /** + * 获取值 + * @returns + */ + getValue(): any; + + /** + * 移除值 + */ + remove(): void; + + /** + * 导出值 + * @param stage + * @returns + */ + exportSchema(stage: TransformStage): CompositeValue; +} diff --git a/packages/types/src/shell/model/props.ts b/packages/types/src/shell/model/props.ts new file mode 100644 index 0000000000..09a5ec4e26 --- /dev/null +++ b/packages/types/src/shell/model/props.ts @@ -0,0 +1,82 @@ +import { CompositeValue } from '../../value-type'; +import { IPublicModelNode } from './node'; +import { IPublicModelProp } from './prop'; + +export interface IPublicModelProps { + /** + * id + */ + get id(): string; + + /** + * 返回当前 props 的路径 + */ + get path(): any[]; + + /** + * 返回所属的 node 实例 + */ + get node(): IPublicModelNode | null; + + /** + * 获取指定 path 的属性模型实例 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @returns + */ + getProp(path: string): IPublicModelProp | null; + + /** + * 获取指定 path 的属性模型实例值 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @returns + */ + getPropValue(path: string): any; + + /** + * 获取指定 path 的属性模型实例, + * 注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @returns + */ + getExtraProp(path: string): IPublicModelProp | null; + + /** + * 获取指定 path 的属性模型实例值 + * 注:导出时,不同于普通属性,该属性并不挂载在 props 之下,而是与 props 同级 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @returns + */ + getExtraPropValue(path: string): any; + + /** + * 设置指定 path 的属性模型实例值 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @param value 值 + * @returns + */ + setPropValue(path: string, value: CompositeValue): void; + + /** + * 设置指定 path 的属性模型实例值 + * @param path 属性路径,支持 a / a.b / a.0 等格式 + * @param value 值 + * @returns + */ + setExtraPropValue(path: string, value: CompositeValue): void; + + /** + * test if the specified key is existing or not. + * @param key + * @returns + */ + has(key: string): boolean; + + /** + * add a key with given value + * @param value + * @param key + * @returns + */ + add(value: CompositeValue, key?: string | number | undefined): any; + +} diff --git a/packages/types/src/shell/model/selection.ts b/packages/types/src/shell/model/selection.ts new file mode 100644 index 0000000000..43a5ee494e --- /dev/null +++ b/packages/types/src/shell/model/selection.ts @@ -0,0 +1,65 @@ +import { IPublicModelNode } from './node'; + +export interface IPublicModelSelection { + + /** + * 返回选中的节点 id + */ + get selected(): string[]; + + /** + * return selected Node instance + */ + get node(): IPublicModelNode | null; + + /** + * 选中指定节点(覆盖方式) + * @param id + */ + select(id: string): void; + + /** + * 批量选中指定节点们 + * @param ids + */ + selectAll(ids: string[]): void; + + /** + * 移除选中的指定节点 + * @param id + */ + remove(id: string): void; + + /** + * 清除所有选中节点 + */ + clear(): void; + + /** + * 判断是否选中了指定节点 + * @param id + * @returns + */ + has(id: string): boolean; + + /** + * 选中指定节点(增量方式) + * @param id + */ + add(id: string): void; + + /** + * 获取选中的节点实例 + * @returns + */ + getNodes(): Array; + + /** + * 获取选区的顶层节点 + * for example: + * getNodes() returns [A, subA, B], then + * getTopNodes() will return [A, B], subA will be removed + * @returns + */ + getTopNodes(): Array; +} diff --git a/packages/types/src/shell/model/setting-prop-entry.ts b/packages/types/src/shell/model/setting-prop-entry.ts new file mode 100644 index 0000000000..90c75a444b --- /dev/null +++ b/packages/types/src/shell/model/setting-prop-entry.ts @@ -0,0 +1,188 @@ +import { CustomView, SetterType } from '../../setter-config'; +import { CompositeValue } from '../../value-type'; +import { FieldExtraProps, FieldConfig } from '../../field-config'; +import { ISetValueOptions } from '../../designer'; +import { IPublicModelNode } from './node'; +import { IPublicModelComponentMeta } from './component-meta'; +import { IPublicModelSettingTopEntry } from './setting-top-entry'; + +export interface IPublicModelSettingPropEntry { + /** + * 获取设置属性的 isGroup + */ + get isGroup(): boolean; + + /** + * 获取设置属性的 id + */ + get id(): string; + + /** + * 获取设置属性的 name + */ + get name(): string | number; + + /** + * 获取设置属性的 key + */ + get key(): string | number; + + /** + * 获取设置属性的 path + */ + get path(): any[]; + + /** + * 获取设置属性的 title + */ + get title(): any; + + /** + * 获取设置属性的 setter + */ + get setter(): SetterType | null; + + /** + * 获取设置属性的 expanded + */ + get expanded(): boolean; + + /** + * 获取设置属性的 extraProps + */ + get extraProps(): FieldExtraProps; + + get props(): IPublicModelSettingTopEntry; + + /** + * 获取设置属性对应的节点实例 + */ + get node(): IPublicModelNode | null; + + /** + * 获取设置属性的父设置属性 + */ + get parent(): IPublicModelSettingPropEntry; + + /** + * 获取顶级设置属性 + */ + get top(): IPublicModelSettingTopEntry; + + /** + * 是否是 SettingField 实例 + */ + get isSettingField(): boolean; + + /** + * componentMeta + */ + get componentMeta(): IPublicModelComponentMeta | null; + + /** + * 获取设置属性的 items + */ + get items(): Array; + + /** + * 设置 key 值 + * @param key + */ + setKey(key: string | number): void; + + /** + * 设置值 + * @param val 值 + */ + setValue(val: CompositeValue, extraOptions?: ISetValueOptions): void; + + /** + * 设置子级属性值 + * @param propName 子属性名 + * @param value 值 + */ + setPropValue(propName: string | number, value: any): void; + + /** + * 清空指定属性值 + * @param propName + */ + clearPropValue(propName: string | number): void; + + /** + * 获取配置的默认值 + * @returns + */ + getDefaultValue(): any; + + /** + * 获取值 + * @returns + */ + getValue(): any; + + /** + * 获取子级属性值 + * @param propName 子属性名 + * @returns + */ + getPropValue(propName: string | number): any; + + /** + * 获取顶层附属属性值 + */ + getExtraPropValue(propName: string): any; + + /** + * 设置顶层附属属性值 + */ + setExtraPropValue(propName: string, value: any): void; + + /** + * 获取设置属性集 + * @returns + */ + getProps(): IPublicModelSettingTopEntry; + + /** + * 是否绑定了变量 + * @returns + */ + isUseVariable(): boolean; + + /** + * 设置绑定变量 + * @param flag + */ + setUseVariable(flag: boolean): void; + + /** + * 创建一个设置 field 实例 + * @param config + * @returns + */ + createField(config: FieldConfig): IPublicModelSettingPropEntry; + + /** + * 获取值,当为变量时,返回 mock + * @returns + */ + getMockOrValue(): any; + + /** + * 销毁当前 field 实例 + */ + purge(): void; + + /** + * 移除当前 field 实例 + */ + remove(): void; + + /** + * 设置 autorun + * @param action + * @returns + */ + onEffect(action: () => void): () => void; +} diff --git a/packages/types/src/shell/model/setting-top-entry.ts b/packages/types/src/shell/model/setting-top-entry.ts new file mode 100644 index 0000000000..5a7726346d --- /dev/null +++ b/packages/types/src/shell/model/setting-top-entry.ts @@ -0,0 +1,30 @@ +import { IPublicModelNode } from './node'; +import { IPublicModelSettingPropEntry } from './setting-prop-entry'; + +export interface IPublicModelSettingTopEntry { + /** + * 返回所属的节点实例 + */ + get node(): IPublicModelNode | null; + + /** + * 获取子级属性对象 + * @param propName + * @returns + */ + get(propName: string | number): IPublicModelSettingPropEntry; + + /** + * 获取指定 propName 的值 + * @param propName + * @returns + */ + getPropValue(propName: string | number): any; + + /** + * 设置指定 propName 的值 + * @param propName + * @param value + */ + setPropValue(propName: string | number, value: any): void; +} diff --git a/packages/types/src/title.ts b/packages/types/src/title.ts index a4ac366144..bba02c489b 100644 --- a/packages/types/src/title.ts +++ b/packages/types/src/title.ts @@ -1,5 +1,5 @@ import { ReactElement, ReactNode } from 'react'; -import { I18nData, isI18nData } from './i18n'; +import { I18nData } from './i18n'; import { TipContent } from './tip'; import { IconType } from './icon'; @@ -29,16 +29,4 @@ export interface TitleConfig { className?: string; } -export type TitleContent = string | I18nData | ReactElement | TitleConfig; - -function isPlainObject(value: any): value is Record { - if (typeof value !== 'object') { - return false; - } - const proto = Object.getPrototypeOf(value); - return proto === Object.prototype || proto === null || Object.getPrototypeOf(proto) === null; -} - -export function isTitleConfig(obj: any): obj is TitleConfig { - return isPlainObject(obj) && !isI18nData(obj); -} +export type TitleContent = string | I18nData | ReactElement | TitleConfig; \ No newline at end of file diff --git a/packages/types/src/value-type.ts b/packages/types/src/value-type.ts index a266cb9f30..81358fda1d 100644 --- a/packages/types/src/value-type.ts +++ b/packages/types/src/value-type.ts @@ -126,30 +126,4 @@ export type CompositeValue = export type CompositeArray = CompositeValue[]; export interface CompositeObject { [key: string]: CompositeValue; -} - -/** - * 为了避免把 { type: 'JSExpression', extType: 'function' } 误判为表达式,故增加如下逻辑。 - * - * 引擎中关于函数的表达: - * 开源版本:{ type: 'JSFunction', source: '', value: '' } - * 内部版本:{ type: 'JSExpression', source: '', value: '', extType: 'function' } - * 能力是对标的,不过开源的 react-renderer 只认识第一种,而内部只识别第二种(包括 Java 代码、RE)。 - * @param data - * @returns - */ -export function isJSExpression(data: any): data is JSExpression { - return data && data.type === 'JSExpression' && data.extType !== 'function'; -} - -export function isJSFunction(x: any): x is JSFunction { - return typeof x === 'object' && x && x.type === 'JSFunction'; -} - -export function isJSSlot(data: any): data is JSSlot { - return data && data.type === 'JSSlot'; -} - -export function isJSBlock(data: any): data is JSBlock { - return data && data.type === 'JSBlock'; -} +} \ No newline at end of file diff --git a/packages/utils/src/check-types/index.ts b/packages/utils/src/check-types/index.ts new file mode 100644 index 0000000000..d4dfa6f32d --- /dev/null +++ b/packages/utils/src/check-types/index.ts @@ -0,0 +1,16 @@ +// 此模块存放 @alilc/lowcode-types 中类型相关判断工具 +export * from './is-action-content-object'; +export * from './is-custom-view'; +export * from './is-dom-text'; +export * from './is-dynamic-setter'; +export * from './is-i18n-data'; +export * from './is-jsblock'; +export * from './is-jsexpression'; +export * from './is-isfunction'; +export * from './is-jsslot'; +export * from './is-lowcode-component-type'; +export * from './is-node-schema'; +export * from './is-procode-component-type'; +export * from './is-project-schema'; +export * from './is-setter-config'; +export * from './is-title-config'; \ No newline at end of file diff --git a/packages/utils/src/check-types/is-action-content-object.ts b/packages/utils/src/check-types/is-action-content-object.ts new file mode 100644 index 0000000000..917f11ee3b --- /dev/null +++ b/packages/utils/src/check-types/is-action-content-object.ts @@ -0,0 +1,6 @@ +import { ActionContentObject } from '@alilc/lowcode-types'; + + +export function isActionContentObject(obj: any): obj is ActionContentObject { + return obj && typeof obj === 'object'; +} diff --git a/packages/utils/src/check-types/is-custom-view.ts b/packages/utils/src/check-types/is-custom-view.ts new file mode 100644 index 0000000000..6f098a9211 --- /dev/null +++ b/packages/utils/src/check-types/is-custom-view.ts @@ -0,0 +1,8 @@ +import { isValidElement } from 'react'; +import { isReactComponent } from '../is-react'; +import { CustomView } from '@alilc/lowcode-types'; + + +export function isCustomView(obj: any): obj is CustomView { + return obj && (isValidElement(obj) || isReactComponent(obj)); +} diff --git a/packages/utils/src/check-types/is-dom-text.ts b/packages/utils/src/check-types/is-dom-text.ts new file mode 100644 index 0000000000..b5c7785177 --- /dev/null +++ b/packages/utils/src/check-types/is-dom-text.ts @@ -0,0 +1,5 @@ +import { DOMText } from '@alilc/lowcode-types'; + +export function isDOMText(data: any): data is DOMText { + return typeof data === 'string'; +} diff --git a/packages/utils/src/check-types/is-dynamic-setter.ts b/packages/utils/src/check-types/is-dynamic-setter.ts new file mode 100644 index 0000000000..2e0ac63b92 --- /dev/null +++ b/packages/utils/src/check-types/is-dynamic-setter.ts @@ -0,0 +1,7 @@ +import { isReactClass } from '../is-react'; +import { DynamicSetter } from '@alilc/lowcode-types'; + + +export function isDynamicSetter(obj: any): obj is DynamicSetter { + return obj && typeof obj === 'function' && !isReactClass(obj); +} diff --git a/packages/utils/src/check-types/is-i18n-data.ts b/packages/utils/src/check-types/is-i18n-data.ts new file mode 100644 index 0000000000..d315a77c4e --- /dev/null +++ b/packages/utils/src/check-types/is-i18n-data.ts @@ -0,0 +1,7 @@ +import { I18nData } from '@alilc/lowcode-types'; + +// type checks + +export function isI18nData(obj: any): obj is I18nData { + return obj && obj.type === 'i18n'; +} diff --git a/packages/utils/src/check-types/is-isfunction.ts b/packages/utils/src/check-types/is-isfunction.ts new file mode 100644 index 0000000000..75506d1ffa --- /dev/null +++ b/packages/utils/src/check-types/is-isfunction.ts @@ -0,0 +1,5 @@ +import { JSFunction } from '@alilc/lowcode-types'; + +export function isJSFunction(x: any): x is JSFunction { + return typeof x === 'object' && x && x.type === 'JSFunction'; +} diff --git a/packages/utils/src/check-types/is-jsblock.ts b/packages/utils/src/check-types/is-jsblock.ts new file mode 100644 index 0000000000..b19fb9a60f --- /dev/null +++ b/packages/utils/src/check-types/is-jsblock.ts @@ -0,0 +1,5 @@ +import { JSBlock } from '@alilc/lowcode-types'; + +export function isJSBlock(data: any): data is JSBlock { + return data && data.type === 'JSBlock'; +} diff --git a/packages/utils/src/check-types/is-jsexpression.ts b/packages/utils/src/check-types/is-jsexpression.ts new file mode 100644 index 0000000000..969b72cd43 --- /dev/null +++ b/packages/utils/src/check-types/is-jsexpression.ts @@ -0,0 +1,15 @@ +import { JSExpression } from '@alilc/lowcode-types'; + +/** + * 为了避免把 { type: 'JSExpression', extType: 'function' } 误判为表达式,故增加如下逻辑。 + * + * 引擎中关于函数的表达: + * 开源版本:{ type: 'JSFunction', source: '', value: '' } + * 内部版本:{ type: 'JSExpression', source: '', value: '', extType: 'function' } + * 能力是对标的,不过开源的 react-renderer 只认识第一种,而内部只识别第二种(包括 Java 代码、RE)。 + * @param data + * @returns + */ +export function isJSExpression(data: any): data is JSExpression { + return data && data.type === 'JSExpression' && data.extType !== 'function'; +} diff --git a/packages/utils/src/check-types/is-jsslot.ts b/packages/utils/src/check-types/is-jsslot.ts new file mode 100644 index 0000000000..bc7c3576f4 --- /dev/null +++ b/packages/utils/src/check-types/is-jsslot.ts @@ -0,0 +1,5 @@ +import { JSSlot } from '@alilc/lowcode-types'; + +export function isJSSlot(data: any): data is JSSlot { + return data && data.type === 'JSSlot'; +} diff --git a/packages/utils/src/check-types/is-lowcode-component-type.ts b/packages/utils/src/check-types/is-lowcode-component-type.ts new file mode 100644 index 0000000000..7c69783788 --- /dev/null +++ b/packages/utils/src/check-types/is-lowcode-component-type.ts @@ -0,0 +1,7 @@ +import { isProCodeComponentType } from './is-procode-component-type'; +import { ComponentMap, LowCodeComponentType } from '@alilc/lowcode-types'; + + +export function isLowCodeComponentType(desc: ComponentMap): desc is LowCodeComponentType { + return !isProCodeComponentType(desc); +} diff --git a/packages/utils/src/check-types/is-node-schema.ts b/packages/utils/src/check-types/is-node-schema.ts new file mode 100644 index 0000000000..2552a920fe --- /dev/null +++ b/packages/utils/src/check-types/is-node-schema.ts @@ -0,0 +1,5 @@ +import { NodeSchema } from '@alilc/lowcode-types'; + +export function isNodeSchema(data: any): data is NodeSchema { + return data && data.componentName; +} diff --git a/packages/utils/src/check-types/is-procode-component-type.ts b/packages/utils/src/check-types/is-procode-component-type.ts new file mode 100644 index 0000000000..53c33c6c94 --- /dev/null +++ b/packages/utils/src/check-types/is-procode-component-type.ts @@ -0,0 +1,6 @@ +import { ComponentMap, ProCodeComponentType } from '@alilc/lowcode-types'; + + +export function isProCodeComponentType(desc: ComponentMap): desc is ProCodeComponentType { + return 'package' in desc; +} diff --git a/packages/utils/src/check-types/is-project-schema.ts b/packages/utils/src/check-types/is-project-schema.ts new file mode 100644 index 0000000000..9dd6d49618 --- /dev/null +++ b/packages/utils/src/check-types/is-project-schema.ts @@ -0,0 +1,5 @@ +import { ProjectSchema } from '@alilc/lowcode-types'; + +export function isProjectSchema(data: any): data is ProjectSchema { + return data && data.componentsTree; +} diff --git a/packages/utils/src/check-types/is-setter-config.ts b/packages/utils/src/check-types/is-setter-config.ts new file mode 100644 index 0000000000..7176a59684 --- /dev/null +++ b/packages/utils/src/check-types/is-setter-config.ts @@ -0,0 +1,7 @@ +import { SetterConfig } from '@alilc/lowcode-types'; +import { isCustomView } from './is-custom-view'; + + +export function isSetterConfig(obj: any): obj is SetterConfig { + return obj && typeof obj === 'object' && 'componentName' in obj && !isCustomView(obj); +} diff --git a/packages/utils/src/check-types/is-title-config.ts b/packages/utils/src/check-types/is-title-config.ts new file mode 100644 index 0000000000..2d5088dc0d --- /dev/null +++ b/packages/utils/src/check-types/is-title-config.ts @@ -0,0 +1,8 @@ +import { isI18nData } from './is-i18n-data'; +import { isPlainObject } from '../is-plain-object'; +import { TitleConfig } from '@alilc/lowcode-types'; + + +export function isTitleConfig(obj: any): obj is TitleConfig { + return isPlainObject(obj) && !isI18nData(obj); +} diff --git a/packages/utils/src/index.ts b/packages/utils/src/index.ts index 4f47402a11..1dd7168fd5 100644 --- a/packages/utils/src/index.ts +++ b/packages/utils/src/index.ts @@ -27,3 +27,4 @@ export * from './clone-enumerable-property'; export * from './logger'; export * as css from './css-helper'; export { transactionManager } from './transaction-manager'; +export * from './check-types'; diff --git a/packages/utils/src/schema.ts b/packages/utils/src/schema.ts index 1580003d29..0bb1248522 100644 --- a/packages/utils/src/schema.ts +++ b/packages/utils/src/schema.ts @@ -1,4 +1,5 @@ -import { isJSBlock, isJSSlot, ActivityType, NodeSchema, PageSchema, RootSchema } from '@alilc/lowcode-types'; +import { ActivityType, NodeSchema, RootSchema } from '@alilc/lowcode-types'; +import { isJSBlock, isJSSlot } from './check-types'; import { isVariable } from './misc'; import { isPlainObject } from './is-plain-object'; From 3fa810d8ce55c5e0eac8dc347d2f22130b58614c Mon Sep 17 00:00:00 2001 From: AndyKim Date: Tue, 6 Dec 2022 11:45:51 +0800 Subject: [PATCH 225/823] fix: add null protection for LowcodeTypes.shape (#1326) * fix: add null protection for LowcodeTypes.shape, to solve the error with umijs/max >= 4.0.30 --- .../designer/src/builtin-simulator/utils/parse-metadata.ts | 2 +- .../tests/builtin-simulator/utils/parse-metadata.test.ts | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/packages/designer/src/builtin-simulator/utils/parse-metadata.ts b/packages/designer/src/builtin-simulator/utils/parse-metadata.ts index ca0a6071c3..f958e2536b 100644 --- a/packages/designer/src/builtin-simulator/utils/parse-metadata.ts +++ b/packages/designer/src/builtin-simulator/utils/parse-metadata.ts @@ -113,7 +113,7 @@ LowcodeTypes.exact = (typesMap: any) => { }; // An object taking on a particular shape -LowcodeTypes.shape = (typesMap: any) => { +LowcodeTypes.shape = (typesMap: any = {}) => { const configs = Object.keys(typesMap).map(key => { return { name: key, diff --git a/packages/designer/tests/builtin-simulator/utils/parse-metadata.test.ts b/packages/designer/tests/builtin-simulator/utils/parse-metadata.test.ts index f2f399c96e..1843a24429 100644 --- a/packages/designer/tests/builtin-simulator/utils/parse-metadata.test.ts +++ b/packages/designer/tests/builtin-simulator/utils/parse-metadata.test.ts @@ -6,4 +6,8 @@ describe('parseMetadata', () => { const md1 = parseMetadata('Div'); const md2 = parseMetadata({ componentName: 'Div' }); }); + it('LowcodeTypes.shape', async () => { + const result = (window as any).PropTypes.shape() + expect(result).toBeDefined(); + }); }); From a54ded2fd6969e1362da644f32b3cefca12bfaf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E7=86=A0?= Date: Tue, 6 Dec 2022 14:26:52 +0800 Subject: [PATCH 226/823] chore: change recommended node version to 16.18, and fix some minor doc link issues (#1327) --- .github/workflows/insufficient information.yml | 2 +- docs/docs/guide/quickStart/start.md | 2 +- docs/docs/participate/prepare.md | 2 +- docs/package.json | 2 +- packages/engine/README-zh_CN.md | 16 ++++++++-------- packages/engine/README.md | 14 +++++++------- packages/ignitor/public/index.html | 4 ++-- 7 files changed, 21 insertions(+), 21 deletions(-) diff --git a/.github/workflows/insufficient information.yml b/.github/workflows/insufficient information.yml index 2b699860d6..15885043a0 100644 --- a/.github/workflows/insufficient information.yml +++ b/.github/workflows/insufficient information.yml @@ -16,4 +16,4 @@ jobs: token: ${{ secrets.GITHUB_TOKEN }} issue-number: ${{ github.event.issue.number }} body: | - 你好 @${{ github.event.issue.user.login }},由于缺乏必要的信息(如 bug 重现步骤、引擎版本信息 等),无法定位问题,请按照 [issue bug 模板](https://github.com/alibaba/lowcode-engine/blob/main/.github/ISSUE_TEMPLATE/bug-report.md) 补全信息,也可以通过阅读[引擎的 issue 说明](https://www.yuque.com/lce/doc/yvlxhs) 了解什么类型的 issue 可以获得更好、更快的支持。 + 你好 @${{ github.event.issue.user.login }},由于缺乏必要的信息(如 bug 重现步骤、引擎版本信息 等),无法定位问题,请按照 [issue bug 模板](https://github.com/alibaba/lowcode-engine/blob/main/.github/ISSUE_TEMPLATE/bug-report.md) 补全信息,也可以通过阅读 [引擎的 issue 说明](https://lowcode-engine.cn/site/community/issue) 了解什么类型的 issue 可以获得更好、更快的支持。 diff --git a/docs/docs/guide/quickStart/start.md b/docs/docs/guide/quickStart/start.md index dd5bbe48ec..13f30159e1 100644 --- a/docs/docs/guide/quickStart/start.md +++ b/docs/docs/guide/quickStart/start.md @@ -11,7 +11,7 @@ title: 快速开始 ### WSL(Window 电脑) Window 环境需要使用 WSL 在 windows 下进行低代码引擎相关的开发。安装教程 ➡️ [WSL 安装教程](https://docs.microsoft.com/zh-cn/windows/wsl/install)。
**对于 Window 环境来说,之后所有需要执行命令的操作都是在 WSL 终端执行的。** ### Node -node 版本推荐 14.17.0。 +node 版本推荐 16.18.0。 #### 查看 Node 版本 ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01oCZKNz290LIu8YUTk_!!6000000008005-2-tps-238-70.png) diff --git a/docs/docs/participate/prepare.md b/docs/docs/participate/prepare.md index dd962cd647..b23dff33d5 100644 --- a/docs/docs/participate/prepare.md +++ b/docs/docs/participate/prepare.md @@ -9,7 +9,7 @@ sidebar_position: 1 如果您需要对低代码编辑器进行定制,您可能只需要 clone [lowcode-demo 项目](https://github.com/alibaba/lowcode-demo)并进行修改,参考“[配置低代码扩展点](/site/docs/guide/expand/editor/summary)”章节。 > 前置条件: -> node >= 14 +> node 推荐使用 16.18.0(14.x 也可以) ### 1. 拉取代码,启动项目 ```bash diff --git a/docs/package.json b/docs/package.json index ef145d3c60..66a731478b 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.0.4", + "version": "1.0.5", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ diff --git a/packages/engine/README-zh_CN.md b/packages/engine/README-zh_CN.md index 5a070affb2..000a711f5f 100644 --- a/packages/engine/README-zh_CN.md +++ b/packages/engine/README-zh_CN.md @@ -41,7 +41,7 @@ - 🌈 提炼自企业级低代码平台的面向扩展设计的内核引擎,奉行最小内核,最强生态的设计理念 - 📦 开箱即用的高质量生态元素,包括 物料体系、设置器、插件 等 - ⚙️ 完善的工具链,支持 物料体系、设置器、插件 等生态元素的全链路研发周期 -- 🔌 强大的扩展能力,已支撑近 100 个各种垂直类低代码平台 +- 🔌 强大的扩展能力,已支撑 100+ 个各种类型低代码平台 - 🛡 使用 TypeScript 开发,提供完整的类型定义文件 ## 🎯 兼容环境 @@ -126,9 +126,9 @@ https://cdn.jsdelivr.net/npm/@alilc/lowcode-react-simulator-renderer@1.0.0/dist/ - [官方物料](https://github.com/alibaba/lowcode-materials) - [官方设置器(setter)](https://github.com/alibaba/lowcode-engine-ext) - [官方插件(plugin)](https://github.com/alibaba/lowcode-plugins) -- [生态元素(物料、setter、插件)工具链](https://www.yuque.com/lce/doc/ulvlkz) -- [用户文档](https://lowcode-engine.cn/docV2) -- [API](https://lowcode-engine.cn/docV2/vlmeme) +- [生态元素(物料、setter、插件)工具链](https://lowcode-engine.cn/site/docs/guide/expand/editor/cli) +- [用户文档](https://lowcode-engine.cn/doc) +- [API](https://lowcode-engine.cn/site/docs/api/) [awesome-lowcode-engine](https://github.com/lowcode-workspace/awesome-lowcode-engine) 中包含了一系列围绕引擎建设的工具、解决方案等,如果你有类似的解决方案或者工具,欢迎提 PR 到该仓库,让更多人了解到 @@ -146,14 +146,14 @@ $ npm start > > 📢 windows 环境必须使用 [WSL](https://docs.microsoft.com/zh-cn/windows/wsl/install),其他终端不保证能正常运行 -lowcode-engine 启动后,提供了几个 umd 文件,可以结合 [lowcode-demo](https://github.com/alibaba/lowcode-demo) 项目做调试,文件代理规则参考[这里](https://www.yuque.com/lce/doc/glz0fx)。 +lowcode-engine 启动后,提供了几个 umd 文件,可以结合 [lowcode-demo](https://github.com/alibaba/lowcode-demo) 项目做调试,文件代理规则参考[这里](https://lowcode-engine.cn/site/docs/participate/prepare#2-配置资源代理)。 ## 🤝 参与共建 请先阅读: -1. [如何配置引擎调试环境?](https://www.yuque.com/lce/doc/glz0fx) -2. [关于引擎的研发协作流程](https://www.yuque.com/lce/doc/contributing) -3. [引擎的工程化配置](https://www.yuque.com/lce/doc/gxwqg6) +1. [如何配置引擎调试环境?](https://lowcode-engine.cn/site/docs/participate/prepare) +2. [关于引擎的研发协作流程](https://lowcode-engine.cn/site/docs/participate/flow) +3. [引擎的工程化配置](https://lowcode-engine.cn/site/docs/participate/config) > 强烈推荐阅读 [《提问的智慧》](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way)、[《如何向开源社区提问题》](https://github.com/seajs/seajs/issues/545) 和 [《如何有效地报告 Bug》](http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html)、[《如何向开源项目提交无法解答的问题》](https://zhuanlan.zhihu.com/p/25795393),更好的问题更容易获得帮助。(此段参考 [antd](https://github.com/ant-design/ant-design)) diff --git a/packages/engine/README.md b/packages/engine/README.md index 63e9671403..8b11e5a1a4 100644 --- a/packages/engine/README.md +++ b/packages/engine/README.md @@ -126,9 +126,9 @@ Pass the files under packages/engine/dist and packages/(react|rax)-simulator-ren - [Official Materials](https://github.com/alibaba/lowcode-materials) - [official setter](https://github.com/alibaba/lowcode-engine-ext) - [Official plugin (plugin)](https://github.com/alibaba/lowcode-plugins) -- [Ecological elements (materials, setters, plugins) toolchain](https://www.yuque.com/lce/doc/ulvlkz) -- [User Documentation](http://lowcode-engine.cn/docV2) -- [API](http://lowcode-engine.cn/docV2/vlmeme) +- [Ecological elements (materials, setters, plugins) toolchain](https://lowcode-engine.cn/site/docs/guide/expand/editor/cli) +- [User Documentation](http://lowcode-engine.cn/doc) +- [API](https://lowcode-engine.cn/site/docs/api/) This [awesome-lowcode-engine](https://github.com/lowcode-workspace/awesome-lowcode-engine) page links to a repository which records all of the tools\materials\solutions that use or built for the lowcode-engine, PR is welcomed. @@ -146,14 +146,14 @@ $ npm start > > 📢 Windows environment must use [WSL](https://docs.microsoft.com/en-us/windows/wsl/install), other terminals are not guaranteed to work normally -After lowcode-engine is started, several umd files are provided, which can be debugged in combination with the [lowcode-demo](https://github.com/alibaba/lowcode-demo) project. Refer to the file proxy rules [here](https://www.yuque.com/lce/doc/glz0fx). +After lowcode-engine is started, several umd files are provided, which can be debugged in combination with the [lowcode-demo](https://github.com/alibaba/lowcode-demo) project. Refer to the file proxy rules [here](https://lowcode-engine.cn/site/docs/participate/prepare). ## 🤝 Participation Please read first: -1. [How to configure the engine debugging environment? ](https://www.yuque.com/lce/doc/glz0fx) -2. [About the R&D collaboration process of the engine](https://www.yuque.com/lce/doc/contributing) -3. [Engineering Configuration of Engine](https://www.yuque.com/lce/doc/gxwqg6) +1. [How to configure the engine debugging environment? ](https://lowcode-engine.cn/site/docs/participate/prepare) +2. [About the R&D collaboration process of the engine](https://lowcode-engine.cn/site/docs/participate/flow) +3. [Engineering Configuration of Engine](https://lowcode-engine.cn/site/docs/participate/config) > Strongly recommend reading ["The Wisdom of Asking Questions"](https://github.com/ryanhanwu/How-To-Ask-Questions-The-Smart-Way), ["How to Ask Questions to the Open Source Community"](https: //github.com/seajs/seajs/issues/545) and [How to Report Bugs Effectively](http://www.chiark.greenend.org.uk/%7Esgtatham/bugs-cn.html), [ "How to Submit Unanswerable Questions to Open Source Projects"](https://zhuanlan.zhihu.com/p/25795393), better questions are easier to get help. (This paragraph refers to [antd](https://github.com/ant-design/ant-design)) diff --git a/packages/ignitor/public/index.html b/packages/ignitor/public/index.html index 8f182f42c5..147fe334d9 100644 --- a/packages/ignitor/public/index.html +++ b/packages/ignitor/public/index.html @@ -8,12 +8,12 @@

- This project only provides engine resource files. For usage, go for + This project only provides engine resource files. For usage, go for Lowcode Demo

For local debugging of lowcode engine, please visit - proxy documentation + proxy documentation to get more information.

From 6ae7c1bee5630cd5b48abaeba3b4b89d95960db8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E7=86=A0?= Date: Thu, 8 Dec 2022 11:41:13 +0800 Subject: [PATCH 227/823] refactor: remove dependency of shell from designer (#1328) --- packages/designer/jest.config.js | 3 +- packages/designer/package.json | 8 ++-- packages/designer/src/designer/designer.ts | 44 +++---------------- packages/designer/src/designer/dragon.ts | 7 ++- .../designer/setting/setting-prop-entry.ts | 3 +- packages/designer/src/document/history.ts | 5 --- packages/designer/src/document/node/node.ts | 6 +-- .../designer/src/plugin/plugin-context.ts | 30 ++++++------- packages/designer/src/plugin/plugin-types.ts | 40 ++++++++++------- .../tests/bugs/prop-variable-jse.test.ts | 4 +- .../bem-tools/drag-resize-engine.test.ts | 9 +--- .../bem-tools/manager.test.tsx | 17 +------ .../builtin-simulator/host-view.test.tsx | 32 -------------- .../tests/builtin-simulator/host.test.ts | 4 +- .../tests/builtin-simulator/viewport.test.ts | 6 +-- .../tests/designer/builtin-hotkey.test.ts | 3 +- .../designer/tests/designer/designer.test.ts | 29 +++++++----- .../designer/tests/designer/dragon.test.ts | 4 +- .../designer/tests/designer/scroller.test.ts | 3 +- .../designer/setting/setting-field.test.ts | 4 +- .../setting/setting-prop-entry.test.ts | 9 +--- .../setting/setting-top-entry.test.ts | 9 +--- .../document-model/document-model.test.ts | 6 +-- .../tests/document/history/history.test.ts | 14 ------ .../document/node/modal-nodes-manager.test.ts | 3 +- .../tests/document/node/node-children.test.ts | 3 +- .../designer/tests/document/node/node.test.ts | 8 ++-- .../tests/document/node/props/prop.test.ts | 5 +-- .../tests/project/project-methods.test.ts | 7 +-- packages/designer/tsconfig.json | 12 +++++ packages/engine/src/engine-core.ts | 3 +- .../engine/src/modules/shell-model-factory.ts | 18 ++++++++ packages/types/src/index.ts | 1 + packages/types/src/shell-model-factory.ts | 8 ++++ packages/types/src/shell/index.ts | 6 ++- 35 files changed, 159 insertions(+), 214 deletions(-) delete mode 100644 packages/designer/tests/builtin-simulator/host-view.test.tsx create mode 100644 packages/designer/tsconfig.json create mode 100644 packages/engine/src/modules/shell-model-factory.ts create mode 100644 packages/types/src/shell-model-factory.ts diff --git a/packages/designer/jest.config.js b/packages/designer/jest.config.js index f77cf4c9f7..6866d24a07 100644 --- a/packages/designer/jest.config.js +++ b/packages/designer/jest.config.js @@ -12,7 +12,8 @@ const jestConfig = { // testMatch: ['**/node-children.test.ts'], // testMatch: ['**/plugin-manager.test.ts'], // testMatch: ['**/history/history.test.ts'], - // testMatch: ['**/host-view.test.tsx'], + // testMatch: ['**/document-model.test.ts'], + // testMatch: ['**/prop.test.ts'], // testMatch: ['(/tests?/.*(test))\\.[jt]s$'], transformIgnorePatterns: [ `/node_modules/(?!${esModules})/`, diff --git a/packages/designer/package.json b/packages/designer/package.json index 830d2fa04b..86e79cf510 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -16,12 +16,9 @@ "license": "MIT", "dependencies": { "@alilc/lowcode-editor-core": "1.0.17", - "@alilc/lowcode-shell": "1.0.17", "@alilc/lowcode-types": "1.0.17", "@alilc/lowcode-utils": "1.0.17", "classnames": "^2.2.6", - "enzyme": "^3.11.0", - "enzyme-adapter-react-16": "^1.15.5", "react": "^16", "react-dom": "^16.7.0", "ric-shim": "^1.0.1", @@ -30,6 +27,7 @@ }, "devDependencies": { "@alib/build-scripts": "^0.1.29", + "@alilc/lowcode-shell": "1.0.17", "@alilc/lowcode-test-mate": "^1.0.1", "@testing-library/react": "^11.2.2", "@types/classnames": "^2.2.7", @@ -43,6 +41,10 @@ "babel-jest": "^26.5.2", "build-plugin-component": "^0.2.10", "build-scripts-config": "^0.1.8", + "enzyme": "^3.11.0", + "@types/enzyme": "^3.10.12", + "enzyme-adapter-react-16": "^1.15.5", + "@types/enzyme-adapter-react-16": "^1.0.6", "jest": "^26.6.3", "lodash": "^4.17.20", "moment": "^2.29.1", diff --git a/packages/designer/src/designer/designer.ts b/packages/designer/src/designer/designer.ts index dcb361fa20..7dbc3cbfdf 100644 --- a/packages/designer/src/designer/designer.ts +++ b/packages/designer/src/designer/designer.ts @@ -10,6 +10,7 @@ import { PropsList, NodeSchema, PropsTransducer, + IShellModelFactory, } from '@alilc/lowcode-types'; import { megreAssets, AssetsJson, isNodeSchema } from '@alilc/lowcode-utils'; import { Project } from '../project'; @@ -28,6 +29,7 @@ import { BemToolsManager } from '../builtin-simulator/bem-tools/manager'; export interface DesignerProps { editor: IEditor; + shellModelFactory: IShellModelFactory; className?: string; style?: object; defaultSchema?: ProjectSchema; @@ -58,6 +60,8 @@ export class Designer { readonly bemToolsManager = new BemToolsManager(this); + readonly shellModelFactory: IShellModelFactory; + get currentDocument() { return this.project.currentDocument; } @@ -72,25 +76,17 @@ export class Designer { constructor(props: DesignerProps) { makeObservable(this); - const { editor } = props; + const { editor, shellModelFactory } = props; this.editor = editor; + this.shellModelFactory = shellModelFactory; this.setProps(props); this.project = new Project(this, props.defaultSchema); - let startTime: any; - let src = ''; this.dragon.onDragstart((e) => { - startTime = Date.now() / 1000; this.detecting.enable = false; const { dragObject } = e; if (isDragNodeObject(dragObject)) { - const node = dragObject.nodes[0]?.parent; - const npm = node?.componentMeta?.npm; - src = - [npm?.package, npm?.componentName].filter((item) => !!item).join('-') || - node?.componentMeta?.componentName || - ''; if (dragObject.nodes.length === 1) { if (dragObject.nodes[0].parent) { // ensure current selecting @@ -135,34 +131,6 @@ export class Designer { if (nodes) { loc.document.selection.selectAll(nodes.map((o) => o.id)); setTimeout(() => this.activeTracker.track(nodes![0]), 10); - const endTime: any = Date.now() / 1000; - const parent = nodes[0]?.parent; - const npm = parent?.componentMeta?.npm; - const dest = - [npm?.package, npm?.componentName].filter((item) => !!item).join('-') || - parent?.componentMeta?.componentName || - ''; - // eslint-disable-next-line no-unused-expressions - // this.postEvent('drag', { - // time: (endTime - startTime).toFixed(2), - // selected: nodes - // ?.map((n) => { - // if (!n) { - // return; - // } - // // eslint-disable-next-line no-shadow - // const npm = n?.componentMeta?.npm; - // return ( - // [npm?.package, npm?.componentName].filter((item) => !!item).join('-') || - // n?.componentMeta?.componentName - // ); - // }) - // .join('&'), - // align: loc?.detail?.near?.align || '', - // pos: loc?.detail?.near?.pos || '', - // src, - // dest, - // }); } } } diff --git a/packages/designer/src/designer/dragon.ts b/packages/designer/src/designer/dragon.ts index 2e80b5dd45..5abfd049d1 100644 --- a/packages/designer/src/designer/dragon.ts +++ b/packages/designer/src/designer/dragon.ts @@ -1,7 +1,6 @@ import { EventEmitter } from 'events'; import { obx, makeObservable } from '@alilc/lowcode-editor-core'; -import { DragNodeObject, DragAnyObject, DragObjectType, DragNodeDataObject, DragObject } from '@alilc/lowcode-types'; -import { Node as ShellNode } from '@alilc/lowcode-shell'; +import { DragNodeObject, DragAnyObject, DragObjectType, DragNodeDataObject, DragObject, IPublicModelNode } from '@alilc/lowcode-types'; import { setNativeSelection, cursor } from '@alilc/lowcode-utils'; import { DropLocation } from './location'; import { Node, DocumentModel } from '../document'; @@ -201,13 +200,13 @@ export class Dragon { * @param dragObject 拖拽对象 * @param boostEvent 拖拽初始时事件 */ - boost(dragObject: DragObject, boostEvent: MouseEvent | DragEvent, fromRglNode?: Node | ShellNode) { + boost(dragObject: DragObject, boostEvent: MouseEvent | DragEvent, fromRglNode?: Node | IPublicModelNode) { const { designer } = this; const masterSensors = this.getMasterSensors(); const handleEvents = makeEventsHandler(boostEvent, masterSensors); const newBie = !isDragNodeObject(dragObject); const forceCopyState = - isDragNodeObject(dragObject) && dragObject.nodes.some((node: Node | ShellNode) => (typeof node.isSlot === 'function' ? node.isSlot() : node.isSlot)); + isDragNodeObject(dragObject) && dragObject.nodes.some((node: Node | IPublicModelNode) => (typeof node.isSlot === 'function' ? node.isSlot() : node.isSlot)); const isBoostFromDragAPI = isDragEvent(boostEvent); let lastSensor: ISensor | undefined; diff --git a/packages/designer/src/designer/setting/setting-prop-entry.ts b/packages/designer/src/designer/setting/setting-prop-entry.ts index 6eb5680a1f..dad8cb70df 100644 --- a/packages/designer/src/designer/setting/setting-prop-entry.ts +++ b/packages/designer/src/designer/setting/setting-prop-entry.ts @@ -1,7 +1,6 @@ import { obx, computed, makeObservable, runInAction } from '@alilc/lowcode-editor-core'; import { GlobalEvent, IEditor, ISetValueOptions } from '@alilc/lowcode-types'; import { uniqueId, isJSExpression } from '@alilc/lowcode-utils'; -import { SettingPropEntry as ShellSettingPropEntry } from '@alilc/lowcode-shell'; import { SettingEntry } from './setting-entry'; import { Node } from '../../document'; import { ComponentMeta } from '../../component-meta'; @@ -363,6 +362,6 @@ export class SettingPropEntry implements SettingEntry { } internalToShellPropEntry() { - return ShellSettingPropEntry.create(this) as any; + return this.designer.shellModelFactory.createSettingPropEntry(this); } } diff --git a/packages/designer/src/document/history.ts b/packages/designer/src/document/history.ts index 69f8662a70..96a1e40f7c 100644 --- a/packages/designer/src/document/history.ts +++ b/packages/designer/src/document/history.ts @@ -1,7 +1,6 @@ import { EventEmitter } from 'events'; import { reaction, untracked, globalContext, Editor } from '@alilc/lowcode-editor-core'; import { NodeSchema } from '@alilc/lowcode-types'; -import { History as ShellHistory } from '@alilc/lowcode-shell'; export interface Serialization { serialize(data: K): T; @@ -192,10 +191,6 @@ export class History { isModified() { return this.isSavePoint(); } - - internalToShellHistory() { - return new ShellHistory(this); - } } export class Session { diff --git a/packages/designer/src/document/node/node.ts b/packages/designer/src/document/node/node.ts index a20173a96d..ec6cc811bf 100644 --- a/packages/designer/src/document/node/node.ts +++ b/packages/designer/src/document/node/node.ts @@ -14,10 +14,10 @@ import { CompositeValue, GlobalEvent, ComponentAction, + IPublicModelNode, } from '@alilc/lowcode-types'; import { compatStage, isDOMText, isJSExpression } from '@alilc/lowcode-utils'; import { SettingTopEntry } from '@alilc/lowcode-designer'; -import { Node as ShellNode } from '@alilc/lowcode-shell'; import { Props, getConvertedExtraKey } from './props/props'; import { DocumentModel } from '../document-model'; import { NodeChildren } from './node-children'; @@ -366,8 +366,8 @@ export class Node { this._slotFor = slotFor; } - internalToShellNode(): ShellNode | null { - return ShellNode.create(this); + internalToShellNode(): IPublicModelNode | null { + return this.document.designer.shellModelFactory.createNode(this); } /** diff --git a/packages/designer/src/plugin/plugin-context.ts b/packages/designer/src/plugin/plugin-context.ts index 24c7065604..edb515543a 100644 --- a/packages/designer/src/plugin/plugin-context.ts +++ b/packages/designer/src/plugin/plugin-context.ts @@ -2,14 +2,14 @@ import { EngineConfig, engineConfig } from '@alilc/lowcode-editor-core'; import { ILowCodePluginManager } from '@alilc/lowcode-designer'; import { - Hotkey, - Project, - Skeleton, - Setters, - Material, - Event, - Common, -} from '@alilc/lowcode-shell'; + IPublicApiHotkey, + IPublicApiProject, + IPublicApiSkeleton, + IPublicApiSetters, + IPublicApiMaterial, + IPublicApiEvent, + IPublicApiCommon, +} from '@alilc/lowcode-types'; import { getLogger, Logger } from '@alilc/lowcode-utils'; import { ILowCodePluginContext, @@ -24,14 +24,14 @@ import { isValidPreferenceKey } from './plugin-utils'; export default class PluginContext implements ILowCodePluginContext, ILowCodePluginContextPrivate { - hotkey: Hotkey; - project: Project; - skeleton: Skeleton; - setters: Setters; - material: Material; - event: Event; + hotkey: IPublicApiHotkey; + project: IPublicApiProject; + skeleton: IPublicApiSkeleton; + setters: IPublicApiSetters; + material: IPublicApiMaterial; + event: IPublicApiEvent; config: EngineConfig; - common: Common; + common: IPublicApiCommon; logger: Logger; plugins: ILowCodePluginManager; preference: IPluginPreferenceMananger; diff --git a/packages/designer/src/plugin/plugin-types.ts b/packages/designer/src/plugin/plugin-types.ts index 2317b11ac8..279a1e459e 100644 --- a/packages/designer/src/plugin/plugin-types.ts +++ b/packages/designer/src/plugin/plugin-types.ts @@ -1,6 +1,16 @@ -import { CompositeObject, ComponentAction, MetadataTransducer } from '@alilc/lowcode-types'; import Logger from 'zen-logger'; -import { Hotkey, Skeleton, Project, Event, Material, Common } from '@alilc/lowcode-shell'; +import { + IPublicApiHotkey, + IPublicApiProject, + IPublicApiSkeleton, + IPublicApiSetters, + IPublicApiMaterial, + IPublicApiEvent, + IPublicApiCommon, + CompositeObject, + ComponentAction, + MetadataTransducer, +} from '@alilc/lowcode-types'; import { EngineConfig } from '@alilc/lowcode-editor-core'; import { Setters } from '../types'; @@ -95,27 +105,27 @@ export interface IPluginPreferenceMananger { } export interface ILowCodePluginContext { - get skeleton(): Skeleton; - get hotkey(): Hotkey; - get setters(): Setters; + get skeleton(): IPublicApiSkeleton; + get hotkey(): IPublicApiHotkey; + get setters(): IPublicApiSetters; get config(): EngineConfig; - get material(): Material; - get event(): Event; - get project(): Project; - get common(): Common; + get material(): IPublicApiMaterial; + get event(): IPublicApiEvent; + get project(): IPublicApiProject; + get common(): IPublicApiCommon; logger: Logger; plugins: ILowCodePluginManager; preference: IPluginPreferenceMananger; } export interface ILowCodePluginContextPrivate { - set hotkey(hotkey: Hotkey); - set project(project: Project); - set skeleton(skeleton: Skeleton); + set hotkey(hotkey: IPublicApiHotkey); + set project(project: IPublicApiProject); + set skeleton(skeleton: IPublicApiSkeleton); set setters(setters: Setters); - set material(material: Material); - set event(event: Event); + set material(material: IPublicApiMaterial); + set event(event: IPublicApiEvent); set config(config: EngineConfig); - set common(common: Common); + set common(common: IPublicApiCommon); } export interface ILowCodePluginContextApiAssembler { assembleApis: (context: ILowCodePluginContextPrivate) => void; diff --git a/packages/designer/tests/bugs/prop-variable-jse.test.ts b/packages/designer/tests/bugs/prop-variable-jse.test.ts index 6483701919..a27fa59cf8 100644 --- a/packages/designer/tests/bugs/prop-variable-jse.test.ts +++ b/packages/designer/tests/bugs/prop-variable-jse.test.ts @@ -1,4 +1,3 @@ -// @ts-nocheck import { Editor } from '@alilc/lowcode-editor-core'; import { TransformStage } from '@alilc/lowcode-types'; import { isPlainObject, isVariable, isJSBlock } from '@alilc/lowcode-utils'; @@ -7,6 +6,7 @@ import { Designer } from '../../src/designer/designer'; import { DocumentModel } from '../../src/document/document-model'; import { Project } from '../../src/project/project'; import formSchema from '../fixtures/schema/form'; +import { shellModelFactory } from '../../../engine/src/modules/shell-model-factory'; /** * bug 背景: @@ -58,7 +58,7 @@ describe('Node 方法测试', () => { it('原始 prop 值是 variable 结构,通过一个 propsReducer 转成了 JSExpression 结构', () => { editor = new Editor(); - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); designer.addPropsReducer(upgradePropsReducer, TransformStage.Upgrade); project = designer.project; doc = new DocumentModel(project, formSchema); diff --git a/packages/designer/tests/builtin-simulator/bem-tools/drag-resize-engine.test.ts b/packages/designer/tests/builtin-simulator/bem-tools/drag-resize-engine.test.ts index 5f52e14b33..ccdc4b2b63 100644 --- a/packages/designer/tests/builtin-simulator/bem-tools/drag-resize-engine.test.ts +++ b/packages/designer/tests/builtin-simulator/bem-tools/drag-resize-engine.test.ts @@ -1,17 +1,12 @@ import '../../fixtures/window'; -import { set } from '../../utils'; import { Editor, globalContext } from '@alilc/lowcode-editor-core'; import { Project } from '../../../src/project/project'; import { DocumentModel } from '../../../src/document/document-model'; import { Designer } from '../../../src/designer/designer'; import DragResizeEngine from '../../../src/builtin-simulator/bem-tools/drag-resize-engine'; import formSchema from '../../fixtures/schema/form'; -import divMetadata from '../../fixtures/component-metadata/div'; -import formMetadata from '../../fixtures/component-metadata/form'; -import otherMeta from '../../fixtures/component-metadata/other'; -import pageMetadata from '../../fixtures/component-metadata/page'; import { fireEvent, createEvent } from '@testing-library/react'; -import { create } from 'lodash'; +import { shellModelFactory } from '../../../../engine/src/modules/shell-model-factory'; describe('DragResizeEngine 测试', () => { let editor: Editor; @@ -26,7 +21,7 @@ describe('DragResizeEngine 测试', () => { }); beforeEach(() => { - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); project = designer.project; doc = project.createDocument(formSchema); doc.open(); diff --git a/packages/designer/tests/builtin-simulator/bem-tools/manager.test.tsx b/packages/designer/tests/builtin-simulator/bem-tools/manager.test.tsx index 32e34020f7..bed1e27de9 100644 --- a/packages/designer/tests/builtin-simulator/bem-tools/manager.test.tsx +++ b/packages/designer/tests/builtin-simulator/bem-tools/manager.test.tsx @@ -1,21 +1,8 @@ import '../../fixtures/window'; -import { set, delayObxTick, delay } from '../../utils'; import { Editor } from '@alilc/lowcode-editor-core'; -import { Project } from '../../../src/project/project'; -import { DocumentModel } from '../../../src/document/document-model'; -import { - isRootNode, - Node, - isNode, - comparePosition, - contains, - insertChild, - insertChildren, - PositionNO, -} from '../../../src/document/node/node'; import { Designer } from '../../../src/designer/designer'; import { BemToolsManager } from '../../../src/builtin-simulator/bem-tools/manager'; -import formSchema from '../../fixtures/schema/form'; +import { shellModelFactory } from '../../../../engine/src/modules/shell-model-factory'; describe('Node 方法测试', () => { let editor: Editor; @@ -26,7 +13,7 @@ describe('Node 方法测试', () => { beforeEach(() => { editor = new Editor(); - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); // project = designer.project; // doc = new DocumentModel(project, formSchema); manager = new BemToolsManager(designer); diff --git a/packages/designer/tests/builtin-simulator/host-view.test.tsx b/packages/designer/tests/builtin-simulator/host-view.test.tsx deleted file mode 100644 index 38ce43bb4a..0000000000 --- a/packages/designer/tests/builtin-simulator/host-view.test.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import React from 'react'; -import set from 'lodash/set'; -import cloneDeep from 'lodash/cloneDeep'; -import '../fixtures/window'; -import { Editor } from '@alilc/lowcode-editor-core'; -import { Project } from '../../src/project/project'; -import { Node } from '../../src/document/node/node'; -import TestRenderer from 'react-test-renderer'; -import { configure, render, mount } from 'enzyme'; -import Adapter from 'enzyme-adapter-react-16'; -import { Designer } from '../../src/designer/designer'; -import formSchema from '../fixtures/schema/form'; -import { getIdsFromSchema, getNodeFromSchemaById } from '../utils'; -import { BuiltinSimulatorHostView } from '../../src/builtin-simulator/host-view'; - -configure({ adapter: new Adapter() }); -const editor = new Editor(); - -describe('host-view 测试', () => { - let designer: Designer; - beforeEach(() => { - designer = new Designer({ editor }); - }); - afterEach(() => { - designer._componentMetasMap.clear(); - designer = null; - }); - - it.skip('host-view', () => { - const hostView = render(); - }); -}); diff --git a/packages/designer/tests/builtin-simulator/host.test.ts b/packages/designer/tests/builtin-simulator/host.test.ts index 37713f3304..4b959565de 100644 --- a/packages/designer/tests/builtin-simulator/host.test.ts +++ b/packages/designer/tests/builtin-simulator/host.test.ts @@ -1,4 +1,3 @@ -// @ts-ignore import '../fixtures/window'; import { Editor, globalContext } from '@alilc/lowcode-editor-core'; import { @@ -15,6 +14,7 @@ import formSchema from '../fixtures/schema/form'; import { getMockDocument, getMockWindow, getMockEvent, delayObxTick } from '../utils'; import { BuiltinSimulatorHost } from '../../src/builtin-simulator/host'; import { fireEvent } from '@testing-library/react'; +import { shellModelFactory } from '../../../engine/src/modules/shell-model-factory'; describe('Host 测试', () => { let editor: Editor; @@ -29,7 +29,7 @@ describe('Host 测试', () => { }); beforeEach(() => { - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); project = designer.project; designer.createComponentMeta(pageMetadata); doc = project.createDocument(formSchema); diff --git a/packages/designer/tests/builtin-simulator/viewport.test.ts b/packages/designer/tests/builtin-simulator/viewport.test.ts index 2938e008a1..e9972fc7c3 100644 --- a/packages/designer/tests/builtin-simulator/viewport.test.ts +++ b/packages/designer/tests/builtin-simulator/viewport.test.ts @@ -1,11 +1,11 @@ import '../fixtures/window'; -import { getMockWindow, set, getMockElement, delay } from '../utils'; +import { getMockWindow, getMockElement, delay } from '../utils'; import { Editor, globalContext } from '@alilc/lowcode-editor-core'; import { Project } from '../../src/project/project'; import { DocumentModel } from '../../src/document/document-model'; import Viewport from '../../src/builtin-simulator/viewport'; import { Designer } from '../../src/designer/designer'; -import { fireEvent } from '@testing-library/react'; +import { shellModelFactory } from '../../../engine/src/modules/shell-model-factory'; describe('Viewport 测试', () => { @@ -28,7 +28,7 @@ describe('Viewport 测试', () => { }); beforeEach(() => { - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); project = designer.project; // doc = project.createDocument(formSchema); }); diff --git a/packages/designer/tests/designer/builtin-hotkey.test.ts b/packages/designer/tests/designer/builtin-hotkey.test.ts index d0fa8a47f8..6e7699d4ad 100644 --- a/packages/designer/tests/designer/builtin-hotkey.test.ts +++ b/packages/designer/tests/designer/builtin-hotkey.test.ts @@ -5,6 +5,7 @@ import formSchema from '../fixtures/schema/form'; import '../../src/designer/builtin-hotkey'; import { fireEvent } from '@testing-library/react'; import { isInLiveEditing } from '../../src/designer/builtin-hotkey'; +import { shellModelFactory } from '../../../engine/src/modules/shell-model-factory'; const editor = new Editor(); @@ -23,7 +24,7 @@ describe('快捷键测试', () => { globalContext.register(editor, Editor); }); beforeEach(() => { - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); editor.set('designer', designer); designer.project.open(formSchema); }); diff --git a/packages/designer/tests/designer/designer.test.ts b/packages/designer/tests/designer/designer.test.ts index 3dd4749cdb..c6d8658c40 100644 --- a/packages/designer/tests/designer/designer.test.ts +++ b/packages/designer/tests/designer/designer.test.ts @@ -12,6 +12,7 @@ import divMetadata from '../fixtures/component-metadata/div'; import { delayObxTick } from '../utils'; import { fireEvent } from '@testing-library/react'; import { DragObjectType } from '@alilc/lowcode-types'; +import { shellModelFactory } from '../../../engine/src/modules/shell-model-factory'; const mockNode = { internalToShellNode() { @@ -32,7 +33,7 @@ describe('Designer 测试', () => { }); beforeEach(() => { - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); project = designer.project; doc = project.createDocument(formSchema); dragon = new Dragon(designer); @@ -58,6 +59,7 @@ describe('Designer 测试', () => { const designer = new Designer({ editor, + shellModelFactory, onDragstart: dragStartMockFn, onDrag: dragMockFn, onDragend: dragEndMockFn, @@ -124,6 +126,7 @@ describe('Designer 测试', () => { const designer = new Designer({ editor, + shellModelFactory, onDragstart: dragStartMockFn, onDrag: dragMockFn, onDragend: dragEndMockFn, @@ -245,14 +248,18 @@ describe('Designer 测试', () => { suspensed: true, componentMetadatas: [buttonMetadata, divMetadata], }; - designer = new Designer({ editor, ...initialProps }); + designer = new Designer({ + editor, + shellModelFactory, + ...initialProps, + }); expect(designer.simulatorComponent).toEqual({ isSimulatorComp: true }); expect(designer.simulatorProps).toEqual({ designMode: 'design' }); expect(designer.suspensed).toBeTruthy(); - expect(designer._componentMetasMap.has('Div')).toBeTruthy(); - expect(designer._componentMetasMap.has('Button')).toBeTruthy(); - const { editor: editorFromDesigner, ...others } = designer.props; + expect((designer as any)._componentMetasMap.has('Div')).toBeTruthy(); + expect((designer as any)._componentMetasMap.has('Button')).toBeTruthy(); + const { editor: editorFromDesigner, shellModelFactory: shellModelFactoryFromDesigner, ...others } = (designer as any).props; expect(others).toEqual(initialProps); expect(designer.get('simulatorProps')).toEqual({ designMode: 'design' }); expect(designer.get('suspensed')).toBeTruthy(); @@ -270,9 +277,9 @@ describe('Designer 测试', () => { expect(designer.simulatorComponent).toEqual({ isSimulatorComp2: true }); expect(designer.simulatorProps).toEqual({ designMode: 'live' }); expect(designer.suspensed).toBeFalsy(); - expect(designer._componentMetasMap.has('Button')).toBeTruthy(); - expect(designer._componentMetasMap.has('Div')).toBeTruthy(); - const { editor: editorFromDesigner2, ...others2 } = designer.props; + expect((designer as any)._componentMetasMap.has('Button')).toBeTruthy(); + expect((designer as any)._componentMetasMap.has('Div')).toBeTruthy(); + const { editor: editorFromDesigner2, shellModelFactory: shellModelFactoryFromDesigner2, ...others2 } = (designer as any).props; expect(others2).toEqual(updatedProps); // 第三次设置 props,跟第二次值一样,for 覆盖率测试 @@ -282,9 +289,9 @@ describe('Designer 测试', () => { expect(designer.simulatorComponent).toEqual({ isSimulatorComp2: true }); expect(designer.simulatorProps).toEqual({ designMode: 'live' }); expect(designer.suspensed).toBeFalsy(); - expect(designer._componentMetasMap.has('Button')).toBeTruthy(); - expect(designer._componentMetasMap.has('Div')).toBeTruthy(); - const { editor: editorFromDesigner3, ...others3 } = designer.props; + expect((designer as any)._componentMetasMap.has('Button')).toBeTruthy(); + expect((designer as any)._componentMetasMap.has('Div')).toBeTruthy(); + const { editor: editorFromDesigner3, shellModelFactory: shellModelFactoryFromDesigner3, ...others3 } = (designer as any).props; expect(others3).toEqual(updatedProps); }); diff --git a/packages/designer/tests/designer/dragon.test.ts b/packages/designer/tests/designer/dragon.test.ts index 42216f06d8..bfafa06511 100644 --- a/packages/designer/tests/designer/dragon.test.ts +++ b/packages/designer/tests/designer/dragon.test.ts @@ -1,5 +1,4 @@ import '../fixtures/window'; -import { set } from '../utils'; import { Editor, globalContext } from '@alilc/lowcode-editor-core'; import { Project } from '../../src/project/project'; import { DocumentModel } from '../../src/document/document-model'; @@ -18,6 +17,7 @@ import { import { DragObjectType } from '@alilc/lowcode-types'; import formSchema from '../fixtures/schema/form'; import { fireEvent } from '@testing-library/react'; +import { shellModelFactory } from '../../../engine/src/modules/shell-model-factory'; describe('Dragon 测试', () => { let editor: Editor; @@ -32,7 +32,7 @@ describe('Dragon 测试', () => { }); beforeEach(() => { - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); project = designer.project; doc = project.createDocument(formSchema); dragon = new Dragon(designer); diff --git a/packages/designer/tests/designer/scroller.test.ts b/packages/designer/tests/designer/scroller.test.ts index 5265596c6e..ff03608b04 100644 --- a/packages/designer/tests/designer/scroller.test.ts +++ b/packages/designer/tests/designer/scroller.test.ts @@ -8,6 +8,7 @@ import { Dragon, } from '../../src/designer/dragon'; import formSchema from '../fixtures/schema/form'; +import { shellModelFactory } from '../../../engine/src/modules/shell-model-factory'; describe('Scroller 测试', () => { let editor: Editor; @@ -22,7 +23,7 @@ describe('Scroller 测试', () => { }); beforeEach(() => { - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); project = designer.project; doc = project.createDocument(formSchema); dragon = new Dragon(designer); diff --git a/packages/designer/tests/designer/setting/setting-field.test.ts b/packages/designer/tests/designer/setting/setting-field.test.ts index 0e600e2eaf..fb8c9d16f2 100644 --- a/packages/designer/tests/designer/setting/setting-field.test.ts +++ b/packages/designer/tests/designer/setting/setting-field.test.ts @@ -1,7 +1,6 @@ // @ts-nocheck import '../../fixtures/window'; import { Editor } from '@alilc/lowcode-editor-core'; -import { Project } from '../../../src/project/project'; import { SettingTopEntry } from '../../../src/designer/setting/setting-top-entry'; import { SettingField } from '../../../src/designer/setting/setting-field'; import { Node } from '../../../src/document/node/node'; @@ -10,6 +9,7 @@ import settingSchema from '../../fixtures/schema/setting'; import buttonMeta from '../../fixtures/component-metadata/button'; import { DocumentModel } from 'designer/src/document'; import { delayObxTick } from '../../utils'; +import { shellModelFactory } from '../../../../engine/src/modules/shell-model-factory'; const editor = new Editor(); @@ -17,7 +17,7 @@ describe('setting-field 测试', () => { let designer: Designer; let doc: DocumentModel; beforeEach(() => { - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); designer.createComponentMeta(buttonMeta); doc = designer.project.open(settingSchema); }); diff --git a/packages/designer/tests/designer/setting/setting-prop-entry.test.ts b/packages/designer/tests/designer/setting/setting-prop-entry.test.ts index 72b3940355..c9aee1244d 100644 --- a/packages/designer/tests/designer/setting/setting-prop-entry.test.ts +++ b/packages/designer/tests/designer/setting/setting-prop-entry.test.ts @@ -1,18 +1,13 @@ -// @ts-nocheck -import set from 'lodash/set'; -import cloneDeep from 'lodash/cloneDeep'; import '../../fixtures/window'; import { Editor } from '@alilc/lowcode-editor-core'; -import { Project } from '../../../src/project/project'; import { SettingTopEntry } from '../../../src/designer/setting/setting-top-entry'; import { SettingPropEntry } from '../../../src/designer/setting/setting-prop-entry'; import { Node } from '../../../src/document/node/node'; import { Designer } from '../../../src/designer/designer'; -import formSchema from '../../../fixtures/schema/form'; import settingSchema from '../../fixtures/schema/setting'; import divMeta from '../../fixtures/component-metadata/div'; -import { getIdsFromSchema, getNodeFromSchemaById } from '../../utils'; import { DocumentModel } from 'designer/src/document'; +import { shellModelFactory } from '../../../../engine/src/modules/shell-model-factory'; const editor = new Editor(); @@ -20,7 +15,7 @@ describe('setting-prop-entry 测试', () => { let designer: Designer; let doc: DocumentModel; beforeEach(() => { - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); designer.createComponentMeta(divMeta); doc = designer.project.open(settingSchema); }); diff --git a/packages/designer/tests/designer/setting/setting-top-entry.test.ts b/packages/designer/tests/designer/setting/setting-top-entry.test.ts index e7a2a7a662..caad129171 100644 --- a/packages/designer/tests/designer/setting/setting-top-entry.test.ts +++ b/packages/designer/tests/designer/setting/setting-top-entry.test.ts @@ -1,22 +1,17 @@ -// @ts-nocheck -import set from 'lodash/set'; -import cloneDeep from 'lodash/cloneDeep'; import '../../fixtures/window'; import { Editor } from '@alilc/lowcode-editor-core'; -import { Project } from '../../../src/project/project'; import { Node } from '../../../src/document/node/node'; import { Designer } from '../../../src/designer/designer'; -import formSchema from '../../fixtures/schema/form'; import settingSchema from '../../fixtures/schema/setting'; import divMeta from '../../fixtures/component-metadata/div'; -import { getIdsFromSchema, getNodeFromSchemaById } from '../../utils'; +import { shellModelFactory } from '../../../../engine/src/modules/shell-model-factory'; const editor = new Editor(); describe('setting-top-entry 测试', () => { let designer: Designer; beforeEach(() => { - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); }); afterEach(() => { designer._componentMetasMap.clear(); diff --git a/packages/designer/tests/document/document-model/document-model.test.ts b/packages/designer/tests/document/document-model/document-model.test.ts index 1061a609c5..9eb7b41ffa 100644 --- a/packages/designer/tests/document/document-model/document-model.test.ts +++ b/packages/designer/tests/document/document-model/document-model.test.ts @@ -2,15 +2,13 @@ import '../../fixtures/window'; import { DocumentModel, isDocumentModel, isPageSchema } from '../../../src/document/document-model'; import { Editor } from '@alilc/lowcode-editor-core'; import { Project } from '../../../src/project/project'; -import { Node } from '../../../src/document/node/node'; import { Designer } from '../../../src/designer/designer'; import formSchema from '../../fixtures/schema/form'; import divMeta from '../../fixtures/component-metadata/div'; import formMeta from '../../fixtures/component-metadata/form'; import otherMeta from '../../fixtures/component-metadata/other'; import pageMeta from '../../fixtures/component-metadata/page'; -// const { DocumentModel } = require('../../../src/document/document-model'); -// const { Node } = require('../__mocks__/node'); +import { shellModelFactory } from '../../../../engine/src/modules/shell-model-factory'; describe('document-model 测试', () => { let editor: Editor; @@ -19,7 +17,7 @@ describe('document-model 测试', () => { beforeEach(() => { editor = new Editor(); - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); project = designer.project; }); diff --git a/packages/designer/tests/document/history/history.test.ts b/packages/designer/tests/document/history/history.test.ts index a4c6d3a66b..960b183f91 100644 --- a/packages/designer/tests/document/history/history.test.ts +++ b/packages/designer/tests/document/history/history.test.ts @@ -272,20 +272,6 @@ describe('History', () => { expect(history.records).toHaveLength(0); }); - it('internalToShellHistory()', async () => { - const history = new History( - () => { - const data = tree.toObject(); - return data; - }, - (data) => { - mockRedoFn(data); - }, - ); - - expect(history.internalToShellHistory().isModified).toBeUndefined(); - }); - it('sleep & wakeup', async () => { const mockRedoFn = jest.fn(); const history = new History( diff --git a/packages/designer/tests/document/node/modal-nodes-manager.test.ts b/packages/designer/tests/document/node/modal-nodes-manager.test.ts index 80ca53b3e5..3e5dcdb79e 100644 --- a/packages/designer/tests/document/node/modal-nodes-manager.test.ts +++ b/packages/designer/tests/document/node/modal-nodes-manager.test.ts @@ -7,6 +7,7 @@ import { Designer } from '../../../src/designer/designer'; import formSchema from '../../fixtures/schema/form-with-modal'; import dlgMetadata from '../../fixtures/component-metadata/dialog'; import { getModalNodes } from '../../../src/document/node/modal-nodes-manager'; +import { shellModelFactory } from '../../../../engine/src/modules/shell-model-factory'; let editor: Editor; let designer: Designer; @@ -15,7 +16,7 @@ let doc: DocumentModel; beforeEach(() => { editor = new Editor(); - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); designer.createComponentMeta(dlgMetadata); project = designer.project; doc = new DocumentModel(project, formSchema); diff --git a/packages/designer/tests/document/node/node-children.test.ts b/packages/designer/tests/document/node/node-children.test.ts index c48c9e7085..1aa7e3ccb3 100644 --- a/packages/designer/tests/document/node/node-children.test.ts +++ b/packages/designer/tests/document/node/node-children.test.ts @@ -8,6 +8,7 @@ import { import { Designer } from '../../../src/designer/designer'; import formSchema from '../../fixtures/schema/form'; import divMetadata from '../../fixtures/component-metadata/div'; +import { shellModelFactory } from '../../../../engine/src/modules/shell-model-factory'; describe('NodeChildren 方法测试', () => { let editor: Editor; @@ -17,7 +18,7 @@ describe('NodeChildren 方法测试', () => { beforeEach(() => { editor = new Editor(); - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); project = designer.project; doc = new DocumentModel(project, formSchema); }); diff --git a/packages/designer/tests/document/node/node.test.ts b/packages/designer/tests/document/node/node.test.ts index 113360d448..d8915c9916 100644 --- a/packages/designer/tests/document/node/node.test.ts +++ b/packages/designer/tests/document/node/node.test.ts @@ -1,6 +1,6 @@ // @ts-nocheck import '../../fixtures/window'; -import { set, delayObxTick, delay } from '../../utils'; +import { set } from '../../utils'; import { Editor } from '@alilc/lowcode-editor-core'; import { Project } from '../../../src/project/project'; import { DocumentModel } from '../../../src/document/document-model'; @@ -10,8 +10,6 @@ import { isNode, comparePosition, contains, - insertChild, - insertChildren, PositionNO, } from '../../../src/document/node/node'; import { Designer } from '../../../src/designer/designer'; @@ -20,11 +18,11 @@ import divMetadata from '../../fixtures/component-metadata/div'; import dialogMetadata from '../../fixtures/component-metadata/dialog'; import btnMetadata from '../../fixtures/component-metadata/button'; import formMetadata from '../../fixtures/component-metadata/form'; -import otherMeta from '../../fixtures/component-metadata/other'; import pageMetadata from '../../fixtures/component-metadata/page'; import rootHeaderMetadata from '../../fixtures/component-metadata/root-header'; import rootContentMetadata from '../../fixtures/component-metadata/root-content'; import rootFooterMetadata from '../../fixtures/component-metadata/root-footer'; +import { shellModelFactory } from '../../../../engine/src/modules/shell-model-factory'; describe('Node 方法测试', () => { let editor: Editor; @@ -34,7 +32,7 @@ describe('Node 方法测试', () => { beforeEach(() => { editor = new Editor(); - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); project = designer.project; doc = new DocumentModel(project, formSchema); }); diff --git a/packages/designer/tests/document/node/props/prop.test.ts b/packages/designer/tests/document/node/props/prop.test.ts index d7b125430d..3d7914a853 100644 --- a/packages/designer/tests/document/node/props/prop.test.ts +++ b/packages/designer/tests/document/node/props/prop.test.ts @@ -1,11 +1,10 @@ -// @ts-nocheck import '../../../fixtures/window'; -import { delayObxTick } from '../../../utils'; import { Editor, engineConfig } from '@alilc/lowcode-editor-core'; import { Designer } from '../../../../src/designer/designer'; import { DocumentModel } from '../../../../src/document/document-model'; import { Prop, isProp, isValidArrayIndex } from '../../../../src/document/node/props/prop'; import { TransformStage } from '@alilc/lowcode-types'; +import { shellModelFactory } from '../../../../../engine/src/modules/shell-model-factory'; const slotNodeImportMockFn = jest.fn(); const slotNodeRemoveMockFn = jest.fn(); @@ -465,7 +464,7 @@ describe('Prop 类测试', () => { describe('slotNode / setAsSlot', () => { const editor = new Editor(); - const designer = new Designer({ editor }); + const designer = new Designer({ editor, shellModelFactory }); const doc = new DocumentModel(designer.project, { componentName: 'Page', children: [ diff --git a/packages/designer/tests/project/project-methods.test.ts b/packages/designer/tests/project/project-methods.test.ts index 0e545e4f4e..b546f8f520 100644 --- a/packages/designer/tests/project/project-methods.test.ts +++ b/packages/designer/tests/project/project-methods.test.ts @@ -1,13 +1,10 @@ -import set from 'lodash/set'; -import cloneDeep from 'lodash/cloneDeep'; import '../fixtures/window'; import { Editor } from '@alilc/lowcode-editor-core'; import { Project } from '../../src/project/project'; import { DocumentModel } from '../../src/document/document-model'; -import { Node } from '../../src/document/node/node'; import { Designer } from '../../src/designer/designer'; import formSchema from '../fixtures/schema/form'; -import { getIdsFromSchema, getNodeFromSchemaById } from '../utils'; +import { shellModelFactory } from '../../../engine/src/modules/shell-model-factory'; describe.only('Project 方法测试', () => { let editor: Editor; @@ -17,7 +14,7 @@ describe.only('Project 方法测试', () => { beforeEach(() => { editor = new Editor(); - designer = new Designer({ editor }); + designer = new Designer({ editor, shellModelFactory }); project = designer.project; doc = new DocumentModel(project, formSchema); }); diff --git a/packages/designer/tsconfig.json b/packages/designer/tsconfig.json new file mode 100644 index 0000000000..9136085c95 --- /dev/null +++ b/packages/designer/tsconfig.json @@ -0,0 +1,12 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "outDir": "lib", + "types": ["node","jest"] + }, + "include": [ + "./src/", + "./tests/" + ], + "exclude": ["**/lib", "**/es", "node_modules"] +} diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index 55355f5745..acc961c16c 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -32,6 +32,7 @@ import { getLogger, isPlainObject } from '@alilc/lowcode-utils'; import './modules/live-editing'; import classes from './modules/classes'; import symbols from './modules/symbols'; +import { shellModelFactory } from './modules/shell-model-factory'; export * from './modules/skeleton-types'; export * from './modules/designer-types'; @@ -46,7 +47,7 @@ globalContext.register(editor, 'editor'); const innerSkeleton = new InnerSkeleton(editor); editor.set('skeleton' as any, innerSkeleton); -const designer = new Designer({ editor }); +const designer = new Designer({ editor, shellModelFactory }); editor.set('designer' as any, designer); const { project: innerProject } = designer; diff --git a/packages/engine/src/modules/shell-model-factory.ts b/packages/engine/src/modules/shell-model-factory.ts new file mode 100644 index 0000000000..05c7b19cb7 --- /dev/null +++ b/packages/engine/src/modules/shell-model-factory.ts @@ -0,0 +1,18 @@ +import { + Node as InnerNode, + SettingField as InnerSettingField, +} from '@alilc/lowcode-designer'; +import { IShellModelFactory, IPublicModelNode, IPublicModelSettingPropEntry } from '@alilc/lowcode-types'; +import { + Node, + SettingPropEntry, +} from '@alilc/lowcode-shell'; +class ShellModelFactory implements IShellModelFactory { + createNode(node: InnerNode | null | undefined): IPublicModelNode | null { + return Node.create(node); + } + createSettingPropEntry(prop: InnerSettingField): IPublicModelSettingPropEntry { + return SettingPropEntry.create(prop); + } +} +export const shellModelFactory = new ShellModelFactory(); \ No newline at end of file diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 708c34326a..8ebd296931 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -27,5 +27,6 @@ export * from './editor-skeleton'; export * from './designer'; export * from './dragon'; export * from './shell'; +export * from './shell-model-factory'; // TODO: remove this in future versions export * from './deprecated'; diff --git a/packages/types/src/shell-model-factory.ts b/packages/types/src/shell-model-factory.ts new file mode 100644 index 0000000000..a7a57648f1 --- /dev/null +++ b/packages/types/src/shell-model-factory.ts @@ -0,0 +1,8 @@ +import { IPublicModelSettingPropEntry, IPublicModelNode } from './shell'; + +export interface IShellModelFactory { + // TODO: 需要给 innerNode 提供一个 interface 并用在这里 + createNode(node: any | null | undefined): IPublicModelNode | null; + // TODO: 需要给 InnerSettingField 提供一个 interface 并用在这里 + createSettingPropEntry(prop: any): IPublicModelSettingPropEntry; +} diff --git a/packages/types/src/shell/index.ts b/packages/types/src/shell/index.ts index c0b2d52808..0ee50daea3 100644 --- a/packages/types/src/shell/index.ts +++ b/packages/types/src/shell/index.ts @@ -1,5 +1,7 @@ -import { IPublicModelNode } from './model/node'; -import { IPublicModelProp } from './model/prop'; +import { + IPublicModelNode, + IPublicModelProp, +} from './model'; export interface PropChangeOptions { key?: string | number; From c314c952eb8b5efeecfe63cb03cf1b5cca0ebd3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9E=97=E7=86=A0?= Date: Thu, 8 Dec 2022 11:42:49 +0800 Subject: [PATCH 228/823] docs: replace yuque links (#1332) --- docs/community/issue.md | 22 ++++++------ docs/docs/api/index.md | 2 +- docs/docs/api/init.md | 2 +- docs/docs/api/material.md | 2 +- docs/docs/api/project.md | 2 +- docs/docs/api/skeleton.md | 4 +-- docs/docs/demoUsage/intro.md | 34 +++++++++--------- docs/docs/demoUsage/makeStuff/table.md | 16 ++++----- docs/docs/demoUsage/panels/canvas.md | 16 ++++----- docs/docs/demoUsage/panels/code.md | 36 +++++++++---------- docs/docs/demoUsage/panels/component.md | 4 +-- docs/docs/demoUsage/panels/datasource.md | 4 +-- docs/docs/demoUsage/panels/settings.md | 4 +-- docs/docs/faq/faq002.md | 10 +++--- docs/docs/faq/faq003.md | 4 +-- docs/docs/faq/faq005.md | 6 ++-- docs/docs/faq/faq007.md | 4 +-- docs/docs/faq/faq009.md | 2 +- docs/docs/faq/faq010.md | 2 +- docs/docs/faq/faq011.md | 8 ++--- docs/docs/faq/faq012.md | 2 +- docs/docs/faq/faq014.md | 2 +- docs/docs/faq/faq018.md | 6 ++-- docs/docs/faq/faq020.md | 2 +- docs/docs/guide/design/datasourceEngine.md | 3 -- docs/docs/guide/design/renderer.md | 4 +-- .../guide/expand/runtime/codeGeneration.md | 2 +- docs/docs/participate/flow.md | 2 +- docs/docs/specs/material-spec.md | 2 +- .../test-cases/rax-app/demo01/schema.json5 | 1 - .../test-cases/rax-app/demo02/schema.json5 | 1 - .../test-cases/rax-app/demo03/schema.json5 | 1 - .../test-cases/rax-app/demo05/schema.json5 | 1 - .../rax-app/demo12-refs/schema.json5 | 1 - modules/material-parser/README.md | 2 +- packages/editor-core/src/config.ts | 4 +-- .../src/transducers/addon-combine.ts | 2 +- 37 files changed, 107 insertions(+), 115 deletions(-) diff --git a/docs/community/issue.md b/docs/community/issue.md index ebda01afcf..2b6bd0f962 100644 --- a/docs/community/issue.md +++ b/docs/community/issue.md @@ -33,7 +33,7 @@ sidebar_position: 2 ### 不同优先级的示例 #### 【支持快】通过线上 Demo 地址 + 控制台输入 API 可复现。 **示例** -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1656387671833-cd44507b-af59-45ec-b0da-f4f0ef61e92e.png#clientId=uaa040ac3-dccc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=295&id=ub61f0ab8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1862&originWidth=3322&originalType=binary&ratio=1&rotation=0&showTitle=false&size=5033674&status=done&style=none&taskId=u3646a3b6-4b22-48e7-94e3-564a09cfa24&title=&width=527) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01np6ARb1KnJFOELjXg_!!6000000001208-2-tps-3322-1862.png) 复现步骤: - 打开线上 demo @@ -70,13 +70,13 @@ window.AliLowCodeEngine.project.openDocument('docl4xkca5b') #### 【支持稍慢】通过线上 demo + 完整操作步骤可复现 **示例** 1.使用 antd 组件 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1656387998779-9f621c7f-82cb-48ad-94fc-84c2cd46065c.png#clientId=uaa040ac3-dccc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=906&id=u0ad0726a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1812&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=838860&status=done&style=none&taskId=u0a0a9e20-f79e-4c8c-8c82-b304f7b7583&title=&width=1792) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN019dFe4Y24SDKbmpbdw_!!6000000007389-2-tps-3584-1812.png) 2.拖拽这个组件 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1656388046560-e07680ee-809a-4ad1-bc47-47c2c00fdd40.png#clientId=uaa040ac3-dccc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=901&id=u23c8416a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1802&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=890196&status=done&style=none&taskId=u7ac32b55-f32c-4215-ac1d-f81f5e986ac&title=&width=1792) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN0109SdxO1OtxSbpLn4Q_!!6000000001764-2-tps-3584-1802.png) 3.配置该属性值为 100 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1656388075312-7c06f15a-464a-49f0-beb5-19320ea0e454.png#clientId=uaa040ac3-dccc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=900&id=ua91e7f85&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1800&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=882142&status=done&style=none&taskId=u61082c8a-1092-4b5b-a2ea-00486cadb71&title=&width=1792) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01WeVXpW1HBny0VmQcS_!!6000000000720-2-tps-3584-1800.png) 期望效果: @@ -84,26 +84,26 @@ window.AliLowCodeEngine.project.openDocument('docl4xkca5b') #### 【支持稍慢】通过线上 demo + 变更代码可复现,并清楚的说明变更代码的位置和内容 **示例** -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1656387894830-6850815f-e2ee-46bf-a2bf-fdda4d166691.png#clientId=uaa040ac3-dccc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=u87419dd1&margin=%5Bobject%20Object%5D&name=image.png&originHeight=754&originWidth=1892&originalType=binary&ratio=1&rotation=0&showTitle=false&size=226627&status=done&style=none&taskId=u88b2bbb8-869c-482c-9510-9d513f6e191&title=&width=946) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01FL0Urq1tl1pLcYhJH_!!6000000005941-2-tps-1892-754.png) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1656387911054-771dd7fc-db90-46ae-b1db-f5f9f7537ed4.png#clientId=uaa040ac3-dccc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=389&id=u0a370108&margin=%5Bobject%20Object%5D&name=image.png&originHeight=778&originWidth=1917&originalType=binary&ratio=1&rotation=0&showTitle=false&size=229881&status=done&style=none&taskId=ucbc7af71-f0e1-4319-9097-8ad6b936c5e&title=&width=958.5) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01WIpR9V1i363wzyFzi_!!6000000004356-2-tps-1917-778.png) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1656387922644-de3f1d64-0206-407d-82ad-2d1155374e37.png#clientId=uaa040ac3-dccc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=127&id=u9c5921eb&margin=%5Bobject%20Object%5D&name=image.png&originHeight=253&originWidth=1836&originalType=binary&ratio=1&rotation=0&showTitle=false&size=58615&status=done&style=none&taskId=u5c8af90a-0d20-40c8-a1f2-e387f037d85&title=&width=918) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01ZDkR3n1MNmP2uk15t_!!6000000001423-2-tps-1836-253.png) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1656387931330-a5453ba1-264b-4325-b3a8-7cb6e22633ee.png#clientId=uaa040ac3-dccc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=457&id=u687acf85&margin=%5Bobject%20Object%5D&name=image.png&originHeight=914&originWidth=1912&originalType=binary&ratio=1&rotation=0&showTitle=false&size=129980&status=done&style=none&taskId=u3a706b70-0da6-484d-857d-1d086f7a4e5&title=&width=956) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01OKzt1Z28b9WZIbM6B_!!6000000007950-2-tps-1912-914.png) #### 【支持慢】有完整的项目地址,下载下来可直接安装依赖并启动复现的 由于完整的项目中有很多冗余的信息,这部分排查起来十分耗时且困难。不推荐使用改方式。 #### 【不保证提供支持】其他 ##### 只有标题没有复现步骤 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1656388351815-e086b980-0828-4c49-ba72-142446313d2d.png#clientId=uaa040ac3-dccc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=510&id=u79a38c3b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1020&originWidth=2520&originalType=binary&ratio=1&rotation=0&showTitle=false&size=529258&status=done&style=none&taskId=u3540b08e-9dff-4c72-8ee5-123912439b0&title=&width=1260) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN017rO2gR1YKpEgIMBjh_!!6000000003041-2-tps-2520-1020.png) ##### 复现步骤不清晰 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1656388451393-2168e5ca-20de-4781-9e51-20e282dbc0ca.png#clientId=uaa040ac3-dccc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=833&id=ubaf001f6&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1666&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1228630&status=done&style=none&taskId=ub26ed4ff-e0cf-4644-9a65-00ddee4b9e5&title=&width=1792) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01vtHi5z225CC7aFVS2_!!6000000007068-2-tps-3584-1666.png) ##### 和引擎无关的 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1656388376995-0ab5d7c0-8ff9-49cf-8854-70e9bb3ff87a.png#clientId=uaa040ac3-dccc-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=715&id=uffc59321&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1430&originWidth=2548&originalType=binary&ratio=1&rotation=0&showTitle=false&size=747119&status=done&style=none&taskId=u861d5fa6-f673-4091-8635-ff45adf680e&title=&width=1274) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01KxqT9M1vcu25xJHFP_!!6000000006194-2-tps-2548-1430.png) diff --git a/docs/docs/api/index.md b/docs/docs/api/index.md index 1afccce180..b888bad0bf 100644 --- a/docs/docs/api/index.md +++ b/docs/docs/api/index.md @@ -5,7 +5,7 @@ sidebar_position: 0 引擎直接提供 9 大类 API,以及若干间接的 API,具体如下图: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645445575048-cc511d60-3b84-411d-a70e-21b7a596d09c.png#clientId=uaab5e9c4-fa7b-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=695&id=u8e1d0318&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1390&originWidth=1278&originalType=binary&ratio=1&rotation=0&showTitle=false&size=410614&status=done&style=none&taskId=u9fdcdcfb-4e8b-4e22-8865-94181f458d0&title=&width=639) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01ZA2RMv1nYlWf6ThGf_!!6000000005102-2-tps-1278-1390.png) ### API 设计约定 一些 API 设计约定: diff --git a/docs/docs/api/init.md b/docs/docs/api/init.md index 13eacaaf8e..93ad133d32 100644 --- a/docs/docs/api/init.md +++ b/docs/docs/api/init.md @@ -135,4 +135,4 @@ init({ ``` 在引擎中即可这样使用。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1657272220368-9ee4430e-9e42-4746-9de8-a233840b0950.png#clientId=u951c1fcc-9dab-4&crop=0&crop=0&crop=1&crop=1&errorMessage=unknown%20error&from=paste&height=292&id=uacb8d50d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1796&originWidth=3584&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1641368&status=error&style=none&taskId=u559fb5cd-4a48-4732-b169-c9868a6d7b7&title=&width=582) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01FWvu051OxAEYrHBy5_!!6000000001771-2-tps-3584-1796.png) diff --git a/docs/docs/api/material.md b/docs/docs/api/material.md index 69a2c76cd5..4cf1948cfd 100644 --- a/docs/docs/api/material.md +++ b/docs/docs/api/material.md @@ -151,7 +151,7 @@ material.addBuiltinComponentAction({ condition: true, }); ``` -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1645446545381-aa6f4543-5f6e-4a03-91c1-e88817823153.png#clientId=u51926daa-3723-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=198&id=u34e8d0d9&margin=%5Bobject%20Object%5D&name=image.png&originHeight=198&originWidth=230&originalType=binary&ratio=1&rotation=0&showTitle=false&size=16907&status=done&style=none&taskId=u27bac39f-a38f-43bf-a0e5-157118e3aa6&title=&width=230) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01jDbN7B1KfWVzJ16tw_!!6000000001191-2-tps-230-198.png) ### removeBuiltinComponentAction 移除设计器辅助层的指定 action diff --git a/docs/docs/api/project.md b/docs/docs/api/project.md index b7dda45b26..7c58968526 100644 --- a/docs/docs/api/project.md +++ b/docs/docs/api/project.md @@ -5,7 +5,7 @@ sidebar_position: 3 # 模块简介 引擎编排模块中包含多种模型,包括[项目模型(project)](#DADnF)、[文档模型(document-model)](#lp7xO)、[节点模型(node)](#m0cJS)、[节点孩子模型(node-children)](#W8seq)、[属性集模型(props)](#IJeRY)以及[属性模型(prop)](#w1diM)。 他们的依赖关系如下图: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645510146964-62f26151-e624-48f6-a422-dacdcb60dbea.png#averageHue=%23fefefe&clientId=ue969b413-090d-4&crop=0&crop=0&crop=1&crop=1&errorMessage=unknown%20error&from=paste&height=676&id=ucd07aeff&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1352&originWidth=1650&originalType=binary&ratio=1&rotation=0&showTitle=false&size=282048&status=error&style=none&taskId=u8ec0cad1-ed80-46f5-8b6b-b7278b4bb7d&title=&width=825) +![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 来获取当前文档模型里所有的节点列表。 diff --git a/docs/docs/api/skeleton.md b/docs/docs/api/skeleton.md index 38850b09f0..1ae573e7ec 100644 --- a/docs/docs/api/skeleton.md +++ b/docs/docs/api/skeleton.md @@ -5,10 +5,10 @@ sidebar_position: 1 ## 模块简介 面板 API 提供了面板扩展和管理的能力,如下图蓝色内容都是扩展出来的。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645442085447-d1822e7f-9e5a-4e06-a770-04b1023d5daf.png#clientId=u9aca70b6-1a98-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=498&id=u2dd3deb2&margin=%5Bobject%20Object%5D&name=image.png&originHeight=996&originWidth=1780&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1549904&status=done&style=none&taskId=u28659b69-981c-416e-bed6-b2f06b8e6fc&title=&width=890) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01eVA0U41xYRP3e5zo0_!!6000000006455-2-tps-1780-996.png) 页面上可以扩展的区域共 5 个,具体如下: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645431386085-2710d33d-0652-450a-a993-c804368da1ce.png#clientId=u1724eb73-4c0c-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=487&id=ud138f866&margin=%5Bobject%20Object%5D&name=image.png&originHeight=974&originWidth=1892&originalType=binary&ratio=1&rotation=0&showTitle=false&size=228235&status=done&style=none&taskId=u265d50a5-3700-406e-84b2-0158ebadaae&title=&width=946) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN014d2AcS1D5c9TshEiQ_!!6000000000165-2-tps-1892-974.png) ### 基本概念 #### 扩展区域位置 (area) ##### topArea diff --git a/docs/docs/demoUsage/intro.md b/docs/docs/demoUsage/intro.md index c8b23dc27d..8fdc356c45 100644 --- a/docs/docs/demoUsage/intro.md +++ b/docs/docs/demoUsage/intro.md @@ -3,28 +3,28 @@ title: 1. 试用低代码引擎 Demo sidebar_position: 0 --- 低代码编辑器中的区块主要包含这些功能点: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644562161350-50ae7ccd-2e6f-4f50-af56-30e5cc5624dc.png#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=892&id=udd8e7731&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1784&originWidth=3384&originalType=binary&ratio=1&rotation=0&showTitle=false&size=509888&status=done&style=none&taskId=u1621cea1-8e9d-48d0-9273-bf852ef8e82&title=&width=1692) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01aGQull1RVdGs7Pt6x_!!6000000002117-2-tps-3384-1784.png) ## 分区块功能介绍 ### 左侧:面板与操作区 #### 物料面板 可以查找组件,并在此拖动组件到编辑器画布中 -![Dec-17-2021 19-12-46.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562213143-49b9aff8-b538-43f4-a66d-53fac98ce7ae.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=u3a98c25c&margin=%5Bobject%20Object%5D&name=Dec-17-2021%2019-12-46.gif&originHeight=754&originWidth=1468&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u265abeb3-a0b1-4cdf-9291-c5fa865d06c&title=&width=734) +![Dec-17-2021 19-12-46.gif](https://img.alicdn.com/imgextra/i1/O1CN01pEu7811SlwzxraLHG_!!6000000002288-1-tps-1468-754.gif) #### 大纲面板 可以调整页面内的组件树结构: -![Dec-17-2021 19-14-34.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562213701-39f3e2c3-f52c-4be4-bb56-90842daa58ab.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=u1d18d088&margin=%5Bobject%20Object%5D&name=Dec-17-2021%2019-14-34.gif&originHeight=754&originWidth=1468&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u2d6ebf59-3cd5-4e80-8599-a4d594a2cbf&title=&width=734) +![Dec-17-2021 19-14-34.gif](https://img.alicdn.com/imgextra/i1/O1CN013DDLqt1GH0rAlajqi_!!6000000000596-1-tps-1468-754.gif) 可以在这里打开或者关闭模态浮层的展现: -![Dec-17-2021 19-19-18.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562213674-44d91956-ac82-4909-98b5-e0bd4fcbe12d.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=u7d3beb31&margin=%5Bobject%20Object%5D&name=Dec-17-2021%2019-19-18.gif&originHeight=754&originWidth=1468&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u6adfe95e-0c27-4c03-8e3c-ca62cb37387&title=&width=734) +![Dec-17-2021 19-19-18.gif](https://img.alicdn.com/imgextra/i2/O1CN01bQfS8W1JitokHRinC_!!6000000001063-1-tps-1468-754.gif) #### 源码面板 可以编辑页面级别的 JavaScript 代码和 CSS 配置 -![Feb-11-2022 14-51-59.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562356337-9e7f7490-396c-4520-b780-4a43a29050ef.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=ui&id=u02b5cb05&margin=%5Bobject%20Object%5D&name=Feb-11-2022%2014-51-59.gif&originHeight=614&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=2080513&status=done&style=none&taskId=u2f95447f-b7a6-453d-8a8c-7d1649581d9&title=) +![Feb-11-2022 14-51-59.gif](https://img.alicdn.com/imgextra/i1/O1CN01d11kK71Q223eWvL5F_!!6000000001917-1-tps-1532-614.gif) #### Schema 编辑 【开发者专属】可以编辑页面的底层 Schema 数据。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644562411102-a8596fce-fd77-4f20-bd3c-b52e2a0beb52.png#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=824&id=u3488f050&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1648&originWidth=3070&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1082743&status=done&style=none&taskId=u529bf58c-2203-484f-bf9f-19c2a3fe870&title=&width=1535) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01lcQOER23Q5sjA0Gn5_!!6000000007249-2-tps-3070-1648.png) 搭配顶部操作区的“保存到本地”和“重置页面”功能,可以实验各种 schema 对低代码页面的改变。 它们操作的数据关系是: @@ -36,45 +36,45 @@ sidebar_position: 0 #### 中英文切换 可以切换编辑器的语言;注:需要组件配置配合。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644562219182-e4233163-b731-4f09-a442-9d5c0e71e7e8.png#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=756&id=ua3adfd78&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1512&originWidth=3018&originalType=binary&ratio=1&rotation=0&showTitle=false&size=384093&status=done&style=none&taskId=uf546934b-ae91-4e3e-9e21-2447de70ed1&title=&width=1509) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644562219666-1baf7da2-6d70-45fa-8805-b6cc9ac99f3f.png#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=755&id=u34aad08e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1510&originWidth=3016&originalType=binary&ratio=1&rotation=0&showTitle=false&size=380190&status=done&style=none&taskId=ud264115a-ae01-4b65-9ccc-4e6efa37b62&title=&width=1508) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN019ORknX1M5SYg7eSJ3_!!6000000001383-2-tps-3018-1512.png) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01R7g7pW21rSJEHd2AI_!!6000000007038-2-tps-3016-1510.png) ## 中部:可视化页面编辑画布区域 点击组件在右侧面板中能够显示出对应组件的属性配置选项 -![Dec-17-2021 19-28-28.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562216925-c4bd5f10-2469-452c-8c2d-fe92ba6d03a7.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=uff491710&margin=%5Bobject%20Object%5D&name=Dec-17-2021%2019-28-28.gif&originHeight=754&originWidth=1468&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u2f775208-8b07-4968-9dd4-420c6e4d3c1&title=&width=734) +![Dec-17-2021 19-28-28.gif](https://img.alicdn.com/imgextra/i1/O1CN01uBU3lR1CuAFTTq4RS_!!6000000000140-1-tps-1468-754.gif) 拖拽修改组件的排列顺序 -![Dec-17-2021 19-29-40.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562219867-61a41b16-4513-4827-80bf-f7e4832bcf3a.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=ueda50ec8&margin=%5Bobject%20Object%5D&name=Dec-17-2021%2019-29-40.gif&originHeight=754&originWidth=1468&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=ue0ec6bea-81f1-4d04-bf82-acde7c9983a&title=&width=734) +![Dec-17-2021 19-29-40.gif](https://img.alicdn.com/imgextra/i3/O1CN01DAAYKd1bycUq1C4JV_!!6000000003534-1-tps-1468-754.gif) 将组件拖拽到容器类型的组件中,注意拖拽时会在右侧提示当前的组件树。 -![Dec-17-2021 19-31-30.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562220001-4afae72e-f9fd-4564-a904-c87f61ba79b5.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=ucc719a0e&margin=%5Bobject%20Object%5D&name=Dec-17-2021%2019-31-30.gif&originHeight=754&originWidth=1468&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u2c46a827-8702-471c-a8c1-eb4f069d108&title=&width=734) +![Dec-17-2021 19-31-30.gif](https://img.alicdn.com/imgextra/i2/O1CN01TzJosP1FIYZe6xIQ5_!!6000000000464-1-tps-1468-754.gif) ## 右侧:组件级别配置 ### 选中的组件 从页面开始一直到当前选中的组件位置,点击对应的名称可以切换到对应的组件上。 -![Dec-17-2021 19-35-25.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562220818-c6532319-51df-4698-a3a4-80f3ab70b209.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=u648c740b&margin=%5Bobject%20Object%5D&name=Dec-17-2021%2019-35-25.gif&originHeight=754&originWidth=1468&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u03dd1651-8139-47f1-9cd1-a5089b64bf9&title=&width=734) +![Dec-17-2021 19-35-25.gif](https://img.alicdn.com/imgextra/i4/O1CN01EbImy425R80OeblSD_!!6000000007522-1-tps-1468-754.gif) ### 选中组件的配置 当前组件的大类目选项,根据组件类型不同,包含如下子类目: #### 属性 组件的基础属性值设置 -![Dec-17-2021 19-37-26.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562222884-191c8433-2386-47f4-bab4-d3d1fe534f12.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=u43676a31&margin=%5Bobject%20Object%5D&name=Dec-17-2021%2019-37-26.gif&originHeight=754&originWidth=1468&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u170b8d2a-c1f9-4acf-a0e2-9825c588dcd&title=&width=734) +![Dec-17-2021 19-37-26.gif](https://img.alicdn.com/imgextra/i2/O1CN01ziBI9T1nQynFKqCp2_!!6000000005085-1-tps-1468-754.gif) #### 样式 组件的样式配置,如文字: -![Dec-17-2021 19-38-55.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562224062-86fcf97b-d229-487f-951d-d2070337c058.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=u4a9930ae&margin=%5Bobject%20Object%5D&name=Dec-17-2021%2019-38-55.gif&originHeight=754&originWidth=1468&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u4a81ecb9-5b51-4758-9dd0-eaeb2e1a318&title=&width=734) +![Dec-17-2021 19-38-55.gif](https://img.alicdn.com/imgextra/i4/O1CN017DQv2R1OEjoawXmKJ_!!6000000001674-1-tps-1468-754.gif) #### 事件 绑定组件对外暴露的事件。 -![Dec-17-2021 19-41-17.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562224632-a3ee9b18-97e8-4d31-b4fe-b58720dc6bf5.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=u534bb1ea&margin=%5Bobject%20Object%5D&name=Dec-17-2021%2019-41-17.gif&originHeight=754&originWidth=1468&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u50691375-2514-4a6c-8bec-0be44adf141&title=&width=734) +![Dec-17-2021 19-41-17.gif](https://img.alicdn.com/imgextra/i2/O1CN01mhVutF24I8cLde0zy_!!6000000007367-1-tps-1468-754.gif) #### 高级 循环、条件渲染与 key 设置。 -![Dec-17-2021 19-46-26.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562226094-899cf104-3c60-439f-8b68-83af595ef275.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=u9190ed31&margin=%5Bobject%20Object%5D&name=Dec-17-2021%2019-46-26.gif&originHeight=754&originWidth=1468&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=uf02555c1-cd82-486d-8561-ca97e0ec1cd&title=&width=734) +![Dec-17-2021 19-46-26.gif](https://img.alicdn.com/imgextra/i4/O1CN01xTjXQX1jMcYwuTGKZ_!!6000000004534-1-tps-1468-754.gif) ## 顶部:操作区 ### 撤回和重做 -![Dec-17-2021 19-52-23.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562226083-d7f69bff-42e6-4173-8ac8-6e5a0c0262d6.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=u81f5d842&margin=%5Bobject%20Object%5D&name=Dec-17-2021%2019-52-23.gif&originHeight=754&originWidth=1468&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=ubeb556cd-2349-44d8-b1be-ba6e32bea4e&title=&width=734) +![Dec-17-2021 19-52-23.gif](https://img.alicdn.com/imgextra/i3/O1CN019VWkbr1jsgHoGKf6g_!!6000000004604-1-tps-1468-754.gif) diff --git a/docs/docs/demoUsage/makeStuff/table.md b/docs/docs/demoUsage/makeStuff/table.md index 96a894890e..173d2e7568 100644 --- a/docs/docs/demoUsage/makeStuff/table.md +++ b/docs/docs/demoUsage/makeStuff/table.md @@ -10,7 +10,7 @@ sidebar_position: 0 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01UU8pVT26XN1A0ExVG_!!6000000007671-2-tps-3032-1648.png) 将他们拖到画布之中: -![Feb-16-2022 16-58-59.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645002115004-4f01eb8d-cf68-4a7c-b0db-bc5aaf2604a3.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=uf69dc239&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2016-58-59.gif&originHeight=792&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7510570&status=done&style=stroke&taskId=ua6ea2651-6c6c-4762-98cc-cc3ab5734cd&title=&width=767) +![Feb-16-2022 16-58-59.gif](https://img.alicdn.com/imgextra/i3/O1CN01UAsQ8124HgDptzPrn_!!6000000007366-1-tps-1534-792.gif) ### 配置组件 选中刚拖入的“查询筛选”组件,您可以配置此组件: @@ -21,7 +21,7 @@ sidebar_position: 0 ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01eWOK0d1fOfsF9PZu9_!!6000000003997-2-tps-3060-1476.png) 掌握组件配置功能,我们就可以完成一个常用的查询框的配置: -![Feb-21-2022 18-05-52.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645437973453-1fd1dc10-99ad-4c18-af49-2741bd81c4ae.gif#clientId=u022fc577-71a7-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=395&id=u964ae52f&margin=%5Bobject%20Object%5D&name=Feb-21-2022%2018-05-52.gif&originHeight=790&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7210902&status=done&style=stroke&taskId=u9e39c54a-7467-4a96-b716-681cf598f09&title=&width=766) +![Feb-21-2022 18-05-52.gif](https://img.alicdn.com/imgextra/i1/O1CN0138fb0P1CTbHKWDBeo_!!6000000000082-1-tps-1532-790.gif) ### 绑定数据 @@ -98,7 +98,7 @@ class LowcodeComponent extends Component { ![image.png](https://img.alicdn.com/imgextra/i1/O1CN01K3Pwjo1PKWQcoBl5K_!!6000000001822-2-tps-3170-1904.png) -![Feb-16-2022 20-24-35.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645014292272-68e07740-47dc-4c94-8437-beded0b07c63.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u4506fc72&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-24-35.gif&originHeight=792&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=6960677&status=done&style=stroke&taskId=u9fe02184-e6dc-4886-b371-c48ca1e2832&title=&width=766) +![Feb-16-2022 20-24-35.gif](https://img.alicdn.com/imgextra/i2/O1CN01VGlZPS1JitoljrFFY_!!6000000001063-1-tps-1532-792.gif) 将 Loading 的“是否显示”字段绑定 `this.state.loading` 后,我们可以看到,这里暴露了一个插槽。插槽是可以任意扩展的预设部分,我们可以把其他的部分拖进插槽: @@ -110,16 +110,16 @@ class LowcodeComponent extends Component { ### 列挂钩浮层 为了能够让表格里的操作挂钩浮层,我们先拖入一个浮层: -![Feb-16-2022 20-32-09.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645014772471-0fce9b50-0f70-492e-bb53-5f875c00f5b4.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u4d33cd05&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-32-09.gif&originHeight=792&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7475148&status=done&style=stroke&taskId=u9dc26cba-41eb-4fe8-b96f-fe391968861&title=&width=766) +![Feb-16-2022 20-32-09.gif](https://img.alicdn.com/imgextra/i2/O1CN01bX3SHk21Z8T4O6knp_!!6000000006998-1-tps-1532-792.gif) 使用大纲树能够临时显示和隐藏此浮层: -![Feb-16-2022 20-32-39.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645014828329-b2de4db6-9032-4280-b886-db17070eea21.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=ue27e6676&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-32-39.gif&originHeight=792&originWidth=1530&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7335022&status=done&style=stroke&taskId=u73554a5d-5ebe-48d1-a861-426ba8501b1&title=&width=765) +![Feb-16-2022 20-32-39.gif](https://img.alicdn.com/imgextra/i3/O1CN01ZtSp0P1LvNqYPeUHg_!!6000000001361-1-tps-1530-792.gif) 我们给表格增加一个数据列: ![Feb-16-2022 20-39-41.gif](https://img.alicdn.com/imgextra/i2/O1CN012K6qWI1hgCG6KwRF7_!!6000000004306-1-tps-1532-792.gif) 然后配置它的行为为“弹窗”: -![Feb-16-2022 20-40-05.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645015223838-7f180e28-43e0-442b-a47e-ea5ff69d4900.gif#clientId=uf61aba9b-3a69-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=396&id=u80f44f38&margin=%5Bobject%20Object%5D&name=Feb-16-2022%2020-40-05.gif&originHeight=792&originWidth=1532&originalType=binary&ratio=1&rotation=0&showTitle=false&size=7261162&status=done&style=stroke&taskId=u3828503a-ecac-452a-8d20-02e4a46ad02&title=&width=766) +![Feb-16-2022 20-40-05.gif](https://img.alicdn.com/imgextra/i2/O1CN016axZh61uc9ln0L3Rz_!!6000000006057-1-tps-1532-792.gif) 实现的效果如下: ![Feb-16-2022 20-42-51.gif](https://img.alicdn.com/imgextra/i4/O1CN018iana91j4l71QTmpE_!!6000000004495-1-tps-1534-792.gif) @@ -127,10 +127,10 @@ class LowcodeComponent extends Component { ### 事件回调 上述功能点中,我们是把操作行为绑定在数据列上的,这一节我们绑定到操作列中。在操作列按钮处,点击下方的“添加一项”: -![Feb-23-2022 11-58-02.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645588703676-2a36cab4-52f4-4f31-9018-d56b41a55283.gif#clientId=u74bf469f-47f0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=395&id=u18d8ea0b&margin=%5Bobject%20Object%5D&name=Feb-23-2022%2011-58-02.gif&originHeight=790&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=8440133&status=done&style=stroke&taskId=u73e25800-c0fa-486b-9b68-4df7db9b9f1&title=&width=767) +![Feb-23-2022 11-58-02.gif](https://img.alicdn.com/imgextra/i4/O1CN01DsBoHQ1tyli2rtoFR_!!6000000005971-1-tps-1534-790.gif) 点击左侧的详情按钮,配置它的事件回调: -![Feb-23-2022 12-00-18.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645588832183-7ed0f06b-731d-4bd8-b934-723de43a8b42.gif#clientId=u74bf469f-47f0-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=395&id=u59505da7&margin=%5Bobject%20Object%5D&name=Feb-23-2022%2012-00-18.gif&originHeight=790&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=9047220&status=done&style=stroke&taskId=ub8ab1b4e-4195-426f-b792-fc8bf91d142&title=&width=767) +![Feb-23-2022 12-00-18.gif](https://img.alicdn.com/imgextra/i2/O1CN017BuNLP1LPmW8zH7hx_!!6000000001292-1-tps-1534-790.gif) 代码侧,我们配置这个回调函数: ```javascript diff --git a/docs/docs/demoUsage/panels/canvas.md b/docs/docs/demoUsage/panels/canvas.md index 0e46780764..35158d29d3 100644 --- a/docs/docs/demoUsage/panels/canvas.md +++ b/docs/docs/demoUsage/panels/canvas.md @@ -5,18 +5,18 @@ sidebar_position: 1 ## 组件操作 ### 画布操作 点击组件在右侧面板中能够显示出对应组件的属性配置选项 -![Dec-17-2021 19-28-28.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562216925-c4bd5f10-2469-452c-8c2d-fe92ba6d03a7.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=uff491710&margin=%5Bobject%20Object%5D&name=Dec-17-2021%2019-28-28.gif&originHeight=754&originWidth=1468&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u2f775208-8b07-4968-9dd4-420c6e4d3c1&title=&width=734) +![Dec-17-2021 19-28-28.gif](https://img.alicdn.com/imgextra/i1/O1CN01flb5tL1inM47Gdo3a_!!6000000004457-1-tps-1468-754.gif) 拖拽修改组件的排列顺序 -![Dec-17-2021 19-29-40.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562219867-61a41b16-4513-4827-80bf-f7e4832bcf3a.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=ueda50ec8&margin=%5Bobject%20Object%5D&name=Dec-17-2021%2019-29-40.gif&originHeight=754&originWidth=1468&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=ue0ec6bea-81f1-4d04-bf82-acde7c9983a&title=&width=734) +![Dec-17-2021 19-29-40.gif](https://img.alicdn.com/imgextra/i3/O1CN01UJ1x731NBFB4eELV0_!!6000000001531-1-tps-1468-754.gif) 拖拽时会在右侧提示当前的组件树。 -![Dec-17-2021 19-31-30.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562220001-4afae72e-f9fd-4564-a904-c87f61ba79b5.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=ucc719a0e&margin=%5Bobject%20Object%5D&name=Dec-17-2021%2019-31-30.gif&originHeight=754&originWidth=1468&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u2c46a827-8702-471c-a8c1-eb4f069d108&title=&width=734) +![Dec-17-2021 19-31-30.gif](https://img.alicdn.com/imgextra/i1/O1CN01jLUYQE1h4dmcfYhZB_!!6000000004224-1-tps-1468-754.gif) ### 组件控制 点击组件右上角的复制按钮,或者按下 `ctrl + c` 再按下 `ctrl + v`,可以将其复制; 点击组件右上角的删除按钮,或者直接使用 `Delete` 键,可以将其删除。 -![Dec-17-2021 19-33-20.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1644562220898-a54f0cfa-26bf-461f-a4aa-9708fc367d7c.gif#clientId=u99b5ef7a-7ebb-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=377&id=u2bae31a2&margin=%5Bobject%20Object%5D&name=Dec-17-2021%2019-33-20.gif&originHeight=754&originWidth=1468&originalType=binary&ratio=1&rotation=0&showTitle=false&status=done&style=none&taskId=u2c4c7b00-b316-431a-9c54-949ae4ed766&title=&width=734) +![Dec-17-2021 19-33-20.gif](https://img.alicdn.com/imgextra/i2/O1CN01QT1pq621gvCVpoOm6_!!6000000007015-1-tps-1468-754.gif) ### 选择组件切换 @@ -28,7 +28,7 @@ sidebar_position: 1 - `→` 向右选择组件 可以 hover 到组件操作辅助区的第一项来选中组件的父级节点: -![Feb-22-2022 14-42-30.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645512169966-17f26afa-00fc-47a5-86be-08505ab39a4f.gif#clientId=u5c3042e1-7626-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=395&id=uee0cbe0a&margin=%5Bobject%20Object%5D&name=Feb-22-2022%2014-42-30.gif&originHeight=790&originWidth=1536&originalType=binary&ratio=1&rotation=0&showTitle=false&size=2913977&status=done&style=stroke&taskId=ud9314fe0-0943-48e5-9f0c-b9b9b4a6b47&title=&width=768) +![Feb-22-2022 14-42-30.gif](https://img.alicdn.com/imgextra/i4/O1CN01RWbgGJ1TM8HoOpQ7V_!!6000000002367-1-tps-1536-790.gif) ### 可扩展项简述 @@ -37,12 +37,12 @@ sidebar_position: 1 ## Slot 区块 React 中,可以定义一个 prop 选项为 `JSXElement` 或 `(...args) => JSXElement` 的形式,这个形式在低代码画布中,被定义为 Slot,允许往其内部拖入组件,进行符合直觉的操作。 -![Feb-22-2022 14-46-02.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645512376500-46baf1b5-2335-4fb5-a430-c2f2245c8439.gif#clientId=u5c3042e1-7626-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=395&id=u8c429d95&margin=%5Bobject%20Object%5D&name=Feb-22-2022%2014-46-02.gif&originHeight=790&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=2389349&status=done&style=stroke&taskId=u7462c2e4-64bf-432a-aa2e-2fef526b4d4&title=&width=767) +![Feb-22-2022 14-46-02.gif](https://img.alicdn.com/imgextra/i4/O1CN01geivkn1csUog5gZbm_!!6000000003656-1-tps-1534-790.gif) ### 锁定 Slot 您可以对 Slot 进行锁定操作,锁定后内部内容无法选中; -![Feb-22-2022 14-50-03.gif](https://cdn.nlark.com/yuque/0/2022/gif/242652/1645512638545-ae46bcd2-883b-4229-9f78-d59087d03d28.gif#clientId=u5c3042e1-7626-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=395&id=u87ff9fe3&margin=%5Bobject%20Object%5D&name=Feb-22-2022%2014-50-03.gif&originHeight=790&originWidth=1534&originalType=binary&ratio=1&rotation=0&showTitle=false&size=9318074&status=done&style=none&taskId=ua4e1f652-2e72-4dcf-ad78-19b42e179c3&title=&width=767) +![Feb-22-2022 14-50-03.gif](https://img.alicdn.com/imgextra/i3/O1CN01eBD3WY1rPNsZt8UVL_!!6000000005623-1-tps-1534-790.gif) 在组件树可以解除操作。 @@ -54,7 +54,7 @@ React 中,可以定义一个 prop 选项为 `JSXElement` 或 `(...args) => JSX - 侵入型:组件编辑态下,会往组件内传入 `__designMode: 'design'`,可以在组件中进行相应处理; -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1645512859914-b51c23b9-50d9-4962-a6f7-96dbdcef6cef.png#clientId=u5c3042e1-7626-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=821&id=uf96a3071&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1642&originWidth=3066&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1024714&status=done&style=none&taskId=u7838e6c7-2349-4224-94ed-4e0e972b2a2&title=&width=1533) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01Xh3o891gvTrNBMMy2_!!6000000004204-2-tps-3066-1642.png) - 双入口型:通过配置物料的 editUrls,加载专属于编辑态组件的物料。pro-layout 使用的是这种方式 ```json diff --git a/docs/docs/demoUsage/panels/code.md b/docs/docs/demoUsage/panels/code.md index 717c2353a2..929c9bcb08 100644 --- a/docs/docs/demoUsage/panels/code.md +++ b/docs/docs/demoUsage/panels/code.md @@ -6,7 +6,7 @@ sidebar_position: 3 ## 面板功能拆解 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644897390779-cefb2c31-82fc-44f4-b824-adc32569ac6f.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=870&id=u23446c19&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1740&originWidth=2502&originalType=binary&ratio=1&rotation=0&showTitle=false&size=865371&status=done&style=none&taskId=u44e2b188-c268-4a30-a628-76a046be9d4&title=&width=1251) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01pRxmmD1agTBVwCO5x_!!6000000003359-2-tps-2502-1740.png) ### 代码编辑面板 @@ -15,8 +15,8 @@ sidebar_position: 3 | 编译前 | 编译后 | | --- | --- | -| ![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644897774925-b54126e0-ff6b-445e-bc68-569731aef8c3.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=95&id=nhuiT&margin=%5Bobject%20Object%5D&name=image.png&originHeight=190&originWidth=670&originalType=binary&ratio=1&rotation=0&showTitle=false&size=25045&status=done&style=none&taskId=u323192f6-7cfa-4d73-a184-2699f648c6f&title=&width=335) | ![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644897840129-83fe9a81-d8b2-4873-8764-904f531ec959.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=55&id=u3ba8300e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=110&originWidth=2094&originalType=binary&ratio=1&rotation=0&showTitle=false&size=44006&status=done&style=none&taskId=uef1552e3-ccdb-45dd-95d5-187a6c6b7df&title=&width=1047) | -| ![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644897884917-641b1547-7b90-4f78-86c1-0cc51996623d.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=60&id=u5fa00781&margin=%5Bobject%20Object%5D&name=image.png&originHeight=120&originWidth=434&originalType=binary&ratio=1&rotation=0&showTitle=false&size=17421&status=done&style=none&taskId=uecee8fbf-a786-4f89-ac9c-f2f8d059fe0&title=&width=217) | ![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644897915892-a1784bc2-693b-4cf6-a082-3c8e0368a987.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=60&id=ubcca6a46&margin=%5Bobject%20Object%5D&name=image.png&originHeight=120&originWidth=2536&originalType=binary&ratio=1&rotation=0&showTitle=false&size=50743&status=done&style=none&taskId=ue0f418e0-4192-4bfd-8912-9b64faedb66&title=&width=1268) | +| ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01xI9RVX1yV46HbW02H_!!6000000006583-2-tps-670-190.png) | ![image.png](https://img.alicdn.com/imgextra/i1/O1CN012exYQL1y37wKM7VFT_!!6000000006522-2-tps-2094-110.png) | +| ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01pK2rPi1lhLij4m3o7_!!6000000004850-2-tps-434-120.png) | ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01ti4n9m1ihOupktQow_!!6000000004444-2-tps-2536-120.png) | > 注:因为编译结果会被 `@babel/runtime` 干扰,目前面板不支持 `async await`或 `{ ...arr }` 形态的语法编译。如果您需要此类编译,您可以考虑在读取 schema 中的 `originCode` 之后自己手动通过 babel 编译。 @@ -28,7 +28,7 @@ sidebar_position: 3 ```typescript window.Next.Message.success('成功') ``` -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644898647058-9a5d6800-31fd-4c62-a577-850b90fc5d21.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=57&id=ue6231d61&margin=%5Bobject%20Object%5D&name=image.png&originHeight=114&originWidth=238&originalType=binary&ratio=1&rotation=0&showTitle=false&size=11360&status=done&style=none&taskId=u869f3709-a599-4ead-a80f-fa3b49c9836&title=&width=119) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01Fxjd801p4eigEBpb6_!!6000000005307-2-tps-238-114.png) #### 局部变量引用 @@ -48,18 +48,18 @@ window.Next.Message.success('成功') | 源码面板中 | schema 中 | | --- | --- | | 本地数据初始值设置: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644899552013-3de394fd-f530-4b4f-8258-8b9c64f11c11.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=73&id=u291f7733&margin=%5Bobject%20Object%5D&name=image.png&originHeight=146&originWidth=370&originalType=binary&ratio=1&rotation=0&showTitle=false&size=17505&status=done&style=none&taskId=u55496884-bc04-4867-9295-c71f44b77ef&title=&width=185) | ![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644899587782-0ceea074-07bb-4260-a580-7f49a82740ed.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=413&id=u01ae12cb&margin=%5Bobject%20Object%5D&name=image.png&originHeight=826&originWidth=2098&originalType=binary&ratio=1&rotation=0&showTitle=false&size=776122&status=done&style=none&taskId=ube04795b-6244-4aac-9ebc-f4624e605db&title=&width=1049) | +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01V6iaTY1gVNHi7gQfK_!!6000000004147-2-tps-370-146.png) | ![image.png](https://img.alicdn.com/imgextra/i2/O1CN010rhIPa268BEfGmzO6_!!6000000007616-2-tps-2098-826.png) | | 生命周期方法: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644899759963-d198edc4-a8c7-4a3f-90ee-b42244398958.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=130&id=uafcbf72e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=260&originWidth=478&originalType=binary&ratio=1&rotation=0&showTitle=false&size=37208&status=done&style=none&taskId=u19b58f72-7058-4a22-9a8e-334a9a541bd&title=&width=239) | ![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644899791416-a7969846-8d7d-4c51-9c55-6b1c65faf07b.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=418&id=uc6edd06d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=836&originWidth=2010&originalType=binary&ratio=1&rotation=0&showTitle=false&size=806116&status=done&style=none&taskId=uacb7cf67-ee4b-45ba-962a-24f43b525bc&title=&width=1005) | +![image.png](https://img.alicdn.com/imgextra/i4/O1CN010Y1TxV1QOvrVLRUjD_!!6000000001967-2-tps-478-260.png) | ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01pbJzVQ1VSfAL7Lh8G_!!6000000002652-2-tps-2010-836.png) | | 自定义函数: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644899808831-538e59a7-6d40-4e1a-bd72-bd2332bb9d7c.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=321&id=u2ea3e043&margin=%5Bobject%20Object%5D&name=image.png&originHeight=642&originWidth=660&originalType=binary&ratio=1&rotation=0&showTitle=false&size=72124&status=done&style=none&taskId=uc6ec76e1-89a0-4dad-a0ab-053730e2b4d&title=&width=330) | ![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644899830711-e262e41e-8332-4810-9293-bd4ef540c919.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=411&id=ueb7c1ad8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=822&originWidth=1862&originalType=binary&ratio=1&rotation=0&showTitle=false&size=815729&status=done&style=none&taskId=u3aae2a2e-4de4-468a-bd5a-5bec53b908a&title=&width=931) | +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01S2gjFk1CU3fm61eiD_!!6000000000083-2-tps-660-642.png) | ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01X35YxU1GUkjj1YWVj_!!6000000000626-2-tps-1862-822.png) | | 编译前全量代码: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644899850193-0b1990ea-e494-4c5f-94ef-9a1fdbde0a98.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=561&id=u92136fdf&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1122&originWidth=762&originalType=binary&ratio=1&rotation=0&showTitle=false&size=165346&status=done&style=none&taskId=u727c08ae-f56f-4632-acc0-837fa220681&title=&width=381) | ![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644899882162-648366a3-5b0b-4cf3-b103-bf3812f6e807.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=398&id=ub882b04a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=796&originWidth=1906&originalType=binary&ratio=1&rotation=0&showTitle=false&size=716114&status=done&style=none&taskId=u94d53b7d-5ea9-471a-b82c-3dec1a532b5&title=&width=953) | +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01sbiK9N1kc1Uxp1OHY_!!6000000004703-2-tps-762-1122.png) | ![image.png](https://img.alicdn.com/imgextra/i3/O1CN01adKSg61QXAzRjQ4bm_!!6000000001985-2-tps-1906-796.png) | - 异常处理:如果代码解析失败,它将无法被正常保存到 schema 中,此时编辑器会弹层提示: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644899252223-57317fcb-0958-4f38-a37b-00eaa5561512.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=819&id=u2d66f54c&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1638&originWidth=3068&originalType=binary&ratio=1&rotation=0&showTitle=false&size=473979&status=done&style=none&taskId=u9e4a4c69-dd56-4265-93d7-9b2e4e8971a&title=&width=1534) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01aSzh8o26rWRu6zXFE_!!6000000007715-2-tps-3068-1638.png) ### 样式编辑面板 @@ -67,7 +67,7 @@ window.Next.Message.success('成功') | 源码面板中 | Schema 中 | | --- | --- | -| ![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644899312003-76f4c95e-221f-4b5f-92ae-c51e664385e0.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=194&id=u30912dec&margin=%5Bobject%20Object%5D&name=image.png&originHeight=388&originWidth=634&originalType=binary&ratio=1&rotation=0&showTitle=false&size=42979&status=done&style=none&taskId=ue2a18106-55f3-4cff-8f95-904317d0419&title=&width=317) | ![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644899355488-aa352d2d-a001-434f-9368-021befea52ed.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=291&id=u60b8f9d4&margin=%5Bobject%20Object%5D&name=image.png&originHeight=582&originWidth=1646&originalType=binary&ratio=1&rotation=0&showTitle=false&size=454443&status=done&style=none&taskId=u236b94fb-6c20-4c6c-9fe3-7cd75eef0c4&title=&width=823) | +| ![image.png](https://img.alicdn.com/imgextra/i2/O1CN01cuWt4L27fRcW5WIP9_!!6000000007824-2-tps-634-388.png) | ![image.png](https://img.alicdn.com/imgextra/i4/O1CN01Edu7Gy1MzKsb2iss8_!!6000000001505-2-tps-1646-582.png) | ## 对接代码 @@ -92,8 +92,8 @@ window.Next.Message.success('成功') 通常书写代码是为了对接低代码配置中的“变量绑定”、“事件回调”、“条件判断”和“循环”部分的。 #### 变量绑定 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644899977727-f4f44171-52e8-4062-b558-436536b84640.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=732&id=ua42e46e3&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1464&originWidth=2738&originalType=binary&ratio=1&rotation=0&showTitle=false&size=957243&status=done&style=stroke&taskId=u56f7f36d-535d-48e9-8a0c-e0cb1f9af1d&title=&width=1369) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644900005551-14c356a0-2e51-4b0b-82b5-8a135d1c6c3e.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=583&id=ufcb9db2b&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1166&originWidth=1528&originalType=binary&ratio=1&rotation=0&showTitle=false&size=153133&status=done&style=stroke&taskId=u208e369b-f019-4019-8c2e-4c28b6eba91&title=&width=764) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01wcgwOI1wOXDtgfrgD_!!6000000006298-2-tps-2738-1464.png) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01GYVAw41FlrvEyFcCO_!!6000000000528-2-tps-1528-1166.png) ```json { "componentName": "NextBlockCell", @@ -110,8 +110,8 @@ window.Next.Message.success('成功') #### 事件回调 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644900095962-2ec54fb5-e1f8-4d4a-a75e-24e1c685a833.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=726&id=ufed11f2e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1452&originWidth=2734&originalType=binary&ratio=1&rotation=0&showTitle=false&size=749908&status=done&style=stroke&taskId=uc379b8ec-c344-48f8-9b43-8d9be961356&title=&width=1367) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644900119673-f9538274-c896-4951-86f2-54d60ac95316.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=581&id=uffdcbbce&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1162&originWidth=1670&originalType=binary&ratio=1&rotation=0&showTitle=false&size=118712&status=done&style=stroke&taskId=u261a9b7f-9f5a-406a-aa55-8a3f33bdd05&title=&width=835) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01B0tvgw1O6x58dbbIb_!!6000000001657-2-tps-2734-1452.png) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01sD9g2n1tQQ0OjQkcY_!!6000000005896-2-tps-1670-1162.png) ```json { "componentName": "Filter", @@ -135,8 +135,8 @@ window.Next.Message.success('成功') ``` #### 条件判断 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644900186943-de6b33de-adca-4c1b-8f47-f68cf6ce5f77.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=726&id=u23b46226&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1452&originWidth=2738&originalType=binary&ratio=1&rotation=0&showTitle=false&size=789132&status=done&style=stroke&taskId=u6322e6a8-bea3-47d8-a374-b9ec6558bb9&title=&width=1369) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644900005551-14c356a0-2e51-4b0b-82b5-8a135d1c6c3e.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=583&id=G2uKJ&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1166&originWidth=1528&originalType=binary&ratio=1&rotation=0&showTitle=false&size=153133&status=done&style=stroke&taskId=u208e369b-f019-4019-8c2e-4c28b6eba91&title=&width=764) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01zXqec823EBaCutOY2_!!6000000007223-2-tps-2738-1452.png) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01Ze3snL24BGfuRIMCl_!!6000000007352-2-tps-1528-1166.png) ```json { "componentName": "Filter", @@ -150,8 +150,8 @@ window.Next.Message.success('成功') ``` #### 循环 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644900265929-c21c9927-1f34-49b6-9dc6-bcb4357190be.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=730&id=u8f457b1e&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1460&originWidth=2746&originalType=binary&ratio=1&rotation=0&showTitle=false&size=781151&status=done&style=stroke&taskId=u92be7d31-2070-4a08-bc1c-6b1a599c682&title=&width=1373) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644900005551-14c356a0-2e51-4b0b-82b5-8a135d1c6c3e.png#clientId=ud3fa1588-e66f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=583&id=ot5cO&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1166&originWidth=1528&originalType=binary&ratio=1&rotation=0&showTitle=false&size=153133&status=done&style=stroke&taskId=u208e369b-f019-4019-8c2e-4c28b6eba91&title=&width=764) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01Kbj6XP297fe0BvhKz_!!6000000008021-2-tps-2746-1460.png) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN018Ogesd1qnN0IOKRDZ_!!6000000005540-2-tps-1528-1166.png) ```json { "componentName": "Filter", diff --git a/docs/docs/demoUsage/panels/component.md b/docs/docs/demoUsage/panels/component.md index eff0e82c8b..d1c6b90880 100644 --- a/docs/docs/demoUsage/panels/component.md +++ b/docs/docs/demoUsage/panels/component.md @@ -5,7 +5,7 @@ sidebar_position: 0 ## 概述 组件面板顾名思义就是承载组件的面板,组件面板会获取并解析传入给低代码引擎的资产包数据 (数据结构[点此查看](https://lowcode-engine.cn/assets)),得到需要被展示的组件列表,并根据分类、排序规则对组件进行排列,同时也提供了搜索功能。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647964501932-33676243-c42b-4e7c-8663-77c5898d3343.png#clientId=uf38e3cbf-9388-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=438&id=ubb9e4616&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1672&originWidth=3056&originalType=binary&ratio=1&rotation=0&showTitle=true&size=451947&status=done&style=stroke&taskId=u0fc240e1-a792-4bd1-b84d-5bbc8e8fc8b&title=%E7%BB%84%E4%BB%B6%E9%9D%A2%E6%9D%BF&width=800 "组件面板") +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01a6xgwH1wCAWugmNvU_!!6000000006271-2-tps-3056-1672.png) ## 组件信息 组件面板承载的组件信息有: @@ -19,7 +19,7 @@ sidebar_position: 0 其中标题和截图是我们能够看到的,schema 片段则是拖拽到设计器时会自动插入页面 schema 中,面板会根据分组、分类来对组件进行排列; 这些组件信息均通过资产包数据获取,字段对应关系如下图所示: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/231502/1647965256061-d15ad119-471f-43c7-8856-2c91bb3670ad.png#clientId=uf38e3cbf-9388-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=1012&id=u1b3132db&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1678&originWidth=1326&originalType=binary&ratio=1&rotation=0&showTitle=false&size=996705&status=done&style=stroke&taskId=u6730f591-c7e1-42ba-8cb7-fcc95e76e8c&title=&width=800) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN012ZUg6a289fl4z6WCm_!!6000000007890-2-tps-1326-1678.png) ## 组件分组、分类排序 组件面板会把相同分组的组件放在同一个 tab 下,相同分类的组件放在同一个 collapse 中,同时也支持对 tab 和 collapse 进行排序; 由于是整体性的排序,组件自身的信息无法决定此排序,因此在资产包数据根节点新增了 sort 字段用于指定分组和分类的排序,具体定义在[《低代码引擎资产包协议规范》](https://lowcode-engine.cn/assets)2.4 sort 章节; diff --git a/docs/docs/demoUsage/panels/datasource.md b/docs/docs/demoUsage/panels/datasource.md index 9fbf38f6a1..7e9028e5eb 100644 --- a/docs/docs/demoUsage/panels/datasource.md +++ b/docs/docs/demoUsage/panels/datasource.md @@ -5,14 +5,14 @@ sidebar_position: 4 ## 🪚 概述 数据源面板主要负责管理低代码中远程数据源内容,通过可视化编辑的方式操作低代码协议中的数据源 Schema,配合 [数据源引擎](/site/docs/guide/design/datasourceEngine) 即可实现低代码中数据源的生产和消费; -![image.png](https://cdn.nlark.com/yuque/0/2022/png/84508/1648397674378-aec10892-5ee4-414d-807e-39f55f3a5be5.png#clientId=u38847497-05f3-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=821&id=u07e82f8a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1642&originWidth=2878&originalType=binary&ratio=1&rotation=0&showTitle=false&size=246032&status=done&style=none&taskId=uc18acbc5-1404-4266-a499-e952d1084c4&title=&width=1439) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN0170HeBg276B7fM9rqh_!!6000000007747-2-tps-2878-1642.png) 数据源面板 ## ❓如何使用 > 面板内包含了数据源创建、删除、编辑、排序、导入导出、复制以及搜索等能力,内置支持了 `fecth` & `JSONP`两种常用远程请求类型; ### 三步创建一个数据源 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/84508/1648398269436-bd241801-e617-4640-830f-03b44aca80a1.png#clientId=u38847497-05f3-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=819&id=u1ee9fa0d&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1638&originWidth=2878&originalType=binary&ratio=1&rotation=0&showTitle=false&size=279302&status=done&style=none&taskId=ue1248934-df36-423c-86f3-160a4e865da&title=&width=1439) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01bkgbqj1cOGfwQtEif_!!6000000003590-2-tps-2878-1638.png) 三步创建数据源 ### 参数详解 diff --git a/docs/docs/demoUsage/panels/settings.md b/docs/docs/demoUsage/panels/settings.md index 3c62553455..9023e587ad 100644 --- a/docs/docs/demoUsage/panels/settings.md +++ b/docs/docs/demoUsage/panels/settings.md @@ -5,7 +5,7 @@ sidebar_position: 2 # 设置器介绍 ## 展示区域 设置器,又称为 Setter,主要展示在编辑器的右边区域,如下图: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1647695118402-ac146307-f6e2-4755-8be3-67278c505283.png#clientId=u547a37e3-c43d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=865&id=u3cac31de&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1730&originWidth=3836&originalType=binary&ratio=1&rotation=0&showTitle=false&size=947162&status=done&style=none&taskId=u35373859-102e-4809-adfd-680b2dd4cda&title=&width=1918) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01jN0toi1OknXWrPuYt_!!6000000001744-2-tps-3836-1730.png) 其中包含 属性、样式、事件、高级 - 属性:展示该物料常规的属性 @@ -18,7 +18,7 @@ sidebar_position: 2 ## 设置器 上述区域中是有多项设置器的,对于一个组件来说,每一项配置都对应一个设置器,比如我们的配置是一个文本,我们需要的是文本设置器,我们需要配置的是数字,我们需要的就是数字设置器。 下图中的标题和按钮类型配置就分别是文本设置器和下拉框设置器。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2553587/1647695118227-bf6caf7c-4974-4b35-8d6b-0c4969fc316d.png#clientId=u547a37e3-c43d-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=407&id=u51d889e6&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1460&originWidth=2120&originalType=binary&ratio=1&rotation=0&showTitle=false&size=489840&status=done&style=none&taskId=u35d4519f-b82d-43c4-9eb4-bd44e6d67b1&title=&width=591) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01Bl2hgm1GiUcXD3TOO_!!6000000000656-2-tps-2120-1460.png) 我们提供了常用的设置器作为内置设置器,也提供了定制能力帮助大家开发特定需求的设置器。 # 内置设置器 | **预置 Setter** | **用途** | diff --git a/docs/docs/faq/faq002.md b/docs/docs/faq/faq002.md index 45e1c0c50e..e1da36b3da 100644 --- a/docs/docs/faq/faq002.md +++ b/docs/docs/faq/faq002.md @@ -6,28 +6,28 @@ tags: [FAQ] 渲染唯一标识(key)和 React 中组件的 key 属性的原理是一致的,都是为了在渲染场景或者组件切换的场景中唯一标识一个组件。 你可以在组件右侧配置面板的「高级」中看到此配置项,该配置项一般配合「是否渲染」和「循环」功能使用。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1659076591507-f37841b4-a3c2-4c87-b875-5f0458b2a3d2.png#clientId=u87aade85-8350-4&crop=0&crop=0&crop=1&crop=1&height=348&id=dbojA&margin=%5Bobject%20Object%5D&name=image.png&originHeight=696&originWidth=560&originalType=binary&ratio=1&rotation=0&showTitle=false&size=102096&status=done&style=none&taskId=ub4a95aaa-8630-47ad-b0e3-881b5d54ac9&title=&width=280) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01wU7y30232jgLlfzRe_!!6000000007198-2-tps-560-696.png) ## 以下场景必需设置「渲染唯一标识」 #### 场景一:同类组件切换 以下场景中,当「爱好」选择「游戏」时显示「最喜欢的游戏」,选择「运动」时显示「最喜欢的运动」 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1659076591520-b2e1121b-3f4e-4c7c-88c8-82a761b85fe0.png#clientId=u87aade85-8350-4&crop=0&crop=0&crop=1&crop=1&height=294&id=Xr3NB&margin=%5Bobject%20Object%5D&name=image.png&originHeight=588&originWidth=1560&originalType=binary&ratio=1&rotation=0&showTitle=false&size=78723&status=done&style=none&taskId=u59b975eb-93a1-4c8a-bb3b-17ef8b7005c&title=&width=780) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN016qHhJB1XWRfUJsml7_!!6000000002931-2-tps-1560-588.png) 配置方式如下: 1. 增加变量数据源:hobby 2. 「最喜欢的游戏」表单标识设置为 game,「是否渲染」绑定变量「state.hobby === '游戏'」 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1659076591653-27fac7ab-bba0-4965-a706-d0c1c867f539.png#clientId=u87aade85-8350-4&crop=0&crop=0&crop=1&crop=1&height=369&id=f8kif&margin=%5Bobject%20Object%5D&name=image.png&originHeight=738&originWidth=2164&originalType=binary&ratio=1&rotation=0&showTitle=false&size=306076&status=done&style=none&taskId=ub6da537a-3bc7-450d-b640-dc0db8defac&title=&width=1082) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01oOemw41d0HY3qpwum_!!6000000003673-2-tps-2164-738.png) 3. 「最喜欢的运动」表单标识设置为 sport,「是否渲染」绑定变量「state.hobby === '运动'」 4. 「爱好」设置 onChange 动作 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1659076591442-2903e2b2-4688-4a5e-98de-7df9933710b5.png#clientId=u87aade85-8350-4&crop=0&crop=0&crop=1&crop=1&height=97&id=hR3Pp&margin=%5Bobject%20Object%5D&name=image.png&originHeight=194&originWidth=892&originalType=binary&ratio=1&rotation=0&showTitle=false&size=53803&status=done&style=none&taskId=ue8919283-2e5f-46a8-9d6b-942c03f8482&title=&width=446) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01oH4Giy1GTpwZwVSrO_!!6000000000624-2-tps-892-194.png) 5. 「提交」按钮绑定 onClick 动作 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1659076591508-ddd3c767-bf22-4dae-a006-5e6c4e0ea956.png#clientId=u87aade85-8350-4&crop=0&crop=0&crop=1&crop=1&height=67&id=VWtPz&margin=%5Bobject%20Object%5D&name=image.png&originHeight=134&originWidth=750&originalType=binary&ratio=1&rotation=0&showTitle=false&size=46519&status=done&style=none&taskId=ud6a5d2b0-481b-4bbb-8fe3-8622e2ebfb3&title=&width=375) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN016kkf3O1uj1i9ev7uy_!!6000000006072-2-tps-750-134.png) 按以上配置(不配置渲染唯一标识),确实可以实现切换爱好时下方的文本框切换,但在提交数据时会发现,即使选择了「运动」,提交的时候 sport 字段是「最喜欢的游戏」的值。 diff --git a/docs/docs/faq/faq003.md b/docs/docs/faq/faq003.md index 74f24b86c4..780614dcfc 100644 --- a/docs/docs/faq/faq003.md +++ b/docs/docs/faq/faq003.md @@ -7,14 +7,14 @@ tags: [FAQ] - [Antd Table 下 button 点击事件怎么拿到行数据?](https://github.com/alibaba/lowcode-engine/issues/341) ## 方式 1 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1657593243427-fb5641b2-4987-475e-88ab-c68d2085edbd.png#clientId=u31b40d04-56f2-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=563&id=u5167bf33&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1126&originWidth=3342&originalType=binary&ratio=1&rotation=0&showTitle=false&size=225551&status=done&style=none&taskId=ud1b89a63-4b6a-4986-a6df-2a463fcf08a&title=&width=1671) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01i58EGG1bxFJBdlS6x_!!6000000003531-2-tps-3342-1126.png) 参考 fusion protable,将操作列直接耦合 button 组件,因为 col.render 函数能拿到 行数据 record,那么 pro-table 组件封装的时候,就可以在渲染操作列按钮的时候,将 col.render 参数透传给 button 组件 ## 方式 2 slot + 扩展参数 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1657593299698-9628db14-7b48-4c06-9e6f-bda637c209a8.png#clientId=u31b40d04-56f2-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=574&id=u20b07439&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1148&originWidth=3284&originalType=binary&ratio=1&rotation=0&showTitle=false&size=232140&status=done&style=none&taskId=ubc80905d-0607-4e73-9386-5dde706e572&title=&width=1642) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01pQk2RC1WBXyxjNDif_!!6000000002750-2-tps-3284-1148.png) 将扩展参数写成: ```json diff --git a/docs/docs/faq/faq005.md b/docs/docs/faq/faq005.md index 6558a67ac2..dd4c9941b4 100644 --- a/docs/docs/faq/faq005.md +++ b/docs/docs/faq/faq005.md @@ -9,13 +9,13 @@ tags: [FAQ] ### 通过资产包 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1657273720962-70045da1-7559-4f7f-a3da-35759778066c.png#averageHue=%231f221e&clientId=ueb9290e1-769e-4&crop=0&crop=0&crop=1&crop=1&errorMessage=unknown%20error&from=paste&height=394&id=u698ffae7&margin=%5Bobject%20Object%5D&name=image.png&originHeight=788&originWidth=806&originalType=binary&ratio=1&rotation=0&showTitle=false&size=175357&status=error&style=none&taskId=u2ed6a3cd-5ec4-4b84-a3c0-fd3379b7019&title=&width=403) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01WWJVSA1WutBvCzXnl_!!6000000002849-2-tps-806-788.png) 就可以在引擎代码中访问到 moment -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1657273737110-6c064e4c-6435-456a-b168-480058b14da8.png#averageHue=%23fdfdfc&clientId=ueb9290e1-769e-4&crop=0&crop=0&crop=1&crop=1&errorMessage=unknown%20error&from=paste&height=126&id=u4ec5fba0&margin=%5Bobject%20Object%5D&name=image.png&originHeight=252&originWidth=1248&originalType=binary&ratio=1&rotation=0&showTitle=false&size=128347&status=error&style=none&taskId=udd229103-04e3-4fc5-9fba-9115354bb9d&title=&width=624) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01EEJ0Kp1nZgJm68nSG_!!6000000005104-2-tps-1248-252.png) PS:需要在 packages 中有相关的资源配置,例如: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1657273863884-2068444e-5653-4b25-ba3a-fd192409fbaa.png#averageHue=%231f1f1d&clientId=ueb9290e1-769e-4&crop=0&crop=0&crop=1&crop=1&errorMessage=unknown%20error&from=paste&height=210&id=ud2a4b3c6&margin=%5Bobject%20Object%5D&name=image.png&originHeight=420&originWidth=1322&originalType=binary&ratio=1&rotation=0&showTitle=false&size=113099&status=error&style=none&taskId=u7ba0f438-9c39-4398-b048-9d0556e2079&title=&width=661) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01bdiHVv206uRYvvAAr_!!6000000006801-2-tps-1322-420.png) 否则在画布中可能会访问不到对应的资源。 diff --git a/docs/docs/faq/faq007.md b/docs/docs/faq/faq007.md index 072444e9a7..07ebba8473 100644 --- a/docs/docs/faq/faq007.md +++ b/docs/docs/faq/faq007.md @@ -3,7 +3,7 @@ title: 设置面板中的高级 tab 如何配置 sidebar_position: 7 tags: [FAQ] --- -![93DC003C-D9A1-4F4F-98A1-F22C0A89EA92.png](https://cdn.nlark.com/yuque/0/2022/png/1053439/1657161085153-a26657ae-2c6e-4124-b9ab-6f8cf8126d1f.png#clientId=u300df630-5bbe-4&crop=0&crop=0&crop=1&crop=1&from=ui&height=591&id=u2ff7824e&margin=%5Bobject%20Object%5D&name=93DC003C-D9A1-4F4F-98A1-F22C0A89EA92.png&originHeight=1714&originWidth=960&originalType=binary&ratio=1&rotation=0&showTitle=false&size=107040&status=done&style=none&taskId=ub377dc1d-db5a-4234-980f-66f7143950d&title=&width=331) +![93DC003C-D9A1-4F4F-98A1-F22C0A89EA92.png](https://img.alicdn.com/imgextra/i4/O1CN01lVutr6243wL6gOQAc_!!6000000007336-2-tps-960-1714.png) 默认这个 tab 下的内容为引擎内置,如需要定制,可以使用以下 API -[https://lowcode-engine.cn/docV2/mu7lml#lIK37](https://lowcode-engine.cn/docV2/mu7lml#lIK37) +[https://lowcode-engine.cn/site/docs/api/material#物料元数据管道函数](https://lowcode-engine.cn/site/docs/api/material#物料元数据管道函数) diff --git a/docs/docs/faq/faq009.md b/docs/docs/faq/faq009.md index 2fe3fa8f63..f1247bfa41 100644 --- a/docs/docs/faq/faq009.md +++ b/docs/docs/faq/faq009.md @@ -19,7 +19,7 @@ AliLowCodeEngine.material.componentsMap ``` 查看物料配置是否正常。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1655277296065-40eeae64-1323-4f7d-89c3-bc48c928aca4.png#clientId=u21fd51ec-6ae9-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=408&id=u21239467&margin=%5Bobject%20Object%5D&name=image.png&originHeight=816&originWidth=1640&originalType=binary&ratio=1&rotation=0&showTitle=false&size=379372&status=done&style=none&taskId=u12a736de-695e-45b9-817b-0f9f6b3a601&title=&width=820) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01bAsPoT1QOTSp7Fmz5_!!6000000001966-2-tps-1640-816.png) 如果正常继续。 LowCodeEngine 需要升级到 1.0.10 diff --git a/docs/docs/faq/faq010.md b/docs/docs/faq/faq010.md index e98ac7f68d..8b54dd2ee9 100644 --- a/docs/docs/faq/faq010.md +++ b/docs/docs/faq/faq010.md @@ -15,4 +15,4 @@ AliLowCodeEngine.skeleton.add({ }); ``` 这里设置 index 为负数,可以将其调整到第一的位置。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1653964459415-694283f6-9c5f-4143-b6d4-51b5aa37f719.png#clientId=uaed53506-efef-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=579&id=u99009edf&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1158&originWidth=1614&originalType=binary&ratio=1&rotation=0&showTitle=false&size=390356&status=done&style=none&taskId=ue153a8c6-13b0-48fa-bfe9-a0d9f7b6cc3&title=&width=807) +![image.png](https://img.alicdn.com/imgextra/i4/O1CN01PTCH3r20fiXrrbcXe_!!6000000006877-2-tps-1614-1158.png) diff --git a/docs/docs/faq/faq011.md b/docs/docs/faq/faq011.md index 793ff7af1e..3c6bf1d2d2 100644 --- a/docs/docs/faq/faq011.md +++ b/docs/docs/faq/faq011.md @@ -5,7 +5,7 @@ tags: [FAQ] --- ## 简单场景 可以利用 props.__designMode -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1653962601596-46e21531-9b8c-45bd-84a7-7522856eb3c9.png#clientId=u8f8d6439-2532-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=220&id=u4d7df210&margin=%5Bobject%20Object%5D&name=image.png&originHeight=440&originWidth=1616&originalType=binary&ratio=1&rotation=0&showTitle=false&size=232329&status=done&style=none&taskId=u85deaa53-ef14-4ce2-a5a2-ac201aa60f5&title=&width=808) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01btr66024FOEldBOr2_!!6000000007361-2-tps-1616-440.png) 设计态中,__designMode 值为 "design" @@ -13,11 +13,11 @@ tags: [FAQ] ## 复杂场景 在资产包里定义 editUrls -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1653962648722-ac8ff758-a0c3-4323-8312-11ac9b511ecf.png#clientId=u8f8d6439-2532-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=269&id=uad79aeaf&margin=%5Bobject%20Object%5D&name=image.png&originHeight=538&originWidth=1590&originalType=binary&ratio=1&rotation=0&showTitle=false&size=257391&status=done&style=none&taskId=u3d8d556b-2da7-40b4-b7e6-cd3600cfbd4&title=&width=795) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01odal6P27Rhjn8NoJ6_!!6000000007794-2-tps-1590-538.png) ### editUrls 在 lowcode/xx/ 下新建一个 view.tsx -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1653971463822-3335e539-6b97-43a7-adf9-cba221a68d87.png#clientId=u89265c24-4294-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=77&id=u466ed474&margin=%5Bobject%20Object%5D&name=image.png&originHeight=154&originWidth=598&originalType=binary&ratio=1&rotation=0&showTitle=false&size=31756&status=done&style=none&taskId=u1f7eeec2-323c-45c7-a1f7-e18bfa3a1db&title=&width=299) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01q0Bbn91Lrig7d0alA_!!6000000001353-2-tps-598-154.png) 再执行 ```json @@ -26,4 +26,4 @@ npm run lowcode:build 之后,build/lowcode 目录下既有 view.js,可作为 editUrls 配置在资产包中。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1653971523747-c15e63e6-9fb7-481e-bf5b-c4bd6cb25927.png#clientId=u89265c24-4294-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=493&id=ucaf08028&margin=%5Bobject%20Object%5D&name=image.png&originHeight=986&originWidth=1082&originalType=binary&ratio=1&rotation=0&showTitle=false&size=235573&status=done&style=none&taskId=ue21c1ab4-0d1b-49fb-8889-b7210b90d41&title=&width=541) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01dvIZ441alxwIlwexS_!!6000000003371-2-tps-1082-986.png) diff --git a/docs/docs/faq/faq012.md b/docs/docs/faq/faq012.md index 95dd7d5337..db156e5b1e 100644 --- a/docs/docs/faq/faq012.md +++ b/docs/docs/faq/faq012.md @@ -61,7 +61,7 @@ condition: () => false, ### 配置没有生效 查看组件中的 schema,对应的配置是否已经正确设置。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/2622706/1653894934869-963be13a-1d6a-458a-a1e1-fd21fa9fc765.png#clientId=uc4e9cec0-362f-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=577&id=u956bc36a&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1154&originWidth=1046&originalType=binary&ratio=1&rotation=0&showTitle=false&size=339838&status=done&style=none&taskId=uf64dae1b-23e9-4444-ab20-9e5f17a5449&title=&width=523) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN015AGT4l1MwaVGGwgua_!!6000000001499-2-tps-1046-1154.png) 没有正确设置上可能的原因是 1.snippets 中没有默认值 diff --git a/docs/docs/faq/faq014.md b/docs/docs/faq/faq014.md index 9c72b2a2ad..8f5f15fe31 100644 --- a/docs/docs/faq/faq014.md +++ b/docs/docs/faq/faq014.md @@ -12,7 +12,7 @@ tags: [FAQ] 在项目的 externals 配置里加[一行配置](https://github.com/alibaba/lowcode-demo/blob/f8afad0df3190565caccc0a1dfd750dbf84c680f/build.json#L16) ## 其他项目 -[相关文档](https://lowcode-engine.cn/docV2/start-with-lce#OMRA2) +[相关文档](/site/docs/guide/create/useEditor#引入-umd-包资源) ### webpack [https://webpack.docschina.org/configuration/externals/](https://webpack.docschina.org/configuration/externals/) diff --git a/docs/docs/faq/faq018.md b/docs/docs/faq/faq018.md index a7b79e44d3..b5a5902404 100644 --- a/docs/docs/faq/faq018.md +++ b/docs/docs/faq/faq018.md @@ -5,6 +5,6 @@ tags: [FAQ] --- 低代码引擎在架构上是和具体语言无关的,通过一定的扩展和插件是可以生成 Vue 页面代码的。 如果只是用现有的基于 React 的 fusion 物料来搭建,只是在最终出码的时候生成 Vue 页面代码,那您需要准备一套和 fusion 兼容的 vue 物料,并定制个出码方案,将[下面的一些出码插件](https://github.com/alibaba/lowcode-engine/blob/main/modules/code-generator/src/solutions/icejs.ts)替换成生成 Vue 框架的即可: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/263300/1648542644942-c019ffd4-1312-4d31-ad61-4e487a47df71.png#clientId=ue0e8d3cc-f9f8-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=517&id=u64b1f996&margin=%5Bobject%20Object%5D&name=image.png&originHeight=1368&originWidth=974&originalType=binary&ratio=1&rotation=0&showTitle=false&size=771387&status=done&style=none&taskId=u51022017-4248-49b8-b8b3-be9a7bb48fb&title=&width=368) -详细定制方案可以参考下[《自定义出码》](https://lowcode-engine.cn/docV2/cplfv0#857ba793)。 -如果您希望在搭建的时候也使用 Vue 的物料,则还需要扩展定制入料、画布和渲染器等模块,详细方案请参考下[《扩展低代码编辑器》](https://lowcode-engine.cn/docV2/srdo3s) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01VxkwCL1l85DiDC2BO_!!6000000004773-2-tps-974-1368.png) +详细定制方案可以参考下[《自定义出码》](/site/docs/guide/expand/runtime/codeGeneration#5自定义出码)。 +如果您希望在搭建的时候也使用 Vue 的物料,则还需要扩展定制入料、画布和渲染器等模块,详细方案请参考下[《扩展低代码编辑器》](/site/docs/guide/expand/editor/summary) diff --git a/docs/docs/faq/faq020.md b/docs/docs/faq/faq020.md index 641e64eb17..5ab1e15f97 100644 --- a/docs/docs/faq/faq020.md +++ b/docs/docs/faq/faq020.md @@ -5,7 +5,7 @@ tags: [FAQ] --- 如果您是自己配置的引擎打包,那么可能会遇到这个问题。 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644896737710-a746e04d-bf4a-40a3-b917-a09235363c81.png#clientId=u627d7b4e-5fe3-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=492&id=u06a9f219&margin=%5Bobject%20Object%5D&name=image.png&originHeight=984&originWidth=1912&originalType=binary&ratio=1&rotation=0&showTitle=false&size=1210174&status=done&style=none&taskId=u2b829db8-026d-472a-baf4-d4660fb5a4a&title=&width=956) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN013xHmcz1WBXygt7VvC_!!6000000002750-2-tps-1912-984.png) 问题的根源是 code-editor 插件运行时直接依赖了 babel 来完成 jsx 编译,babel 从 7.17.0 开始依赖了使用 ESM 编写的 @ampproject/remapping@2.1.0。如果打包工具无法正确处理 ESM,则可能报错。 diff --git a/docs/docs/guide/design/datasourceEngine.md b/docs/docs/guide/design/datasourceEngine.md index f382d9facd..33c7adb082 100644 --- a/docs/docs/guide/design/datasourceEngine.md +++ b/docs/docs/guide/design/datasourceEngine.md @@ -32,7 +32,6 @@ create 接收三个参数,第一个是 DataSource,对于运行时渲染和 ```typescript /** * 数据源对象--运行时渲染 - * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 */ export interface DataSource { list: DataSourceConfig[]; @@ -41,7 +40,6 @@ export interface DataSource { /** * 数据源对象 - * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 */ export interface DataSourceConfig { id: string; @@ -96,7 +94,6 @@ export interface RuntimeDataSourceConfig { /** * 数据源对象 - * @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#XMeF5 */ export interface RuntimeDataSource { list: RuntimeDataSourceConfig[]; diff --git a/docs/docs/guide/design/renderer.md b/docs/docs/guide/design/renderer.md index 417c50de83..bef13694a1 100644 --- a/docs/docs/guide/design/renderer.md +++ b/docs/docs/guide/design/renderer.md @@ -194,7 +194,7 @@ ReactDOM.render(( 画布的渲染和预览模式的渲染的区别在于,画布的渲染和设计器之间是有交互的。所以在这里我们新增了一层 `Simulator` 作为设计器和渲染的连接器。 `Simulator` 是将设计器传入的 `DocumentModel` 和组件/库描述转成相应的 Schema 和 组件类。再调用 Render 层完成渲染。我们这里介绍一下它提供的能力。 ##### 整体架构 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644398136330-0f48202b-b581-4b1f-af79-72a667a194d9.png#clientId=udd4eb4ee-bdb1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=432&id=u734b5c16&margin=%5Bobject%20Object%5D&name=image.png&originHeight=864&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&size=572012&status=done&style=none&taskId=u7d7cf569-d5a9-4bea-9b2d-1121b85728f&title=&width=750) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN017cYBAp1hvJKPUVLbx_!!6000000004339-2-tps-1500-864.png) - `Project`:位于顶层的 Project,保留了对所有文档模型的引用,用于管理应用级 Schema 的导入与导出。 - `Document`:文档模型包括 Simulator 与数据模型两部分。Simulator 通过一份 Simulator Host 协议与数据模型层通信,达到画布上的 UI 操作驱动数据模型变化。通过多文档的设计及多 Tab 交互方式,能够实现同时设计多个页面,以及在一个浏览器标签里进行搭建与配置应用属性。 @@ -207,7 +207,7 @@ ReactDOM.render(( - 通用交互模型:内置了拖拽、活跃追踪、悬停探测、剪贴板、滚动、快捷键绑定。 ##### 模拟器介绍 -![image.png](https://cdn.nlark.com/yuque/0/2022/png/242652/1644398137096-260646a0-f264-48af-9600-6f7141a6a1d8.png#clientId=udd4eb4ee-bdb1-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=370&id=ubfb08f11&margin=%5Bobject%20Object%5D&name=image.png&originHeight=740&originWidth=1500&originalType=binary&ratio=1&rotation=0&showTitle=false&size=353179&status=done&style=none&taskId=u3cd764bb-52f6-47a6-8026-fee6a36d08d&title=&width=750) +![image.png](https://img.alicdn.com/imgextra/i2/O1CN01GF1PMj288kxovvnK8_!!6000000007888-2-tps-1500-740.png) - 运行时环境:从运行时环境来看,目前我们有 React 生态、Rax 生态。而在对外的历程中,我们也会拥有 Vue 生态、Angular 生态等。 - 布局模式:不同于 C 端营销页的搭建,中后台场景大多是表单、表格,流式布局是主流的选择。对于设计师、产品来说,是需要绝对布局的方式来进行页面研发的。 diff --git a/docs/docs/guide/expand/runtime/codeGeneration.md b/docs/docs/guide/expand/runtime/codeGeneration.md index b773ca7196..5cb63c9f64 100644 --- a/docs/docs/guide/expand/runtime/codeGeneration.md +++ b/docs/docs/guide/expand/runtime/codeGeneration.md @@ -123,7 +123,7 @@ console.log(result); // 出码结果 (默认是递归结构描述的,可以传 ### 5)自定义出码 前端框架灵活多变,默认内置的出码方案很难满足所有人的需求,好在此代码生成器支持非常灵活的插件机制 -- 内置功能大多都是通过插件完成的(在 `src/plugins`下),比如: -![image.png](https://cdn.nlark.com/yuque/0/2022/png/263300/1644824565650-584c2be5-4be3-4c9a-96d9-e27990111b0b.png#averageHue=%232b2b2e&clientId=u8b65d964-7bef-4&crop=0&crop=0&crop=1&crop=1&from=paste&height=376&id=u3e0a61a8&margin=%5Bobject%20Object%5D&name=image.png&originHeight=376&originWidth=457&originalType=binary&ratio=1&rotation=0&showTitle=false&size=151355&status=done&style=none&taskId=ueef52494-2e18-45a2-8409-7f68e200f63&title=&width=457) +![image.png](https://img.alicdn.com/imgextra/i1/O1CN01CEl2Hq1omnH0UCyGF_!!6000000005268-2-tps-457-376.png) 所以您可以通过添加自己的插件或替换掉默认内置的插件来实现您的自定义功能。 为了方便自定义出码方案,出码模块还提供自定义出码方案的脚手架功能,即执行下面脚本即可生成一个自定义出码方案: ```shell diff --git a/docs/docs/participate/flow.md b/docs/docs/participate/flow.md index e9675a387d..676abffedf 100644 --- a/docs/docs/participate/flow.md +++ b/docs/docs/participate/flow.md @@ -19,7 +19,7 @@ sidebar_position: 2 几点要求: 1. commit message 格式遵循 [ConvensionalCommits](https://www.conventionalcommits.org/en/v1.0.0/#summary) -![image.png](https://cdn.nlark.com/yuque/0/2022/png/110793/1645066644352-4de1c64c-bff6-4482-90d1-1fb610aa91f2.png#averageHue=%23eceef0&clientId=u6dcee4f0-35df-4&crop=0&crop=0&crop=1&crop=1&height=297&id=CfpQy&margin=%5Bobject%20Object%5D&name=image.png&originHeight=594&originWidth=2070&originalType=binary&ratio=1&rotation=0&showTitle=false&size=341605&status=done&style=none&taskId=u4499b752-5e24-42f6-9186-280fd5a51aa&title=&width=1035) +![image.png](https://img.alicdn.com/imgextra/i3/O1CN01M9UzVM1iqYpyxECdV_!!6000000004464-2-tps-2070-594.png) 2. 请按照一个 bugfix / feature 对应一个 commit,假如不是,请 rebase 后再提交 MR,不要一堆无用的、试验性的 commit。 好处:从引擎的整体 commit 历史来看,会很清晰,**每个 commit 完成一件确定的事,changelog 也能自动生成**。另外,假如因为某个 commit 导致了 bug,也很容易通过 rebase drop 等方式快速修复。 diff --git a/docs/docs/specs/material-spec.md b/docs/docs/specs/material-spec.md index 9d12da5262..c74d0c96a2 100644 --- a/docs/docs/specs/material-spec.md +++ b/docs/docs/specs/material-spec.md @@ -841,7 +841,7 @@ props 数组下对象字段描述: | extraProps.setValue | setter 内容修改时调用,开发者可在该函数内部修改节点 schema 或者进行其他操作 | Function | (target: SettingTarget, value: any) => void; | -根据属性值类型 propType,确定对应控件类型 (setter) ,详见 [https://lowcode-engine.cn/docV2/grfylu](https://lowcode-engine.cn/docV2/grfylu) +根据属性值类型 propType,确定对应控件类型 (setter) 。 ###### 2.2.2.4.2 通用扩展面板支持性配置 supports (AA) diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo01/schema.json5 b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo01/schema.json5 index 282f979e89..94c3a2fb7b 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo01/schema.json5 +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo01/schema.json5 @@ -1,6 +1,5 @@ { // 本例是一个非常简单的 Hello world 页面 - // Schema 参见:https://yuque.antfin-inc.com/mo/spec/spec-materials#eNCJr version: '1.0.0', componentsMap: [ { diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo02/schema.json5 b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo02/schema.json5 index fa39cdb45d..59f1a8bbc2 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo02/schema.json5 +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo02/schema.json5 @@ -1,6 +1,5 @@ { // 本例是一个比较复杂的,带有循环和条件渲染的,以及有各种事件处理函数的页面 - // Schema 参见:https://yuque.antfin-inc.com/mo/spec/spec-materials#eNCJr version: '1.0.0', componentsMap: [ { diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo03/schema.json5 b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo03/schema.json5 index 5652b1db1a..bed7c8092f 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo03/schema.json5 +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo03/schema.json5 @@ -1,6 +1,5 @@ { // 本例是一个路由测试页面,里面有几个页面,相互之间有跳转关系的 - // Schema 参见:https://yuque.antfin-inc.com/mo/spec/spec-materials#eNCJr version: '1.0.0', componentsMap: [ { diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo05/schema.json5 b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo05/schema.json5 index 3c767dfd9b..483e527319 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo05/schema.json5 +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo05/schema.json5 @@ -1,6 +1,5 @@ { // 这是一个关于国际化的 schema 示例 - // Schema 参见:https://yuque.antfin-inc.com/mo/spec/spec-materials#eNCJr version: '1.0.0', componentsMap: [ { diff --git a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo12-refs/schema.json5 b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo12-refs/schema.json5 index 4f5f5db7f2..9a89838a12 100644 --- a/modules/code-generator/tests/fixtures/test-cases/rax-app/demo12-refs/schema.json5 +++ b/modules/code-generator/tests/fixtures/test-cases/rax-app/demo12-refs/schema.json5 @@ -1,6 +1,5 @@ { // 这是一个关于国际化的 schema 示例 - // Schema 参见:https://yuque.antfin-inc.com/mo/spec/spec-materials#eNCJr version: '1.0.0', componentsMap: [ { diff --git a/modules/material-parser/README.md b/modules/material-parser/README.md index 4507b7e6ea..0d3f5555d5 100644 --- a/modules/material-parser/README.md +++ b/modules/material-parser/README.md @@ -4,7 +4,7 @@ 本模块负责物料接入,能自动扫描、解析源码组件,并最终产出一份符合《中后台搭建组件描述协议》的 **JSON Schema**。 -详见[文档](https://lowcode-engine.cn/docV2/yhgcqb)。 +详见[文档](https://lowcode-engine.cn/site/docs/guide/design/materialParser)。 ## demo diff --git a/packages/editor-core/src/config.ts b/packages/editor-core/src/config.ts index ee44546c55..4d870f5783 100644 --- a/packages/editor-core/src/config.ts +++ b/packages/editor-core/src/config.ts @@ -123,7 +123,7 @@ const VALID_ENGINE_OPTIONS = { description: '自定义 simulatorUrl 的地址', }, /** - * 与 react-renderer 的 appHelper 一致, https://lowcode-engine.cn/docV2/nhilce#appHelper + * 与 react-renderer 的 appHelper 一致, https://www.yuque.com/lce/doc/nhilce#appHelper */ appHelper: { type: 'object', @@ -247,7 +247,7 @@ export interface EngineOptions { enableFilterReducerInRenderStage?: boolean; }; /** - * 与 react-renderer 的 appHelper 一致, https://lowcode-engine.cn/docV2/nhilce#appHelper + * 与 react-renderer 的 appHelper 一致, https://www.yuque.com/lce/doc/nhilce#appHelper */ appHelper?: { /** 全局公共函数 */ diff --git a/packages/editor-skeleton/src/transducers/addon-combine.ts b/packages/editor-skeleton/src/transducers/addon-combine.ts index 8975e7efa0..d02d6aa189 100644 --- a/packages/editor-skeleton/src/transducers/addon-combine.ts +++ b/packages/editor-skeleton/src/transducers/addon-combine.ts @@ -319,7 +319,7 @@ export default function (metadata: TransformedComponentMetadata): TransformedCom title: { label: '渲染唯一标识(key)', tip: '搭配「条件渲染」或「循环渲染」时使用,和 react 组件中的 key 原理相同,点击查看帮助', - docUrl: 'https://lowcode-engine.cn/docV2/qm75w3', + docUrl: 'https://www.yuque.com/lce/doc/qm75w3', }, setter: [ { From 5a3ca971877a0889323b72605766ab25dfb0a15e Mon Sep 17 00:00:00 2001 From: JackLian Date: Thu, 8 Dec 2022 11:46:51 +0800 Subject: [PATCH 229/823] chore: update doc version --- docs/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/package.json b/docs/package.json index 66a731478b..d0e6685dcb 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.0.5", + "version": "1.0.6", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 5de97c10c8b308ebb63040f385853c8fa5c1bcaa Mon Sep 17 00:00:00 2001 From: JackLian Date: Thu, 8 Dec 2022 13:21:33 +0800 Subject: [PATCH 230/823] feat: add types for engineConfig and put it to types --- packages/editor-core/src/config.ts | 170 +++++--------------------- packages/editor-core/src/editor.ts | 15 ++- packages/types/src/assets.ts | 2 +- packages/types/src/engine-config.ts | 181 ++++++++++++++++++++++++++++ packages/types/src/index.ts | 1 + 5 files changed, 219 insertions(+), 150 deletions(-) create mode 100644 packages/types/src/engine-config.ts diff --git a/packages/editor-core/src/config.ts b/packages/editor-core/src/config.ts index 4d870f5783..ad426f74b9 100644 --- a/packages/editor-core/src/config.ts +++ b/packages/editor-core/src/config.ts @@ -1,9 +1,6 @@ -import { ComponentType } from 'react'; import { get as lodashGet } from 'lodash'; import { isPlainObject } from '@alilc/lowcode-utils'; - -import { RequestHandlersMap } from '@alilc/lowcode-datasource-types'; - +import { EngineOptions, IEngineConfig } from '@alilc/lowcode-types'; import { getLogger } from './utils/logger'; const logger = getLogger({ level: 'log', bizName: 'config' }); @@ -53,7 +50,7 @@ const VALID_ENGINE_OPTIONS = { enableStrictPluginMode: { type: 'boolean', default: STRICT_PLUGIN_MODE_DEFAULT, - description: '开启严格插件模式,默认值: STRICT_PLUGIN_MODE_DEFAULT , 严格模式下,插件将无法通过engineOptions传递自定义配置项', + description: '开启严格插件模式,默认值:STRICT_PLUGIN_MODE_DEFAULT , 严格模式下,插件将无法通过 engineOptions 传递自定义配置项', }, enableReactiveContainer: { type: 'boolean', @@ -123,7 +120,7 @@ const VALID_ENGINE_OPTIONS = { description: '自定义 simulatorUrl 的地址', }, /** - * 与 react-renderer 的 appHelper 一致, https://www.yuque.com/lce/doc/nhilce#appHelper + * 与 react-renderer 的 appHelper 一致,https://lowcode-engine.cn/site/docs/guide/expand/runtime/renderer#apphelper */ appHelper: { type: 'object', @@ -146,138 +143,7 @@ const VALID_ENGINE_OPTIONS = { description: '配置指定节点为根组件', }, }; -export interface EngineOptions { - /** - * 是否开启 condition 的能力,默认在设计器中不管 condition 是啥都正常展示 - */ - enableCondition?: boolean; - /** - * @todo designMode 无法映射到文档渲染模块 - * - * 设计模式,live 模式将会实时展示变量值,默认值:'design' - */ - designMode?: 'design' | 'live'; - /** - * 设备类型,默认值:'default' - */ - device?: 'default' | 'mobile' | string; - /** - * 指定初始化的 deviceClassName,挂载到画布的顶层节点上 - */ - deviceClassName?: string; - /** - * 语言,默认值:'zh-CN' - */ - locale?: string; - /** - * 渲染器类型,默认值:'react' - */ - renderEnv?: 'react' | 'rax' | string; - /** - * 设备类型映射器,处理设计器与渲染器中 device 的映射 - */ - deviceMapper?: { - transform: (originalDevice: string) => string; - }; - /** - * 开启严格插件模式,默认值: STRICT_PLUGIN_MODE_DEFAULT , 严格模式下,插件将无法通过engineOptions传递自定义配置项 - * enable strict plugin mode, default value: false - * under strict mode, customed engineOption is not accepted. - */ - enableStrictPluginMode?: boolean; - /** - * 开启拖拽组件时,即将被放入的容器是否有视觉反馈,默认值:false - */ - enableReactiveContainer?: boolean; - /** - * 关闭画布自动渲染,在资产包多重异步加载的场景有效,默认值:false - */ - disableAutoRender?: boolean; - /** - * 关闭拖拽组件时的虚线响应,性能考虑,默认值:false - */ - disableDetecting?: boolean; - /** - * 定制画布中点击被忽略的 selectors,默认值:undefined - */ - customizeIgnoreSelectors?: (defaultIgnoreSelectors: string[], e: MouseEvent) => string[]; - /** - * 禁止默认的设置面板,默认值:false - */ - disableDefaultSettingPanel?: boolean; - /** - * 禁止默认的设置器,默认值:false - */ - disableDefaultSetters?: boolean; - /** - * 打开画布的锁定操作,默认值:false - */ - enableCanvasLock?: boolean; - /** - * 容器锁定后,容器本身是否可以设置属性,仅当画布锁定特性开启时生效, 默认值为:false - */ - enableLockedNodeSetting?: boolean; - /** - * 当选中节点切换时,是否停留在相同的设置 tab 上,默认值:false - */ - stayOnTheSameSettingTab?: boolean; - /** - * 是否在只有一个 item 的时候隐藏设置 tabs,默认值:false - */ - hideSettingsTabsWhenOnlyOneItem?: boolean; - /** - * 自定义 loading 组件 - */ - loadingComponent?: ComponentType; - /** - * 设置所有属性支持变量配置,默认值:false - */ - supportVariableGlobally?: boolean; - /** - * 设置 simulator 相关的 url,默认值:undefined - */ - simulatorUrl?: string[]; - /** - * Vision-polyfill settings - */ - visionSettings?: { - // 是否禁用降级 reducer,默认值:false - disableCompatibleReducer?: boolean; - // 是否开启在 render 阶段开启 filter reducer,默认值:false - enableFilterReducerInRenderStage?: boolean; - }; - /** - * 与 react-renderer 的 appHelper 一致, https://www.yuque.com/lce/doc/nhilce#appHelper - */ - appHelper?: { - /** 全局公共函数 */ - utils?: Record; - /** 全局常量 */ - constants?: Record; - }; - /** - * 数据源引擎的请求处理器映射 - */ - requestHandlersMap?: RequestHandlersMap; - - /** - * @default true - * JSExpression 是否只支持使用 this 来访问上下文变量,假如需要兼容原来的 'state.xxx',则设置为 false - */ - thisRequiredInJSE?: boolean; - - /** - * @default false - * 当开启组件未找到严格模式时,渲染模块不会默认给一个容器组件 - */ - enableStrictNotFoundMode?: boolean; - - /** - * 配置指定节点为根组件 - */ - focusNodeSelector?: (rootNode: Node) => Node; -} const getStrictModeValue = (engineOptions: EngineOptions, defaultValue: boolean): boolean => { if (!engineOptions || !isPlainObject(engineOptions)) { @@ -289,7 +155,25 @@ const getStrictModeValue = (engineOptions: EngineOptions, defaultValue: boolean) } return engineOptions.enableStrictPluginMode; }; -export class EngineConfig { + +export interface IEngineConfigPrivate { + /** + * if engineOptions.strictPluginMode === true, only accept propertied predefined in EngineOptions. + * + * @param {EngineOptions} engineOptions + * @memberof EngineConfig + */ + setEngineOptions(engineOptions: EngineOptions): void; + + notifyGot(key: string): void; + + setWait(key: string, resolve: (data: any) => void, once?: boolean): void; + + delWait(key: string, fn: any): void; +} + + +export class EngineConfig implements IEngineConfig, IEngineConfigPrivate { private config: { [key: string]: any } = {}; private waits = new Map< @@ -363,7 +247,7 @@ export class EngineConfig { }; Object.keys(engineOptions).forEach((key) => { if (isValidKey(key)) { - this.set(key, engineOptions[key]); + this.set(key, (engineOptions as any)[key]); } else { logger.warn(`failed to config ${key} to engineConfig, only predefined options can be set under strict mode, predefined options: `, VALID_ENGINE_OPTIONS); } @@ -408,7 +292,7 @@ export class EngineConfig { } } - private notifyGot(key: string) { + notifyGot(key: string): void { let waits = this.waits.get(key); if (!waits) { return; @@ -428,7 +312,7 @@ export class EngineConfig { } } - private setWait(key: string, resolve: (data: any) => void, once?: boolean) { + setWait(key: string, resolve: (data: any) => void, once?: boolean) { const waits = this.waits.get(key); if (waits) { waits.push({ resolve, once }); @@ -437,7 +321,7 @@ export class EngineConfig { } } - private delWait(key: string, fn: any) { + delWait(key: string, fn: any) { const waits = this.waits.get(key); if (!waits) { return; @@ -454,4 +338,4 @@ export class EngineConfig { } } -export const engineConfig = new EngineConfig(); +export const engineConfig = new EngineConfig(); \ No newline at end of file diff --git a/packages/editor-core/src/editor.ts b/packages/editor-core/src/editor.ts index bc46086f65..f3b52c61d3 100644 --- a/packages/editor-core/src/editor.ts +++ b/packages/editor-core/src/editor.ts @@ -1,3 +1,5 @@ +/* eslint-disable no-console */ +/* eslint-disable max-len */ import { StrictEventEmitter } from 'strict-event-emitter-types'; import { EventEmitter } from 'events'; import { @@ -13,7 +15,6 @@ import { } from '@alilc/lowcode-types'; import { engineConfig } from './config'; import { globalLocale } from './intl'; -import * as utils from './utils'; import Preference from './utils/preference'; import { obx } from './utils'; import { AssetsJson, AssetLoader } from '@alilc/lowcode-utils'; @@ -68,7 +69,9 @@ export class Editor extends (EventEmitter as any) implements IEditor { private hooks: HookConfig[] = []; - get(keyOrType: KeyOrType): GetReturnType | undefined { + get( + keyOrType: KeyOrType, + ): GetReturnType | undefined { return this.context.get(keyOrType as any); } @@ -76,7 +79,7 @@ export class Editor extends (EventEmitter as any) implements IEditor { return this.context.has(keyOrType); } - set(key: KeyType, data: any): void | Promise { + set(key: KeyType, data: any): void | Promise { if (key === 'assets') { return this.setAssets(data); } @@ -113,8 +116,8 @@ export class Editor extends (EventEmitter as any) implements IEditor { const { exportName, url } = component; await (new AssetLoader()).load(url); if (window[exportName]) { - assets.components = assets.components.concat(window[exportName].components || []); - assets.componentList = assets.componentList.concat(window[exportName].componentList || []); + assets.components = assets.components.concat((window[exportName] as any).components || []); + assets.componentList = assets.componentList?.concat((window[exportName] as any).componentList || []); } return window[exportName]; }), @@ -215,7 +218,7 @@ export class Editor extends (EventEmitter as any) implements IEditor { registerHooks = (hooks: HookConfig[]) => { this.initHooks(hooks).forEach(({ message, type, handler }) => { if (['on', 'once'].indexOf(type) !== -1) { - this[type](message, handler); + this[type]((message as any), handler); } }); }; diff --git a/packages/types/src/assets.ts b/packages/types/src/assets.ts index 65129532a1..581af679b1 100644 --- a/packages/types/src/assets.ts +++ b/packages/types/src/assets.ts @@ -62,7 +62,7 @@ export interface AssetsJson { */ version: string; /** - * 大包列表,external与package的概念相似,融合在一起 + * 大包列表,external 与 package 的概念相似,融合在一起 */ packages?: Package[]; /** diff --git a/packages/types/src/engine-config.ts b/packages/types/src/engine-config.ts new file mode 100644 index 0000000000..5fb2196fdc --- /dev/null +++ b/packages/types/src/engine-config.ts @@ -0,0 +1,181 @@ +import { RequestHandlersMap } from '@alilc/lowcode-datasource-types'; +import { ComponentType } from 'react'; + +export interface EngineOptions { + /** + * 是否开启 condition 的能力,默认在设计器中不管 condition 是啥都正常展示 + */ + enableCondition?: boolean; + /** + * @todo designMode 无法映射到文档渲染模块 + * + * 设计模式,live 模式将会实时展示变量值,默认值:'design' + */ + designMode?: 'design' | 'live'; + /** + * 设备类型,默认值:'default' + */ + device?: 'default' | 'mobile' | string; + /** + * 指定初始化的 deviceClassName,挂载到画布的顶层节点上 + */ + deviceClassName?: string; + /** + * 语言,默认值:'zh-CN' + */ + locale?: string; + /** + * 渲染器类型,默认值:'react' + */ + renderEnv?: 'react' | 'rax' | string; + /** + * 设备类型映射器,处理设计器与渲染器中 device 的映射 + */ + deviceMapper?: { + transform: (originalDevice: string) => string; + }; + /** + * 开启严格插件模式,默认值:STRICT_PLUGIN_MODE_DEFAULT , 严格模式下,插件将无法通过 engineOptions 传递自定义配置项 + * enable strict plugin mode, default value: false + * under strict mode, customed engineOption is not accepted. + */ + enableStrictPluginMode?: boolean; + /** + * 开启拖拽组件时,即将被放入的容器是否有视觉反馈,默认值:false + */ + enableReactiveContainer?: boolean; + /** + * 关闭画布自动渲染,在资产包多重异步加载的场景有效,默认值:false + */ + disableAutoRender?: boolean; + /** + * 关闭拖拽组件时的虚线响应,性能考虑,默认值:false + */ + disableDetecting?: boolean; + /** + * 定制画布中点击被忽略的 selectors,默认值:undefined + */ + customizeIgnoreSelectors?: (defaultIgnoreSelectors: string[], e: MouseEvent) => string[]; + /** + * 禁止默认的设置面板,默认值:false + */ + disableDefaultSettingPanel?: boolean; + /** + * 禁止默认的设置器,默认值:false + */ + disableDefaultSetters?: boolean; + /** + * 打开画布的锁定操作,默认值:false + */ + enableCanvasLock?: boolean; + /** + * 容器锁定后,容器本身是否可以设置属性,仅当画布锁定特性开启时生效,默认值为:false + */ + enableLockedNodeSetting?: boolean; + /** + * 当选中节点切换时,是否停留在相同的设置 tab 上,默认值:false + */ + stayOnTheSameSettingTab?: boolean; + /** + * 是否在只有一个 item 的时候隐藏设置 tabs,默认值:false + */ + hideSettingsTabsWhenOnlyOneItem?: boolean; + /** + * 自定义 loading 组件 + */ + loadingComponent?: ComponentType; + /** + * 设置所有属性支持变量配置,默认值:false + */ + supportVariableGlobally?: boolean; + /** + * 设置 simulator 相关的 url,默认值:undefined + */ + simulatorUrl?: string[]; + /** + * Vision-polyfill settings + */ + visionSettings?: { + // 是否禁用降级 reducer,默认值:false + disableCompatibleReducer?: boolean; + // 是否开启在 render 阶段开启 filter reducer,默认值:false + enableFilterReducerInRenderStage?: boolean; + }; + /** + * 与 react-renderer 的 appHelper 一致,https://lowcode-engine.cn/site/docs/guide/expand/runtime/renderer#apphelper + */ + appHelper?: { + /** 全局公共函数 */ + utils?: Record; + /** 全局常量 */ + constants?: Record; + }; + + /** + * 数据源引擎的请求处理器映射 + */ + requestHandlersMap?: RequestHandlersMap; + + /** + * @default true + * JSExpression 是否只支持使用 this 来访问上下文变量,假如需要兼容原来的 'state.xxx',则设置为 false + */ + thisRequiredInJSE?: boolean; + + /** + * @default false + * 当开启组件未找到严格模式时,渲染模块不会默认给一个容器组件 + */ + enableStrictNotFoundMode?: boolean; + + /** + * 配置指定节点为根组件 + */ + focusNodeSelector?: (rootNode: Node) => Node; +} + +export interface IEngineConfig { + /** + * 判断指定 key 是否有值 + * @param key + * @returns + */ + has(key: string): boolean; + + /** + * 获取指定 key 的值 + * @param key + * @param defaultValue + * @returns + */ + get(key: string, defaultValue?: any): any; + + /** + * 设置指定 key 的值 + * @param key + * @param value + */ + set(key: string, value: any): void; + + /** + * 批量设值,set 的对象版本 + * @param config + */ + setConfig(config: { [key: string]: any }): void; + + /** + * 获取指定 key 的值,若此时还未赋值,则等待,若已有值,则直接返回值 + * 注:此函数返回 Promise 实例,只会执行(fullfill)一次 + * @param key + * @returns + */ + onceGot(key: string): Promise; + + /** + * 获取指定 key 的值,函数回调模式,若多次被赋值,回调会被多次调用 + * @param key + * @param fn + * @returns + */ + onGot(key: string, fn: (data: any) => void): () => void; +} \ No newline at end of file diff --git a/packages/types/src/index.ts b/packages/types/src/index.ts index 8ebd296931..9db5bae46f 100644 --- a/packages/types/src/index.ts +++ b/packages/types/src/index.ts @@ -28,5 +28,6 @@ export * from './designer'; export * from './dragon'; export * from './shell'; export * from './shell-model-factory'; +export * from './engine-config'; // TODO: remove this in future versions export * from './deprecated'; From 335314aec6843511dc0f53ba73518df7910e6d9a Mon Sep 17 00:00:00 2001 From: huoteng Date: Thu, 8 Dec 2022 13:34:04 +0800 Subject: [PATCH 231/823] fix(history): do not record unchanged data --- packages/designer/src/document/history.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/packages/designer/src/document/history.ts b/packages/designer/src/document/history.ts index 96a1e40f7c..eaac946b15 100644 --- a/packages/designer/src/document/history.ts +++ b/packages/designer/src/document/history.ts @@ -41,6 +41,12 @@ export class History { if (this.asleep) return; untracked(() => { const log = this.currentSerialization.serialize(data); + + // do not record unchanged data + if (this.session.data === log) { + return; + } + if (this.session.isActive()) { this.session.log(log); } else { From f6feef218aeecaa8a2ab4f164756662dba0d054e Mon Sep 17 00:00:00 2001 From: JackLian Date: Fri, 9 Dec 2022 11:19:52 +0800 Subject: [PATCH 232/823] fix: plugin context, enhancePluginContextHook not working --- package.json | 5 +++-- packages/designer/src/plugin/plugin-context.ts | 3 +-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index 7e70b38ae2..0fd7fdf8a5 100644 --- a/package.json +++ b/package.json @@ -60,5 +60,6 @@ }, "resolutions": { "@builder/babel-preset-ice": "1.0.1" - } -} + }, + "repository": "git@github.com:alibaba/lowcode-engine.git" +} \ No newline at end of file diff --git a/packages/designer/src/plugin/plugin-context.ts b/packages/designer/src/plugin/plugin-context.ts index edb515543a..7ddc3a5bd9 100644 --- a/packages/designer/src/plugin/plugin-context.ts +++ b/packages/designer/src/plugin/plugin-context.ts @@ -41,6 +41,7 @@ export default class PluginContext implements ILowCodePluginContext, ILowCodePlu options: IPluginContextOptions, contextApiAssembler: ILowCodePluginContextApiAssembler, ) { + contextApiAssembler.assembleApis(this); this.plugins = plugins; const { pluginName = 'anonymous' } = options; this.logger = getLogger({ level: 'warn', bizName: `designer:plugin:${pluginName}` }); @@ -49,8 +50,6 @@ export default class PluginContext implements ILowCodePluginContext, ILowCodePlu if (enhancePluginContextHook) { enhancePluginContextHook(this); } - - contextApiAssembler.assembleApis(this); } setPreference( From 9b95daba8136c0c12a697a2de9ca386d0350616a Mon Sep 17 00:00:00 2001 From: JackLian Date: Fri, 9 Dec 2022 11:42:37 +0800 Subject: [PATCH 233/823] chore: upgrade dep versions --- package.json | 5 +++-- packages/designer/package.json | 4 ++-- packages/editor-core/package.json | 2 +- packages/editor-skeleton/package.json | 2 +- packages/plugin-designer/package.json | 2 +- packages/plugin-outline-pane/package.json | 2 +- packages/rax-simulator-renderer/package.json | 2 +- packages/react-renderer/package.json | 2 +- packages/react-simulator-renderer/package.json | 2 +- packages/renderer-core/package.json | 2 +- packages/shell/package.json | 4 ++-- packages/types/package.json | 2 +- packages/utils/package.json | 2 +- 13 files changed, 17 insertions(+), 16 deletions(-) diff --git a/package.json b/package.json index 0fd7fdf8a5..cbd75e75b4 100644 --- a/package.json +++ b/package.json @@ -59,7 +59,8 @@ "lockfile": "enable" }, "resolutions": { - "@builder/babel-preset-ice": "1.0.1" + "@builder/babel-preset-ice": "1.0.1", + "typescript": "4.6.2" }, "repository": "git@github.com:alibaba/lowcode-engine.git" -} \ No newline at end of file +} diff --git a/packages/designer/package.json b/packages/designer/package.json index 86e79cf510..4f35daf711 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -39,8 +39,8 @@ "@types/react-dom": "^16", "@types/semver": "7.3.9", "babel-jest": "^26.5.2", - "build-plugin-component": "^0.2.10", - "build-scripts-config": "^0.1.8", + "build-plugin-component": "^1.0.0", + "build-scripts-config": "^3.0.3", "enzyme": "^3.11.0", "@types/enzyme": "^3.10.12", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 208f932d69..90c551fece 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -37,7 +37,7 @@ "@types/react": "^16", "@types/react-dom": "^16", "@types/store": "^2.0.2", - "build-plugin-component": "^0.2.11", + "build-plugin-component": "^1.0.0", "build-plugin-fusion": "^0.1.0", "build-plugin-moment-locales": "^0.1.0" }, diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 705c418b26..7847364129 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -30,7 +30,7 @@ "@alib/build-scripts": "^0.1.3", "@types/react": "^16.9.13", "@types/react-dom": "^16.9.4", - "build-plugin-component": "^0.2.7", + "build-plugin-component": "^1.0.0", "build-plugin-fusion": "^0.1.0", "build-plugin-moment-locales": "^0.1.0" }, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index 5e06b8cd86..a01ac6d4ef 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -28,7 +28,7 @@ "@alib/build-scripts": "^0.1.3", "@types/react": "^16.9.13", "@types/react-dom": "^16.9.4", - "build-plugin-component": "^0.2.7" + "build-plugin-component": "^1.0.0" }, "publishConfig": { "access": "public", diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index a5129db9dc..c67a36f66a 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -28,7 +28,7 @@ "@types/node": "^13.7.1", "@types/react": "^16", "@types/react-dom": "^16", - "build-plugin-component": "^0.2.10", + "build-plugin-component": "^1.0.0", "build-plugin-fusion": "^0.1.1", "build-plugin-moment-locales": "^0.1.0" }, diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index 87134571b9..680e78a70c 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -36,7 +36,7 @@ "@types/rax": "^1.0.0", "@types/react": "^16", "@types/react-dom": "^16", - "build-plugin-component": "^0.2.11", + "build-plugin-component": "^1.0.0", "build-plugin-rax-component": "^0.2.11" }, "peerDependencies": { diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 7d1ebf1121..52c5211dd1 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -27,7 +27,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.19.17", - "build-plugin-component": "^0.2.10", + "build-plugin-component": "^1.0.0", "build-plugin-fusion": "^0.1.0", "build-plugin-moment-locales": "^0.1.0", "react": "^16.4.1", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index c91dec079c..45cc423c8c 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -34,7 +34,7 @@ "@types/react": "^16", "@types/react-dom": "^16", "@types/react-router": "5.1.18", - "build-plugin-component": "^0.2.11" + "build-plugin-component": "^1.0.0" }, "publishConfig": { "access": "public", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 6c818991f5..217606287a 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -46,7 +46,7 @@ "@types/react-is": "^17.0.3", "@types/react-test-renderer": "^17.0.1", "babel-jest": "^26.5.2", - "build-plugin-component": "^0.2.11", + "build-plugin-component": "^1.0.0", "jest": "^26.6.3", "react-test-renderer": "^17.0.2", "ts-jest": "^26.5.0" diff --git a/packages/shell/package.json b/packages/shell/package.json index 9d0e0b62fd..fd794904bb 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -39,8 +39,8 @@ "@types/react": "^16", "@types/react-dom": "^16", "babel-jest": "^26.5.2", - "build-plugin-component": "^0.2.10", - "build-scripts-config": "^0.1.8", + "build-plugin-component": "^1.0.0", + "build-scripts-config": "^3.0.3", "jest": "^26.6.3", "lodash": "^4.17.20", "moment": "^2.29.1", diff --git a/packages/types/package.json b/packages/types/package.json index 39d3e7c49b..c61ecded9f 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -20,7 +20,7 @@ "@alib/build-scripts": "^0.1.18", "@types/node": "^13.7.1", "@types/react": "^16", - "build-plugin-component": "^0.2.10" + "build-plugin-component": "^1.0.0" }, "publishConfig": { "access": "public", diff --git a/packages/utils/package.json b/packages/utils/package.json index 5555f84573..2b1b75fb1b 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -24,7 +24,7 @@ "@alib/build-scripts": "^0.1.18", "@types/node": "^13.7.1", "@types/react": "^16", - "build-plugin-component": "^0.2.10" + "build-plugin-component": "^1.0.0" }, "publishConfig": { "access": "public", From de3443a9dc0f68ca094e5e92ca6ccbc61ac7e488 Mon Sep 17 00:00:00 2001 From: JackLian Date: Fri, 9 Dec 2022 11:34:12 +0800 Subject: [PATCH 234/823] docs: add faqs --- docs/docs/faq/faq021.md | 18 ++++++++++++++++++ docs/docs/faq/faq022.md | 18 ++++++++++++++++++ docs/docs/participate/doc.md | 4 ++-- docs/docs/participate/index.md | 3 ++- docs/package.json | 2 +- 5 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 docs/docs/faq/faq021.md create mode 100644 docs/docs/faq/faq022.md diff --git a/docs/docs/faq/faq021.md b/docs/docs/faq/faq021.md new file mode 100644 index 0000000000..ba5c18e113 --- /dev/null +++ b/docs/docs/faq/faq021.md @@ -0,0 +1,18 @@ +--- +title: 提交 PR 时,明明签署过 CLA,仍被提示需要签署 +sidebar_position: 21 +tags: [FAQ] +--- +## 问题原因 + +原因是:git commit 时,本地 git config 配置的 email 与 github 账号的 email 不一致,导致未被识别出来,检查方式 + +```bash +git config user.email +``` + +## 解决办法 + +如何配置,可参考 [is-it-possible-to-have-different-git-configuration-for-different-projects](https://stackoverflow.com/questions/8801729/is-it-possible-to-have-different-git-configuration-for-different-projects) + +配置好正确的 email 之后,已提交的代码需要以新的配置重新提交才可生效。 \ No newline at end of file diff --git a/docs/docs/faq/faq022.md b/docs/docs/faq/faq022.md new file mode 100644 index 0000000000..86ec00c37b --- /dev/null +++ b/docs/docs/faq/faq022.md @@ -0,0 +1,18 @@ +--- +title: 节点无法拖拽到 Page 下 +sidebar_position: 22 +tags: [FAQ] +--- +查看 Page 节点的 childWhitelist 配置,如果 Page 配置了 childWhitelist,且当前节点不在白名单下,是无法拖拽的。 +```typescript +AliLowCodeEngine.material.getComponentMeta('Page').getMetadata().configure.component.nestingRule.childWhitelist +``` + +比如在 [demo](https://lowcode-engine.cn/demo/demo-general/index.html) 中 Page 组件的 childWhitelist 为:['NextPage', 'ProDialog', 'Dialog', 'Drawer'],则只有这些组件可以拖拽到 Page 的 children 下,其他组件均不可以。 + +说明:1.0.15 之前 Page 组件的 childWhitelist 限制是失效的,在 1.0.16 版本进行了 bug 修复。 + +### 解决办法 +**方法 1:直接修改 Page 组件的 childWhitelist,比如删除**。 + +**方法 2:通过 **[**material.registerMetadataTransducer**](/site/docs/api/material#registermetadatatransducer)** 修改 Page 组件的 childWhitelist(适用于 Page 组件是其他人维护的)** diff --git a/docs/docs/participate/doc.md b/docs/docs/participate/doc.md index d2b86ff330..1e19918db5 100644 --- a/docs/docs/participate/doc.md +++ b/docs/docs/participate/doc.md @@ -1,5 +1,5 @@ --- -title: 官网文档协作流程 +title: 参与文档贡献 sidebar_position: 3 --- @@ -10,7 +10,7 @@ sidebar_position: 3 - 官方文档通过 github 管理文档源,官网文档与[主仓库 develop 分支](https://github.com/alibaba/lowcode-engine/tree/develop/docs)保持同步。 - 点击每篇文档下发的 `编辑此页` 可直接定位到 github 中位置。 - 欢迎 PR,文档 PR 也会作为贡献者贡献,会用于贡献度统计。 -- 文档同步到官方网站由官方人员进行操作,如有需要可以通过 issue 或 贡献者群与相关人员沟通。 +- **文档同步到官方网站由官方人员进行操作**,如有需要可以通过 issue 或 贡献者群与相关人员沟通。 - 为了提供更好的阅读和使用体验,文档中的图片文件会定期转换成可信的 CDN 地址。 ### PR 提交注意事项 diff --git a/docs/docs/participate/index.md b/docs/docs/participate/index.md index 854da7e183..ea87651ffd 100644 --- a/docs/docs/participate/index.md +++ b/docs/docs/participate/index.md @@ -22,9 +22,10 @@ sidebar_position: 0 3. 如果你修复了 bug 或者添加了代码,而这些内容需要测试,请添加测试! 4. 确保通过测试套件(yarn test)。 5. 请签订贡献者许可证协议(Contributor License Agreement)。 + > 如已签署 CLA 仍被提示需要签署,[解决办法](/site/docs/faq/faq021) ### 核心贡献者交流 如果你想长期参与到项目维护中,我们提供了一个核心贡献者交流群。 1. 可以通过[填写问卷](https://survey.taobao.com/apps/zhiliao/4YEtu9gHF)的方式,参与到其中。 -2. 填写问卷后加微信号 `wxidvlalalalal` 说明一下 +2. 填写问卷后加微信号 `wxidvlalalalal` 说明一下。 diff --git a/docs/package.json b/docs/package.json index d0e6685dcb..c32b197944 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.0.6", + "version": "1.0.7", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From f9dcbaf61824df2a1901758d3ef15e6a1b865be5 Mon Sep 17 00:00:00 2001 From: wangwei Date: Tue, 13 Dec 2022 10:31:44 +0800 Subject: [PATCH 235/823] feat: assets.components support reference field (#1355) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: 资产包协议兼容低代码组件物料 --- packages/editor-core/src/editor.ts | 18 +++++----- .../editor-core/src/utils/assets-transform.ts | 26 ++++++++++++++ packages/types/src/assets.ts | 16 +++++++-- packages/types/src/npm.ts | 36 ++++++++++++++++++- packages/types/src/utils.ts | 34 ++++++++++++++++++ 5 files changed, 118 insertions(+), 12 deletions(-) create mode 100644 packages/editor-core/src/utils/assets-transform.ts diff --git a/packages/editor-core/src/editor.ts b/packages/editor-core/src/editor.ts index f3b52c61d3..892cdb719c 100644 --- a/packages/editor-core/src/editor.ts +++ b/packages/editor-core/src/editor.ts @@ -18,6 +18,7 @@ import { globalLocale } from './intl'; import Preference from './utils/preference'; import { obx } from './utils'; import { AssetsJson, AssetLoader } from '@alilc/lowcode-utils'; +import { assetsTransform } from './utils/assets-transform'; EventEmitter.defaultMaxListeners = 100; @@ -124,7 +125,8 @@ export class Editor extends (EventEmitter as any) implements IEditor { ); } } - this.context.set('assets', assets); + const innerAssets = assetsTransform(assets); + this.context.set('assets', innerAssets); this.notifyGot('assets'); } @@ -145,7 +147,7 @@ export class Editor extends (EventEmitter as any) implements IEditor { const x = this.context.get(keyOrType); if (x !== undefined) { fn(x); - return () => {}; + return () => { }; } else { this.setWait(keyOrType, fn); return () => { @@ -169,7 +171,7 @@ export class Editor extends (EventEmitter as any) implements IEditor { const { hooks = [], lifeCycles } = this.config; this.emit('editor.beforeInit'); - const init = (lifeCycles && lifeCycles.init) || ((): void => {}); + const init = (lifeCycles && lifeCycles.init) || ((): void => { }); try { await init(this); @@ -231,11 +233,11 @@ export class Editor extends (EventEmitter as any) implements IEditor { /* eslint-disable */ private waits = new Map< - KeyType, - Array<{ - once?: boolean; - resolve: (data: any) => void; - }> + KeyType, + Array<{ + once?: boolean; + resolve: (data: any) => void; + }> >(); /* eslint-enable */ diff --git a/packages/editor-core/src/utils/assets-transform.ts b/packages/editor-core/src/utils/assets-transform.ts new file mode 100644 index 0000000000..d4e735c03b --- /dev/null +++ b/packages/editor-core/src/utils/assets-transform.ts @@ -0,0 +1,26 @@ +import { AssetsJson, ComponentDescription } from '@alilc/lowcode-types'; + + +export function assetsTransform(assets: AssetsJson) { + const { components, packages } = assets; + const packageMaps = (packages || []).reduce((acc, cur) => { + const key = (cur.id || cur.package) as string; + acc[key] = cur; + return acc; + }, {} as any); + components.forEach((componentDesc) => { + let { devMode, schema, reference } = componentDesc as ComponentDescription; + if ((devMode as string) === 'lowcode') { + devMode = 'lowCode'; + } else if (devMode === 'proCode') { + devMode = 'proCode'; + } + if (devMode) { + (componentDesc as ComponentDescription).devMode = devMode; + } + if (devMode === 'lowCode' && !schema && reference) { + (componentDesc as ComponentDescription).schema = packageMaps[reference.id as string].schema; + } + }); + return assets; +} \ No newline at end of file diff --git a/packages/types/src/assets.ts b/packages/types/src/assets.ts index 581af679b1..588f562305 100644 --- a/packages/types/src/assets.ts +++ b/packages/types/src/assets.ts @@ -1,5 +1,7 @@ import { Snippet, ComponentMetadata } from './metadata'; import { I18nData } from './i18n'; +import { Reference } from './npm'; +import { EitherOr } from './utils'; export interface AssetItem { type: AssetType; @@ -103,11 +105,15 @@ export interface ComponentSort { * 定义组件大包及 external 资源的信息 * 应该被编辑器默认加载 */ -export interface Package { +export type Package = EitherOr<{ /** - * 包名 + * npm 包名 */ package: string; + /** + * 包唯一标识 + */ + id: string; /** * 包版本号 */ @@ -142,7 +148,7 @@ export interface Package { * 组件描述导出名字,可以通过 window[exportName] 获取到组件描述的 Object 内容; */ exportName?: string; -} +}, 'package', 'id'>; /** * 组件分类 @@ -208,6 +214,10 @@ export interface ComponentDescription extends ComponentMetadata { * @todo 待补充文档 @jinchan */ keywords: string[]; + /** + * 替代 npm 字段的升级版本 + */ + reference?: Reference; } /** diff --git a/packages/types/src/npm.ts b/packages/types/src/npm.ts index f805158e52..78de0795b9 100644 --- a/packages/types/src/npm.ts +++ b/packages/types/src/npm.ts @@ -1,4 +1,4 @@ - +import { EitherOr } from './utils'; /** * npm 源引入完整描述对象 */ @@ -33,6 +33,40 @@ export interface NpmInfo { main?: string; } +/** + * 资源引用信息,Npm 的升级版本, + */ +export type Reference = EitherOr<{ + /** + * 引用资源的 id 标识 + */ + id: string; + /** + * 引用资源的包名 + */ + package: string; + /** + * 引用资源的导出对象中的属性值名称 + */ + exportName: string; + /** + * 引用 exportName 上的子对象 + */ + subName: string; + /** + * 引用的资源主入口 + */ + main?: string; + /** + * 是否从引用资源的导出对象中获取属性值 + */ + destructuring?: boolean; + /** + * 资源版本号 + */ + version: string; +}, 'package', 'id'>; + export interface LowCodeComponentType { /** * 研发模式 diff --git a/packages/types/src/utils.ts b/packages/types/src/utils.ts index b8ac406efd..ffe6115085 100644 --- a/packages/types/src/utils.ts +++ b/packages/types/src/utils.ts @@ -15,3 +15,37 @@ export type ExternalUtils = { export type UtilItem = InternalUtils | ExternalUtils; export type UtilsMap = UtilItem[]; + +type FilterOptional = Pick< + T, + Exclude< + { + [K in keyof T]: T extends Record ? K : never; + }[keyof T], + undefined + > +>; + +type FilterNotOptional = Pick< + T, + Exclude< + { + [K in keyof T]: T extends Record ? never : K; + }[keyof T], + undefined + > +>; + +type PartialEither = { [P in Exclude, K>]-?: T[P] } & + { [P in Exclude, K>]?: T[P] } & + { [P in Extract]?: undefined }; + +type Object = { + [name: string]: any; +}; + +export type EitherOr = + ( + PartialEither, L> | + PartialEither, R> + ) & Omit; From 6aa02e612f5cf80c62a6628cf3ff529e95c6e902 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Tue, 13 Dec 2022 14:42:17 +0800 Subject: [PATCH 236/823] chore: delete pnpm-lock.yaml --- .gitignore | 1 + pnpm-lock.yaml | 8997 ------------------------------------------------ 2 files changed, 1 insertion(+), 8997 deletions(-) delete mode 100644 pnpm-lock.yaml diff --git a/.gitignore b/.gitignore index dc6504d08b..05159f0473 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ packages/*/output/ packages/demo/ package-lock.json yarn.lock +pnpm-lock.yaml deploy-space/packages deploy-space/.env diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml deleted file mode 100644 index 467380b120..0000000000 --- a/pnpm-lock.yaml +++ /dev/null @@ -1,8997 +0,0 @@ -lockfileVersion: 5.4 - -overrides: - '@builder/babel-preset-ice': 1.0.1 - -specifiers: - del: ^6.1.1 - execa: ^5.1.1 - f2elint: ^2.0.1 - gulp: ^4.0.2 - husky: ^7.0.4 - lerna: ^4.0.0 - rimraf: ^3.0.2 - typescript: ^4.5.5 - yarn: ^1.22.17 - -devDependencies: - del: 6.1.1 - execa: 5.1.1 - f2elint: 2.2.1_typescript@4.8.4 - gulp: 4.0.2 - husky: 7.0.4 - lerna: 4.0.0 - rimraf: 3.0.2 - typescript: 4.8.4 - yarn: 1.22.19 - -packages: - - /@ampproject/remapping/2.2.0: - resolution: {integrity: sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/gen-mapping': 0.1.1 - '@jridgewell/trace-mapping': 0.3.17 - dev: true - - /@babel/code-frame/7.12.11: - resolution: {integrity: sha512-Zt1yodBx1UcyiePMSkWnU4hPqhwq7hGi2nFL1LeA3EUl+q2LQx16MISgJ0+z7dnmgvP9QtIleuETGOiOH1RcIw==} - dependencies: - '@babel/highlight': 7.18.6 - dev: true - - /@babel/code-frame/7.18.6: - resolution: {integrity: sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/highlight': 7.18.6 - dev: true - - /@babel/compat-data/7.20.0: - resolution: {integrity: sha512-Gt9jszFJYq7qzXVK4slhc6NzJXnOVmRECWcVjF/T23rNXD9NtWQ0W3qxdg+p9wWIB+VQw3GYV/U2Ha9bRTfs4w==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/core/7.19.6: - resolution: {integrity: sha512-D2Ue4KHpc6Ys2+AxpIx1BZ8+UegLLLE2p3KJEuJRKmokHOtl49jQ5ny1773KsGLZs8MQvBidAF6yWUJxRqtKtg==} - engines: {node: '>=6.9.0'} - dependencies: - '@ampproject/remapping': 2.2.0 - '@babel/code-frame': 7.18.6 - '@babel/generator': 7.20.0 - '@babel/helper-compilation-targets': 7.20.0_@babel+core@7.19.6 - '@babel/helper-module-transforms': 7.19.6 - '@babel/helpers': 7.20.0 - '@babel/parser': 7.20.0 - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.0 - '@babel/types': 7.20.0 - convert-source-map: 1.9.0 - debug: 4.3.4 - gensync: 1.0.0-beta.2 - json5: 2.2.1 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/eslint-parser/7.19.1_mgnruehwwwnc5e6kz5xt6nx3ru: - resolution: {integrity: sha512-AqNf2QWt1rtu2/1rLswy6CDP7H9Oh3mMhk177Y67Rg8d7RD9WfOLLv8CGn6tisFvS2htm86yIe1yLF6I1UDaGQ==} - engines: {node: ^10.13.0 || ^12.13.0 || >=14.0.0} - peerDependencies: - '@babel/core': '>=7.11.0' - eslint: ^7.5.0 || ^8.0.0 - dependencies: - '@babel/core': 7.19.6 - '@nicolo-ribaudo/eslint-scope-5-internals': 5.1.1-v1 - eslint: 7.32.0 - eslint-visitor-keys: 2.1.0 - semver: 6.3.0 - dev: true - - /@babel/generator/7.20.0: - resolution: {integrity: sha512-GUPcXxWibClgmYJuIwC2Bc2Lg+8b9VjaJ+HlNdACEVt+Wlr1eoU1OPZjZRm7Hzl0gaTsUZNQfeihvZJhG7oc3w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.0 - '@jridgewell/gen-mapping': 0.3.2 - jsesc: 2.5.2 - dev: true - - /@babel/helper-annotate-as-pure/7.18.6: - resolution: {integrity: sha512-duORpUiYrEpzKIop6iNbjnwKLAKnJ47csTyRACyEmWj0QdUrm5aqNJGHSSEQSUAvNW0ojX0dOmK9dZduvkfeXA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.0 - dev: true - - /@babel/helper-compilation-targets/7.20.0_@babel+core@7.19.6: - resolution: {integrity: sha512-0jp//vDGp9e8hZzBc6N/KwA5ZK3Wsm/pfm4CrY7vzegkVxc65SgSn6wYOnwHe9Js9HRQ1YTCKLGPzDtaS3RoLQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0 - dependencies: - '@babel/compat-data': 7.20.0 - '@babel/core': 7.19.6 - '@babel/helper-validator-option': 7.18.6 - browserslist: 4.21.4 - semver: 6.3.0 - dev: true - - /@babel/helper-environment-visitor/7.18.9: - resolution: {integrity: sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-function-name/7.19.0: - resolution: {integrity: sha512-WAwHBINyrpqywkUH0nTnNgI5ina5TFn85HKS0pbPDfxFfhyR/aNQEn4hGi1P1JyT//I0t4OgXUlofzWILRvS5w==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.18.10 - '@babel/types': 7.20.0 - dev: true - - /@babel/helper-hoist-variables/7.18.6: - resolution: {integrity: sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.0 - dev: true - - /@babel/helper-module-imports/7.18.6: - resolution: {integrity: sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.0 - dev: true - - /@babel/helper-module-transforms/7.19.6: - resolution: {integrity: sha512-fCmcfQo/KYr/VXXDIyd3CBGZ6AFhPFy1TfSEJ+PilGVlQT6jcbqtHAM4C1EciRqMza7/TpOUZliuSH+U6HAhJw==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-module-imports': 7.18.6 - '@babel/helper-simple-access': 7.19.4 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/helper-validator-identifier': 7.19.1 - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.0 - '@babel/types': 7.20.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/helper-plugin-utils/7.19.0: - resolution: {integrity: sha512-40Ryx7I8mT+0gaNxm8JGTZFUITNqdLAgdg0hXzeVZxVD6nFsdhQvip6v8dqkRHzsz1VFpFAaOCHNn0vKBL7Czw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-simple-access/7.19.4: - resolution: {integrity: sha512-f9Xq6WqBFqaDfbCzn2w85hwklswz5qsKlh7f08w4Y9yhJHpnNC0QemtSkK5YyOY8kPGvyiwdzZksGUhnGdaUIg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.0 - dev: true - - /@babel/helper-split-export-declaration/7.18.6: - resolution: {integrity: sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/types': 7.20.0 - dev: true - - /@babel/helper-string-parser/7.19.4: - resolution: {integrity: sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-identifier/7.19.1: - resolution: {integrity: sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helper-validator-option/7.18.6: - resolution: {integrity: sha512-XO7gESt5ouv/LRJdrVjkShckw6STTaB7l9BrpBaAHDeF5YZT+01PCwmR0SJHnkW6i8OwW/EVWRShfi4j2x+KQw==} - engines: {node: '>=6.9.0'} - dev: true - - /@babel/helpers/7.20.0: - resolution: {integrity: sha512-aGMjYraN0zosCEthoGLdqot1oRsmxVTQRHadsUPz5QM44Zej2PYRz7XiDE7GqnkZnNtLbOuxqoZw42vkU7+XEQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/template': 7.18.10 - '@babel/traverse': 7.20.0 - '@babel/types': 7.20.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/highlight/7.18.6: - resolution: {integrity: sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-validator-identifier': 7.19.1 - chalk: 2.4.2 - js-tokens: 4.0.0 - dev: true - - /@babel/parser/7.20.0: - resolution: {integrity: sha512-G9VgAhEaICnz8iiJeGJQyVl6J2nTjbW0xeisva0PK6XcKsga7BIaqm4ZF8Rg1Wbaqmy6znspNqhPaPkyukujzg==} - engines: {node: '>=6.0.0'} - hasBin: true - dependencies: - '@babel/types': 7.20.0 - dev: true - - /@babel/plugin-syntax-jsx/7.18.6_@babel+core@7.19.6: - resolution: {integrity: sha512-6mmljtAedFGTWu2p/8WIORGwy+61PLgOMPOdazc7YoJ9ZCWUyFy3A6CpPkRKLKD1ToAesxX8KGEViAiLo9N+7Q==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-react-display-name/7.18.6_@babel+core@7.19.6: - resolution: {integrity: sha512-TV4sQ+T013n61uMoygyMRm+xf04Bd5oqFpv2jAEQwSZ8NwQA7zeRPg1LMVg2PWi3zWBz+CLKD+v5bcpZ/BS0aA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/plugin-transform-react-jsx-development/7.18.6_@babel+core@7.19.6: - resolution: {integrity: sha512-SA6HEjwYFKF7WDjWcMcMGUimmw/nhNRDWxr+KaLSCrkD/LMDBvWRmHAYgE1HDeF8KUuI8OAu+RT6EOtKxSW2qA==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.6 - dev: true - - /@babel/plugin-transform-react-jsx/7.19.0_@babel+core@7.19.6: - resolution: {integrity: sha512-UVEvX3tXie3Szm3emi1+G63jyw1w5IcMY0FSKM+CRnKRI5Mr1YbCNgsSTwoTwKphQEG9P+QqmuRFneJPZuHNhg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-module-imports': 7.18.6 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/plugin-syntax-jsx': 7.18.6_@babel+core@7.19.6 - '@babel/types': 7.20.0 - dev: true - - /@babel/plugin-transform-react-pure-annotations/7.18.6_@babel+core@7.19.6: - resolution: {integrity: sha512-I8VfEPg9r2TRDdvnHgPepTKvuRomzA8+u+nhY7qSI1fR2hRNebasZEETLyM5mAUr0Ku56OkXJ0I7NHJnO6cJiQ==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-annotate-as-pure': 7.18.6 - '@babel/helper-plugin-utils': 7.19.0 - dev: true - - /@babel/preset-react/7.18.6_@babel+core@7.19.6: - resolution: {integrity: sha512-zXr6atUmyYdiWRVLOZahakYmOBHtWc2WGCkP8PYTgZi0iJXDY2CN180TdrIW4OGOAdLc7TifzDIvtx6izaRIzg==} - engines: {node: '>=6.9.0'} - peerDependencies: - '@babel/core': ^7.0.0-0 - dependencies: - '@babel/core': 7.19.6 - '@babel/helper-plugin-utils': 7.19.0 - '@babel/helper-validator-option': 7.18.6 - '@babel/plugin-transform-react-display-name': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-react-jsx': 7.19.0_@babel+core@7.19.6 - '@babel/plugin-transform-react-jsx-development': 7.18.6_@babel+core@7.19.6 - '@babel/plugin-transform-react-pure-annotations': 7.18.6_@babel+core@7.19.6 - dev: true - - /@babel/runtime-corejs3/7.20.0: - resolution: {integrity: sha512-v1JH7PeAAGBEyTQM9TqojVl+b20zXtesFKCJHu50xMxZKD1fX0TKaKHPsZfFkXfs7D1M9M6Eeqg1FkJ3a0x2dA==} - engines: {node: '>=6.9.0'} - dependencies: - core-js-pure: 3.26.0 - regenerator-runtime: 0.13.10 - dev: true - - /@babel/runtime/7.20.0: - resolution: {integrity: sha512-NDYdls71fTXoU8TZHfbBWg7DiZfNzClcKui/+kyi6ppD2L1qnWW3VV6CjtaBXSUGGhiTWJ6ereOIkUvenif66Q==} - engines: {node: '>=6.9.0'} - dependencies: - regenerator-runtime: 0.13.10 - dev: true - - /@babel/template/7.18.10: - resolution: {integrity: sha512-TI+rCtooWHr3QJ27kJxfjutghu44DLnasDMwpDqCXVTal9RLp3RSYNh4NdBrRP2cQAoG9A8juOQl6P6oZG4JxA==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.18.6 - '@babel/parser': 7.20.0 - '@babel/types': 7.20.0 - dev: true - - /@babel/traverse/7.20.0: - resolution: {integrity: sha512-5+cAXQNARgjRUK0JWu2UBwja4JLSO/rBMPJzpsKb+oBF5xlUuCfljQepS4XypBQoiigL0VQjTZy6WiONtUdScQ==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/code-frame': 7.18.6 - '@babel/generator': 7.20.0 - '@babel/helper-environment-visitor': 7.18.9 - '@babel/helper-function-name': 7.19.0 - '@babel/helper-hoist-variables': 7.18.6 - '@babel/helper-split-export-declaration': 7.18.6 - '@babel/parser': 7.20.0 - '@babel/types': 7.20.0 - debug: 4.3.4 - globals: 11.12.0 - transitivePeerDependencies: - - supports-color - dev: true - - /@babel/types/7.20.0: - resolution: {integrity: sha512-Jlgt3H0TajCW164wkTOTzHkZb075tMQMULzrLUoUeKmO7eFL96GgDxf7/Axhc5CAuKE3KFyVW1p6ysKsi2oXAg==} - engines: {node: '>=6.9.0'} - dependencies: - '@babel/helper-string-parser': 7.19.4 - '@babel/helper-validator-identifier': 7.19.1 - to-fast-properties: 2.0.0 - dev: true - - /@commitlint/cli/11.0.0: - resolution: {integrity: sha512-YWZWg1DuqqO5Zjh7vUOeSX76vm0FFyz4y0cpGMFhrhvUi5unc4IVfCXZ6337R9zxuBtmveiRuuhQqnRRer+13g==} - engines: {node: '>=v10.22.0'} - hasBin: true - dependencies: - '@babel/runtime': 7.20.0 - '@commitlint/format': 11.0.0 - '@commitlint/lint': 11.0.0 - '@commitlint/load': 11.0.0 - '@commitlint/read': 11.0.0 - chalk: 4.1.0 - core-js: 3.26.0 - get-stdin: 8.0.0 - lodash: 4.17.21 - resolve-from: 5.0.0 - resolve-global: 1.0.0 - yargs: 15.4.1 - dev: true - - /@commitlint/ensure/11.0.0: - resolution: {integrity: sha512-/T4tjseSwlirKZdnx4AuICMNNlFvRyPQimbZIOYujp9DSO6XRtOy9NrmvWujwHsq9F5Wb80QWi4WMW6HMaENug==} - engines: {node: '>=v10.22.0'} - dependencies: - '@commitlint/types': 11.0.0 - lodash: 4.17.21 - dev: true - - /@commitlint/execute-rule/11.0.0: - resolution: {integrity: sha512-g01p1g4BmYlZ2+tdotCavrMunnPFPhTzG1ZiLKTCYrooHRbmvqo42ZZn4QMStUEIcn+jfLb6BRZX3JzIwA1ezQ==} - engines: {node: '>=v10.22.0'} - dev: true - - /@commitlint/format/11.0.0: - resolution: {integrity: sha512-bpBLWmG0wfZH/svzqD1hsGTpm79TKJWcf6EXZllh2J/LSSYKxGlv967lpw0hNojme0sZd4a/97R3qA2QHWWSLg==} - engines: {node: '>=v10.22.0'} - dependencies: - '@commitlint/types': 11.0.0 - chalk: 4.1.2 - dev: true - - /@commitlint/is-ignored/11.0.0: - resolution: {integrity: sha512-VLHOUBN+sOlkYC4tGuzE41yNPO2w09sQnOpfS+pSPnBFkNUUHawEuA44PLHtDvQgVuYrMAmSWFQpWabMoP5/Xg==} - engines: {node: '>=v10.22.0'} - dependencies: - '@commitlint/types': 11.0.0 - semver: 7.3.2 - dev: true - - /@commitlint/lint/11.0.0: - resolution: {integrity: sha512-Q8IIqGIHfwKr8ecVZyYh6NtXFmKw4YSEWEr2GJTB/fTZXgaOGtGFZDWOesCZllQ63f1s/oWJYtVv5RAEuwN8BQ==} - engines: {node: '>=v10.22.0'} - dependencies: - '@commitlint/is-ignored': 11.0.0 - '@commitlint/parse': 11.0.0 - '@commitlint/rules': 11.0.0 - '@commitlint/types': 11.0.0 - dev: true - - /@commitlint/load/11.0.0: - resolution: {integrity: sha512-t5ZBrtgvgCwPfxmG811FCp39/o3SJ7L+SNsxFL92OR4WQxPcu6c8taD0CG2lzOHGuRyuMxZ7ps3EbngT2WpiCg==} - engines: {node: '>=v10.22.0'} - dependencies: - '@commitlint/execute-rule': 11.0.0 - '@commitlint/resolve-extends': 11.0.0 - '@commitlint/types': 11.0.0 - chalk: 4.1.0 - cosmiconfig: 7.0.1 - lodash: 4.17.21 - resolve-from: 5.0.0 - dev: true - - /@commitlint/message/11.0.0: - resolution: {integrity: sha512-01ObK/18JL7PEIE3dBRtoMmU6S3ecPYDTQWWhcO+ErA3Ai0KDYqV5VWWEijdcVafNpdeUNrEMigRkxXHQLbyJA==} - engines: {node: '>=v10.22.0'} - dev: true - - /@commitlint/parse/11.0.0: - resolution: {integrity: sha512-DekKQAIYWAXIcyAZ6/PDBJylWJ1BROTfDIzr9PMVxZRxBPc1gW2TG8fLgjZfBP5mc0cuthPkVi91KQQKGri/7A==} - engines: {node: '>=v10.22.0'} - dependencies: - conventional-changelog-angular: 5.0.13 - conventional-commits-parser: 3.2.4 - dev: true - - /@commitlint/read/11.0.0: - resolution: {integrity: sha512-37V0V91GSv0aDzMzJioKpCoZw6l0shk7+tRG8RkW1GfZzUIytdg3XqJmM+IaIYpaop0m6BbZtfq+idzUwJnw7g==} - engines: {node: '>=v10.22.0'} - dependencies: - '@commitlint/top-level': 11.0.0 - fs-extra: 9.1.0 - git-raw-commits: 2.0.11 - dev: true - - /@commitlint/resolve-extends/11.0.0: - resolution: {integrity: sha512-WinU6Uv6L7HDGLqn/To13KM1CWvZ09VHZqryqxXa1OY+EvJkfU734CwnOEeNlSCK7FVLrB4kmodLJtL1dkEpXw==} - engines: {node: '>=v10.22.0'} - dependencies: - import-fresh: 3.3.0 - lodash: 4.17.21 - resolve-from: 5.0.0 - resolve-global: 1.0.0 - dev: true - - /@commitlint/rules/11.0.0: - resolution: {integrity: sha512-2hD9y9Ep5ZfoNxDDPkQadd2jJeocrwC4vJ98I0g8pNYn/W8hS9+/FuNpolREHN8PhmexXbkjrwyQrWbuC0DVaA==} - engines: {node: '>=v10.22.0'} - dependencies: - '@commitlint/ensure': 11.0.0 - '@commitlint/message': 11.0.0 - '@commitlint/to-lines': 11.0.0 - '@commitlint/types': 11.0.0 - dev: true - - /@commitlint/to-lines/11.0.0: - resolution: {integrity: sha512-TIDTB0Y23jlCNubDROUVokbJk6860idYB5cZkLWcRS9tlb6YSoeLn1NLafPlrhhkkkZzTYnlKYzCVrBNVes1iw==} - engines: {node: '>=v10.22.0'} - dev: true - - /@commitlint/top-level/11.0.0: - resolution: {integrity: sha512-O0nFU8o+Ws+py5pfMQIuyxOtfR/kwtr5ybqTvR+C2lUPer2x6lnQU+OnfD7hPM+A+COIUZWx10mYQvkR3MmtAA==} - engines: {node: '>=v10.22.0'} - dependencies: - find-up: 5.0.0 - dev: true - - /@commitlint/types/11.0.0: - resolution: {integrity: sha512-VoNqai1vR5anRF5Tuh/+SWDFk7xi7oMwHrHrbm1BprYXjB2RJsWLhUrStMssDxEl5lW/z3EUdg8RvH/IUBccSQ==} - engines: {node: '>=v10.22.0'} - dev: true - - /@es-joy/jsdoccomment/0.20.1: - resolution: {integrity: sha512-oeJK41dcdqkvdZy/HctKklJNkt/jh+av3PZARrZEl+fs/8HaHeeYoAvEwOV0u5I6bArTF17JEsTZMY359e/nfQ==} - engines: {node: ^12 || ^14 || ^16 || ^17} - dependencies: - comment-parser: 1.3.0 - esquery: 1.4.0 - jsdoc-type-pratt-parser: 2.2.5 - dev: true - - /@eslint/eslintrc/0.4.3: - resolution: {integrity: sha512-J6KFFz5QCYUJq3pf0mjEcCJVERbzv71PUIDczuh9JkwGEzced6CO5ADLHB1rbf/+oPBtoPfMYNOpGDzCANlbXw==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - ajv: 6.12.6 - debug: 4.3.4 - espree: 7.3.1 - globals: 13.17.0 - ignore: 4.0.6 - import-fresh: 3.3.0 - js-yaml: 3.14.1 - minimatch: 3.1.2 - strip-json-comments: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true - - /@gar/promisify/1.1.3: - resolution: {integrity: sha512-k2Ty1JcVojjJFwrg/ThKi2ujJ7XNLYaFGNB/bWT9wGR+oSMJHMa5w+CUq6p/pVrKeNNgA7pCqEcjSnHVoqJQFw==} - dev: true - - /@humanwhocodes/config-array/0.5.0: - resolution: {integrity: sha512-FagtKFz74XrTl7y6HCzQpwDfXP0yhxe9lHLD1UZxjvZIcbyRz8zTFF/yYNfSfzU414eDwZ1SrO0Qvtyf+wFMQg==} - engines: {node: '>=10.10.0'} - dependencies: - '@humanwhocodes/object-schema': 1.2.1 - debug: 4.3.4 - minimatch: 3.1.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@humanwhocodes/object-schema/1.2.1: - resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==} - dev: true - - /@hutson/parse-repository-url/3.0.2: - resolution: {integrity: sha512-H9XAx3hc0BQHY6l+IFSWHDySypcXsvsuLhgYLUGywmJ5pswRVQJUHpOsobnLYp2ZUaUlKiKDrgWWhosOwAEM8Q==} - engines: {node: '>=6.9.0'} - dev: true - - /@jridgewell/gen-mapping/0.1.1: - resolution: {integrity: sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.14 - dev: true - - /@jridgewell/gen-mapping/0.3.2: - resolution: {integrity: sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==} - engines: {node: '>=6.0.0'} - dependencies: - '@jridgewell/set-array': 1.1.2 - '@jridgewell/sourcemap-codec': 1.4.14 - '@jridgewell/trace-mapping': 0.3.17 - dev: true - - /@jridgewell/resolve-uri/3.1.0: - resolution: {integrity: sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/set-array/1.1.2: - resolution: {integrity: sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==} - engines: {node: '>=6.0.0'} - dev: true - - /@jridgewell/sourcemap-codec/1.4.14: - resolution: {integrity: sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==} - dev: true - - /@jridgewell/trace-mapping/0.3.17: - resolution: {integrity: sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==} - dependencies: - '@jridgewell/resolve-uri': 3.1.0 - '@jridgewell/sourcemap-codec': 1.4.14 - dev: true - - /@lerna/add/4.0.0: - resolution: {integrity: sha512-cpmAH1iS3k8JBxNvnMqrGTTjbY/ZAiKa1ChJzFevMYY3eeqbvhsBKnBcxjRXtdrJ6bd3dCQM+ZtK+0i682Fhng==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/bootstrap': 4.0.0 - '@lerna/command': 4.0.0 - '@lerna/filter-options': 4.0.0 - '@lerna/npm-conf': 4.0.0 - '@lerna/validation-error': 4.0.0 - dedent: 0.7.0 - npm-package-arg: 8.1.5 - p-map: 4.0.0 - pacote: 11.3.5 - semver: 7.3.8 - transitivePeerDependencies: - - bluebird - - supports-color - dev: true - - /@lerna/bootstrap/4.0.0: - resolution: {integrity: sha512-RkS7UbeM2vu+kJnHzxNRCLvoOP9yGNgkzRdy4UV2hNalD7EP41bLvRVOwRYQ7fhc2QcbhnKNdOBihYRL0LcKtw==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/command': 4.0.0 - '@lerna/filter-options': 4.0.0 - '@lerna/has-npm-version': 4.0.0 - '@lerna/npm-install': 4.0.0 - '@lerna/package-graph': 4.0.0 - '@lerna/pulse-till-done': 4.0.0 - '@lerna/rimraf-dir': 4.0.0 - '@lerna/run-lifecycle': 4.0.0 - '@lerna/run-topologically': 4.0.0 - '@lerna/symlink-binary': 4.0.0 - '@lerna/symlink-dependencies': 4.0.0 - '@lerna/validation-error': 4.0.0 - dedent: 0.7.0 - get-port: 5.1.1 - multimatch: 5.0.0 - npm-package-arg: 8.1.5 - npmlog: 4.1.2 - p-map: 4.0.0 - p-map-series: 2.1.0 - p-waterfall: 2.1.1 - read-package-tree: 5.3.1 - semver: 7.3.8 - dev: true - - /@lerna/changed/4.0.0: - resolution: {integrity: sha512-cD+KuPRp6qiPOD+BO6S6SN5cARspIaWSOqGBpGnYzLb4uWT8Vk4JzKyYtc8ym1DIwyoFXHosXt8+GDAgR8QrgQ==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/collect-updates': 4.0.0 - '@lerna/command': 4.0.0 - '@lerna/listable': 4.0.0 - '@lerna/output': 4.0.0 - dev: true - - /@lerna/check-working-tree/4.0.0: - resolution: {integrity: sha512-/++bxM43jYJCshBiKP5cRlCTwSJdRSxVmcDAXM+1oUewlZJVSVlnks5eO0uLxokVFvLhHlC5kHMc7gbVFPHv6Q==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/collect-uncommitted': 4.0.0 - '@lerna/describe-ref': 4.0.0 - '@lerna/validation-error': 4.0.0 - dev: true - - /@lerna/child-process/4.0.0: - resolution: {integrity: sha512-XtCnmCT9eyVsUUHx6y/CTBYdV9g2Cr/VxyseTWBgfIur92/YKClfEtJTbOh94jRT62hlKLqSvux/UhxXVh613Q==} - engines: {node: '>= 10.18.0'} - dependencies: - chalk: 4.1.2 - execa: 5.1.1 - strong-log-transformer: 2.1.0 - dev: true - - /@lerna/clean/4.0.0: - resolution: {integrity: sha512-uugG2iN9k45ITx2jtd8nEOoAtca8hNlDCUM0N3lFgU/b1mEQYAPRkqr1qs4FLRl/Y50ZJ41wUz1eazS+d/0osA==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/command': 4.0.0 - '@lerna/filter-options': 4.0.0 - '@lerna/prompt': 4.0.0 - '@lerna/pulse-till-done': 4.0.0 - '@lerna/rimraf-dir': 4.0.0 - p-map: 4.0.0 - p-map-series: 2.1.0 - p-waterfall: 2.1.1 - dev: true - - /@lerna/cli/4.0.0: - resolution: {integrity: sha512-Neaw3GzFrwZiRZv2g7g6NwFjs3er1vhraIniEs0jjVLPMNC4eata0na3GfE5yibkM/9d3gZdmihhZdZ3EBdvYA==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/global-options': 4.0.0 - dedent: 0.7.0 - npmlog: 4.1.2 - yargs: 16.2.0 - dev: true - - /@lerna/collect-uncommitted/4.0.0: - resolution: {integrity: sha512-ufSTfHZzbx69YNj7KXQ3o66V4RC76ffOjwLX0q/ab//61bObJ41n03SiQEhSlmpP+gmFbTJ3/7pTe04AHX9m/g==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/child-process': 4.0.0 - chalk: 4.1.2 - npmlog: 4.1.2 - dev: true - - /@lerna/collect-updates/4.0.0: - resolution: {integrity: sha512-bnNGpaj4zuxsEkyaCZLka9s7nMs58uZoxrRIPJ+nrmrZYp1V5rrd+7/NYTuunOhY2ug1sTBvTAxj3NZQ+JKnOw==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/child-process': 4.0.0 - '@lerna/describe-ref': 4.0.0 - minimatch: 3.1.2 - npmlog: 4.1.2 - slash: 3.0.0 - dev: true - - /@lerna/command/4.0.0: - resolution: {integrity: sha512-LM9g3rt5FsPNFqIHUeRwWXLNHJ5NKzOwmVKZ8anSp4e1SPrv2HNc1V02/9QyDDZK/w+5POXH5lxZUI1CHaOK/A==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/child-process': 4.0.0 - '@lerna/package-graph': 4.0.0 - '@lerna/project': 4.0.0 - '@lerna/validation-error': 4.0.0 - '@lerna/write-log-file': 4.0.0 - clone-deep: 4.0.1 - dedent: 0.7.0 - execa: 5.1.1 - is-ci: 2.0.0 - npmlog: 4.1.2 - dev: true - - /@lerna/conventional-commits/4.0.0: - resolution: {integrity: sha512-CSUQRjJHFrH8eBn7+wegZLV3OrNc0Y1FehYfYGhjLE2SIfpCL4bmfu/ViYuHh9YjwHaA+4SX6d3hR+xkeseKmw==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/validation-error': 4.0.0 - conventional-changelog-angular: 5.0.13 - conventional-changelog-core: 4.2.4 - conventional-recommended-bump: 6.1.0 - fs-extra: 9.1.0 - get-stream: 6.0.1 - lodash.template: 4.5.0 - npm-package-arg: 8.1.5 - npmlog: 4.1.2 - pify: 5.0.0 - semver: 7.3.8 - dev: true - - /@lerna/create-symlink/4.0.0: - resolution: {integrity: sha512-I0phtKJJdafUiDwm7BBlEUOtogmu8+taxq6PtIrxZbllV9hWg59qkpuIsiFp+no7nfRVuaasNYHwNUhDAVQBig==} - engines: {node: '>= 10.18.0'} - dependencies: - cmd-shim: 4.1.0 - fs-extra: 9.1.0 - npmlog: 4.1.2 - dev: true - - /@lerna/create/4.0.0: - resolution: {integrity: sha512-mVOB1niKByEUfxlbKTM1UNECWAjwUdiioIbRQZEeEabtjCL69r9rscIsjlGyhGWCfsdAG5wfq4t47nlDXdLLag==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/child-process': 4.0.0 - '@lerna/command': 4.0.0 - '@lerna/npm-conf': 4.0.0 - '@lerna/validation-error': 4.0.0 - dedent: 0.7.0 - fs-extra: 9.1.0 - globby: 11.1.0 - init-package-json: 2.0.5 - npm-package-arg: 8.1.5 - p-reduce: 2.1.0 - pacote: 11.3.5 - pify: 5.0.0 - semver: 7.3.8 - slash: 3.0.0 - validate-npm-package-license: 3.0.4 - validate-npm-package-name: 3.0.0 - whatwg-url: 8.7.0 - yargs-parser: 20.2.4 - transitivePeerDependencies: - - bluebird - - supports-color - dev: true - - /@lerna/describe-ref/4.0.0: - resolution: {integrity: sha512-eTU5+xC4C5Gcgz+Ey4Qiw9nV2B4JJbMulsYJMW8QjGcGh8zudib7Sduj6urgZXUYNyhYpRs+teci9M2J8u+UvQ==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/child-process': 4.0.0 - npmlog: 4.1.2 - dev: true - - /@lerna/diff/4.0.0: - resolution: {integrity: sha512-jYPKprQVg41+MUMxx6cwtqsNm0Yxx9GDEwdiPLwcUTFx+/qKCEwifKNJ1oGIPBxyEHX2PFCOjkK39lHoj2qiag==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/child-process': 4.0.0 - '@lerna/command': 4.0.0 - '@lerna/validation-error': 4.0.0 - npmlog: 4.1.2 - dev: true - - /@lerna/exec/4.0.0: - resolution: {integrity: sha512-VGXtL/b/JfY84NB98VWZpIExfhLOzy0ozm/0XaS4a2SmkAJc5CeUfrhvHxxkxiTBLkU+iVQUyYEoAT0ulQ8PCw==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/child-process': 4.0.0 - '@lerna/command': 4.0.0 - '@lerna/filter-options': 4.0.0 - '@lerna/profiler': 4.0.0 - '@lerna/run-topologically': 4.0.0 - '@lerna/validation-error': 4.0.0 - p-map: 4.0.0 - dev: true - - /@lerna/filter-options/4.0.0: - resolution: {integrity: sha512-vV2ANOeZhOqM0rzXnYcFFCJ/kBWy/3OA58irXih9AMTAlQLymWAK0akWybl++sUJ4HB9Hx12TOqaXbYS2NM5uw==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/collect-updates': 4.0.0 - '@lerna/filter-packages': 4.0.0 - dedent: 0.7.0 - npmlog: 4.1.2 - dev: true - - /@lerna/filter-packages/4.0.0: - resolution: {integrity: sha512-+4AJIkK7iIiOaqCiVTYJxh/I9qikk4XjNQLhE3kixaqgMuHl1NQ99qXRR0OZqAWB9mh8Z1HA9bM5K1HZLBTOqA==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/validation-error': 4.0.0 - multimatch: 5.0.0 - npmlog: 4.1.2 - dev: true - - /@lerna/get-npm-exec-opts/4.0.0: - resolution: {integrity: sha512-yvmkerU31CTWS2c7DvmAWmZVeclPBqI7gPVr5VATUKNWJ/zmVcU4PqbYoLu92I9Qc4gY1TuUplMNdNuZTSL7IQ==} - engines: {node: '>= 10.18.0'} - dependencies: - npmlog: 4.1.2 - dev: true - - /@lerna/get-packed/4.0.0: - resolution: {integrity: sha512-rfWONRsEIGyPJTxFzC8ECb3ZbsDXJbfqWYyeeQQDrJRPnEJErlltRLPLgC2QWbxFgFPsoDLeQmFHJnf0iDfd8w==} - engines: {node: '>= 10.18.0'} - dependencies: - fs-extra: 9.1.0 - ssri: 8.0.1 - tar: 6.1.11 - dev: true - - /@lerna/github-client/4.0.0: - resolution: {integrity: sha512-2jhsldZtTKXYUBnOm23Lb0Fx8G4qfSXF9y7UpyUgWUj+YZYd+cFxSuorwQIgk5P4XXrtVhsUesIsli+BYSThiw==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/child-process': 4.0.0 - '@octokit/plugin-enterprise-rest': 6.0.1 - '@octokit/rest': 18.12.0 - git-url-parse: 11.6.0 - npmlog: 4.1.2 - transitivePeerDependencies: - - encoding - dev: true - - /@lerna/gitlab-client/4.0.0: - resolution: {integrity: sha512-OMUpGSkeDWFf7BxGHlkbb35T7YHqVFCwBPSIR6wRsszY8PAzCYahtH3IaJzEJyUg6vmZsNl0FSr3pdA2skhxqA==} - engines: {node: '>= 10.18.0'} - dependencies: - node-fetch: 2.6.7 - npmlog: 4.1.2 - whatwg-url: 8.7.0 - transitivePeerDependencies: - - encoding - dev: true - - /@lerna/global-options/4.0.0: - resolution: {integrity: sha512-TRMR8afAHxuYBHK7F++Ogop2a82xQjoGna1dvPOY6ltj/pEx59pdgcJfYcynYqMkFIk8bhLJJN9/ndIfX29FTQ==} - engines: {node: '>= 10.18.0'} - dev: true - - /@lerna/has-npm-version/4.0.0: - resolution: {integrity: sha512-LQ3U6XFH8ZmLCsvsgq1zNDqka0Xzjq5ibVN+igAI5ccRWNaUsE/OcmsyMr50xAtNQMYMzmpw5GVLAivT2/YzCg==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/child-process': 4.0.0 - semver: 7.3.8 - dev: true - - /@lerna/import/4.0.0: - resolution: {integrity: sha512-FaIhd+4aiBousKNqC7TX1Uhe97eNKf5/SC7c5WZANVWtC7aBWdmswwDt3usrzCNpj6/Wwr9EtEbYROzxKH8ffg==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/child-process': 4.0.0 - '@lerna/command': 4.0.0 - '@lerna/prompt': 4.0.0 - '@lerna/pulse-till-done': 4.0.0 - '@lerna/validation-error': 4.0.0 - dedent: 0.7.0 - fs-extra: 9.1.0 - p-map-series: 2.1.0 - dev: true - - /@lerna/info/4.0.0: - resolution: {integrity: sha512-8Uboa12kaCSZEn4XRfPz5KU9XXoexSPS4oeYGj76s2UQb1O1GdnEyfjyNWoUl1KlJ2i/8nxUskpXIftoFYH0/Q==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/command': 4.0.0 - '@lerna/output': 4.0.0 - envinfo: 7.8.1 - dev: true - - /@lerna/init/4.0.0: - resolution: {integrity: sha512-wY6kygop0BCXupzWj5eLvTUqdR7vIAm0OgyV9WHpMYQGfs1V22jhztt8mtjCloD/O0nEe4tJhdG62XU5aYmPNQ==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/child-process': 4.0.0 - '@lerna/command': 4.0.0 - fs-extra: 9.1.0 - p-map: 4.0.0 - write-json-file: 4.3.0 - dev: true - - /@lerna/link/4.0.0: - resolution: {integrity: sha512-KlvPi7XTAcVOByfaLlOeYOfkkDcd+bejpHMCd1KcArcFTwijOwXOVi24DYomIeHvy6HsX/IUquJ4PPUJIeB4+w==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/command': 4.0.0 - '@lerna/package-graph': 4.0.0 - '@lerna/symlink-dependencies': 4.0.0 - p-map: 4.0.0 - slash: 3.0.0 - dev: true - - /@lerna/list/4.0.0: - resolution: {integrity: sha512-L2B5m3P+U4Bif5PultR4TI+KtW+SArwq1i75QZ78mRYxPc0U/piau1DbLOmwrdqr99wzM49t0Dlvl6twd7GHFg==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/command': 4.0.0 - '@lerna/filter-options': 4.0.0 - '@lerna/listable': 4.0.0 - '@lerna/output': 4.0.0 - dev: true - - /@lerna/listable/4.0.0: - resolution: {integrity: sha512-/rPOSDKsOHs5/PBLINZOkRIX1joOXUXEtyUs5DHLM8q6/RP668x/1lFhw6Dx7/U+L0+tbkpGtZ1Yt0LewCLgeQ==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/query-graph': 4.0.0 - chalk: 4.1.2 - columnify: 1.6.0 - dev: true - - /@lerna/log-packed/4.0.0: - resolution: {integrity: sha512-+dpCiWbdzgMAtpajLToy9PO713IHoE6GV/aizXycAyA07QlqnkpaBNZ8DW84gHdM1j79TWockGJo9PybVhrrZQ==} - engines: {node: '>= 10.18.0'} - dependencies: - byte-size: 7.0.1 - columnify: 1.6.0 - has-unicode: 2.0.1 - npmlog: 4.1.2 - dev: true - - /@lerna/npm-conf/4.0.0: - resolution: {integrity: sha512-uS7H02yQNq3oejgjxAxqq/jhwGEE0W0ntr8vM3EfpCW1F/wZruwQw+7bleJQ9vUBjmdXST//tk8mXzr5+JXCfw==} - engines: {node: '>= 10.18.0'} - dependencies: - config-chain: 1.1.13 - pify: 5.0.0 - dev: true - - /@lerna/npm-dist-tag/4.0.0: - resolution: {integrity: sha512-F20sg28FMYTgXqEQihgoqSfwmq+Id3zT23CnOwD+XQMPSy9IzyLf1fFVH319vXIw6NF6Pgs4JZN2Qty6/CQXGw==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/otplease': 4.0.0 - npm-package-arg: 8.1.5 - npm-registry-fetch: 9.0.0 - npmlog: 4.1.2 - transitivePeerDependencies: - - bluebird - - supports-color - dev: true - - /@lerna/npm-install/4.0.0: - resolution: {integrity: sha512-aKNxq2j3bCH3eXl3Fmu4D54s/YLL9WSwV8W7X2O25r98wzrO38AUN6AB9EtmAx+LV/SP15et7Yueg9vSaanRWg==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/child-process': 4.0.0 - '@lerna/get-npm-exec-opts': 4.0.0 - fs-extra: 9.1.0 - npm-package-arg: 8.1.5 - npmlog: 4.1.2 - signal-exit: 3.0.7 - write-pkg: 4.0.0 - dev: true - - /@lerna/npm-publish/4.0.0: - resolution: {integrity: sha512-vQb7yAPRo5G5r77DRjHITc9piR9gvEKWrmfCH7wkfBnGWEqu7n8/4bFQ7lhnkujvc8RXOsYpvbMQkNfkYibD/w==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/otplease': 4.0.0 - '@lerna/run-lifecycle': 4.0.0 - fs-extra: 9.1.0 - libnpmpublish: 4.0.2 - npm-package-arg: 8.1.5 - npmlog: 4.1.2 - pify: 5.0.0 - read-package-json: 3.0.1 - transitivePeerDependencies: - - bluebird - - supports-color - dev: true - - /@lerna/npm-run-script/4.0.0: - resolution: {integrity: sha512-Jmyh9/IwXJjOXqKfIgtxi0bxi1pUeKe5bD3S81tkcy+kyng/GNj9WSqD5ZggoNP2NP//s4CLDAtUYLdP7CU9rA==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/child-process': 4.0.0 - '@lerna/get-npm-exec-opts': 4.0.0 - npmlog: 4.1.2 - dev: true - - /@lerna/otplease/4.0.0: - resolution: {integrity: sha512-Sgzbqdk1GH4psNiT6hk+BhjOfIr/5KhGBk86CEfHNJTk9BK4aZYyJD4lpDbDdMjIV4g03G7pYoqHzH765T4fxw==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/prompt': 4.0.0 - dev: true - - /@lerna/output/4.0.0: - resolution: {integrity: sha512-Un1sHtO1AD7buDQrpnaYTi2EG6sLF+KOPEAMxeUYG5qG3khTs2Zgzq5WE3dt2N/bKh7naESt20JjIW6tBELP0w==} - engines: {node: '>= 10.18.0'} - dependencies: - npmlog: 4.1.2 - dev: true - - /@lerna/pack-directory/4.0.0: - resolution: {integrity: sha512-NJrmZNmBHS+5aM+T8N6FVbaKFScVqKlQFJNY2k7nsJ/uklNKsLLl6VhTQBPwMTbf6Tf7l6bcKzpy7aePuq9UiQ==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/get-packed': 4.0.0 - '@lerna/package': 4.0.0 - '@lerna/run-lifecycle': 4.0.0 - npm-packlist: 2.2.2 - npmlog: 4.1.2 - tar: 6.1.11 - temp-write: 4.0.0 - dev: true - - /@lerna/package-graph/4.0.0: - resolution: {integrity: sha512-QED2ZCTkfXMKFoTGoccwUzjHtZMSf3UKX14A4/kYyBms9xfFsesCZ6SLI5YeySEgcul8iuIWfQFZqRw+Qrjraw==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/prerelease-id-from-version': 4.0.0 - '@lerna/validation-error': 4.0.0 - npm-package-arg: 8.1.5 - npmlog: 4.1.2 - semver: 7.3.8 - dev: true - - /@lerna/package/4.0.0: - resolution: {integrity: sha512-l0M/izok6FlyyitxiQKr+gZLVFnvxRQdNhzmQ6nRnN9dvBJWn+IxxpM+cLqGACatTnyo9LDzNTOj2Db3+s0s8Q==} - engines: {node: '>= 10.18.0'} - dependencies: - load-json-file: 6.2.0 - npm-package-arg: 8.1.5 - write-pkg: 4.0.0 - dev: true - - /@lerna/prerelease-id-from-version/4.0.0: - resolution: {integrity: sha512-GQqguzETdsYRxOSmdFZ6zDBXDErIETWOqomLERRY54f4p+tk4aJjoVdd9xKwehC9TBfIFvlRbL1V9uQGHh1opg==} - engines: {node: '>= 10.18.0'} - dependencies: - semver: 7.3.8 - dev: true - - /@lerna/profiler/4.0.0: - resolution: {integrity: sha512-/BaEbqnVh1LgW/+qz8wCuI+obzi5/vRE8nlhjPzdEzdmWmZXuCKyWSEzAyHOJWw1ntwMiww5dZHhFQABuoFz9Q==} - engines: {node: '>= 10.18.0'} - dependencies: - fs-extra: 9.1.0 - npmlog: 4.1.2 - upath: 2.0.1 - dev: true - - /@lerna/project/4.0.0: - resolution: {integrity: sha512-o0MlVbDkD5qRPkFKlBZsXZjoNTWPyuL58564nSfZJ6JYNmgAptnWPB2dQlAc7HWRZkmnC2fCkEdoU+jioPavbg==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/package': 4.0.0 - '@lerna/validation-error': 4.0.0 - cosmiconfig: 7.0.1 - dedent: 0.7.0 - dot-prop: 6.0.1 - glob-parent: 5.1.2 - globby: 11.1.0 - load-json-file: 6.2.0 - npmlog: 4.1.2 - p-map: 4.0.0 - resolve-from: 5.0.0 - write-json-file: 4.3.0 - dev: true - - /@lerna/prompt/4.0.0: - resolution: {integrity: sha512-4Ig46oCH1TH5M7YyTt53fT6TuaKMgqUUaqdgxvp6HP6jtdak6+amcsqB8YGz2eQnw/sdxunx84DfI9XpoLj4bQ==} - engines: {node: '>= 10.18.0'} - dependencies: - inquirer: 7.3.3 - npmlog: 4.1.2 - dev: true - - /@lerna/publish/4.0.0: - resolution: {integrity: sha512-K8jpqjHrChH22qtkytA5GRKIVFEtqBF6JWj1I8dWZtHs4Jywn8yB1jQ3BAMLhqmDJjWJtRck0KXhQQKzDK2UPg==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/check-working-tree': 4.0.0 - '@lerna/child-process': 4.0.0 - '@lerna/collect-updates': 4.0.0 - '@lerna/command': 4.0.0 - '@lerna/describe-ref': 4.0.0 - '@lerna/log-packed': 4.0.0 - '@lerna/npm-conf': 4.0.0 - '@lerna/npm-dist-tag': 4.0.0 - '@lerna/npm-publish': 4.0.0 - '@lerna/otplease': 4.0.0 - '@lerna/output': 4.0.0 - '@lerna/pack-directory': 4.0.0 - '@lerna/prerelease-id-from-version': 4.0.0 - '@lerna/prompt': 4.0.0 - '@lerna/pulse-till-done': 4.0.0 - '@lerna/run-lifecycle': 4.0.0 - '@lerna/run-topologically': 4.0.0 - '@lerna/validation-error': 4.0.0 - '@lerna/version': 4.0.0 - fs-extra: 9.1.0 - libnpmaccess: 4.0.3 - npm-package-arg: 8.1.5 - npm-registry-fetch: 9.0.0 - npmlog: 4.1.2 - p-map: 4.0.0 - p-pipe: 3.1.0 - pacote: 11.3.5 - semver: 7.3.8 - transitivePeerDependencies: - - bluebird - - encoding - - supports-color - dev: true - - /@lerna/pulse-till-done/4.0.0: - resolution: {integrity: sha512-Frb4F7QGckaybRhbF7aosLsJ5e9WuH7h0KUkjlzSByVycxY91UZgaEIVjS2oN9wQLrheLMHl6SiFY0/Pvo0Cxg==} - engines: {node: '>= 10.18.0'} - dependencies: - npmlog: 4.1.2 - dev: true - - /@lerna/query-graph/4.0.0: - resolution: {integrity: sha512-YlP6yI3tM4WbBmL9GCmNDoeQyzcyg1e4W96y/PKMZa5GbyUvkS2+Jc2kwPD+5KcXou3wQZxSPzR3Te5OenaDdg==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/package-graph': 4.0.0 - dev: true - - /@lerna/resolve-symlink/4.0.0: - resolution: {integrity: sha512-RtX8VEUzqT+uLSCohx8zgmjc6zjyRlh6i/helxtZTMmc4+6O4FS9q5LJas2uGO2wKvBlhcD6siibGt7dIC3xZA==} - engines: {node: '>= 10.18.0'} - dependencies: - fs-extra: 9.1.0 - npmlog: 4.1.2 - read-cmd-shim: 2.0.0 - dev: true - - /@lerna/rimraf-dir/4.0.0: - resolution: {integrity: sha512-QNH9ABWk9mcMJh2/muD9iYWBk1oQd40y6oH+f3wwmVGKYU5YJD//+zMiBI13jxZRtwBx0vmBZzkBkK1dR11cBg==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/child-process': 4.0.0 - npmlog: 4.1.2 - path-exists: 4.0.0 - rimraf: 3.0.2 - dev: true - - /@lerna/run-lifecycle/4.0.0: - resolution: {integrity: sha512-IwxxsajjCQQEJAeAaxF8QdEixfI7eLKNm4GHhXHrgBu185JcwScFZrj9Bs+PFKxwb+gNLR4iI5rpUdY8Y0UdGQ==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/npm-conf': 4.0.0 - npm-lifecycle: 3.1.5 - npmlog: 4.1.2 - dev: true - - /@lerna/run-topologically/4.0.0: - resolution: {integrity: sha512-EVZw9hGwo+5yp+VL94+NXRYisqgAlj0jWKWtAIynDCpghRxCE5GMO3xrQLmQgqkpUl9ZxQFpICgYv5DW4DksQA==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/query-graph': 4.0.0 - p-queue: 6.6.2 - dev: true - - /@lerna/run/4.0.0: - resolution: {integrity: sha512-9giulCOzlMPzcZS/6Eov6pxE9gNTyaXk0Man+iCIdGJNMrCnW7Dme0Z229WWP/UoxDKg71F2tMsVVGDiRd8fFQ==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/command': 4.0.0 - '@lerna/filter-options': 4.0.0 - '@lerna/npm-run-script': 4.0.0 - '@lerna/output': 4.0.0 - '@lerna/profiler': 4.0.0 - '@lerna/run-topologically': 4.0.0 - '@lerna/timer': 4.0.0 - '@lerna/validation-error': 4.0.0 - p-map: 4.0.0 - dev: true - - /@lerna/symlink-binary/4.0.0: - resolution: {integrity: sha512-zualodWC4q1QQc1pkz969hcFeWXOsVYZC5AWVtAPTDfLl+TwM7eG/O6oP+Rr3fFowspxo6b1TQ6sYfDV6HXNWA==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/create-symlink': 4.0.0 - '@lerna/package': 4.0.0 - fs-extra: 9.1.0 - p-map: 4.0.0 - dev: true - - /@lerna/symlink-dependencies/4.0.0: - resolution: {integrity: sha512-BABo0MjeUHNAe2FNGty1eantWp8u83BHSeIMPDxNq0MuW2K3CiQRaeWT3EGPAzXpGt0+hVzBrA6+OT0GPn7Yuw==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/create-symlink': 4.0.0 - '@lerna/resolve-symlink': 4.0.0 - '@lerna/symlink-binary': 4.0.0 - fs-extra: 9.1.0 - p-map: 4.0.0 - p-map-series: 2.1.0 - dev: true - - /@lerna/timer/4.0.0: - resolution: {integrity: sha512-WFsnlaE7SdOvjuyd05oKt8Leg3ENHICnvX3uYKKdByA+S3g+TCz38JsNs7OUZVt+ba63nC2nbXDlUnuT2Xbsfg==} - engines: {node: '>= 10.18.0'} - dev: true - - /@lerna/validation-error/4.0.0: - resolution: {integrity: sha512-1rBOM5/koiVWlRi3V6dB863E1YzJS8v41UtsHgMr6gB2ncJ2LsQtMKlJpi3voqcgh41H8UsPXR58RrrpPpufyw==} - engines: {node: '>= 10.18.0'} - dependencies: - npmlog: 4.1.2 - dev: true - - /@lerna/version/4.0.0: - resolution: {integrity: sha512-otUgiqs5W9zGWJZSCCMRV/2Zm2A9q9JwSDS7s/tlKq4mWCYriWo7+wsHEA/nPTMDyYyBO5oyZDj+3X50KDUzeA==} - engines: {node: '>= 10.18.0'} - dependencies: - '@lerna/check-working-tree': 4.0.0 - '@lerna/child-process': 4.0.0 - '@lerna/collect-updates': 4.0.0 - '@lerna/command': 4.0.0 - '@lerna/conventional-commits': 4.0.0 - '@lerna/github-client': 4.0.0 - '@lerna/gitlab-client': 4.0.0 - '@lerna/output': 4.0.0 - '@lerna/prerelease-id-from-version': 4.0.0 - '@lerna/prompt': 4.0.0 - '@lerna/run-lifecycle': 4.0.0 - '@lerna/run-topologically': 4.0.0 - '@lerna/validation-error': 4.0.0 - chalk: 4.1.2 - dedent: 0.7.0 - load-json-file: 6.2.0 - minimatch: 3.1.2 - npmlog: 4.1.2 - p-map: 4.0.0 - p-pipe: 3.1.0 - p-reduce: 2.1.0 - p-waterfall: 2.1.1 - semver: 7.3.8 - slash: 3.0.0 - temp-write: 4.0.0 - write-json-file: 4.3.0 - transitivePeerDependencies: - - encoding - dev: true - - /@lerna/write-log-file/4.0.0: - resolution: {integrity: sha512-XRG5BloiArpXRakcnPHmEHJp+4AtnhRtpDIHSghmXD5EichI1uD73J7FgPp30mm2pDRq3FdqB0NbwSEsJ9xFQg==} - engines: {node: '>= 10.18.0'} - dependencies: - npmlog: 4.1.2 - write-file-atomic: 3.0.3 - dev: true - - /@nicolo-ribaudo/eslint-scope-5-internals/5.1.1-v1: - resolution: {integrity: sha512-54/JRvkLIzzDWshCWfuhadfrfZVPiElY8Fcgmg1HroEly/EDSszzhBAsarCux+D/kOslTRquNzuyGSmUSTTHGg==} - dependencies: - eslint-scope: 5.1.1 - dev: true - - /@nodelib/fs.scandir/2.1.5: - resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - run-parallel: 1.2.0 - dev: true - - /@nodelib/fs.stat/2.0.5: - resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==} - engines: {node: '>= 8'} - dev: true - - /@nodelib/fs.walk/1.2.8: - resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==} - engines: {node: '>= 8'} - dependencies: - '@nodelib/fs.scandir': 2.1.5 - fastq: 1.13.0 - dev: true - - /@npmcli/ci-detect/1.4.0: - resolution: {integrity: sha512-3BGrt6FLjqM6br5AhWRKTr3u5GIVkjRYeAFrMp3HjnfICrg4xOrVRwFavKT6tsp++bq5dluL5t8ME/Nha/6c1Q==} - dev: true - - /@npmcli/fs/1.1.1: - resolution: {integrity: sha512-8KG5RD0GVP4ydEzRn/I4BNDuxDtqVbOdm8675T49OIG/NGhaK0pjPX7ZcDlvKYbA+ulvVK3ztfcF4uBdOxuJbQ==} - dependencies: - '@gar/promisify': 1.1.3 - semver: 7.3.8 - dev: true - - /@npmcli/git/2.1.0: - resolution: {integrity: sha512-/hBFX/QG1b+N7PZBFs0bi+evgRZcK9nWBxQKZkGoXUT5hJSwl5c4d7y8/hm+NQZRPhQ67RzFaj5UM9YeyKoryw==} - dependencies: - '@npmcli/promise-spawn': 1.3.2 - lru-cache: 6.0.0 - mkdirp: 1.0.4 - npm-pick-manifest: 6.1.1 - promise-inflight: 1.0.1 - promise-retry: 2.0.1 - semver: 7.3.8 - which: 2.0.2 - transitivePeerDependencies: - - bluebird - dev: true - - /@npmcli/installed-package-contents/1.0.7: - resolution: {integrity: sha512-9rufe0wnJusCQoLpV9ZPKIVP55itrM5BxOXs10DmdbRfgWtHy1LDyskbwRnBghuB0PrF7pNPOqREVtpz4HqzKw==} - engines: {node: '>= 10'} - hasBin: true - dependencies: - npm-bundled: 1.1.2 - npm-normalize-package-bin: 1.0.1 - dev: true - - /@npmcli/move-file/1.1.2: - resolution: {integrity: sha512-1SUf/Cg2GzGDyaf15aR9St9TWlb+XvbZXWpDx8YKs7MLzMH/BCeopv+y9vzrzgkfykCGuWOlSu3mZhj2+FQcrg==} - engines: {node: '>=10'} - dependencies: - mkdirp: 1.0.4 - rimraf: 3.0.2 - dev: true - - /@npmcli/node-gyp/1.0.3: - resolution: {integrity: sha512-fnkhw+fmX65kiLqk6E3BFLXNC26rUhK90zVwe2yncPliVT/Qos3xjhTLE59Df8KnPlcwIERXKVlU1bXoUQ+liA==} - dev: true - - /@npmcli/promise-spawn/1.3.2: - resolution: {integrity: sha512-QyAGYo/Fbj4MXeGdJcFzZ+FkDkomfRBrPM+9QYJSg+PxgAUL+LU3FneQk37rKR2/zjqkCV1BLHccX98wRXG3Sg==} - dependencies: - infer-owner: 1.0.4 - dev: true - - /@npmcli/run-script/1.8.6: - resolution: {integrity: sha512-e42bVZnC6VluBZBAFEr3YrdqSspG3bgilyg4nSLBJ7TRGNCzxHa92XAHxQBLYg0BmgwO4b2mf3h/l5EkEWRn3g==} - dependencies: - '@npmcli/node-gyp': 1.0.3 - '@npmcli/promise-spawn': 1.3.2 - node-gyp: 7.1.2 - read-package-json-fast: 2.0.3 - dev: true - - /@octokit/auth-token/2.5.0: - resolution: {integrity: sha512-r5FVUJCOLl19AxiuZD2VRZ/ORjp/4IN98Of6YJoJOkY75CIBuYfmiNHGrDwXr+aLGG55igl9QrxX3hbiXlLb+g==} - dependencies: - '@octokit/types': 6.41.0 - dev: true - - /@octokit/core/3.6.0: - resolution: {integrity: sha512-7RKRKuA4xTjMhY+eG3jthb3hlZCsOwg3rztWh75Xc+ShDWOfDDATWbeZpAHBNRpm4Tv9WgBMOy1zEJYXG6NJ7Q==} - dependencies: - '@octokit/auth-token': 2.5.0 - '@octokit/graphql': 4.8.0 - '@octokit/request': 5.6.3 - '@octokit/request-error': 2.1.0 - '@octokit/types': 6.41.0 - before-after-hook: 2.2.3 - universal-user-agent: 6.0.0 - transitivePeerDependencies: - - encoding - dev: true - - /@octokit/endpoint/6.0.12: - resolution: {integrity: sha512-lF3puPwkQWGfkMClXb4k/eUT/nZKQfxinRWJrdZaJO85Dqwo/G0yOC434Jr2ojwafWJMYqFGFa5ms4jJUgujdA==} - dependencies: - '@octokit/types': 6.41.0 - is-plain-object: 5.0.0 - universal-user-agent: 6.0.0 - dev: true - - /@octokit/graphql/4.8.0: - resolution: {integrity: sha512-0gv+qLSBLKF0z8TKaSKTsS39scVKF9dbMxJpj3U0vC7wjNWFuIpL/z76Qe2fiuCbDRcJSavkXsVtMS6/dtQQsg==} - dependencies: - '@octokit/request': 5.6.3 - '@octokit/types': 6.41.0 - universal-user-agent: 6.0.0 - transitivePeerDependencies: - - encoding - dev: true - - /@octokit/openapi-types/12.11.0: - resolution: {integrity: sha512-VsXyi8peyRq9PqIz/tpqiL2w3w80OgVMwBHltTml3LmVvXiphgeqmY9mvBw9Wu7e0QWk/fqD37ux8yP5uVekyQ==} - dev: true - - /@octokit/plugin-enterprise-rest/6.0.1: - resolution: {integrity: sha512-93uGjlhUD+iNg1iWhUENAtJata6w5nE+V4urXOAlIXdco6xNZtUSfYY8dzp3Udy74aqO/B5UZL80x/YMa5PKRw==} - dev: true - - /@octokit/plugin-paginate-rest/2.21.3_@octokit+core@3.6.0: - resolution: {integrity: sha512-aCZTEf0y2h3OLbrgKkrfFdjRL6eSOo8komneVQJnYecAxIej7Bafor2xhuDJOIFau4pk0i/P28/XgtbyPF0ZHw==} - peerDependencies: - '@octokit/core': '>=2' - dependencies: - '@octokit/core': 3.6.0 - '@octokit/types': 6.41.0 - dev: true - - /@octokit/plugin-request-log/1.0.4_@octokit+core@3.6.0: - resolution: {integrity: sha512-mLUsMkgP7K/cnFEw07kWqXGF5LKrOkD+lhCrKvPHXWDywAwuDUeDwWBpc69XK3pNX0uKiVt8g5z96PJ6z9xCFA==} - peerDependencies: - '@octokit/core': '>=3' - dependencies: - '@octokit/core': 3.6.0 - dev: true - - /@octokit/plugin-rest-endpoint-methods/5.16.2_@octokit+core@3.6.0: - resolution: {integrity: sha512-8QFz29Fg5jDuTPXVtey05BLm7OB+M8fnvE64RNegzX7U+5NUXcOcnpTIK0YfSHBg8gYd0oxIq3IZTe9SfPZiRw==} - peerDependencies: - '@octokit/core': '>=3' - dependencies: - '@octokit/core': 3.6.0 - '@octokit/types': 6.41.0 - deprecation: 2.3.1 - dev: true - - /@octokit/request-error/2.1.0: - resolution: {integrity: sha512-1VIvgXxs9WHSjicsRwq8PlR2LR2x6DwsJAaFgzdi0JfJoGSO8mYI/cHJQ+9FbN21aa+DrgNLnwObmyeSC8Rmpg==} - dependencies: - '@octokit/types': 6.41.0 - deprecation: 2.3.1 - once: 1.4.0 - dev: true - - /@octokit/request/5.6.3: - resolution: {integrity: sha512-bFJl0I1KVc9jYTe9tdGGpAMPy32dLBXXo1dS/YwSCTL/2nd9XeHsY616RE3HPXDVk+a+dBuzyz5YdlXwcDTr2A==} - dependencies: - '@octokit/endpoint': 6.0.12 - '@octokit/request-error': 2.1.0 - '@octokit/types': 6.41.0 - is-plain-object: 5.0.0 - node-fetch: 2.6.7 - universal-user-agent: 6.0.0 - transitivePeerDependencies: - - encoding - dev: true - - /@octokit/rest/18.12.0: - resolution: {integrity: sha512-gDPiOHlyGavxr72y0guQEhLsemgVjwRePayJ+FcKc2SJqKUbxbkvf5kAZEWA/MKvsfYlQAMVzNJE3ezQcxMJ2Q==} - dependencies: - '@octokit/core': 3.6.0 - '@octokit/plugin-paginate-rest': 2.21.3_@octokit+core@3.6.0 - '@octokit/plugin-request-log': 1.0.4_@octokit+core@3.6.0 - '@octokit/plugin-rest-endpoint-methods': 5.16.2_@octokit+core@3.6.0 - transitivePeerDependencies: - - encoding - dev: true - - /@octokit/types/6.41.0: - resolution: {integrity: sha512-eJ2jbzjdijiL3B4PrSQaSjuF2sPEQPVCPzBvTHJD9Nz+9dw2SGH4K4xeQJ77YfTq5bRQ+bD8wT11JbeDPmxmGg==} - dependencies: - '@octokit/openapi-types': 12.11.0 - dev: true - - /@stylelint/postcss-css-in-js/0.37.3_j55xdkkcxc32kvnyvx3y7casfm: - resolution: {integrity: sha512-scLk3cSH1H9KggSniseb2KNAU5D9FWc3H7BxCSAIdtU9OWIyw0zkEZ9qEKHryRM+SExYXRKNb7tOOVNAsQ3iwg==} - peerDependencies: - postcss: '>=7.0.0' - postcss-syntax: '>=0.36.2' - dependencies: - '@babel/core': 7.19.6 - postcss: 7.0.39 - postcss-syntax: 0.36.2_kei4jy7wdgbhc236h4oijypxom - transitivePeerDependencies: - - supports-color - dev: true - - /@stylelint/postcss-markdown/0.36.2_j55xdkkcxc32kvnyvx3y7casfm: - resolution: {integrity: sha512-2kGbqUVJUGE8dM+bMzXG/PYUWKkjLIkRLWNh39OaADkiabDRdw8ATFCgbMz5xdIcvwspPAluSL7uY+ZiTWdWmQ==} - deprecated: 'Use the original unforked package instead: postcss-markdown' - peerDependencies: - postcss: '>=7.0.0' - postcss-syntax: '>=0.36.2' - dependencies: - postcss: 7.0.39 - postcss-syntax: 0.36.2_kei4jy7wdgbhc236h4oijypxom - remark: 13.0.0 - unist-util-find-all-after: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /@tootallnate/once/1.1.2: - resolution: {integrity: sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==} - engines: {node: '>= 6'} - dev: true - - /@types/json-schema/7.0.11: - resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==} - dev: true - - /@types/json5/0.0.29: - resolution: {integrity: sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==} - dev: true - - /@types/mdast/3.0.10: - resolution: {integrity: sha512-W864tg/Osz1+9f4lrGTZpCSO5/z4608eUp19tbozkq2HJK6i3z1kT0H9tlADXuYIb1YYOBByU4Jsqkk75q48qA==} - dependencies: - '@types/unist': 2.0.6 - dev: true - - /@types/minimatch/3.0.5: - resolution: {integrity: sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==} - dev: true - - /@types/minimist/1.2.2: - resolution: {integrity: sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ==} - dev: true - - /@types/normalize-package-data/2.4.1: - resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} - dev: true - - /@types/parse-json/4.0.0: - resolution: {integrity: sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==} - dev: true - - /@types/semver/7.3.13: - resolution: {integrity: sha512-21cFJr9z3g5dW8B0CVI9g2O9beqaThGQ6ZFBqHfwhzLDKUxaqTIy3vnfah/UPkfOiF2pLq+tGz+W8RyCskuslw==} - dev: true - - /@types/unist/2.0.6: - resolution: {integrity: sha512-PBjIUxZHOuj0R15/xuwJYjFi+KZdNFrehocChv4g5hu6aFroHue8m0lBP0POdK2nKzbw0cgV1mws8+V/JAcEkQ==} - dev: true - - /@typescript-eslint/eslint-plugin/5.41.0_df7bmmpvcdp26iorckypvaliia: - resolution: {integrity: sha512-DXUS22Y57/LAFSg3x7Vi6RNAuLpTXwxB9S2nIA7msBb/Zt8p7XqMwdpdc1IU7CkOQUPgAqR5fWvxuKCbneKGmA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - '@typescript-eslint/parser': ^5.0.0 - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/parser': 5.41.0_3rubbgt5ekhqrcgx4uwls3neim - '@typescript-eslint/scope-manager': 5.41.0 - '@typescript-eslint/type-utils': 5.41.0_3rubbgt5ekhqrcgx4uwls3neim - '@typescript-eslint/utils': 5.41.0_3rubbgt5ekhqrcgx4uwls3neim - debug: 4.3.4 - eslint: 7.32.0 - ignore: 5.2.0 - regexpp: 3.2.0 - semver: 7.3.8 - tsutils: 3.21.0_typescript@4.8.4 - typescript: 4.8.4 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/parser/5.41.0_3rubbgt5ekhqrcgx4uwls3neim: - resolution: {integrity: sha512-HQVfix4+RL5YRWZboMD1pUfFN8MpRH4laziWkkAzyO1fvNOY/uinZcvo3QiFJVS/siNHupV8E5+xSwQZrl6PZA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/scope-manager': 5.41.0 - '@typescript-eslint/types': 5.41.0 - '@typescript-eslint/typescript-estree': 5.41.0_typescript@4.8.4 - debug: 4.3.4 - eslint: 7.32.0 - typescript: 4.8.4 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/scope-manager/5.41.0: - resolution: {integrity: sha512-xOxPJCnuktUkY2xoEZBKXO5DBCugFzjrVndKdUnyQr3+9aDWZReKq9MhaoVnbL+maVwWJu/N0SEtrtEUNb62QQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.41.0 - '@typescript-eslint/visitor-keys': 5.41.0 - dev: true - - /@typescript-eslint/type-utils/5.41.0_3rubbgt5ekhqrcgx4uwls3neim: - resolution: {integrity: sha512-L30HNvIG6A1Q0R58e4hu4h+fZqaO909UcnnPbwKiN6Rc3BUEx6ez2wgN7aC0cBfcAjZfwkzE+E2PQQ9nEuoqfA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: '*' - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/typescript-estree': 5.41.0_typescript@4.8.4 - '@typescript-eslint/utils': 5.41.0_3rubbgt5ekhqrcgx4uwls3neim - debug: 4.3.4 - eslint: 7.32.0 - tsutils: 3.21.0_typescript@4.8.4 - typescript: 4.8.4 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/types/5.41.0: - resolution: {integrity: sha512-5BejraMXMC+2UjefDvrH0Fo/eLwZRV6859SXRg+FgbhA0R0l6lDqDGAQYhKbXhPN2ofk2kY5sgGyLNL907UXpA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - - /@typescript-eslint/typescript-estree/5.41.0_typescript@4.8.4: - resolution: {integrity: sha512-SlzFYRwFSvswzDSQ/zPkIWcHv8O5y42YUskko9c4ki+fV6HATsTODUPbRbcGDFYP86gaJL5xohUEytvyNNcXWg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - typescript: '*' - peerDependenciesMeta: - typescript: - optional: true - dependencies: - '@typescript-eslint/types': 5.41.0 - '@typescript-eslint/visitor-keys': 5.41.0 - debug: 4.3.4 - globby: 11.1.0 - is-glob: 4.0.3 - semver: 7.3.8 - tsutils: 3.21.0_typescript@4.8.4 - typescript: 4.8.4 - transitivePeerDependencies: - - supports-color - dev: true - - /@typescript-eslint/utils/5.41.0_3rubbgt5ekhqrcgx4uwls3neim: - resolution: {integrity: sha512-QlvfwaN9jaMga9EBazQ+5DDx/4sAdqDkcs05AsQHMaopluVCUyu1bTRUVKzXbgjDlrRAQrYVoi/sXJ9fmG+KLQ==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - '@types/json-schema': 7.0.11 - '@types/semver': 7.3.13 - '@typescript-eslint/scope-manager': 5.41.0 - '@typescript-eslint/types': 5.41.0 - '@typescript-eslint/typescript-estree': 5.41.0_typescript@4.8.4 - eslint: 7.32.0 - eslint-scope: 5.1.1 - eslint-utils: 3.0.0_eslint@7.32.0 - semver: 7.3.8 - transitivePeerDependencies: - - supports-color - - typescript - dev: true - - /@typescript-eslint/visitor-keys/5.41.0: - resolution: {integrity: sha512-vilqeHj267v8uzzakbm13HkPMl7cbYpKVjgFWZPIOHIJHZtinvypUhJ5xBXfWYg4eFKqztbMMpOgFpT9Gfx4fw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@typescript-eslint/types': 5.41.0 - eslint-visitor-keys: 3.3.0 - dev: true - - /JSONStream/1.3.5: - resolution: {integrity: sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ==} - hasBin: true - dependencies: - jsonparse: 1.3.1 - through: 2.3.8 - dev: true - - /abbrev/1.1.1: - resolution: {integrity: sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==} - dev: true - - /acorn-jsx/5.3.2_acorn@7.4.1: - resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==} - peerDependencies: - acorn: ^6.0.0 || ^7.0.0 || ^8.0.0 - dependencies: - acorn: 7.4.1 - dev: true - - /acorn/7.4.1: - resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - /add-stream/1.0.0: - resolution: {integrity: sha512-qQLMr+8o0WC4FZGQTcJiKBVC59JylcPSrTtk6usvmIDFUOCKegapy1VHQwRbFMOFyb/inzUVqHs+eMYKDM1YeQ==} - dev: true - - /agent-base/6.0.2: - resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} - engines: {node: '>= 6.0.0'} - dependencies: - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: true - - /agentkeepalive/4.2.1: - resolution: {integrity: sha512-Zn4cw2NEqd+9fiSVWMscnjyQ1a8Yfoc5oBajLeo5w+YBHgDUcEBY2hS4YpTz6iN5f/2zQiktcuM6tS8x1p9dpA==} - engines: {node: '>= 8.0.0'} - dependencies: - debug: 4.3.4 - depd: 1.1.2 - humanize-ms: 1.2.1 - transitivePeerDependencies: - - supports-color - dev: true - - /aggregate-error/3.1.0: - resolution: {integrity: sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==} - engines: {node: '>=8'} - dependencies: - clean-stack: 2.2.0 - indent-string: 4.0.0 - dev: true - - /ajv/6.12.6: - resolution: {integrity: sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==} - dependencies: - fast-deep-equal: 3.1.3 - fast-json-stable-stringify: 2.1.0 - json-schema-traverse: 0.4.1 - uri-js: 4.4.1 - dev: true - - /ajv/8.11.0: - resolution: {integrity: sha512-wGgprdCvMalC0BztXvitD2hC04YffAvtsUn93JbGXYLAtCUO4xd17mCCZQxUOItiBwZvJScWo8NIvQMQ71rdpg==} - dependencies: - fast-deep-equal: 3.1.3 - json-schema-traverse: 1.0.0 - require-from-string: 2.0.2 - uri-js: 4.4.1 - dev: true - - /ansi-colors/1.1.0: - resolution: {integrity: sha512-SFKX67auSNoVR38N3L+nvsPjOE0bybKTYbkf5tRvushrAPQ9V75huw0ZxBkKVeRU9kqH3d6HA4xTckbwZ4ixmA==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: true - - /ansi-colors/4.1.3: - resolution: {integrity: sha512-/6w/C21Pm1A7aZitlI5Ni/2J6FFQN8i1Cvz3kHABAAbw93v/NlvKdVOqz7CCWz/3iv/JplRSEEZ83XION15ovw==} - engines: {node: '>=6'} - dev: true - - /ansi-escapes/4.3.2: - resolution: {integrity: sha512-gKXj5ALrKWQLsYG9jlTRmR/xKluxHV+Z9QEwNIgCfM1/uwPMCuzVVnh5mwTd+OuBZcwSIMbqssNWRm1lE51QaQ==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.21.3 - dev: true - - /ansi-gray/0.1.1: - resolution: {integrity: sha512-HrgGIZUl8h2EHuZaU9hTR/cU5nhKxpVE1V6kdGsQ8e4zirElJ5fvtfc8N7Q1oq1aatO275i8pUFUCpNWCAnVWw==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-wrap: 0.1.0 - dev: true - - /ansi-regex/2.1.1: - resolution: {integrity: sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==} - engines: {node: '>=0.10.0'} - dev: true - - /ansi-regex/5.0.1: - resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==} - engines: {node: '>=8'} - dev: true - - /ansi-styles/3.2.1: - resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==} - engines: {node: '>=4'} - dependencies: - color-convert: 1.9.3 - dev: true - - /ansi-styles/4.3.0: - resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} - engines: {node: '>=8'} - dependencies: - color-convert: 2.0.1 - dev: true - - /ansi-wrap/0.1.0: - resolution: {integrity: sha512-ZyznvL8k/FZeQHr2T6LzcJ/+vBApDnMNZvfVFy3At0knswWd6rJ3/0Hhmpu8oqa6C92npmozs890sX9Dl6q+Qw==} - engines: {node: '>=0.10.0'} - dev: true - - /anymatch/2.0.0: - resolution: {integrity: sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==} - dependencies: - micromatch: 3.1.10 - normalize-path: 2.1.1 - transitivePeerDependencies: - - supports-color - dev: true - - /append-buffer/1.0.2: - resolution: {integrity: sha512-WLbYiXzD3y/ATLZFufV/rZvWdZOs+Z/+5v1rBZ463Jn398pa6kcde27cvozYnBoxXblGZTFfoPpsaEw0orU5BA==} - engines: {node: '>=0.10.0'} - dependencies: - buffer-equal: 1.0.1 - dev: true - - /aproba/1.2.0: - resolution: {integrity: sha512-Y9J6ZjXtoYh8RnXVCMOU/ttDmk1aBjunq9vO0ta5x85WDQiQfUF9sIPBITdbiiIVcBo03Hi3jMxigBtsddlXRw==} - dev: true - - /aproba/2.0.0: - resolution: {integrity: sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ==} - dev: true - - /archy/1.0.0: - resolution: {integrity: sha512-Xg+9RwCg/0p32teKdGMPTPnVXKD0w3DfHnFTficozsAgsvq2XenPJq/MYpzzQ/v8zrOyJn6Ds39VA4JIDwFfqw==} - dev: true - - /are-we-there-yet/1.1.7: - resolution: {integrity: sha512-nxwy40TuMiUGqMyRHgCSWZ9FM4VAoRP4xUYSTv5ImRog+h9yISPbVH7H8fASCIzYn9wlEv4zvFL7uKDMCFQm3g==} - dependencies: - delegates: 1.0.0 - readable-stream: 2.3.7 - dev: true - - /argparse/1.0.10: - resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} - dependencies: - sprintf-js: 1.0.3 - dev: true - - /argparse/2.0.1: - resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==} - dev: true - - /aria-query/4.2.2: - resolution: {integrity: sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==} - engines: {node: '>=6.0'} - dependencies: - '@babel/runtime': 7.20.0 - '@babel/runtime-corejs3': 7.20.0 - dev: true - - /arr-diff/4.0.0: - resolution: {integrity: sha512-YVIQ82gZPGBebQV/a8dar4AitzCQs0jjXwMPZllpXMaGjXPYVUawSxQrRsjhjupyVxEvbHgUmIhKVlND+j02kA==} - engines: {node: '>=0.10.0'} - dev: true - - /arr-filter/1.1.2: - resolution: {integrity: sha512-A2BETWCqhsecSvCkWAeVBFLH6sXEUGASuzkpjL3GR1SlL/PWL6M3J8EAAld2Uubmh39tvkJTqC9LeLHCUKmFXA==} - engines: {node: '>=0.10.0'} - dependencies: - make-iterator: 1.0.1 - dev: true - - /arr-flatten/1.1.0: - resolution: {integrity: sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==} - engines: {node: '>=0.10.0'} - dev: true - - /arr-map/2.0.2: - resolution: {integrity: sha512-tVqVTHt+Q5Xb09qRkbu+DidW1yYzz5izWS2Xm2yFm7qJnmUfz4HPzNxbHkdRJbz2lrqI7S+z17xNYdFcBBO8Hw==} - engines: {node: '>=0.10.0'} - dependencies: - make-iterator: 1.0.1 - dev: true - - /arr-union/3.1.0: - resolution: {integrity: sha512-sKpyeERZ02v1FeCZT8lrfJq5u6goHCtpTAzPwJYe7c8SPFOboNjNg1vz2L4VTn9T4PQxEx13TbXLmYUcS6Ug7Q==} - engines: {node: '>=0.10.0'} - dev: true - - /array-differ/3.0.0: - resolution: {integrity: sha512-THtfYS6KtME/yIAhKjZ2ul7XI96lQGHRputJQHO80LAWQnuGP4iCIN8vdMRboGbIEYBwU33q8Tch1os2+X0kMg==} - engines: {node: '>=8'} - dev: true - - /array-each/1.0.1: - resolution: {integrity: sha512-zHjL5SZa68hkKHBFBK6DJCTtr9sfTCPCaph/L7tMSLcTFgy+zX7E+6q5UArbtOtMBCtxdICpfTCspRse+ywyXA==} - engines: {node: '>=0.10.0'} - dev: true - - /array-ify/1.0.0: - resolution: {integrity: sha512-c5AMf34bKdvPhQ7tBGhqkgKNUzMr4WUs+WDtC2ZUGOUncbxKMTvqxYctiseW3+L4bA8ec+GcZ6/A/FW4m8ukng==} - dev: true - - /array-includes/3.1.5: - resolution: {integrity: sha512-iSDYZMMyTPkiFasVqfuAQnWAYcvO/SeBSCGKePoEthjp4LEMTe4uLc7b025o4jAZpHhihh8xPo99TNWUWWkGDQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - get-intrinsic: 1.1.3 - is-string: 1.0.7 - dev: true - - /array-initial/1.1.0: - resolution: {integrity: sha512-BC4Yl89vneCYfpLrs5JU2aAu9/a+xWbeKhvISg9PT7eWFB9UlRvI+rKEtk6mgxWr3dSkk9gQ8hCrdqt06NXPdw==} - engines: {node: '>=0.10.0'} - dependencies: - array-slice: 1.1.0 - is-number: 4.0.0 - dev: true - - /array-last/1.3.0: - resolution: {integrity: sha512-eOCut5rXlI6aCOS7Z7kCplKRKyiFQ6dHFBem4PwlwKeNFk2/XxTrhRh5T9PyaEWGy/NHTZWbY+nsZlNFJu9rYg==} - engines: {node: '>=0.10.0'} - dependencies: - is-number: 4.0.0 - dev: true - - /array-slice/1.1.0: - resolution: {integrity: sha512-B1qMD3RBP7O8o0H2KbrXDyB0IccejMF15+87Lvlor12ONPRHP6gTjXMNkt/d3ZuOGbAe66hFmaCfECI24Ufp6w==} - engines: {node: '>=0.10.0'} - dev: true - - /array-sort/1.0.0: - resolution: {integrity: sha512-ihLeJkonmdiAsD7vpgN3CRcx2J2S0TiYW+IS/5zHBI7mKUq3ySvBdzzBfD236ubDBQFiiyG3SWCPc+msQ9KoYg==} - engines: {node: '>=0.10.0'} - dependencies: - default-compare: 1.0.0 - get-value: 2.0.6 - kind-of: 5.1.0 - dev: true - - /array-union/2.1.0: - resolution: {integrity: sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==} - engines: {node: '>=8'} - dev: true - - /array-unique/0.3.2: - resolution: {integrity: sha512-SleRWjh9JUud2wH1hPs9rZBZ33H6T9HOiL0uwGnGx9FpE6wKGyfWugmbkEOIs6qWrZhg0LWeLziLrEwQJhs5mQ==} - engines: {node: '>=0.10.0'} - dev: true - - /array.prototype.flat/1.3.0: - resolution: {integrity: sha512-12IUEkHsAhA4DY5s0FPgNXIdc8VRSqD9Zp78a5au9abH/SOBrsp082JOWFNTjkMozh8mqcdiKuaLGhPeYztxSw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - es-shim-unscopables: 1.0.0 - dev: true - - /array.prototype.flatmap/1.3.0: - resolution: {integrity: sha512-PZC9/8TKAIxcWKdyeb77EzULHPrIX/tIZebLJUQOMR1OwYosT8yggdfWScfTBCDj5utONvOuPQQumYsU2ULbkg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - es-shim-unscopables: 1.0.0 - dev: true - - /array.prototype.reduce/1.0.4: - resolution: {integrity: sha512-WnM+AjG/DvLRLo4DDl+r+SvCzYtD2Jd9oeBYMcEaI7t3fFrHY9M53/wdLcTvmZNQ70IU6Htj0emFkZ5TS+lrdw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - es-array-method-boxes-properly: 1.0.0 - is-string: 1.0.7 - dev: true - - /arrify/1.0.1: - resolution: {integrity: sha512-3CYzex9M9FGQjCGMGyi6/31c8GJbgb0qGyrx5HWxPd0aCwh4cB2YjMb2Xf9UuoogrMrlO9cTqnB5rI5GHZTcUA==} - engines: {node: '>=0.10.0'} - dev: true - - /arrify/2.0.1: - resolution: {integrity: sha512-3duEwti880xqi4eAMN8AyR4a0ByT90zoYdLlevfrvU43vb0YZwZVfxOgxWrLXXXpyugL0hNZc9G6BiB5B3nUug==} - engines: {node: '>=8'} - dev: true - - /asap/2.0.6: - resolution: {integrity: sha512-BSHWgDSAiKs50o2Re8ppvp3seVHXSRM44cdSsT9FfNEUUZLOGWVCsiWaRPWM1Znn+mqZ1OfVZ3z3DWEzSp7hRA==} - dev: true - - /asn1/0.2.6: - resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} - dependencies: - safer-buffer: 2.1.2 - dev: true - - /assert-plus/1.0.0: - resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} - engines: {node: '>=0.8'} - dev: true - - /assign-symbols/1.0.0: - resolution: {integrity: sha512-Q+JC7Whu8HhmTdBph/Tq59IoRtoy6KAm5zzPv00WdujX82lbAL8K7WVjne7vdCsAmbF4AYaDOPyO3k0kl8qIrw==} - engines: {node: '>=0.10.0'} - dev: true - - /ast-types-flow/0.0.7: - resolution: {integrity: sha512-eBvWn1lvIApYMhzQMsu9ciLfkBY499mFZlNqG+/9WR7PVlroQw0vG30cOQQbaKz3sCEc44TAOu2ykzqXSNnwag==} - dev: true - - /astral-regex/2.0.0: - resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} - engines: {node: '>=8'} - dev: true - - /async-done/1.3.2: - resolution: {integrity: sha512-uYkTP8dw2og1tu1nmza1n1CMW0qb8gWWlwqMmLb7MhBVs4BXrFziT6HXUd+/RlRA/i4H9AkofYloUbs1fwMqlw==} - engines: {node: '>= 0.10'} - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - process-nextick-args: 2.0.1 - stream-exhaust: 1.0.2 - dev: true - - /async-each/1.0.3: - resolution: {integrity: sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==} - dev: true - - /async-settle/1.0.0: - resolution: {integrity: sha512-VPXfB4Vk49z1LHHodrEQ6Xf7W4gg1w0dAPROHngx7qgDjqmIQ+fXmwgGXTW/ITLai0YLSvWepJOP9EVpMnEAcw==} - engines: {node: '>= 0.10'} - dependencies: - async-done: 1.3.2 - dev: true - - /async/3.2.4: - resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} - dev: true - - /asynckit/0.4.0: - resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: true - - /at-least-node/1.0.0: - resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} - engines: {node: '>= 4.0.0'} - dev: true - - /atob/2.1.2: - resolution: {integrity: sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==} - engines: {node: '>= 4.5.0'} - hasBin: true - dev: true - - /autoprefixer/9.8.8: - resolution: {integrity: sha512-eM9d/swFopRt5gdJ7jrpCwgvEMIayITpojhkkSMRsFHYuH5bkSQ4p/9qTEHtmNudUZh22Tehu7I6CxAW0IXTKA==} - hasBin: true - dependencies: - browserslist: 4.21.4 - caniuse-lite: 1.0.30001426 - normalize-range: 0.1.2 - num2fraction: 1.2.2 - picocolors: 0.2.1 - postcss: 7.0.39 - postcss-value-parser: 4.2.0 - dev: true - - /aws-sign2/0.7.0: - resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} - dev: true - - /aws4/1.11.0: - resolution: {integrity: sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA==} - dev: true - - /axe-core/4.5.0: - resolution: {integrity: sha512-4+rr8eQ7+XXS5nZrKcMO/AikHL0hVqy+lHWAnE3xdHl+aguag8SOQ6eEqLexwLNWgXIMfunGuD3ON1/6Kyet0A==} - engines: {node: '>=4'} - dev: true - - /axobject-query/2.2.0: - resolution: {integrity: sha512-Td525n+iPOOyUQIeBfcASuG6uJsDOITl7Mds5gFyerkWiX7qhUTdYUBlSgNMyVqtSJqwpt1kXGLdUt6SykLMRA==} - dev: true - - /bach/1.2.0: - resolution: {integrity: sha512-bZOOfCb3gXBXbTFXq3OZtGR88LwGeJvzu6szttaIzymOTS4ZttBNOWSv7aLZja2EMycKtRYV0Oa8SNKH/zkxvg==} - engines: {node: '>= 0.10'} - dependencies: - arr-filter: 1.1.2 - arr-flatten: 1.1.0 - arr-map: 2.0.2 - array-each: 1.0.1 - array-initial: 1.1.0 - array-last: 1.3.0 - async-done: 1.3.2 - async-settle: 1.0.0 - now-and-later: 2.0.1 - dev: true - - /bail/1.0.5: - resolution: {integrity: sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==} - dev: true - - /balanced-match/1.0.2: - resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} - dev: true - - /balanced-match/2.0.0: - resolution: {integrity: sha512-1ugUSr8BHXRnK23KfuYS+gVMC3LB8QGH9W1iGtDPsNWoQbgtXSExkBu2aDR4epiGWZOjZsj6lDl/N/AqqTC3UA==} - dev: true - - /base/0.11.2: - resolution: {integrity: sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==} - engines: {node: '>=0.10.0'} - dependencies: - cache-base: 1.0.1 - class-utils: 0.3.6 - component-emitter: 1.3.0 - define-property: 1.0.0 - isobject: 3.0.1 - mixin-deep: 1.3.2 - pascalcase: 0.1.1 - dev: true - - /base64-js/1.5.1: - resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} - dev: true - - /bcrypt-pbkdf/1.0.2: - resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} - dependencies: - tweetnacl: 0.14.5 - dev: true - - /before-after-hook/2.2.3: - resolution: {integrity: sha512-NzUnlZexiaH/46WDhANlyR2bXRopNg4F/zuSA3OpZnllCUgRaOF2znDioDWrmbNVsuZk6l9pMquQB38cfBZwkQ==} - dev: true - - /binary-extensions/1.13.1: - resolution: {integrity: sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==} - engines: {node: '>=0.10.0'} - dev: true - - /bindings/1.5.0: - resolution: {integrity: sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==} - dependencies: - file-uri-to-path: 1.0.0 - dev: true - optional: true - - /bl/4.1.0: - resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} - dependencies: - buffer: 5.7.1 - inherits: 2.0.4 - readable-stream: 3.6.0 - dev: true - - /brace-expansion/1.1.11: - resolution: {integrity: sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==} - dependencies: - balanced-match: 1.0.2 - concat-map: 0.0.1 - dev: true - - /brace-expansion/2.0.1: - resolution: {integrity: sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==} - dependencies: - balanced-match: 1.0.2 - dev: true - - /braces/2.3.2: - resolution: {integrity: sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==} - engines: {node: '>=0.10.0'} - dependencies: - arr-flatten: 1.1.0 - array-unique: 0.3.2 - extend-shallow: 2.0.1 - fill-range: 4.0.0 - isobject: 3.0.1 - repeat-element: 1.1.4 - snapdragon: 0.8.2 - snapdragon-node: 2.1.1 - split-string: 3.1.0 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /braces/3.0.2: - resolution: {integrity: sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==} - engines: {node: '>=8'} - dependencies: - fill-range: 7.0.1 - dev: true - - /browserslist/4.21.4: - resolution: {integrity: sha512-CBHJJdDmgjl3daYjN5Cp5kbTf1mUhZoS+beLklHIvkOWscs83YAhLlF3Wsh/lciQYAcbBJgTOD44VtG31ZM4Hw==} - engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} - hasBin: true - dependencies: - caniuse-lite: 1.0.30001426 - electron-to-chromium: 1.4.284 - node-releases: 2.0.6 - update-browserslist-db: 1.0.10_browserslist@4.21.4 - dev: true - - /buffer-equal/1.0.1: - resolution: {integrity: sha512-QoV3ptgEaQpvVwbXdSO39iqPQTCxSF7A5U99AxbHYqUdCizL/lH2Z0A2y6nbZucxMEOtNyZfG2s6gsVugGpKkg==} - engines: {node: '>=0.4'} - dev: true - - /buffer-from/1.1.2: - resolution: {integrity: sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==} - dev: true - - /buffer/5.7.1: - resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} - dependencies: - base64-js: 1.5.1 - ieee754: 1.2.1 - dev: true - - /builtins/1.0.3: - resolution: {integrity: sha512-uYBjakWipfaO/bXI7E8rq6kpwHRZK5cNYrUv2OzZSI/FvmdMyXJ2tG9dKcjEC5YHmHpUAwsargWIZNWdxb/bnQ==} - dev: true - - /byline/5.0.0: - resolution: {integrity: sha512-s6webAy+R4SR8XVuJWt2V2rGvhnrhxN+9S15GNuTK3wKPOXFF6RNc+8ug2XhH+2s4f+uudG4kUVYmYOQWL2g0Q==} - engines: {node: '>=0.10.0'} - dev: true - - /byte-size/7.0.1: - resolution: {integrity: sha512-crQdqyCwhokxwV1UyDzLZanhkugAgft7vt0qbbdt60C6Zf3CAiGmtUCylbtYwrU6loOUw3euGrNtW1J651ot1A==} - engines: {node: '>=10'} - dev: true - - /cacache/15.3.0: - resolution: {integrity: sha512-VVdYzXEn+cnbXpFgWs5hTT7OScegHVmLhJIR8Ufqk3iFD6A6j5iSX1KuBTfNEv4tdJWE2PzA6IVFtcLC7fN9wQ==} - engines: {node: '>= 10'} - dependencies: - '@npmcli/fs': 1.1.1 - '@npmcli/move-file': 1.1.2 - chownr: 2.0.0 - fs-minipass: 2.1.0 - glob: 7.2.3 - infer-owner: 1.0.4 - lru-cache: 6.0.0 - minipass: 3.3.4 - minipass-collect: 1.0.2 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - mkdirp: 1.0.4 - p-map: 4.0.0 - promise-inflight: 1.0.1 - rimraf: 3.0.2 - ssri: 8.0.1 - tar: 6.1.11 - unique-filename: 1.1.1 - transitivePeerDependencies: - - bluebird - dev: true - - /cache-base/1.0.1: - resolution: {integrity: sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==} - engines: {node: '>=0.10.0'} - dependencies: - collection-visit: 1.0.0 - component-emitter: 1.3.0 - get-value: 2.0.6 - has-value: 1.0.0 - isobject: 3.0.1 - set-value: 2.0.1 - to-object-path: 0.3.0 - union-value: 1.0.1 - unset-value: 1.0.0 - dev: true - - /call-bind/1.0.2: - resolution: {integrity: sha512-7O+FbCihrB5WGbFYesctwmTKae6rOiIzmz1icreWJ+0aA7LJfuqhEso2T9ncpcFtzMQtzXf2QGGueWJGTYsqrA==} - dependencies: - function-bind: 1.1.1 - get-intrinsic: 1.1.3 - dev: true - - /caller-callsite/2.0.0: - resolution: {integrity: sha512-JuG3qI4QOftFsZyOn1qq87fq5grLIyk1JYd5lJmdA+fG7aQ9pA/i3JIJGcO3q0MrRcHlOt1U+ZeHW8Dq9axALQ==} - engines: {node: '>=4'} - dependencies: - callsites: 2.0.0 - dev: true - - /caller-path/2.0.0: - resolution: {integrity: sha512-MCL3sf6nCSXOwCTzvPKhN18TU7AHTvdtam8DAogxcrJ8Rjfbbg7Lgng64H9Iy+vUV6VGFClN/TyxBkAebLRR4A==} - engines: {node: '>=4'} - dependencies: - caller-callsite: 2.0.0 - dev: true - - /callsites/2.0.0: - resolution: {integrity: sha512-ksWePWBloaWPxJYQ8TL0JHvtci6G5QTKwQ95RcWAa/lzoAKuAOflGdAK92hpHXjkwb8zLxoLNUoNYZgVsaJzvQ==} - engines: {node: '>=4'} - dev: true - - /callsites/3.1.0: - resolution: {integrity: sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==} - engines: {node: '>=6'} - dev: true - - /camelcase-keys/6.2.2: - resolution: {integrity: sha512-YrwaA0vEKazPBkn0ipTiMpSajYDSe+KjQfrjhcBMxJt/znbvlHd8Pw/Vamaz5EB4Wfhs3SUR3Z9mwRu/P3s3Yg==} - engines: {node: '>=8'} - dependencies: - camelcase: 5.3.1 - map-obj: 4.3.0 - quick-lru: 4.0.1 - dev: true - - /camelcase/3.0.0: - resolution: {integrity: sha512-4nhGqUkc4BqbBBB4Q6zLuD7lzzrHYrjKGeYaEji/3tFR5VdJu9v+LilhGIVe8wxEJPPOeWo7eg8dwY13TZ1BNg==} - engines: {node: '>=0.10.0'} - dev: true - - /camelcase/5.3.1: - resolution: {integrity: sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==} - engines: {node: '>=6'} - dev: true - - /caniuse-lite/1.0.30001426: - resolution: {integrity: sha512-n7cosrHLl8AWt0wwZw/PJZgUg3lV0gk9LMI7ikGJwhyhgsd2Nb65vKvmSexCqq/J7rbH3mFG6yZZiPR5dLPW5A==} - dev: true - - /caseless/0.12.0: - resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} - dev: true - - /chalk/2.4.2: - resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==} - engines: {node: '>=4'} - dependencies: - ansi-styles: 3.2.1 - escape-string-regexp: 1.0.5 - supports-color: 5.5.0 - dev: true - - /chalk/4.1.0: - resolution: {integrity: sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - dev: true - - /chalk/4.1.2: - resolution: {integrity: sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - supports-color: 7.2.0 - dev: true - - /character-entities-legacy/1.1.4: - resolution: {integrity: sha512-3Xnr+7ZFS1uxeiUDvV02wQ+QDbc55o97tIV5zHScSPJpcLm/r0DFPcoY3tYRp+VZukxuMeKgXYmsXQHO05zQeA==} - dev: true - - /character-entities/1.2.4: - resolution: {integrity: sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==} - dev: true - - /character-reference-invalid/1.1.4: - resolution: {integrity: sha512-mKKUkUbhPpQlCOfIuZkvSEgktjPFIsZKRRbC6KWVEMvlzblj3i3asQv5ODsrwt0N3pHAEvjP8KTQPHkp0+6jOg==} - dev: true - - /chardet/0.7.0: - resolution: {integrity: sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==} - dev: true - - /chokidar/2.1.8: - resolution: {integrity: sha512-ZmZUazfOzf0Nve7duiCKD23PFSCs4JPoYyccjUFF3aQkQadqBhfzhjkwBH2mNOG9cTBwhamM37EIsIkZw3nRgg==} - deprecated: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies - dependencies: - anymatch: 2.0.0 - async-each: 1.0.3 - braces: 2.3.2 - glob-parent: 3.1.0 - inherits: 2.0.4 - is-binary-path: 1.0.1 - is-glob: 4.0.3 - normalize-path: 3.0.0 - path-is-absolute: 1.0.1 - readdirp: 2.2.1 - upath: 1.2.0 - optionalDependencies: - fsevents: 1.2.13 - transitivePeerDependencies: - - supports-color - dev: true - - /chownr/1.1.4: - resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==} - dev: true - - /chownr/2.0.0: - resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} - engines: {node: '>=10'} - dev: true - - /ci-info/2.0.0: - resolution: {integrity: sha512-5tK7EtrZ0N+OLFMthtqOj4fI2Jeb88C4CAZPu25LDVUgXJ0A3Js4PMGqrn0JU1W0Mh1/Z8wZzYPxqUrXeBboCQ==} - dev: true - - /class-utils/0.3.6: - resolution: {integrity: sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==} - engines: {node: '>=0.10.0'} - dependencies: - arr-union: 3.1.0 - define-property: 0.2.5 - isobject: 3.0.1 - static-extend: 0.1.2 - dev: true - - /clean-stack/2.2.0: - resolution: {integrity: sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==} - engines: {node: '>=6'} - dev: true - - /cli-cursor/3.1.0: - resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} - engines: {node: '>=8'} - dependencies: - restore-cursor: 3.1.0 - dev: true - - /cli-spinners/2.7.0: - resolution: {integrity: sha512-qu3pN8Y3qHNgE2AFweciB1IfMnmZ/fsNTEE+NOFjmGB2F/7rLhnhzppvpCnN4FovtP26k8lHyy9ptEbNwWFLzw==} - engines: {node: '>=6'} - dev: true - - /cli-width/3.0.0: - resolution: {integrity: sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw==} - engines: {node: '>= 10'} - dev: true - - /cliui/3.2.0: - resolution: {integrity: sha512-0yayqDxWQbqk3ojkYqUKqaAQ6AfNKeKWRNA8kR0WXzAsdHpP4BIaOmMAG87JGuO6qcobyW4GjxHd9PmhEd+T9w==} - dependencies: - string-width: 1.0.2 - strip-ansi: 3.0.1 - wrap-ansi: 2.1.0 - dev: true - - /cliui/6.0.0: - resolution: {integrity: sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ==} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 6.2.0 - dev: true - - /cliui/7.0.4: - resolution: {integrity: sha512-OcRE68cOsVMXp1Yvonl/fzkQOyjLSu/8bhPDfQt0e0/Eb283TKP20Fs2MqoPsr9SwA595rRCA+QMzYc9nBP+JQ==} - dependencies: - string-width: 4.2.3 - strip-ansi: 6.0.1 - wrap-ansi: 7.0.0 - dev: true - - /clone-buffer/1.0.0: - resolution: {integrity: sha512-KLLTJWrvwIP+OPfMn0x2PheDEP20RPUcGXj/ERegTgdmPEZylALQldygiqrPPu8P45uNuPs7ckmReLY6v/iA5g==} - engines: {node: '>= 0.10'} - dev: true - - /clone-deep/4.0.1: - resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} - engines: {node: '>=6'} - dependencies: - is-plain-object: 2.0.4 - kind-of: 6.0.3 - shallow-clone: 3.0.1 - dev: true - - /clone-regexp/2.2.0: - resolution: {integrity: sha512-beMpP7BOtTipFuW8hrJvREQ2DrRu3BE7by0ZpibtfBA+qfHYvMGTc2Yb1JMYPKg/JUw0CHYvpg796aNTSW9z7Q==} - engines: {node: '>=6'} - dependencies: - is-regexp: 2.1.0 - dev: true - - /clone-stats/1.0.0: - resolution: {integrity: sha512-au6ydSpg6nsrigcZ4m8Bc9hxjeW+GJ8xh5G3BJCMt4WXe1H10UNaVOamqQTmrx1kjVuxAHIQSNU6hY4Nsn9/ag==} - dev: true - - /clone/1.0.4: - resolution: {integrity: sha512-JQHZ2QMW6l3aH/j6xCqQThY/9OH4D/9ls34cgkUBiEeocRTU04tHfKPBsUK1PqZCUQM7GiA0IIXJSuXHI64Kbg==} - engines: {node: '>=0.8'} - dev: true - - /clone/2.1.2: - resolution: {integrity: sha512-3Pe/CF1Nn94hyhIYpjtiLhdCoEoz0DqQ+988E9gmeEdQZlojxnOb74wctFyuwWQHzqyf9X7C7MG8juUpqBJT8w==} - engines: {node: '>=0.8'} - dev: true - - /cloneable-readable/1.1.3: - resolution: {integrity: sha512-2EF8zTQOxYq70Y4XKtorQupqF0m49MBz2/yf5Bj+MHjvpG3Hy7sImifnqD6UA+TKYxeSV+u6qqQPawN5UvnpKQ==} - dependencies: - inherits: 2.0.4 - process-nextick-args: 2.0.1 - readable-stream: 2.3.7 - dev: true - - /cmd-shim/4.1.0: - resolution: {integrity: sha512-lb9L7EM4I/ZRVuljLPEtUJOP+xiQVknZ4ZMpMgEp4JzNldPb27HU03hi6K1/6CoIuit/Zm/LQXySErFeXxDprw==} - engines: {node: '>=10'} - dependencies: - mkdirp-infer-owner: 2.0.0 - dev: true - - /code-point-at/1.1.0: - resolution: {integrity: sha512-RpAVKQA5T63xEj6/giIbUEtZwJ4UFIc3ZtvEkiaUERylqe8xb5IvqcgOurZLahv93CLKfxcw5YI+DZcUBRyLXA==} - engines: {node: '>=0.10.0'} - dev: true - - /collection-map/1.0.0: - resolution: {integrity: sha512-5D2XXSpkOnleOI21TG7p3T0bGAsZ/XknZpKBmGYyluO8pw4zA3K8ZlrBIbC4FXg3m6z/RNFiUFfT2sQK01+UHA==} - engines: {node: '>=0.10.0'} - dependencies: - arr-map: 2.0.2 - for-own: 1.0.0 - make-iterator: 1.0.1 - dev: true - - /collection-visit/1.0.0: - resolution: {integrity: sha512-lNkKvzEeMBBjUGHZ+q6z9pSJla0KWAQPvtzhEV9+iGyQYG+pBpl7xKDhxoNSOZH2hhv0v5k0y2yAM4o4SjoSkw==} - engines: {node: '>=0.10.0'} - dependencies: - map-visit: 1.0.0 - object-visit: 1.0.1 - dev: true - - /color-convert/1.9.3: - resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==} - dependencies: - color-name: 1.1.3 - dev: true - - /color-convert/2.0.1: - resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==} - engines: {node: '>=7.0.0'} - dependencies: - color-name: 1.1.4 - dev: true - - /color-name/1.1.3: - resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==} - dev: true - - /color-name/1.1.4: - resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==} - dev: true - - /color-support/1.1.3: - resolution: {integrity: sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg==} - hasBin: true - dev: true - - /columnify/1.6.0: - resolution: {integrity: sha512-lomjuFZKfM6MSAnV9aCZC9sc0qGbmZdfygNv+nCpqVkSKdCxCklLtd16O0EILGkImHw9ZpHkAnHaB+8Zxq5W6Q==} - engines: {node: '>=8.0.0'} - dependencies: - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - dev: true - - /combined-stream/1.0.8: - resolution: {integrity: sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==} - engines: {node: '>= 0.8'} - dependencies: - delayed-stream: 1.0.0 - dev: true - - /command-exists/1.2.9: - resolution: {integrity: sha512-LTQ/SGc+s0Xc0Fu5WaKnR0YiygZkm9eKFvyS+fRsU7/ZWFF8ykFM6Pc9aCVf1+xasOOZpO3BAVgVrKvsqKHV7w==} - dev: true - - /commander/6.2.1: - resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} - engines: {node: '>= 6'} - dev: true - - /comment-parser/1.3.0: - resolution: {integrity: sha512-hRpmWIKgzd81vn0ydoWoyPoALEOnF4wt8yKD35Ib1D6XC2siLiYaiqfGkYrunuKdsXGwpBpHU3+9r+RVw2NZfA==} - engines: {node: '>= 12.0.0'} - dev: true - - /commitlint-config-ali/0.1.3: - resolution: {integrity: sha512-udq2cb0i9uXfT6JOgOL7w+iJ0NCcg84az3i6vqEHNI1GCeKXOdZCAjz20XE5dvyWVIfFMcj3d3J0ydgCL6eJHQ==} - dependencies: - conventional-changelog-conventionalcommits: 4.6.3 - dev: true - - /compare-func/2.0.0: - resolution: {integrity: sha512-zHig5N+tPWARooBnb0Zx1MFcdfpyJrfTJ3Y5L+IFvUm8rM74hHz66z0gw0x4tijh5CorKkKUCnW82R2vmpeCRA==} - dependencies: - array-ify: 1.0.0 - dot-prop: 5.3.0 - dev: true - - /component-emitter/1.3.0: - resolution: {integrity: sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==} - dev: true - - /concat-map/0.0.1: - resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==} - dev: true - - /concat-stream/1.6.2: - resolution: {integrity: sha512-27HBghJxjiZtIk3Ycvn/4kbJk/1uZuJFfuPEns6LaEvpvG1f0hTea8lilrouyo9mVc2GWdcEZ8OLoGmSADlrCw==} - engines: {'0': node >= 0.8} - dependencies: - buffer-from: 1.1.2 - inherits: 2.0.4 - readable-stream: 2.3.7 - typedarray: 0.0.6 - dev: true - - /concat-stream/2.0.0: - resolution: {integrity: sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==} - engines: {'0': node >= 6.0} - dependencies: - buffer-from: 1.1.2 - inherits: 2.0.4 - readable-stream: 3.6.0 - typedarray: 0.0.6 - dev: true - - /config-chain/1.1.13: - resolution: {integrity: sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==} - dependencies: - ini: 1.3.8 - proto-list: 1.2.4 - dev: true - - /console-control-strings/1.1.0: - resolution: {integrity: sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ==} - dev: true - - /conventional-changelog-angular/5.0.13: - resolution: {integrity: sha512-i/gipMxs7s8L/QeuavPF2hLnJgH6pEZAttySB6aiQLWcX3puWDL3ACVmvBhJGxnAy52Qc15ua26BufY6KpmrVA==} - engines: {node: '>=10'} - dependencies: - compare-func: 2.0.0 - q: 1.5.1 - dev: true - - /conventional-changelog-conventionalcommits/4.6.3: - resolution: {integrity: sha512-LTTQV4fwOM4oLPad317V/QNQ1FY4Hju5qeBIM1uTHbrnCE+Eg4CdRZ3gO2pUeR+tzWdp80M2j3qFFEDWVqOV4g==} - engines: {node: '>=10'} - dependencies: - compare-func: 2.0.0 - lodash: 4.17.21 - q: 1.5.1 - dev: true - - /conventional-changelog-core/4.2.4: - resolution: {integrity: sha512-gDVS+zVJHE2v4SLc6B0sLsPiloR0ygU7HaDW14aNJE1v4SlqJPILPl/aJC7YdtRE4CybBf8gDwObBvKha8Xlyg==} - engines: {node: '>=10'} - dependencies: - add-stream: 1.0.0 - conventional-changelog-writer: 5.0.1 - conventional-commits-parser: 3.2.4 - dateformat: 3.0.3 - get-pkg-repo: 4.2.1 - git-raw-commits: 2.0.11 - git-remote-origin-url: 2.0.0 - git-semver-tags: 4.1.1 - lodash: 4.17.21 - normalize-package-data: 3.0.3 - q: 1.5.1 - read-pkg: 3.0.0 - read-pkg-up: 3.0.0 - through2: 4.0.2 - dev: true - - /conventional-changelog-preset-loader/2.3.4: - resolution: {integrity: sha512-GEKRWkrSAZeTq5+YjUZOYxdHq+ci4dNwHvpaBC3+ENalzFWuCWa9EZXSuZBpkr72sMdKB+1fyDV4takK1Lf58g==} - engines: {node: '>=10'} - dev: true - - /conventional-changelog-writer/5.0.1: - resolution: {integrity: sha512-5WsuKUfxW7suLblAbFnxAcrvf6r+0b7GvNaWUwUIk0bXMnENP/PEieGKVUQrjPqwPT4o3EPAASBXiY6iHooLOQ==} - engines: {node: '>=10'} - hasBin: true - dependencies: - conventional-commits-filter: 2.0.7 - dateformat: 3.0.3 - handlebars: 4.7.7 - json-stringify-safe: 5.0.1 - lodash: 4.17.21 - meow: 8.1.2 - semver: 6.3.0 - split: 1.0.1 - through2: 4.0.2 - dev: true - - /conventional-commits-filter/2.0.7: - resolution: {integrity: sha512-ASS9SamOP4TbCClsRHxIHXRfcGCnIoQqkvAzCSbZzTFLfcTqJVugB0agRgsEELsqaeWgsXv513eS116wnlSSPA==} - engines: {node: '>=10'} - dependencies: - lodash.ismatch: 4.4.0 - modify-values: 1.0.1 - dev: true - - /conventional-commits-parser/3.2.4: - resolution: {integrity: sha512-nK7sAtfi+QXbxHCYfhpZsfRtaitZLIA6889kFIouLvz6repszQDgxBu7wf2WbU+Dco7sAnNCJYERCwt54WPC2Q==} - engines: {node: '>=10'} - hasBin: true - dependencies: - is-text-path: 1.0.1 - JSONStream: 1.3.5 - lodash: 4.17.21 - meow: 8.1.2 - split2: 3.2.2 - through2: 4.0.2 - dev: true - - /conventional-recommended-bump/6.1.0: - resolution: {integrity: sha512-uiApbSiNGM/kkdL9GTOLAqC4hbptObFo4wW2QRyHsKciGAfQuLU1ShZ1BIVI/+K2BE/W1AWYQMCXAsv4dyKPaw==} - engines: {node: '>=10'} - hasBin: true - dependencies: - concat-stream: 2.0.0 - conventional-changelog-preset-loader: 2.3.4 - conventional-commits-filter: 2.0.7 - conventional-commits-parser: 3.2.4 - git-raw-commits: 2.0.11 - git-semver-tags: 4.1.1 - meow: 8.1.2 - q: 1.5.1 - dev: true - - /convert-source-map/1.9.0: - resolution: {integrity: sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==} - dev: true - - /copy-descriptor/0.1.1: - resolution: {integrity: sha512-XgZ0pFcakEUlbwQEVNg3+QAis1FyTL3Qel9FYy8pSkQqoG3PNoT0bOCQtOXcOkur21r2Eq2kI+IE+gsmAEVlYw==} - engines: {node: '>=0.10.0'} - dev: true - - /copy-props/2.0.5: - resolution: {integrity: sha512-XBlx8HSqrT0ObQwmSzM7WE5k8FxTV75h1DX1Z3n6NhQ/UYYAvInWYmG06vFt7hQZArE2fuO62aihiWIVQwh1sw==} - dependencies: - each-props: 1.3.2 - is-plain-object: 5.0.0 - dev: true - - /core-js-pure/3.26.0: - resolution: {integrity: sha512-LiN6fylpVBVwT8twhhluD9TzXmZQQsr2I2eIKtWNbZI1XMfBT7CV18itaN6RA7EtQd/SDdRx/wzvAShX2HvhQA==} - requiresBuild: true - dev: true - - /core-js/3.26.0: - resolution: {integrity: sha512-+DkDrhoR4Y0PxDz6rurahuB+I45OsEUv8E1maPTB6OuHRohMMcznBq9TMpdpDMm/hUPob/mJJS3PqgbHpMTQgw==} - requiresBuild: true - dev: true - - /core-util-is/1.0.2: - resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} - dev: true - - /core-util-is/1.0.3: - resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} - dev: true - - /cosmiconfig/5.2.1: - resolution: {integrity: sha512-H65gsXo1SKjf8zmrJ67eJk8aIRKV5ff2D4uKZIBZShbhGSpEmsQOPW/SKMKYhSTrqR7ufy6RP69rPogdaPh/kA==} - engines: {node: '>=4'} - dependencies: - import-fresh: 2.0.0 - is-directory: 0.3.1 - js-yaml: 3.14.1 - parse-json: 4.0.0 - dev: true - - /cosmiconfig/7.0.1: - resolution: {integrity: sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==} - engines: {node: '>=10'} - dependencies: - '@types/parse-json': 4.0.0 - import-fresh: 3.3.0 - parse-json: 5.2.0 - path-type: 4.0.0 - yaml: 1.10.2 - dev: true - - /cross-spawn/6.0.5: - resolution: {integrity: sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==} - engines: {node: '>=4.8'} - dependencies: - nice-try: 1.0.5 - path-key: 2.0.1 - semver: 5.7.1 - shebang-command: 1.2.0 - which: 1.3.1 - dev: true - - /cross-spawn/7.0.3: - resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} - engines: {node: '>= 8'} - dependencies: - path-key: 3.1.1 - shebang-command: 2.0.0 - which: 2.0.2 - dev: true - - /cssesc/3.0.0: - resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /d/1.0.1: - resolution: {integrity: sha512-m62ShEObQ39CfralilEQRjH6oAMtNCV1xJyEx5LpRYUVN+EviphDgUc/F3hnYbADmkiNs67Y+3ylmlG7Lnu+FA==} - dependencies: - es5-ext: 0.10.62 - type: 1.2.0 - dev: true - - /damerau-levenshtein/1.0.8: - resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} - dev: true - - /dargs/7.0.0: - resolution: {integrity: sha512-2iy1EkLdlBzQGvbweYRFxmFath8+K7+AKB0TlhHWkNuH+TmovaMH/Wp7V7R4u7f4SnX3OgLsU9t1NI9ioDnUpg==} - engines: {node: '>=8'} - dev: true - - /dashdash/1.14.1: - resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} - engines: {node: '>=0.10'} - dependencies: - assert-plus: 1.0.0 - dev: true - - /dateformat/3.0.3: - resolution: {integrity: sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q==} - dev: true - - /debug/2.6.9: - resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.0.0 - dev: true - - /debug/3.2.7: - resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.3 - dev: true - - /debug/4.3.4: - resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} - engines: {node: '>=6.0'} - peerDependencies: - supports-color: '*' - peerDependenciesMeta: - supports-color: - optional: true - dependencies: - ms: 2.1.2 - dev: true - - /debuglog/1.0.1: - resolution: {integrity: sha512-syBZ+rnAK3EgMsH2aYEOLUW7mZSY9Gb+0wUMCFsZvcmiz+HigA0LOcq/HoQqVuGG+EKykunc7QG2bzrponfaSw==} - dev: true - - /decamelize-keys/1.1.0: - resolution: {integrity: sha512-ocLWuYzRPoS9bfiSdDd3cxvrzovVMZnRDVEzAs+hWIVXGDbHxWMECij2OBuyB/An0FFW/nLuq6Kv1i/YC5Qfzg==} - engines: {node: '>=0.10.0'} - dependencies: - decamelize: 1.2.0 - map-obj: 1.0.1 - dev: true - - /decamelize/1.2.0: - resolution: {integrity: sha512-z2S+W9X73hAUUki+N+9Za2lBlun89zigOyGrsax+KUQ6wKW4ZoWpEYBkGhQjwAjjDCkWxhY0VKEhk8wzY7F5cA==} - engines: {node: '>=0.10.0'} - dev: true - - /decode-uri-component/0.2.0: - resolution: {integrity: sha512-hjf+xovcEn31w/EUYdTXQh/8smFL/dzYjohQGEIgjyNavaJfBY2p5F527Bo1VPATxv0VYTUC2bOcXvqFwk78Og==} - engines: {node: '>=0.10'} - dev: true - - /dedent/0.7.0: - resolution: {integrity: sha512-Q6fKUPqnAHAyhiUgFU7BUzLiv0kd8saH9al7tnu5Q/okj6dnupxyTgFIBjVzJATdfIAm9NAsvXNzjaKa+bxVyA==} - dev: true - - /deep-is/0.1.4: - resolution: {integrity: sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==} - dev: true - - /default-compare/1.0.0: - resolution: {integrity: sha512-QWfXlM0EkAbqOCbD/6HjdwT19j7WCkMyiRhWilc4H9/5h/RzTF9gv5LYh1+CmDV5d1rki6KAWLtQale0xt20eQ==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 5.1.0 - dev: true - - /default-resolution/2.0.0: - resolution: {integrity: sha512-2xaP6GiwVwOEbXCGoJ4ufgC76m8cj805jrghScewJC2ZDsb9U0b4BIrba+xt/Uytyd0HvQ6+WymSRTfnYj59GQ==} - engines: {node: '>= 0.10'} - dev: true - - /defaults/1.0.4: - resolution: {integrity: sha512-eFuaLoy/Rxalv2kr+lqMlUnrDWV+3j4pljOIJgLIhI058IQfWJ7vXhyEIHu+HtC738klGALYxOKDO0bQP3tg8A==} - dependencies: - clone: 1.0.4 - dev: true - - /define-properties/1.1.4: - resolution: {integrity: sha512-uckOqKcfaVvtBdsVkdPv3XjveQJsNQqmhXgRi8uhvWWuPYZCNlzT8qAyblUgNoXdHdjMTzAqeGjAoli8f+bzPA==} - engines: {node: '>= 0.4'} - dependencies: - has-property-descriptors: 1.0.0 - object-keys: 1.1.1 - dev: true - - /define-property/0.2.5: - resolution: {integrity: sha512-Rr7ADjQZenceVOAKop6ALkkRAmH1A4Gx9hV/7ZujPUN2rkATqFO0JZLZInbAjpZYoJ1gUx8MRMQVkYemcbMSTA==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 0.1.6 - dev: true - - /define-property/1.0.0: - resolution: {integrity: sha512-cZTYKFWspt9jZsMscWo8sc/5lbPC9Q0N5nBLgb+Yd915iL3udB1uFgS3B8YCx66UVHq018DAVFoee7x+gxggeA==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 1.0.2 - dev: true - - /define-property/2.0.2: - resolution: {integrity: sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-descriptor: 1.0.2 - isobject: 3.0.1 - dev: true - - /del/6.1.1: - resolution: {integrity: sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==} - engines: {node: '>=10'} - dependencies: - globby: 11.1.0 - graceful-fs: 4.2.10 - is-glob: 4.0.3 - is-path-cwd: 2.2.0 - is-path-inside: 3.0.3 - p-map: 4.0.0 - rimraf: 3.0.2 - slash: 3.0.0 - dev: true - - /delayed-stream/1.0.0: - resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} - engines: {node: '>=0.4.0'} - dev: true - - /delegates/1.0.0: - resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} - dev: true - - /depd/1.1.2: - resolution: {integrity: sha512-7emPTl6Dpo6JRXOXjLRxck+FlLRX5847cLKEn00PLAgc3g2hTZZgr+e4c2v6QpSmLeFP3n5yUo7ft6avBK/5jQ==} - engines: {node: '>= 0.6'} - dev: true - - /deprecation/2.3.1: - resolution: {integrity: sha512-xmHIy4F3scKVwMsQ4WnVaS8bHOx0DmVwRywosKhaILI0ywMDWPtBSku2HNxRvF7jtwDRsoEwYQSfbxj8b7RlJQ==} - dev: true - - /detect-file/1.0.0: - resolution: {integrity: sha512-DtCOLG98P007x7wiiOmfI0fi3eIKyWiLTGJ2MDnVi/E04lWGbf+JzrRHMm0rgIIZJGtHpKpbVgLWHrv8xXpc3Q==} - engines: {node: '>=0.10.0'} - dev: true - - /detect-indent/5.0.0: - resolution: {integrity: sha512-rlpvsxUtM0PQvy9iZe640/IWwWYyBsTApREbA1pHOpmOUIl9MkP/U4z7vTtg4Oaojvqhxt7sdufnT0EzGaR31g==} - engines: {node: '>=4'} - dev: true - - /detect-indent/6.1.0: - resolution: {integrity: sha512-reYkTUJAZb9gUuZ2RvVCNhVHdg62RHnJ7WJl8ftMi4diZ6NWlciOzQN88pUhSELEwflJht4oQDv0F0BMlwaYtA==} - engines: {node: '>=8'} - dev: true - - /dezalgo/1.0.4: - resolution: {integrity: sha512-rXSP0bf+5n0Qonsb+SVVfNfIsimO4HEtmnIpPHY8Q1UCzKlQrDMfdobr8nJOOsRgWCyMRqeSBQzmWUMq7zvVig==} - dependencies: - asap: 2.0.6 - wrappy: 1.0.2 - dev: true - - /dir-glob/3.0.1: - resolution: {integrity: sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==} - engines: {node: '>=8'} - dependencies: - path-type: 4.0.0 - dev: true - - /doctrine/2.1.0: - resolution: {integrity: sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==} - engines: {node: '>=0.10.0'} - dependencies: - esutils: 2.0.3 - dev: true - - /doctrine/3.0.0: - resolution: {integrity: sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==} - engines: {node: '>=6.0.0'} - dependencies: - esutils: 2.0.3 - dev: true - - /dom-serializer/0.2.2: - resolution: {integrity: sha512-2/xPb3ORsQ42nHYiSunXkDjPLBaEj/xTwUO4B7XCZQTRk7EBtTOPaygh10YAAh2OI1Qrp6NWfpAhzswj0ydt9g==} - dependencies: - domelementtype: 2.3.0 - entities: 2.2.0 - dev: true - - /domelementtype/1.3.1: - resolution: {integrity: sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==} - dev: true - - /domelementtype/2.3.0: - resolution: {integrity: sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==} - dev: true - - /domhandler/2.4.2: - resolution: {integrity: sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==} - dependencies: - domelementtype: 1.3.1 - dev: true - - /domutils/1.7.0: - resolution: {integrity: sha512-Lgd2XcJ/NjEw+7tFvfKxOzCYKZsdct5lczQ2ZaQY8Djz7pfAD3Gbp8ySJWtreII/vDlMVmxwa6pHmdxIYgttDg==} - dependencies: - dom-serializer: 0.2.2 - domelementtype: 1.3.1 - dev: true - - /dot-prop/5.3.0: - resolution: {integrity: sha512-QM8q3zDe58hqUqjraQOmzZ1LIH9SWQJTlEKCH4kJ2oQvLZk7RbQXvtDM2XEq3fwkV9CCvvH4LA0AV+ogFsBM2Q==} - engines: {node: '>=8'} - dependencies: - is-obj: 2.0.0 - dev: true - - /dot-prop/6.0.1: - resolution: {integrity: sha512-tE7ztYzXHIeyvc7N+hR3oi7FIbf/NIjVP9hmAt3yMXzrQ072/fpjGLx2GxNxGxUl5V73MEqYzioOMoVhGMJ5cA==} - engines: {node: '>=10'} - dependencies: - is-obj: 2.0.0 - dev: true - - /duplexer/0.1.2: - resolution: {integrity: sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==} - dev: true - - /duplexify/3.7.1: - resolution: {integrity: sha512-07z8uv2wMyS51kKhD1KsdXJg5WQ6t93RneqRxUHnskXVtlYYkLqM0gqStQZ3pj073g687jPCHrqNfCzawLYh5g==} - dependencies: - end-of-stream: 1.4.4 - inherits: 2.0.4 - readable-stream: 2.3.7 - stream-shift: 1.0.1 - dev: true - - /each-props/1.3.2: - resolution: {integrity: sha512-vV0Hem3zAGkJAyU7JSjixeU66rwdynTAa1vofCrSA5fEln+m67Az9CcnkVD776/fsN/UjIWmBDoNRS6t6G9RfA==} - dependencies: - is-plain-object: 2.0.4 - object.defaults: 1.1.0 - dev: true - - /ecc-jsbn/0.1.2: - resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} - dependencies: - jsbn: 0.1.1 - safer-buffer: 2.1.2 - dev: true - - /ejs/3.1.8: - resolution: {integrity: sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==} - engines: {node: '>=0.10.0'} - hasBin: true - dependencies: - jake: 10.8.5 - dev: true - - /electron-to-chromium/1.4.284: - resolution: {integrity: sha512-M8WEXFuKXMYMVr45fo8mq0wUrrJHheiKZf6BArTKk9ZBYCKJEOU5H8cdWgDT+qCVZf7Na4lVUaZsA+h6uA9+PA==} - dev: true - - /emoji-regex/8.0.0: - resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - dev: true - - /emoji-regex/9.2.2: - resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==} - dev: true - - /encoding/0.1.13: - resolution: {integrity: sha512-ETBauow1T35Y/WZMkio9jiM0Z5xjHHmJ4XmjZOq1l/dXz3lr2sRn87nJy20RupqSh1F2m3HHPSp8ShIPQJrJ3A==} - requiresBuild: true - dependencies: - iconv-lite: 0.6.3 - dev: true - optional: true - - /end-of-stream/1.4.4: - resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} - dependencies: - once: 1.4.0 - dev: true - - /enquirer/2.3.6: - resolution: {integrity: sha512-yjNnPr315/FjS4zIsUxYguYUPP2e1NK4d7E7ZOLiyYCcbFBiTMyID+2wvm2w6+pZ/odMA7cRkjhsPbltwBOrLg==} - engines: {node: '>=8.6'} - dependencies: - ansi-colors: 4.1.3 - dev: true - - /entities/1.1.2: - resolution: {integrity: sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==} - dev: true - - /entities/2.0.3: - resolution: {integrity: sha512-MyoZ0jgnLvB2X3Lg5HqpFmn1kybDiIfEQmKzTb5apr51Rb+T3KdmMiqa70T+bhGnyv7bQ6WMj2QMHpGMmlrUYQ==} - dev: true - - /entities/2.2.0: - resolution: {integrity: sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==} - dev: true - - /env-paths/2.2.1: - resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} - engines: {node: '>=6'} - dev: true - - /envinfo/7.8.1: - resolution: {integrity: sha512-/o+BXHmB7ocbHEAs6F2EnG0ogybVVUdkRunTT2glZU9XAaGmhqskrvKwqXuDfNjEO0LZKWdejEEpnq8aM0tOaw==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /err-code/2.0.3: - resolution: {integrity: sha512-2bmlRpNKBxT/CRmPOlyISQpNj+qSeYvcym/uT0Jx2bMOlKLtSy1ZmLuVxSEKKyor/N5yhvp/ZiG1oE3DEYMSFA==} - dev: true - - /error-ex/1.3.2: - resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} - dependencies: - is-arrayish: 0.2.1 - dev: true - - /es-abstract/1.20.4: - resolution: {integrity: sha512-0UtvRN79eMe2L+UNEF1BwRe364sj/DXhQ/k5FmivgoSdpM90b8Jc0mDzKMGo7QS0BVbOP/bTwBKNnDc9rNzaPA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - es-to-primitive: 1.2.1 - function-bind: 1.1.1 - function.prototype.name: 1.1.5 - get-intrinsic: 1.1.3 - get-symbol-description: 1.0.0 - has: 1.0.3 - has-property-descriptors: 1.0.0 - has-symbols: 1.0.3 - internal-slot: 1.0.3 - is-callable: 1.2.7 - is-negative-zero: 2.0.2 - is-regex: 1.1.4 - is-shared-array-buffer: 1.0.2 - is-string: 1.0.7 - is-weakref: 1.0.2 - object-inspect: 1.12.2 - object-keys: 1.1.1 - object.assign: 4.1.4 - regexp.prototype.flags: 1.4.3 - safe-regex-test: 1.0.0 - string.prototype.trimend: 1.0.5 - string.prototype.trimstart: 1.0.5 - unbox-primitive: 1.0.2 - dev: true - - /es-array-method-boxes-properly/1.0.0: - resolution: {integrity: sha512-wd6JXUmyHmt8T5a2xreUwKcGPq6f1f+WwIJkijUqiGcJz1qqnZgP6XIK+QyIWU5lT7imeNxUll48bziG+TSYcA==} - dev: true - - /es-shim-unscopables/1.0.0: - resolution: {integrity: sha512-Jm6GPcCdC30eMLbZ2x8z2WuRwAws3zTBBKuusffYVUrNj/GVSUAZ+xKMaUpfNDR5IbyNA5LJbaecoUVbmUcB1w==} - dependencies: - has: 1.0.3 - dev: true - - /es-to-primitive/1.2.1: - resolution: {integrity: sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==} - engines: {node: '>= 0.4'} - dependencies: - is-callable: 1.2.7 - is-date-object: 1.0.5 - is-symbol: 1.0.4 - dev: true - - /es5-ext/0.10.62: - resolution: {integrity: sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==} - engines: {node: '>=0.10'} - requiresBuild: true - dependencies: - es6-iterator: 2.0.3 - es6-symbol: 3.1.3 - next-tick: 1.1.0 - dev: true - - /es6-iterator/2.0.3: - resolution: {integrity: sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==} - dependencies: - d: 1.0.1 - es5-ext: 0.10.62 - es6-symbol: 3.1.3 - dev: true - - /es6-symbol/3.1.3: - resolution: {integrity: sha512-NJ6Yn3FuDinBaBRWl/q5X/s4koRHBrgKAu+yGI6JCBeiu3qrcbJhwT2GeR/EXVfylRk8dpQVJoLEFhK+Mu31NA==} - dependencies: - d: 1.0.1 - ext: 1.7.0 - dev: true - - /es6-weak-map/2.0.3: - resolution: {integrity: sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==} - dependencies: - d: 1.0.1 - es5-ext: 0.10.62 - es6-iterator: 2.0.3 - es6-symbol: 3.1.3 - dev: true - - /escalade/3.1.1: - resolution: {integrity: sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==} - engines: {node: '>=6'} - dev: true - - /escape-string-regexp/1.0.5: - resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==} - engines: {node: '>=0.8.0'} - dev: true - - /escape-string-regexp/4.0.0: - resolution: {integrity: sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA==} - engines: {node: '>=10'} - dev: true - - /eslint-config-ali/13.1.0_eslint@7.32.0: - resolution: {integrity: sha512-ZjWrpiKADEmNhtfB64iVN3ejlDS5sS9OZx9+jN3mF+oqaroWqrTPvqQvY472M4ykL0JgT+AqsZdG+kWDqUw/6g==} - peerDependencies: - eslint: '>=6.8.0' - dependencies: - eslint: 7.32.0 - dev: true - - /eslint-config-egg/10.0.0_3rubbgt5ekhqrcgx4uwls3neim: - resolution: {integrity: sha512-CA0hs3cxvp0HfjWvBuU4wK3Zrw6SyfSZl4WWfvoV8IbI30VsVUWXdETVfXpMVsadXkMiJ0U37X8tICNSBIyAIw==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dependencies: - '@babel/core': 7.19.6 - '@babel/eslint-parser': 7.19.1_mgnruehwwwnc5e6kz5xt6nx3ru - '@typescript-eslint/eslint-plugin': 5.41.0_df7bmmpvcdp26iorckypvaliia - '@typescript-eslint/parser': 5.41.0_3rubbgt5ekhqrcgx4uwls3neim - eslint-plugin-eggache: 1.0.0 - eslint-plugin-import: 2.26.0_eqxe32jpi637ohevnaikdwsmhq - eslint-plugin-jsdoc: 37.9.7_eslint@7.32.0 - eslint-plugin-jsx-a11y: 6.6.1_eslint@7.32.0 - eslint-plugin-node: 11.1.0_eslint@7.32.0 - eslint-plugin-react: 7.31.10_eslint@7.32.0 - transitivePeerDependencies: - - eslint - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - - typescript - dev: true - - /eslint-config-prettier/7.2.0_eslint@7.32.0: - resolution: {integrity: sha512-rV4Qu0C3nfJKPOAhFujFxB7RMP+URFyQqqOZW9DMRD7ZDTFyjaIlETU3xzHELt++4ugC0+Jm084HQYkkJe+Ivg==} - hasBin: true - peerDependencies: - eslint: '>=7.0.0' - dependencies: - eslint: 7.32.0 - dev: true - - /eslint-import-resolver-node/0.3.6: - resolution: {integrity: sha512-0En0w03NRVMn9Uiyn8YRPDKvWjxCWkslUEhGNTdGx15RvPJYQ+lbOlqrlNI2vEAs4pDYK4f/HN2TbDmk5TP0iw==} - dependencies: - debug: 3.2.7 - resolve: 1.22.1 - transitivePeerDependencies: - - supports-color - dev: true - - /eslint-module-utils/2.7.4_bqu7xrk3mkpslzy6j5cosz3swi: - resolution: {integrity: sha512-j4GT+rqzCoRKHwURX7pddtIPGySnX9Si/cgMI5ztrcqOPtk5dDEeZ34CQVPphnqkJytlc97Vuk05Um2mJ3gEQA==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: '*' - eslint-import-resolver-node: '*' - eslint-import-resolver-typescript: '*' - eslint-import-resolver-webpack: '*' - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - eslint: - optional: true - eslint-import-resolver-node: - optional: true - eslint-import-resolver-typescript: - optional: true - eslint-import-resolver-webpack: - optional: true - dependencies: - '@typescript-eslint/parser': 5.41.0_3rubbgt5ekhqrcgx4uwls3neim - debug: 3.2.7 - eslint: 7.32.0 - eslint-import-resolver-node: 0.3.6 - transitivePeerDependencies: - - supports-color - dev: true - - /eslint-plugin-eggache/1.0.0: - resolution: {integrity: sha512-LPTrTvITFDZggiXAIdMPL4bJo0wvXUgJqC3f6UIskJxzHZze2aBTvjWQJ7TgEbkfpk++KWhcOl+lels+qAPKDg==} - engines: {node: '>=6.0.0'} - dev: true - - /eslint-plugin-es/3.0.1_eslint@7.32.0: - resolution: {integrity: sha512-GUmAsJaN4Fc7Gbtl8uOBlayo2DqhwWvEzykMHSCZHU3XdJ+NSzzZcVhXh3VxX5icqQ+oQdIEawXX8xkR3mIFmQ==} - engines: {node: '>=8.10.0'} - peerDependencies: - eslint: '>=4.19.1' - dependencies: - eslint: 7.32.0 - eslint-utils: 2.1.0 - regexpp: 3.2.0 - dev: true - - /eslint-plugin-import/2.26.0_eqxe32jpi637ohevnaikdwsmhq: - resolution: {integrity: sha512-hYfi3FXaM8WPLf4S1cikh/r4IxnO6zrhZbEGz2b660EJRbuxgpDS5gkCuYgGWg2xxh2rBuIr4Pvhve/7c31koA==} - engines: {node: '>=4'} - peerDependencies: - '@typescript-eslint/parser': '*' - eslint: ^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8 - peerDependenciesMeta: - '@typescript-eslint/parser': - optional: true - dependencies: - '@typescript-eslint/parser': 5.41.0_3rubbgt5ekhqrcgx4uwls3neim - array-includes: 3.1.5 - array.prototype.flat: 1.3.0 - debug: 2.6.9 - doctrine: 2.1.0 - eslint: 7.32.0 - eslint-import-resolver-node: 0.3.6 - eslint-module-utils: 2.7.4_bqu7xrk3mkpslzy6j5cosz3swi - has: 1.0.3 - is-core-module: 2.11.0 - is-glob: 4.0.3 - minimatch: 3.1.2 - object.values: 1.1.5 - resolve: 1.22.1 - tsconfig-paths: 3.14.1 - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - supports-color - dev: true - - /eslint-plugin-jsdoc/37.9.7_eslint@7.32.0: - resolution: {integrity: sha512-8alON8yYcStY94o0HycU2zkLKQdcS+qhhOUNQpfONHHwvI99afbmfpYuPqf6PbLz5pLZldG3Te5I0RbAiTN42g==} - engines: {node: ^12 || ^14 || ^16 || ^17} - peerDependencies: - eslint: ^7.0.0 || ^8.0.0 - dependencies: - '@es-joy/jsdoccomment': 0.20.1 - comment-parser: 1.3.0 - debug: 4.3.4 - escape-string-regexp: 4.0.0 - eslint: 7.32.0 - esquery: 1.4.0 - regextras: 0.8.0 - semver: 7.3.8 - spdx-expression-parse: 3.0.1 - transitivePeerDependencies: - - supports-color - dev: true - - /eslint-plugin-jsx-a11y/6.6.1_eslint@7.32.0: - resolution: {integrity: sha512-sXgFVNHiWffBq23uiS/JaP6eVR622DqwB4yTzKvGZGcPq6/yZ3WmOZfuBks/vHWo9GaFOqC2ZK4i6+C35knx7Q==} - engines: {node: '>=4.0'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - dependencies: - '@babel/runtime': 7.20.0 - aria-query: 4.2.2 - array-includes: 3.1.5 - ast-types-flow: 0.0.7 - axe-core: 4.5.0 - axobject-query: 2.2.0 - damerau-levenshtein: 1.0.8 - emoji-regex: 9.2.2 - eslint: 7.32.0 - has: 1.0.3 - jsx-ast-utils: 3.3.3 - language-tags: 1.0.5 - minimatch: 3.1.2 - semver: 6.3.0 - dev: true - - /eslint-plugin-node/11.1.0_eslint@7.32.0: - resolution: {integrity: sha512-oUwtPJ1W0SKD0Tr+wqu92c5xuCeQqB3hSCHasn/ZgjFdA9iDGNkNf2Zi9ztY7X+hNuMib23LNGRm6+uN+KLE3g==} - engines: {node: '>=8.10.0'} - peerDependencies: - eslint: '>=5.16.0' - dependencies: - eslint: 7.32.0 - eslint-plugin-es: 3.0.1_eslint@7.32.0 - eslint-utils: 2.1.0 - ignore: 5.2.0 - minimatch: 3.1.2 - resolve: 1.22.1 - semver: 6.3.0 - dev: true - - /eslint-plugin-prettier/3.4.1_krfuiecpk3xclvkrlwn2dh4uea: - resolution: {integrity: sha512-htg25EUYUeIhKHXjOinK4BgCcDwtLHjqaxCDsMy5nbnUMkKFvIhMVCp+5GFUXQ4Nr8lBsPqtGAqBenbpFqAA2g==} - engines: {node: '>=6.0.0'} - peerDependencies: - eslint: '>=5.0.0' - eslint-config-prettier: '*' - prettier: '>=1.13.0' - peerDependenciesMeta: - eslint-config-prettier: - optional: true - dependencies: - eslint: 7.32.0 - eslint-config-prettier: 7.2.0_eslint@7.32.0 - prettier: 2.7.1 - prettier-linter-helpers: 1.0.0 - dev: true - - /eslint-plugin-react-hooks/4.6.0_eslint@7.32.0: - resolution: {integrity: sha512-oFc7Itz9Qxh2x4gNHStv3BqJq54ExXmfC+a1NjAta66IAN87Wu0R/QArgIS9qKzX3dXKPI9H5crl9QchNMY9+g==} - engines: {node: '>=10'} - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - dependencies: - eslint: 7.32.0 - dev: true - - /eslint-plugin-react/7.31.10_eslint@7.32.0: - resolution: {integrity: sha512-e4N/nc6AAlg4UKW/mXeYWd3R++qUano5/o+t+wnWxIf+bLsOaH3a4q74kX3nDjYym3VBN4HyO9nEn1GcAqgQOA==} - engines: {node: '>=4'} - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - dependencies: - array-includes: 3.1.5 - array.prototype.flatmap: 1.3.0 - doctrine: 2.1.0 - eslint: 7.32.0 - estraverse: 5.3.0 - jsx-ast-utils: 3.3.3 - minimatch: 3.1.2 - object.entries: 1.1.5 - object.fromentries: 2.0.5 - object.hasown: 1.1.1 - object.values: 1.1.5 - prop-types: 15.8.1 - resolve: 2.0.0-next.4 - semver: 6.3.0 - string.prototype.matchall: 4.0.7 - dev: true - - /eslint-plugin-vue/7.20.0_eslint@7.32.0: - resolution: {integrity: sha512-oVNDqzBC9h3GO+NTgWeLMhhGigy6/bQaQbHS+0z7C4YEu/qK/yxHvca/2PTZtGNPsCrHwOTgKMrwu02A9iPBmw==} - engines: {node: '>=8.10'} - peerDependencies: - eslint: ^6.2.0 || ^7.0.0 || ^8.0.0 - dependencies: - eslint: 7.32.0 - eslint-utils: 2.1.0 - natural-compare: 1.4.0 - semver: 6.3.0 - vue-eslint-parser: 7.11.0_eslint@7.32.0 - transitivePeerDependencies: - - supports-color - dev: true - - /eslint-scope/5.1.1: - resolution: {integrity: sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==} - engines: {node: '>=8.0.0'} - dependencies: - esrecurse: 4.3.0 - estraverse: 4.3.0 - dev: true - - /eslint-utils/2.1.0: - resolution: {integrity: sha512-w94dQYoauyvlDc43XnGB8lU3Zt713vNChgt4EWwhXAP2XkBvndfxF0AgIqKOOasjPIPzj9JqgwkwbCYD0/V3Zg==} - engines: {node: '>=6'} - dependencies: - eslint-visitor-keys: 1.3.0 - dev: true - - /eslint-utils/3.0.0_eslint@7.32.0: - resolution: {integrity: sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==} - engines: {node: ^10.0.0 || ^12.0.0 || >= 14.0.0} - peerDependencies: - eslint: '>=5' - dependencies: - eslint: 7.32.0 - eslint-visitor-keys: 2.1.0 - dev: true - - /eslint-visitor-keys/1.3.0: - resolution: {integrity: sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==} - engines: {node: '>=4'} - dev: true - - /eslint-visitor-keys/2.1.0: - resolution: {integrity: sha512-0rSmRBzXgDzIsD6mGdJgevzgezI534Cer5L/vyMX0kHzT/jiB43jRhd9YUlMGYLQy2zprNmoT8qasCGtY+QaKw==} - engines: {node: '>=10'} - dev: true - - /eslint-visitor-keys/3.3.0: - resolution: {integrity: sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - dev: true - - /eslint/7.32.0: - resolution: {integrity: sha512-VHZ8gX+EDfz+97jGcgyGCyRia/dPOd6Xh9yPv8Bl1+SoaIwD+a/vlrOmGRUyOYu7MwUhc7CxqeaDZU13S4+EpA==} - engines: {node: ^10.12.0 || >=12.0.0} - hasBin: true - dependencies: - '@babel/code-frame': 7.12.11 - '@eslint/eslintrc': 0.4.3 - '@humanwhocodes/config-array': 0.5.0 - ajv: 6.12.6 - chalk: 4.1.2 - cross-spawn: 7.0.3 - debug: 4.3.4 - doctrine: 3.0.0 - enquirer: 2.3.6 - escape-string-regexp: 4.0.0 - eslint-scope: 5.1.1 - eslint-utils: 2.1.0 - eslint-visitor-keys: 2.1.0 - espree: 7.3.1 - esquery: 1.4.0 - esutils: 2.0.3 - fast-deep-equal: 3.1.3 - file-entry-cache: 6.0.1 - functional-red-black-tree: 1.0.1 - glob-parent: 5.1.2 - globals: 13.17.0 - ignore: 4.0.6 - import-fresh: 3.3.0 - imurmurhash: 0.1.4 - is-glob: 4.0.3 - js-yaml: 3.14.1 - json-stable-stringify-without-jsonify: 1.0.1 - levn: 0.4.1 - lodash.merge: 4.6.2 - minimatch: 3.1.2 - natural-compare: 1.4.0 - optionator: 0.9.1 - progress: 2.0.3 - regexpp: 3.2.0 - semver: 7.3.8 - strip-ansi: 6.0.1 - strip-json-comments: 3.1.1 - table: 6.8.0 - text-table: 0.2.0 - v8-compile-cache: 2.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /espree/6.2.1: - resolution: {integrity: sha512-ysCxRQY3WaXJz9tdbWOwuWr5Y/XrPTGX9Kiz3yoUXwW0VZ4w30HTkQLaGx/+ttFjF8i+ACbArnB4ce68a9m5hw==} - engines: {node: '>=6.0.0'} - dependencies: - acorn: 7.4.1 - acorn-jsx: 5.3.2_acorn@7.4.1 - eslint-visitor-keys: 1.3.0 - dev: true - - /espree/7.3.1: - resolution: {integrity: sha512-v3JCNCE64umkFpmkFGqzVKsOT0tN1Zr+ueqLZfpV1Ob8e+CEgPWa+OxCoGH3tnhimMKIaBm4m/vaRpJ/krRz2g==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - acorn: 7.4.1 - acorn-jsx: 5.3.2_acorn@7.4.1 - eslint-visitor-keys: 1.3.0 - dev: true - - /esprima/4.0.1: - resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /esquery/1.4.0: - resolution: {integrity: sha512-cCDispWt5vHHtwMY2YrAQ4ibFkAL8RbH5YGBnZBc90MolvvfkkQcJro/aZiAQUlQ3qgrYS6D6v8Gc5G5CQsc9w==} - engines: {node: '>=0.10'} - dependencies: - estraverse: 5.3.0 - dev: true - - /esrecurse/4.3.0: - resolution: {integrity: sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag==} - engines: {node: '>=4.0'} - dependencies: - estraverse: 5.3.0 - dev: true - - /estraverse/4.3.0: - resolution: {integrity: sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==} - engines: {node: '>=4.0'} - dev: true - - /estraverse/5.3.0: - resolution: {integrity: sha512-MMdARuVEQziNTeJD8DgMqmhwR11BRQ/cBP+pLtYdSTnf3MIO8fFeiINEbX36ZdNlfU/7A9f3gUw49B3oQsvwBA==} - engines: {node: '>=4.0'} - dev: true - - /esutils/2.0.3: - resolution: {integrity: sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g==} - engines: {node: '>=0.10.0'} - dev: true - - /eventemitter3/4.0.7: - resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} - dev: true - - /execa/1.0.0: - resolution: {integrity: sha512-adbxcyWV46qiHyvSp50TKt05tB4tK3HcmF7/nxfAdhnox83seTDbwnaqKO4sXRy7roHAIFqJP/Rw/AuEbX61LA==} - engines: {node: '>=6'} - dependencies: - cross-spawn: 6.0.5 - get-stream: 4.1.0 - is-stream: 1.1.0 - npm-run-path: 2.0.2 - p-finally: 1.0.0 - signal-exit: 3.0.7 - strip-eof: 1.0.0 - dev: true - - /execa/5.1.1: - resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} - engines: {node: '>=10'} - dependencies: - cross-spawn: 7.0.3 - get-stream: 6.0.1 - human-signals: 2.1.0 - is-stream: 2.0.1 - merge-stream: 2.0.0 - npm-run-path: 4.0.1 - onetime: 5.1.2 - signal-exit: 3.0.7 - strip-final-newline: 2.0.0 - dev: true - - /execall/2.0.0: - resolution: {integrity: sha512-0FU2hZ5Hh6iQnarpRtQurM/aAvp3RIbfvgLHrcqJYzhXyV2KFruhuChf9NC6waAhiUR7FFtlugkI4p7f2Fqlow==} - engines: {node: '>=8'} - dependencies: - clone-regexp: 2.2.0 - dev: true - - /expand-brackets/2.1.4: - resolution: {integrity: sha512-w/ozOKR9Obk3qoWeY/WDi6MFta9AoMR+zud60mdnbniMcBxRuFJyDt2LdX/14A1UABeqk+Uk+LDfUpvoGKppZA==} - engines: {node: '>=0.10.0'} - dependencies: - debug: 2.6.9 - define-property: 0.2.5 - extend-shallow: 2.0.1 - posix-character-classes: 0.1.1 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /expand-tilde/2.0.2: - resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} - engines: {node: '>=0.10.0'} - dependencies: - homedir-polyfill: 1.0.3 - dev: true - - /ext/1.7.0: - resolution: {integrity: sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==} - dependencies: - type: 2.7.2 - dev: true - - /extend-shallow/2.0.1: - resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==} - engines: {node: '>=0.10.0'} - dependencies: - is-extendable: 0.1.1 - dev: true - - /extend-shallow/3.0.2: - resolution: {integrity: sha512-BwY5b5Ql4+qZoefgMj2NUmx+tehVTH/Kf4k1ZEtOHNFcm2wSxMRo992l6X3TIgni2eZVTZ85xMOjF31fwZAj6Q==} - engines: {node: '>=0.10.0'} - dependencies: - assign-symbols: 1.0.0 - is-extendable: 1.0.1 - dev: true - - /extend/3.0.2: - resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - dev: true - - /external-editor/3.1.0: - resolution: {integrity: sha512-hMQ4CX1p1izmuLYyZqLMO/qGNw10wSv9QDCPfzXfyFrOaCSSoRfqE1Kf1s5an66J5JZC62NewG+mK49jOCtQew==} - engines: {node: '>=4'} - dependencies: - chardet: 0.7.0 - iconv-lite: 0.4.24 - tmp: 0.0.33 - dev: true - - /extglob/2.0.4: - resolution: {integrity: sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==} - engines: {node: '>=0.10.0'} - dependencies: - array-unique: 0.3.2 - define-property: 1.0.0 - expand-brackets: 2.1.4 - extend-shallow: 2.0.1 - fragment-cache: 0.2.1 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /extsprintf/1.3.0: - resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} - engines: {'0': node >=0.6.0} - dev: true - - /f2elint/2.2.1_typescript@4.8.4: - resolution: {integrity: sha512-3hhU7H3XYo2VGrOr5yPpGT4nK+AvJcNPRzF8EDcnyDWgpm76Qm4o1ByWzloCtGmqUP0RNVG/8uCKp3jeHVyVRg==} - engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} - hasBin: true - dependencies: - '@babel/core': 7.19.6 - '@babel/eslint-parser': 7.19.1_mgnruehwwwnc5e6kz5xt6nx3ru - '@babel/preset-react': 7.18.6_@babel+core@7.19.6 - '@commitlint/cli': 11.0.0 - '@typescript-eslint/eslint-plugin': 5.41.0_df7bmmpvcdp26iorckypvaliia - '@typescript-eslint/parser': 5.41.0_3rubbgt5ekhqrcgx4uwls3neim - chalk: 4.1.2 - command-exists: 1.2.9 - commander: 6.2.1 - commitlint-config-ali: 0.1.3 - cross-spawn: 7.0.3 - ejs: 3.1.8 - eslint: 7.32.0 - eslint-config-ali: 13.1.0_eslint@7.32.0 - eslint-config-egg: 10.0.0_3rubbgt5ekhqrcgx4uwls3neim - eslint-config-prettier: 7.2.0_eslint@7.32.0 - eslint-plugin-import: 2.26.0_eqxe32jpi637ohevnaikdwsmhq - eslint-plugin-jsx-a11y: 6.6.1_eslint@7.32.0 - eslint-plugin-prettier: 3.4.1_krfuiecpk3xclvkrlwn2dh4uea - eslint-plugin-react: 7.31.10_eslint@7.32.0 - eslint-plugin-react-hooks: 4.6.0_eslint@7.32.0 - eslint-plugin-vue: 7.20.0_eslint@7.32.0 - execa: 5.1.1 - fs-extra: 9.1.0 - glob: 7.2.3 - husky: 3.1.0 - inquirer: 7.3.3 - is-docker: 2.2.1 - lodash: 4.17.21 - markdownlint: 0.22.0 - markdownlint-config-ali: 0.1.1_markdownlint@0.22.0 - markdownlint-rule-helpers: 0.13.0 - ora: 5.4.1 - prettier: 2.7.1 - strip-ansi: 6.0.1 - stylelint: 13.13.1 - stylelint-config-ali: 0.4.2_2vkgt733dnumio3be4grtjqkwy - stylelint-scss: 3.21.0_stylelint@13.13.1 - terminal-link: 2.1.1 - text-table: 0.2.0 - vue-eslint-parser: 7.11.0_eslint@7.32.0 - transitivePeerDependencies: - - eslint-import-resolver-typescript - - eslint-import-resolver-webpack - - postcss-jsx - - postcss-markdown - - supports-color - - typescript - dev: true - - /fancy-log/1.3.3: - resolution: {integrity: sha512-k9oEhlyc0FrVh25qYuSELjr8oxsCoc4/LEZfg2iJJrfEk/tZL9bCoJE47gqAvI2m/AUjluCS4+3I0eTx8n3AEw==} - engines: {node: '>= 0.10'} - dependencies: - ansi-gray: 0.1.1 - color-support: 1.1.3 - parse-node-version: 1.0.1 - time-stamp: 1.1.0 - dev: true - - /fast-deep-equal/3.1.3: - resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} - dev: true - - /fast-diff/1.2.0: - resolution: {integrity: sha512-xJuoT5+L99XlZ8twedaRf6Ax2TgQVxvgZOYoPKqZufmJib0tL2tegPBOZb1pVNgIhlqDlA0eO0c3wBvQcmzx4w==} - dev: true - - /fast-glob/3.2.12: - resolution: {integrity: sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w==} - engines: {node: '>=8.6.0'} - dependencies: - '@nodelib/fs.stat': 2.0.5 - '@nodelib/fs.walk': 1.2.8 - glob-parent: 5.1.2 - merge2: 1.4.1 - micromatch: 4.0.5 - dev: true - - /fast-json-stable-stringify/2.1.0: - resolution: {integrity: sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==} - dev: true - - /fast-levenshtein/1.1.4: - resolution: {integrity: sha512-Ia0sQNrMPXXkqVFt6w6M1n1oKo3NfKs+mvaV811Jwir7vAk9a6PVV9VPYf6X3BU97QiLEmuW3uXH9u87zDFfdw==} - dev: true - - /fast-levenshtein/2.0.6: - resolution: {integrity: sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw==} - dev: true - - /fastest-levenshtein/1.0.16: - resolution: {integrity: sha512-eRnCtTTtGZFpQCwhJiUOuxPQWRXVKYDn0b2PeHfXL6/Zi53SLAzAHfVhVWK2AryC/WH05kGfxhFIPvTF0SXQzg==} - engines: {node: '>= 4.9.1'} - dev: true - - /fastq/1.13.0: - resolution: {integrity: sha512-YpkpUnK8od0o1hmeSc7UUs/eB/vIPWJYjKck2QKIzAf71Vm1AAQ3EbuZB3g2JIy+pg+ERD0vqI79KyZiB2e2Nw==} - dependencies: - reusify: 1.0.4 - dev: true - - /figures/3.2.0: - resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} - engines: {node: '>=8'} - dependencies: - escape-string-regexp: 1.0.5 - dev: true - - /file-entry-cache/6.0.1: - resolution: {integrity: sha512-7Gps/XWymbLk2QLYK4NzpMOrYjMhdIxXuIvy2QBsLE6ljuodKvdkWs/cpyJJ3CVIVpH0Oi1Hvg1ovbMzLdFBBg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flat-cache: 3.0.4 - dev: true - - /file-uri-to-path/1.0.0: - resolution: {integrity: sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==} - dev: true - optional: true - - /filelist/1.0.4: - resolution: {integrity: sha512-w1cEuf3S+DrLCQL7ET6kz+gmlJdbq9J7yXCSjK/OZCPA+qEN1WyF4ZAf0YYJa4/shHJra2t/d/r8SV4Ji+x+8Q==} - dependencies: - minimatch: 5.1.0 - dev: true - - /fill-range/4.0.0: - resolution: {integrity: sha512-VcpLTWqWDiTerugjj8e3+esbg+skS3M9e54UuR3iCeIDMXCLTsAH8hTSzDQU/X6/6t3eYkOKoZSef2PlU6U1XQ==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 2.0.1 - is-number: 3.0.0 - repeat-string: 1.6.1 - to-regex-range: 2.1.1 - dev: true - - /fill-range/7.0.1: - resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} - engines: {node: '>=8'} - dependencies: - to-regex-range: 5.0.1 - dev: true - - /filter-obj/1.1.0: - resolution: {integrity: sha512-8rXg1ZnX7xzy2NGDVkBVaAy+lSlPNwad13BtgSlLuxfIslyt5Vg64U7tFcCt4WS1R0hvtnQybT/IyCkGZ3DpXQ==} - engines: {node: '>=0.10.0'} - dev: true - - /find-up/1.1.2: - resolution: {integrity: sha512-jvElSjyuo4EMQGoTwo1uJU5pQMwTW5lS1x05zzfJuTIyLR3zwO27LYrxNg+dlvKpGOuGy/MzBdXh80g0ve5+HA==} - engines: {node: '>=0.10.0'} - dependencies: - path-exists: 2.1.0 - pinkie-promise: 2.0.1 - dev: true - - /find-up/2.1.0: - resolution: {integrity: sha512-NWzkk0jSJtTt08+FBFMvXoeZnOJD+jTtsRmBYbAIzJdX6l7dLgR7CTubCM5/eDdPUBvLCeVasP1brfVR/9/EZQ==} - engines: {node: '>=4'} - dependencies: - locate-path: 2.0.0 - dev: true - - /find-up/4.1.0: - resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==} - engines: {node: '>=8'} - dependencies: - locate-path: 5.0.0 - path-exists: 4.0.0 - dev: true - - /find-up/5.0.0: - resolution: {integrity: sha512-78/PXT1wlLLDgTzDs7sjq9hzz0vXD+zn+7wypEe4fXQxCmdmqfGsEPQxmiCSQI3ajFV91bVSsvNtrJRiW6nGng==} - engines: {node: '>=10'} - dependencies: - locate-path: 6.0.0 - path-exists: 4.0.0 - dev: true - - /findup-sync/2.0.0: - resolution: {integrity: sha512-vs+3unmJT45eczmcAZ6zMJtxN3l/QXeccaXQx5cu/MeJMhewVfoWZqibRkOxPnmoR59+Zy5hjabfQc6JLSah4g==} - engines: {node: '>= 0.10'} - dependencies: - detect-file: 1.0.0 - is-glob: 3.1.0 - micromatch: 3.1.10 - resolve-dir: 1.0.1 - transitivePeerDependencies: - - supports-color - dev: true - - /findup-sync/3.0.0: - resolution: {integrity: sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg==} - engines: {node: '>= 0.10'} - dependencies: - detect-file: 1.0.0 - is-glob: 4.0.3 - micromatch: 3.1.10 - resolve-dir: 1.0.1 - transitivePeerDependencies: - - supports-color - dev: true - - /fined/1.2.0: - resolution: {integrity: sha512-ZYDqPLGxDkDhDZBjZBb+oD1+j0rA4E0pXY50eplAAOPg2N/gUBSSk5IM1/QhPfyVo19lJ+CvXpqfvk+b2p/8Ng==} - engines: {node: '>= 0.10'} - dependencies: - expand-tilde: 2.0.2 - is-plain-object: 2.0.4 - object.defaults: 1.1.0 - object.pick: 1.3.0 - parse-filepath: 1.0.2 - dev: true - - /flagged-respawn/1.0.1: - resolution: {integrity: sha512-lNaHNVymajmk0OJMBn8fVUAU1BtDeKIqKoVhk4xAALB57aALg6b4W0MfJ/cUE0g9YBXy5XhSlPIpYIJ7HaY/3Q==} - engines: {node: '>= 0.10'} - dev: true - - /flat-cache/3.0.4: - resolution: {integrity: sha512-dm9s5Pw7Jc0GvMYbshN6zchCA9RgQlzzEZX3vylR9IqFfS8XciblUXOKfW6SiuJ0e13eDYZoZV5wdrev7P3Nwg==} - engines: {node: ^10.12.0 || >=12.0.0} - dependencies: - flatted: 3.2.7 - rimraf: 3.0.2 - dev: true - - /flatted/3.2.7: - resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==} - dev: true - - /flush-write-stream/1.1.1: - resolution: {integrity: sha512-3Z4XhFZ3992uIq0XOqb9AreonueSYphE6oYbpt5+3u06JWklbsPkNv3ZKkP9Bz/r+1MWCaMoSQ28P85+1Yc77w==} - dependencies: - inherits: 2.0.4 - readable-stream: 2.3.7 - dev: true - - /for-in/1.0.2: - resolution: {integrity: sha512-7EwmXrOjyL+ChxMhmG5lnW9MPt1aIeZEwKhQzoBUdTV0N3zuwWDZYVJatDvZ2OyzPUvdIAZDsCetk3coyMfcnQ==} - engines: {node: '>=0.10.0'} - dev: true - - /for-own/1.0.0: - resolution: {integrity: sha512-0OABksIGrxKK8K4kynWkQ7y1zounQxP+CWnyclVwj81KW3vlLlGUx57DKGcP/LH216GzqnstnPocF16Nxs0Ycg==} - engines: {node: '>=0.10.0'} - dependencies: - for-in: 1.0.2 - dev: true - - /forever-agent/0.6.1: - resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} - dev: true - - /form-data/2.3.3: - resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} - engines: {node: '>= 0.12'} - dependencies: - asynckit: 0.4.0 - combined-stream: 1.0.8 - mime-types: 2.1.35 - dev: true - - /fragment-cache/0.2.1: - resolution: {integrity: sha512-GMBAbW9antB8iZRHLoGw0b3HANt57diZYFO/HL1JGIC1MjKrdmhxvrJbupnVvpys0zsz7yBApXdQyfepKly2kA==} - engines: {node: '>=0.10.0'} - dependencies: - map-cache: 0.2.2 - dev: true - - /fs-extra/9.1.0: - resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} - engines: {node: '>=10'} - dependencies: - at-least-node: 1.0.0 - graceful-fs: 4.2.10 - jsonfile: 6.1.0 - universalify: 2.0.0 - dev: true - - /fs-minipass/1.2.7: - resolution: {integrity: sha512-GWSSJGFy4e9GUeCcbIkED+bgAoFyj7XF1mV8rma3QW4NIqX9Kyx79N/PF61H5udOV3aY1IaMLs6pGbH71nlCTA==} - dependencies: - minipass: 2.9.0 - dev: true - - /fs-minipass/2.1.0: - resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.4 - dev: true - - /fs-mkdirp-stream/1.0.0: - resolution: {integrity: sha512-+vSd9frUnapVC2RZYfL3FCB2p3g4TBhaUmrsWlSudsGdnxIuUvBB2QM1VZeBtc49QFwrp+wQLrDs3+xxDgI5gQ==} - engines: {node: '>= 0.10'} - dependencies: - graceful-fs: 4.2.10 - through2: 2.0.5 - dev: true - - /fs.realpath/1.0.0: - resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==} - dev: true - - /fsevents/1.2.13: - resolution: {integrity: sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==} - engines: {node: '>= 4.0'} - os: [darwin] - deprecated: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2. - requiresBuild: true - dependencies: - bindings: 1.5.0 - nan: 2.17.0 - dev: true - optional: true - - /function-bind/1.1.1: - resolution: {integrity: sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==} - dev: true - - /function.prototype.name/1.1.5: - resolution: {integrity: sha512-uN7m/BzVKQnCUF/iW8jYea67v++2u7m5UgENbHRtdDVclOUP+FMPlCNdmk0h/ysGyo2tavMJEDqJAkJdRa1vMA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - functions-have-names: 1.2.3 - dev: true - - /functional-red-black-tree/1.0.1: - resolution: {integrity: sha512-dsKNQNdj6xA3T+QlADDA7mOSlX0qiMINjn0cgr+eGHGsbSHzTabcIogz2+p/iqP1Xs6EP/sS2SbqH+brGTbq0g==} - dev: true - - /functions-have-names/1.2.3: - resolution: {integrity: sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==} - dev: true - - /gauge/2.7.4: - resolution: {integrity: sha512-14x4kjc6lkD3ltw589k0NrPD6cCNTD6CWoVUNpB85+DrtONoZn+Rug6xZU5RvSC4+TZPxA5AnBibQYAvZn41Hg==} - dependencies: - aproba: 1.2.0 - console-control-strings: 1.1.0 - has-unicode: 2.0.1 - object-assign: 4.1.1 - signal-exit: 3.0.7 - string-width: 1.0.2 - strip-ansi: 3.0.1 - wide-align: 1.1.5 - dev: true - - /gensync/1.0.0-beta.2: - resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==} - engines: {node: '>=6.9.0'} - dev: true - - /get-caller-file/1.0.3: - resolution: {integrity: sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==} - dev: true - - /get-caller-file/2.0.5: - resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==} - engines: {node: 6.* || 8.* || >= 10.*} - dev: true - - /get-intrinsic/1.1.3: - resolution: {integrity: sha512-QJVz1Tj7MS099PevUG5jvnt9tSkXN8K14dxQlikJuPt4uD9hHAHjLyLBiLR5zELelBdD9QNRAXZzsJx0WaDL9A==} - dependencies: - function-bind: 1.1.1 - has: 1.0.3 - has-symbols: 1.0.3 - dev: true - - /get-pkg-repo/4.2.1: - resolution: {integrity: sha512-2+QbHjFRfGB74v/pYWjd5OhU3TDIC2Gv/YKUTk/tCvAz0pkn/Mz6P3uByuBimLOcPvN2jYdScl3xGFSrx0jEcA==} - engines: {node: '>=6.9.0'} - hasBin: true - dependencies: - '@hutson/parse-repository-url': 3.0.2 - hosted-git-info: 4.1.0 - through2: 2.0.5 - yargs: 16.2.0 - dev: true - - /get-port/5.1.1: - resolution: {integrity: sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ==} - engines: {node: '>=8'} - dev: true - - /get-stdin/7.0.0: - resolution: {integrity: sha512-zRKcywvrXlXsA0v0i9Io4KDRaAw7+a1ZpjRwl9Wox8PFlVCCHra7E9c4kqXCoCM9nR5tBkaTTZRBoCm60bFqTQ==} - engines: {node: '>=8'} - dev: true - - /get-stdin/8.0.0: - resolution: {integrity: sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==} - engines: {node: '>=10'} - dev: true - - /get-stream/4.1.0: - resolution: {integrity: sha512-GMat4EJ5161kIy2HevLlr4luNjBgvmj413KaQA7jt4V8B4RDsfpHk7WQ9GVqfYyyx8OS/L66Kox+rJRNklLK7w==} - engines: {node: '>=6'} - dependencies: - pump: 3.0.0 - dev: true - - /get-stream/6.0.1: - resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} - engines: {node: '>=10'} - dev: true - - /get-symbol-description/1.0.0: - resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.1.3 - dev: true - - /get-value/2.0.6: - resolution: {integrity: sha512-Ln0UQDlxH1BapMu3GPtf7CuYNwRZf2gwCuPqbyG6pB8WfmFpzqcy4xtAaAMUhnNqjMKTiCPZG2oMT3YSx8U2NA==} - engines: {node: '>=0.10.0'} - dev: true - - /getpass/0.1.7: - resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} - dependencies: - assert-plus: 1.0.0 - dev: true - - /git-raw-commits/2.0.11: - resolution: {integrity: sha512-VnctFhw+xfj8Va1xtfEqCUD2XDrbAPSJx+hSrE5K7fGdjZruW7XV+QOrN7LF/RJyvspRiD2I0asWsxFp0ya26A==} - engines: {node: '>=10'} - hasBin: true - dependencies: - dargs: 7.0.0 - lodash: 4.17.21 - meow: 8.1.2 - split2: 3.2.2 - through2: 4.0.2 - dev: true - - /git-remote-origin-url/2.0.0: - resolution: {integrity: sha512-eU+GGrZgccNJcsDH5LkXR3PB9M958hxc7sbA8DFJjrv9j4L2P/eZfKhM+QD6wyzpiv+b1BpK0XrYCxkovtjSLw==} - engines: {node: '>=4'} - dependencies: - gitconfiglocal: 1.0.0 - pify: 2.3.0 - dev: true - - /git-semver-tags/4.1.1: - resolution: {integrity: sha512-OWyMt5zBe7xFs8vglMmhM9lRQzCWL3WjHtxNNfJTMngGym7pC1kh8sP6jevfydJ6LP3ZvGxfb6ABYgPUM0mtsA==} - engines: {node: '>=10'} - hasBin: true - dependencies: - meow: 8.1.2 - semver: 6.3.0 - dev: true - - /git-up/4.0.5: - resolution: {integrity: sha512-YUvVDg/vX3d0syBsk/CKUTib0srcQME0JyHkL5BaYdwLsiCslPWmDSi8PUMo9pXYjrryMcmsCoCgsTpSCJEQaA==} - dependencies: - is-ssh: 1.4.0 - parse-url: 6.0.5 - dev: true - - /git-url-parse/11.6.0: - resolution: {integrity: sha512-WWUxvJs5HsyHL6L08wOusa/IXYtMuCAhrMmnTjQPpBU0TTHyDhnOATNH3xNQz7YOQUsqIIPTGr4xiVti1Hsk5g==} - dependencies: - git-up: 4.0.5 - dev: true - - /gitconfiglocal/1.0.0: - resolution: {integrity: sha512-spLUXeTAVHxDtKsJc8FkFVgFtMdEN9qPGpL23VfSHx4fP4+Ds097IXLvymbnDH8FnmxX5Nr9bPw3A+AQ6mWEaQ==} - dependencies: - ini: 1.3.8 - dev: true - - /glob-parent/3.1.0: - resolution: {integrity: sha512-E8Ak/2+dZY6fnzlR7+ueWvhsH1SjHr4jjss4YS/h4py44jY9MhK/VFdaZJAWDz6BbL21KeteKxFSFpq8OS5gVA==} - dependencies: - is-glob: 3.1.0 - path-dirname: 1.0.2 - dev: true - - /glob-parent/5.1.2: - resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==} - engines: {node: '>= 6'} - dependencies: - is-glob: 4.0.3 - dev: true - - /glob-stream/6.1.0: - resolution: {integrity: sha512-uMbLGAP3S2aDOHUDfdoYcdIePUCfysbAd0IAoWVZbeGU/oNQ8asHVSshLDJUPWxfzj8zsCG7/XeHPHTtow0nsw==} - engines: {node: '>= 0.10'} - dependencies: - extend: 3.0.2 - glob: 7.2.3 - glob-parent: 3.1.0 - is-negated-glob: 1.0.0 - ordered-read-streams: 1.0.1 - pumpify: 1.5.1 - readable-stream: 2.3.7 - remove-trailing-separator: 1.1.0 - to-absolute-glob: 2.0.2 - unique-stream: 2.3.1 - dev: true - - /glob-watcher/5.0.5: - resolution: {integrity: sha512-zOZgGGEHPklZNjZQaZ9f41i7F2YwE+tS5ZHrDhbBCk3stwahn5vQxnFmBJZHoYdusR6R1bLSXeGUy/BhctwKzw==} - engines: {node: '>= 0.10'} - dependencies: - anymatch: 2.0.0 - async-done: 1.3.2 - chokidar: 2.1.8 - is-negated-glob: 1.0.0 - just-debounce: 1.1.0 - normalize-path: 3.0.0 - object.defaults: 1.1.0 - transitivePeerDependencies: - - supports-color - dev: true - - /glob/7.2.3: - resolution: {integrity: sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==} - dependencies: - fs.realpath: 1.0.0 - inflight: 1.0.6 - inherits: 2.0.4 - minimatch: 3.1.2 - once: 1.4.0 - path-is-absolute: 1.0.1 - dev: true - - /global-dirs/0.1.1: - resolution: {integrity: sha512-NknMLn7F2J7aflwFOlGdNIuCDpN3VGoSoB+aap3KABFWbHVn1TCgFC+np23J8W2BiZbjfEw3BFBycSMv1AFblg==} - engines: {node: '>=4'} - dependencies: - ini: 1.3.8 - dev: true - - /global-modules/1.0.0: - resolution: {integrity: sha512-sKzpEkf11GpOFuw0Zzjzmt4B4UZwjOcG757PPvrfhxcLFbq0wpsgpOqxpxtxFiCG4DtG93M6XRVbF2oGdev7bg==} - engines: {node: '>=0.10.0'} - dependencies: - global-prefix: 1.0.2 - is-windows: 1.0.2 - resolve-dir: 1.0.1 - dev: true - - /global-modules/2.0.0: - resolution: {integrity: sha512-NGbfmJBp9x8IxyJSd1P+otYK8vonoJactOogrVfFRIAEY1ukil8RSKDz2Yo7wh1oihl51l/r6W4epkeKJHqL8A==} - engines: {node: '>=6'} - dependencies: - global-prefix: 3.0.0 - dev: true - - /global-prefix/1.0.2: - resolution: {integrity: sha512-5lsx1NUDHtSjfg0eHlmYvZKv8/nVqX4ckFbM+FrGcQ+04KWcWFo9P5MxPZYSzUvyzmdTbI7Eix8Q4IbELDqzKg==} - engines: {node: '>=0.10.0'} - dependencies: - expand-tilde: 2.0.2 - homedir-polyfill: 1.0.3 - ini: 1.3.8 - is-windows: 1.0.2 - which: 1.3.1 - dev: true - - /global-prefix/3.0.0: - resolution: {integrity: sha512-awConJSVCHVGND6x3tmMaKcQvwXLhjdkmomy2W+Goaui8YPgYgXJZewhg3fWC+DlfqqQuWg8AwqjGTD2nAPVWg==} - engines: {node: '>=6'} - dependencies: - ini: 1.3.8 - kind-of: 6.0.3 - which: 1.3.1 - dev: true - - /globals/11.12.0: - resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==} - engines: {node: '>=4'} - dev: true - - /globals/13.17.0: - resolution: {integrity: sha512-1C+6nQRb1GwGMKm2dH/E7enFAMxGTmGI7/dEdhy/DNelv85w9B72t3uc5frtMNXIbzrarJJ/lTCjcaZwbLJmyw==} - engines: {node: '>=8'} - dependencies: - type-fest: 0.20.2 - dev: true - - /globby/11.1.0: - resolution: {integrity: sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==} - engines: {node: '>=10'} - dependencies: - array-union: 2.1.0 - dir-glob: 3.0.1 - fast-glob: 3.2.12 - ignore: 5.2.0 - merge2: 1.4.1 - slash: 3.0.0 - dev: true - - /globjoin/0.1.4: - resolution: {integrity: sha512-xYfnw62CKG8nLkZBfWbhWwDw02CHty86jfPcc2cr3ZfeuK9ysoVPPEUxf21bAD/rWAgk52SuBrLJlefNy8mvFg==} - dev: true - - /glogg/1.0.2: - resolution: {integrity: sha512-5mwUoSuBk44Y4EshyiqcH95ZntbDdTQqA3QYSrxmzj28Ai0vXBGMH1ApSANH14j2sIRtqCEyg6PfsuP7ElOEDA==} - engines: {node: '>= 0.10'} - dependencies: - sparkles: 1.0.1 - dev: true - - /gonzales-pe/4.3.0: - resolution: {integrity: sha512-otgSPpUmdWJ43VXyiNgEYE4luzHCL2pz4wQ0OnDluC6Eg4Ko3Vexy/SrSynglw/eR+OhkzmqFCZa/OFa/RgAOQ==} - engines: {node: '>=0.6.0'} - hasBin: true - dependencies: - minimist: 1.2.7 - dev: true - - /graceful-fs/4.2.10: - resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} - dev: true - - /gulp-cli/2.3.0: - resolution: {integrity: sha512-zzGBl5fHo0EKSXsHzjspp3y5CONegCm8ErO5Qh0UzFzk2y4tMvzLWhoDokADbarfZRL2pGpRp7yt6gfJX4ph7A==} - engines: {node: '>= 0.10'} - hasBin: true - dependencies: - ansi-colors: 1.1.0 - archy: 1.0.0 - array-sort: 1.0.0 - color-support: 1.1.3 - concat-stream: 1.6.2 - copy-props: 2.0.5 - fancy-log: 1.3.3 - gulplog: 1.0.0 - interpret: 1.4.0 - isobject: 3.0.1 - liftoff: 3.1.0 - matchdep: 2.0.0 - mute-stdout: 1.0.1 - pretty-hrtime: 1.0.3 - replace-homedir: 1.0.0 - semver-greatest-satisfied-range: 1.1.0 - v8flags: 3.2.0 - yargs: 7.1.2 - transitivePeerDependencies: - - supports-color - dev: true - - /gulp/4.0.2: - resolution: {integrity: sha512-dvEs27SCZt2ibF29xYgmnwwCYZxdxhQ/+LFWlbAW8y7jt68L/65402Lz3+CKy0Ov4rOs+NERmDq7YlZaDqUIfA==} - engines: {node: '>= 0.10'} - hasBin: true - dependencies: - glob-watcher: 5.0.5 - gulp-cli: 2.3.0 - undertaker: 1.3.0 - vinyl-fs: 3.0.3 - transitivePeerDependencies: - - supports-color - dev: true - - /gulplog/1.0.0: - resolution: {integrity: sha512-hm6N8nrm3Y08jXie48jsC55eCZz9mnb4OirAStEk2deqeyhXU3C1otDVh+ccttMuc1sBi6RX6ZJ720hs9RCvgw==} - engines: {node: '>= 0.10'} - dependencies: - glogg: 1.0.2 - dev: true - - /handlebars/4.7.7: - resolution: {integrity: sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA==} - engines: {node: '>=0.4.7'} - hasBin: true - dependencies: - minimist: 1.2.7 - neo-async: 2.6.2 - source-map: 0.6.1 - wordwrap: 1.0.0 - optionalDependencies: - uglify-js: 3.17.4 - dev: true - - /har-schema/2.0.0: - resolution: {integrity: sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==} - engines: {node: '>=4'} - dev: true - - /har-validator/5.1.5: - resolution: {integrity: sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==} - engines: {node: '>=6'} - deprecated: this library is no longer supported - dependencies: - ajv: 6.12.6 - har-schema: 2.0.0 - dev: true - - /hard-rejection/2.1.0: - resolution: {integrity: sha512-VIZB+ibDhx7ObhAe7OVtoEbuP4h/MuOTHJ+J8h/eBXotJYl0fBgR72xDFCKgIh22OJZIOVNxBMWuhAr10r8HdA==} - engines: {node: '>=6'} - dev: true - - /has-bigints/1.0.2: - resolution: {integrity: sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==} - dev: true - - /has-flag/3.0.0: - resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==} - engines: {node: '>=4'} - dev: true - - /has-flag/4.0.0: - resolution: {integrity: sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==} - engines: {node: '>=8'} - dev: true - - /has-property-descriptors/1.0.0: - resolution: {integrity: sha512-62DVLZGoiEBDHQyqG4w9xCuZ7eJEwNmJRWw2VY84Oedb7WFcA27fiEVe8oUQx9hAUJ4ekurquucTGwsyO1XGdQ==} - dependencies: - get-intrinsic: 1.1.3 - dev: true - - /has-symbols/1.0.3: - resolution: {integrity: sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==} - engines: {node: '>= 0.4'} - dev: true - - /has-tostringtag/1.0.0: - resolution: {integrity: sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==} - engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.0.3 - dev: true - - /has-unicode/2.0.1: - resolution: {integrity: sha512-8Rf9Y83NBReMnx0gFzA8JImQACstCYWUplepDa9xprwwtmgEZUF0h/i5xSA625zB/I37EtrswSST6OXxwaaIJQ==} - dev: true - - /has-value/0.3.1: - resolution: {integrity: sha512-gpG936j8/MzaeID5Yif+577c17TxaDmhuyVgSwtnL/q8UUTySg8Mecb+8Cf1otgLoD7DDH75axp86ER7LFsf3Q==} - engines: {node: '>=0.10.0'} - dependencies: - get-value: 2.0.6 - has-values: 0.1.4 - isobject: 2.1.0 - dev: true - - /has-value/1.0.0: - resolution: {integrity: sha512-IBXk4GTsLYdQ7Rvt+GRBrFSVEkmuOUy4re0Xjd9kJSUQpnTrWR4/y9RpfexN9vkAPMFuQoeWKwqzPozRTlasGw==} - engines: {node: '>=0.10.0'} - dependencies: - get-value: 2.0.6 - has-values: 1.0.0 - isobject: 3.0.1 - dev: true - - /has-values/0.1.4: - resolution: {integrity: sha512-J8S0cEdWuQbqD9//tlZxiMuMNmxB8PlEwvYwuxsTmR1G5RXUePEX/SJn7aD0GMLieuZYSwNH0cQuJGwnYunXRQ==} - engines: {node: '>=0.10.0'} - dev: true - - /has-values/1.0.0: - resolution: {integrity: sha512-ODYZC64uqzmtfGMEAX/FvZiRyWLpAC3vYnNunURUnkGVTS+mI0smVsWaPydRBsE3g+ok7h960jChO8mFcWlHaQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-number: 3.0.0 - kind-of: 4.0.0 - dev: true - - /has/1.0.3: - resolution: {integrity: sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==} - engines: {node: '>= 0.4.0'} - dependencies: - function-bind: 1.1.1 - dev: true - - /homedir-polyfill/1.0.3: - resolution: {integrity: sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==} - engines: {node: '>=0.10.0'} - dependencies: - parse-passwd: 1.0.0 - dev: true - - /hosted-git-info/2.8.9: - resolution: {integrity: sha512-mxIDAb9Lsm6DoOJ7xH+5+X4y1LU/4Hi50L9C5sIswK3JzULS4bwk1FvjdBgvYR4bzT4tuUQiC15FE2f5HbLvYw==} - dev: true - - /hosted-git-info/4.1.0: - resolution: {integrity: sha512-kyCuEOWjJqZuDbRHzL8V93NzQhwIB71oFWSyzVo+KPZI+pnQPPxucdkrOZvkLRnrf5URsQM+IJ09Dw29cRALIA==} - engines: {node: '>=10'} - dependencies: - lru-cache: 6.0.0 - dev: true - - /html-tags/3.2.0: - resolution: {integrity: sha512-vy7ClnArOZwCnqZgvv+ddgHgJiAFXe3Ge9ML5/mBctVJoUoYPCdxVucOywjDARn6CVoh3dRSFdPHy2sX80L0Wg==} - engines: {node: '>=8'} - dev: true - - /htmlparser2/3.10.1: - resolution: {integrity: sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==} - dependencies: - domelementtype: 1.3.1 - domhandler: 2.4.2 - domutils: 1.7.0 - entities: 1.1.2 - inherits: 2.0.4 - readable-stream: 3.6.0 - dev: true - - /http-cache-semantics/4.1.0: - resolution: {integrity: sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==} - dev: true - - /http-proxy-agent/4.0.1: - resolution: {integrity: sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==} - engines: {node: '>= 6'} - dependencies: - '@tootallnate/once': 1.1.2 - agent-base: 6.0.2 - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: true - - /http-signature/1.2.0: - resolution: {integrity: sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==} - engines: {node: '>=0.8', npm: '>=1.3.7'} - dependencies: - assert-plus: 1.0.0 - jsprim: 1.4.2 - sshpk: 1.17.0 - dev: true - - /https-proxy-agent/5.0.1: - resolution: {integrity: sha512-dFcAjpTQFgoLMzC2VwU+C/CbS7uRL0lWmxDITmqm7C+7F0Odmj6s9l6alZc6AELXhrnggM2CeWSXHGOdX2YtwA==} - engines: {node: '>= 6'} - dependencies: - agent-base: 6.0.2 - debug: 4.3.4 - transitivePeerDependencies: - - supports-color - dev: true - - /human-signals/2.1.0: - resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} - engines: {node: '>=10.17.0'} - dev: true - - /humanize-ms/1.2.1: - resolution: {integrity: sha512-Fl70vYtsAFb/C06PTS9dZBo7ihau+Tu/DNCk/OyHhea07S+aeMWpFFkUaXRa8fI+ScZbEI8dfSxwY7gxZ9SAVQ==} - dependencies: - ms: 2.1.3 - dev: true - - /husky/3.1.0: - resolution: {integrity: sha512-FJkPoHHB+6s4a+jwPqBudBDvYZsoQW5/HBuMSehC8qDiCe50kpcxeqFoDSlow+9I6wg47YxBoT3WxaURlrDIIQ==} - engines: {node: '>=8.6.0'} - hasBin: true - requiresBuild: true - dependencies: - chalk: 2.4.2 - ci-info: 2.0.0 - cosmiconfig: 5.2.1 - execa: 1.0.0 - get-stdin: 7.0.0 - opencollective-postinstall: 2.0.3 - pkg-dir: 4.2.0 - please-upgrade-node: 3.2.0 - read-pkg: 5.2.0 - run-node: 1.0.0 - slash: 3.0.0 - dev: true - - /husky/7.0.4: - resolution: {integrity: sha512-vbaCKN2QLtP/vD4yvs6iz6hBEo6wkSzs8HpRah1Z6aGmF2KW5PdYuAd7uX5a+OyBZHBhd+TFLqgjUgytQr4RvQ==} - engines: {node: '>=12'} - hasBin: true - dev: true - - /iconv-lite/0.4.24: - resolution: {integrity: sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==} - engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - dev: true - - /iconv-lite/0.6.3: - resolution: {integrity: sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==} - engines: {node: '>=0.10.0'} - dependencies: - safer-buffer: 2.1.2 - dev: true - optional: true - - /ieee754/1.2.1: - resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} - dev: true - - /ignore-walk/3.0.4: - resolution: {integrity: sha512-PY6Ii8o1jMRA1z4F2hRkH/xN59ox43DavKvD3oDpfurRlOJyAHpifIwpbdv1n4jt4ov0jSpw3kQ4GhJnpBL6WQ==} - dependencies: - minimatch: 3.1.2 - dev: true - - /ignore/4.0.6: - resolution: {integrity: sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==} - engines: {node: '>= 4'} - dev: true - - /ignore/5.2.0: - resolution: {integrity: sha512-CmxgYGiEPCLhfLnpPp1MoRmifwEIOgjcHXxOBjv7mY96c+eWScsOP9c112ZyLdWHi0FxHjI+4uVhKYp/gcdRmQ==} - engines: {node: '>= 4'} - dev: true - - /import-fresh/2.0.0: - resolution: {integrity: sha512-eZ5H8rcgYazHbKC3PG4ClHNykCSxtAhxSSEM+2mb+7evD2CKF5V7c0dNum7AdpDh0ZdICwZY9sRSn8f+KH96sg==} - engines: {node: '>=4'} - dependencies: - caller-path: 2.0.0 - resolve-from: 3.0.0 - dev: true - - /import-fresh/3.3.0: - resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==} - engines: {node: '>=6'} - dependencies: - parent-module: 1.0.1 - resolve-from: 4.0.0 - dev: true - - /import-lazy/4.0.0: - resolution: {integrity: sha512-rKtvo6a868b5Hu3heneU+L4yEQ4jYKLtjpnPeUdK7h0yzXGmyBTypknlkCvHFBqfX9YlorEiMM6Dnq/5atfHkw==} - engines: {node: '>=8'} - dev: true - - /import-local/3.1.0: - resolution: {integrity: sha512-ASB07uLtnDs1o6EHjKpX34BKYDSqnFerfTOJL2HvMqF70LnxpjkzDB8J44oT9pu4AMPkQwf8jl6szgvNd2tRIg==} - engines: {node: '>=8'} - hasBin: true - dependencies: - pkg-dir: 4.2.0 - resolve-cwd: 3.0.0 - dev: true - - /imurmurhash/0.1.4: - resolution: {integrity: sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA==} - engines: {node: '>=0.8.19'} - dev: true - - /indent-string/4.0.0: - resolution: {integrity: sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==} - engines: {node: '>=8'} - dev: true - - /infer-owner/1.0.4: - resolution: {integrity: sha512-IClj+Xz94+d7irH5qRyfJonOdfTzuDaifE6ZPWfx0N0+/ATZCbuTPq2prFl526urkQd90WyUKIh1DfBQ2hMz9A==} - dev: true - - /inflight/1.0.6: - resolution: {integrity: sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==} - dependencies: - once: 1.4.0 - wrappy: 1.0.2 - dev: true - - /inherits/2.0.4: - resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==} - dev: true - - /ini/1.3.8: - resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==} - dev: true - - /init-package-json/2.0.5: - resolution: {integrity: sha512-u1uGAtEFu3VA6HNl/yUWw57jmKEMx8SKOxHhxjGnOFUiIlFnohKDFg4ZrPpv9wWqk44nDxGJAtqjdQFm+9XXQA==} - engines: {node: '>=10'} - dependencies: - npm-package-arg: 8.1.5 - promzard: 0.3.0 - read: 1.0.7 - read-package-json: 4.1.2 - semver: 7.3.8 - validate-npm-package-license: 3.0.4 - validate-npm-package-name: 3.0.0 - dev: true - - /inquirer/7.3.3: - resolution: {integrity: sha512-JG3eIAj5V9CwcGvuOmoo6LB9kbAYT8HXffUl6memuszlwDC/qvFAJw49XJ5NROSFNPxp3iQg1GqkFhaY/CR0IA==} - engines: {node: '>=8.0.0'} - dependencies: - ansi-escapes: 4.3.2 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-width: 3.0.0 - external-editor: 3.1.0 - figures: 3.2.0 - lodash: 4.17.21 - mute-stream: 0.0.8 - run-async: 2.4.1 - rxjs: 6.6.7 - string-width: 4.2.3 - strip-ansi: 6.0.1 - through: 2.3.8 - dev: true - - /internal-slot/1.0.3: - resolution: {integrity: sha512-O0DB1JC/sPyZl7cIo78n5dR7eUSwwpYPiXRhTzNxZVAMUuB8vlnRFyLxdrVToks6XPLVnFfbzaVd5WLjhgg+vA==} - engines: {node: '>= 0.4'} - dependencies: - get-intrinsic: 1.1.3 - has: 1.0.3 - side-channel: 1.0.4 - dev: true - - /interpret/1.4.0: - resolution: {integrity: sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA==} - engines: {node: '>= 0.10'} - dev: true - - /invert-kv/1.0.0: - resolution: {integrity: sha512-xgs2NH9AE66ucSq4cNG1nhSFghr5l6tdL15Pk+jl46bmmBapgoaY/AacXyaDznAqmGL99TiLSQgO/XazFSKYeQ==} - engines: {node: '>=0.10.0'} - dev: true - - /ip/2.0.0: - resolution: {integrity: sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==} - dev: true - - /is-absolute/1.0.0: - resolution: {integrity: sha512-dOWoqflvcydARa360Gvv18DZ/gRuHKi2NU/wU5X1ZFzdYfH29nkiNZsF3mp4OJ3H4yo9Mx8A/uAGNzpzPN3yBA==} - engines: {node: '>=0.10.0'} - dependencies: - is-relative: 1.0.0 - is-windows: 1.0.2 - dev: true - - /is-accessor-descriptor/0.1.6: - resolution: {integrity: sha512-e1BM1qnDbMRG3ll2U9dSK0UMHuWOs3pY3AtcFsmvwPtKL3MML/Q86i+GilLfvqEs4GW+ExB91tQ3Ig9noDIZ+A==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /is-accessor-descriptor/1.0.0: - resolution: {integrity: sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 6.0.3 - dev: true - - /is-alphabetical/1.0.4: - resolution: {integrity: sha512-DwzsA04LQ10FHTZuL0/grVDk4rFoVH1pjAToYwBrHSxcrBIGQuXrQMtD5U1b0U2XVgKZCTLLP8u2Qxqhy3l2Vg==} - dev: true - - /is-alphanumerical/1.0.4: - resolution: {integrity: sha512-UzoZUr+XfVz3t3v4KyGEniVL9BDRoQtY7tOyrRybkVNjDFWyo1yhXNGrrBTQxp3ib9BLAWs7k2YKBQsFRkZG9A==} - dependencies: - is-alphabetical: 1.0.4 - is-decimal: 1.0.4 - dev: true - - /is-arrayish/0.2.1: - resolution: {integrity: sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==} - dev: true - - /is-bigint/1.0.4: - resolution: {integrity: sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==} - dependencies: - has-bigints: 1.0.2 - dev: true - - /is-binary-path/1.0.1: - resolution: {integrity: sha512-9fRVlXc0uCxEDj1nQzaWONSpbTfx0FmJfzHF7pwlI8DkWGoHBBea4Pg5Ky0ojwwxQmnSifgbKkI06Qv0Ljgj+Q==} - engines: {node: '>=0.10.0'} - dependencies: - binary-extensions: 1.13.1 - dev: true - - /is-boolean-object/1.1.2: - resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 - dev: true - - /is-buffer/1.1.6: - resolution: {integrity: sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==} - dev: true - - /is-buffer/2.0.5: - resolution: {integrity: sha512-i2R6zNFDwgEHJyQUtJEk0XFi1i0dPFn/oqjK3/vPCcDeJvW5NQ83V8QbicfF1SupOaB0h8ntgBC2YiE7dfyctQ==} - engines: {node: '>=4'} - dev: true - - /is-callable/1.2.7: - resolution: {integrity: sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==} - engines: {node: '>= 0.4'} - dev: true - - /is-ci/2.0.0: - resolution: {integrity: sha512-YfJT7rkpQB0updsdHLGWrvhBJfcfzNNawYDNIyQXJz0IViGf75O8EBPKSdvw2rF+LGCsX4FZ8tcr3b19LcZq4w==} - hasBin: true - dependencies: - ci-info: 2.0.0 - dev: true - - /is-core-module/2.11.0: - resolution: {integrity: sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==} - dependencies: - has: 1.0.3 - dev: true - - /is-data-descriptor/0.1.4: - resolution: {integrity: sha512-+w9D5ulSoBNlmw9OHn3U2v51SyoCd0he+bB3xMl62oijhrspxowjU+AIcDY0N3iEJbUEkB15IlMASQsxYigvXg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /is-data-descriptor/1.0.0: - resolution: {integrity: sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 6.0.3 - dev: true - - /is-date-object/1.0.5: - resolution: {integrity: sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - - /is-decimal/1.0.4: - resolution: {integrity: sha512-RGdriMmQQvZ2aqaQq3awNA6dCGtKpiDFcOzrTWrDAT2MiWrKQVPmxLGHl7Y2nNu6led0kEyoX0enY0qXYsv9zw==} - dev: true - - /is-descriptor/0.1.6: - resolution: {integrity: sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==} - engines: {node: '>=0.10.0'} - dependencies: - is-accessor-descriptor: 0.1.6 - is-data-descriptor: 0.1.4 - kind-of: 5.1.0 - dev: true - - /is-descriptor/1.0.2: - resolution: {integrity: sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==} - engines: {node: '>=0.10.0'} - dependencies: - is-accessor-descriptor: 1.0.0 - is-data-descriptor: 1.0.0 - kind-of: 6.0.3 - dev: true - - /is-directory/0.3.1: - resolution: {integrity: sha512-yVChGzahRFvbkscn2MlwGismPO12i9+znNruC5gVEntG3qu0xQMzsGg/JFbrsqDOHtHFPci+V5aP5T9I+yeKqw==} - engines: {node: '>=0.10.0'} - dev: true - - /is-docker/2.2.1: - resolution: {integrity: sha512-F+i2BKsFrH66iaUFc0woD8sLy8getkwTwtOBjvs56Cx4CgJDeKQeqfz8wAYiSb8JOprWhHH5p77PbmYCvvUuXQ==} - engines: {node: '>=8'} - hasBin: true - dev: true - - /is-extendable/0.1.1: - resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==} - engines: {node: '>=0.10.0'} - dev: true - - /is-extendable/1.0.1: - resolution: {integrity: sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==} - engines: {node: '>=0.10.0'} - dependencies: - is-plain-object: 2.0.4 - dev: true - - /is-extglob/2.1.1: - resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} - engines: {node: '>=0.10.0'} - dev: true - - /is-fullwidth-code-point/1.0.0: - resolution: {integrity: sha512-1pqUqRjkhPJ9miNq9SwMfdvi6lBJcd6eFxvfaivQhaH3SgisfiuudvFntdKOmxuee/77l+FPjKrQjWvmPjWrRw==} - engines: {node: '>=0.10.0'} - dependencies: - number-is-nan: 1.0.1 - dev: true - - /is-fullwidth-code-point/3.0.0: - resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} - engines: {node: '>=8'} - dev: true - - /is-glob/3.1.0: - resolution: {integrity: sha512-UFpDDrPgM6qpnFNI+rh/p3bUaq9hKLZN8bMUWzxmcnZVS3omf4IPK+BrewlnWjO1WmUsMYuSjKh4UJuV4+Lqmw==} - engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - dev: true - - /is-glob/4.0.3: - resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==} - engines: {node: '>=0.10.0'} - dependencies: - is-extglob: 2.1.1 - dev: true - - /is-hexadecimal/1.0.4: - resolution: {integrity: sha512-gyPJuv83bHMpocVYoqof5VDiZveEoGoFL8m3BXNb2VW8Xs+rz9kqO8LOQ5DH6EsuvilT1ApazU0pyl+ytbPtlw==} - dev: true - - /is-interactive/1.0.0: - resolution: {integrity: sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w==} - engines: {node: '>=8'} - dev: true - - /is-lambda/1.0.1: - resolution: {integrity: sha512-z7CMFGNrENq5iFB9Bqo64Xk6Y9sg+epq1myIcdHaGnbMTYOxvzsEtdYqQUylB7LxfkvgrrjP32T6Ywciio9UIQ==} - dev: true - - /is-negated-glob/1.0.0: - resolution: {integrity: sha512-czXVVn/QEmgvej1f50BZ648vUI+em0xqMq2Sn+QncCLN4zj1UAxlT+kw/6ggQTOaZPd1HqKQGEqbpQVtJucWug==} - engines: {node: '>=0.10.0'} - dev: true - - /is-negative-zero/2.0.2: - resolution: {integrity: sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==} - engines: {node: '>= 0.4'} - dev: true - - /is-number-object/1.0.7: - resolution: {integrity: sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - - /is-number/3.0.0: - resolution: {integrity: sha512-4cboCqIpliH+mAvFNegjZQ4kgKc3ZUhQVr3HvWbSh5q3WH2v82ct+T2Y1hdU5Gdtorx/cLifQjqCbL7bpznLTg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /is-number/4.0.0: - resolution: {integrity: sha512-rSklcAIlf1OmFdyAqbnWTLVelsQ58uvZ66S/ZyawjWqIviTWCjg2PzVGw8WUA+nNuPTqb4wgA+NszrJ+08LlgQ==} - engines: {node: '>=0.10.0'} - dev: true - - /is-number/7.0.0: - resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} - engines: {node: '>=0.12.0'} - dev: true - - /is-obj/2.0.0: - resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} - engines: {node: '>=8'} - dev: true - - /is-path-cwd/2.2.0: - resolution: {integrity: sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==} - engines: {node: '>=6'} - dev: true - - /is-path-inside/3.0.3: - resolution: {integrity: sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==} - engines: {node: '>=8'} - dev: true - - /is-plain-obj/1.1.0: - resolution: {integrity: sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==} - engines: {node: '>=0.10.0'} - dev: true - - /is-plain-obj/2.1.0: - resolution: {integrity: sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==} - engines: {node: '>=8'} - dev: true - - /is-plain-object/2.0.4: - resolution: {integrity: sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: true - - /is-plain-object/5.0.0: - resolution: {integrity: sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q==} - engines: {node: '>=0.10.0'} - dev: true - - /is-regex/1.1.4: - resolution: {integrity: sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - has-tostringtag: 1.0.0 - dev: true - - /is-regexp/2.1.0: - resolution: {integrity: sha512-OZ4IlER3zmRIoB9AqNhEggVxqIH4ofDns5nRrPS6yQxXE1TPCUpFznBfRQmQa8uC+pXqjMnukiJBxCisIxiLGA==} - engines: {node: '>=6'} - dev: true - - /is-relative/1.0.0: - resolution: {integrity: sha512-Kw/ReK0iqwKeu0MITLFuj0jbPAmEiOsIwyIXvvbfa6QfmN9pkD1M+8pdk7Rl/dTKbH34/XBFMbgD4iMJhLQbGA==} - engines: {node: '>=0.10.0'} - dependencies: - is-unc-path: 1.0.0 - dev: true - - /is-shared-array-buffer/1.0.2: - resolution: {integrity: sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==} - dependencies: - call-bind: 1.0.2 - dev: true - - /is-ssh/1.4.0: - resolution: {integrity: sha512-x7+VxdxOdlV3CYpjvRLBv5Lo9OJerlYanjwFrPR9fuGPjCiNiCzFgAWpiLAohSbsnH4ZAys3SBh+hq5rJosxUQ==} - dependencies: - protocols: 2.0.1 - dev: true - - /is-stream/1.1.0: - resolution: {integrity: sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==} - engines: {node: '>=0.10.0'} - dev: true - - /is-stream/2.0.1: - resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} - engines: {node: '>=8'} - dev: true - - /is-string/1.0.7: - resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} - engines: {node: '>= 0.4'} - dependencies: - has-tostringtag: 1.0.0 - dev: true - - /is-symbol/1.0.4: - resolution: {integrity: sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==} - engines: {node: '>= 0.4'} - dependencies: - has-symbols: 1.0.3 - dev: true - - /is-text-path/1.0.1: - resolution: {integrity: sha512-xFuJpne9oFz5qDaodwmmG08e3CawH/2ZV8Qqza1Ko7Sk8POWbkRdwIoAWVhqvq0XeUzANEhKo2n0IXUGBm7A/w==} - engines: {node: '>=0.10.0'} - dependencies: - text-extensions: 1.9.0 - dev: true - - /is-typedarray/1.0.0: - resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} - dev: true - - /is-unc-path/1.0.0: - resolution: {integrity: sha512-mrGpVd0fs7WWLfVsStvgF6iEJnbjDFZh9/emhRDcGWTduTfNHd9CHeUwH3gYIjdbwo4On6hunkztwOaAw0yllQ==} - engines: {node: '>=0.10.0'} - dependencies: - unc-path-regex: 0.1.2 - dev: true - - /is-unicode-supported/0.1.0: - resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} - engines: {node: '>=10'} - dev: true - - /is-utf8/0.2.1: - resolution: {integrity: sha512-rMYPYvCzsXywIsldgLaSoPlw5PfoB/ssr7hY4pLfcodrA5M/eArza1a9VmTiNIBNMjOGr1Ow9mTyU2o69U6U9Q==} - dev: true - - /is-valid-glob/1.0.0: - resolution: {integrity: sha512-AhiROmoEFDSsjx8hW+5sGwgKVIORcXnrlAx/R0ZSeaPw70Vw0CqkGBBhHGL58Uox2eXnU1AnvXJl1XlyedO5bA==} - engines: {node: '>=0.10.0'} - dev: true - - /is-weakref/1.0.2: - resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} - dependencies: - call-bind: 1.0.2 - dev: true - - /is-windows/1.0.2: - resolution: {integrity: sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==} - engines: {node: '>=0.10.0'} - dev: true - - /isarray/1.0.0: - resolution: {integrity: sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==} - dev: true - - /isexe/2.0.0: - resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true - - /isobject/2.1.0: - resolution: {integrity: sha512-+OUdGJlgjOBZDfxnDjYYG6zp487z0JGNQq3cYQYg5f5hKR+syHMsaztzGeml/4kGG55CSpKSpWTY+jYGgsHLgA==} - engines: {node: '>=0.10.0'} - dependencies: - isarray: 1.0.0 - dev: true - - /isobject/3.0.1: - resolution: {integrity: sha512-WhB9zCku7EGTj/HQQRz5aUQEUeoQZH2bWcltRErOpymJ4boYE6wL9Tbr23krRPSZ+C5zqNSrSw+Cc7sZZ4b7vg==} - engines: {node: '>=0.10.0'} - dev: true - - /isstream/0.1.2: - resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} - dev: true - - /jake/10.8.5: - resolution: {integrity: sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==} - engines: {node: '>=10'} - hasBin: true - dependencies: - async: 3.2.4 - chalk: 4.1.2 - filelist: 1.0.4 - minimatch: 3.1.2 - dev: true - - /js-tokens/4.0.0: - resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==} - dev: true - - /js-yaml/3.14.1: - resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==} - hasBin: true - dependencies: - argparse: 1.0.10 - esprima: 4.0.1 - dev: true - - /jsbn/0.1.1: - resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} - dev: true - - /jsdoc-type-pratt-parser/2.2.5: - resolution: {integrity: sha512-2a6eRxSxp1BW040hFvaJxhsCMI9lT8QB8t14t+NY5tC5rckIR0U9cr2tjOeaFirmEOy6MHvmJnY7zTBHq431Lw==} - engines: {node: '>=12.0.0'} - dev: true - - /jsesc/2.5.2: - resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /json-parse-better-errors/1.0.2: - resolution: {integrity: sha512-mrqyZKfX5EhL7hvqcV6WG1yYjnjeuYDzDhhcAAUrq8Po85NBQBJP+ZDUT75qZQ98IkUoBqdkExkukOU7Ts2wrw==} - dev: true - - /json-parse-even-better-errors/2.3.1: - resolution: {integrity: sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==} - dev: true - - /json-schema-traverse/0.4.1: - resolution: {integrity: sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==} - dev: true - - /json-schema-traverse/1.0.0: - resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} - dev: true - - /json-schema/0.4.0: - resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} - dev: true - - /json-stable-stringify-without-jsonify/1.0.1: - resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==} - dev: true - - /json-stringify-safe/5.0.1: - resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} - dev: true - - /json5/1.0.1: - resolution: {integrity: sha512-aKS4WQjPenRxiQsC93MNfjx+nbF4PAdYzmd/1JIj8HYzqfbu86beTuNgXDzPknWk0n0uARlyewZo4s++ES36Ow==} - hasBin: true - dependencies: - minimist: 1.2.7 - dev: true - - /json5/2.2.1: - resolution: {integrity: sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==} - engines: {node: '>=6'} - hasBin: true - dev: true - - /jsonfile/6.1.0: - resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} - dependencies: - universalify: 2.0.0 - optionalDependencies: - graceful-fs: 4.2.10 - dev: true - - /jsonparse/1.3.1: - resolution: {integrity: sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg==} - engines: {'0': node >= 0.2.0} - dev: true - - /jsprim/1.4.2: - resolution: {integrity: sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==} - engines: {node: '>=0.6.0'} - dependencies: - assert-plus: 1.0.0 - extsprintf: 1.3.0 - json-schema: 0.4.0 - verror: 1.10.0 - dev: true - - /jsx-ast-utils/3.3.3: - resolution: {integrity: sha512-fYQHZTZ8jSfmWZ0iyzfwiU4WDX4HpHbMCZ3gPlWYiCl3BoeOTsqKBqnTVfH2rYT7eP5c3sVbeSPHnnJOaTrWiw==} - engines: {node: '>=4.0'} - dependencies: - array-includes: 3.1.5 - object.assign: 4.1.4 - dev: true - - /just-debounce/1.1.0: - resolution: {integrity: sha512-qpcRocdkUmf+UTNBYx5w6dexX5J31AKK1OmPwH630a83DdVVUIngk55RSAiIGpQyoH0dlr872VHfPjnQnK1qDQ==} - dev: true - - /kind-of/3.2.2: - resolution: {integrity: sha512-NOW9QQXMoZGg/oqnVNoNTTIFEIid1627WCffUBJEdMxYApq7mNE7CpzucIPc+ZQg25Phej7IJSmX3hO+oblOtQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 - dev: true - - /kind-of/4.0.0: - resolution: {integrity: sha512-24XsCxmEbRwEDbz/qz3stgin8TTzZ1ESR56OMCN0ujYg+vRutNSiOj9bHH9u85DKgXguraugV5sFuvbD4FW/hw==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 - dev: true - - /kind-of/5.1.0: - resolution: {integrity: sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==} - engines: {node: '>=0.10.0'} - dev: true - - /kind-of/6.0.3: - resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==} - engines: {node: '>=0.10.0'} - dev: true - - /known-css-properties/0.21.0: - resolution: {integrity: sha512-sZLUnTqimCkvkgRS+kbPlYW5o8q5w1cu+uIisKpEWkj31I8mx8kNG162DwRav8Zirkva6N5uoFsm9kzK4mUXjw==} - dev: true - - /language-subtag-registry/0.3.22: - resolution: {integrity: sha512-tN0MCzyWnoz/4nHS6uxdlFWoUZT7ABptwKPQ52Ea7URk6vll88bWBVhodtnlfEuCcKWNGoc+uGbw1cwa9IKh/w==} - dev: true - - /language-tags/1.0.5: - resolution: {integrity: sha512-qJhlO9cGXi6hBGKoxEG/sKZDAHD5Hnu9Hs4WbOY3pCWXDhw0N8x1NenNzm2EnNLkLkk7J2SdxAkDSbb6ftT+UQ==} - dependencies: - language-subtag-registry: 0.3.22 - dev: true - - /last-run/1.1.1: - resolution: {integrity: sha512-U/VxvpX4N/rFvPzr3qG5EtLKEnNI0emvIQB3/ecEwv+8GHaUKbIB8vxv1Oai5FAF0d0r7LXHhLLe5K/yChm5GQ==} - engines: {node: '>= 0.10'} - dependencies: - default-resolution: 2.0.0 - es6-weak-map: 2.0.3 - dev: true - - /lazystream/1.0.1: - resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} - engines: {node: '>= 0.6.3'} - dependencies: - readable-stream: 2.3.7 - dev: true - - /lcid/1.0.0: - resolution: {integrity: sha512-YiGkH6EnGrDGqLMITnGjXtGmNtjoXw9SVUzcaos8RBi7Ps0VBylkq+vOcY9QE5poLasPCR849ucFUkl0UzUyOw==} - engines: {node: '>=0.10.0'} - dependencies: - invert-kv: 1.0.0 - dev: true - - /lead/1.0.0: - resolution: {integrity: sha512-IpSVCk9AYvLHo5ctcIXxOBpMWUe+4TKN3VPWAKUbJikkmsGp0VrSM8IttVc32D6J4WUsiPE6aEFRNmIoF/gdow==} - engines: {node: '>= 0.10'} - dependencies: - flush-write-stream: 1.1.1 - dev: true - - /lerna/4.0.0: - resolution: {integrity: sha512-DD/i1znurfOmNJb0OBw66NmNqiM8kF6uIrzrJ0wGE3VNdzeOhz9ziWLYiRaZDGGwgbcjOo6eIfcx9O5Qynz+kg==} - engines: {node: '>= 10.18.0'} - hasBin: true - dependencies: - '@lerna/add': 4.0.0 - '@lerna/bootstrap': 4.0.0 - '@lerna/changed': 4.0.0 - '@lerna/clean': 4.0.0 - '@lerna/cli': 4.0.0 - '@lerna/create': 4.0.0 - '@lerna/diff': 4.0.0 - '@lerna/exec': 4.0.0 - '@lerna/import': 4.0.0 - '@lerna/info': 4.0.0 - '@lerna/init': 4.0.0 - '@lerna/link': 4.0.0 - '@lerna/list': 4.0.0 - '@lerna/publish': 4.0.0 - '@lerna/run': 4.0.0 - '@lerna/version': 4.0.0 - import-local: 3.1.0 - npmlog: 4.1.2 - transitivePeerDependencies: - - bluebird - - encoding - - supports-color - dev: true - - /levn/0.4.1: - resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.2.1 - type-check: 0.4.0 - dev: true - - /libnpmaccess/4.0.3: - resolution: {integrity: sha512-sPeTSNImksm8O2b6/pf3ikv4N567ERYEpeKRPSmqlNt1dTZbvgpJIzg5vAhXHpw2ISBsELFRelk0jEahj1c6nQ==} - engines: {node: '>=10'} - dependencies: - aproba: 2.0.0 - minipass: 3.3.4 - npm-package-arg: 8.1.5 - npm-registry-fetch: 11.0.0 - transitivePeerDependencies: - - bluebird - - supports-color - dev: true - - /libnpmpublish/4.0.2: - resolution: {integrity: sha512-+AD7A2zbVeGRCFI2aO//oUmapCwy7GHqPXFJh3qpToSRNU+tXKJ2YFUgjt04LPPAf2dlEH95s6EhIHM1J7bmOw==} - engines: {node: '>=10'} - dependencies: - normalize-package-data: 3.0.3 - npm-package-arg: 8.1.5 - npm-registry-fetch: 11.0.0 - semver: 7.3.8 - ssri: 8.0.1 - transitivePeerDependencies: - - bluebird - - supports-color - dev: true - - /liftoff/3.1.0: - resolution: {integrity: sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog==} - engines: {node: '>= 0.8'} - dependencies: - extend: 3.0.2 - findup-sync: 3.0.0 - fined: 1.2.0 - flagged-respawn: 1.0.1 - is-plain-object: 2.0.4 - object.map: 1.0.1 - rechoir: 0.6.2 - resolve: 1.22.1 - transitivePeerDependencies: - - supports-color - dev: true - - /lines-and-columns/1.2.4: - resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} - dev: true - - /linkify-it/3.0.3: - resolution: {integrity: sha512-ynTsyrFSdE5oZ/O9GEf00kPngmOfVwazR5GKDq6EYfhlpFug3J2zybX56a2PRRpc9P+FuSoGNAwjlbDs9jJBPQ==} - dependencies: - uc.micro: 1.0.6 - dev: true - - /load-json-file/1.1.0: - resolution: {integrity: sha512-cy7ZdNRXdablkXYNI049pthVeXFurRyb9+hA/dZzerZ0pGTx42z+y+ssxBaVV2l70t1muq5IdKhn4UtcoGUY9A==} - engines: {node: '>=0.10.0'} - dependencies: - graceful-fs: 4.2.10 - parse-json: 2.2.0 - pify: 2.3.0 - pinkie-promise: 2.0.1 - strip-bom: 2.0.0 - dev: true - - /load-json-file/4.0.0: - resolution: {integrity: sha512-Kx8hMakjX03tiGTLAIdJ+lL0htKnXjEZN6hk/tozf/WOuYGdZBJrZ+rCJRbVCugsjB3jMLn9746NsQIf5VjBMw==} - engines: {node: '>=4'} - dependencies: - graceful-fs: 4.2.10 - parse-json: 4.0.0 - pify: 3.0.0 - strip-bom: 3.0.0 - dev: true - - /load-json-file/6.2.0: - resolution: {integrity: sha512-gUD/epcRms75Cw8RT1pUdHugZYM5ce64ucs2GEISABwkRsOQr0q2wm/MV2TKThycIe5e0ytRweW2RZxclogCdQ==} - engines: {node: '>=8'} - dependencies: - graceful-fs: 4.2.10 - parse-json: 5.2.0 - strip-bom: 4.0.0 - type-fest: 0.6.0 - dev: true - - /locate-path/2.0.0: - resolution: {integrity: sha512-NCI2kiDkyR7VeEKm27Kda/iQHyKJe1Bu0FlTbYp3CqJu+9IFe9bLyAjMxf5ZDDbEg+iMPzB5zYyUTSm8wVTKmA==} - engines: {node: '>=4'} - dependencies: - p-locate: 2.0.0 - path-exists: 3.0.0 - dev: true - - /locate-path/5.0.0: - resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} - engines: {node: '>=8'} - dependencies: - p-locate: 4.1.0 - dev: true - - /locate-path/6.0.0: - resolution: {integrity: sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw==} - engines: {node: '>=10'} - dependencies: - p-locate: 5.0.0 - dev: true - - /lodash._reinterpolate/3.0.0: - resolution: {integrity: sha512-xYHt68QRoYGjeeM/XOE1uJtvXQAgvszfBhjV4yvsQH0u2i9I6cI6c6/eG4Hh3UAOVn0y/xAXwmTzEay49Q//HA==} - dev: true - - /lodash.ismatch/4.4.0: - resolution: {integrity: sha512-fPMfXjGQEV9Xsq/8MTSgUf255gawYRbjwMyDbcvDhXgV7enSZA0hynz6vMPnpAb5iONEzBHBPsT+0zes5Z301g==} - dev: true - - /lodash.merge/4.6.2: - resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==} - dev: true - - /lodash.template/4.5.0: - resolution: {integrity: sha512-84vYFxIkmidUiFxidA/KjjH9pAycqW+h980j7Fuz5qxRtO9pgB7MDFTdys1N7A5mcucRiDyEq4fusljItR1T/A==} - dependencies: - lodash._reinterpolate: 3.0.0 - lodash.templatesettings: 4.2.0 - dev: true - - /lodash.templatesettings/4.2.0: - resolution: {integrity: sha512-stgLz+i3Aa9mZgnjr/O+v9ruKZsPsndy7qPZOchbqk2cnTU1ZaldKK+v7m54WoKIyxiuMZTKT2H81F8BeAc3ZQ==} - dependencies: - lodash._reinterpolate: 3.0.0 - dev: true - - /lodash.truncate/4.4.2: - resolution: {integrity: sha512-jttmRe7bRse52OsWIMDLaXxWqRAmtIUccAQ3garviCqJjafXOfNMO0yMfNpdD6zbGaTU0P5Nz7e7gAT6cKmJRw==} - dev: true - - /lodash/4.17.21: - resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} - dev: true - - /log-symbols/4.1.0: - resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} - engines: {node: '>=10'} - dependencies: - chalk: 4.1.2 - is-unicode-supported: 0.1.0 - dev: true - - /longest-streak/2.0.4: - resolution: {integrity: sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==} - dev: true - - /loose-envify/1.4.0: - resolution: {integrity: sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==} - hasBin: true - dependencies: - js-tokens: 4.0.0 - dev: true - - /lru-cache/6.0.0: - resolution: {integrity: sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==} - engines: {node: '>=10'} - dependencies: - yallist: 4.0.0 - dev: true - - /make-dir/2.1.0: - resolution: {integrity: sha512-LS9X+dc8KLxXCb8dni79fLIIUA5VyZoyjSMCwTluaXA0o27cCK0bhXkpgw+sTXVpPy/lSO57ilRixqk0vDmtRA==} - engines: {node: '>=6'} - dependencies: - pify: 4.0.1 - semver: 5.7.1 - dev: true - - /make-dir/3.1.0: - resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} - engines: {node: '>=8'} - dependencies: - semver: 6.3.0 - dev: true - - /make-fetch-happen/8.0.14: - resolution: {integrity: sha512-EsS89h6l4vbfJEtBZnENTOFk8mCRpY5ru36Xe5bcX1KYIli2mkSHqoFsp5O1wMDvTJJzxe/4THpCTtygjeeGWQ==} - engines: {node: '>= 10'} - dependencies: - agentkeepalive: 4.2.1 - cacache: 15.3.0 - http-cache-semantics: 4.1.0 - http-proxy-agent: 4.0.1 - https-proxy-agent: 5.0.1 - is-lambda: 1.0.1 - lru-cache: 6.0.0 - minipass: 3.3.4 - minipass-collect: 1.0.2 - minipass-fetch: 1.4.1 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - promise-retry: 2.0.1 - socks-proxy-agent: 5.0.1 - ssri: 8.0.1 - transitivePeerDependencies: - - bluebird - - supports-color - dev: true - - /make-fetch-happen/9.1.0: - resolution: {integrity: sha512-+zopwDy7DNknmwPQplem5lAZX/eCOzSvSNNcSKm5eVwTkOBzoktEfXsa9L23J/GIRhxRsaxzkPEhrJEpE2F4Gg==} - engines: {node: '>= 10'} - dependencies: - agentkeepalive: 4.2.1 - cacache: 15.3.0 - http-cache-semantics: 4.1.0 - http-proxy-agent: 4.0.1 - https-proxy-agent: 5.0.1 - is-lambda: 1.0.1 - lru-cache: 6.0.0 - minipass: 3.3.4 - minipass-collect: 1.0.2 - minipass-fetch: 1.4.1 - minipass-flush: 1.0.5 - minipass-pipeline: 1.2.4 - negotiator: 0.6.3 - promise-retry: 2.0.1 - socks-proxy-agent: 6.2.1 - ssri: 8.0.1 - transitivePeerDependencies: - - bluebird - - supports-color - dev: true - - /make-iterator/1.0.1: - resolution: {integrity: sha512-pxiuXh0iVEq7VM7KMIhs5gxsfxCux2URptUQaXo4iZZJxBAzTPOLE2BumO5dbfVYq/hBJFBR/a1mFDmOx5AGmw==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 6.0.3 - dev: true - - /map-cache/0.2.2: - resolution: {integrity: sha512-8y/eV9QQZCiyn1SprXSrCmqJN0yNRATe+PO8ztwqrvrbdRLA3eYJF0yaR0YayLWkMbsQSKWS9N2gPcGEc4UsZg==} - engines: {node: '>=0.10.0'} - dev: true - - /map-obj/1.0.1: - resolution: {integrity: sha512-7N/q3lyZ+LVCp7PzuxrJr4KMbBE2hW7BT7YNia330OFxIf4d3r5zVpicP2650l7CPN6RM9zOJRl3NGpqSiw3Eg==} - engines: {node: '>=0.10.0'} - dev: true - - /map-obj/4.3.0: - resolution: {integrity: sha512-hdN1wVrZbb29eBGiGjJbeP8JbKjq1urkHJ/LIP/NY48MZ1QVXUsQBV1G1zvYFHn1XE06cwjBsOI2K3Ulnj1YXQ==} - engines: {node: '>=8'} - dev: true - - /map-visit/1.0.0: - resolution: {integrity: sha512-4y7uGv8bd2WdM9vpQsiQNo41Ln1NvhvDRuVt0k2JZQ+ezN2uaQes7lZeZ+QQUHOLQAtDaBJ+7wCbi+ab/KFs+w==} - engines: {node: '>=0.10.0'} - dependencies: - object-visit: 1.0.1 - dev: true - - /markdown-it/12.0.2: - resolution: {integrity: sha512-4Lkvjbv2kK+moL9TbeV+6/NHx+1Q+R/NIdUlFlkqkkzUcTod4uiyTJRiBidKR9qXSdkNFkgv+AELY8KN9vSgVA==} - hasBin: true - dependencies: - argparse: 2.0.1 - entities: 2.0.3 - linkify-it: 3.0.3 - mdurl: 1.0.1 - uc.micro: 1.0.6 - dev: true - - /markdownlint-config-ali/0.1.1_markdownlint@0.22.0: - resolution: {integrity: sha512-nA7+Tl2aHCr0rUH1lID166FwpQ1qDdfK+cMTNFWFOgvnsYOMCP4ADWsLl+4TG+3c4xQpxT6P/tC1vfnNylbcvg==} - peerDependencies: - markdownlint: ^0.21.1 - dependencies: - markdownlint: 0.22.0 - dev: true - - /markdownlint-rule-helpers/0.13.0: - resolution: {integrity: sha512-rRY0itbcHG4e+ntz0bbY3AIceSJMKS0TafEMgEtKVHRZ54/JUSy6/4ypCL618RlJvYRej+xMLxX5nkJqIeTZaQ==} - dev: true - - /markdownlint/0.22.0: - resolution: {integrity: sha512-J4B+iMc12pOdp/wfYi03W2qfAfEyiZzq3qvQh/8vOMNU8vXYY6Jg440EY7dWTBCqROhb1i4nAn3BTByJ5kdx1w==} - engines: {node: '>=10'} - dependencies: - markdown-it: 12.0.2 - dev: true - - /matchdep/2.0.0: - resolution: {integrity: sha512-LFgVbaHIHMqCRuCZyfCtUOq9/Lnzhi7Z0KFUE2fhD54+JN2jLh3hC02RLkqauJ3U4soU6H1J3tfj/Byk7GoEjA==} - engines: {node: '>= 0.10.0'} - dependencies: - findup-sync: 2.0.0 - micromatch: 3.1.10 - resolve: 1.22.1 - stack-trace: 0.0.10 - transitivePeerDependencies: - - supports-color - dev: true - - /mathml-tag-names/2.1.3: - resolution: {integrity: sha512-APMBEanjybaPzUrfqU0IMU5I0AswKMH7k8OTLs0vvV4KZpExkTkY87nR/zpbuTPj+gARop7aGUbl11pnDfW6xg==} - dev: true - - /mdast-util-from-markdown/0.8.5: - resolution: {integrity: sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==} - dependencies: - '@types/mdast': 3.0.10 - mdast-util-to-string: 2.0.0 - micromark: 2.11.4 - parse-entities: 2.0.0 - unist-util-stringify-position: 2.0.3 - transitivePeerDependencies: - - supports-color - dev: true - - /mdast-util-to-markdown/0.6.5: - resolution: {integrity: sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==} - dependencies: - '@types/unist': 2.0.6 - longest-streak: 2.0.4 - mdast-util-to-string: 2.0.0 - parse-entities: 2.0.0 - repeat-string: 1.6.1 - zwitch: 1.0.5 - dev: true - - /mdast-util-to-string/2.0.0: - resolution: {integrity: sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==} - dev: true - - /mdurl/1.0.1: - resolution: {integrity: sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==} - dev: true - - /meow/8.1.2: - resolution: {integrity: sha512-r85E3NdZ+mpYk1C6RjPFEMSE+s1iZMuHtsHAqY0DT3jZczl0diWUZ8g6oU7h0M9cD2EL+PzaYghhCLzR0ZNn5Q==} - engines: {node: '>=10'} - dependencies: - '@types/minimist': 1.2.2 - camelcase-keys: 6.2.2 - decamelize-keys: 1.1.0 - hard-rejection: 2.1.0 - minimist-options: 4.1.0 - normalize-package-data: 3.0.3 - read-pkg-up: 7.0.1 - redent: 3.0.0 - trim-newlines: 3.0.1 - type-fest: 0.18.1 - yargs-parser: 20.2.9 - dev: true - - /meow/9.0.0: - resolution: {integrity: sha512-+obSblOQmRhcyBt62furQqRAQpNyWXo8BuQ5bN7dG8wmwQ+vwHKp/rCFD4CrTP8CsDQD1sjoZ94K417XEUk8IQ==} - engines: {node: '>=10'} - dependencies: - '@types/minimist': 1.2.2 - camelcase-keys: 6.2.2 - decamelize: 1.2.0 - decamelize-keys: 1.1.0 - hard-rejection: 2.1.0 - minimist-options: 4.1.0 - normalize-package-data: 3.0.3 - read-pkg-up: 7.0.1 - redent: 3.0.0 - trim-newlines: 3.0.1 - type-fest: 0.18.1 - yargs-parser: 20.2.9 - dev: true - - /merge-stream/2.0.0: - resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: true - - /merge2/1.4.1: - resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} - engines: {node: '>= 8'} - dev: true - - /micromark/2.11.4: - resolution: {integrity: sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==} - dependencies: - debug: 4.3.4 - parse-entities: 2.0.0 - transitivePeerDependencies: - - supports-color - dev: true - - /micromatch/3.1.10: - resolution: {integrity: sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==} - engines: {node: '>=0.10.0'} - dependencies: - arr-diff: 4.0.0 - array-unique: 0.3.2 - braces: 2.3.2 - define-property: 2.0.2 - extend-shallow: 3.0.2 - extglob: 2.0.4 - fragment-cache: 0.2.1 - kind-of: 6.0.3 - nanomatch: 1.2.13 - object.pick: 1.3.0 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /micromatch/4.0.5: - resolution: {integrity: sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==} - engines: {node: '>=8.6'} - dependencies: - braces: 3.0.2 - picomatch: 2.3.1 - dev: true - - /mime-db/1.52.0: - resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} - engines: {node: '>= 0.6'} - dev: true - - /mime-types/2.1.35: - resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.52.0 - dev: true - - /mimic-fn/2.1.0: - resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} - engines: {node: '>=6'} - dev: true - - /min-indent/1.0.1: - resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} - engines: {node: '>=4'} - dev: true - - /minimatch/3.1.2: - resolution: {integrity: sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==} - dependencies: - brace-expansion: 1.1.11 - dev: true - - /minimatch/5.1.0: - resolution: {integrity: sha512-9TPBGGak4nHfGZsPBohm9AWg6NoT7QTCehS3BIJABslyZbzxfV78QM2Y6+i741OPZIafFAaiiEMh5OyIrJPgtg==} - engines: {node: '>=10'} - dependencies: - brace-expansion: 2.0.1 - dev: true - - /minimist-options/4.1.0: - resolution: {integrity: sha512-Q4r8ghd80yhO/0j1O3B2BjweX3fiHg9cdOwjJd2J76Q135c+NDxGCqdYKQ1SKBuFfgWbAUzBfvYjPUEeNgqN1A==} - engines: {node: '>= 6'} - dependencies: - arrify: 1.0.1 - is-plain-obj: 1.1.0 - kind-of: 6.0.3 - dev: true - - /minimist/1.2.7: - resolution: {integrity: sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==} - dev: true - - /minipass-collect/1.0.2: - resolution: {integrity: sha512-6T6lH0H8OG9kITm/Jm6tdooIbogG9e0tLgpY6mphXSm/A9u8Nq1ryBG+Qspiub9LjWlBPsPS3tWQ/Botq4FdxA==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.4 - dev: true - - /minipass-fetch/1.4.1: - resolution: {integrity: sha512-CGH1eblLq26Y15+Azk7ey4xh0J/XfJfrCox5LDJiKqI2Q2iwOLOKrlmIaODiSQS8d18jalF6y2K2ePUm0CmShw==} - engines: {node: '>=8'} - dependencies: - minipass: 3.3.4 - minipass-sized: 1.0.3 - minizlib: 2.1.2 - optionalDependencies: - encoding: 0.1.13 - dev: true - - /minipass-flush/1.0.5: - resolution: {integrity: sha512-JmQSYYpPUqX5Jyn1mXaRwOda1uQ8HP5KAT/oDSLCzt1BYRhQU0/hDtsB1ufZfEEzMZ9aAVmsBw8+FWsIXlClWw==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.4 - dev: true - - /minipass-json-stream/1.0.1: - resolution: {integrity: sha512-ODqY18UZt/I8k+b7rl2AENgbWE8IDYam+undIJONvigAz8KR5GWblsFTEfQs0WODsjbSXWlm+JHEv8Gr6Tfdbg==} - dependencies: - jsonparse: 1.3.1 - minipass: 3.3.4 - dev: true - - /minipass-pipeline/1.2.4: - resolution: {integrity: sha512-xuIq7cIOt09RPRJ19gdi4b+RiNvDFYe5JH+ggNvBqGqpQXcru3PcRmOZuHBKWK1Txf9+cQ+HMVN4d6z46LZP7A==} - engines: {node: '>=8'} - dependencies: - minipass: 3.3.4 - dev: true - - /minipass-sized/1.0.3: - resolution: {integrity: sha512-MbkQQ2CTiBMlA2Dm/5cY+9SWFEN8pzzOXi6rlM5Xxq0Yqbda5ZQy9sU75a673FE9ZK0Zsbr6Y5iP6u9nktfg2g==} - engines: {node: '>=8'} - dependencies: - minipass: 3.3.4 - dev: true - - /minipass/2.9.0: - resolution: {integrity: sha512-wxfUjg9WebH+CUDX/CdbRlh5SmfZiy/hpkxaRI16Y9W56Pa75sWgd/rvFilSgrauD9NyFymP/+JFV3KwzIsJeg==} - dependencies: - safe-buffer: 5.2.1 - yallist: 3.1.1 - dev: true - - /minipass/3.3.4: - resolution: {integrity: sha512-I9WPbWHCGu8W+6k1ZiGpPu0GkoKBeorkfKNuAFBNS1HNFJvke82sxvI5bzcCNpWPorkOO5QQ+zomzzwRxejXiw==} - engines: {node: '>=8'} - dependencies: - yallist: 4.0.0 - dev: true - - /minizlib/1.3.3: - resolution: {integrity: sha512-6ZYMOEnmVsdCeTJVE0W9ZD+pVnE8h9Hma/iOwwRDsdQoePpoX56/8B6z3P9VNwppJuBKNRuFDRNRqRWexT9G9Q==} - dependencies: - minipass: 2.9.0 - dev: true - - /minizlib/2.1.2: - resolution: {integrity: sha512-bAxsR8BVfj60DWXHE3u30oHzfl4G7khkSuPW+qvpd7jFRHm7dLxOjUk1EHACJ/hxLY8phGJ0YhYHZo7jil7Qdg==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.4 - yallist: 4.0.0 - dev: true - - /mixin-deep/1.3.2: - resolution: {integrity: sha512-WRoDn//mXBiJ1H40rqa3vH0toePwSsGb45iInWlTySa+Uu4k3tYUSxa2v1KqAiLtvlrSzaExqS1gtk96A9zvEA==} - engines: {node: '>=0.10.0'} - dependencies: - for-in: 1.0.2 - is-extendable: 1.0.1 - dev: true - - /mkdirp-infer-owner/2.0.0: - resolution: {integrity: sha512-sdqtiFt3lkOaYvTXSRIUjkIdPTcxgv5+fgqYE/5qgwdw12cOrAuzzgzvVExIkH/ul1oeHN3bCLOWSG3XOqbKKw==} - engines: {node: '>=10'} - dependencies: - chownr: 2.0.0 - infer-owner: 1.0.4 - mkdirp: 1.0.4 - dev: true - - /mkdirp/0.5.6: - resolution: {integrity: sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==} - hasBin: true - dependencies: - minimist: 1.2.7 - dev: true - - /mkdirp/1.0.4: - resolution: {integrity: sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==} - engines: {node: '>=10'} - hasBin: true - dev: true - - /modify-values/1.0.1: - resolution: {integrity: sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==} - engines: {node: '>=0.10.0'} - dev: true - - /ms/2.0.0: - resolution: {integrity: sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==} - dev: true - - /ms/2.1.2: - resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true - - /ms/2.1.3: - resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} - dev: true - - /multimatch/5.0.0: - resolution: {integrity: sha512-ypMKuglUrZUD99Tk2bUQ+xNQj43lPEfAeX2o9cTteAmShXy2VHDJpuwu1o0xqoKCt9jLVAvwyFKdLTPXKAfJyA==} - engines: {node: '>=10'} - dependencies: - '@types/minimatch': 3.0.5 - array-differ: 3.0.0 - array-union: 2.1.0 - arrify: 2.0.1 - minimatch: 3.1.2 - dev: true - - /mute-stdout/1.0.1: - resolution: {integrity: sha512-kDcwXR4PS7caBpuRYYBUz9iVixUk3anO3f5OYFiIPwK/20vCzKCHyKoulbiDY1S53zD2bxUpxN/IJ+TnXjfvxg==} - engines: {node: '>= 0.10'} - dev: true - - /mute-stream/0.0.8: - resolution: {integrity: sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==} - dev: true - - /nan/2.17.0: - resolution: {integrity: sha512-2ZTgtl0nJsO0KQCjEpxcIr5D+Yv90plTitZt9JBfQvVJDS5seMl3FOvsh3+9CoYWXf/1l5OaZzzF6nDm4cagaQ==} - dev: true - optional: true - - /nanomatch/1.2.13: - resolution: {integrity: sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==} - engines: {node: '>=0.10.0'} - dependencies: - arr-diff: 4.0.0 - array-unique: 0.3.2 - define-property: 2.0.2 - extend-shallow: 3.0.2 - fragment-cache: 0.2.1 - is-windows: 1.0.2 - kind-of: 6.0.3 - object.pick: 1.3.0 - regex-not: 1.0.2 - snapdragon: 0.8.2 - to-regex: 3.0.2 - transitivePeerDependencies: - - supports-color - dev: true - - /natural-compare/1.4.0: - resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==} - dev: true - - /negotiator/0.6.3: - resolution: {integrity: sha512-+EUsqGPLsM+j/zdChZjsnX51g4XrHFOIXwfnCVPGlQk/k5giakcKsuxCObBRu6DSm9opw/O6slWbJdghQM4bBg==} - engines: {node: '>= 0.6'} - dev: true - - /neo-async/2.6.2: - resolution: {integrity: sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==} - dev: true - - /next-tick/1.1.0: - resolution: {integrity: sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==} - dev: true - - /nice-try/1.0.5: - resolution: {integrity: sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==} - dev: true - - /node-fetch/2.6.7: - resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - dependencies: - whatwg-url: 5.0.0 - dev: true - - /node-gyp/5.1.1: - resolution: {integrity: sha512-WH0WKGi+a4i4DUt2mHnvocex/xPLp9pYt5R6M2JdFB7pJ7Z34hveZ4nDTGTiLXCkitA9T8HFZjhinBCiVHYcWw==} - engines: {node: '>= 6.0.0'} - hasBin: true - dependencies: - env-paths: 2.2.1 - glob: 7.2.3 - graceful-fs: 4.2.10 - mkdirp: 0.5.6 - nopt: 4.0.3 - npmlog: 4.1.2 - request: 2.88.2 - rimraf: 2.7.1 - semver: 5.7.1 - tar: 4.4.19 - which: 1.3.1 - dev: true - - /node-gyp/7.1.2: - resolution: {integrity: sha512-CbpcIo7C3eMu3dL1c3d0xw449fHIGALIJsRP4DDPHpyiW8vcriNY7ubh9TE4zEKfSxscY7PjeFnshE7h75ynjQ==} - engines: {node: '>= 10.12.0'} - hasBin: true - dependencies: - env-paths: 2.2.1 - glob: 7.2.3 - graceful-fs: 4.2.10 - nopt: 5.0.0 - npmlog: 4.1.2 - request: 2.88.2 - rimraf: 3.0.2 - semver: 7.3.8 - tar: 6.1.11 - which: 2.0.2 - dev: true - - /node-releases/2.0.6: - resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==} - dev: true - - /nopt/4.0.3: - resolution: {integrity: sha512-CvaGwVMztSMJLOeXPrez7fyfObdZqNUK1cPAEzLHrTybIua9pMdmmPR5YwtfNftIOMv3DPUhFaxsZMNTQO20Kg==} - hasBin: true - dependencies: - abbrev: 1.1.1 - osenv: 0.1.5 - dev: true - - /nopt/5.0.0: - resolution: {integrity: sha512-Tbj67rffqceeLpcRXrT7vKAN8CwfPeIBgM7E6iBkmKLV7bEMwpGgYLGv0jACUsECaa/vuxP0IjEont6umdMgtQ==} - engines: {node: '>=6'} - hasBin: true - dependencies: - abbrev: 1.1.1 - dev: true - - /normalize-package-data/2.5.0: - resolution: {integrity: sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==} - dependencies: - hosted-git-info: 2.8.9 - resolve: 1.22.1 - semver: 5.7.1 - validate-npm-package-license: 3.0.4 - dev: true - - /normalize-package-data/3.0.3: - resolution: {integrity: sha512-p2W1sgqij3zMMyRC067Dg16bfzVH+w7hyegmpIvZ4JNjqtGOVAIvLmjBx3yP7YTe9vKJgkoNOPjwQGogDoMXFA==} - engines: {node: '>=10'} - dependencies: - hosted-git-info: 4.1.0 - is-core-module: 2.11.0 - semver: 7.3.8 - validate-npm-package-license: 3.0.4 - dev: true - - /normalize-path/2.1.1: - resolution: {integrity: sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==} - engines: {node: '>=0.10.0'} - dependencies: - remove-trailing-separator: 1.1.0 - dev: true - - /normalize-path/3.0.0: - resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} - engines: {node: '>=0.10.0'} - dev: true - - /normalize-range/0.1.2: - resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} - engines: {node: '>=0.10.0'} - dev: true - - /normalize-selector/0.2.0: - resolution: {integrity: sha512-dxvWdI8gw6eAvk9BlPffgEoGfM7AdijoCwOEJge3e3ulT2XLgmU7KvvxprOaCu05Q1uGRHmOhHe1r6emZoKyFw==} - dev: true - - /normalize-url/6.1.0: - resolution: {integrity: sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==} - engines: {node: '>=10'} - dev: true - - /now-and-later/2.0.1: - resolution: {integrity: sha512-KGvQ0cB70AQfg107Xvs/Fbu+dGmZoTRJp2TaPwcwQm3/7PteUyN2BCgk8KBMPGBUXZdVwyWS8fDCGFygBm19UQ==} - engines: {node: '>= 0.10'} - dependencies: - once: 1.4.0 - dev: true - - /npm-bundled/1.1.2: - resolution: {integrity: sha512-x5DHup0SuyQcmL3s7Rx/YQ8sbw/Hzg0rj48eN0dV7hf5cmQq5PXIeioroH3raV1QC1yh3uTYuMThvEQF3iKgGQ==} - dependencies: - npm-normalize-package-bin: 1.0.1 - dev: true - - /npm-install-checks/4.0.0: - resolution: {integrity: sha512-09OmyDkNLYwqKPOnbI8exiOZU2GVVmQp7tgez2BPi5OZC8M82elDAps7sxC4l//uSUtotWqoEIDwjRvWH4qz8w==} - engines: {node: '>=10'} - dependencies: - semver: 7.3.8 - dev: true - - /npm-lifecycle/3.1.5: - resolution: {integrity: sha512-lDLVkjfZmvmfvpvBzA4vzee9cn+Me4orq0QF8glbswJVEbIcSNWib7qGOffolysc3teCqbbPZZkzbr3GQZTL1g==} - dependencies: - byline: 5.0.0 - graceful-fs: 4.2.10 - node-gyp: 5.1.1 - resolve-from: 4.0.0 - slide: 1.1.6 - uid-number: 0.0.6 - umask: 1.1.0 - which: 1.3.1 - dev: true - - /npm-normalize-package-bin/1.0.1: - resolution: {integrity: sha512-EPfafl6JL5/rU+ot6P3gRSCpPDW5VmIzX959Ob1+ySFUuuYHWHekXpwdUZcKP5C+DS4GEtdJluwBjnsNDl+fSA==} - dev: true - - /npm-package-arg/8.1.5: - resolution: {integrity: sha512-LhgZrg0n0VgvzVdSm1oiZworPbTxYHUJCgtsJW8mGvlDpxTM1vSJc3m5QZeUkhAHIzbz3VCHd/R4osi1L1Tg/Q==} - engines: {node: '>=10'} - dependencies: - hosted-git-info: 4.1.0 - semver: 7.3.8 - validate-npm-package-name: 3.0.0 - dev: true - - /npm-packlist/2.2.2: - resolution: {integrity: sha512-Jt01acDvJRhJGthnUJVF/w6gumWOZxO7IkpY/lsX9//zqQgnF7OJaxgQXcerd4uQOLu7W5bkb4mChL9mdfm+Zg==} - engines: {node: '>=10'} - hasBin: true - dependencies: - glob: 7.2.3 - ignore-walk: 3.0.4 - npm-bundled: 1.1.2 - npm-normalize-package-bin: 1.0.1 - dev: true - - /npm-pick-manifest/6.1.1: - resolution: {integrity: sha512-dBsdBtORT84S8V8UTad1WlUyKIY9iMsAmqxHbLdeEeBNMLQDlDWWra3wYUx9EBEIiG/YwAy0XyNHDd2goAsfuA==} - dependencies: - npm-install-checks: 4.0.0 - npm-normalize-package-bin: 1.0.1 - npm-package-arg: 8.1.5 - semver: 7.3.8 - dev: true - - /npm-registry-fetch/11.0.0: - resolution: {integrity: sha512-jmlgSxoDNuhAtxUIG6pVwwtz840i994dL14FoNVZisrmZW5kWd63IUTNv1m/hyRSGSqWjCUp/YZlS1BJyNp9XA==} - engines: {node: '>=10'} - dependencies: - make-fetch-happen: 9.1.0 - minipass: 3.3.4 - minipass-fetch: 1.4.1 - minipass-json-stream: 1.0.1 - minizlib: 2.1.2 - npm-package-arg: 8.1.5 - transitivePeerDependencies: - - bluebird - - supports-color - dev: true - - /npm-registry-fetch/9.0.0: - resolution: {integrity: sha512-PuFYYtnQ8IyVl6ib9d3PepeehcUeHN9IO5N/iCRhyg9tStQcqGQBRVHmfmMWPDERU3KwZoHFvbJ4FPXPspvzbA==} - engines: {node: '>=10'} - dependencies: - '@npmcli/ci-detect': 1.4.0 - lru-cache: 6.0.0 - make-fetch-happen: 8.0.14 - minipass: 3.3.4 - minipass-fetch: 1.4.1 - minipass-json-stream: 1.0.1 - minizlib: 2.1.2 - npm-package-arg: 8.1.5 - transitivePeerDependencies: - - bluebird - - supports-color - dev: true - - /npm-run-path/2.0.2: - resolution: {integrity: sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==} - engines: {node: '>=4'} - dependencies: - path-key: 2.0.1 - dev: true - - /npm-run-path/4.0.1: - resolution: {integrity: sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==} - engines: {node: '>=8'} - dependencies: - path-key: 3.1.1 - dev: true - - /npmlog/4.1.2: - resolution: {integrity: sha512-2uUqazuKlTaSI/dC8AzicUck7+IrEaOnN/e0jd3Xtt1KcGpwx30v50mL7oPyr/h9bL3E4aZccVwpwP+5W9Vjkg==} - dependencies: - are-we-there-yet: 1.1.7 - console-control-strings: 1.1.0 - gauge: 2.7.4 - set-blocking: 2.0.0 - dev: true - - /num2fraction/1.2.2: - resolution: {integrity: sha512-Y1wZESM7VUThYY+4W+X4ySH2maqcA+p7UR+w8VWNWVAd6lwuXXWz/w/Cz43J/dI2I+PS6wD5N+bJUF+gjWvIqg==} - dev: true - - /number-is-nan/1.0.1: - resolution: {integrity: sha512-4jbtZXNAsfZbAHiiqjLPBiCl16dES1zI4Hpzzxw61Tk+loF+sBDBKx1ICKKKwIqQ7M0mFn1TmkN7euSncWgHiQ==} - engines: {node: '>=0.10.0'} - dev: true - - /oauth-sign/0.9.0: - resolution: {integrity: sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==} - dev: true - - /object-assign/4.1.1: - resolution: {integrity: sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==} - engines: {node: '>=0.10.0'} - dev: true - - /object-copy/0.1.0: - resolution: {integrity: sha512-79LYn6VAb63zgtmAteVOWo9Vdj71ZVBy3Pbse+VqxDpEP83XuujMrGqHIwAXJ5I/aM0zU7dIyIAhifVTPrNItQ==} - engines: {node: '>=0.10.0'} - dependencies: - copy-descriptor: 0.1.1 - define-property: 0.2.5 - kind-of: 3.2.2 - dev: true - - /object-inspect/1.12.2: - resolution: {integrity: sha512-z+cPxW0QGUp0mcqcsgQyLVRDoXFQbXOwBaqyF7VIgI4TWNQsDHrBpUQslRmIfAoYWdYzs6UlKJtB2XJpTaNSpQ==} - dev: true - - /object-keys/1.1.1: - resolution: {integrity: sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==} - engines: {node: '>= 0.4'} - dev: true - - /object-visit/1.0.1: - resolution: {integrity: sha512-GBaMwwAVK9qbQN3Scdo0OyvgPW7l3lnaVMj84uTOZlswkX0KpF6fyDBJhtTthf7pymztoN36/KEr1DyhF96zEA==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: true - - /object.assign/4.1.4: - resolution: {integrity: sha512-1mxKf0e58bvyjSCtKYY4sRe9itRk3PJpquJOjeIkz885CczcI4IvJJDLPS72oowuSh+pBxUFROpX+TU++hxhZQ==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - has-symbols: 1.0.3 - object-keys: 1.1.1 - dev: true - - /object.defaults/1.1.0: - resolution: {integrity: sha512-c/K0mw/F11k4dEUBMW8naXUuBuhxRCfG7W+yFy8EcijU/rSmazOUd1XAEEe6bC0OuXY4HUKjTJv7xbxIMqdxrA==} - engines: {node: '>=0.10.0'} - dependencies: - array-each: 1.0.1 - array-slice: 1.1.0 - for-own: 1.0.0 - isobject: 3.0.1 - dev: true - - /object.entries/1.1.5: - resolution: {integrity: sha512-TyxmjUoZggd4OrrU1W66FMDG6CuqJxsFvymeyXI51+vQLN67zYfZseptRge703kKQdo4uccgAKebXFcRCzk4+g==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - dev: true - - /object.fromentries/2.0.5: - resolution: {integrity: sha512-CAyG5mWQRRiBU57Re4FKoTBjXfDoNwdFVH2Y1tS9PqCsfUTymAohOkEMSG3aRNKmv4lV3O7p1et7c187q6bynw==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - dev: true - - /object.getownpropertydescriptors/2.1.4: - resolution: {integrity: sha512-sccv3L/pMModT6dJAYF3fzGMVcb38ysQ0tEE6ixv2yXJDtEIPph268OlAdJj5/qZMZDq2g/jqvwppt36uS/uQQ==} - engines: {node: '>= 0.8'} - dependencies: - array.prototype.reduce: 1.0.4 - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - dev: true - - /object.hasown/1.1.1: - resolution: {integrity: sha512-LYLe4tivNQzq4JdaWW6WO3HMZZJWzkkH8fnI6EebWl0VZth2wL2Lovm74ep2/gZzlaTdV62JZHEqHQ2yVn8Q/A==} - dependencies: - define-properties: 1.1.4 - es-abstract: 1.20.4 - dev: true - - /object.map/1.0.1: - resolution: {integrity: sha512-3+mAJu2PLfnSVGHwIWubpOFLscJANBKuB/6A4CxBstc4aqwQY0FWcsppuy4jU5GSB95yES5JHSI+33AWuS4k6w==} - engines: {node: '>=0.10.0'} - dependencies: - for-own: 1.0.0 - make-iterator: 1.0.1 - dev: true - - /object.pick/1.3.0: - resolution: {integrity: sha512-tqa/UMy/CCoYmj+H5qc07qvSL9dqcs/WZENZ1JbtWBlATP+iVOe778gE6MSijnyCnORzDuX6hU+LA4SZ09YjFQ==} - engines: {node: '>=0.10.0'} - dependencies: - isobject: 3.0.1 - dev: true - - /object.reduce/1.0.1: - resolution: {integrity: sha512-naLhxxpUESbNkRqc35oQ2scZSJueHGQNUfMW/0U37IgN6tE2dgDWg3whf+NEliy3F/QysrO48XKUz/nGPe+AQw==} - engines: {node: '>=0.10.0'} - dependencies: - for-own: 1.0.0 - make-iterator: 1.0.1 - dev: true - - /object.values/1.1.5: - resolution: {integrity: sha512-QUZRW0ilQ3PnPpbNtgdNV1PDbEqLIiSFB3l+EnGtBQ/8SUTLj1PZwtQHABZtLgwpJZTSZhuGLOGk57Drx2IvYg==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - dev: true - - /once/1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - dependencies: - wrappy: 1.0.2 - dev: true - - /onetime/5.1.2: - resolution: {integrity: sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==} - engines: {node: '>=6'} - dependencies: - mimic-fn: 2.1.0 - dev: true - - /opencollective-postinstall/2.0.3: - resolution: {integrity: sha512-8AV/sCtuzUeTo8gQK5qDZzARrulB3egtLzFgteqB2tcT4Mw7B8Kt7JcDHmltjz6FOAHsvTevk70gZEbhM4ZS9Q==} - hasBin: true - dev: true - - /optionator/0.9.1: - resolution: {integrity: sha512-74RlY5FCnhq4jRxVUPKDaRwrVNXMqsGsiW6AJw4XK8hmtm10wC0ypZBLw5IIp85NZMr91+qd1RvvENwg7jjRFw==} - engines: {node: '>= 0.8.0'} - dependencies: - deep-is: 0.1.4 - fast-levenshtein: 2.0.6 - levn: 0.4.1 - prelude-ls: 1.2.1 - type-check: 0.4.0 - word-wrap: 1.2.3 - dev: true - - /ora/5.4.1: - resolution: {integrity: sha512-5b6Y85tPxZZ7QytO+BQzysW31HJku27cRIlkbAXaNx+BdcVi+LlRFmVXzeF6a7JCwJpyw5c4b+YSVImQIrBpuQ==} - engines: {node: '>=10'} - dependencies: - bl: 4.1.0 - chalk: 4.1.2 - cli-cursor: 3.1.0 - cli-spinners: 2.7.0 - is-interactive: 1.0.0 - is-unicode-supported: 0.1.0 - log-symbols: 4.1.0 - strip-ansi: 6.0.1 - wcwidth: 1.0.1 - dev: true - - /ordered-read-streams/1.0.1: - resolution: {integrity: sha512-Z87aSjx3r5c0ZB7bcJqIgIRX5bxR7A4aSzvIbaxd0oTkWBCOoKfuGHiKj60CHVUgg1Phm5yMZzBdt8XqRs73Mw==} - dependencies: - readable-stream: 2.3.7 - dev: true - - /os-homedir/1.0.2: - resolution: {integrity: sha512-B5JU3cabzk8c67mRRd3ECmROafjYMXbuzlwtqdM8IbS8ktlTix8aFGb2bAGKrSRIlnfKwovGUUr72JUPyOb6kQ==} - engines: {node: '>=0.10.0'} - dev: true - - /os-locale/1.4.0: - resolution: {integrity: sha512-PRT7ZORmwu2MEFt4/fv3Q+mEfN4zetKxufQrkShY2oGvUms9r8otu5HfdyIFHkYXjO7laNsoVGmM2MANfuTA8g==} - engines: {node: '>=0.10.0'} - dependencies: - lcid: 1.0.0 - dev: true - - /os-tmpdir/1.0.2: - resolution: {integrity: sha512-D2FR03Vir7FIu45XBY20mTb+/ZSWB00sjU9jdQXt83gDrI4Ztz5Fs7/yy74g2N5SVQY4xY1qDr4rNddwYRVX0g==} - engines: {node: '>=0.10.0'} - dev: true - - /osenv/0.1.5: - resolution: {integrity: sha512-0CWcCECdMVc2Rw3U5w9ZjqX6ga6ubk1xDVKxtBQPK7wis/0F2r9T6k4ydGYhecl7YUBxBVxhL5oisPsNxAPe2g==} - dependencies: - os-homedir: 1.0.2 - os-tmpdir: 1.0.2 - dev: true - - /p-finally/1.0.0: - resolution: {integrity: sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==} - engines: {node: '>=4'} - dev: true - - /p-limit/1.3.0: - resolution: {integrity: sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==} - engines: {node: '>=4'} - dependencies: - p-try: 1.0.0 - dev: true - - /p-limit/2.3.0: - resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==} - engines: {node: '>=6'} - dependencies: - p-try: 2.2.0 - dev: true - - /p-limit/3.1.0: - resolution: {integrity: sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ==} - engines: {node: '>=10'} - dependencies: - yocto-queue: 0.1.0 - dev: true - - /p-locate/2.0.0: - resolution: {integrity: sha512-nQja7m7gSKuewoVRen45CtVfODR3crN3goVQ0DDZ9N3yHxgpkuBhZqsaiotSQRrADUrne346peY7kT3TSACykg==} - engines: {node: '>=4'} - dependencies: - p-limit: 1.3.0 - dev: true - - /p-locate/4.1.0: - resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==} - engines: {node: '>=8'} - dependencies: - p-limit: 2.3.0 - dev: true - - /p-locate/5.0.0: - resolution: {integrity: sha512-LaNjtRWUBY++zB5nE/NwcaoMylSPk+S+ZHNB1TzdbMJMny6dynpAGt7X/tl/QYq3TIeE6nxHppbo2LGymrG5Pw==} - engines: {node: '>=10'} - dependencies: - p-limit: 3.1.0 - dev: true - - /p-map-series/2.1.0: - resolution: {integrity: sha512-RpYIIK1zXSNEOdwxcfe7FdvGcs7+y5n8rifMhMNWvaxRNMPINJHF5GDeuVxWqnfrcHPSCnp7Oo5yNXHId9Av2Q==} - engines: {node: '>=8'} - dev: true - - /p-map/4.0.0: - resolution: {integrity: sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==} - engines: {node: '>=10'} - dependencies: - aggregate-error: 3.1.0 - dev: true - - /p-pipe/3.1.0: - resolution: {integrity: sha512-08pj8ATpzMR0Y80x50yJHn37NF6vjrqHutASaX5LiH5npS9XPvrUmscd9MF5R4fuYRHOxQR1FfMIlF7AzwoPqw==} - engines: {node: '>=8'} - dev: true - - /p-queue/6.6.2: - resolution: {integrity: sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==} - engines: {node: '>=8'} - dependencies: - eventemitter3: 4.0.7 - p-timeout: 3.2.0 - dev: true - - /p-reduce/2.1.0: - resolution: {integrity: sha512-2USApvnsutq8uoxZBGbbWM0JIYLiEMJ9RlaN7fAzVNb9OZN0SHjjTTfIcb667XynS5Y1VhwDJVDa72TnPzAYWw==} - engines: {node: '>=8'} - dev: true - - /p-timeout/3.2.0: - resolution: {integrity: sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==} - engines: {node: '>=8'} - dependencies: - p-finally: 1.0.0 - dev: true - - /p-try/1.0.0: - resolution: {integrity: sha512-U1etNYuMJoIz3ZXSrrySFjsXQTWOx2/jdi86L+2pRvph/qMKL6sbcCYdH23fqsbm8TH2Gn0OybpT4eSFlCVHww==} - engines: {node: '>=4'} - dev: true - - /p-try/2.2.0: - resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} - engines: {node: '>=6'} - dev: true - - /p-waterfall/2.1.1: - resolution: {integrity: sha512-RRTnDb2TBG/epPRI2yYXsimO0v3BXC8Yd3ogr1545IaqKK17VGhbWVeGGN+XfCm/08OK8635nH31c8bATkHuSw==} - engines: {node: '>=8'} - dependencies: - p-reduce: 2.1.0 - dev: true - - /pacote/11.3.5: - resolution: {integrity: sha512-fT375Yczn4zi+6Hkk2TBe1x1sP8FgFsEIZ2/iWaXY2r/NkhDJfxbcn5paz1+RTFCyNf+dPnaoBDJoAxXSU8Bkg==} - engines: {node: '>=10'} - hasBin: true - dependencies: - '@npmcli/git': 2.1.0 - '@npmcli/installed-package-contents': 1.0.7 - '@npmcli/promise-spawn': 1.3.2 - '@npmcli/run-script': 1.8.6 - cacache: 15.3.0 - chownr: 2.0.0 - fs-minipass: 2.1.0 - infer-owner: 1.0.4 - minipass: 3.3.4 - mkdirp: 1.0.4 - npm-package-arg: 8.1.5 - npm-packlist: 2.2.2 - npm-pick-manifest: 6.1.1 - npm-registry-fetch: 11.0.0 - promise-retry: 2.0.1 - read-package-json-fast: 2.0.3 - rimraf: 3.0.2 - ssri: 8.0.1 - tar: 6.1.11 - transitivePeerDependencies: - - bluebird - - supports-color - dev: true - - /parent-module/1.0.1: - resolution: {integrity: sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==} - engines: {node: '>=6'} - dependencies: - callsites: 3.1.0 - dev: true - - /parse-entities/2.0.0: - resolution: {integrity: sha512-kkywGpCcRYhqQIchaWqZ875wzpS/bMKhz5HnN3p7wveJTkTtyAB/AlnS0f8DFSqYW1T82t6yEAkEcB+A1I3MbQ==} - dependencies: - character-entities: 1.2.4 - character-entities-legacy: 1.1.4 - character-reference-invalid: 1.1.4 - is-alphanumerical: 1.0.4 - is-decimal: 1.0.4 - is-hexadecimal: 1.0.4 - dev: true - - /parse-filepath/1.0.2: - resolution: {integrity: sha512-FwdRXKCohSVeXqwtYonZTXtbGJKrn+HNyWDYVcp5yuJlesTwNH4rsmRZ+GrKAPJ5bLpRxESMeS+Rl0VCHRvB2Q==} - engines: {node: '>=0.8'} - dependencies: - is-absolute: 1.0.0 - map-cache: 0.2.2 - path-root: 0.1.1 - dev: true - - /parse-json/2.2.0: - resolution: {integrity: sha512-QR/GGaKCkhwk1ePQNYDRKYZ3mwU9ypsKhB0XyFnLQdomyEqk3e8wpW3V5Jp88zbxK4n5ST1nqo+g9juTpownhQ==} - engines: {node: '>=0.10.0'} - dependencies: - error-ex: 1.3.2 - dev: true - - /parse-json/4.0.0: - resolution: {integrity: sha512-aOIos8bujGN93/8Ox/jPLh7RwVnPEysynVFE+fQZyg6jKELEHwzgKdLRFHUgXJL6kylijVSBC4BvN9OmsB48Rw==} - engines: {node: '>=4'} - dependencies: - error-ex: 1.3.2 - json-parse-better-errors: 1.0.2 - dev: true - - /parse-json/5.2.0: - resolution: {integrity: sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==} - engines: {node: '>=8'} - dependencies: - '@babel/code-frame': 7.18.6 - error-ex: 1.3.2 - json-parse-even-better-errors: 2.3.1 - lines-and-columns: 1.2.4 - dev: true - - /parse-node-version/1.0.1: - resolution: {integrity: sha512-3YHlOa/JgH6Mnpr05jP9eDG254US9ek25LyIxZlDItp2iJtwyaXQb57lBYLdT3MowkUFYEV2XXNAYIPlESvJlA==} - engines: {node: '>= 0.10'} - dev: true - - /parse-passwd/1.0.0: - resolution: {integrity: sha512-1Y1A//QUXEZK7YKz+rD9WydcE1+EuPr6ZBgKecAB8tmoW6UFv0NREVJe1p+jRxtThkcbbKkfwIbWJe/IeE6m2Q==} - engines: {node: '>=0.10.0'} - dev: true - - /parse-path/4.0.4: - resolution: {integrity: sha512-Z2lWUis7jlmXC1jeOG9giRO2+FsuyNipeQ43HAjqAZjwSe3SEf+q/84FGPHoso3kyntbxa4c4i77t3m6fGf8cw==} - dependencies: - is-ssh: 1.4.0 - protocols: 1.4.8 - qs: 6.11.0 - query-string: 6.14.1 - dev: true - - /parse-url/6.0.5: - resolution: {integrity: sha512-e35AeLTSIlkw/5GFq70IN7po8fmDUjpDPY1rIK+VubRfsUvBonjQ+PBZG+vWMACnQSmNlvl524IucoDmcioMxA==} - dependencies: - is-ssh: 1.4.0 - normalize-url: 6.1.0 - parse-path: 4.0.4 - protocols: 1.4.8 - dev: true - - /pascalcase/0.1.1: - resolution: {integrity: sha512-XHXfu/yOQRy9vYOtUDVMN60OEJjW013GoObG1o+xwQTpB9eYJX/BjXMsdW13ZDPruFhYYn0AG22w0xgQMwl3Nw==} - engines: {node: '>=0.10.0'} - dev: true - - /path-dirname/1.0.2: - resolution: {integrity: sha512-ALzNPpyNq9AqXMBjeymIjFDAkAFH06mHJH/cSBHAgU0s4vfpBn6b2nf8tiRLvagKD8RbTpq2FKTBg7cl9l3c7Q==} - dev: true - - /path-exists/2.1.0: - resolution: {integrity: sha512-yTltuKuhtNeFJKa1PiRzfLAU5182q1y4Eb4XCJ3PBqyzEDkAZRzBrKKBct682ls9reBVHf9udYLN5Nd+K1B9BQ==} - engines: {node: '>=0.10.0'} - dependencies: - pinkie-promise: 2.0.1 - dev: true - - /path-exists/3.0.0: - resolution: {integrity: sha512-bpC7GYwiDYQ4wYLe+FA8lhRjhQCMcQGuSgGGqDkg/QerRWw9CmGRT0iSOVRSZJ29NMLZgIzqaljJ63oaL4NIJQ==} - engines: {node: '>=4'} - dev: true - - /path-exists/4.0.0: - resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} - engines: {node: '>=8'} - dev: true - - /path-is-absolute/1.0.1: - resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} - engines: {node: '>=0.10.0'} - dev: true - - /path-key/2.0.1: - resolution: {integrity: sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==} - engines: {node: '>=4'} - dev: true - - /path-key/3.1.1: - resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} - engines: {node: '>=8'} - dev: true - - /path-parse/1.0.7: - resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} - dev: true - - /path-root-regex/0.1.2: - resolution: {integrity: sha512-4GlJ6rZDhQZFE0DPVKh0e9jmZ5egZfxTkp7bcRDuPlJXbAwhxcl2dINPUAsjLdejqaLsCeg8axcLjIbvBjN4pQ==} - engines: {node: '>=0.10.0'} - dev: true - - /path-root/0.1.1: - resolution: {integrity: sha512-QLcPegTHF11axjfojBIoDygmS2E3Lf+8+jI6wOVmNVenrKSo3mFdSGiIgdSHenczw3wPtlVMQaFVwGmM7BJdtg==} - engines: {node: '>=0.10.0'} - dependencies: - path-root-regex: 0.1.2 - dev: true - - /path-type/1.1.0: - resolution: {integrity: sha512-S4eENJz1pkiQn9Znv33Q+deTOKmbl+jj1Fl+qiP/vYezj+S8x+J3Uo0ISrx/QoEvIlOaDWJhPaRd1flJ9HXZqg==} - engines: {node: '>=0.10.0'} - dependencies: - graceful-fs: 4.2.10 - pify: 2.3.0 - pinkie-promise: 2.0.1 - dev: true - - /path-type/3.0.0: - resolution: {integrity: sha512-T2ZUsdZFHgA3u4e5PfPbjd7HDDpxPnQb5jN0SrDsjNSuVXHJqtwTnWqG0B1jZrgmJ/7lj1EmVIByWt1gxGkWvg==} - engines: {node: '>=4'} - dependencies: - pify: 3.0.0 - dev: true - - /path-type/4.0.0: - resolution: {integrity: sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==} - engines: {node: '>=8'} - dev: true - - /performance-now/2.1.0: - resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} - dev: true - - /picocolors/0.2.1: - resolution: {integrity: sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA==} - dev: true - - /picocolors/1.0.0: - resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==} - dev: true - - /picomatch/2.3.1: - resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} - engines: {node: '>=8.6'} - dev: true - - /pify/2.3.0: - resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} - engines: {node: '>=0.10.0'} - dev: true - - /pify/3.0.0: - resolution: {integrity: sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==} - engines: {node: '>=4'} - dev: true - - /pify/4.0.1: - resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} - engines: {node: '>=6'} - dev: true - - /pify/5.0.0: - resolution: {integrity: sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA==} - engines: {node: '>=10'} - dev: true - - /pinkie-promise/2.0.1: - resolution: {integrity: sha512-0Gni6D4UcLTbv9c57DfxDGdr41XfgUjqWZu492f0cIGr16zDU06BWP/RAEvOuo7CQ0CNjHaLlM59YJJFm3NWlw==} - engines: {node: '>=0.10.0'} - dependencies: - pinkie: 2.0.4 - dev: true - - /pinkie/2.0.4: - resolution: {integrity: sha512-MnUuEycAemtSaeFSjXKW/aroV7akBbY+Sv+RkyqFjgAe73F+MR0TBWKBRDkmfWq/HiFmdavfZ1G7h4SPZXaCSg==} - engines: {node: '>=0.10.0'} - dev: true - - /pkg-dir/4.2.0: - resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} - engines: {node: '>=8'} - dependencies: - find-up: 4.1.0 - dev: true - - /please-upgrade-node/3.2.0: - resolution: {integrity: sha512-gQR3WpIgNIKwBMVLkpMUeR3e1/E1y42bqDQZfql+kDeXd8COYfM8PQA4X6y7a8u9Ua9FHmsrrmirW2vHs45hWg==} - dependencies: - semver-compare: 1.0.0 - dev: true - - /posix-character-classes/0.1.1: - resolution: {integrity: sha512-xTgYBc3fuo7Yt7JbiuFxSYGToMoz8fLoE6TC9Wx1P/u+LfeThMOAqmuyECnlBaaJb+u1m9hHiXUEtwW4OzfUJg==} - engines: {node: '>=0.10.0'} - dev: true - - /postcss-html/0.36.0_j55xdkkcxc32kvnyvx3y7casfm: - resolution: {integrity: sha512-HeiOxGcuwID0AFsNAL0ox3mW6MHH5cstWN1Z3Y+n6H+g12ih7LHdYxWwEA/QmrebctLjo79xz9ouK3MroHwOJw==} - peerDependencies: - postcss: '>=5.0.0' - postcss-syntax: '>=0.36.0' - dependencies: - htmlparser2: 3.10.1 - postcss: 7.0.39 - postcss-syntax: 0.36.2_kei4jy7wdgbhc236h4oijypxom - dev: true - - /postcss-less/3.1.4: - resolution: {integrity: sha512-7TvleQWNM2QLcHqvudt3VYjULVB49uiW6XzEUFmvwHzvsOEF5MwBrIXZDJQvJNFGjJQTzSzZnDoCJ8h/ljyGXA==} - engines: {node: '>=6.14.4'} - dependencies: - postcss: 7.0.39 - dev: true - - /postcss-media-query-parser/0.2.3: - resolution: {integrity: sha512-3sOlxmbKcSHMjlUXQZKQ06jOswE7oVkXPxmZdoB1r5l0q6gTFTQSHxNxOrCccElbW7dxNytifNEo8qidX2Vsig==} - dev: true - - /postcss-resolve-nested-selector/0.1.1: - resolution: {integrity: sha512-HvExULSwLqHLgUy1rl3ANIqCsvMS0WHss2UOsXhXnQaZ9VCc2oBvIpXrl00IUFT5ZDITME0o6oiXeiHr2SAIfw==} - dev: true - - /postcss-safe-parser/4.0.2: - resolution: {integrity: sha512-Uw6ekxSWNLCPesSv/cmqf2bY/77z11O7jZGPax3ycZMFU/oi2DMH9i89AdHc1tRwFg/arFoEwX0IS3LCUxJh1g==} - engines: {node: '>=6.0.0'} - dependencies: - postcss: 7.0.39 - dev: true - - /postcss-sass/0.4.4: - resolution: {integrity: sha512-BYxnVYx4mQooOhr+zer0qWbSPYnarAy8ZT7hAQtbxtgVf8gy+LSLT/hHGe35h14/pZDTw1DsxdbrwxBN++H+fg==} - dependencies: - gonzales-pe: 4.3.0 - postcss: 7.0.39 - dev: true - - /postcss-scss/2.1.1: - resolution: {integrity: sha512-jQmGnj0hSGLd9RscFw9LyuSVAa5Bl1/KBPqG1NQw9w8ND55nY4ZEsdlVuYJvLPpV+y0nwTV5v/4rHPzZRihQbA==} - engines: {node: '>=6.0.0'} - dependencies: - postcss: 7.0.39 - dev: true - - /postcss-selector-parser/6.0.10: - resolution: {integrity: sha512-IQ7TZdoaqbT+LCpShg46jnZVlhWD2w6iQYAcYXfHARZ7X1t/UGhhceQDs5X0cGqKvYlHNOuv7Oa1xmb0oQuA3w==} - engines: {node: '>=4'} - dependencies: - cssesc: 3.0.0 - util-deprecate: 1.0.2 - dev: true - - /postcss-syntax/0.36.2_kei4jy7wdgbhc236h4oijypxom: - resolution: {integrity: sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==} - peerDependencies: - postcss: '>=5.0.0' - postcss-html: '*' - postcss-jsx: '*' - postcss-less: '*' - postcss-markdown: '*' - postcss-scss: '*' - peerDependenciesMeta: - postcss-html: - optional: true - postcss-jsx: - optional: true - postcss-less: - optional: true - postcss-markdown: - optional: true - postcss-scss: - optional: true - dependencies: - postcss: 7.0.39 - postcss-html: 0.36.0_j55xdkkcxc32kvnyvx3y7casfm - postcss-less: 3.1.4 - postcss-scss: 2.1.1 - dev: true - - /postcss-value-parser/4.2.0: - resolution: {integrity: sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==} - dev: true - - /postcss/7.0.39: - resolution: {integrity: sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA==} - engines: {node: '>=6.0.0'} - dependencies: - picocolors: 0.2.1 - source-map: 0.6.1 - dev: true - - /prelude-ls/1.2.1: - resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} - engines: {node: '>= 0.8.0'} - dev: true - - /prettier-linter-helpers/1.0.0: - resolution: {integrity: sha512-GbK2cP9nraSSUF9N2XwUwqfzlAFlMNYYl+ShE/V+H8a9uNl/oUqB1w2EL54Jh0OlyRSd8RfWYJ3coVS4TROP2w==} - engines: {node: '>=6.0.0'} - dependencies: - fast-diff: 1.2.0 - dev: true - - /prettier/2.7.1: - resolution: {integrity: sha512-ujppO+MkdPqoVINuDFDRLClm7D78qbDt0/NR+wp5FqEZOoTNAjPHWj17QRhu7geIHJfcNhRk1XVQmF8Bp3ye+g==} - engines: {node: '>=10.13.0'} - hasBin: true - dev: true - - /pretty-hrtime/1.0.3: - resolution: {integrity: sha512-66hKPCr+72mlfiSjlEB1+45IjXSqvVAIy6mocupoww4tBFE9R9IhwwUGoI4G++Tc9Aq+2rxOt0RFU6gPcrte0A==} - engines: {node: '>= 0.8'} - dev: true - - /process-nextick-args/2.0.1: - resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} - dev: true - - /progress/2.0.3: - resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} - engines: {node: '>=0.4.0'} - dev: true - - /promise-inflight/1.0.1: - resolution: {integrity: sha512-6zWPyEOFaQBJYcGMHBKTKJ3u6TBsnMFOIZSa6ce1e/ZrrsOlnHRHbabMjLiBYKp+n44X9eUI6VUPaukCXHuG4g==} - peerDependencies: - bluebird: '*' - peerDependenciesMeta: - bluebird: - optional: true - dev: true - - /promise-retry/2.0.1: - resolution: {integrity: sha512-y+WKFlBR8BGXnsNlIHFGPZmyDf3DFMoLhaflAnyZgV6rG6xu+JwesTo2Q9R6XwYmtmwAFCkAk3e35jEdoeh/3g==} - engines: {node: '>=10'} - dependencies: - err-code: 2.0.3 - retry: 0.12.0 - dev: true - - /promzard/0.3.0: - resolution: {integrity: sha512-JZeYqd7UAcHCwI+sTOeUDYkvEU+1bQ7iE0UT1MgB/tERkAPkesW46MrpIySzODi+owTjZtiF8Ay5j9m60KmMBw==} - dependencies: - read: 1.0.7 - dev: true - - /prop-types/15.8.1: - resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} - dependencies: - loose-envify: 1.4.0 - object-assign: 4.1.1 - react-is: 16.13.1 - dev: true - - /proto-list/1.2.4: - resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} - dev: true - - /protocols/1.4.8: - resolution: {integrity: sha512-IgjKyaUSjsROSO8/D49Ab7hP8mJgTYcqApOqdPhLoPxAplXmkp+zRvsrSQjFn5by0rhm4VH0GAUELIPpx7B1yg==} - dev: true - - /protocols/2.0.1: - resolution: {integrity: sha512-/XJ368cyBJ7fzLMwLKv1e4vLxOju2MNAIokcr7meSaNcVbWz/CPcW22cP04mwxOErdA5mwjA8Q6w/cdAQxVn7Q==} - dev: true - - /psl/1.9.0: - resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} - dev: true - - /pump/2.0.1: - resolution: {integrity: sha512-ruPMNRkN3MHP1cWJc9OWr+T/xDP0jhXYCLfJcBuX54hhfIBnaQmAUMfDcG4DM5UMWByBbJY69QSphm3jtDKIkA==} - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - dev: true - - /pump/3.0.0: - resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} - dependencies: - end-of-stream: 1.4.4 - once: 1.4.0 - dev: true - - /pumpify/1.5.1: - resolution: {integrity: sha512-oClZI37HvuUJJxSKKrC17bZ9Cu0ZYhEAGPsPUy9KlMUmv9dKX2o77RUmq7f3XjIxbwyGwYzbzQ1L2Ks8sIradQ==} - dependencies: - duplexify: 3.7.1 - inherits: 2.0.4 - pump: 2.0.1 - dev: true - - /punycode/2.1.1: - resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} - engines: {node: '>=6'} - dev: true - - /q/1.5.1: - resolution: {integrity: sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==} - engines: {node: '>=0.6.0', teleport: '>=0.2.0'} - dev: true - - /qs/6.11.0: - resolution: {integrity: sha512-MvjoMCJwEarSbUYk5O+nmoSzSutSsTwF85zcHPQ9OrlFoZOYIjaqBAJIqIXjptyD5vThxGq52Xu/MaJzRkIk4Q==} - engines: {node: '>=0.6'} - dependencies: - side-channel: 1.0.4 - dev: true - - /qs/6.5.3: - resolution: {integrity: sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==} - engines: {node: '>=0.6'} - dev: true - - /query-string/6.14.1: - resolution: {integrity: sha512-XDxAeVmpfu1/6IjyT/gXHOl+S0vQ9owggJ30hhWKdHAsNPOcasn5o9BW0eejZqL2e4vMjhAxoW3jVHcD6mbcYw==} - engines: {node: '>=6'} - dependencies: - decode-uri-component: 0.2.0 - filter-obj: 1.1.0 - split-on-first: 1.1.0 - strict-uri-encode: 2.0.0 - dev: true - - /queue-microtask/1.2.3: - resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} - dev: true - - /quick-lru/4.0.1: - resolution: {integrity: sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g==} - engines: {node: '>=8'} - dev: true - - /react-is/16.13.1: - resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==} - dev: true - - /read-cmd-shim/2.0.0: - resolution: {integrity: sha512-HJpV9bQpkl6KwjxlJcBoqu9Ba0PQg8TqSNIOrulGt54a0uup0HtevreFHzYzkm0lpnleRdNBzXznKrgxglEHQw==} - dev: true - - /read-package-json-fast/2.0.3: - resolution: {integrity: sha512-W/BKtbL+dUjTuRL2vziuYhp76s5HZ9qQhd/dKfWIZveD0O40453QNyZhC0e63lqZrAQ4jiOapVoeJ7JrszenQQ==} - engines: {node: '>=10'} - dependencies: - json-parse-even-better-errors: 2.3.1 - npm-normalize-package-bin: 1.0.1 - dev: true - - /read-package-json/2.1.2: - resolution: {integrity: sha512-D1KmuLQr6ZSJS0tW8hf3WGpRlwszJOXZ3E8Yd/DNRaM5d+1wVRZdHlpGBLAuovjr28LbWvjpWkBHMxpRGGjzNA==} - dependencies: - glob: 7.2.3 - json-parse-even-better-errors: 2.3.1 - normalize-package-data: 2.5.0 - npm-normalize-package-bin: 1.0.1 - dev: true - - /read-package-json/3.0.1: - resolution: {integrity: sha512-aLcPqxovhJTVJcsnROuuzQvv6oziQx4zd3JvG0vGCL5MjTONUc4uJ90zCBC6R7W7oUKBNoR/F8pkyfVwlbxqng==} - engines: {node: '>=10'} - dependencies: - glob: 7.2.3 - json-parse-even-better-errors: 2.3.1 - normalize-package-data: 3.0.3 - npm-normalize-package-bin: 1.0.1 - dev: true - - /read-package-json/4.1.2: - resolution: {integrity: sha512-Dqer4pqzamDE2O4M55xp1qZMuLPqi4ldk2ya648FOMHRjwMzFhuxVrG04wd0c38IsvkVdr3vgHI6z+QTPdAjrQ==} - engines: {node: '>=10'} - dependencies: - glob: 7.2.3 - json-parse-even-better-errors: 2.3.1 - normalize-package-data: 3.0.3 - npm-normalize-package-bin: 1.0.1 - dev: true - - /read-package-tree/5.3.1: - resolution: {integrity: sha512-mLUDsD5JVtlZxjSlPPx1RETkNjjvQYuweKwNVt1Sn8kP5Jh44pvYuUHCp6xSVDZWbNxVxG5lyZJ921aJH61sTw==} - deprecated: The functionality that this package provided is now in @npmcli/arborist - dependencies: - read-package-json: 2.1.2 - readdir-scoped-modules: 1.1.0 - util-promisify: 2.1.0 - dev: true - - /read-pkg-up/1.0.1: - resolution: {integrity: sha512-WD9MTlNtI55IwYUS27iHh9tK3YoIVhxis8yKhLpTqWtml739uXc9NWTpxoHkfZf3+DkCCsXox94/VWZniuZm6A==} - engines: {node: '>=0.10.0'} - dependencies: - find-up: 1.1.2 - read-pkg: 1.1.0 - dev: true - - /read-pkg-up/3.0.0: - resolution: {integrity: sha512-YFzFrVvpC6frF1sz8psoHDBGF7fLPc+llq/8NB43oagqWkx8ar5zYtsTORtOjw9W2RHLpWP+zTWwBvf1bCmcSw==} - engines: {node: '>=4'} - dependencies: - find-up: 2.1.0 - read-pkg: 3.0.0 - dev: true - - /read-pkg-up/7.0.1: - resolution: {integrity: sha512-zK0TB7Xd6JpCLmlLmufqykGE+/TlOePD6qKClNW7hHDKFh/J7/7gCWGR7joEQEW1bKq3a3yUZSObOoWLFQ4ohg==} - engines: {node: '>=8'} - dependencies: - find-up: 4.1.0 - read-pkg: 5.2.0 - type-fest: 0.8.1 - dev: true - - /read-pkg/1.1.0: - resolution: {integrity: sha512-7BGwRHqt4s/uVbuyoeejRn4YmFnYZiFl4AuaeXHlgZf3sONF0SOGlxs2Pw8g6hCKupo08RafIO5YXFNOKTfwsQ==} - engines: {node: '>=0.10.0'} - dependencies: - load-json-file: 1.1.0 - normalize-package-data: 2.5.0 - path-type: 1.1.0 - dev: true - - /read-pkg/3.0.0: - resolution: {integrity: sha512-BLq/cCO9two+lBgiTYNqD6GdtK8s4NpaWrl6/rCO9w0TUS8oJl7cmToOZfRYllKTISY6nt1U7jQ53brmKqY6BA==} - engines: {node: '>=4'} - dependencies: - load-json-file: 4.0.0 - normalize-package-data: 2.5.0 - path-type: 3.0.0 - dev: true - - /read-pkg/5.2.0: - resolution: {integrity: sha512-Ug69mNOpfvKDAc2Q8DRpMjjzdtrnv9HcSMX+4VsZxD1aZ6ZzrIE7rlzXBtWTyhULSMKg076AW6WR5iZpD0JiOg==} - engines: {node: '>=8'} - dependencies: - '@types/normalize-package-data': 2.4.1 - normalize-package-data: 2.5.0 - parse-json: 5.2.0 - type-fest: 0.6.0 - dev: true - - /read/1.0.7: - resolution: {integrity: sha512-rSOKNYUmaxy0om1BNjMN4ezNT6VKK+2xF4GBhc81mkH7L60i6dp8qPYrkndNLT3QPphoII3maL9PVC9XmhHwVQ==} - engines: {node: '>=0.8'} - dependencies: - mute-stream: 0.0.8 - dev: true - - /readable-stream/2.3.7: - resolution: {integrity: sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==} - dependencies: - core-util-is: 1.0.3 - inherits: 2.0.4 - isarray: 1.0.0 - process-nextick-args: 2.0.1 - safe-buffer: 5.1.2 - string_decoder: 1.1.1 - util-deprecate: 1.0.2 - dev: true - - /readable-stream/3.6.0: - resolution: {integrity: sha512-BViHy7LKeTz4oNnkcLJ+lVSL6vpiFeX6/d3oSH8zCW7UxP2onchk+vTGB143xuFjHS3deTgkKoXXymXqymiIdA==} - engines: {node: '>= 6'} - dependencies: - inherits: 2.0.4 - string_decoder: 1.3.0 - util-deprecate: 1.0.2 - dev: true - - /readdir-scoped-modules/1.1.0: - resolution: {integrity: sha512-asaikDeqAQg7JifRsZn1NJZXo9E+VwlyCfbkZhwyISinqk5zNS6266HS5kah6P0SaQKGF6SkNnZVHUzHFYxYDw==} - dependencies: - debuglog: 1.0.1 - dezalgo: 1.0.4 - graceful-fs: 4.2.10 - once: 1.4.0 - dev: true - - /readdirp/2.2.1: - resolution: {integrity: sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==} - engines: {node: '>=0.10'} - dependencies: - graceful-fs: 4.2.10 - micromatch: 3.1.10 - readable-stream: 2.3.7 - transitivePeerDependencies: - - supports-color - dev: true - - /rechoir/0.6.2: - resolution: {integrity: sha512-HFM8rkZ+i3zrV+4LQjwQ0W+ez98pApMGM3HUrN04j3CqzPOzl9nmP15Y8YXNm8QHGv/eacOVEjqhmWpkRV0NAw==} - engines: {node: '>= 0.10'} - dependencies: - resolve: 1.22.1 - dev: true - - /redent/3.0.0: - resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} - engines: {node: '>=8'} - dependencies: - indent-string: 4.0.0 - strip-indent: 3.0.0 - dev: true - - /regenerator-runtime/0.13.10: - resolution: {integrity: sha512-KepLsg4dU12hryUO7bp/axHAKvwGOCV0sGloQtpagJ12ai+ojVDqkeGSiRX1zlq+kjIMZ1t7gpze+26QqtdGqw==} - dev: true - - /regex-not/1.0.2: - resolution: {integrity: sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 3.0.2 - safe-regex: 1.1.0 - dev: true - - /regexp.prototype.flags/1.4.3: - resolution: {integrity: sha512-fjggEOO3slI6Wvgjwflkc4NFRCTZAu5CnNfBd5qOMYhWdn67nJBBu34/TkD++eeFmd8C9r9jfXJ27+nSiRkSUA==} - engines: {node: '>= 0.4'} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - functions-have-names: 1.2.3 - dev: true - - /regexpp/3.2.0: - resolution: {integrity: sha512-pq2bWo9mVD43nbts2wGv17XLiNLya+GklZ8kaDLV2Z08gDCsGpnKn9BFMepvWuHCbyVvY7J5o5+BVvoQbmlJLg==} - engines: {node: '>=8'} - dev: true - - /regextras/0.8.0: - resolution: {integrity: sha512-k519uI04Z3SaY0fLX843MRXnDeG2+vHOFsyhiPZvNLe7r8rD2YNRjq4BQLZZ0oAr2NrtvZlICsXysGNFPGa3CQ==} - engines: {node: '>=0.1.14'} - dev: true - - /remark-parse/9.0.0: - resolution: {integrity: sha512-geKatMwSzEXKHuzBNU1z676sGcDcFoChMK38TgdHJNAYfFtsfHDQG7MoJAjs6sgYMqyLduCYWDIWZIxiPeafEw==} - dependencies: - mdast-util-from-markdown: 0.8.5 - transitivePeerDependencies: - - supports-color - dev: true - - /remark-stringify/9.0.1: - resolution: {integrity: sha512-mWmNg3ZtESvZS8fv5PTvaPckdL4iNlCHTt8/e/8oN08nArHRHjNZMKzA/YW3+p7/lYqIw4nx1XsjCBo/AxNChg==} - dependencies: - mdast-util-to-markdown: 0.6.5 - dev: true - - /remark/13.0.0: - resolution: {integrity: sha512-HDz1+IKGtOyWN+QgBiAT0kn+2s6ovOxHyPAFGKVE81VSzJ+mq7RwHFledEvB5F1p4iJvOah/LOKdFuzvRnNLCA==} - dependencies: - remark-parse: 9.0.0 - remark-stringify: 9.0.1 - unified: 9.2.2 - transitivePeerDependencies: - - supports-color - dev: true - - /remove-bom-buffer/3.0.0: - resolution: {integrity: sha512-8v2rWhaakv18qcvNeli2mZ/TMTL2nEyAKRvzo1WtnZBl15SHyEhrCu2/xKlJyUFKHiHgfXIyuY6g2dObJJycXQ==} - engines: {node: '>=0.10.0'} - dependencies: - is-buffer: 1.1.6 - is-utf8: 0.2.1 - dev: true - - /remove-bom-stream/1.2.0: - resolution: {integrity: sha512-wigO8/O08XHb8YPzpDDT+QmRANfW6vLqxfaXm1YXhnFf3AkSLyjfG3GEFg4McZkmgL7KvCj5u2KczkvSP6NfHA==} - engines: {node: '>= 0.10'} - dependencies: - remove-bom-buffer: 3.0.0 - safe-buffer: 5.2.1 - through2: 2.0.5 - dev: true - - /remove-trailing-separator/1.1.0: - resolution: {integrity: sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==} - dev: true - - /repeat-element/1.1.4: - resolution: {integrity: sha512-LFiNfRcSu7KK3evMyYOuCzv3L10TW7yC1G2/+StMjK8Y6Vqd2MG7r/Qjw4ghtuCOjFvlnms/iMmLqpvW/ES/WQ==} - engines: {node: '>=0.10.0'} - dev: true - - /repeat-string/1.6.1: - resolution: {integrity: sha512-PV0dzCYDNfRi1jCDbJzpW7jNNDRuCOG/jI5ctQcGKt/clZD+YcPS3yIlWuTJMmESC8aevCFmWJy5wjAFgNqN6w==} - engines: {node: '>=0.10'} - dev: true - - /replace-ext/1.0.1: - resolution: {integrity: sha512-yD5BHCe7quCgBph4rMQ+0KkIRKwWCrHDOX1p1Gp6HwjPM5kVoCdKGNhN7ydqqsX6lJEnQDKZ/tFMiEdQ1dvPEw==} - engines: {node: '>= 0.10'} - dev: true - - /replace-homedir/1.0.0: - resolution: {integrity: sha512-CHPV/GAglbIB1tnQgaiysb8H2yCy8WQ7lcEwQ/eT+kLj0QHV8LnJW0zpqpE7RSkrMSRoa+EBoag86clf7WAgSg==} - engines: {node: '>= 0.10'} - dependencies: - homedir-polyfill: 1.0.3 - is-absolute: 1.0.0 - remove-trailing-separator: 1.1.0 - dev: true - - /request/2.88.2: - resolution: {integrity: sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==} - engines: {node: '>= 6'} - deprecated: request has been deprecated, see https://github.com/request/request/issues/3142 - dependencies: - aws-sign2: 0.7.0 - aws4: 1.11.0 - caseless: 0.12.0 - combined-stream: 1.0.8 - extend: 3.0.2 - forever-agent: 0.6.1 - form-data: 2.3.3 - har-validator: 5.1.5 - http-signature: 1.2.0 - is-typedarray: 1.0.0 - isstream: 0.1.2 - json-stringify-safe: 5.0.1 - mime-types: 2.1.35 - oauth-sign: 0.9.0 - performance-now: 2.1.0 - qs: 6.5.3 - safe-buffer: 5.2.1 - tough-cookie: 2.5.0 - tunnel-agent: 0.6.0 - uuid: 3.4.0 - dev: true - - /require-directory/2.1.1: - resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} - engines: {node: '>=0.10.0'} - dev: true - - /require-from-string/2.0.2: - resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==} - engines: {node: '>=0.10.0'} - dev: true - - /require-main-filename/1.0.1: - resolution: {integrity: sha512-IqSUtOVP4ksd1C/ej5zeEh/BIP2ajqpn8c5x+q99gvcIG/Qf0cud5raVnE/Dwd0ua9TXYDoDc0RE5hBSdz22Ug==} - dev: true - - /require-main-filename/2.0.0: - resolution: {integrity: sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==} - dev: true - - /resolve-cwd/3.0.0: - resolution: {integrity: sha512-OrZaX2Mb+rJCpH/6CpSqt9xFVpN++x01XnN2ie9g6P5/3xelLAkXWVADpdz1IHD/KFfEXyE6V0U01OQ3UO2rEg==} - engines: {node: '>=8'} - dependencies: - resolve-from: 5.0.0 - dev: true - - /resolve-dir/1.0.1: - resolution: {integrity: sha512-R7uiTjECzvOsWSfdM0QKFNBVFcK27aHOUwdvK53BcW8zqnGdYp0Fbj82cy54+2A4P2tFM22J5kRfe1R+lM/1yg==} - engines: {node: '>=0.10.0'} - dependencies: - expand-tilde: 2.0.2 - global-modules: 1.0.0 - dev: true - - /resolve-from/3.0.0: - resolution: {integrity: sha512-GnlH6vxLymXJNMBo7XP1fJIzBFbdYt49CuTwmB/6N53t+kMPRMFKz783LlQ4tv28XoQfMWinAJX6WCGf2IlaIw==} - engines: {node: '>=4'} - dev: true - - /resolve-from/4.0.0: - resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==} - engines: {node: '>=4'} - dev: true - - /resolve-from/5.0.0: - resolution: {integrity: sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==} - engines: {node: '>=8'} - dev: true - - /resolve-global/1.0.0: - resolution: {integrity: sha512-zFa12V4OLtT5XUX/Q4VLvTfBf+Ok0SPc1FNGM/z9ctUdiU618qwKpWnd0CHs3+RqROfyEg/DhuHbMWYqcgljEw==} - engines: {node: '>=8'} - dependencies: - global-dirs: 0.1.1 - dev: true - - /resolve-options/1.1.0: - resolution: {integrity: sha512-NYDgziiroVeDC29xq7bp/CacZERYsA9bXYd1ZmcJlF3BcrZv5pTb4NG7SjdyKDnXZ84aC4vo2u6sNKIA1LCu/A==} - engines: {node: '>= 0.10'} - dependencies: - value-or-function: 3.0.0 - dev: true - - /resolve-url/0.2.1: - resolution: {integrity: sha512-ZuF55hVUQaaczgOIwqWzkEcEidmlD/xl44x1UZnhOXcYuFN2S6+rcxpG+C1N3So0wvNI3DmJICUFfu2SxhBmvg==} - deprecated: https://github.com/lydell/resolve-url#deprecated - dev: true - - /resolve/1.22.1: - resolution: {integrity: sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==} - hasBin: true - dependencies: - is-core-module: 2.11.0 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - dev: true - - /resolve/2.0.0-next.4: - resolution: {integrity: sha512-iMDbmAWtfU+MHpxt/I5iWI7cY6YVEZUQ3MBgPQ++XD1PELuJHIl82xBmObyP2KyQmkNB2dsqF7seoQQiAn5yDQ==} - hasBin: true - dependencies: - is-core-module: 2.11.0 - path-parse: 1.0.7 - supports-preserve-symlinks-flag: 1.0.0 - dev: true - - /restore-cursor/3.1.0: - resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} - engines: {node: '>=8'} - dependencies: - onetime: 5.1.2 - signal-exit: 3.0.7 - dev: true - - /ret/0.1.15: - resolution: {integrity: sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==} - engines: {node: '>=0.12'} - dev: true - - /retry/0.12.0: - resolution: {integrity: sha512-9LkiTwjUh6rT555DtE9rTX+BKByPfrMzEAtnlEtdEwr3Nkffwiihqe2bWADg+OQRjt9gl6ICdmB/ZFDCGAtSow==} - engines: {node: '>= 4'} - dev: true - - /reusify/1.0.4: - resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==} - engines: {iojs: '>=1.0.0', node: '>=0.10.0'} - dev: true - - /rimraf/2.7.1: - resolution: {integrity: sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==} - hasBin: true - dependencies: - glob: 7.2.3 - dev: true - - /rimraf/3.0.2: - resolution: {integrity: sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==} - hasBin: true - dependencies: - glob: 7.2.3 - dev: true - - /run-async/2.4.1: - resolution: {integrity: sha512-tvVnVv01b8c1RrA6Ep7JkStj85Guv/YrMcwqYQnwjsAS2cTmmPGBBjAjpCW7RrSodNSoE2/qg9O4bceNvUuDgQ==} - engines: {node: '>=0.12.0'} - dev: true - - /run-node/1.0.0: - resolution: {integrity: sha512-kc120TBlQ3mih1LSzdAJXo4xn/GWS2ec0l3S+syHDXP9uRr0JAT8Qd3mdMuyjqCzeZktgP3try92cEgf9Nks8A==} - engines: {node: '>=4'} - hasBin: true - dev: true - - /run-parallel/1.2.0: - resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==} - dependencies: - queue-microtask: 1.2.3 - dev: true - - /rxjs/6.6.7: - resolution: {integrity: sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==} - engines: {npm: '>=2.0.0'} - dependencies: - tslib: 1.14.1 - dev: true - - /safe-buffer/5.1.2: - resolution: {integrity: sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==} - dev: true - - /safe-buffer/5.2.1: - resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==} - dev: true - - /safe-regex-test/1.0.0: - resolution: {integrity: sha512-JBUUzyOgEwXQY1NuPtvcj/qcBDbDmEvWufhlnXZIm75DEHp+afM1r1ujJpJsV/gSM4t59tpDyPi1sd6ZaPFfsA==} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.1.3 - is-regex: 1.1.4 - dev: true - - /safe-regex/1.1.0: - resolution: {integrity: sha512-aJXcif4xnaNUzvUuC5gcb46oTS7zvg4jpMTnuqtrEPlR3vFr4pxtdTwaF1Qs3Enjn9HK+ZlwQui+a7z0SywIzg==} - dependencies: - ret: 0.1.15 - dev: true - - /safer-buffer/2.1.2: - resolution: {integrity: sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==} - dev: true - - /semver-compare/1.0.0: - resolution: {integrity: sha512-YM3/ITh2MJ5MtzaM429anh+x2jiLVjqILF4m4oyQB18W7Ggea7BfqdH/wGMK7dDiMghv/6WG7znWMwUDzJiXow==} - dev: true - - /semver-greatest-satisfied-range/1.1.0: - resolution: {integrity: sha512-Ny/iyOzSSa8M5ML46IAx3iXc6tfOsYU2R4AXi2UpHk60Zrgyq6eqPj/xiOfS0rRl/iiQ/rdJkVjw/5cdUyCntQ==} - engines: {node: '>= 0.10'} - dependencies: - sver-compat: 1.5.0 - dev: true - - /semver/5.7.1: - resolution: {integrity: sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==} - hasBin: true - dev: true - - /semver/6.3.0: - resolution: {integrity: sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==} - hasBin: true - dev: true - - /semver/7.3.2: - resolution: {integrity: sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==} - engines: {node: '>=10'} - hasBin: true - dev: true - - /semver/7.3.8: - resolution: {integrity: sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==} - engines: {node: '>=10'} - hasBin: true - dependencies: - lru-cache: 6.0.0 - dev: true - - /set-blocking/2.0.0: - resolution: {integrity: sha512-KiKBS8AnWGEyLzofFfmvKwpdPzqiy16LvQfK3yv/fVH7Bj13/wl3JSR1J+rfgRE9q7xUJK4qvgS8raSOeLUehw==} - dev: true - - /set-value/2.0.1: - resolution: {integrity: sha512-JxHc1weCN68wRY0fhCoXpyK55m/XPHafOmK4UWD7m2CI14GMcFypt4w/0+NV5f/ZMby2F6S2wwA7fgynh9gWSw==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 2.0.1 - is-extendable: 0.1.1 - is-plain-object: 2.0.4 - split-string: 3.1.0 - dev: true - - /shallow-clone/3.0.1: - resolution: {integrity: sha512-/6KqX+GVUdqPuPPd2LxDDxzX6CAbjJehAAOKlNpqqUpAqPM6HeL8f+o3a+JsyGjn2lv0WY8UsTgUJjU9Ok55NA==} - engines: {node: '>=8'} - dependencies: - kind-of: 6.0.3 - dev: true - - /shebang-command/1.2.0: - resolution: {integrity: sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==} - engines: {node: '>=0.10.0'} - dependencies: - shebang-regex: 1.0.0 - dev: true - - /shebang-command/2.0.0: - resolution: {integrity: sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==} - engines: {node: '>=8'} - dependencies: - shebang-regex: 3.0.0 - dev: true - - /shebang-regex/1.0.0: - resolution: {integrity: sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==} - engines: {node: '>=0.10.0'} - dev: true - - /shebang-regex/3.0.0: - resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} - engines: {node: '>=8'} - dev: true - - /side-channel/1.0.4: - resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} - dependencies: - call-bind: 1.0.2 - get-intrinsic: 1.1.3 - object-inspect: 1.12.2 - dev: true - - /signal-exit/3.0.7: - resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - dev: true - - /slash/3.0.0: - resolution: {integrity: sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==} - engines: {node: '>=8'} - dev: true - - /slice-ansi/4.0.0: - resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - astral-regex: 2.0.0 - is-fullwidth-code-point: 3.0.0 - dev: true - - /slide/1.1.6: - resolution: {integrity: sha512-NwrtjCg+lZoqhFU8fOwl4ay2ei8PaqCBOUV3/ektPY9trO1yQ1oXEfmHAhKArUVUr/hOHvy5f6AdP17dCM0zMw==} - dev: true - - /smart-buffer/4.2.0: - resolution: {integrity: sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==} - engines: {node: '>= 6.0.0', npm: '>= 3.0.0'} - dev: true - - /snapdragon-node/2.1.1: - resolution: {integrity: sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==} - engines: {node: '>=0.10.0'} - dependencies: - define-property: 1.0.0 - isobject: 3.0.1 - snapdragon-util: 3.0.1 - dev: true - - /snapdragon-util/3.0.1: - resolution: {integrity: sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /snapdragon/0.8.2: - resolution: {integrity: sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==} - engines: {node: '>=0.10.0'} - dependencies: - base: 0.11.2 - debug: 2.6.9 - define-property: 0.2.5 - extend-shallow: 2.0.1 - map-cache: 0.2.2 - source-map: 0.5.7 - source-map-resolve: 0.5.3 - use: 3.1.1 - transitivePeerDependencies: - - supports-color - dev: true - - /socks-proxy-agent/5.0.1: - resolution: {integrity: sha512-vZdmnjb9a2Tz6WEQVIurybSwElwPxMZaIc7PzqbJTrezcKNznv6giT7J7tZDZ1BojVaa1jvO/UiUdhDVB0ACoQ==} - engines: {node: '>= 6'} - dependencies: - agent-base: 6.0.2 - debug: 4.3.4 - socks: 2.7.1 - transitivePeerDependencies: - - supports-color - dev: true - - /socks-proxy-agent/6.2.1: - resolution: {integrity: sha512-a6KW9G+6B3nWZ1yB8G7pJwL3ggLy1uTzKAgCb7ttblwqdz9fMGJUuTy3uFzEP48FAs9FLILlmzDlE2JJhVQaXQ==} - engines: {node: '>= 10'} - dependencies: - agent-base: 6.0.2 - debug: 4.3.4 - socks: 2.7.1 - transitivePeerDependencies: - - supports-color - dev: true - - /socks/2.7.1: - resolution: {integrity: sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==} - engines: {node: '>= 10.13.0', npm: '>= 3.0.0'} - dependencies: - ip: 2.0.0 - smart-buffer: 4.2.0 - dev: true - - /sort-keys/2.0.0: - resolution: {integrity: sha512-/dPCrG1s3ePpWm6yBbxZq5Be1dXGLyLn9Z791chDC3NFrpkVbWGzkBwPN1knaciexFXgRJ7hzdnwZ4stHSDmjg==} - engines: {node: '>=4'} - dependencies: - is-plain-obj: 1.1.0 - dev: true - - /sort-keys/4.2.0: - resolution: {integrity: sha512-aUYIEU/UviqPgc8mHR6IW1EGxkAXpeRETYcrzg8cLAvUPZcpAlleSXHV2mY7G12GphSH6Gzv+4MMVSSkbdteHg==} - engines: {node: '>=8'} - dependencies: - is-plain-obj: 2.1.0 - dev: true - - /source-map-resolve/0.5.3: - resolution: {integrity: sha512-Htz+RnsXWk5+P2slx5Jh3Q66vhQj1Cllm0zvnaY98+NFx+Dv2CF/f5O/t8x+KaNdrdIAsruNzoh/KpialbqAnw==} - deprecated: See https://github.com/lydell/source-map-resolve#deprecated - dependencies: - atob: 2.1.2 - decode-uri-component: 0.2.0 - resolve-url: 0.2.1 - source-map-url: 0.4.1 - urix: 0.1.0 - dev: true - - /source-map-url/0.4.1: - resolution: {integrity: sha512-cPiFOTLUKvJFIg4SKVScy4ilPPW6rFgMgfuZJPNoDuMs3nC1HbMUycBoJw77xFIp6z1UJQJOfx6C9GMH80DiTw==} - deprecated: See https://github.com/lydell/source-map-url#deprecated - dev: true - - /source-map/0.5.7: - resolution: {integrity: sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==} - engines: {node: '>=0.10.0'} - dev: true - - /source-map/0.6.1: - resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==} - engines: {node: '>=0.10.0'} - dev: true - - /sparkles/1.0.1: - resolution: {integrity: sha512-dSO0DDYUahUt/0/pD/Is3VIm5TGJjludZ0HVymmhYF6eNA53PVLhnUk0znSYbH8IYBuJdCE+1luR22jNLMaQdw==} - engines: {node: '>= 0.10'} - dev: true - - /spdx-correct/3.1.1: - resolution: {integrity: sha512-cOYcUWwhCuHCXi49RhFRCyJEK3iPj1Ziz9DpViV3tbZOwXD49QzIN3MpOLJNxh2qwq2lJJZaKMVw9qNi4jTC0w==} - dependencies: - spdx-expression-parse: 3.0.1 - spdx-license-ids: 3.0.12 - dev: true - - /spdx-exceptions/2.3.0: - resolution: {integrity: sha512-/tTrYOC7PPI1nUAgx34hUpqXuyJG+DTHJTnIULG4rDygi4xu/tfgmq1e1cIRwRzwZgo4NLySi+ricLkZkw4i5A==} - dev: true - - /spdx-expression-parse/3.0.1: - resolution: {integrity: sha512-cbqHunsQWnJNE6KhVSMsMeH5H/L9EpymbzqTQ3uLwNCLZ1Q481oWaofqH7nO6V07xlXwY6PhQdQ2IedWx/ZK4Q==} - dependencies: - spdx-exceptions: 2.3.0 - spdx-license-ids: 3.0.12 - dev: true - - /spdx-license-ids/3.0.12: - resolution: {integrity: sha512-rr+VVSXtRhO4OHbXUiAF7xW3Bo9DuuF6C5jH+q/x15j2jniycgKbxU09Hr0WqlSLUs4i4ltHGXqTe7VHclYWyA==} - dev: true - - /specificity/0.4.1: - resolution: {integrity: sha512-1klA3Gi5PD1Wv9Q0wUoOQN1IWAuPu0D1U03ThXTr0cJ20+/iq2tHSDnK7Kk/0LXJ1ztUB2/1Os0wKmfyNgUQfg==} - hasBin: true - dev: true - - /split-on-first/1.1.0: - resolution: {integrity: sha512-43ZssAJaMusuKWL8sKUBQXHWOpq8d6CfN/u1p4gUzfJkM05C8rxTmYrkIPTXapZpORA6LkkzcUulJ8FqA7Uudw==} - engines: {node: '>=6'} - dev: true - - /split-string/3.1.0: - resolution: {integrity: sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==} - engines: {node: '>=0.10.0'} - dependencies: - extend-shallow: 3.0.2 - dev: true - - /split/1.0.1: - resolution: {integrity: sha512-mTyOoPbrivtXnwnIxZRFYRrPNtEFKlpB2fvjSnCQUiAA6qAZzqwna5envK4uk6OIeP17CsdF3rSBGYVBsU0Tkg==} - dependencies: - through: 2.3.8 - dev: true - - /split2/3.2.2: - resolution: {integrity: sha512-9NThjpgZnifTkJpzTZ7Eue85S49QwpNhZTq6GRJwObb6jnLFNGB7Qm73V5HewTROPyxD0C29xqmaI68bQtV+hg==} - dependencies: - readable-stream: 3.6.0 - dev: true - - /sprintf-js/1.0.3: - resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==} - dev: true - - /sshpk/1.17.0: - resolution: {integrity: sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ==} - engines: {node: '>=0.10.0'} - hasBin: true - dependencies: - asn1: 0.2.6 - assert-plus: 1.0.0 - bcrypt-pbkdf: 1.0.2 - dashdash: 1.14.1 - ecc-jsbn: 0.1.2 - getpass: 0.1.7 - jsbn: 0.1.1 - safer-buffer: 2.1.2 - tweetnacl: 0.14.5 - dev: true - - /ssri/8.0.1: - resolution: {integrity: sha512-97qShzy1AiyxvPNIkLWoGua7xoQzzPjQ0HAH4B0rWKo7SZ6USuPcrUiAFrws0UH8RrbWmgq3LMTObhPIHbbBeQ==} - engines: {node: '>= 8'} - dependencies: - minipass: 3.3.4 - dev: true - - /stack-trace/0.0.10: - resolution: {integrity: sha512-KGzahc7puUKkzyMt+IqAep+TVNbKP+k2Lmwhub39m1AsTSkaDutx56aDCo+HLDzf/D26BIHTJWNiTG1KAJiQCg==} - dev: true - - /static-extend/0.1.2: - resolution: {integrity: sha512-72E9+uLc27Mt718pMHt9VMNiAL4LMsmDbBva8mxWUCkT07fSzEGMYUCk0XWY6lp0j6RBAG4cJ3mWuZv2OE3s0g==} - engines: {node: '>=0.10.0'} - dependencies: - define-property: 0.2.5 - object-copy: 0.1.0 - dev: true - - /stream-exhaust/1.0.2: - resolution: {integrity: sha512-b/qaq/GlBK5xaq1yrK9/zFcyRSTNxmcZwFLGSTG0mXgZl/4Z6GgiyYOXOvY7N3eEvFRAG1bkDRz5EPGSvPYQlw==} - dev: true - - /stream-shift/1.0.1: - resolution: {integrity: sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==} - dev: true - - /strict-uri-encode/2.0.0: - resolution: {integrity: sha512-QwiXZgpRcKkhTj2Scnn++4PKtWsH0kpzZ62L2R6c/LUVYv7hVnZqcg2+sMuT6R7Jusu1vviK/MFsu6kNJfWlEQ==} - engines: {node: '>=4'} - dev: true - - /string-width/1.0.2: - resolution: {integrity: sha512-0XsVpQLnVCXHJfyEs8tC0zpTVIr5PKKsQtkT29IwupnPTjtPmQ3xT/4yCREF9hYkV/3M3kzcUTSAZT6a6h81tw==} - engines: {node: '>=0.10.0'} - dependencies: - code-point-at: 1.1.0 - is-fullwidth-code-point: 1.0.0 - strip-ansi: 3.0.1 - dev: true - - /string-width/4.2.3: - resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} - engines: {node: '>=8'} - dependencies: - emoji-regex: 8.0.0 - is-fullwidth-code-point: 3.0.0 - strip-ansi: 6.0.1 - dev: true - - /string.prototype.matchall/4.0.7: - resolution: {integrity: sha512-f48okCX7JiwVi1NXCVWcFnZgADDC/n2vePlQ/KUCNqCikLLilQvwjMO8+BHVKvgzH0JB0J9LEPgxOGT02RoETg==} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - get-intrinsic: 1.1.3 - has-symbols: 1.0.3 - internal-slot: 1.0.3 - regexp.prototype.flags: 1.4.3 - side-channel: 1.0.4 - dev: true - - /string.prototype.trimend/1.0.5: - resolution: {integrity: sha512-I7RGvmjV4pJ7O3kdf+LXFpVfdNOxtCW/2C8f6jNiW4+PQchwxkCDzlk1/7p+Wl4bqFIZeF47qAHXLuHHWKAxog==} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - dev: true - - /string.prototype.trimstart/1.0.5: - resolution: {integrity: sha512-THx16TJCGlsN0o6dl2o6ncWUsdgnLRSA23rRE5pyGBw/mLr3Ej/R2LaqCtgP8VNMGZsvMWnf9ooZPyY2bHvUFg==} - dependencies: - call-bind: 1.0.2 - define-properties: 1.1.4 - es-abstract: 1.20.4 - dev: true - - /string_decoder/1.1.1: - resolution: {integrity: sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==} - dependencies: - safe-buffer: 5.1.2 - dev: true - - /string_decoder/1.3.0: - resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==} - dependencies: - safe-buffer: 5.2.1 - dev: true - - /strip-ansi/3.0.1: - resolution: {integrity: sha512-VhumSSbBqDTP8p2ZLKj40UjBCV4+v8bUSEpUb4KjRgWk9pbqGF4REFj6KEagidb2f/M6AzC0EmFyDNGaw9OCzg==} - engines: {node: '>=0.10.0'} - dependencies: - ansi-regex: 2.1.1 - dev: true - - /strip-ansi/6.0.1: - resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==} - engines: {node: '>=8'} - dependencies: - ansi-regex: 5.0.1 - dev: true - - /strip-bom/2.0.0: - resolution: {integrity: sha512-kwrX1y7czp1E69n2ajbG65mIo9dqvJ+8aBQXOGVxqwvNbsXdFM6Lq37dLAY3mknUwru8CfcCbfOLL/gMo+fi3g==} - engines: {node: '>=0.10.0'} - dependencies: - is-utf8: 0.2.1 - dev: true - - /strip-bom/3.0.0: - resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==} - engines: {node: '>=4'} - dev: true - - /strip-bom/4.0.0: - resolution: {integrity: sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==} - engines: {node: '>=8'} - dev: true - - /strip-eof/1.0.0: - resolution: {integrity: sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==} - engines: {node: '>=0.10.0'} - dev: true - - /strip-final-newline/2.0.0: - resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} - engines: {node: '>=6'} - dev: true - - /strip-indent/3.0.0: - resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} - engines: {node: '>=8'} - dependencies: - min-indent: 1.0.1 - dev: true - - /strip-json-comments/3.1.1: - resolution: {integrity: sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==} - engines: {node: '>=8'} - dev: true - - /strong-log-transformer/2.1.0: - resolution: {integrity: sha512-B3Hgul+z0L9a236FAUC9iZsL+nVHgoCJnqCbN588DjYxvGXaXaaFbfmQ/JhvKjZwsOukuR72XbHv71Qkug0HxA==} - engines: {node: '>=4'} - hasBin: true - dependencies: - duplexer: 0.1.2 - minimist: 1.2.7 - through: 2.3.8 - dev: true - - /style-search/0.1.0: - resolution: {integrity: sha512-Dj1Okke1C3uKKwQcetra4jSuk0DqbzbYtXipzFlFMZtowbF1x7BKJwB9AayVMyFARvU8EDrZdcax4At/452cAg==} - dev: true - - /stylelint-config-ali/0.4.2_2vkgt733dnumio3be4grtjqkwy: - resolution: {integrity: sha512-IFcaD4/dVwRQ48oPaUxr4YjqX3hV9KfWH3XjNHnhwM8q5MPH1i+WWYp2vtx4p1gP9Ur4RIDHY8fGKbpxWGnNbA==} - peerDependencies: - stylelint: '>=8.3.0' - stylelint-scss: '>=2.0.0' - dependencies: - stylelint: 13.13.1 - stylelint-scss: 3.21.0_stylelint@13.13.1 - dev: true - - /stylelint-scss/3.21.0_stylelint@13.13.1: - resolution: {integrity: sha512-CMI2wSHL+XVlNExpauy/+DbUcB/oUZLARDtMIXkpV/5yd8nthzylYd1cdHeDMJVBXeYHldsnebUX6MoV5zPW4A==} - engines: {node: '>=8'} - peerDependencies: - stylelint: ^8.0.0 || ^9.0.0 || ^10.0.0 || ^11.0.0 || ^12.0.0 || ^13.0.0 - dependencies: - lodash: 4.17.21 - postcss-media-query-parser: 0.2.3 - postcss-resolve-nested-selector: 0.1.1 - postcss-selector-parser: 6.0.10 - postcss-value-parser: 4.2.0 - stylelint: 13.13.1 - dev: true - - /stylelint/13.13.1: - resolution: {integrity: sha512-Mv+BQr5XTUrKqAXmpqm6Ddli6Ief+AiPZkRsIrAoUKFuq/ElkUh9ZMYxXD0iQNZ5ADghZKLOWz1h7hTClB7zgQ==} - engines: {node: '>=10.13.0'} - hasBin: true - dependencies: - '@stylelint/postcss-css-in-js': 0.37.3_j55xdkkcxc32kvnyvx3y7casfm - '@stylelint/postcss-markdown': 0.36.2_j55xdkkcxc32kvnyvx3y7casfm - autoprefixer: 9.8.8 - balanced-match: 2.0.0 - chalk: 4.1.2 - cosmiconfig: 7.0.1 - debug: 4.3.4 - execall: 2.0.0 - fast-glob: 3.2.12 - fastest-levenshtein: 1.0.16 - file-entry-cache: 6.0.1 - get-stdin: 8.0.0 - global-modules: 2.0.0 - globby: 11.1.0 - globjoin: 0.1.4 - html-tags: 3.2.0 - ignore: 5.2.0 - import-lazy: 4.0.0 - imurmurhash: 0.1.4 - known-css-properties: 0.21.0 - lodash: 4.17.21 - log-symbols: 4.1.0 - mathml-tag-names: 2.1.3 - meow: 9.0.0 - micromatch: 4.0.5 - normalize-selector: 0.2.0 - postcss: 7.0.39 - postcss-html: 0.36.0_j55xdkkcxc32kvnyvx3y7casfm - postcss-less: 3.1.4 - postcss-media-query-parser: 0.2.3 - postcss-resolve-nested-selector: 0.1.1 - postcss-safe-parser: 4.0.2 - postcss-sass: 0.4.4 - postcss-scss: 2.1.1 - postcss-selector-parser: 6.0.10 - postcss-syntax: 0.36.2_kei4jy7wdgbhc236h4oijypxom - postcss-value-parser: 4.2.0 - resolve-from: 5.0.0 - slash: 3.0.0 - specificity: 0.4.1 - string-width: 4.2.3 - strip-ansi: 6.0.1 - style-search: 0.1.0 - sugarss: 2.0.0 - svg-tags: 1.0.0 - table: 6.8.0 - v8-compile-cache: 2.3.0 - write-file-atomic: 3.0.3 - transitivePeerDependencies: - - postcss-jsx - - postcss-markdown - - supports-color - dev: true - - /sugarss/2.0.0: - resolution: {integrity: sha512-WfxjozUk0UVA4jm+U1d736AUpzSrNsQcIbyOkoE364GrtWmIrFdk5lksEupgWMD4VaT/0kVx1dobpiDumSgmJQ==} - dependencies: - postcss: 7.0.39 - dev: true - - /supports-color/5.5.0: - resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==} - engines: {node: '>=4'} - dependencies: - has-flag: 3.0.0 - dev: true - - /supports-color/7.2.0: - resolution: {integrity: sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==} - engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - dev: true - - /supports-hyperlinks/2.3.0: - resolution: {integrity: sha512-RpsAZlpWcDwOPQA22aCH4J0t7L8JmAvsCxfOSEwm7cQs3LshN36QaTkwd70DnBOXDWGssw2eUoc8CaRWT0XunA==} - engines: {node: '>=8'} - dependencies: - has-flag: 4.0.0 - supports-color: 7.2.0 - dev: true - - /supports-preserve-symlinks-flag/1.0.0: - resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} - engines: {node: '>= 0.4'} - dev: true - - /sver-compat/1.5.0: - resolution: {integrity: sha512-aFTHfmjwizMNlNE6dsGmoAM4lHjL0CyiobWaFiXWSlD7cIxshW422Nb8KbXCmR6z+0ZEPY+daXJrDyh/vuwTyg==} - dependencies: - es6-iterator: 2.0.3 - es6-symbol: 3.1.3 - dev: true - - /svg-tags/1.0.0: - resolution: {integrity: sha512-ovssysQTa+luh7A5Weu3Rta6FJlFBBbInjOh722LIt6klpU2/HtdUbszju/G4devcvk8PGt7FCLv5wftu3THUA==} - dev: true - - /table/6.8.0: - resolution: {integrity: sha512-s/fitrbVeEyHKFa7mFdkuQMWlH1Wgw/yEXMt5xACT4ZpzWFluehAxRtUUQKPuWhaLAWhFcVx6w3oC8VKaUfPGA==} - engines: {node: '>=10.0.0'} - dependencies: - ajv: 8.11.0 - lodash.truncate: 4.4.2 - slice-ansi: 4.0.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true - - /tar/4.4.19: - resolution: {integrity: sha512-a20gEsvHnWe0ygBY8JbxoM4w3SJdhc7ZAuxkLqh+nvNQN2IOt0B5lLgM490X5Hl8FF0dl0tOf2ewFYAlIFgzVA==} - engines: {node: '>=4.5'} - dependencies: - chownr: 1.1.4 - fs-minipass: 1.2.7 - minipass: 2.9.0 - minizlib: 1.3.3 - mkdirp: 0.5.6 - safe-buffer: 5.2.1 - yallist: 3.1.1 - dev: true - - /tar/6.1.11: - resolution: {integrity: sha512-an/KZQzQUkZCkuoAA64hM92X0Urb6VpRhAFllDzz44U2mcD5scmT3zBc4VgVpkugF580+DQn8eAFSyoQt0tznA==} - engines: {node: '>= 10'} - dependencies: - chownr: 2.0.0 - fs-minipass: 2.1.0 - minipass: 3.3.4 - minizlib: 2.1.2 - mkdirp: 1.0.4 - yallist: 4.0.0 - dev: true - - /temp-dir/1.0.0: - resolution: {integrity: sha512-xZFXEGbG7SNC3itwBzI3RYjq/cEhBkx2hJuKGIUOcEULmkQExXiHat2z/qkISYsuR+IKumhEfKKbV5qXmhICFQ==} - engines: {node: '>=4'} - dev: true - - /temp-write/4.0.0: - resolution: {integrity: sha512-HIeWmj77uOOHb0QX7siN3OtwV3CTntquin6TNVg6SHOqCP3hYKmox90eeFOGaY1MqJ9WYDDjkyZrW6qS5AWpbw==} - engines: {node: '>=8'} - dependencies: - graceful-fs: 4.2.10 - is-stream: 2.0.1 - make-dir: 3.1.0 - temp-dir: 1.0.0 - uuid: 3.4.0 - dev: true - - /terminal-link/2.1.1: - resolution: {integrity: sha512-un0FmiRUQNr5PJqy9kP7c40F5BOfpGlYTrxonDChEZB7pzZxRNp/bt+ymiy9/npwXya9KH99nJ/GXFIiUkYGFQ==} - engines: {node: '>=8'} - dependencies: - ansi-escapes: 4.3.2 - supports-hyperlinks: 2.3.0 - dev: true - - /text-extensions/1.9.0: - resolution: {integrity: sha512-wiBrwC1EhBelW12Zy26JeOUkQ5mRu+5o8rpsJk5+2t+Y5vE7e842qtZDQ2g1NpX/29HdyFeJ4nSIhI47ENSxlQ==} - engines: {node: '>=0.10'} - dev: true - - /text-table/0.2.0: - resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} - dev: true - - /through/2.3.8: - resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} - dev: true - - /through2-filter/3.0.0: - resolution: {integrity: sha512-jaRjI2WxN3W1V8/FMZ9HKIBXixtiqs3SQSX4/YGIiP3gL6djW48VoZq9tDqeCWs3MT8YY5wb/zli8VW8snY1CA==} - dependencies: - through2: 2.0.5 - xtend: 4.0.2 - dev: true - - /through2/2.0.5: - resolution: {integrity: sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ==} - dependencies: - readable-stream: 2.3.7 - xtend: 4.0.2 - dev: true - - /through2/4.0.2: - resolution: {integrity: sha512-iOqSav00cVxEEICeD7TjLB1sueEL+81Wpzp2bY17uZjZN0pWZPuo4suZ/61VujxmqSGFfgOcNuTZ85QJwNZQpw==} - dependencies: - readable-stream: 3.6.0 - dev: true - - /time-stamp/1.1.0: - resolution: {integrity: sha512-gLCeArryy2yNTRzTGKbZbloctj64jkZ57hj5zdraXue6aFgd6PmvVtEyiUU+hvU0v7q08oVv8r8ev0tRo6bvgw==} - engines: {node: '>=0.10.0'} - dev: true - - /tmp/0.0.33: - resolution: {integrity: sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==} - engines: {node: '>=0.6.0'} - dependencies: - os-tmpdir: 1.0.2 - dev: true - - /to-absolute-glob/2.0.2: - resolution: {integrity: sha512-rtwLUQEwT8ZeKQbyFJyomBRYXyE16U5VKuy0ftxLMK/PZb2fkOsg5r9kHdauuVDbsNdIBoC/HCthpidamQFXYA==} - engines: {node: '>=0.10.0'} - dependencies: - is-absolute: 1.0.0 - is-negated-glob: 1.0.0 - dev: true - - /to-fast-properties/2.0.0: - resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} - engines: {node: '>=4'} - dev: true - - /to-object-path/0.3.0: - resolution: {integrity: sha512-9mWHdnGRuh3onocaHzukyvCZhzvr6tiflAy/JRFXcJX0TjgfWA9pk9t8CMbzmBE4Jfw58pXbkngtBtqYxzNEyg==} - engines: {node: '>=0.10.0'} - dependencies: - kind-of: 3.2.2 - dev: true - - /to-regex-range/2.1.1: - resolution: {integrity: sha512-ZZWNfCjUokXXDGXFpZehJIkZqq91BcULFq/Pi7M5i4JnxXdhMKAK682z8bCW3o8Hj1wuuzoKcW3DfVzaP6VuNg==} - engines: {node: '>=0.10.0'} - dependencies: - is-number: 3.0.0 - repeat-string: 1.6.1 - dev: true - - /to-regex-range/5.0.1: - resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==} - engines: {node: '>=8.0'} - dependencies: - is-number: 7.0.0 - dev: true - - /to-regex/3.0.2: - resolution: {integrity: sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==} - engines: {node: '>=0.10.0'} - dependencies: - define-property: 2.0.2 - extend-shallow: 3.0.2 - regex-not: 1.0.2 - safe-regex: 1.1.0 - dev: true - - /to-through/2.0.0: - resolution: {integrity: sha512-+QIz37Ly7acM4EMdw2PRN389OneM5+d844tirkGp4dPKzI5OE72V9OsbFp+CIYJDahZ41ZV05hNtcPAQUAm9/Q==} - engines: {node: '>= 0.10'} - dependencies: - through2: 2.0.5 - dev: true - - /tough-cookie/2.5.0: - resolution: {integrity: sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==} - engines: {node: '>=0.8'} - dependencies: - psl: 1.9.0 - punycode: 2.1.1 - dev: true - - /tr46/0.0.3: - resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==} - dev: true - - /tr46/2.1.0: - resolution: {integrity: sha512-15Ih7phfcdP5YxqiB+iDtLoaTz4Nd35+IiAv0kQ5FNKHzXgdWqPoTIqEDDJmXceQt4JZk6lVPT8lnDlPpGDppw==} - engines: {node: '>=8'} - dependencies: - punycode: 2.1.1 - dev: true - - /trim-newlines/3.0.1: - resolution: {integrity: sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw==} - engines: {node: '>=8'} - dev: true - - /trough/1.0.5: - resolution: {integrity: sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==} - dev: true - - /tsconfig-paths/3.14.1: - resolution: {integrity: sha512-fxDhWnFSLt3VuTwtvJt5fpwxBHg5AdKWMsgcPOOIilyjymcYVZoCQF8fvFRezCNfblEXmi+PcM1eYHeOAgXCOQ==} - dependencies: - '@types/json5': 0.0.29 - json5: 1.0.1 - minimist: 1.2.7 - strip-bom: 3.0.0 - dev: true - - /tslib/1.14.1: - resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==} - dev: true - - /tsutils/3.21.0_typescript@4.8.4: - resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==} - engines: {node: '>= 6'} - peerDependencies: - typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta' - dependencies: - tslib: 1.14.1 - typescript: 4.8.4 - dev: true - - /tunnel-agent/0.6.0: - resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} - dependencies: - safe-buffer: 5.2.1 - dev: true - - /tweetnacl/0.14.5: - resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} - dev: true - - /type-check/0.4.0: - resolution: {integrity: sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew==} - engines: {node: '>= 0.8.0'} - dependencies: - prelude-ls: 1.2.1 - dev: true - - /type-fest/0.18.1: - resolution: {integrity: sha512-OIAYXk8+ISY+qTOwkHtKqzAuxchoMiD9Udx+FSGQDuiRR+PJKJHc2NJAXlbhkGwTt/4/nKZxELY1w3ReWOL8mw==} - engines: {node: '>=10'} - dev: true - - /type-fest/0.20.2: - resolution: {integrity: sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==} - engines: {node: '>=10'} - dev: true - - /type-fest/0.21.3: - resolution: {integrity: sha512-t0rzBq87m3fVcduHDUFhKmyyX+9eo6WQjZvf51Ea/M0Q7+T374Jp1aUiyUl0GKxp8M/OETVHSDvmkyPgvX+X2w==} - engines: {node: '>=10'} - dev: true - - /type-fest/0.4.1: - resolution: {integrity: sha512-IwzA/LSfD2vC1/YDYMv/zHP4rDF1usCwllsDpbolT3D4fUepIO7f9K70jjmUewU/LmGUKJcwcVtDCpnKk4BPMw==} - engines: {node: '>=6'} - dev: true - - /type-fest/0.6.0: - resolution: {integrity: sha512-q+MB8nYR1KDLrgr4G5yemftpMC7/QLqVndBmEEdqzmNj5dcFOO4Oo8qlwZE3ULT3+Zim1F8Kq4cBnikNhlCMlg==} - engines: {node: '>=8'} - dev: true - - /type-fest/0.8.1: - resolution: {integrity: sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==} - engines: {node: '>=8'} - dev: true - - /type/1.2.0: - resolution: {integrity: sha512-+5nt5AAniqsCnu2cEQQdpzCAh33kVx8n0VoFidKpB1dVVLAN/F+bgVOqOJqOnEnrhp222clB5p3vUlD+1QAnfg==} - dev: true - - /type/2.7.2: - resolution: {integrity: sha512-dzlvlNlt6AXU7EBSfpAscydQ7gXB+pPGsPnfJnZpiNJBDj7IaJzQlBZYGdEi4R9HmPdBv2XmWJ6YUtoTa7lmCw==} - dev: true - - /typedarray-to-buffer/3.1.5: - resolution: {integrity: sha512-zdu8XMNEDepKKR+XYOXAVPtWui0ly0NtohUscw+UmaHiAWT8hrV1rr//H6V+0DvJ3OQ19S979M0laLfX8rm82Q==} - dependencies: - is-typedarray: 1.0.0 - dev: true - - /typedarray/0.0.6: - resolution: {integrity: sha512-/aCDEGatGvZ2BIk+HmLf4ifCJFwvKFNb9/JeZPMulfgFracn9QFcAf5GO8B/mweUjSoblS5In0cWhqpfs/5PQA==} - dev: true - - /typescript/4.8.4: - resolution: {integrity: sha512-QCh+85mCy+h0IGff8r5XWzOVSbBO+KfeYrMQh7NJ58QujwcE22u+NUSmUxqF+un70P9GXKxa2HCNiTTMJknyjQ==} - engines: {node: '>=4.2.0'} - hasBin: true - dev: true - - /uc.micro/1.0.6: - resolution: {integrity: sha512-8Y75pvTYkLJW2hWQHXxoqRgV7qb9B+9vFEtidML+7koHUFapnVJAZ6cKs+Qjz5Aw3aZWHMC6u0wJE3At+nSGwA==} - dev: true - - /uglify-js/3.17.4: - resolution: {integrity: sha512-T9q82TJI9e/C1TAxYvfb16xO120tMVFZrGA3f9/P4424DNu6ypK103y0GPFVa17yotwSyZW5iYXgjYHkGrJW/g==} - engines: {node: '>=0.8.0'} - hasBin: true - requiresBuild: true - dev: true - optional: true - - /uid-number/0.0.6: - resolution: {integrity: sha512-c461FXIljswCuscZn67xq9PpszkPT6RjheWFQTgCyabJrTUozElanb0YEqv2UGgk247YpcJkFBuSGNvBlpXM9w==} - dev: true - - /umask/1.1.0: - resolution: {integrity: sha512-lE/rxOhmiScJu9L6RTNVgB/zZbF+vGC0/p6D3xnkAePI2o0sMyFG966iR5Ki50OI/0mNi2yaRnxfLsPmEZF/JA==} - dev: true - - /unbox-primitive/1.0.2: - resolution: {integrity: sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==} - dependencies: - call-bind: 1.0.2 - has-bigints: 1.0.2 - has-symbols: 1.0.3 - which-boxed-primitive: 1.0.2 - dev: true - - /unc-path-regex/0.1.2: - resolution: {integrity: sha512-eXL4nmJT7oCpkZsHZUOJo8hcX3GbsiDOa0Qu9F646fi8dT3XuSVopVqAcEiVzSKKH7UoDti23wNX3qGFxcW5Qg==} - engines: {node: '>=0.10.0'} - dev: true - - /undertaker-registry/1.0.1: - resolution: {integrity: sha512-UR1khWeAjugW3548EfQmL9Z7pGMlBgXteQpr1IZeZBtnkCJQJIJ1Scj0mb9wQaPvUZ9Q17XqW6TIaPchJkyfqw==} - engines: {node: '>= 0.10'} - dev: true - - /undertaker/1.3.0: - resolution: {integrity: sha512-/RXwi5m/Mu3H6IHQGww3GNt1PNXlbeCuclF2QYR14L/2CHPz3DFZkvB5hZ0N/QUkiXWCACML2jXViIQEQc2MLg==} - engines: {node: '>= 0.10'} - dependencies: - arr-flatten: 1.1.0 - arr-map: 2.0.2 - bach: 1.2.0 - collection-map: 1.0.0 - es6-weak-map: 2.0.3 - fast-levenshtein: 1.1.4 - last-run: 1.1.1 - object.defaults: 1.1.0 - object.reduce: 1.0.1 - undertaker-registry: 1.0.1 - dev: true - - /unified/9.2.2: - resolution: {integrity: sha512-Sg7j110mtefBD+qunSLO1lqOEKdrwBFBrR6Qd8f4uwkhWNlbkaqwHse6e7QvD3AP/MNoJdEDLaf8OxYyoWgorQ==} - dependencies: - bail: 1.0.5 - extend: 3.0.2 - is-buffer: 2.0.5 - is-plain-obj: 2.1.0 - trough: 1.0.5 - vfile: 4.2.1 - dev: true - - /union-value/1.0.1: - resolution: {integrity: sha512-tJfXmxMeWYnczCVs7XAEvIV7ieppALdyepWMkHkwciRpZraG/xwT+s2JN8+pr1+8jCRf80FFzvr+MpQeeoF4Xg==} - engines: {node: '>=0.10.0'} - dependencies: - arr-union: 3.1.0 - get-value: 2.0.6 - is-extendable: 0.1.1 - set-value: 2.0.1 - dev: true - - /unique-filename/1.1.1: - resolution: {integrity: sha512-Vmp0jIp2ln35UTXuryvjzkjGdRyf9b2lTXuSYUiPmzRcl3FDtYqAwOnTJkAngD9SWhnoJzDbTKwaOrZ+STtxNQ==} - dependencies: - unique-slug: 2.0.2 - dev: true - - /unique-slug/2.0.2: - resolution: {integrity: sha512-zoWr9ObaxALD3DOPfjPSqxt4fnZiWblxHIgeWqW8x7UqDzEtHEQLzji2cuJYQFCU6KmoJikOYAZlrTHHebjx2w==} - dependencies: - imurmurhash: 0.1.4 - dev: true - - /unique-stream/2.3.1: - resolution: {integrity: sha512-2nY4TnBE70yoxHkDli7DMazpWiP7xMdCYqU2nBRO0UB+ZpEkGsSija7MvmvnZFUeC+mrgiUfcHSr3LmRFIg4+A==} - dependencies: - json-stable-stringify-without-jsonify: 1.0.1 - through2-filter: 3.0.0 - dev: true - - /unist-util-find-all-after/3.0.2: - resolution: {integrity: sha512-xaTC/AGZ0rIM2gM28YVRAFPIZpzbpDtU3dRmp7EXlNVA8ziQc4hY3H7BHXM1J49nEmiqc3svnqMReW+PGqbZKQ==} - dependencies: - unist-util-is: 4.1.0 - dev: true - - /unist-util-is/4.1.0: - resolution: {integrity: sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==} - dev: true - - /unist-util-stringify-position/2.0.3: - resolution: {integrity: sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==} - dependencies: - '@types/unist': 2.0.6 - dev: true - - /universal-user-agent/6.0.0: - resolution: {integrity: sha512-isyNax3wXoKaulPDZWHQqbmIx1k2tb9fb3GGDBRxCscfYV2Ch7WxPArBsFEG8s/safwXTT7H4QGhaIkTp9447w==} - dev: true - - /universalify/2.0.0: - resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} - engines: {node: '>= 10.0.0'} - dev: true - - /unset-value/1.0.0: - resolution: {integrity: sha512-PcA2tsuGSF9cnySLHTLSh2qrQiJ70mn+r+Glzxv2TWZblxsxCC52BDlZoPCsz7STd9pN7EZetkWZBAvk4cgZdQ==} - engines: {node: '>=0.10.0'} - dependencies: - has-value: 0.3.1 - isobject: 3.0.1 - dev: true - - /upath/1.2.0: - resolution: {integrity: sha512-aZwGpamFO61g3OlfT7OQCHqhGnW43ieH9WZeP7QxN/G/jS4jfqUkZxoryvJgVPEcrl5NL/ggHsSmLMHuH64Lhg==} - engines: {node: '>=4'} - dev: true - - /upath/2.0.1: - resolution: {integrity: sha512-1uEe95xksV1O0CYKXo8vQvN1JEbtJp7lb7C5U9HMsIp6IVwntkH/oNUzyVNQSd4S1sYk2FpSSW44FqMc8qee5w==} - engines: {node: '>=4'} - dev: true - - /update-browserslist-db/1.0.10_browserslist@4.21.4: - resolution: {integrity: sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==} - hasBin: true - peerDependencies: - browserslist: '>= 4.21.0' - dependencies: - browserslist: 4.21.4 - escalade: 3.1.1 - picocolors: 1.0.0 - dev: true - - /uri-js/4.4.1: - resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - dependencies: - punycode: 2.1.1 - dev: true - - /urix/0.1.0: - resolution: {integrity: sha512-Am1ousAhSLBeB9cG/7k7r2R0zj50uDRlZHPGbazid5s9rlF1F/QKYObEKSIunSjIOkJZqwRRLpvewjEkM7pSqg==} - deprecated: Please see https://github.com/lydell/urix#deprecated - dev: true - - /use/3.1.1: - resolution: {integrity: sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==} - engines: {node: '>=0.10.0'} - dev: true - - /util-deprecate/1.0.2: - resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} - dev: true - - /util-promisify/2.1.0: - resolution: {integrity: sha512-K+5eQPYs14b3+E+hmE2J6gCZ4JmMl9DbYS6BeP2CHq6WMuNxErxf5B/n0fz85L8zUuoO6rIzNNmIQDu/j+1OcA==} - dependencies: - object.getownpropertydescriptors: 2.1.4 - dev: true - - /uuid/3.4.0: - resolution: {integrity: sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==} - deprecated: Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details. - hasBin: true - dev: true - - /v8-compile-cache/2.3.0: - resolution: {integrity: sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==} - dev: true - - /v8flags/3.2.0: - resolution: {integrity: sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg==} - engines: {node: '>= 0.10'} - dependencies: - homedir-polyfill: 1.0.3 - dev: true - - /validate-npm-package-license/3.0.4: - resolution: {integrity: sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==} - dependencies: - spdx-correct: 3.1.1 - spdx-expression-parse: 3.0.1 - dev: true - - /validate-npm-package-name/3.0.0: - resolution: {integrity: sha512-M6w37eVCMMouJ9V/sdPGnC5H4uDr73/+xdq0FBLO3TFFX1+7wiUY6Es328NN+y43tmY+doUdN9g9J21vqB7iLw==} - dependencies: - builtins: 1.0.3 - dev: true - - /value-or-function/3.0.0: - resolution: {integrity: sha512-jdBB2FrWvQC/pnPtIqcLsMaQgjhdb6B7tk1MMyTKapox+tQZbdRP4uLxu/JY0t7fbfDCUMnuelzEYv5GsxHhdg==} - engines: {node: '>= 0.10'} - dev: true - - /verror/1.10.0: - resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} - engines: {'0': node >=0.6.0} - dependencies: - assert-plus: 1.0.0 - core-util-is: 1.0.2 - extsprintf: 1.3.0 - dev: true - - /vfile-message/2.0.4: - resolution: {integrity: sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==} - dependencies: - '@types/unist': 2.0.6 - unist-util-stringify-position: 2.0.3 - dev: true - - /vfile/4.2.1: - resolution: {integrity: sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==} - dependencies: - '@types/unist': 2.0.6 - is-buffer: 2.0.5 - unist-util-stringify-position: 2.0.3 - vfile-message: 2.0.4 - dev: true - - /vinyl-fs/3.0.3: - resolution: {integrity: sha512-vIu34EkyNyJxmP0jscNzWBSygh7VWhqun6RmqVfXePrOwi9lhvRs//dOaGOTRUQr4tx7/zd26Tk5WeSVZitgng==} - engines: {node: '>= 0.10'} - dependencies: - fs-mkdirp-stream: 1.0.0 - glob-stream: 6.1.0 - graceful-fs: 4.2.10 - is-valid-glob: 1.0.0 - lazystream: 1.0.1 - lead: 1.0.0 - object.assign: 4.1.4 - pumpify: 1.5.1 - readable-stream: 2.3.7 - remove-bom-buffer: 3.0.0 - remove-bom-stream: 1.2.0 - resolve-options: 1.1.0 - through2: 2.0.5 - to-through: 2.0.0 - value-or-function: 3.0.0 - vinyl: 2.2.1 - vinyl-sourcemap: 1.1.0 - dev: true - - /vinyl-sourcemap/1.1.0: - resolution: {integrity: sha512-NiibMgt6VJGJmyw7vtzhctDcfKch4e4n9TBeoWlirb7FMg9/1Ov9k+A5ZRAtywBpRPiyECvQRQllYM8dECegVA==} - engines: {node: '>= 0.10'} - dependencies: - append-buffer: 1.0.2 - convert-source-map: 1.9.0 - graceful-fs: 4.2.10 - normalize-path: 2.1.1 - now-and-later: 2.0.1 - remove-bom-buffer: 3.0.0 - vinyl: 2.2.1 - dev: true - - /vinyl/2.2.1: - resolution: {integrity: sha512-LII3bXRFBZLlezoG5FfZVcXflZgWP/4dCwKtxd5ky9+LOtM4CS3bIRQsmR1KMnMW07jpE8fqR2lcxPZ+8sJIcw==} - engines: {node: '>= 0.10'} - dependencies: - clone: 2.1.2 - clone-buffer: 1.0.0 - clone-stats: 1.0.0 - cloneable-readable: 1.1.3 - remove-trailing-separator: 1.1.0 - replace-ext: 1.0.1 - dev: true - - /vue-eslint-parser/7.11.0_eslint@7.32.0: - resolution: {integrity: sha512-qh3VhDLeh773wjgNTl7ss0VejY9bMMa0GoDG2fQVyDzRFdiU3L7fw74tWZDHNQXdZqxO3EveQroa9ct39D2nqg==} - engines: {node: '>=8.10'} - peerDependencies: - eslint: '>=5.0.0' - dependencies: - debug: 4.3.4 - eslint: 7.32.0 - eslint-scope: 5.1.1 - eslint-visitor-keys: 1.3.0 - espree: 6.2.1 - esquery: 1.4.0 - lodash: 4.17.21 - semver: 6.3.0 - transitivePeerDependencies: - - supports-color - dev: true - - /wcwidth/1.0.1: - resolution: {integrity: sha512-XHPEwS0q6TaxcvG85+8EYkbiCux2XtWG2mkc47Ng2A77BQu9+DqIOJldST4HgPkuea7dvKSj5VgX3P1d4rW8Tg==} - dependencies: - defaults: 1.0.4 - dev: true - - /webidl-conversions/3.0.1: - resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==} - dev: true - - /webidl-conversions/6.1.0: - resolution: {integrity: sha512-qBIvFLGiBpLjfwmYAaHPXsn+ho5xZnGvyGvsarywGNc8VyQJUMHJ8OBKGGrPER0okBeMDaan4mNBlgBROxuI8w==} - engines: {node: '>=10.4'} - dev: true - - /whatwg-url/5.0.0: - resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==} - dependencies: - tr46: 0.0.3 - webidl-conversions: 3.0.1 - dev: true - - /whatwg-url/8.7.0: - resolution: {integrity: sha512-gAojqb/m9Q8a5IV96E3fHJM70AzCkgt4uXYX2O7EmuyOnLrViCQlsEBmF9UQIu3/aeAIp2U17rtbpZWNntQqdg==} - engines: {node: '>=10'} - dependencies: - lodash: 4.17.21 - tr46: 2.1.0 - webidl-conversions: 6.1.0 - dev: true - - /which-boxed-primitive/1.0.2: - resolution: {integrity: sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==} - dependencies: - is-bigint: 1.0.4 - is-boolean-object: 1.1.2 - is-number-object: 1.0.7 - is-string: 1.0.7 - is-symbol: 1.0.4 - dev: true - - /which-module/1.0.0: - resolution: {integrity: sha512-F6+WgncZi/mJDrammbTuHe1q0R5hOXv/mBaiNA2TCNT/LTHusX0V+CJnj9XT8ki5ln2UZyyddDgHfCzyrOH7MQ==} - dev: true - - /which-module/2.0.0: - resolution: {integrity: sha512-B+enWhmw6cjfVC7kS8Pj9pCrKSc5txArRyaYGe088shv/FGWH+0Rjx/xPgtsWfsUtS27FkP697E4DDhgrgoc0Q==} - dev: true - - /which/1.3.1: - resolution: {integrity: sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==} - hasBin: true - dependencies: - isexe: 2.0.0 - dev: true - - /which/2.0.2: - resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==} - engines: {node: '>= 8'} - hasBin: true - dependencies: - isexe: 2.0.0 - dev: true - - /wide-align/1.1.5: - resolution: {integrity: sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==} - dependencies: - string-width: 1.0.2 - dev: true - - /word-wrap/1.2.3: - resolution: {integrity: sha512-Hz/mrNwitNRh/HUAtM/VT/5VH+ygD6DV7mYKZAtHOrbs8U7lvPS6xf7EJKMF0uW1KJCl0H701g3ZGus+muE5vQ==} - engines: {node: '>=0.10.0'} - dev: true - - /wordwrap/1.0.0: - resolution: {integrity: sha512-gvVzJFlPycKc5dZN4yPkP8w7Dc37BtP1yczEneOb4uq34pXZcvrtRTmWV8W+Ume+XCxKgbjM+nevkyFPMybd4Q==} - dev: true - - /wrap-ansi/2.1.0: - resolution: {integrity: sha512-vAaEaDM946gbNpH5pLVNR+vX2ht6n0Bt3GXwVB1AuAqZosOvHNF3P7wDnh8KLkSqgUh0uh77le7Owgoz+Z9XBw==} - engines: {node: '>=0.10.0'} - dependencies: - string-width: 1.0.2 - strip-ansi: 3.0.1 - dev: true - - /wrap-ansi/6.2.0: - resolution: {integrity: sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA==} - engines: {node: '>=8'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true - - /wrap-ansi/7.0.0: - resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} - engines: {node: '>=10'} - dependencies: - ansi-styles: 4.3.0 - string-width: 4.2.3 - strip-ansi: 6.0.1 - dev: true - - /wrappy/1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - dev: true - - /write-file-atomic/2.4.3: - resolution: {integrity: sha512-GaETH5wwsX+GcnzhPgKcKjJ6M2Cq3/iZp1WyY/X1CSqrW+jVNM9Y7D8EC2sM4ZG/V8wZlSniJnCKWPmBYAucRQ==} - dependencies: - graceful-fs: 4.2.10 - imurmurhash: 0.1.4 - signal-exit: 3.0.7 - dev: true - - /write-file-atomic/3.0.3: - resolution: {integrity: sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==} - dependencies: - imurmurhash: 0.1.4 - is-typedarray: 1.0.0 - signal-exit: 3.0.7 - typedarray-to-buffer: 3.1.5 - dev: true - - /write-json-file/3.2.0: - resolution: {integrity: sha512-3xZqT7Byc2uORAatYiP3DHUUAVEkNOswEWNs9H5KXiicRTvzYzYqKjYc4G7p+8pltvAw641lVByKVtMpf+4sYQ==} - engines: {node: '>=6'} - dependencies: - detect-indent: 5.0.0 - graceful-fs: 4.2.10 - make-dir: 2.1.0 - pify: 4.0.1 - sort-keys: 2.0.0 - write-file-atomic: 2.4.3 - dev: true - - /write-json-file/4.3.0: - resolution: {integrity: sha512-PxiShnxf0IlnQuMYOPPhPkhExoCQuTUNPOa/2JWCYTmBquU9njyyDuwRKN26IZBlp4yn1nt+Agh2HOOBl+55HQ==} - engines: {node: '>=8.3'} - dependencies: - detect-indent: 6.1.0 - graceful-fs: 4.2.10 - is-plain-obj: 2.1.0 - make-dir: 3.1.0 - sort-keys: 4.2.0 - write-file-atomic: 3.0.3 - dev: true - - /write-pkg/4.0.0: - resolution: {integrity: sha512-v2UQ+50TNf2rNHJ8NyWttfm/EJUBWMJcx6ZTYZr6Qp52uuegWw/lBkCtCbnYZEmPRNL61m+u67dAmGxo+HTULA==} - engines: {node: '>=8'} - dependencies: - sort-keys: 2.0.0 - type-fest: 0.4.1 - write-json-file: 3.2.0 - dev: true - - /xtend/4.0.2: - resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==} - engines: {node: '>=0.4'} - dev: true - - /y18n/3.2.2: - resolution: {integrity: sha512-uGZHXkHnhF0XeeAPgnKfPv1bgKAYyVvmNL1xlKsPYZPaIHxGti2hHqvOCQv71XMsLxu1QjergkqogUnms5D3YQ==} - dev: true - - /y18n/4.0.3: - resolution: {integrity: sha512-JKhqTOwSrqNA1NY5lSztJ1GrBiUodLMmIZuLiDaMRJ+itFd+ABVE8XBjOvIWL+rSqNDC74LCSFmlb/U4UZ4hJQ==} - dev: true - - /y18n/5.0.8: - resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==} - engines: {node: '>=10'} - dev: true - - /yallist/3.1.1: - resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==} - dev: true - - /yallist/4.0.0: - resolution: {integrity: sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==} - dev: true - - /yaml/1.10.2: - resolution: {integrity: sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==} - engines: {node: '>= 6'} - dev: true - - /yargs-parser/18.1.3: - resolution: {integrity: sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==} - engines: {node: '>=6'} - dependencies: - camelcase: 5.3.1 - decamelize: 1.2.0 - dev: true - - /yargs-parser/20.2.4: - resolution: {integrity: sha512-WOkpgNhPTlE73h4VFAFsOnomJVaovO8VqLDzy5saChRBFQFBoMYirowyW+Q9HB4HFF4Z7VZTiG3iSzJJA29yRA==} - engines: {node: '>=10'} - dev: true - - /yargs-parser/20.2.9: - resolution: {integrity: sha512-y11nGElTIV+CT3Zv9t7VKl+Q3hTQoT9a1Qzezhhl6Rp21gJ/IVTW7Z3y9EWXhuUBC2Shnf+DX0antecpAwSP8w==} - engines: {node: '>=10'} - dev: true - - /yargs-parser/5.0.1: - resolution: {integrity: sha512-wpav5XYiddjXxirPoCTUPbqM0PXvJ9hiBMvuJgInvo4/lAOTZzUprArw17q2O1P2+GHhbBr18/iQwjL5Z9BqfA==} - dependencies: - camelcase: 3.0.0 - object.assign: 4.1.4 - dev: true - - /yargs/15.4.1: - resolution: {integrity: sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==} - engines: {node: '>=8'} - dependencies: - cliui: 6.0.0 - decamelize: 1.2.0 - find-up: 4.1.0 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - require-main-filename: 2.0.0 - set-blocking: 2.0.0 - string-width: 4.2.3 - which-module: 2.0.0 - y18n: 4.0.3 - yargs-parser: 18.1.3 - dev: true - - /yargs/16.2.0: - resolution: {integrity: sha512-D1mvvtDG0L5ft/jGWkLpG1+m0eQxOfaBvTNELraWj22wSVUMWxZUvYgJYcKh6jGGIkJFhH4IZPQhR4TKpc8mBw==} - engines: {node: '>=10'} - dependencies: - cliui: 7.0.4 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 20.2.9 - dev: true - - /yargs/7.1.2: - resolution: {integrity: sha512-ZEjj/dQYQy0Zx0lgLMLR8QuaqTihnxirir7EwUHp1Axq4e3+k8jXU5K0VLbNvedv1f4EWtBonDIZm0NUr+jCcA==} - dependencies: - camelcase: 3.0.0 - cliui: 3.2.0 - decamelize: 1.2.0 - get-caller-file: 1.0.3 - os-locale: 1.4.0 - read-pkg-up: 1.0.1 - require-directory: 2.1.1 - require-main-filename: 1.0.1 - set-blocking: 2.0.0 - string-width: 1.0.2 - which-module: 1.0.0 - y18n: 3.2.2 - yargs-parser: 5.0.1 - dev: true - - /yarn/1.22.19: - resolution: {integrity: sha512-/0V5q0WbslqnwP91tirOvldvYISzaqhClxzyUKXYxs07yUILIs5jx/k6CFe8bvKSkds5w+eiOqta39Wk3WxdcQ==} - engines: {node: '>=4.0.0'} - hasBin: true - requiresBuild: true - dev: true - - /yocto-queue/0.1.0: - resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} - engines: {node: '>=10'} - dev: true - - /zwitch/1.0.5: - resolution: {integrity: sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==} - dev: true From 5d042dd53371ed01fe9b3e8b32fdaf952e167f83 Mon Sep 17 00:00:00 2001 From: JackLian Date: Tue, 13 Dec 2022 17:18:37 +0800 Subject: [PATCH 237/823] fix: remove as Type --- .../editor-core/src/utils/assets-transform.ts | 18 ++++++++++-------- packages/types/src/assets.ts | 14 ++++++++++++-- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/packages/editor-core/src/utils/assets-transform.ts b/packages/editor-core/src/utils/assets-transform.ts index d4e735c03b..8dc1b6fc3b 100644 --- a/packages/editor-core/src/utils/assets-transform.ts +++ b/packages/editor-core/src/utils/assets-transform.ts @@ -1,25 +1,27 @@ -import { AssetsJson, ComponentDescription } from '@alilc/lowcode-types'; - +/* eslint-disable no-param-reassign */ +import { AssetsJson, ComponentDescription, Package, RemoteComponentDescription } from '@alilc/lowcode-types'; +// TODO: 该转换逻辑未来需要消化掉 export function assetsTransform(assets: AssetsJson) { const { components, packages } = assets; - const packageMaps = (packages || []).reduce((acc, cur) => { - const key = (cur.id || cur.package) as string; + const packageMaps = (packages || []).reduce((acc: Record, cur: Package) => { + const key = cur.id || cur.package || ''; acc[key] = cur; return acc; }, {} as any); - components.forEach((componentDesc) => { - let { devMode, schema, reference } = componentDesc as ComponentDescription; + components.forEach((componentDesc: ComponentDescription | RemoteComponentDescription) => { + let { devMode, schema, reference } = componentDesc; if ((devMode as string) === 'lowcode') { devMode = 'lowCode'; } else if (devMode === 'proCode') { devMode = 'proCode'; } if (devMode) { - (componentDesc as ComponentDescription).devMode = devMode; + componentDesc.devMode = devMode; } if (devMode === 'lowCode' && !schema && reference) { - (componentDesc as ComponentDescription).schema = packageMaps[reference.id as string].schema; + const referenceId = reference.id || ''; + componentDesc.schema = packageMaps[referenceId].schema; } }); return assets; diff --git a/packages/types/src/assets.ts b/packages/types/src/assets.ts index 588f562305..b9fdeffdcd 100644 --- a/packages/types/src/assets.ts +++ b/packages/types/src/assets.ts @@ -2,6 +2,7 @@ import { Snippet, ComponentMetadata } from './metadata'; import { I18nData } from './i18n'; import { Reference } from './npm'; import { EitherOr } from './utils'; +import { ComponentSchema } from './schema'; export interface AssetItem { type: AssetType; @@ -148,6 +149,10 @@ export type Package = EitherOr<{ * 组件描述导出名字,可以通过 window[exportName] 获取到组件描述的 Object 内容; */ exportName?: string; + /** + * 低代码组件 schema 内容 + */ + schema?: ComponentSchema; }, 'package', 'id'>; /** @@ -223,7 +228,7 @@ export interface ComponentDescription extends ComponentMetadata { /** * 远程物料描述 */ -export interface RemoteComponentDescription { +export interface RemoteComponentDescription extends ComponentMetadata { /** * 组件描述导出名字,可以通过 window[exportName] 获取到组件描述的 Object 内容; */ @@ -233,9 +238,14 @@ export interface RemoteComponentDescription { */ url?: string; /** - * 组件(库)的 npm 信息; + * 组件 (库) 的 npm 信息; */ package?: { npm?: string; }; + + /** + * 替代 npm 字段的升级版本 + */ + reference?: Reference; } From d9e1203eeb1800690d58eb9dce4622066d0df953 Mon Sep 17 00:00:00 2001 From: JackLian Date: Tue, 13 Dec 2022 17:44:56 +0800 Subject: [PATCH 238/823] chore: add pub:preminor --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index cbd75e75b4..08e649a3f8 100644 --- a/package.json +++ b/package.json @@ -22,6 +22,7 @@ "lint:modules:fix": "f2elint fix -i ./modules/*/src", "pub": "npm run watchdog:build && lerna publish patch --force-publish --exact --no-changelog", "pub:premajor": "npm run watchdog:build && lerna publish premajor --force-publish --exact --dist-tag beta --preid beta --no-changelog", + "pub:preminor": "npm run watchdog:build && lerna publish preminor --force-publish --exact --dist-tag beta --preid beta --no-changelog", "pub:prepatch": "npm run watchdog:build && lerna publish prepatch --force-publish --exact --dist-tag beta --preid beta --no-changelog", "pub:prerelease": "npm run watchdog:build && lerna publish prerelease --force-publish --exact --dist-tag beta --preid beta --no-changelog", "setup": "node ./scripts/setup.js", From 778ba32a14d47ba8e57b78de4f815246484e6a6c Mon Sep 17 00:00:00 2001 From: huoteng Date: Tue, 13 Dec 2022 18:58:51 +0800 Subject: [PATCH 239/823] feat: support online tree title extra --- packages/engine/src/engine-core.ts | 3 +++ .../src/helper/tree-title-extra.ts | 20 +++++++++++++++++++ .../plugin-outline-pane/src/views/pane.tsx | 5 +++++ .../src/views/tree-title.tsx | 3 +++ 4 files changed, 31 insertions(+) create mode 100644 packages/plugin-outline-pane/src/helper/tree-title-extra.ts diff --git a/packages/engine/src/engine-core.ts b/packages/engine/src/engine-core.ts index acc961c16c..7775c4c642 100644 --- a/packages/engine/src/engine-core.ts +++ b/packages/engine/src/engine-core.ts @@ -172,6 +172,9 @@ engineConfig.set('isOpenSource', isOpenSource); keepVisibleWhileDragging: true, ...engineConfig.get('defaultOutlinePaneProps'), }, + contentProps: { + treeTitleExtra: engineConfig.get('treeTitleExtra'), + }, }); skeleton.add({ area: 'rightArea', diff --git a/packages/plugin-outline-pane/src/helper/tree-title-extra.ts b/packages/plugin-outline-pane/src/helper/tree-title-extra.ts new file mode 100644 index 0000000000..b1bcbf6edc --- /dev/null +++ b/packages/plugin-outline-pane/src/helper/tree-title-extra.ts @@ -0,0 +1,20 @@ +import { globalContext } from '@alilc/lowcode-editor-core'; +import { ReactElement } from 'react'; + +const TREE_TITLE_EXTRA_KEY = 'TREE_TITLE_EXTRA_KEY'; + +export const registerTreeTitleExtra = (extra: ReactElement) => { + if (extra && !globalContext.has(TREE_TITLE_EXTRA_KEY)) { + globalContext.register(extra, TREE_TITLE_EXTRA_KEY); + } +}; + +export const getTreeTitleExtra = () => { + try { + return globalContext.get(TREE_TITLE_EXTRA_KEY); + } catch (e) { + // console.error('getTreeTitleExtra Error', e); + } + + return null; +}; diff --git a/packages/plugin-outline-pane/src/views/pane.tsx b/packages/plugin-outline-pane/src/views/pane.tsx index a57bfad92f..a86eaa3830 100644 --- a/packages/plugin-outline-pane/src/views/pane.tsx +++ b/packages/plugin-outline-pane/src/views/pane.tsx @@ -6,6 +6,7 @@ import TreeView from './tree'; import './style.less'; import { IEditor } from '@alilc/lowcode-types'; import Filter from './filter'; +import { registerTreeTitleExtra } from '../helper/tree-title-extra'; @observer export class OutlinePane extends Component<{ config: any; editor: IEditor }> { @@ -15,6 +16,10 @@ export class OutlinePane extends Component<{ config: any; editor: IEditor }> { this.main.purge(); } + componentDidMount() { + registerTreeTitleExtra(this.props?.config?.contentProps?.treeTitleExtra); + } + render() { const tree = this.main.currentTree; diff --git a/packages/plugin-outline-pane/src/views/tree-title.tsx b/packages/plugin-outline-pane/src/views/tree-title.tsx index 3398ffc631..a17440465f 100644 --- a/packages/plugin-outline-pane/src/views/tree-title.tsx +++ b/packages/plugin-outline-pane/src/views/tree-title.tsx @@ -13,6 +13,7 @@ import { IconLoop } from '../icons/loop'; import { IconRadioActive } from '../icons/radio-active'; import { IconRadio } from '../icons/radio'; import { IconLock, IconUnlock } from '../icons'; +import { getTreeTitleExtra } from '../helper/tree-title-extra'; function emitOutlineEvent(type: string, treeNode: TreeNode, rest?: Record) { @@ -97,6 +98,7 @@ export default class TreeTitle extends Component<{ }; } const { filterWorking, matchSelf, keywords } = treeNode.filterReult; + const Extra = getTreeTitleExtra(); return (
+ {Extra && } {node.slotFor && ( {/* todo: click redirect to prop */} From 546017d203c6de585dd2ce45177c249256f9cb4d Mon Sep 17 00:00:00 2001 From: JackLian Date: Wed, 14 Dec 2022 11:18:54 +0800 Subject: [PATCH 240/823] docs: some minor doc optimizations --- docs/docs/api/index.md | 34 +++++++++++++++++-- .../appendix/api.md} | 5 +-- docs/docs/guide/expand/editor/_category_.json | 6 ++-- docs/docs/guide/expand/editor/summary.md | 2 +- .../docs/guide/expand/runtime/_category_.json | 6 ++-- docs/docs/participate/config.md | 4 +-- docs/docs/participate/flow.md | 34 +++++++++++++++++-- docs/package.json | 2 +- 8 files changed, 78 insertions(+), 15 deletions(-) rename docs/docs/{api/datasource.md => demoUsage/appendix/api.md} (86%) diff --git a/docs/docs/api/index.md b/docs/docs/api/index.md index b888bad0bf..212337a620 100644 --- a/docs/docs/api/index.md +++ b/docs/docs/api/index.md @@ -3,9 +3,39 @@ title: API 总览 sidebar_position: 0 --- -引擎直接提供 9 大类 API,以及若干间接的 API,具体如下图: +引擎提供的公开 API 分为`命名空间`和`模型`两类,其中`命名空间`用于聚合一大类的 API,`模型`为各 API 涉及到的对象模型。 + +### 命名空间 + +引擎直接提供以下几大类 API + +- skeleton 面板 API +- material 物料 API +- project 模型 API +- simulator-host 模拟器 API +- hotkey 快捷键 API +- setters 设置器 API +- event 事件 API +- config 配置 API +- common 通用 API +- logger 日志 API +- init 初始化 API + +### 模型 +以下模型通过前面的 API 以返回值等形式间接透出。 + +- document-model 文档 +- node 节点 +- node-children 节点孩子 +- props 属性集 +- prop 属性 +- setting-prop-entry 设置属性 +- setting-top-entry 设置属性集 +- component-meta 物料元数据 +- selection 画布选中 +- detecting 画布 hover +- history 操作历史 -![image.png](https://img.alicdn.com/imgextra/i3/O1CN01ZA2RMv1nYlWf6ThGf_!!6000000005102-2-tps-1278-1390.png) ### API 设计约定 一些 API 设计约定: diff --git a/docs/docs/api/datasource.md b/docs/docs/demoUsage/appendix/api.md similarity index 86% rename from docs/docs/api/datasource.md rename to docs/docs/demoUsage/appendix/api.md index 994e1ee180..6c2b529c5c 100644 --- a/docs/docs/api/datasource.md +++ b/docs/docs/demoUsage/appendix/api.md @@ -1,7 +1,8 @@ --- -title: DataSource - 数据源 API -sidebar_position: 12 +title: demo 使用相关 API +sidebar_position: 2 --- +## 数据源相关 ### 请求数据源 ```javascript // 请求 userList(userList 在数据源面板中定义) diff --git a/docs/docs/guide/expand/editor/_category_.json b/docs/docs/guide/expand/editor/_category_.json index b0c35885cb..52662a9d1e 100644 --- a/docs/docs/guide/expand/editor/_category_.json +++ b/docs/docs/guide/expand/editor/_category_.json @@ -1,4 +1,6 @@ { - "label": "扩展低代码编辑器", - "position": 1 + "label": "扩展编辑态", + "position": 1, + "collapsed": false, + "collapsible": true } diff --git a/docs/docs/guide/expand/editor/summary.md b/docs/docs/guide/expand/editor/summary.md index bcb1e2b714..872205e213 100644 --- a/docs/docs/guide/expand/editor/summary.md +++ b/docs/docs/guide/expand/editor/summary.md @@ -1,5 +1,5 @@ --- -title: 低代码扩展简述 +title: 编辑态扩展简述 sidebar_position: 0 --- ## 扩展点简述 diff --git a/docs/docs/guide/expand/runtime/_category_.json b/docs/docs/guide/expand/runtime/_category_.json index 14aafc9395..f382ad4068 100644 --- a/docs/docs/guide/expand/runtime/_category_.json +++ b/docs/docs/guide/expand/runtime/_category_.json @@ -1,4 +1,6 @@ { - "label": "扩展低代码运行时", - "position": 2 + "label": "扩展运行时", + "position": 2, + "collapsed": false, + "collapsible": true } diff --git a/docs/docs/participate/config.md b/docs/docs/participate/config.md index 0694cdba34..235cd4f027 100644 --- a/docs/docs/participate/config.md +++ b/docs/docs/participate/config.md @@ -9,6 +9,7 @@ sidebar_position: 3 ``` +> 注,这里的版本号是示例,请尽量选用最新版 工程化配置我们进行了统一,具体如下: ```shell @@ -22,7 +23,6 @@ sidebar_position: 3 "react": "var window.React", "react-dom": "var window.ReactDOM", "prop-types": "var window.PropTypes", - "rax": "var window.Rax", "@alilc/lowcode-engine": "var window.AliLowCodeEngine", "@alilc/lowcode-engine-ext": "var window.AliLowCodeEngineExt", "moment": "var moment", @@ -39,7 +39,7 @@ sidebar_position: 3 ["build-plugin-fusion", { }], ["build-plugin-moment-locales", { - "locales": ["zh-cn"] + "locales": ["zh-CN"] }], "./build.plugin.js" ] diff --git a/docs/docs/participate/flow.md b/docs/docs/participate/flow.md index 676abffedf..0a088807a5 100644 --- a/docs/docs/participate/flow.md +++ b/docs/docs/participate/flow.md @@ -19,7 +19,8 @@ sidebar_position: 2 几点要求: 1. commit message 格式遵循 [ConvensionalCommits](https://www.conventionalcommits.org/en/v1.0.0/#summary) -![image.png](https://img.alicdn.com/imgextra/i3/O1CN01M9UzVM1iqYpyxECdV_!!6000000004464-2-tps-2070-594.png) + + 2. 请按照一个 bugfix / feature 对应一个 commit,假如不是,请 rebase 后再提交 MR,不要一堆无用的、试验性的 commit。 好处:从引擎的整体 commit 历史来看,会很清晰,**每个 commit 完成一件确定的事,changelog 也能自动生成**。另外,假如因为某个 commit 导致了 bug,也很容易通过 rebase drop 等方式快速修复。 @@ -42,7 +43,7 @@ sidebar_position: 2 > 此处是理想节奏,实际情况可能会有调整 -- 日常迭代 2 周,一般月中或月底 +- 日常迭代 2 周,一般月中或月底,发版日两天前发最后一个 beta 版本,原则上不接受新 pr,灰度 2 天后,发正式版。 - 特殊情况紧急迭代随时发 - 大 Feature 迭代,每年 2 - 4 次 @@ -79,7 +80,34 @@ sidebar_position: 2 如果是发布 beta 版本,步骤如下(以发布 1.0.1 版本为例): -#### 发某版本首个 beta,如 1.0.1-beta.0 +#### 发某 y 位版本首个 beta,如 1.1.0-beta.0 +1. 拉 develop 分支 + ```bash + git checkout develop + ``` + 更新到最新(如需) + ```bash + git pull + ``` +2. 拉 release 分支,此处以 1.1.0 版本做示例 + ```bash + git checkout -b release/1.1.0-beta + git push --set-upstream origin release/1.1.0-beta + ``` +3. build + ```bash + npm run build + ``` +4. 发布,此处需有 @alilc scope 发包权限 + ```bash + npm run pub:preminor + ``` +5. 同步到 tnpm 源 & alifd CDN + ```bash + tnpm run sync + ``` + +#### 发某 z 位版本首个 beta,如 1.0.1-beta.0 1. 拉 develop 分支 ```bash git checkout develop diff --git a/docs/package.json b/docs/package.json index c32b197944..d03668ad91 100644 --- a/docs/package.json +++ b/docs/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine-docs", - "version": "1.0.7", + "version": "1.0.8", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From bacbe6acaab66b7ad3dcefc7312ddd7d6758f246 Mon Sep 17 00:00:00 2001 From: JackLian Date: Wed, 14 Dec 2022 11:36:37 +0800 Subject: [PATCH 241/823] docs: fix broken link --- docs/docs/faq/faq006.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/docs/faq/faq006.md b/docs/docs/faq/faq006.md index 5a6334c04d..1a4490b1bf 100644 --- a/docs/docs/faq/faq006.md +++ b/docs/docs/faq/faq006.md @@ -3,4 +3,4 @@ title: 如何通过 API 手动调用数据源请求 sidebar_position: 6 tags: [FAQ] --- -参考:[DataSource API](/site/docs/api/datasource) \ No newline at end of file +参考:[DataSource API](/site/docs/demoUsage/appendix/api) \ No newline at end of file From 36105b28f56ca36b13614231670b7e7d6f2350eb Mon Sep 17 00:00:00 2001 From: liujuping Date: Mon, 19 Dec 2022 15:12:43 +0800 Subject: [PATCH 242/823] chore(release): publish 1.0.18 --- lerna.json | 2 +- packages/designer/package.json | 14 +++++++------- packages/editor-core/package.json | 6 +++--- packages/editor-skeleton/package.json | 10 +++++----- packages/engine/package.json | 16 ++++++++-------- packages/ignitor/package.json | 2 +- packages/plugin-designer/package.json | 8 ++++---- packages/plugin-outline-pane/package.json | 10 +++++----- packages/rax-renderer/package.json | 6 +++--- packages/rax-simulator-renderer/package.json | 10 +++++----- packages/react-renderer/package.json | 4 ++-- packages/react-simulator-renderer/package.json | 10 +++++----- packages/renderer-core/package.json | 8 ++++---- packages/shell/package.json | 12 ++++++------ packages/types/package.json | 2 +- packages/utils/package.json | 4 ++-- 16 files changed, 62 insertions(+), 62 deletions(-) diff --git a/lerna.json b/lerna.json index 506c77a040..af393cf270 100644 --- a/lerna.json +++ b/lerna.json @@ -1,6 +1,6 @@ { "lerna": "4.0.0", - "version": "1.0.17", + "version": "1.0.18", "npmClient": "yarn", "useWorkspaces": true, "packages": [ diff --git a/packages/designer/package.json b/packages/designer/package.json index 4f35daf711..320704d387 100644 --- a/packages/designer/package.json +++ b/packages/designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-designer", - "version": "1.0.17", + "version": "1.0.18", "description": "Designer for Ali LowCode Engine", "main": "lib/index.js", "module": "es/index.js", @@ -15,9 +15,9 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-editor-core": "1.0.17", - "@alilc/lowcode-types": "1.0.17", - "@alilc/lowcode-utils": "1.0.17", + "@alilc/lowcode-editor-core": "1.0.18", + "@alilc/lowcode-types": "1.0.18", + "@alilc/lowcode-utils": "1.0.18", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", @@ -27,10 +27,12 @@ }, "devDependencies": { "@alib/build-scripts": "^0.1.29", - "@alilc/lowcode-shell": "1.0.17", + "@alilc/lowcode-shell": "1.0.18", "@alilc/lowcode-test-mate": "^1.0.1", "@testing-library/react": "^11.2.2", "@types/classnames": "^2.2.7", + "@types/enzyme": "^3.10.12", + "@types/enzyme-adapter-react-16": "^1.0.6", "@types/jest": "^26.0.16", "@types/lodash": "^4.14.165", "@types/medium-editor": "^5.0.3", @@ -42,9 +44,7 @@ "build-plugin-component": "^1.0.0", "build-scripts-config": "^3.0.3", "enzyme": "^3.11.0", - "@types/enzyme": "^3.10.12", "enzyme-adapter-react-16": "^1.15.5", - "@types/enzyme-adapter-react-16": "^1.0.6", "jest": "^26.6.3", "lodash": "^4.17.20", "moment": "^2.29.1", diff --git a/packages/editor-core/package.json b/packages/editor-core/package.json index 90c551fece..39d7fd859e 100644 --- a/packages/editor-core/package.json +++ b/packages/editor-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-core", - "version": "1.0.17", + "version": "1.0.18", "description": "Core Api for Ali lowCode engine", "license": "MIT", "main": "lib/index.js", @@ -14,8 +14,8 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.0.17", - "@alilc/lowcode-utils": "1.0.17", + "@alilc/lowcode-types": "1.0.18", + "@alilc/lowcode-utils": "1.0.18", "classnames": "^2.2.6", "debug": "^4.1.1", "intl-messageformat": "^9.3.1", diff --git a/packages/editor-skeleton/package.json b/packages/editor-skeleton/package.json index 7847364129..691b3478e6 100644 --- a/packages/editor-skeleton/package.json +++ b/packages/editor-skeleton/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-editor-skeleton", - "version": "1.0.17", + "version": "1.0.18", "description": "alibaba lowcode editor skeleton", "main": "lib/index.js", "module": "es/index.js", @@ -18,10 +18,10 @@ ], "dependencies": { "@alifd/next": "^1.20.12", - "@alilc/lowcode-designer": "1.0.17", - "@alilc/lowcode-editor-core": "1.0.17", - "@alilc/lowcode-types": "1.0.17", - "@alilc/lowcode-utils": "1.0.17", + "@alilc/lowcode-designer": "1.0.18", + "@alilc/lowcode-editor-core": "1.0.18", + "@alilc/lowcode-types": "1.0.18", + "@alilc/lowcode-utils": "1.0.18", "classnames": "^2.2.6", "react": "^16.8.1", "react-dom": "^16.8.1" diff --git a/packages/engine/package.json b/packages/engine/package.json index c91ec27e5a..cae258f86c 100644 --- a/packages/engine/package.json +++ b/packages/engine/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-engine", - "version": "1.0.17", + "version": "1.0.18", "description": "An enterprise-class low-code technology stack with scale-out design / 一套面向扩展设计的企业级低代码技术体系", "main": "lib/engine-core.js", "module": "es/engine-core.js", @@ -19,14 +19,14 @@ "license": "MIT", "dependencies": { "@alifd/next": "^1.19.12", - "@alilc/lowcode-designer": "1.0.17", - "@alilc/lowcode-editor-core": "1.0.17", - "@alilc/lowcode-editor-skeleton": "1.0.17", + "@alilc/lowcode-designer": "1.0.18", + "@alilc/lowcode-editor-core": "1.0.18", + "@alilc/lowcode-editor-skeleton": "1.0.18", "@alilc/lowcode-engine-ext": "^1.0.0", - "@alilc/lowcode-plugin-designer": "1.0.17", - "@alilc/lowcode-plugin-outline-pane": "1.0.17", - "@alilc/lowcode-shell": "1.0.17", - "@alilc/lowcode-utils": "1.0.17", + "@alilc/lowcode-plugin-designer": "1.0.18", + "@alilc/lowcode-plugin-outline-pane": "1.0.18", + "@alilc/lowcode-shell": "1.0.18", + "@alilc/lowcode-utils": "1.0.18", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/ignitor/package.json b/packages/ignitor/package.json index 1da63595ca..62a9d4661a 100644 --- a/packages/ignitor/package.json +++ b/packages/ignitor/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-ignitor", - "version": "1.0.17", + "version": "1.0.18", "description": "点火器,bootstrap lce project", "main": "lib/index.js", "private": true, diff --git a/packages/plugin-designer/package.json b/packages/plugin-designer/package.json index a01ac6d4ef..a016c3d16a 100644 --- a/packages/plugin-designer/package.json +++ b/packages/plugin-designer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-designer", - "version": "1.0.17", + "version": "1.0.18", "description": "alibaba lowcode editor designer plugin", "files": [ "es", @@ -18,9 +18,9 @@ ], "author": "xiayang.xy", "dependencies": { - "@alilc/lowcode-designer": "1.0.17", - "@alilc/lowcode-editor-core": "1.0.17", - "@alilc/lowcode-utils": "1.0.17", + "@alilc/lowcode-designer": "1.0.18", + "@alilc/lowcode-editor-core": "1.0.18", + "@alilc/lowcode-utils": "1.0.18", "react": "^16.8.1", "react-dom": "^16.8.1" }, diff --git a/packages/plugin-outline-pane/package.json b/packages/plugin-outline-pane/package.json index c67a36f66a..8e8a05edfb 100644 --- a/packages/plugin-outline-pane/package.json +++ b/packages/plugin-outline-pane/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-plugin-outline-pane", - "version": "1.0.17", + "version": "1.0.18", "description": "Outline pane for Ali lowCode engine", "files": [ "es", @@ -13,10 +13,10 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-designer": "1.0.17", - "@alilc/lowcode-editor-core": "1.0.17", - "@alilc/lowcode-types": "1.0.17", - "@alilc/lowcode-utils": "1.0.17", + "@alilc/lowcode-designer": "1.0.18", + "@alilc/lowcode-editor-core": "1.0.18", + "@alilc/lowcode-types": "1.0.18", + "@alilc/lowcode-utils": "1.0.18", "classnames": "^2.2.6", "react": "^16", "react-dom": "^16.7.0", diff --git a/packages/rax-renderer/package.json b/packages/rax-renderer/package.json index e98d8511fd..98fc5d8686 100644 --- a/packages/rax-renderer/package.json +++ b/packages/rax-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-renderer", - "version": "1.0.17", + "version": "1.0.18", "description": "Rax renderer for Ali lowCode engine", "main": "lib/index.js", "module": "es/index.js", @@ -30,8 +30,8 @@ "build": "build-scripts build" }, "dependencies": { - "@alilc/lowcode-renderer-core": "1.0.17", - "@alilc/lowcode-utils": "1.0.17", + "@alilc/lowcode-renderer-core": "1.0.18", + "@alilc/lowcode-utils": "1.0.18", "rax-find-dom-node": "^1.0.1" }, "devDependencies": { diff --git a/packages/rax-simulator-renderer/package.json b/packages/rax-simulator-renderer/package.json index 680e78a70c..994fea2987 100644 --- a/packages/rax-simulator-renderer/package.json +++ b/packages/rax-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-rax-simulator-renderer", - "version": "1.0.17", + "version": "1.0.18", "description": "rax simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -13,10 +13,10 @@ "build:umd": "build-scripts build --config build.umd.json" }, "dependencies": { - "@alilc/lowcode-designer": "1.0.17", - "@alilc/lowcode-rax-renderer": "1.0.17", - "@alilc/lowcode-types": "1.0.17", - "@alilc/lowcode-utils": "1.0.17", + "@alilc/lowcode-designer": "1.0.18", + "@alilc/lowcode-rax-renderer": "1.0.18", + "@alilc/lowcode-types": "1.0.18", + "@alilc/lowcode-utils": "1.0.18", "classnames": "^2.2.6", "driver-universal": "^3.1.3", "history": "^5.0.0", diff --git a/packages/react-renderer/package.json b/packages/react-renderer/package.json index 52c5211dd1..069d65d635 100644 --- a/packages/react-renderer/package.json +++ b/packages/react-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-renderer", - "version": "1.0.17", + "version": "1.0.18", "description": "react renderer for ali lowcode engine", "main": "lib/index.js", "module": "es/index.js", @@ -22,7 +22,7 @@ ], "dependencies": { "@alifd/next": "^1.21.16", - "@alilc/lowcode-renderer-core": "1.0.17" + "@alilc/lowcode-renderer-core": "1.0.18" }, "devDependencies": { "@alib/build-scripts": "^0.1.18", diff --git a/packages/react-simulator-renderer/package.json b/packages/react-simulator-renderer/package.json index 45cc423c8c..45dcac2ae9 100644 --- a/packages/react-simulator-renderer/package.json +++ b/packages/react-simulator-renderer/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-react-simulator-renderer", - "version": "1.0.17", + "version": "1.0.18", "description": "react simulator renderer for alibaba lowcode designer", "main": "lib/index.js", "module": "es/index.js", @@ -17,10 +17,10 @@ "test:cov": "build-scripts test --config build.test.json --jest-coverage" }, "dependencies": { - "@alilc/lowcode-designer": "1.0.17", - "@alilc/lowcode-react-renderer": "1.0.17", - "@alilc/lowcode-types": "1.0.17", - "@alilc/lowcode-utils": "1.0.17", + "@alilc/lowcode-designer": "1.0.18", + "@alilc/lowcode-react-renderer": "1.0.18", + "@alilc/lowcode-types": "1.0.18", + "@alilc/lowcode-utils": "1.0.18", "classnames": "^2.2.6", "mobx": "^6.3.0", "mobx-react": "^7.2.0", diff --git a/packages/renderer-core/package.json b/packages/renderer-core/package.json index 217606287a..e12cda3090 100644 --- a/packages/renderer-core/package.json +++ b/packages/renderer-core/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-renderer-core", - "version": "1.0.17", + "version": "1.0.18", "description": "renderer core", "license": "MIT", "main": "lib/index.js", @@ -16,8 +16,8 @@ }, "dependencies": { "@alilc/lowcode-datasource-engine": "^1.0.0", - "@alilc/lowcode-types": "1.0.17", - "@alilc/lowcode-utils": "1.0.17", + "@alilc/lowcode-types": "1.0.18", + "@alilc/lowcode-utils": "1.0.18", "classnames": "^2.2.6", "debug": "^4.1.1", "fetch-jsonp": "^1.1.3", @@ -33,7 +33,7 @@ "devDependencies": { "@alib/build-scripts": "^0.1.18", "@alifd/next": "^1.26.0", - "@alilc/lowcode-designer": "1.0.17", + "@alilc/lowcode-designer": "1.0.18", "@alilc/lowcode-test-mate": "^1.0.1", "@babel/plugin-transform-typescript": "^7.16.8", "@testing-library/react": "^11.2.2", diff --git a/packages/shell/package.json b/packages/shell/package.json index fd794904bb..6922dced5a 100644 --- a/packages/shell/package.json +++ b/packages/shell/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-shell", - "version": "1.0.17", + "version": "1.0.18", "description": "Shell Layer for AliLowCodeEngine", "main": "lib/index.js", "module": "es/index.js", @@ -15,11 +15,11 @@ }, "license": "MIT", "dependencies": { - "@alilc/lowcode-designer": "1.0.17", - "@alilc/lowcode-editor-core": "1.0.17", - "@alilc/lowcode-editor-skeleton": "1.0.17", - "@alilc/lowcode-types": "1.0.17", - "@alilc/lowcode-utils": "1.0.17", + "@alilc/lowcode-designer": "1.0.18", + "@alilc/lowcode-editor-core": "1.0.18", + "@alilc/lowcode-editor-skeleton": "1.0.18", + "@alilc/lowcode-types": "1.0.18", + "@alilc/lowcode-utils": "1.0.18", "classnames": "^2.2.6", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/packages/types/package.json b/packages/types/package.json index c61ecded9f..0df2532967 100644 --- a/packages/types/package.json +++ b/packages/types/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-types", - "version": "1.0.17", + "version": "1.0.18", "description": "Types for Ali lowCode engine", "files": [ "es", diff --git a/packages/utils/package.json b/packages/utils/package.json index 2b1b75fb1b..7a27152922 100644 --- a/packages/utils/package.json +++ b/packages/utils/package.json @@ -1,6 +1,6 @@ { "name": "@alilc/lowcode-utils", - "version": "1.0.17", + "version": "1.0.18", "description": "Utils for Ali lowCode engine", "files": [ "lib", @@ -14,7 +14,7 @@ }, "dependencies": { "@alifd/next": "^1.19.16", - "@alilc/lowcode-types": "1.0.17", + "@alilc/lowcode-types": "1.0.18", "lodash": "^4.17.21", "mobx": "^6.3.0", "react": "^16", From 064e8423825defcb972640479a662c8d24470c5d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Wed, 14 Dec 2022 17:25:02 +0800 Subject: [PATCH 243/823] feat(spec): support type NodeSchema when the Node is JSSlot --- docs/docs/specs/lowcode-spec.md | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/docs/docs/specs/lowcode-spec.md b/docs/docs/specs/lowcode-spec.md index 6ad87caefe..cbe2040949 100644 --- a/docs/docs/specs/lowcode-spec.md +++ b/docs/docs/specs/lowcode-spec.md @@ -281,7 +281,7 @@ sidebar_position: 0 | 参数 | 说明 | 类型 | 变量支持 | 默认值 | | --------------- | ---------------------- | ------------------------- | -------- | ------ | -| componentsMap[] | 描述组件映射关系的集合 | Array\<**ComponentMap**\> | - | null | +| componentsMap[] | 描述组件映射关系的集合 | **ComponentMap**[] | - | null | **ComponentMap 结构描述**如下: @@ -413,7 +413,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 +607,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 +751,7 @@ try { | 参数 | 说明 | 值类型 | 默认值 | 备注 | | ----- | ---------- | --------------------- | -------- | -------------------------------------------------------------- | | type | 值类型描述 | String | 'JSSlot' | 固定值 | -| value | 具体的值 | Array\ | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述(A)) | +| value | 具体的值 | NodeSchema \| NodeSchema[] | null | 内容为 NodeSchema 类型,详见[组件结构描述](#232-组件结构描述(A)) | 举例描述:如 **Card** 的 **title** 属性 @@ -782,8 +782,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 +1106,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) | - | | From 3fe9882f9d5ef9302ee0265facb26ba1e58cccad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Wed, 21 Dec 2022 09:52:55 +0800 Subject: [PATCH 244/823] fix: compatible with SlotSchema which doesn't have title / name / params --- packages/designer/src/document/node/props/prop.ts | 12 ++++++++++-- packages/types/src/schema.ts | 7 +++++++ 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/packages/designer/src/document/node/props/prop.ts b/packages/designer/src/document/node/props/prop.ts index 634a6b14bf..33eb45d1cf 100644 --- a/packages/designer/src/document/node/props/prop.ts +++ b/packages/designer/src/document/node/props/prop.ts @@ -315,9 +315,17 @@ export class Prop implements IPropParent { setAsSlot(data: JSSlot) { this._type = 'slot'; let slotSchema: SlotSchema; - // 当 data.value 的结构为 { componentName: 'Slot' } 时,直接当成 slotSchema 使用 + // 当 data.value 的结构为 { componentName: 'Slot' } 时,复用部分 slotSchema 数据 if ((isPlainObject(data.value) && data.value?.componentName === 'Slot')) { - slotSchema = data.value as SlotSchema; + const value = data.value as SlotSchema; + slotSchema = { + componentName: 'Slot', + title: value.title || value.props?.slotTitle, + id: data.id, + name: value.name || value.props?.slotName, + params: value.params || value.props?.slotParams, + children: data.value, + } as SlotSchema; } else { slotSchema = { componentName: 'Slot', diff --git a/packages/types/src/schema.ts b/packages/types/src/schema.ts index e320d6b510..fe86a4132a 100644 --- a/packages/types/src/schema.ts +++ b/packages/types/src/schema.ts @@ -162,7 +162,14 @@ export type RootSchema = PageSchema | ComponentSchema | BlockSchema; export interface SlotSchema extends NodeSchema { componentName: 'Slot'; name?: string; + title?: string; params?: string[]; + props?: { + slotTitle?: string; + slotName?: string; + slotParams?: string[]; + }; + children?: NodeSchema[]; } /** From b3938b69a1f9548b25bc7357f8020f217c46733e Mon Sep 17 00:00:00 2001 From: JackLian Date: Tue, 20 Dec 2022 21:33:13 +0800 Subject: [PATCH 245/823] chore: add new cdn support --- docs/README.md | 7 ++--- docs/docs/guide/create/useEditor.md | 4 ++- docs/docs/participate/flow.md | 15 ++++++--- docs/package.json | 3 +- docs/scripts/sync-oss.js | 48 +++++++++++++++++++++++++++++ package.json | 3 +- packages/engine/README-zh_CN.md | 25 +++++++++------ packages/engine/README.md | 25 +++++++++------ scripts/sync-oss.js | 48 +++++++++++++++++++++++++++++ 9 files changed, 148 insertions(+), 30 deletions(-) create mode 100644 docs/scripts/sync-oss.js create mode 100644 scripts/sync-oss.js diff --git a/docs/README.md b/docs/README.md index 12c8f1fbe9..85da75163c 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/docs/guide/create/useEditor.md b/docs/docs/guide/create/useEditor.md index 21de391080..7a778e02de 100644 --- a/docs/docs/guide/create/useEditor.md +++ b/docs/docs/guide/create/useEditor.md @@ -80,7 +80,9 @@ 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 的服务比较缓慢,您可以使用 alicdn 来获得确定版本的低代码引擎,如对于引擎的 1.0.18 版本,可用以下官方 cdn 替代 +> - [https://alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.18/dist/js/engine-core.js](https://alifd.alicdn.com/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](https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.18/dist/js/engine-core.js) ### 配置打包 diff --git a/docs/docs/participate/flow.md b/docs/docs/participate/flow.md index 0a088807a5..b8b804e123 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/package.json b/docs/package.json index d03668ad91..1cf731345b 100644 --- a/docs/package.json +++ b/docs/package.json @@ -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/sync-oss.js b/docs/scripts/sync-oss.js new file mode 100644 index 0000000000..407f113bdb --- /dev/null +++ b/docs/scripts/sync-oss.js @@ -0,0 +1,48 @@ +#!/usr/bin/env node +const http = require('http'); +const package = require('../package.json'); +const { version, name } = package; +const options = { + method: 'PUT', + // 暂时使用 日常环境的 uipaas-node,上线后可切换成线上环境 https://uipaas-node.alibaba-inc.com + hostname: 'uipaas-node.alibaba.net', + 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/package.json b/package.json index 08e649a3f8..572958d822 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,8 @@ "test": "lerna run test --stream", "test:snapshot": "lerna run test:snapshot", "watchdog:build": "node ./scripts/watchdog.js", - "sync": "./scripts/sync.sh" + "sync": "./scripts/sync.sh", + "syncOss": "node ./scripts/sync-oss.js" }, "husky": { "hooks": { diff --git a/packages/engine/README-zh_CN.md b/packages/engine/README-zh_CN.md index 000a711f5f..793ee050be 100644 --- a/packages/engine/README-zh_CN.md +++ b/packages/engine/README-zh_CN.md @@ -97,26 +97,33 @@ init(document.getElementById('lce')); ### cdn 可选方式: #### 方式 1(推荐):alifd cdn ```html -https://alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.0/dist/js/engine-core.js +https://alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.18/dist/js/engine-core.js -https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@1.0.0/dist/js/react-simulator-renderer.js +https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@1.0.18/dist/js/react-simulator-renderer.js ``` -#### 方式 2:unpkg +#### 方式 2(推荐):uipaas cdn ```html -https://unpkg.com/@alilc/lowcode-engine@1.0.0/dist/js/engine-core.js +https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.18/dist/js/engine-core.js -https://unpkg.com/@alilc/lowcode-react-simulator-renderer@1.0.0/dist/js/react-simulator-renderer.js +https://uipaas-assets.com/prod/npm/@alilc/lowcode-react-simulator-renderer/1.0.18/dist/js/react-simulator-renderer.js ``` -#### 方式 3:jsdelivr +#### 方式 3:unpkg ```html -https://cdn.jsdelivr.net/npm/@alilc/lowcode-engine@1.0.0/dist/js/engine-core.js +https://unpkg.com/@alilc/lowcode-engine@1.0.18/dist/js/engine-core.js -https://cdn.jsdelivr.net/npm/@alilc/lowcode-react-simulator-renderer@1.0.0/dist/js/react-simulator-renderer.js +https://unpkg.com/@alilc/lowcode-react-simulator-renderer@1.0.18/dist/js/react-simulator-renderer.js ``` -#### 方式 4:使用自有 cdn +#### 方式 4:jsdelivr +```html +https://cdn.jsdelivr.net/npm/@alilc/lowcode-engine@1.0.18/dist/js/engine-core.js + +https://cdn.jsdelivr.net/npm/@alilc/lowcode-react-simulator-renderer@1.0.18/dist/js/react-simulator-renderer.js +``` + +#### 方式 5:使用自有 cdn 将源码中 packages/engine/dist 和 packages/(react|rax)-simulator-renderer/dist 下的文件传至你的 cdn 提供商 ## 🔗 相关链接 diff --git a/packages/engine/README.md b/packages/engine/README.md index 8b11e5a1a4..8ce6759231 100644 --- a/packages/engine/README.md +++ b/packages/engine/README.md @@ -97,26 +97,33 @@ init(document.getElementById('lce')); ### cdn optional method: #### Method 1: alifd cdn ```html -https://alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.0/dist/js/engine-core.js +https://alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.18/dist/js/engine-core.js -https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@1.0.0/dist/js/react-simulator-renderer.js +https://alifd.alicdn.com/npm/@alilc/lowcode-react-simulator-renderer@1.0.18/dist/js/react-simulator-renderer.js ``` -#### Method 2: unpkg +#### Method 2: uipaas cdn ```html -https://unpkg.com/@alilc/lowcode-engine@1.0.0/dist/js/engine-core.js +https://uipaas-assets.com/prod/npm/@alilc/lowcode-engine/1.0.18/dist/js/engine-core.js -https://unpkg.com/@alilc/lowcode-react-simulator-renderer@1.0.0/dist/js/react-simulator-renderer.js +https://uipaas-assets.com/prod/npm/@alilc/lowcode-react-simulator-renderer/1.0.18/dist/js/react-simulator-renderer.js ``` -#### Method 3: jsdelivr +#### Method 3: unpkg ```html -https://cdn.jsdelivr.net/npm/@alilc/lowcode-engine@1.0.0/dist/js/engine-core.js +https://unpkg.com/@alilc/lowcode-engine@1.0.18/dist/js/engine-core.js -https://cdn.jsdelivr.net/npm/@alilc/lowcode-react-simulator-renderer@1.0.0/dist/js/react-simulator-renderer.js +https://unpkg.com/@alilc/lowcode-react-simulator-renderer@1.0.18/dist/js/react-simulator-renderer.js ``` -#### Method 4: Use your own cdn +#### Method 4: jsdelivr +```html +https://cdn.jsdelivr.net/npm/@alilc/lowcode-engine@1.0.18/dist/js/engine-core.js + +https://cdn.jsdelivr.net/npm/@alilc/lowcode-react-simulator-renderer@1.0.18/dist/js/react-simulator-renderer.js +``` + +#### Method 5: Use your own cdn Pass the files under packages/engine/dist and packages/(react|rax)-simulator-renderer/dist in the source code to your cdn provider ## 🔗 Related Links diff --git a/scripts/sync-oss.js b/scripts/sync-oss.js new file mode 100644 index 0000000000..422f7162d5 --- /dev/null +++ b/scripts/sync-oss.js @@ -0,0 +1,48 @@ +#!/usr/bin/env node +const http = require('http'); +const package = require('../packages/engine/package.json'); +const { version, name } = package; +const options = { + method: 'PUT', + // 暂时使用 日常环境的 uipaas-node,上线后可切换成线上环境 https://uipaas-node.alibaba-inc.com + hostname: 'uipaas-node.alibaba.net', + 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 From 82b6a01533337db7b1489c4b1a3235993bb45a7f Mon Sep 17 00:00:00 2001 From: JackLian Date: Wed, 21 Dec 2022 11:41:28 +0800 Subject: [PATCH 246/823] docs: change cdn --- docs/docs/guide/create/useEditor.md | 11 +++++------ docs/docs/participate/config.md | 26 +++++++++++++++++--------- docs/docs/participate/prepare.md | 12 ++++++------ docs/package.json | 2 +- 4 files changed, 29 insertions(+), 22 deletions(-) diff --git a/docs/docs/guide/create/useEditor.md b/docs/docs/guide/create/useEditor.md index 7a778e02de..cbb38f77de 100644 --- a/docs/docs/guide/create/useEditor.md +++ b/docs/docs/guide/create/useEditor.md @@ -54,13 +54,13 @@ sidebar_position: 0 ```html - + - + @@ -76,12 +76,11 @@ sidebar_position: 0 - + - + ``` -> 注:如果 unpkg 的服务比较缓慢,您可以使用 alicdn 来获得确定版本的低代码引擎,如对于引擎的 1.0.18 版本,可用以下官方 cdn 替代 -> - [https://alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.18/dist/js/engine-core.js](https://alifd.alicdn.com/npm/@alilc/lowcode-engine@1.0.18/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/participate/config.md b/docs/docs/participate/config.md index 235cd4f027..1d70a7a89e 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/prepare.md b/docs/docs/participate/prepare.md index b23dff33d5..c0e1d5880e 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/package.json b/docs/package.json index 1cf731345b..d28f9e7cfa 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.9", "description": "低代码引擎版本化文档", "license": "MIT", "files": [ From 1ca940c88001ac0e201e447ad5a37a9a1f5f537e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Tue, 13 Dec 2022 11:36:44 +0800 Subject: [PATCH 247/823] feat: support UIPaaS-Component code generator solution --- .../code-generator/src/cli/solutions/example-solution.ts | 4 ++-- modules/code-generator/src/generator/ProjectBuilder.ts | 9 ++++++--- modules/code-generator/src/parser/SchemaParser.ts | 7 +++---- .../code-generator/src/postprocessor/prettier/index.ts | 4 +++- modules/code-generator/src/types/core.ts | 6 ++++++ modules/code-generator/src/utils/dataSource.ts | 8 ++++---- modules/code-generator/src/utils/index.ts | 2 ++ modules/code-generator/src/utils/nodeToJSX.ts | 8 +++----- modules/code-generator/src/utils/schema.ts | 8 ++++++++ 9 files changed, 37 insertions(+), 19 deletions(-) diff --git a/modules/code-generator/src/cli/solutions/example-solution.ts b/modules/code-generator/src/cli/solutions/example-solution.ts index 2efff780cd..fe303f360f 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/ProjectBuilder.ts b/modules/code-generator/src/generator/ProjectBuilder.ts index 2a1282d6eb..186def2c58 100644 --- a/modules/code-generator/src/generator/ProjectBuilder.ts +++ b/modules/code-generator/src/generator/ProjectBuilder.ts @@ -62,10 +62,10 @@ export class ProjectBuilder implements IProjectBuilder { private projectPostProcessors: ProjectPostProcessor[]; /** 是否处于严格模式 */ - public readonly inStrictMode: boolean; + readonly inStrictMode: boolean; /** 一些额外的上下文数据 */ - public readonly extraContextData: IContextData; + readonly extraContextData: IContextData; constructor({ template, @@ -260,7 +260,10 @@ 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; diff --git a/modules/code-generator/src/parser/SchemaParser.ts b/modules/code-generator/src/parser/SchemaParser.ts index 2e526d88bc..ab46365610 100644 --- a/modules/code-generator/src/parser/SchemaParser.ts +++ b/modules/code-generator/src/parser/SchemaParser.ts @@ -32,7 +32,7 @@ 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'; @@ -141,7 +141,7 @@ export class SchemaParser implements ISchemaParser { if (schema.componentsTree.length > 0) { const firstRoot: ContainerSchema = schema.componentsTree[0] as ContainerSchema; - if (!('fileName' in firstRoot) || !firstRoot.fileName) { + if (!firstRoot.fileName && !isValidContainerType(firstRoot)) { // 整个 schema 描述一个容器,且无根节点定义 const container: IContainerInfo = { ...firstRoot, @@ -259,8 +259,7 @@ export class SchemaParser implements ISchemaParser { 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: NpmInfo } => u.type !== 'function', ) .map( (u): IExternalDependency => ({ diff --git a/modules/code-generator/src/postprocessor/prettier/index.ts b/modules/code-generator/src/postprocessor/prettier/index.ts index afdcc62258..d4e61e3c00 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/types/core.ts b/modules/code-generator/src/types/core.ts index 99ca8c97ad..b1a00ad373 100644 --- a/modules/code-generator/src/types/core.ts +++ b/modules/code-generator/src/types/core.ts @@ -170,11 +170,17 @@ export interface IProjectBuilder { /** 项目级别的前置处理器 */ export type ProjectPreProcessor = (schema: ProjectSchema) => Promise | ProjectSchema; +export interface ProjectPostProcessorOptions { + parseResult?: IParseResult; + template?: IProjectTemplate; +} + /** 项目级别的后置处理器 */ export type ProjectPostProcessor = ( result: ResultDir, schema: ProjectSchema, originalSchema: ProjectSchema | string, + options: ProjectPostProcessorOptions, ) => Promise | ResultDir; /** 模块级别的后置处理器的工厂方法 */ diff --git a/modules/code-generator/src/utils/dataSource.ts b/modules/code-generator/src/utils/dataSource.ts index 610f399344..cd10351624 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 ff5194172d..cac63d415c 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/nodeToJSX.ts b/modules/code-generator/src/utils/nodeToJSX.ts index 0b5919902f..e928b866b7 100644 --- a/modules/code-generator/src/utils/nodeToJSX.ts +++ b/modules/code-generator/src/utils/nodeToJSX.ts @@ -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; @@ -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, 下面会统一加的 }), @@ -391,8 +390,7 @@ export function createNodeGenerator(cfg: NodeGeneratorConfig = {}): NodeGenerato return `{${valueStr}}`; }; - return (nodeItem: NodeDataType, scope: IScope) => - unwrapJsExprQuoteInJsx(generateNode(nodeItem, scope)); + return (nodeItem: NodeDataType, 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 b2faecbc64..9a4f131d41 100644 --- a/modules/code-generator/src/utils/schema.ts +++ b/modules/code-generator/src/utils/schema.ts @@ -138,3 +138,11 @@ export function handleSubNodes( return []; } } + +export function isValidContainerType(schema: NodeSchema) { + return [ + 'Page', + 'Component', + 'Block', + ].includes(schema.componentName); +} \ No newline at end of file From 2bd40d7589167553d82f69993363eecf466fff20 Mon Sep 17 00:00:00 2001 From: eternalsky Date: Wed, 14 Dec 2022 10:00:27 +0800 Subject: [PATCH 248/823] feat(codegen): add demo slots & add new cli option solutionOptions --- .../bin/lowcode-code-generator.js | 1 + modules/code-generator/src/cli/run.ts | 18 ++++++++++++++++-- .../src/generator/ProjectBuilder.ts | 9 +++++++++ modules/code-generator/src/types/core.ts | 1 + 4 files changed, 27 insertions(+), 2 deletions(-) diff --git a/modules/code-generator/bin/lowcode-code-generator.js b/modules/code-generator/bin/lowcode-code-generator.js index 6259a5a6fc..79c36c49a0 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/src/cli/run.ts b/modules/code-generator/src/cli/run.ts index db66b46013..7dcfd9d5ac 100644 --- a/modules/code-generator/src/cli/run.ts +++ b/modules/code-generator/src/cli/run.ts @@ -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']; } diff --git a/modules/code-generator/src/generator/ProjectBuilder.ts b/modules/code-generator/src/generator/ProjectBuilder.ts index 186def2c58..1cac2dea2d 100644 --- a/modules/code-generator/src/generator/ProjectBuilder.ts +++ b/modules/code-generator/src/generator/ProjectBuilder.ts @@ -241,6 +241,15 @@ 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 diff --git a/modules/code-generator/src/types/core.ts b/modules/code-generator/src/types/core.ts index b1a00ad373..f79db6cd90 100644 --- a/modules/code-generator/src/types/core.ts +++ b/modules/code-generator/src/types/core.ts @@ -25,6 +25,7 @@ export enum FileType { TS = 'ts', TSX = 'tsx', JSON = 'json', + MD = 'md', } export enum ChunkType { From 9cb4f0bd791edf3a55ffa99c7a6cf651dad56b84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?LeoYuan=20=E8=A2=81=E5=8A=9B=E7=9A=93?= Date: Wed, 14 Dec 2022 14:21:55 +0800 Subject: [PATCH 249/823] chore: update UT snapshots of CodeGenerator --- .../tests/bugfix/i18n-with-params.test.ts | 2 +- .../bugfix/icejs-import-wrong-naming.test.ts | 28 +- .../bugfix/icejs-missing-imports-1.test.ts | 2 +- .../icejs-package-json-dependencies.test.ts | 10 +- .../demo01/expected/demo-project/package.json | 2 +- .../demo02/expected/demo-project/package.json | 6 +- .../demo-project/src/pages/Home/index.jsx | 2 + .../demo03/expected/demo-project/package.json | 2 +- .../demo04/expected/demo-project/package.json | 2 +- .../demo05/expected/demo-project/package.json | 2 +- .../expected/demo-project/package.json | 2 +- .../expected/demo-project/package.json | 2 +- .../expected/demo-project/package.json | 2 +- .../expected/demo-project/package.json | 2 +- .../expected/demo-project/package.json | 2 +- .../expected/demo-project/package.json | 4 +- .../expected/demo-project/package.json | 2 +- .../expected/demo-project/package.json | 4 +- .../demo1/expected/demo-project/package.json | 6 +- .../demo1/expected/demo-project/src/app.js | 6 +- .../expected/demo-project/src/constants.js | 2 +- .../expected/demo-project/src/global.scss | 2 +- .../demo1/expected/demo-project/src/i18n.js | 18 +- .../demo-project/src/pages/Test/index.jsx | 62 +-- .../demo1/expected/demo-project/src/routes.js | 8 +- .../demo1/expected/demo-project/src/utils.js | 2 +- .../expected/demo-project/package.json | 4 +- .../expected/demo-project/src/app.js | 6 +- .../expected/demo-project/src/global.scss | 2 +- .../expected/demo-project/src/i18n.js | 18 +- .../demo-project/src/pages/Aaaa/index.jsx | 26 +- .../expected/demo-project/src/routes.js | 8 +- .../expected/demo-project/src/utils.js | 8 +- .../demo2/expected/demo-project/package.json | 2 +- .../demo2/expected/demo-project/src/app.js | 6 +- .../expected/demo-project/src/constants.js | 2 +- .../expected/demo-project/src/global.scss | 2 +- .../demo2/expected/demo-project/src/i18n.js | 30 +- .../demo-project/src/pages/Test/index.jsx | 34 +- .../demo2/expected/demo-project/src/routes.js | 8 +- .../demo2/expected/demo-project/src/utils.js | 2 +- .../demo3/expected/demo-project/package.json | 2 +- .../demo3/expected/demo-project/src/app.js | 6 +- .../expected/demo-project/src/constants.js | 2 +- .../expected/demo-project/src/global.scss | 2 +- .../demo3/expected/demo-project/src/i18n.js | 30 +- .../demo-project/src/pages/Test/index.jsx | 14 +- .../demo3/expected/demo-project/src/routes.js | 8 +- .../demo3/expected/demo-project/src/utils.js | 2 +- .../demo4/expected/demo-project/package.json | 6 +- .../demo4/expected/demo-project/src/app.js | 6 +- .../expected/demo-project/src/global.scss | 2 +- .../demo4/expected/demo-project/src/i18n.js | 18 +- .../demo-project/src/pages/Test/index.jsx | 72 ++-- .../demo4/expected/demo-project/src/routes.js | 8 +- .../demo4/expected/demo-project/src/utils.js | 2 +- .../test-cases/react-app/demo4/schema.json5 | 10 +- .../demo5/expected/demo-project/package.json | 2 +- .../demo5/expected/demo-project/src/app.js | 6 +- .../expected/demo-project/src/global.scss | 2 +- .../demo5/expected/demo-project/src/i18n.js | 18 +- .../demo-project/src/pages/Test/index.jsx | 156 +++---- .../demo5/expected/demo-project/src/routes.js | 8 +- .../demo5/expected/demo-project/src/utils.js | 2 +- .../expected/demo-project/package.json | 6 +- .../expected/demo-project/src/app.js | 6 +- .../expected/demo-project/src/constants.js | 2 +- .../expected/demo-project/src/global.scss | 2 +- .../expected/demo-project/src/i18n.js | 18 +- .../demo-project/src/pages/Test/index.jsx | 62 +-- .../expected/demo-project/src/routes.js | 8 +- .../expected/demo-project/src/utils.js | 2 +- .../expected/demo-project/package.json | 2 +- .../expected/demo-project/src/app.js | 6 +- .../expected/demo-project/src/global.scss | 2 +- .../expected/demo-project/src/i18n.js | 18 +- .../demo-project/src/pages/Test/index.jsx | 398 +++++++++--------- .../expected/demo-project/src/routes.js | 8 +- .../expected/demo-project/src/utils.js | 2 +- .../expected/demo-project/package.json | 4 +- .../expected/demo-project/src/app.js | 6 +- .../expected/demo-project/src/global.scss | 2 +- .../expected/demo-project/src/i18n.js | 18 +- .../demo-project/src/pages/Example/index.jsx | 30 +- .../expected/demo-project/src/routes.js | 8 +- .../expected/demo-project/src/utils.js | 2 +- .../expected/demo-project/package.json | 4 +- .../expected/demo-project/src/app.js | 6 +- .../src/components/Index/index.jsx | 120 ------ .../expected/demo-project/src/global.scss | 2 +- .../expected/demo-project/src/i18n.js | 18 +- .../{components/Index => pages/$}/index.css | 0 .../demo-project/src/pages/$/index.jsx | 79 ++++ .../expected/demo-project/src/routes.js | 13 +- .../expected/demo-project/src/utils.js | 2 +- .../expected/demo-project/package.json | 2 +- .../expected/demo-project/src/app.js | 6 +- .../expected/demo-project/src/global.scss | 2 +- .../expected/demo-project/src/i18n.js | 18 +- .../demo-project/src/pages/Test/index.jsx | 226 +++++----- .../expected/demo-project/src/routes.js | 8 +- .../expected/demo-project/src/utils.js | 2 +- .../expected/demo-project/package.json | 2 +- .../expected/demo-project/src/app.js | 6 +- .../expected/demo-project/src/global.scss | 2 +- .../expected/demo-project/src/i18n.js | 18 +- .../demo-project/src/pages/Test/index.jsx | 293 ++++++------- .../expected/demo-project/src/routes.js | 8 +- .../expected/demo-project/src/utils.js | 2 +- .../__snapshots__/prettier.test.ts.snap | 4 +- 110 files changed, 1078 insertions(+), 1103 deletions(-) delete mode 100644 modules/code-generator/tests/fixtures/test-cases/react-app/demo9-datasource-engine/expected/demo-project/src/components/Index/index.jsx rename modules/code-generator/tests/fixtures/test-cases/react-app/demo9-datasource-engine/expected/demo-project/src/{components/Index => pages/$}/index.css (100%) create mode 100644 modules/code-generator/tests/fixtures/test-cases/react-app/demo9-datasource-engine/expected/demo-project/src/pages/$/index.jsx 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 be2d5e9e68..d640525eb1 100644 --- a/modules/code-generator/tests/bugfix/i18n-with-params.test.ts +++ b/modules/code-generator/tests/bugfix/i18n-with-params.test.ts @@ -19,7 +19,7 @@ describe(testCaseBaseName, () => { ` 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 51e22b3a97..1f29fe6122 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 @@ -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,11 +187,11 @@ 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 ='); }); }); 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 17c40a4fa1..cad73474ac 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 6edd6b9124..88ca02c6ba 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/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 38cfdd186a..fd03ed9bc5 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 ca5a0f59cb..4d9a779880 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 06e39454d0..7bfda59caf 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 48690ff4d9..58b97921b5 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 16fa70bbc1..56dda7653a 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 38cfdd186a..fd03ed9bc5 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 bf31a967ea..dc00ba429f 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 38cfdd186a..fd03ed9bc5 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 bf31a967ea..dc00ba429f 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 bf31a967ea..dc00ba429f 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 bf31a967ea..dc00ba429f 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 60f0cb38a1..067cc161d9 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 38cfdd186a..fd03ed9bc5 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 3e59d29844..afadad8785 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 767ec3898f..36eaf12f26 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 fb01b106b4..266d8ef71d 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 c4a5859ee4..91198f9044 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 2d97c56b09..ed7204b4a3 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 1ae7c84b5e..adbbe673dc 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 b90fe6254d..c8db61db74 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 { -
+