Merge branch 2.x-fix-types into 2.x

Title: 补充第二批类型定义 

- 优化 types 类型定义,使得类型注释能在 VSCode 中正确被提示

![](https://cn-hangzhou.oss-cdn.aliyun-inc.com/git/force/uploads/comment/43449/101888317763806785/image.png)

-  参照协议规范,完善所有 schema 和 asset 相关描述
- 将资产包协议的类型定义从 utils 移动到 types 中
- 跟随物料规范,追加 ComponentSort 标识

Link: https://code.aone.alibaba-inc.com/ali-lowcode/ali-lowcode-engine/codereview/7216325
This commit is contained in:
lihao.ylh 2021-12-21 14:43:21 +08:00
commit 9a4da20bf0
13 changed files with 842 additions and 205 deletions

View File

@ -13,5 +13,5 @@ export interface SettingEntry extends SettingTarget {
// 父级
readonly parent: SettingEntry;
get(propName: string | number): SettingEntry | null;
get: (propName: string | number) => SettingEntry | null;
}

View File

@ -18,9 +18,9 @@ export interface IWidgetBaseConfig {
name: string;
/**
*
* type 'Panel' 'leftFloatArea'
* type 'Widget' 'mainArea'
* 'leftArea'
* - type 'Panel' 'leftFloatArea'
* - type 'Widget' 'mainArea'
* - 'leftArea'
*/
area?: IWidgetConfigArea;
props?: Record<string, any>;

View File

@ -1,35 +1,223 @@
import { NpmInfo } from './npm';
import { PropConfig } from './prop-config';
import { Snippet, ComponentMetadata } from './metadata';
import { I18nData } from './i18n';
export interface Package { // 应该被编辑器默认加载定义组件大包及external资源的信息
package: string; // 包名
version: string; // 包版本号
urls?: string[] | any; // 组件渲染态视图打包后的 CDN url 列表,包含 js 和 css
editUrls?: string[] | any; // 组件编辑态视图打包后的 CDN url 列表,包含 js 和 css
library: string; // 作为全局变量引用时的名称和webpack output.library字段含义一样用来定义全局变量名
async?: boolean,
export interface AssetItem {
type: AssetType;
content?: string | null;
device?: string;
level?: AssetLevel;
id?: string;
}
export enum AssetLevel {
// 环境依赖库 比如 react, react-dom
Environment = 1,
// 基础类库,比如 lodash deep fusion antd
Library = 2,
// 主题
Theme = 3,
// 运行时
Runtime = 4,
// 业务组件
Components = 5,
// 应用 & 页面
App = 6,
}
export const AssetLevels = [
AssetLevel.Environment,
AssetLevel.Library,
AssetLevel.Theme,
AssetLevel.Runtime,
AssetLevel.Components,
AssetLevel.App,
];
export type URL = string;
export enum AssetType {
JSUrl = 'jsUrl',
CSSUrl = 'cssUrl',
CSSText = 'cssText',
JSText = 'jsText',
Bundle = 'bundle',
}
export interface AssetBundle {
type: AssetType.Bundle;
level?: AssetLevel;
assets?: Asset | AssetList | null;
}
export type Asset = AssetList | AssetBundle | AssetItem | URL;
export type AssetList = Array<Asset | undefined | null>;
/**
*
*/
export interface AssetsJson {
/**
*
*/
version: string;
/**
* external与package的概念相似
*/
packages?: Package[];
/**
*
*/
components: Array<ComponentDescription | RemoteComponentDescription>;
/**
*
* @deprecated
*/
componentList?: ComponentCategory[];
/**
*
* @deprecated
*/
bizComponentList?: ComponentCategory[];
/**
* tab category
*/
sort?: ComponentSort;
}
/**
* tab category
*/
export interface ComponentSort {
/**
* tab ["精选组件", "原子组件"]
*/
groupList?: string[];
/**
* tab category category categoryList
*/
categoryList?: string[];
}
/**
* external
*
*/
export interface Package {
/**
*
*/
package: string;
/**
*
*/
version: string;
/**
* CDN url js css
*/
urls?: string[] | any;
/**
* CDN url js css
*/
editUrls?: string[] | any;
/**
* webpack output.library字段含义一样
*/
library: string;
/**
* @deprecated
*
* @todo @度城
*/
async?: boolean;
/**
* window[exportName] Object
*/
exportName?: string;
}
export interface ComponentCategory { // 组件分类
title: string; // 组件分类title
icon?: string; // 组件分类icon
children?: ComponentItem[] | ComponentCategory[]; // 可能有子分类
/**
*
* @deprecated ComponentMetadata
*/
export interface ComponentCategory {
/**
* title
*/
title: string;
/**
* icon
*/
icon?: string;
/**
*
*/
children?: ComponentItem[] | ComponentCategory[];
}
export interface ComponentItem { // 组件
title: string; // 组件title
componentName?: string; // 组件名
icon?: string; // 组件icon
/**
*
* @deprecated ComponentMetadata
*/
export interface ComponentItem {
/**
* title
*/
title: string;
/**
*
*/
componentName?: string;
/**
* icon
*/
icon?: string;
/**
*
*/
snippets?: Snippet[];
/**
*
*/
group?: string | I18nData;
/**
*
*/
category?: string | I18nData;
/**
*
*/
priority?: number;
}
/**
*
*/
export interface ComponentDescription extends ComponentMetadata {
/**
* @todo @jinchan
*/
keywords: string[];
}
/**
*
*/
export interface RemoteComponentDescription {
exportName: string;
url: string;
/**
* window[exportName] Object
*/
exportName?: string;
/**
*
*/
url?: string;
/**
* () npm
*/
package?: {
npm?: string;
};
}

View File

@ -1,7 +1,11 @@
import { TitleContent } from './title';
import { SetterType, DynamicSetter } from './setter-config';
import { SettingTarget } from './setting-target';
import { LiveTextEditingConfig } from './metadata';
/**
* extra props for field
*/
export interface FieldExtraProps {
/**
*
@ -15,6 +19,9 @@ export interface FieldExtraProps {
* get value for field
*/
getValue?: (target: SettingTarget, fieldValue: any) => any;
/**
* set value for field
*/
setValue?: (target: SettingTarget, value: any) => void;
/**
* the field conditional show, is not set always true
@ -49,16 +56,20 @@ export interface FieldExtraProps {
* compatiable vision display
*/
display?: 'accordion' | 'inline' | 'block' | 'plain' | 'popup' | 'entry';
liveTextEditing?: {
selector: string;
// 编辑模式 纯文本|段落编辑|文章编辑(默认纯文本,无跟随工具条)
mode?: 'plaintext' | 'paragraph' | 'article';
// 从 contentEditable 获取内容并设置到属性
onSaveContent?: (content: string, prop: any) => any;
};
// @todo 这个 omit 是否合理?
/**
* @todo
*/
liveTextEditing?: Omit<LiveTextEditingConfig, 'propTarget'>;
}
/**
*
*/
export interface FieldConfig extends FieldExtraProps {
/**
* field
*/
type?: 'field' | 'group';
/**
* the name of this setting field, which used in quickEditor
@ -70,6 +81,8 @@ export interface FieldConfig extends FieldExtraProps {
*/
title?: TitleContent;
/**
* setter
*
* the field body contains when .type = 'field'
*/
setter?: SetterType | DynamicSetter;
@ -79,6 +92,15 @@ export interface FieldConfig extends FieldExtraProps {
items?: FieldConfig[];
/**
* extra props for field
*
*/
extraProps?: FieldExtraProps;
/**
* @deprecated
*/
description?: TitleContent;
/**
* @deprecated
*/
isExtends?: boolean;
}

View File

@ -9,39 +9,107 @@ import { NodeSchema, NodeData, ComponentSchema } from './schema';
import { SettingTarget } from './setting-target';
import { I18nData } from './i18n';
/**
*
*/
export type NestingFilter = (testNode: any, currentNode: any) => boolean;
/**
*
* a a, FormField Form Column Table
*/
export interface NestingRule {
// 子级白名单
/**
*
*/
childWhitelist?: string[] | string | RegExp | NestingFilter;
// 父级白名单
/**
*
*/
parentWhitelist?: string[] | string | RegExp | NestingFilter;
// 后裔白名单
/**
*
*/
descendantWhitelist?: string[] | string | RegExp | NestingFilter;
// 后裔黑名单
/**
*
*/
descendantBlacklist?: string[] | string | RegExp | NestingFilter;
// 祖先白名单 可用来做区域高亮
/**
*
*/
ancestorWhitelist?: string[] | string | RegExp | NestingFilter;
}
/**
*
*/
export interface ComponentConfigure {
/**
*
*/
isContainer?: boolean;
/**
*
*/
isModal?: boolean;
/**
*
*/
isNullNode?: boolean;
/**
*
*/
descriptor?: string;
/**
*
* a a, FormField Form Column Table
*/
nestingRule?: NestingRule;
/**
*
*
*/
isMinimalRenderUnit?: boolean;
/**
* cssSelector
*/
rootSelector?: string;
// copy, move, remove | *
/**
* `'copy'`, `'move'`, `'remove'`
*/
disableBehaviors?: string[] | string;
/**
*
*/
actions?: ComponentAction[];
}
/**
*
*
* schema () schema snippets schema
*/
export interface Snippet {
screenshot: string;
label: string;
schema: NodeSchema;
/**
* title
*/
title?: string;
/**
* snippet
*/
screenshot?: string;
/**
* snippet
*
* @deprecated 使
*/
label?: string;
/**
* schema
*/
schema?: NodeSchema;
}
export interface InitialItem {
@ -57,52 +125,110 @@ export interface AutorunItem {
autorun: (target: SettingTarget) => any;
}
/**
*
*/
export interface Experimental {
/**
* @todo
*/
context?: { [contextInfoName: string]: any };
/**
* @deprecated 使 metadata snippets
*/
snippets?: Snippet[];
/**
* @todo
*/
view?: ComponentType<any>;
transducers?: any; // ? should support
/**
* @todo
*/
transducers?: any;
/**
* @deprecated prop
*/
initials?: InitialItem[];
/**
* @todo
*/
filters?: FilterItem[];
/**
* @todo
*/
autoruns?: AutorunItem[];
/**
* callbacks onNodeAddonResize
*/
callbacks?: Callbacks;
/**
* children
*/
initialChildren?: NodeData[] | ((target: SettingTarget) => NodeData[]);
isAbsoluteLayoutContainer: boolean;
/**
* @todo
*/
isAbsoluteLayoutContainer?: boolean;
/**
* @todo
*/
hideSelectTools?: boolean;
// 样式 及 位置handle上必须有明确的标识以便事件路由判断或者主动设置事件独占模式
// NWSE 是交给引擎计算放置位置ReactElement 必须自己控制初始位置
/**
* handle上必须有明确的标识以便事件路由判断
* NWSE ReactElement
*/
/**
* resize
* - hover
* - mousedown
* - dragstart resizing hud
* - drag
*/
getResizingHandlers?: (
currentNode: any,
) =>
| Array<{
type: 'N' | 'W' | 'S' | 'E' | 'NW' | 'NE' | 'SE' | 'SW';
content?: ReactElement;
propTarget?: string;
appearOn?: 'mouse-enter' | 'mouse-hover' | 'selected' | 'always';
}>
| ReactElement[];
// hover时 控制柄高亮
// mousedown 时请求独占
// dragstart 请求 通用 resizing 控制
// 请求 hud 显示
// drag 时 计算 并 设置效果
// 更新控制柄位置
) => (
| Array<{
type: 'N' | 'W' | 'S' | 'E' | 'NW' | 'NE' | 'SE' | 'SW';
content?: ReactElement;
propTarget?: string;
appearOn?: 'mouse-enter' | 'mouse-hover' | 'selected' | 'always';
}>
| ReactElement[]
);
// 纯文本编辑:如果 children 内容是
// 文本编辑:配置
/**
* Live Text Editing children
*/
liveTextEditing?: LiveTextEditingConfig[];
/**
* @deprecated 使
*/
isTopFixed?: boolean;
}
// thinkof Array
/**
* Live Text Editing children
*/
export interface LiveTextEditingConfig {
/**
* @todo
*/
propTarget: string;
/**
* @todo
*/
selector?: string;
// 编辑模式 纯文本|段落编辑|文章编辑(默认纯文本,无跟随工具条)
/**
* ||
* @default 'plaintext'
*/
mode?: 'plaintext' | 'paragraph' | 'article';
// 从 contentEditable 获取内容并设置到属性
/**
* contentEditable
*/
onSaveContent?: (content: string, prop: any) => any;
}
@ -112,41 +238,97 @@ export type ConfigureSupportEvent = string | {
description?: string;
};
export type ConfigureSupport = {
/**
*
*/
export interface ConfigureSupport {
/**
*
*/
events?: ConfigureSupportEvent[];
/**
* className
*/
className?: boolean;
/**
*
*/
style?: boolean;
/**
*
*/
lifecycles?: any[];
// general?: boolean;
/**
*
*/
loop?: boolean;
/**
*
*/
condition?: boolean;
};
}
/**
*
*/
export interface Configure {
/**
*
*/
props?: FieldConfig[];
/**
*
*/
component?: ComponentConfigure;
/**
*
*/
supports?: ConfigureSupport;
}
/**
*
*/
export interface ActionContentObject {
// 图标
/**
*
*/
icon?: IconType;
// 描述
/**
*
*/
title?: TipContent;
// 执行动作
/**
*
*/
action?: (currentNode: any) => void;
}
/**
* @todo
*/
export interface ComponentAction {
// behaviorName
/**
* behaviorName
*/
name: string;
// 菜单名称
/**
*
*/
content: string | ReactNode | ActionContentObject;
// 子集
/**
*
*/
items?: ComponentAction[];
// 显示与否always: 无法禁用
/**
*
* always: 无法禁用
*/
condition?: boolean | ((currentNode: any) => boolean) | 'always';
// 显示在工具条上
/**
*
*/
important?: boolean;
}
@ -154,7 +336,13 @@ export function isActionContentObject(obj: any): obj is ActionContentObject {
return obj && typeof obj === 'object';
}
/**
* meta
*/
export interface ComponentMetadata {
/**
*
*/
componentName: string;
/**
* unique id
@ -168,29 +356,78 @@ export interface ComponentMetadata {
* svg icon for component
*/
icon?: IconType;
/**
*
*/
tags?: string[];
/**
*
*/
description?: string;
/**
*
*/
docUrl?: string;
/**
*
*/
screenshot?: string;
/**
*
*/
devMode?: 'procode' | 'lowcode';
/**
* npm
*/
npm?: NpmInfo;
/**
*
*/
props?: PropConfig[];
/**
*
*/
configure?: FieldConfig[] | Configure;
/**
*
*/
experimental?: Experimental;
/**
* @todo
*/
schema?: ComponentSchema;
/**
*
*/
snippets?: Snippet[];
/**
*
*/
group?: string | I18nData;
/**
*
*/
category?: string | I18nData;
/**
*
*/
priority?: number;
}
/**
* @todo
*/
export interface TransformedComponentMetadata extends ComponentMetadata {
configure: Configure & { combined?: FieldConfig[] };
}
// handleResizing
/**
* handleResizing
*/
// hooks & events
/**
* callbacks onNodeAddonResize
*/
export interface Callbacks {
// hooks
onMouseDownHook?: (e: MouseEvent, currentNode: any) => any;
@ -198,7 +435,8 @@ export interface Callbacks {
onClickHook?: (e: MouseEvent, currentNode: any) => any;
// onLocateHook?: (e: any, currentNode: any) => any;
// onAcceptHook?: (currentNode: any, locationData: any) => any;
onMoveHook?: (currentNode: any) => boolean; // thinkof 限制性拖拽
onMoveHook?: (currentNode: any) => boolean;
// thinkof 限制性拖拽
onHoverHook?: (currentNode: any) => boolean;
onChildMoveHook?: (childNode: any, currentNode: any) => boolean;
@ -230,4 +468,4 @@ export interface Callbacks {
},
currentNode: any,
) => void;
}
}

View File

@ -1,10 +1,34 @@
/**
* npm
*/
export interface NpmInfo {
/**
*
*/
componentName?: string;
/**
*
*/
package: string;
/**
*
*/
version?: string;
/**
*
*/
destructuring?: boolean;
/**
*
*/
exportName?: string;
/**
*
*/
subName?: string;
/**
*
*/
main?: string;
}

View File

@ -38,10 +38,28 @@ export interface Exact {
isRequired?: boolean;
}
/**
*
*/
export interface PropConfig {
/**
*
*/
name: string;
/**
*
*/
propType: PropType;
/**
*
*/
description?: string;
/**
*
*/
defaultValue?: any;
/**
* @deprecated
*/
setter?: any;
}

View File

@ -11,19 +11,47 @@ import { I18nMap } from './i18n';
import { UtilsMap } from './utils';
import { AppConfig } from './app-config';
// 搭建基础协议 - 单个组件树节点描述
// 转换成一个 .jsx 文件内 React Class 类 render 函数返回的 jsx 代码
/**
* -
*/
export interface NodeSchema {
id?: string;
componentName: string; // 组件名称 必填、首字母大写
props?: PropsMap | PropsList; // 组件属性对象
/**
*
*/
componentName: string;
/**
*
*/
props?: PropsMap | PropsList;
/**
*
*/
leadingComponents?: string;
condition?: CompositeValue; // 渲染条件
loop?: CompositeValue; // 循环数据
loopArgs?: [string, string]; // 循环迭代对象、索引名称 ["item", "index"]
children?: NodeData | NodeData[]; // 子节点
isLocked?: boolean; // 是否锁定
/**
*
*/
condition?: CompositeValue;
/**
*
*/
loop?: CompositeValue;
/**
* ["item", "index"]
*/
loopArgs?: [string, string];
/**
*
*/
children?: NodeData | NodeData[];
/**
*
*/
isLocked?: boolean;
// @todo
// ------- future support -----
conditionGroup?: string;
title?: string;
@ -49,22 +77,53 @@ export function isDOMText(data: any): data is DOMText {
export type DOMText = string;
/**
*
*/
export interface ContainerSchema extends NodeSchema {
componentName: string; // 'Block' | 'Page' | 'Component';
/**
* 'Block' | 'Page' | 'Component';
*/
componentName: string;
/**
*
*/
fileName: string;
/**
* @todo
*/
meta?: Record<string, unknown>;
/**
*
*/
state?: {
[key: string]: CompositeValue;
};
/**
*
*/
methods?: {
[key: string]: JSExpression | JSFunction;
};
/**
*
*/
lifeCycles?: {
[key: string]: JSExpression | JSFunction;
};
/**
*
*/
css?: string;
/**
*
*/
dataSource?: DataSource;
/**
*
*/
defaultProps?: CompositeObject;
// @todo propDefinitions
}
/**
@ -91,25 +150,66 @@ export interface BlockSchema extends ContainerSchema {
componentName: 'Block';
}
/**
* @todo
*/
export type RootSchema = PageSchema | ComponentSchema | BlockSchema;
/**
* Slot schema
*/
export interface SlotSchema extends NodeSchema {
componentName: 'Slot';
name?: string;
params?: string[];
}
/**
*
*/
export interface ProjectSchema {
version: string;
componentsMap: ComponentsMap;
componentsTree: RootSchema[];
i18n?: I18nMap;
utils?: UtilsMap;
constants?: JSONObject;
css?: string;
dataSource?: DataSource;
config?: AppConfig | Record<string, any>;
id?: string;
/**
*
*/
version: string;
/**
*
*/
componentsMap: ComponentsMap;
/**
*
*
* 1,
*/
componentsTree: RootSchema[];
/**
*
*/
i18n?: I18nMap;
/**
*
*/
utils?: UtilsMap;
/**
*
*/
constants?: JSONObject;
/**
*
*/
css?: string;
/**
*
*/
dataSource?: DataSource;
/**
*
*/
config?: AppConfig | Record<string, any>;
/**
*
*/
meta?: Record<string, any>;
}

View File

@ -1,6 +1,7 @@
import { ComponentClass, Component, ComponentType, ReactElement, isValidElement } from 'react';
import { TitleContent } from './title';
import { SettingTarget } from './setting-target';
import { CompositeValue } from './value-type';
function isReactClass(obj: any): obj is ComponentClass<any> {
return obj && obj.prototype && (obj.prototype.isReactComponent || obj.prototype instanceof Component);
@ -15,27 +16,56 @@ export type CustomView = ReactElement | ComponentType<any>;
export type DynamicProps = (target: SettingTarget) => Record<string, unknown>;
export type DynamicSetter = (target: SettingTarget) => string | SetterConfig | CustomView;
/**
*
*/
export interface SetterConfig {
// if *string* passed must be a registered Setter Name
/**
* if *string* passed must be a registered Setter Name
* setter
*/
componentName: string | CustomView;
/**
* setter
*
* the props pass to Setter Component
*/
props?: Record<string, unknown> | DynamicProps;
/**
* @deprecated
*/
children?: any;
/**
*
*
* ArraySetter
*/
isRequired?: boolean;
/**
* Setter
*
* @todo initialValue defaultValue
*/
initialValue?: any | ((target: SettingTarget) => any);
/* for MixedSetter */
// for MixedSetter
/**
* MixedSetter Setter
*/
title?: TitleContent;
// for MixedSetter check this is available
/**
* MixedSetter
*/
condition?: (target: SettingTarget) => boolean;
/**
* MixedSetter
*
* @todo
*/
valueType?: CompositeValue[];
}
/**
* if *string* passed must be a registered Setter Name, future support blockSchema
*/
// 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 {

View File

@ -31,31 +31,55 @@ export interface SettingTarget {
*/
readonly top: SettingTarget;
// 父级
/**
*
*/
readonly parent: SettingTarget;
// 获取当前值
getValue(): any;
/**
*
*/
getValue: () => any;
// 设置当前值
setValue(value: any): void;
/**
*
*/
setValue: (value: any) => void;
// 取得子项
get(propName: string | number): SettingTarget | null;
/**
*
*/
get: (propName: string | number) => SettingTarget | null;
// 获取子项属性值
getPropValue(propName: string | number): any;
/**
*
*/
getPropValue: (propName: string | number) => any;
// 设置子项属性值
setPropValue(propName: string | number, value: any): void;
/**
*
*/
setPropValue: (propName: string | number, value: any) => void;
// 清除已设置值
clearPropValue(propName: string | number): void;
/**
*
*/
clearPropValue: (propName: string | number) => void;
// 获取顶层附属属性值
getExtraPropValue(propName: string): any;
/**
*
*/
getExtraPropValue: (propName: string) => any;
// 设置顶层附属属性值
setExtraPropValue(propName: string, value: any): void;
/**
*
*/
setExtraPropValue: (propName: string, value: any) => void;
// @todo 补充 node 定义
/**
* node
*/
getNode: () => any;
}

View File

@ -3,11 +3,29 @@ import { I18nData, isI18nData } from './i18n';
import { TipContent } from './tip';
import { IconType } from './icon';
/**
* props setter title
*/
export interface TitleConfig {
/**
*
*/
label?: I18nData | ReactNode;
/**
* hover
*/
tip?: TipContent;
/**
*
*/
docUrl?: string;
/**
*
*/
icon?: IconType;
/**
* CSS
*/
className?: string;
}

View File

@ -1,6 +1,10 @@
import { NodeSchema, NodeData } from './schema';
// 表达式
/**
*
*
* this
*/
export interface JSExpression {
type: 'JSExpression';
/**
@ -9,69 +13,93 @@ export interface JSExpression {
value: string;
/**
*
*
* @todo
*/
mock?: any;
/** 源码 */
compiled?: string;
}
// 函数
export interface JSFunction {
type: 'JSFunction';
/**
*
*
*
* @todo
*/
value: string;
compiled?: string;
}
/**
*
* @see https://yuque.antfin-inc.com/mo/spec/spec-low-code-building-schema#feHTW
*
* ( React / ) binding this
*/
export interface JSFunction {
type: 'JSFunction';
/**
*
*/
value: string;
/** 源码 */
compiled?: string;
}
// 函数
export interface JSFunction {
type: 'JSFunction';
/**
*
*
*
* @todo
*/
value: string;
compiled?: string;
/**
*
*
* @todo
*/
mock?: any;
/**
* extTypeevents
*
* @todo
*/
[key: string]: any;
}
/**
* Slot
*
* ReactNode Function return ReactNode
*/
export interface JSSlot {
type: 'JSSlot';
/**
* @todo
*/
title?: string;
// 函数的入参
/**
* Function return ReactNode
*
* this[]
*/
params?: string[];
/**
*
*/
value?: NodeData[] | NodeData;
/**
* @todo
*/
name?: string;
}
/**
* @deprecated
*
* @todo
*/
export interface JSBlock {
type: 'JSBlock';
value: NodeSchema;
}
// JSON 基本类型
/**
* JSON
*/
export type JSONValue =
| boolean
| string
@ -85,7 +113,9 @@ export interface JSONObject {
[key: string]: JSONValue;
}
// 复合类型
/**
*
*/
export type CompositeValue =
| JSONValue
| JSExpression

View File

@ -1,67 +1,10 @@
import { Package, ComponentCategory, ComponentDescription, RemoteComponentDescription } from '@ali/lowcode-types';
import { AssetItem, AssetType, AssetLevels, Asset, AssetList, AssetBundle, AssetLevel, AssetsJson } from '@ali/lowcode-types';
import { isCSSUrl } from './is-css-url';
import { createDefer } from './create-defer';
import { load, evaluate } from './script';
export interface AssetItem {
type: AssetType;
content?: string | null;
device?: string;
level?: AssetLevel;
id?: string;
}
export enum AssetLevel {
// 环境依赖库 比如 react, react-dom
Environment = 1,
// 基础类库,比如 lodash deep fusion antd
Library = 2,
// 主题
Theme = 3,
// 运行时
Runtime = 4,
// 业务组件
Components = 5,
// 应用 & 页面
App = 6,
}
export const AssetLevels = [
AssetLevel.Environment,
AssetLevel.Library,
AssetLevel.Theme,
AssetLevel.Runtime,
AssetLevel.Components,
AssetLevel.App,
];
export type URL = string;
export enum AssetType {
JSUrl = 'jsUrl',
CSSUrl = 'cssUrl',
CSSText = 'cssText',
JSText = 'jsText',
Bundle = 'bundle',
}
export interface AssetBundle {
type: AssetType.Bundle;
level?: AssetLevel;
assets?: Asset | AssetList | null;
}
export type Asset = AssetList | AssetBundle | AssetItem | URL;
export type AssetList = Array<Asset | undefined | null>;
export interface AssetsJson {
version: string; // 资产包协议版本号
packages?: Package[]; // 大包列表external与package的概念相似融合在一起
components: Array<ComponentDescription | RemoteComponentDescription>; // 所有组件的描述协议列表所有组件的列表
componentList?: ComponentCategory[]; // 组件分类列表,用来描述物料面板
bizComponentList?: ComponentCategory[]; // 业务组件分类列表,用来描述物料面板
}
// API 向下兼容
export { AssetItem, AssetType, AssetLevels, Asset, AssetList, AssetBundle, AssetLevel, AssetsJson } from '@ali/lowcode-types';
export function isAssetItem(obj: any): obj is AssetItem {
return obj && obj.type;
@ -104,7 +47,7 @@ export function assetItem(type: AssetType, content?: string | null, level?: Asse
export function megreAssets(assets: AssetsJson, incrementalAssets: AssetsJson): AssetsJson {
if (incrementalAssets.packages) {
assets.packages = [...assets.packages, ...incrementalAssets.packages];
assets.packages = [...(assets.packages || []), ...incrementalAssets.packages];
}
if (incrementalAssets.components) {
@ -122,9 +65,9 @@ function megreAssetsComponentList(assets: AssetsJson, incrementalAssets: AssetsJ
if (incrementalAssets[listName]) {
if (assets[listName]) {
// 根据title进行合并
incrementalAssets[listName].map((item) => {
incrementalAssets[listName]?.map((item) => {
let matchFlag = false;
assets[listName].map((assetItem) => {
assets[listName]?.map((assetItem) => {
if (assetItem.title === item.title) {
assetItem.children = assetItem.children.concat(item.children);
matchFlag = true;
@ -133,7 +76,7 @@ function megreAssetsComponentList(assets: AssetsJson, incrementalAssets: AssetsJ
return assetItem;
});
!matchFlag && assets[listName].push(item);
!matchFlag && assets[listName]?.push(item);
return item;
});
}
@ -319,8 +262,10 @@ export class AssetLoader {
return isUrl ? load(content) : evaluate(content);
}
private async loadAsyncLibrary(asyncLibraryMap) {
const promiseList = []; const libraryKeyList = [];
// todo 补充类型
private async loadAsyncLibrary(asyncLibraryMap: Record<string, any>) {
const promiseList: any[] = [];
const libraryKeyList: any[] = [];
for (const key in asyncLibraryMap) {
// 需要异步加载
if (asyncLibraryMap[key].async) {