diff --git a/modules/code-generator/src/cli/solutions/example-solution.ts b/modules/code-generator/src/cli/solutions/example-solution.ts index 2efff780c..fe303f360 100644 --- a/modules/code-generator/src/cli/solutions/example-solution.ts +++ b/modules/code-generator/src/cli/solutions/example-solution.ts @@ -559,8 +559,8 @@ codealike.json "registry": "https://registry.npm.xxx.com" }, "dependencies": { - "@alilc/lowcode-code-generator": "^1.0.0-beta.16", - "@alilc/lowcode-types": "^1.0.0-beta.21", + "@alilc/lowcode-code-generator": "^1.0.0", + "@alilc/lowcode-types": "^1.0.0", "tslib": "^2.3.0" }, "devDependencies": { diff --git a/modules/code-generator/src/generator/ProjectBuilder.ts b/modules/code-generator/src/generator/ProjectBuilder.ts index 2a1282d6e..186def2c5 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 2e526d88b..ab4636561 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 afdcc6225..d4e61e3c0 100644 --- a/modules/code-generator/src/postprocessor/prettier/index.ts +++ b/modules/code-generator/src/postprocessor/prettier/index.ts @@ -9,7 +9,7 @@ const PARSERS = ['css', 'scss', 'less', 'json', 'html', 'vue']; export interface ProcessorConfig { customFileTypeParser: Record; - plugins?: Array; + plugins?: prettier.Plugin[]; } const factory: PostProcessorFactory = (config?: ProcessorConfig) => { @@ -33,6 +33,8 @@ const factory: PostProcessorFactory = (config?: ProcessorConfig return prettier.format(content, { parser, plugins: [parserBabel, parserPostCss, parserHtml, ...(cfg.plugins || [])], + singleQuote: true, + jsxSingleQuote: false, }); }; diff --git a/modules/code-generator/src/types/core.ts b/modules/code-generator/src/types/core.ts index 99ca8c97a..b1a00ad37 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 610f39934..cd1035162 100644 --- a/modules/code-generator/src/utils/dataSource.ts +++ b/modules/code-generator/src/utils/dataSource.ts @@ -1,7 +1,7 @@ import changeCase from 'change-case'; import type { IProjectInfo } from '../types/intermediate'; -export type DataSourceDependenciesConfig = { +export interface DataSourceDependenciesConfig { /** 数据源引擎的版本 */ engineVersion?: string; /** 数据源引擎的包名 */ @@ -14,7 +14,7 @@ export type DataSourceDependenciesConfig = { handlersPackages?: { [key: string]: string; }; -}; +} export function buildDataSourceDependencies( ir: IProjectInfo, @@ -22,13 +22,13 @@ export function buildDataSourceDependencies( ): Record { return { // 数据源引擎的依赖包 - [cfg.enginePackage || '@alilc/lowcode-datasource-engine']: cfg.engineVersion || 'latest', + [cfg.enginePackage || '@alilc/lowcode-datasource-engine']: cfg.engineVersion || '^1.0.0', // 各种数据源的 handlers 的依赖包 ...(ir.dataSourcesTypes || []).reduce( (acc, dsType) => ({ ...acc, - [getDataSourceHandlerPackageName(dsType)]: cfg.handlersVersion?.[dsType] || 'latest', + [getDataSourceHandlerPackageName(dsType)]: cfg.handlersVersion?.[dsType] || '^1.0.0', }), {}, ), diff --git a/modules/code-generator/src/utils/index.ts b/modules/code-generator/src/utils/index.ts index ff5194172..cac63d415 100644 --- a/modules/code-generator/src/utils/index.ts +++ b/modules/code-generator/src/utils/index.ts @@ -11,6 +11,7 @@ import * as schema from './schema'; import * as version from './version'; import * as scope from './Scope'; import * as expressionParser from './expressionParser'; +import * as dataSource from './dataSource'; export { common, @@ -25,4 +26,5 @@ export { version, scope, expressionParser, + dataSource, }; diff --git a/modules/code-generator/src/utils/nodeToJSX.ts b/modules/code-generator/src/utils/nodeToJSX.ts index 0b5919902..e928b866b 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 b2faecbc6..9a4f131d4 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