forked from alibaba/lowcode-engine
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcore.ts
More file actions
235 lines (198 loc) · 6.36 KB
/
core.ts
File metadata and controls
235 lines (198 loc) · 6.36 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
import {
JSONArray,
JSONObject,
CompositeArray,
CompositeObject,
ResultDir,
ResultFile,
NodeDataType,
ProjectSchema,
JSExpression,
JSFunction,
JSSlot,
} from '@alilc/lowcode-types';
import { IParseResult } from './intermediate';
import { IScopeBindings } from '../utils/ScopeBindings';
export enum FileType {
CSS = 'css',
SCSS = 'scss',
LESS = 'less',
HTML = 'html',
JS = 'js',
JSX = 'jsx',
TS = 'ts',
TSX = 'tsx',
JSON = 'json',
}
export enum ChunkType {
AST = 'ast',
STRING = 'string',
JSON = 'json',
}
export enum PluginType {
COMPONENT = 'component',
UTILS = 'utils',
I18N = 'i18n',
}
export type ChunkContent = string | any;
export type CodeGeneratorFunction<T> = (content: T) => string;
export interface ICodeChunk {
type: ChunkType;
fileType: string;
name: string;
subModule?: string;
content: ChunkContent;
linkAfter: string[];
ext?: Record<string, unknown>;
}
export interface IBaseCodeStruct {
chunks: ICodeChunk[];
depNames: string[];
}
export interface ICodeStruct extends IBaseCodeStruct {
ir: any;
contextData: IContextData;
}
/** 上下文数据,用来在插件之间共享一些数据 */
export interface IContextData extends IProjectBuilderOptions {
/** 是否使用了 Ref 的 API (this.$/this.$$) */
useRefApi?: boolean;
/**
* 其他自定义数据
* (三方自定义插件也可以在此放一些数据,建议起个长一点的名称,用自己的插件名做前缀,以防冲突)
*/
[key: string]: any;
}
export type BuilderComponentPlugin = (initStruct: ICodeStruct) => Promise<ICodeStruct>;
export type BuilderComponentPluginFactory<T> = (config?: T) => BuilderComponentPlugin;
export interface IChunkBuilder {
run: (ir: any, initialStructure?: ICodeStruct) => Promise<{ chunks: ICodeChunk[][] }>;
getPlugins: () => BuilderComponentPlugin[];
addPlugin: (plugin: BuilderComponentPlugin) => void;
}
export interface ICodeBuilder {
link: (chunkDefinitions: ICodeChunk[]) => string;
generateByType: (type: string, content: unknown) => string;
}
export interface ICompiledModule {
files: ResultFile[];
}
export interface IModuleBuilder {
generateModule: (input: unknown) => Promise<ICompiledModule>;
generateModuleCode: (schema: ProjectSchema | string) => Promise<ResultDir>;
linkCodeChunks: (chunks: Record<string, ICodeChunk[]>, fileName: string) => ResultFile[];
addPlugin: (plugin: BuilderComponentPlugin) => void;
}
/**
* 引擎对外接口
*
* @export
* @interface ICodeGenerator
*/
export interface ICodeGenerator {
/**
* 出码接口,把 Schema 转换成代码文件系统描述
*
* @param {(ProjectSchema)} schema 传入的 Schema
* @returns {ResultDir}
* @memberof ICodeGenerator
*/
toCode: (schema: ProjectSchema) => Promise<ResultDir>;
}
export interface ISchemaParser {
validate: (schema: ProjectSchema) => boolean;
parse: (schema: ProjectSchema | string) => IParseResult;
}
export interface IProjectTemplate {
slots: Record<string, IProjectSlot>;
generateTemplate: () => ResultDir | Promise<ResultDir>;
}
export interface IProjectSlot {
path: string[];
fileName?: string;
}
export interface IProjectPlugins {
[slotName: string]: BuilderComponentPlugin[];
}
export interface IProjectBuilderOptions {
/** 是否处于严格模式(默认: 否) */
inStrictMode?: boolean;
/**
* 是否要容忍对 JSExpression 求值时的异常
* 默认:true
* 注: 如果容忍异常,则会在求值时包裹 try-catch 块,
* catch 到异常时默认会抛出一个 CustomEvent 事件里面包含异常信息和求值的表达式
*/
tolerateEvalErrors?: boolean;
/**
* 容忍异常的时候的的错误处理语句块
* 默认: 无
* 您可以设置为一个语句块,比如:
* window.dispatchEvent(new CustomEvent('lowcode-eval-error', { error, expr }))
*
* 一般可以结合埋点监控模块用来监控求值异常
*
* 其中:
* - error: 异常信息
* - expr: 求值的表达式
*/
evalErrorsHandler?: string;
}
export interface IProjectBuilder {
generateProject: (schema: ProjectSchema | string) => Promise<ResultDir>;
}
/** 项目级别的前置处理器 */
export type ProjectPreProcessor = (schema: ProjectSchema) => Promise<ProjectSchema> | ProjectSchema;
/** 项目级别的后置处理器 */
export type ProjectPostProcessor = (
result: ResultDir,
schema: ProjectSchema,
originalSchema: ProjectSchema | string,
) => Promise<ResultDir> | ResultDir;
/** 模块级别的后置处理器的工厂方法 */
export type PostProcessorFactory<T> = (config?: T) => PostProcessor;
/** 模块级别的后置处理器 */
export type PostProcessor = (content: string, fileType: string) => string;
// TODO: temp interface, need modify
export interface IPluginOptions {
fileDirDepth: number;
}
export type BaseGenerator<I, T, C> = (
input: I,
scope: IScope,
config?: C,
next?: BaseGenerator<I, T, C>,
) => T;
type CompositeTypeGenerator<I, T> =
| BaseGenerator<I, T, CompositeValueGeneratorOptions>
| Array<BaseGenerator<I, T, CompositeValueGeneratorOptions>>;
export type NodeGenerator<T> = (nodeItem: NodeDataType, scope: IScope) => T;
// FIXME: 在新的实现中,添加了第一参数 this: CustomHandlerSet 作为上下文。究其本质
// scopeBindings?: IScopeBindings;
// 这个组合只用来用来处理 CompositeValue 类型,不是这个类型的不要放在这里
export interface HandlerSet<T> {
string?: CompositeTypeGenerator<string, T>;
boolean?: CompositeTypeGenerator<boolean, T>;
number?: CompositeTypeGenerator<number, T>;
expression?: CompositeTypeGenerator<JSExpression, T>;
function?: CompositeTypeGenerator<JSFunction, T>;
slot?: CompositeTypeGenerator<JSSlot, T>;
array?: CompositeTypeGenerator<JSONArray | CompositeArray, T>;
object?: CompositeTypeGenerator<JSONObject | CompositeObject, T>;
}
export interface CompositeValueGeneratorOptions {
handlers?: HandlerSet<string>;
nodeGenerator?: NodeGenerator<string>;
tolerateEvalErrors?: boolean;
}
/**
* 作用域定义,维护作用域内定义,支持作用域链上溯
*/
export interface IScope {
// 父级作用域(如果是根作用域则为 null)
readonly parent: IScope | null;
// 作用域内定义的变量/函数等 bindings
readonly bindings?: IScopeBindings;
// TODO: 需要有上下文信息吗? 描述什么内容
createSubScope: (ownIndentifiers: string[]) => IScope;
}