feat: support UIPaaS-Component code generator solution

This commit is contained in:
LeoYuan 袁力皓 2022-12-13 11:36:44 +08:00 committed by eternalsky
parent 82b6a01533
commit 1ca940c880
9 changed files with 37 additions and 19 deletions

View File

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

View File

@ -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;

View File

@ -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 => ({

View File

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

View File

@ -170,11 +170,17 @@ export interface IProjectBuilder {
/** 项目级别的前置处理器 */
export type ProjectPreProcessor = (schema: ProjectSchema) => Promise<ProjectSchema> | ProjectSchema;
export interface ProjectPostProcessorOptions {
parseResult?: IParseResult;
template?: IProjectTemplate;
}
/** 项目级别的后置处理器 */
export type ProjectPostProcessor = (
result: ResultDir,
schema: ProjectSchema,
originalSchema: ProjectSchema | string,
options: ProjectPostProcessorOptions,
) => Promise<ResultDir> | ResultDir;
/** 模块级别的后置处理器的工厂方法 */

View File

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

View File

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

View File

@ -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 = {

View File

@ -138,3 +138,11 @@ export function handleSubNodes<T>(
return [];
}
}
export function isValidContainerType(schema: NodeSchema) {
return [
'Page',
'Component',
'Block',
].includes(schema.componentName);
}