mirror of
https://github.com/alibaba/lowcode-engine.git
synced 2026-04-20 04:18:05 +00:00
fix: 🐛 use lowcode types
This commit is contained in:
parent
8647ade39d
commit
b11425b9e2
13473
packages/code-generator/demo/assets.json
Normal file
13473
packages/code-generator/demo/assets.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -4,20 +4,20 @@ const CodeGenerator = require('../lib').default;
|
|||||||
|
|
||||||
function flatFiles(rootName, dir) {
|
function flatFiles(rootName, dir) {
|
||||||
const dirRoot = rootName ? `${rootName}/${dir.name}` : dir.name;
|
const dirRoot = rootName ? `${rootName}/${dir.name}` : dir.name;
|
||||||
const files = dir.files.map(file => ({
|
const files = dir.files.map((file) => ({
|
||||||
name: `${dirRoot}/${file.name}.${file.ext}`,
|
name: `${dirRoot}/${file.name}.${file.ext}`,
|
||||||
content: file.content,
|
content: file.content,
|
||||||
ext: '',
|
ext: '',
|
||||||
}));
|
}));
|
||||||
const filesInSub = dir.dirs.map(subDir => flatFiles(`${dirRoot}`, subDir));
|
const filesInSub = dir.dirs.map((subDir) => flatFiles(`${dirRoot}`, subDir));
|
||||||
const result = files.concat.apply(files, filesInSub);
|
const result = files.concat(...filesInSub);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
function displayResultInConsole(root, fileName) {
|
function displayResultInConsole(root, fileName) {
|
||||||
const files = flatFiles('.', root);
|
const files = flatFiles('.', root);
|
||||||
files.forEach(file => {
|
files.forEach((file) => {
|
||||||
if (!fileName || fileName === file.name) {
|
if (!fileName || fileName === file.name) {
|
||||||
console.log(`========== ${file.name} Start ==========`);
|
console.log(`========== ${file.name} Start ==========`);
|
||||||
console.log(file.content);
|
console.log(file.content);
|
||||||
@ -37,20 +37,62 @@ async function writeResultToDisk(root, path) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getComponentsMap() {
|
||||||
|
const assetJson = fs.readFileSync('./demo/assets.json', { encoding: 'utf8' });
|
||||||
|
const assets = JSON.parse(assetJson);
|
||||||
|
const { components } = assets;
|
||||||
|
|
||||||
|
const componentsMap = components
|
||||||
|
.filter((c) => !!c.npm)
|
||||||
|
.map((c) => ({
|
||||||
|
componentName: c.componentName,
|
||||||
|
...(c.npm || {}),
|
||||||
|
}));
|
||||||
|
|
||||||
|
return componentsMap;
|
||||||
|
}
|
||||||
|
|
||||||
function main() {
|
function main() {
|
||||||
const schemaJson = fs.readFileSync('./demo/sampleSchema.json', { encoding: 'utf8' });
|
const schemaJson = fs.readFileSync('./demo/sampleSchema.json', { encoding: 'utf8' });
|
||||||
const createIceJsProjectBuilder = CodeGenerator.solutions.icejs;
|
const createIceJsProjectBuilder = CodeGenerator.solutions.icejs;
|
||||||
const builder = createIceJsProjectBuilder();
|
const builder = createIceJsProjectBuilder();
|
||||||
|
|
||||||
builder.generateProject(schemaJson).then(result => {
|
builder.generateProject(schemaJson).then((result) => {
|
||||||
displayResultInConsole(result);
|
displayResultInConsole(result);
|
||||||
writeResultToDisk(result, 'output/lowcodeDemo').then(response =>
|
writeResultToDisk(result, 'output/lowcodeDemo').then((response) =>
|
||||||
console.log('Write to disk: ', JSON.stringify(response)),
|
console.log('Write to disk: ', JSON.stringify(response)),
|
||||||
);
|
);
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function demo() {
|
||||||
|
const schemaJson = fs.readFileSync('./demo/schema.json', { encoding: 'utf8' });
|
||||||
|
const createIceJsProjectBuilder = CodeGenerator.solutions.icejs;
|
||||||
|
const builder = createIceJsProjectBuilder();
|
||||||
|
|
||||||
|
const componentsMap = getComponentsMap();
|
||||||
|
const root = JSON.parse(schemaJson);
|
||||||
|
|
||||||
|
const fullSchema = {
|
||||||
|
version: '1.0.0',
|
||||||
|
config: {
|
||||||
|
historyMode: 'hash',
|
||||||
|
targetRootID: 'J_Container',
|
||||||
|
},
|
||||||
|
meta: {
|
||||||
|
name: 'demoproject',
|
||||||
|
},
|
||||||
|
componentsTree: [root],
|
||||||
|
componentsMap,
|
||||||
|
};
|
||||||
|
|
||||||
|
builder.generateProject(fullSchema).then((result) => {
|
||||||
|
displayResultInConsole(result);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
function exportModule() {
|
function exportModule() {
|
||||||
const schemaJson = fs.readFileSync('./demo/shenmaSample.json', { encoding: 'utf8' });
|
const schemaJson = fs.readFileSync('./demo/shenmaSample.json', { encoding: 'utf8' });
|
||||||
const moduleBuilder = CodeGenerator.createModuleBuilder({
|
const moduleBuilder = CodeGenerator.createModuleBuilder({
|
||||||
@ -66,13 +108,11 @@ function exportModule() {
|
|||||||
CodeGenerator.plugins.react.jsx(),
|
CodeGenerator.plugins.react.jsx(),
|
||||||
CodeGenerator.plugins.style.css(),
|
CodeGenerator.plugins.style.css(),
|
||||||
],
|
],
|
||||||
postProcessors: [
|
postProcessors: [CodeGenerator.postprocessor.prettier()],
|
||||||
CodeGenerator.postprocessor.prettier(),
|
|
||||||
],
|
|
||||||
mainFileName: 'index',
|
mainFileName: 'index',
|
||||||
});
|
});
|
||||||
|
|
||||||
moduleBuilder.generateModuleCode(schemaJson).then(result => {
|
moduleBuilder.generateModuleCode(schemaJson).then((result) => {
|
||||||
displayResultInConsole(result);
|
displayResultInConsole(result);
|
||||||
return result;
|
return result;
|
||||||
});
|
});
|
||||||
@ -81,7 +121,7 @@ function exportModule() {
|
|||||||
function exportProject() {
|
function exportProject() {
|
||||||
const schemaJson = fs.readFileSync('./demo/sampleSchema.json', { encoding: 'utf8' });
|
const schemaJson = fs.readFileSync('./demo/sampleSchema.json', { encoding: 'utf8' });
|
||||||
|
|
||||||
const builder = CodeGenerator.createProjectBuilder({
|
const builder = CodeGenerator.createProjectBuilder({
|
||||||
template: CodeGenerator.solutionParts.icejs.template,
|
template: CodeGenerator.solutionParts.icejs.template,
|
||||||
plugins: {
|
plugins: {
|
||||||
components: [
|
components: [
|
||||||
@ -108,41 +148,21 @@ function exportProject() {
|
|||||||
CodeGenerator.plugins.react.jsx(),
|
CodeGenerator.plugins.react.jsx(),
|
||||||
CodeGenerator.plugins.style.css(),
|
CodeGenerator.plugins.style.css(),
|
||||||
],
|
],
|
||||||
router: [
|
router: [CodeGenerator.plugins.common.esmodule(), CodeGenerator.solutionParts.icejs.plugins.router()],
|
||||||
CodeGenerator.plugins.common.esmodule(),
|
entry: [CodeGenerator.solutionParts.icejs.plugins.entry()],
|
||||||
CodeGenerator.solutionParts.icejs.plugins.router(),
|
constants: [CodeGenerator.plugins.project.constants()],
|
||||||
],
|
utils: [CodeGenerator.plugins.common.esmodule(), CodeGenerator.plugins.project.utils()],
|
||||||
entry: [
|
i18n: [CodeGenerator.plugins.project.i18n()],
|
||||||
CodeGenerator.solutionParts.icejs.plugins.entry(),
|
globalStyle: [CodeGenerator.solutionParts.icejs.plugins.globalStyle()],
|
||||||
],
|
htmlEntry: [CodeGenerator.solutionParts.icejs.plugins.entryHtml()],
|
||||||
constants: [
|
packageJSON: [CodeGenerator.solutionParts.icejs.plugins.packageJSON()],
|
||||||
CodeGenerator.plugins.project.constants(),
|
|
||||||
],
|
|
||||||
utils: [
|
|
||||||
CodeGenerator.plugins.common.esmodule(),
|
|
||||||
CodeGenerator.plugins.project.utils(),
|
|
||||||
],
|
|
||||||
i18n: [
|
|
||||||
CodeGenerator.plugins.project.i18n(),
|
|
||||||
],
|
|
||||||
globalStyle: [
|
|
||||||
CodeGenerator.solutionParts.icejs.plugins.globalStyle(),
|
|
||||||
],
|
|
||||||
htmlEntry: [
|
|
||||||
CodeGenerator.solutionParts.icejs.plugins.entryHtml(),
|
|
||||||
],
|
|
||||||
packageJSON: [
|
|
||||||
CodeGenerator.solutionParts.icejs.plugins.packageJSON(),
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
postProcessors: [
|
postProcessors: [CodeGenerator.postprocessor.prettier()],
|
||||||
CodeGenerator.postprocessor.prettier(),
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
builder.generateProject(schemaJson).then(result => {
|
builder.generateProject(schemaJson).then((result) => {
|
||||||
displayResultInConsole(result);
|
displayResultInConsole(result);
|
||||||
writeResultToDisk(result, 'output/lowcodeDemo').then(response =>
|
writeResultToDisk(result, 'output/lowcodeDemo').then((response) =>
|
||||||
console.log('Write to disk: ', JSON.stringify(response)),
|
console.log('Write to disk: ', JSON.stringify(response)),
|
||||||
);
|
);
|
||||||
return result;
|
return result;
|
||||||
@ -151,4 +171,5 @@ function exportProject() {
|
|||||||
|
|
||||||
// main();
|
// main();
|
||||||
// exportModule();
|
// exportModule();
|
||||||
exportProject();
|
// exportProject();
|
||||||
|
demo();
|
||||||
|
|||||||
420
packages/code-generator/demo/schema.json
Normal file
420
packages/code-generator/demo/schema.json
Normal file
@ -0,0 +1,420 @@
|
|||||||
|
{
|
||||||
|
"componentName": "Page",
|
||||||
|
"id": "node_dockcviv8fo1",
|
||||||
|
"props": {
|
||||||
|
"ref": "outterView",
|
||||||
|
"autoLoading": true,
|
||||||
|
"style": {
|
||||||
|
"padding": "0 5px 0 5px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"fileName": "test",
|
||||||
|
"dataSource": {
|
||||||
|
"list": []
|
||||||
|
},
|
||||||
|
"state": {
|
||||||
|
"text": "outter",
|
||||||
|
"isShowDialog": false
|
||||||
|
},
|
||||||
|
"css": "body {font-size: 12px;} .botton{width:100px;color:#ff00ff}",
|
||||||
|
"lifeCycles": {
|
||||||
|
"componentDidMount": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "function() {\n console.log('did mount');\n }"
|
||||||
|
},
|
||||||
|
"componentWillUnmount": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "function() {\n console.log('will umount');\n }"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"methods": {
|
||||||
|
"testFunc": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "function() {\n console.log('test func');\n }"
|
||||||
|
},
|
||||||
|
"onClick": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "function(){\n this.setState({\n isShowDialog:true\n })\n\t}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": [{
|
||||||
|
"componentName": "Box",
|
||||||
|
"id": "node_dockcy8n9xed",
|
||||||
|
"props": {
|
||||||
|
"style": {
|
||||||
|
"backgroundColor": "rgba(31,56,88,0.1)",
|
||||||
|
"padding": "12px 12px 12px 12px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": [{
|
||||||
|
"componentName": "Box",
|
||||||
|
"id": "node_dockcy8n9xee",
|
||||||
|
"props": {
|
||||||
|
"style": {
|
||||||
|
"padding": "12px 12px 12px 12px",
|
||||||
|
"backgroundColor": "#ffffff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": [{
|
||||||
|
"componentName": "Breadcrumb",
|
||||||
|
"id": "node_dockcy8n9xef",
|
||||||
|
"props": {
|
||||||
|
"prefix": "next-",
|
||||||
|
"maxNode": 100,
|
||||||
|
"component": "nav"
|
||||||
|
},
|
||||||
|
"children": [{
|
||||||
|
"componentName": "Breadcrumb.Item",
|
||||||
|
"id": "node_dockcy8n9xeg",
|
||||||
|
"props": {
|
||||||
|
"prefix": "next-"
|
||||||
|
},
|
||||||
|
"children": ["首页"]
|
||||||
|
}, {
|
||||||
|
"componentName": "Breadcrumb.Item",
|
||||||
|
"id": "node_dockcy8n9xei",
|
||||||
|
"props": {
|
||||||
|
"prefix": "next-"
|
||||||
|
},
|
||||||
|
"children": ["品质中台"]
|
||||||
|
}, {
|
||||||
|
"componentName": "Breadcrumb.Item",
|
||||||
|
"id": "node_dockcy8n9xek",
|
||||||
|
"props": {
|
||||||
|
"prefix": "next-"
|
||||||
|
},
|
||||||
|
"children": ["商家品质页面管理"]
|
||||||
|
}, {
|
||||||
|
"componentName": "Breadcrumb.Item",
|
||||||
|
"id": "node_dockcy8n9xem",
|
||||||
|
"props": {
|
||||||
|
"prefix": "next-"
|
||||||
|
},
|
||||||
|
"children": ["质检知识条配置"]
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"componentName": "Box",
|
||||||
|
"id": "node_dockcy8n9xeo",
|
||||||
|
"props": {
|
||||||
|
"style": {
|
||||||
|
"marginTop": "12px",
|
||||||
|
"backgroundColor": "#ffffff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": [{
|
||||||
|
"componentName": "Form",
|
||||||
|
"id": "node_dockcy8n9xep",
|
||||||
|
"props": {
|
||||||
|
"inline": true,
|
||||||
|
"style": {
|
||||||
|
"marginTop": "12px",
|
||||||
|
"marginRight": "12px",
|
||||||
|
"marginLeft": "12px"
|
||||||
|
},
|
||||||
|
"__events": []
|
||||||
|
},
|
||||||
|
"children": [{
|
||||||
|
"componentName": "Form.Item",
|
||||||
|
"id": "node_dockcy8n9xeq",
|
||||||
|
"props": {
|
||||||
|
"style": {
|
||||||
|
"marginBottom": "0"
|
||||||
|
},
|
||||||
|
"label": "类目名:"
|
||||||
|
},
|
||||||
|
"children": [{
|
||||||
|
"componentName": "Select",
|
||||||
|
"id": "node_dockcy8n9xer",
|
||||||
|
"props": {
|
||||||
|
"mode": "single",
|
||||||
|
"hasArrow": true,
|
||||||
|
"cacheValue": true,
|
||||||
|
"style": {
|
||||||
|
"width": "150px"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"componentName": "Form.Item",
|
||||||
|
"id": "node_dockcy8n9xes",
|
||||||
|
"props": {
|
||||||
|
"style": {
|
||||||
|
"marginBottom": "0"
|
||||||
|
},
|
||||||
|
"label": "项目类型:"
|
||||||
|
},
|
||||||
|
"children": [{
|
||||||
|
"componentName": "Select",
|
||||||
|
"id": "node_dockcy8n9xet",
|
||||||
|
"props": {
|
||||||
|
"mode": "single",
|
||||||
|
"hasArrow": true,
|
||||||
|
"cacheValue": true,
|
||||||
|
"style": {
|
||||||
|
"width": "200px"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"componentName": "Form.Item",
|
||||||
|
"id": "node_dockcy8n9xeu",
|
||||||
|
"props": {
|
||||||
|
"style": {
|
||||||
|
"marginBottom": "0"
|
||||||
|
},
|
||||||
|
"label": "项目 ID:"
|
||||||
|
},
|
||||||
|
"children": [{
|
||||||
|
"componentName": "Input",
|
||||||
|
"id": "node_dockcy8n9xev",
|
||||||
|
"props": {
|
||||||
|
"hasBorder": true,
|
||||||
|
"size": "medium",
|
||||||
|
"autoComplete": "off",
|
||||||
|
"style": {
|
||||||
|
"width": "200px"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"componentName": "Button.Group",
|
||||||
|
"id": "node_dockcy8n9xew",
|
||||||
|
"props": {},
|
||||||
|
"children": [{
|
||||||
|
"componentName": "Button",
|
||||||
|
"id": "node_dockcy8n9xex",
|
||||||
|
"props": {
|
||||||
|
"type": "primary",
|
||||||
|
"style": {
|
||||||
|
"margin": "0 5px 0 5px"
|
||||||
|
},
|
||||||
|
"htmlType": "submit"
|
||||||
|
},
|
||||||
|
"children": [{
|
||||||
|
"componentName": "Icon",
|
||||||
|
"id": "node_dockcy8n9xey",
|
||||||
|
"props": {
|
||||||
|
"type": "success"
|
||||||
|
}
|
||||||
|
}, "搜索"]
|
||||||
|
}, {
|
||||||
|
"componentName": "Button",
|
||||||
|
"id": "node_dockcy8n9xe10",
|
||||||
|
"props": {
|
||||||
|
"type": "normal",
|
||||||
|
"style": {
|
||||||
|
"margin": "0 5px 0 5px"
|
||||||
|
},
|
||||||
|
"htmlType": "reset"
|
||||||
|
},
|
||||||
|
"children": ["清空"]
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"componentName": "Box",
|
||||||
|
"id": "node_dockcy8n9xe12",
|
||||||
|
"props": {
|
||||||
|
"style": {
|
||||||
|
"justifyContent": "flex-end",
|
||||||
|
"display": "flex",
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"flexDirection": "row",
|
||||||
|
"paddingRight": "24px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": [{
|
||||||
|
"componentName": "Button",
|
||||||
|
"id": "node_dockcy8n9xe13",
|
||||||
|
"props": {
|
||||||
|
"prefix": "next-",
|
||||||
|
"type": "primary",
|
||||||
|
"size": "medium",
|
||||||
|
"htmlType": "button",
|
||||||
|
"component": "button",
|
||||||
|
"style": {
|
||||||
|
"width": "100px"
|
||||||
|
},
|
||||||
|
"events": {
|
||||||
|
"onClick": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "function(){ this.onClick() }",
|
||||||
|
"__eventData": {
|
||||||
|
"type": "componentEvent",
|
||||||
|
"name": "onClick",
|
||||||
|
"relatedEventName": "onClick"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"__events": [{
|
||||||
|
"type": "componentEvent",
|
||||||
|
"name": "onClick",
|
||||||
|
"relatedEventName": "onClick"
|
||||||
|
}],
|
||||||
|
"onClick": {
|
||||||
|
"type": "JSFunction",
|
||||||
|
"value": "function(){ this.onClick() }"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": ["新建配置"]
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"componentName": "Box",
|
||||||
|
"id": "node_dockcy8n9xe15",
|
||||||
|
"props": {
|
||||||
|
"style": {
|
||||||
|
"backgroundColor": "#ffffff"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": [{
|
||||||
|
"componentName": "Table",
|
||||||
|
"id": "node_dockcy8n9xe16",
|
||||||
|
"props": {
|
||||||
|
"dataSource": [{
|
||||||
|
"firstCategory": "其他",
|
||||||
|
"secondCategory": "新品预览",
|
||||||
|
"leafCategory": "",
|
||||||
|
"projectType": "标识判断",
|
||||||
|
"projectId": "",
|
||||||
|
"title": "其他类目->新品预览类目类型知识库",
|
||||||
|
"url": "其他",
|
||||||
|
"operation": "编辑"
|
||||||
|
}, {
|
||||||
|
"firstCategory": "其他",
|
||||||
|
"secondCategory": "新品预览",
|
||||||
|
"leafCategory": "",
|
||||||
|
"projectType": "",
|
||||||
|
"projectId": "1",
|
||||||
|
"title": "其他类目->新品预览项目Id知识库",
|
||||||
|
"url": "其他",
|
||||||
|
"operation": "编辑"
|
||||||
|
}],
|
||||||
|
"size": "medium",
|
||||||
|
"prefix": "next-",
|
||||||
|
"hasBorder": true,
|
||||||
|
"hasHeader": true,
|
||||||
|
"isZebra": false,
|
||||||
|
"loading": false,
|
||||||
|
"expandedIndexSimulate": false,
|
||||||
|
"primaryKey": "id",
|
||||||
|
"locale": "zhCN.Table",
|
||||||
|
"crossline": false,
|
||||||
|
"style": {
|
||||||
|
"margin": "24px 12px 24px 12px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": [{
|
||||||
|
"componentName": "Table.Column",
|
||||||
|
"id": "node_dockcy8n9xe17",
|
||||||
|
"props": {
|
||||||
|
"title": "一级类目",
|
||||||
|
"dataIndex": "firstCategory"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"componentName": "Table.Column",
|
||||||
|
"id": "node_dockcy8n9xe18",
|
||||||
|
"props": {
|
||||||
|
"title": "二级类目",
|
||||||
|
"dataIndex": "secondCategory"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"componentName": "Table.Column",
|
||||||
|
"id": "node_dockcy8n9xe19",
|
||||||
|
"props": {
|
||||||
|
"title": "叶子类目",
|
||||||
|
"dataIndex": "leafCategory"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"componentName": "Table.Column",
|
||||||
|
"id": "node_dockcy8n9xe1a",
|
||||||
|
"props": {
|
||||||
|
"title": "项目类型",
|
||||||
|
"dataIndex": "projectType"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"componentName": "Table.Column",
|
||||||
|
"id": "node_dockcy8n9xe1b",
|
||||||
|
"props": {
|
||||||
|
"title": "项目 ID",
|
||||||
|
"dataIndex": "projectId"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"componentName": "Table.Column",
|
||||||
|
"id": "node_dockcy8n9xe1c",
|
||||||
|
"props": {
|
||||||
|
"title": "知识条标题",
|
||||||
|
"dataIndex": "title"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"componentName": "Table.Column",
|
||||||
|
"id": "node_dockcy8n9xe1d",
|
||||||
|
"props": {
|
||||||
|
"title": "知识条链接",
|
||||||
|
"dataIndex": "url"
|
||||||
|
}
|
||||||
|
}, {
|
||||||
|
"componentName": "Table.Column",
|
||||||
|
"id": "node_dockcy8n9xe1e",
|
||||||
|
"props": {
|
||||||
|
"title": "操作",
|
||||||
|
"dataIndex": "operation"
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"componentName": "Box",
|
||||||
|
"id": "node_dockcy8n9xe1f",
|
||||||
|
"props": {
|
||||||
|
"style": {
|
||||||
|
"backgroundColor": "#ffffff",
|
||||||
|
"paddingBottom": "24px"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"children": [{
|
||||||
|
"componentName": "Pagination",
|
||||||
|
"id": "node_dockcy8n9xe1g",
|
||||||
|
"props": {
|
||||||
|
"prefix": "next-",
|
||||||
|
"type": "normal",
|
||||||
|
"shape": "normal",
|
||||||
|
"size": "medium",
|
||||||
|
"defaultCurrent": 1,
|
||||||
|
"total": 100,
|
||||||
|
"pageShowCount": 5,
|
||||||
|
"pageSize": 10,
|
||||||
|
"pageSizePosition": "start",
|
||||||
|
"showJump": true,
|
||||||
|
"style": {
|
||||||
|
"display": "flex",
|
||||||
|
"justifyContent": "flex-end"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}]
|
||||||
|
}, {
|
||||||
|
"componentName": "Dialog",
|
||||||
|
"id": "node_dockcy8n9xe1h",
|
||||||
|
"props": {
|
||||||
|
"prefix": "next-",
|
||||||
|
"footerAlign": "right",
|
||||||
|
"footerActions": ["ok", "cancel"],
|
||||||
|
"closeable": "esc,close",
|
||||||
|
"hasMask": true,
|
||||||
|
"align": "cc cc",
|
||||||
|
"minMargin": 40,
|
||||||
|
"visible": {
|
||||||
|
"type": "JSExpression",
|
||||||
|
"value": "this.state.isShowDialog"
|
||||||
|
},
|
||||||
|
"children": {
|
||||||
|
"type": "JSSlot"
|
||||||
|
},
|
||||||
|
"title": "标题",
|
||||||
|
"footer": {
|
||||||
|
"type": "JSSlot"
|
||||||
|
},
|
||||||
|
"events": []
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
}
|
||||||
@ -15,6 +15,7 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@ali/am-eslint-config": "*",
|
"@ali/am-eslint-config": "*",
|
||||||
|
"@ali/lowcode-types": "^0.8.11",
|
||||||
"@ali/my-prettier": "^1.0.0",
|
"@ali/my-prettier": "^1.0.0",
|
||||||
"@babel/generator": "^7.9.5",
|
"@babel/generator": "^7.9.5",
|
||||||
"@babel/parser": "^7.9.4",
|
"@babel/parser": "^7.9.4",
|
||||||
|
|||||||
@ -1,13 +1,12 @@
|
|||||||
|
import { ProjectSchema, ResultFile, ResultDir } from '@ali/lowcode-types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BuilderComponentPlugin,
|
BuilderComponentPlugin,
|
||||||
CodeGeneratorError,
|
CodeGeneratorError,
|
||||||
IBasicSchema,
|
|
||||||
ICodeChunk,
|
ICodeChunk,
|
||||||
ICompiledModule,
|
ICompiledModule,
|
||||||
IModuleBuilder,
|
IModuleBuilder,
|
||||||
IParseResult,
|
IParseResult,
|
||||||
IResultDir,
|
|
||||||
IResultFile,
|
|
||||||
ISchemaParser,
|
ISchemaParser,
|
||||||
PostProcessor,
|
PostProcessor,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
@ -17,9 +16,7 @@ import { COMMON_SUB_MODULE_NAME } from '../const/generator';
|
|||||||
import SchemaParser from '../parser/SchemaParser';
|
import SchemaParser from '../parser/SchemaParser';
|
||||||
import ChunkBuilder from './ChunkBuilder';
|
import ChunkBuilder from './ChunkBuilder';
|
||||||
import CodeBuilder from './CodeBuilder';
|
import CodeBuilder from './CodeBuilder';
|
||||||
|
import { createResultFile, createResultDir, addFile } from '../utils/resultHelper';
|
||||||
import ResultDir from '../model/ResultDir';
|
|
||||||
import ResultFile from '../model/ResultFile';
|
|
||||||
|
|
||||||
export function createModuleBuilder(
|
export function createModuleBuilder(
|
||||||
options: {
|
options: {
|
||||||
@ -37,33 +34,27 @@ export function createModuleBuilder(
|
|||||||
const generateModule = async (input: unknown): Promise<ICompiledModule> => {
|
const generateModule = async (input: unknown): Promise<ICompiledModule> => {
|
||||||
const moduleMainName = options.mainFileName || COMMON_SUB_MODULE_NAME;
|
const moduleMainName = options.mainFileName || COMMON_SUB_MODULE_NAME;
|
||||||
if (chunkGenerator.getPlugins().length <= 0) {
|
if (chunkGenerator.getPlugins().length <= 0) {
|
||||||
throw new CodeGeneratorError(
|
throw new CodeGeneratorError('No plugins found. Component generation cannot work without any plugins!');
|
||||||
'No plugins found. Component generation cannot work without any plugins!',
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let files: IResultFile[] = [];
|
let files: ResultFile[] = [];
|
||||||
|
|
||||||
const { chunks } = await chunkGenerator.run(input);
|
const { chunks } = await chunkGenerator.run(input);
|
||||||
chunks.forEach(fileChunkList => {
|
chunks.forEach((fileChunkList) => {
|
||||||
const content = linker.link(fileChunkList);
|
const content = linker.link(fileChunkList);
|
||||||
const file = new ResultFile(
|
const file = createResultFile(fileChunkList[0].subModule || moduleMainName, fileChunkList[0].fileType, content);
|
||||||
fileChunkList[0].subModule || moduleMainName,
|
|
||||||
fileChunkList[0].fileType,
|
|
||||||
content,
|
|
||||||
);
|
|
||||||
files.push(file);
|
files.push(file);
|
||||||
});
|
});
|
||||||
|
|
||||||
if (options.postProcessors.length > 0) {
|
if (options.postProcessors.length > 0) {
|
||||||
files = files.map(file => {
|
files = files.map((file) => {
|
||||||
let content = file.content;
|
let content = file.content;
|
||||||
const type = file.ext;
|
const type = file.ext;
|
||||||
options.postProcessors.forEach(processer => {
|
options.postProcessors.forEach((processer) => {
|
||||||
content = processer(content, type);
|
content = processer(content, type);
|
||||||
});
|
});
|
||||||
|
|
||||||
return new ResultFile(file.name, type, content);
|
return createResultFile(file.name, type, content);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,7 +63,7 @@ export function createModuleBuilder(
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateModuleCode = async (schema: IBasicSchema | string): Promise<IResultDir> => {
|
const generateModuleCode = async (schema: ProjectSchema | string): Promise<ResultDir> => {
|
||||||
// Init
|
// Init
|
||||||
const schemaParser: ISchemaParser = new SchemaParser();
|
const schemaParser: ISchemaParser = new SchemaParser();
|
||||||
const parseResult: IParseResult = schemaParser.parse(schema);
|
const parseResult: IParseResult = schemaParser.parse(schema);
|
||||||
@ -80,26 +71,19 @@ export function createModuleBuilder(
|
|||||||
const containerInfo = parseResult.containers[0];
|
const containerInfo = parseResult.containers[0];
|
||||||
const { files } = await generateModule(containerInfo);
|
const { files } = await generateModule(containerInfo);
|
||||||
|
|
||||||
const dir = new ResultDir(containerInfo.moduleName);
|
const dir = createResultDir(containerInfo.moduleName);
|
||||||
files.forEach(file => dir.addFile(file));
|
files.forEach((file) => addFile(dir, file));
|
||||||
|
|
||||||
return dir;
|
return dir;
|
||||||
}
|
};
|
||||||
|
|
||||||
const linkCodeChunks = (
|
const linkCodeChunks = (chunks: Record<string, ICodeChunk[]>, fileName: string) => {
|
||||||
chunks: Record<string, ICodeChunk[]>,
|
const files: ResultFile[] = [];
|
||||||
fileName: string,
|
|
||||||
) => {
|
|
||||||
const files: IResultFile[] = [];
|
|
||||||
|
|
||||||
Object.keys(chunks).forEach(fileKey => {
|
Object.keys(chunks).forEach((fileKey) => {
|
||||||
const fileChunkList = chunks[fileKey];
|
const fileChunkList = chunks[fileKey];
|
||||||
const content = linker.link(fileChunkList);
|
const content = linker.link(fileChunkList);
|
||||||
const file = new ResultFile(
|
const file = createResultFile(fileChunkList[0].subModule || fileName, fileChunkList[0].fileType, content);
|
||||||
fileChunkList[0].subModule || fileName,
|
|
||||||
fileChunkList[0].fileType,
|
|
||||||
content,
|
|
||||||
);
|
|
||||||
files.push(file);
|
files.push(file);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@ -1,36 +1,35 @@
|
|||||||
|
import { ResultDir, ResultFile, ProjectSchema } from '@ali/lowcode-types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
IModuleBuilder,
|
IModuleBuilder,
|
||||||
IParseResult,
|
IParseResult,
|
||||||
IProjectBuilder,
|
IProjectBuilder,
|
||||||
IProjectPlugins,
|
IProjectPlugins,
|
||||||
IProjectSchema,
|
|
||||||
IProjectTemplate,
|
IProjectTemplate,
|
||||||
IResultDir,
|
|
||||||
IResultFile,
|
|
||||||
ISchemaParser,
|
ISchemaParser,
|
||||||
PostProcessor,
|
PostProcessor,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
|
|
||||||
import ResultDir from '../model/ResultDir';
|
|
||||||
import SchemaParser from '../parser/SchemaParser';
|
import SchemaParser from '../parser/SchemaParser';
|
||||||
|
import { createResultDir, addDirectory, addFile } from '../utils/resultHelper';
|
||||||
|
|
||||||
import { createModuleBuilder } from '../generator/ModuleBuilder';
|
import { createModuleBuilder } from '../generator/ModuleBuilder';
|
||||||
|
|
||||||
interface IModuleInfo {
|
interface IModuleInfo {
|
||||||
moduleName?: string;
|
moduleName?: string;
|
||||||
path: string[];
|
path: string[];
|
||||||
files: IResultFile[];
|
files: ResultFile[];
|
||||||
}
|
}
|
||||||
|
|
||||||
function getDirFromRoot(root: IResultDir, path: string[]): IResultDir {
|
function getDirFromRoot(root: ResultDir, path: string[]): ResultDir {
|
||||||
let current: IResultDir = root;
|
let current: ResultDir = root;
|
||||||
path.forEach(p => {
|
path.forEach((p) => {
|
||||||
const exist = current.dirs.find(d => d.name === p);
|
const exist = current.dirs.find((d) => d.name === p);
|
||||||
if (exist) {
|
if (exist) {
|
||||||
current = exist;
|
current = exist;
|
||||||
} else {
|
} else {
|
||||||
const newDir = new ResultDir(p);
|
const newDir = createResultDir(p);
|
||||||
current.addDirectory(newDir);
|
addDirectory(current, newDir);
|
||||||
current = newDir;
|
current = newDir;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -57,7 +56,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
this.postProcessors = postProcessors;
|
this.postProcessors = postProcessors;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async generateProject(schema: IProjectSchema | string): Promise<IResultDir> {
|
async generateProject(schema: ProjectSchema | string): Promise<ResultDir> {
|
||||||
// Init
|
// Init
|
||||||
const schemaParser: ISchemaParser = new SchemaParser();
|
const schemaParser: ISchemaParser = new SchemaParser();
|
||||||
const builders = this.createModuleBuilders();
|
const builders = this.createModuleBuilders();
|
||||||
@ -76,7 +75,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
// components
|
// components
|
||||||
// pages
|
// pages
|
||||||
const containerBuildResult: IModuleInfo[] = await Promise.all<IModuleInfo>(
|
const containerBuildResult: IModuleInfo[] = await Promise.all<IModuleInfo>(
|
||||||
parseResult.containers.map(async containerInfo => {
|
parseResult.containers.map(async (containerInfo) => {
|
||||||
let builder: IModuleBuilder;
|
let builder: IModuleBuilder;
|
||||||
let path: string[];
|
let path: string[];
|
||||||
if (containerInfo.containerType === 'Page') {
|
if (containerInfo.containerType === 'Page') {
|
||||||
@ -100,9 +99,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
|
|
||||||
// router
|
// router
|
||||||
if (parseResult.globalRouter && builders.router) {
|
if (parseResult.globalRouter && builders.router) {
|
||||||
const { files } = await builders.router.generateModule(
|
const { files } = await builders.router.generateModule(parseResult.globalRouter);
|
||||||
parseResult.globalRouter,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.router.path,
|
path: this.template.slots.router.path,
|
||||||
@ -112,9 +109,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
|
|
||||||
// entry
|
// entry
|
||||||
if (parseResult.project && builders.entry) {
|
if (parseResult.project && builders.entry) {
|
||||||
const { files } = await builders.entry.generateModule(
|
const { files } = await builders.entry.generateModule(parseResult.project);
|
||||||
parseResult.project,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.entry.path,
|
path: this.template.slots.entry.path,
|
||||||
@ -122,14 +117,8 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
// constants?
|
// constants?
|
||||||
if (
|
if (parseResult.project && builders.constants && this.template.slots.constants) {
|
||||||
parseResult.project &&
|
const { files } = await builders.constants.generateModule(parseResult.project);
|
||||||
builders.constants &&
|
|
||||||
this.template.slots.constants
|
|
||||||
) {
|
|
||||||
const { files } = await builders.constants.generateModule(
|
|
||||||
parseResult.project,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.constants.path,
|
path: this.template.slots.constants.path,
|
||||||
@ -137,14 +126,8 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
// utils?
|
// utils?
|
||||||
if (
|
if (parseResult.globalUtils && builders.utils && this.template.slots.utils) {
|
||||||
parseResult.globalUtils &&
|
const { files } = await builders.utils.generateModule(parseResult.globalUtils);
|
||||||
builders.utils &&
|
|
||||||
this.template.slots.utils
|
|
||||||
) {
|
|
||||||
const { files } = await builders.utils.generateModule(
|
|
||||||
parseResult.globalUtils,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.utils.path,
|
path: this.template.slots.utils.path,
|
||||||
@ -153,9 +136,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
}
|
}
|
||||||
// i18n?
|
// i18n?
|
||||||
if (parseResult.globalI18n && builders.i18n && this.template.slots.i18n) {
|
if (parseResult.globalI18n && builders.i18n && this.template.slots.i18n) {
|
||||||
const { files } = await builders.i18n.generateModule(
|
const { files } = await builders.i18n.generateModule(parseResult.globalI18n);
|
||||||
parseResult.globalI18n,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.i18n.path,
|
path: this.template.slots.i18n.path,
|
||||||
@ -164,9 +145,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
}
|
}
|
||||||
// globalStyle
|
// globalStyle
|
||||||
if (parseResult.project && builders.globalStyle) {
|
if (parseResult.project && builders.globalStyle) {
|
||||||
const { files } = await builders.globalStyle.generateModule(
|
const { files } = await builders.globalStyle.generateModule(parseResult.project);
|
||||||
parseResult.project,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.globalStyle.path,
|
path: this.template.slots.globalStyle.path,
|
||||||
@ -175,9 +154,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
}
|
}
|
||||||
// htmlEntry
|
// htmlEntry
|
||||||
if (parseResult.project && builders.htmlEntry) {
|
if (parseResult.project && builders.htmlEntry) {
|
||||||
const { files } = await builders.htmlEntry.generateModule(
|
const { files } = await builders.htmlEntry.generateModule(parseResult.project);
|
||||||
parseResult.project,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.htmlEntry.path,
|
path: this.template.slots.htmlEntry.path,
|
||||||
@ -186,9 +163,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
}
|
}
|
||||||
// packageJSON
|
// packageJSON
|
||||||
if (parseResult.project && builders.packageJSON) {
|
if (parseResult.project && builders.packageJSON) {
|
||||||
const { files } = await builders.packageJSON.generateModule(
|
const { files } = await builders.packageJSON.generateModule(parseResult.project);
|
||||||
parseResult.project,
|
|
||||||
);
|
|
||||||
|
|
||||||
buildResult.push({
|
buildResult.push({
|
||||||
path: this.template.slots.packageJSON.path,
|
path: this.template.slots.packageJSON.path,
|
||||||
@ -199,14 +174,14 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
// Post Process
|
// Post Process
|
||||||
|
|
||||||
// Combine Modules
|
// Combine Modules
|
||||||
buildResult.forEach(moduleInfo => {
|
buildResult.forEach((moduleInfo) => {
|
||||||
let targetDir = getDirFromRoot(projectRoot, moduleInfo.path);
|
let targetDir = getDirFromRoot(projectRoot, moduleInfo.path);
|
||||||
if (moduleInfo.moduleName) {
|
if (moduleInfo.moduleName) {
|
||||||
const dir = new ResultDir(moduleInfo.moduleName);
|
const dir = createResultDir(moduleInfo.moduleName);
|
||||||
targetDir.addDirectory(dir);
|
addDirectory(targetDir, dir);
|
||||||
targetDir = dir;
|
targetDir = dir;
|
||||||
}
|
}
|
||||||
moduleInfo.files.forEach(file => targetDir.addFile(file));
|
moduleInfo.files.forEach((file) => addFile(targetDir, file));
|
||||||
});
|
});
|
||||||
|
|
||||||
return projectRoot;
|
return projectRoot;
|
||||||
@ -215,7 +190,7 @@ export class ProjectBuilder implements IProjectBuilder {
|
|||||||
private createModuleBuilders(): Record<string, IModuleBuilder> {
|
private createModuleBuilders(): Record<string, IModuleBuilder> {
|
||||||
const builders: Record<string, IModuleBuilder> = {};
|
const builders: Record<string, IModuleBuilder> = {};
|
||||||
|
|
||||||
Object.keys(this.plugins).forEach(pluginName => {
|
Object.keys(this.plugins).forEach((pluginName) => {
|
||||||
if (this.plugins[pluginName].length > 0) {
|
if (this.plugins[pluginName].length > 0) {
|
||||||
const options: { mainFileName?: string } = {};
|
const options: { mainFileName?: string } = {};
|
||||||
if (this.template.slots[pluginName] && this.template.slots[pluginName].fileName) {
|
if (this.template.slots[pluginName] && this.template.slots[pluginName].fileName) {
|
||||||
|
|||||||
@ -11,11 +11,7 @@ import createRecoreProjectBuilder from './solutions/recore';
|
|||||||
|
|
||||||
// 引入说明
|
// 引入说明
|
||||||
import { REACT_CHUNK_NAME } from './plugins/component/react/const';
|
import { REACT_CHUNK_NAME } from './plugins/component/react/const';
|
||||||
import {
|
import { COMMON_CHUNK_NAME, CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from './const/generator';
|
||||||
COMMON_CHUNK_NAME,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME,
|
|
||||||
DEFAULT_LINK_AFTER,
|
|
||||||
} from './const/generator';
|
|
||||||
|
|
||||||
// 引入通用插件组
|
// 引入通用插件组
|
||||||
import esmodule from './plugins/common/esmodule';
|
import esmodule from './plugins/common/esmodule';
|
||||||
@ -38,8 +34,11 @@ import prettier from './postprocessor/prettier';
|
|||||||
import * as utilsCommon from './utils/common';
|
import * as utilsCommon from './utils/common';
|
||||||
import * as utilsCompositeType from './utils/compositeType';
|
import * as utilsCompositeType from './utils/compositeType';
|
||||||
import * as utilsJsExpression from './utils/jsExpression';
|
import * as utilsJsExpression from './utils/jsExpression';
|
||||||
|
import * as utilsJsSlot from './utils/jsSlot';
|
||||||
import * as utilsNodeToJSX from './utils/nodeToJSX';
|
import * as utilsNodeToJSX from './utils/nodeToJSX';
|
||||||
|
import * as utilsResultHelper from './utils/resultHelper';
|
||||||
import * as utilsTemplateHelper from './utils/templateHelper';
|
import * as utilsTemplateHelper from './utils/templateHelper';
|
||||||
|
import * as utilsValidate from './utils/validate';
|
||||||
|
|
||||||
// 引入内置解决方案模块
|
// 引入内置解决方案模块
|
||||||
import icejs from './plugins/project/framework/icejs';
|
import icejs from './plugins/project/framework/icejs';
|
||||||
@ -91,8 +90,11 @@ export default {
|
|||||||
common: utilsCommon,
|
common: utilsCommon,
|
||||||
compositeType: utilsCompositeType,
|
compositeType: utilsCompositeType,
|
||||||
jsExpression: utilsJsExpression,
|
jsExpression: utilsJsExpression,
|
||||||
|
jsSlot: utilsJsSlot,
|
||||||
nodeToJSX: utilsNodeToJSX,
|
nodeToJSX: utilsNodeToJSX,
|
||||||
|
resultHelper: utilsResultHelper,
|
||||||
templateHelper: utilsTemplateHelper,
|
templateHelper: utilsTemplateHelper,
|
||||||
|
validate: utilsValidate,
|
||||||
},
|
},
|
||||||
chunkNames: {
|
chunkNames: {
|
||||||
COMMON_CHUNK_NAME,
|
COMMON_CHUNK_NAME,
|
||||||
|
|||||||
@ -1,31 +0,0 @@
|
|||||||
import { CodeGeneratorError, IResultDir, IResultFile } from '../types';
|
|
||||||
|
|
||||||
export default class ResultDir implements IResultDir {
|
|
||||||
public name: string;
|
|
||||||
public dirs: IResultDir[];
|
|
||||||
public files: IResultFile[];
|
|
||||||
|
|
||||||
constructor(name: string) {
|
|
||||||
this.name = name;
|
|
||||||
this.dirs = [];
|
|
||||||
this.files = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
public addDirectory(dir: IResultDir): void {
|
|
||||||
if (this.dirs.findIndex(d => d.name === dir.name) < 0) {
|
|
||||||
this.dirs.push(dir);
|
|
||||||
} else {
|
|
||||||
throw new CodeGeneratorError('Adding same directory to one directory');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public addFile(file: IResultFile): void {
|
|
||||||
if (
|
|
||||||
this.files.findIndex(f => f.name === file.name && f.ext === file.ext) < 0
|
|
||||||
) {
|
|
||||||
this.files.push(file);
|
|
||||||
} else {
|
|
||||||
throw new CodeGeneratorError('Adding same file to one directory');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
import { IResultFile } from '../types';
|
|
||||||
|
|
||||||
export default class ResultFile implements IResultFile {
|
|
||||||
public name: string;
|
|
||||||
public ext: string;
|
|
||||||
public content: string;
|
|
||||||
|
|
||||||
constructor(name: string, ext: string = 'jsx', content: string = '') {
|
|
||||||
this.name = name;
|
|
||||||
this.ext = ext;
|
|
||||||
this.content = content;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -2,28 +2,24 @@
|
|||||||
* 解析器是对输入的固定格式数据做拆解,使其符合引擎后续步骤预期,完成统一处理逻辑的步骤。
|
* 解析器是对输入的固定格式数据做拆解,使其符合引擎后续步骤预期,完成统一处理逻辑的步骤。
|
||||||
* 本解析器面向的是标准 schema 协议。
|
* 本解析器面向的是标准 schema 协议。
|
||||||
*/
|
*/
|
||||||
|
import { IUtilItem, NodeDataType, NodeSchema, ContainerSchema, ProjectSchema, PropsMap } from '@ali/lowcode-types';
|
||||||
|
|
||||||
import { SUPPORT_SCHEMA_VERSION_LIST } from '../const';
|
import { SUPPORT_SCHEMA_VERSION_LIST } from '../const';
|
||||||
|
|
||||||
import { handleChildren } from '../utils/nodeToJSX';
|
import { handleSubNodes } from '../utils/nodeToJSX';
|
||||||
|
import { uniqueArray } from '../utils/common';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
ChildNodeType,
|
|
||||||
CodeGeneratorError,
|
CodeGeneratorError,
|
||||||
CompatibilityError,
|
CompatibilityError,
|
||||||
DependencyType,
|
DependencyType,
|
||||||
IBasicSchema,
|
|
||||||
IComponentNodeItem,
|
|
||||||
IContainerInfo,
|
IContainerInfo,
|
||||||
IContainerNodeItem,
|
|
||||||
IExternalDependency,
|
IExternalDependency,
|
||||||
IInternalDependency,
|
IInternalDependency,
|
||||||
InternalDependencyType,
|
InternalDependencyType,
|
||||||
IPageMeta,
|
|
||||||
IParseResult,
|
IParseResult,
|
||||||
IProjectSchema,
|
|
||||||
ISchemaParser,
|
ISchemaParser,
|
||||||
IUtilItem,
|
INpmPackage,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
|
|
||||||
const defaultContainer: IContainerInfo = {
|
const defaultContainer: IContainerInfo = {
|
||||||
@ -36,23 +32,21 @@ const defaultContainer: IContainerInfo = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
class SchemaParser implements ISchemaParser {
|
class SchemaParser implements ISchemaParser {
|
||||||
public validate(schema: IBasicSchema): boolean {
|
validate(schema: ProjectSchema): boolean {
|
||||||
if (SUPPORT_SCHEMA_VERSION_LIST.indexOf(schema.version) < 0) {
|
if (SUPPORT_SCHEMA_VERSION_LIST.indexOf(schema.version) < 0) {
|
||||||
throw new CompatibilityError(
|
throw new CompatibilityError(`Not support schema with version [${schema.version}]`);
|
||||||
`Not support schema with version [${schema.version}]`,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public parse(schemaSrc: IProjectSchema | string): IParseResult {
|
parse(schemaSrc: ProjectSchema | string): IParseResult {
|
||||||
// TODO: collect utils depends in JSExpression
|
// TODO: collect utils depends in JSExpression
|
||||||
const compDeps: Record<string, IExternalDependency> = {};
|
const compDeps: Record<string, IExternalDependency> = {};
|
||||||
const internalDeps: Record<string, IInternalDependency> = {};
|
const internalDeps: Record<string, IInternalDependency> = {};
|
||||||
let utilsDeps: IExternalDependency[] = [];
|
let utilsDeps: IExternalDependency[] = [];
|
||||||
|
|
||||||
let schema: IProjectSchema;
|
let schema: ProjectSchema;
|
||||||
if (typeof schemaSrc === 'string') {
|
if (typeof schemaSrc === 'string') {
|
||||||
try {
|
try {
|
||||||
schema = JSON.parse(schemaSrc);
|
schema = JSON.parse(schemaSrc);
|
||||||
@ -64,29 +58,39 @@ class SchemaParser implements ISchemaParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 解析三方组件依赖
|
// 解析三方组件依赖
|
||||||
schema.componentsMap.forEach(info => {
|
schema.componentsMap.forEach((info) => {
|
||||||
info.dependencyType = DependencyType.External;
|
const extDep: IExternalDependency = {
|
||||||
info.importName = info.componentName;
|
componentName: info.componentName,
|
||||||
compDeps[info.componentName] = info;
|
package: info.package,
|
||||||
|
version: info.version || '',
|
||||||
|
destructuring: info.destructuring || false,
|
||||||
|
exportName: info.exportName || info.componentName || '',
|
||||||
|
subName: info.subName,
|
||||||
|
main: info.main,
|
||||||
|
dependencyType: DependencyType.External,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (extDep.componentName) {
|
||||||
|
compDeps[extDep.componentName] = extDep;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
let containers: IContainerInfo[];
|
let containers: IContainerInfo[];
|
||||||
// Test if this is a lowcode component without container
|
// Test if this is a lowcode component without container
|
||||||
if (schema.componentsTree.length > 0) {
|
if (schema.componentsTree.length > 0) {
|
||||||
const firstRoot: IContainerNodeItem = schema
|
const firstRoot: ContainerSchema = schema.componentsTree[0] as ContainerSchema;
|
||||||
.componentsTree[0] as IContainerNodeItem;
|
|
||||||
|
|
||||||
if (!firstRoot.fileName) {
|
if (!firstRoot.fileName) {
|
||||||
// 整个 schema 描述一个容器,且无根节点定义
|
// 整个 schema 描述一个容器,且无根节点定义
|
||||||
const container: IContainerInfo = {
|
const container: IContainerInfo = {
|
||||||
...defaultContainer,
|
...defaultContainer,
|
||||||
children: schema.componentsTree as IComponentNodeItem[],
|
children: schema.componentsTree as NodeSchema[],
|
||||||
};
|
};
|
||||||
containers = [container];
|
containers = [container];
|
||||||
} else {
|
} else {
|
||||||
// 普通带 1 到多个容器的 schema
|
// 普通带 1 到多个容器的 schema
|
||||||
containers = schema.componentsTree.map(n => {
|
containers = schema.componentsTree.map((n) => {
|
||||||
const subRoot = n as IContainerNodeItem;
|
const subRoot = n as ContainerSchema;
|
||||||
const container: IContainerInfo = {
|
const container: IContainerInfo = {
|
||||||
...subRoot,
|
...subRoot,
|
||||||
containerType: subRoot.componentName,
|
containerType: subRoot.componentName,
|
||||||
@ -100,7 +104,7 @@ class SchemaParser implements ISchemaParser {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 建立所有容器的内部依赖索引
|
// 建立所有容器的内部依赖索引
|
||||||
containers.forEach(container => {
|
containers.forEach((container) => {
|
||||||
let type;
|
let type;
|
||||||
switch (container.containerType) {
|
switch (container.containerType) {
|
||||||
case 'Page':
|
case 'Page':
|
||||||
@ -125,51 +129,87 @@ class SchemaParser implements ISchemaParser {
|
|||||||
internalDeps[dep.moduleName] = dep;
|
internalDeps[dep.moduleName] = dep;
|
||||||
});
|
});
|
||||||
|
|
||||||
// 分析容器内部组件依赖
|
// TODO: 不应该在出码部分解决?
|
||||||
containers.forEach(container => {
|
// 处理 children 写在了 props 里的情况
|
||||||
|
containers.forEach((container) => {
|
||||||
if (container.children) {
|
if (container.children) {
|
||||||
// const depNames = this.getComponentNames(container.children);
|
handleSubNodes<string>(
|
||||||
// container.deps = uniqueArray<string>(depNames)
|
container.children,
|
||||||
// .map(depName => internalDeps[depName] || compDeps[depName])
|
{
|
||||||
// .filter(dep => !!dep);
|
node: (i: NodeSchema) => {
|
||||||
container.deps = Object.keys(compDeps).map(
|
if (i.props) {
|
||||||
depName => compDeps[depName],
|
if (Array.isArray(i.props)) {
|
||||||
|
// FIXME: is array type props description
|
||||||
|
} else {
|
||||||
|
const nodeProps = i.props as PropsMap;
|
||||||
|
if (nodeProps.children && !i.children) {
|
||||||
|
i.children = nodeProps.children as NodeDataType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return [''];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rerun: true,
|
||||||
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 分析容器内部组件依赖
|
||||||
|
containers.forEach((container) => {
|
||||||
|
if (container.children) {
|
||||||
|
const depNames = this.getComponentNames(container.children);
|
||||||
|
container.deps = uniqueArray<string>(depNames, (i: string) => i)
|
||||||
|
.map((depName) => internalDeps[depName] || compDeps[depName])
|
||||||
|
.filter((dep) => !!dep);
|
||||||
|
// container.deps = Object.keys(compDeps).map((depName) => compDeps[depName]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// 分析路由配置
|
// 分析路由配置
|
||||||
const routes = containers
|
const routes = containers
|
||||||
.filter(container => container.containerType === 'Page')
|
.filter((container) => container.containerType === 'Page')
|
||||||
.map(page => {
|
.map((page) => {
|
||||||
const meta = page.meta as IPageMeta;
|
let router = '';
|
||||||
if (meta) {
|
if (page.meta) {
|
||||||
return {
|
router = (page.meta as any)?.router || '';
|
||||||
path: meta.router,
|
|
||||||
componentName: page.moduleName,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!router) {
|
||||||
|
router = `/${page.fileName}`;
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
path: '',
|
path: router,
|
||||||
componentName: page.moduleName,
|
componentName: page.moduleName,
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
const routerDeps = routes
|
const routerDeps = routes
|
||||||
.map(r => internalDeps[r.componentName] || compDeps[r.componentName])
|
.map((r) => internalDeps[r.componentName] || compDeps[r.componentName])
|
||||||
.filter(dep => !!dep);
|
.filter((dep) => !!dep);
|
||||||
|
|
||||||
// 分析 Utils 依赖
|
// 分析 Utils 依赖
|
||||||
let utils: IUtilItem[];
|
let utils: IUtilItem[];
|
||||||
if (schema.utils) {
|
if (schema.utils) {
|
||||||
utils = schema.utils;
|
utils = schema.utils;
|
||||||
utilsDeps = schema.utils
|
utilsDeps = schema.utils.filter((u) => u.type !== 'function').map((u) => u.content as IExternalDependency);
|
||||||
.filter(u => u.type !== 'function')
|
|
||||||
.map(u => u.content as IExternalDependency);
|
|
||||||
} else {
|
} else {
|
||||||
utils = [];
|
utils = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 分析项目 npm 依赖
|
||||||
|
let npms: INpmPackage[] = [];
|
||||||
|
containers.forEach((con) => {
|
||||||
|
const p = (con.deps || [])
|
||||||
|
.map((dep) => (dep.dependencyType === DependencyType.External ? dep : null))
|
||||||
|
.filter((dep) => dep !== null);
|
||||||
|
npms.push(...((p as unknown) as INpmPackage[]));
|
||||||
|
});
|
||||||
|
npms = uniqueArray<INpmPackage>(npms, (i) => i.package);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
containers,
|
containers,
|
||||||
globalUtils: {
|
globalUtils: {
|
||||||
@ -182,19 +222,24 @@ class SchemaParser implements ISchemaParser {
|
|||||||
deps: routerDeps,
|
deps: routerDeps,
|
||||||
},
|
},
|
||||||
project: {
|
project: {
|
||||||
meta: schema.meta,
|
|
||||||
config: schema.config,
|
|
||||||
css: schema.css,
|
css: schema.css,
|
||||||
constants: schema.constants,
|
constants: schema.constants,
|
||||||
i18n: schema.i18n,
|
i18n: schema.i18n,
|
||||||
|
packages: npms,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public getComponentNames(children: ChildNodeType): string[] {
|
getComponentNames(children: NodeDataType): string[] {
|
||||||
return handleChildren<string>(children, {
|
return handleSubNodes<string>(
|
||||||
node: (i: IComponentNodeItem) => [i.componentName],
|
children,
|
||||||
});
|
{
|
||||||
|
node: (i: NodeSchema) => [i.componentName],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
rerun: true,
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -15,6 +15,8 @@ import {
|
|||||||
IWithDependency,
|
IWithDependency,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
|
|
||||||
|
import { isValidIdentifier } from '../../utils/validate';
|
||||||
|
|
||||||
function groupDepsByPack(deps: IDependency[]): Record<string, IDependency[]> {
|
function groupDepsByPack(deps: IDependency[]): Record<string, IDependency[]> {
|
||||||
const depMap: Record<string, IDependency[]> = {};
|
const depMap: Record<string, IDependency[]> = {};
|
||||||
|
|
||||||
@ -25,48 +27,53 @@ function groupDepsByPack(deps: IDependency[]): Record<string, IDependency[]> {
|
|||||||
depMap[pkg].push(dep);
|
depMap[pkg].push(dep);
|
||||||
};
|
};
|
||||||
|
|
||||||
deps.forEach(dep => {
|
// TODO: main 这个信息到底怎么用,是不是外部包不需要使用?
|
||||||
|
// deps.forEach(dep => {
|
||||||
|
// if (dep.dependencyType === DependencyType.Internal) {
|
||||||
|
// addDep(
|
||||||
|
// `${(dep as IInternalDependency).moduleName}${`/${dep.main}` || ''}`,
|
||||||
|
// dep,
|
||||||
|
// );
|
||||||
|
// } else {
|
||||||
|
// addDep(`${(dep as IExternalDependency).package}${`/${dep.main}` || ''}`, dep);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
|
||||||
|
deps.forEach((dep) => {
|
||||||
if (dep.dependencyType === DependencyType.Internal) {
|
if (dep.dependencyType === DependencyType.Internal) {
|
||||||
addDep(
|
addDep(`${(dep as IInternalDependency).moduleName}`, dep);
|
||||||
`${(dep as IInternalDependency).moduleName}${dep.main || ''}`,
|
|
||||||
dep,
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
addDep(`${(dep as IExternalDependency).package}${dep.main || ''}`, dep);
|
addDep(`${(dep as IExternalDependency).package}`, dep);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return depMap;
|
return depMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
function buildPackageImport(
|
function buildPackageImport(pkg: string, deps: IDependency[], targetFileType: string): ICodeChunk[] {
|
||||||
pkg: string,
|
|
||||||
deps: IDependency[],
|
|
||||||
targetFileType: string,
|
|
||||||
): ICodeChunk[] {
|
|
||||||
const chunks: ICodeChunk[] = [];
|
const chunks: ICodeChunk[] = [];
|
||||||
let defaultImport: string = '';
|
let defaultImport = '';
|
||||||
let defaultImportAs: string = '';
|
let defaultImportAs = '';
|
||||||
const imports: Record<string, string> = {};
|
const imports: Record<string, string> = {};
|
||||||
|
|
||||||
deps.forEach(dep => {
|
deps.forEach((dep) => {
|
||||||
const srcName = dep.exportName;
|
const srcName = dep.exportName;
|
||||||
let targetName = dep.importName || dep.exportName;
|
let targetName = dep.componentName || dep.exportName;
|
||||||
if (dep.subName) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (dep.subName) {
|
if (dep.subName) {
|
||||||
chunks.push({
|
if (targetName !== `${srcName}.${dep.subName}`) {
|
||||||
type: ChunkType.STRING,
|
if (!isValidIdentifier(targetName)) {
|
||||||
fileType: targetFileType,
|
throw new CodeGeneratorError(`Invalid Identifier [${targetName}]`);
|
||||||
name: COMMON_CHUNK_NAME.FileVarDefine,
|
}
|
||||||
content: `const ${targetName} = ${srcName}.${dep.subName};`,
|
|
||||||
linkAfter: [
|
chunks.push({
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
type: ChunkType.STRING,
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
fileType: targetFileType,
|
||||||
],
|
name: COMMON_CHUNK_NAME.FileVarDefine,
|
||||||
});
|
content: `const ${targetName} = ${srcName}.${dep.subName};`,
|
||||||
|
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport, COMMON_CHUNK_NAME.InternalDepsImport],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
targetName = srcName;
|
targetName = srcName;
|
||||||
}
|
}
|
||||||
@ -74,18 +81,14 @@ function buildPackageImport(
|
|||||||
if (dep.destructuring) {
|
if (dep.destructuring) {
|
||||||
imports[srcName] = targetName;
|
imports[srcName] = targetName;
|
||||||
} else if (defaultImport) {
|
} else if (defaultImport) {
|
||||||
throw new CodeGeneratorError(
|
throw new CodeGeneratorError(`[${pkg}] has more than one default export.`);
|
||||||
`[${pkg}] has more than one default export.`,
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
defaultImport = srcName;
|
defaultImport = srcName;
|
||||||
defaultImportAs = targetName;
|
defaultImportAs = targetName;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const items = Object.keys(imports).map(src =>
|
const items = Object.keys(imports).map((src) => (src === imports[src] ? src : `${src} as ${imports[src]}`));
|
||||||
src === imports[src] ? src : `${src} as ${imports[src]}`,
|
|
||||||
);
|
|
||||||
|
|
||||||
const statementL = ['import'];
|
const statementL = ['import'];
|
||||||
if (defaultImport) {
|
if (defaultImport) {
|
||||||
@ -125,7 +128,7 @@ function buildPackageImport(
|
|||||||
|
|
||||||
type PluginConfig = {
|
type PluginConfig = {
|
||||||
fileType: string;
|
fileType: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?: PluginConfig) => {
|
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?: PluginConfig) => {
|
||||||
const cfg: PluginConfig = {
|
const cfg: PluginConfig = {
|
||||||
@ -143,9 +146,9 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?: Plu
|
|||||||
if (ir && ir.deps && ir.deps.length > 0) {
|
if (ir && ir.deps && ir.deps.length > 0) {
|
||||||
const packs = groupDepsByPack(ir.deps);
|
const packs = groupDepsByPack(ir.deps);
|
||||||
|
|
||||||
Object.keys(packs).forEach(pkg => {
|
Object.keys(packs).forEach((pkg) => {
|
||||||
const chunks = buildPackageImport(pkg, packs[pkg], cfg.fileType);
|
const chunks = buildPackageImport(pkg, packs[pkg], cfg.fileType);
|
||||||
next.chunks.push.apply(next.chunks, chunks);
|
next.chunks.push(...chunks);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -52,10 +52,7 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|||||||
fileType: FileType.JSX,
|
fileType: FileType.JSX,
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.ConstructorEnd,
|
name: CLASS_DEFINE_CHUNK_NAME.ConstructorEnd,
|
||||||
content: '}',
|
content: '}',
|
||||||
linkAfter: [
|
linkAfter: [CLASS_DEFINE_CHUNK_NAME.ConstructorStart, CLASS_DEFINE_CHUNK_NAME.ConstructorContent],
|
||||||
CLASS_DEFINE_CHUNK_NAME.ConstructorStart,
|
|
||||||
CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
next.chunks.push({
|
next.chunks.push({
|
||||||
@ -75,11 +72,7 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|||||||
fileType: FileType.JSX,
|
fileType: FileType.JSX,
|
||||||
name: REACT_CHUNK_NAME.ClassRenderEnd,
|
name: REACT_CHUNK_NAME.ClassRenderEnd,
|
||||||
content: '}',
|
content: '}',
|
||||||
linkAfter: [
|
linkAfter: [REACT_CHUNK_NAME.ClassRenderStart, REACT_CHUNK_NAME.ClassRenderPre, REACT_CHUNK_NAME.ClassRenderJSX],
|
||||||
REACT_CHUNK_NAME.ClassRenderStart,
|
|
||||||
REACT_CHUNK_NAME.ClassRenderPre,
|
|
||||||
REACT_CHUNK_NAME.ClassRenderJSX,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
next.chunks.push({
|
next.chunks.push({
|
||||||
|
|||||||
@ -13,7 +13,7 @@ import {
|
|||||||
|
|
||||||
type PluginConfig = {
|
type PluginConfig = {
|
||||||
fileType: string;
|
fileType: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
||||||
const cfg: PluginConfig = {
|
const cfg: PluginConfig = {
|
||||||
@ -30,9 +30,9 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
|||||||
|
|
||||||
if (ir.state) {
|
if (ir.state) {
|
||||||
const state = ir.state;
|
const state = ir.state;
|
||||||
const fields = Object.keys(state).map<string>(stateName => {
|
const fields = Object.keys(state).map<string>((stateName) => {
|
||||||
const [isString, value] = generateCompositeType(state[stateName]);
|
const value = generateCompositeType(state[stateName]);
|
||||||
return `${stateName}: ${isString ? `'${value}'` : value},`;
|
return `${stateName}: ${value},`;
|
||||||
});
|
});
|
||||||
|
|
||||||
next.chunks.push({
|
next.chunks.push({
|
||||||
|
|||||||
@ -14,7 +14,7 @@ import {
|
|||||||
type PluginConfig = {
|
type PluginConfig = {
|
||||||
fileType: string;
|
fileType: string;
|
||||||
implementType: 'inConstructor' | 'insMember' | 'hooks';
|
implementType: 'inConstructor' | 'insMember' | 'hooks';
|
||||||
}
|
};
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
||||||
const cfg: PluginConfig = {
|
const cfg: PluginConfig = {
|
||||||
@ -32,9 +32,9 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
|||||||
|
|
||||||
if (ir.state) {
|
if (ir.state) {
|
||||||
const state = ir.state;
|
const state = ir.state;
|
||||||
const fields = Object.keys(state).map<string>(stateName => {
|
const fields = Object.keys(state).map<string>((stateName) => {
|
||||||
const [isString, value] = generateCompositeType(state[stateName]);
|
const value = generateCompositeType(state[stateName]);
|
||||||
return `${stateName}: ${isString ? `'${value}'` : value},`;
|
return `${stateName}: ${value},`;
|
||||||
});
|
});
|
||||||
|
|
||||||
if (cfg.implementType === 'inConstructor') {
|
if (cfg.implementType === 'inConstructor') {
|
||||||
|
|||||||
@ -1,28 +1,23 @@
|
|||||||
import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
||||||
import { REACT_CHUNK_NAME } from './const';
|
import { REACT_CHUNK_NAME } from './const';
|
||||||
|
|
||||||
import {
|
import { generateFunction } from '../../../utils/jsExpression';
|
||||||
getFuncExprBody,
|
|
||||||
transformFuncExpr2MethodMember,
|
|
||||||
} from '../../../utils/jsExpression';
|
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BuilderComponentPlugin,
|
BuilderComponentPlugin,
|
||||||
BuilderComponentPluginFactory,
|
BuilderComponentPluginFactory,
|
||||||
ChunkType,
|
ChunkType,
|
||||||
CodeGeneratorError,
|
|
||||||
FileType,
|
FileType,
|
||||||
ICodeChunk,
|
ICodeChunk,
|
||||||
ICodeStruct,
|
ICodeStruct,
|
||||||
IContainerInfo,
|
IContainerInfo,
|
||||||
IJSExpression,
|
|
||||||
} from '../../../types';
|
} from '../../../types';
|
||||||
|
|
||||||
type PluginConfig = {
|
type PluginConfig = {
|
||||||
fileType: string;
|
fileType: string;
|
||||||
exportNameMapping: Record<string, string>;
|
exportNameMapping: Record<string, string>;
|
||||||
normalizeNameMapping: Record<string, string>;
|
normalizeNameMapping: Record<string, string>;
|
||||||
}
|
};
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
||||||
const cfg: PluginConfig = {
|
const cfg: PluginConfig = {
|
||||||
@ -41,7 +36,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
|||||||
|
|
||||||
if (ir.lifeCycles) {
|
if (ir.lifeCycles) {
|
||||||
const lifeCycles = ir.lifeCycles;
|
const lifeCycles = ir.lifeCycles;
|
||||||
const chunks = Object.keys(lifeCycles).map<ICodeChunk>(lifeCycleName => {
|
const chunks = Object.keys(lifeCycles).map<ICodeChunk>((lifeCycleName) => {
|
||||||
const normalizeName = cfg.normalizeNameMapping[lifeCycleName] || lifeCycleName;
|
const normalizeName = cfg.normalizeNameMapping[lifeCycleName] || lifeCycleName;
|
||||||
const exportName = cfg.exportNameMapping[lifeCycleName] || lifeCycleName;
|
const exportName = cfg.exportNameMapping[lifeCycleName] || lifeCycleName;
|
||||||
if (normalizeName === 'constructor') {
|
if (normalizeName === 'constructor') {
|
||||||
@ -49,9 +44,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
|||||||
type: ChunkType.STRING,
|
type: ChunkType.STRING,
|
||||||
fileType: cfg.fileType,
|
fileType: cfg.fileType,
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
name: CLASS_DEFINE_CHUNK_NAME.ConstructorContent,
|
||||||
content: getFuncExprBody(
|
content: generateFunction(lifeCycles[lifeCycleName], { isBlock: true }),
|
||||||
(lifeCycles[lifeCycleName] as IJSExpression).value,
|
|
||||||
),
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.ConstructorStart]],
|
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.ConstructorStart]],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -60,9 +53,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
|||||||
type: ChunkType.STRING,
|
type: ChunkType.STRING,
|
||||||
fileType: cfg.fileType,
|
fileType: cfg.fileType,
|
||||||
name: REACT_CHUNK_NAME.ClassRenderPre,
|
name: REACT_CHUNK_NAME.ClassRenderPre,
|
||||||
content: getFuncExprBody(
|
content: generateFunction(lifeCycles[lifeCycleName], { isBlock: true }),
|
||||||
(lifeCycles[lifeCycleName] as IJSExpression).value,
|
|
||||||
),
|
|
||||||
linkAfter: [REACT_CHUNK_NAME.ClassRenderStart],
|
linkAfter: [REACT_CHUNK_NAME.ClassRenderStart],
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -71,15 +62,12 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
|||||||
type: ChunkType.STRING,
|
type: ChunkType.STRING,
|
||||||
fileType: cfg.fileType,
|
fileType: cfg.fileType,
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.InsMethod,
|
name: CLASS_DEFINE_CHUNK_NAME.InsMethod,
|
||||||
content: transformFuncExpr2MethodMember(
|
content: generateFunction(lifeCycles[lifeCycleName], { name: exportName, isMember: true }),
|
||||||
exportName,
|
|
||||||
(lifeCycles[lifeCycleName] as IJSExpression).value,
|
|
||||||
),
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]],
|
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]],
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
next.chunks.push.apply(next.chunks, chunks);
|
next.chunks.push(...chunks);
|
||||||
}
|
}
|
||||||
|
|
||||||
return next;
|
return next;
|
||||||
|
|||||||
@ -1,6 +1,6 @@
|
|||||||
import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
||||||
|
|
||||||
import { transformFuncExpr2MethodMember } from '../../../utils/jsExpression';
|
import { generateFunction } from '../../../utils/jsExpression';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BuilderComponentPlugin,
|
BuilderComponentPlugin,
|
||||||
@ -10,12 +10,11 @@ import {
|
|||||||
ICodeChunk,
|
ICodeChunk,
|
||||||
ICodeStruct,
|
ICodeStruct,
|
||||||
IContainerInfo,
|
IContainerInfo,
|
||||||
IJSExpression,
|
|
||||||
} from '../../../types';
|
} from '../../../types';
|
||||||
|
|
||||||
type PluginConfig = {
|
type PluginConfig = {
|
||||||
fileType: string;
|
fileType: string;
|
||||||
}
|
};
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
||||||
const cfg: PluginConfig = {
|
const cfg: PluginConfig = {
|
||||||
@ -32,18 +31,15 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
|||||||
|
|
||||||
if (ir.methods) {
|
if (ir.methods) {
|
||||||
const methods = ir.methods;
|
const methods = ir.methods;
|
||||||
const chunks = Object.keys(methods).map<ICodeChunk>(methodName => ({
|
const chunks = Object.keys(methods).map<ICodeChunk>((methodName) => ({
|
||||||
type: ChunkType.STRING,
|
type: ChunkType.STRING,
|
||||||
fileType: cfg.fileType,
|
fileType: cfg.fileType,
|
||||||
name: CLASS_DEFINE_CHUNK_NAME.InsMethod,
|
name: CLASS_DEFINE_CHUNK_NAME.InsMethod,
|
||||||
content: transformFuncExpr2MethodMember(
|
content: generateFunction(methods[methodName], { name: methodName, isMember: true }),
|
||||||
methodName,
|
|
||||||
(methods[methodName] as IJSExpression).value,
|
|
||||||
),
|
|
||||||
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]],
|
linkAfter: [...DEFAULT_LINK_AFTER[CLASS_DEFINE_CHUNK_NAME.InsMethod]],
|
||||||
}));
|
}));
|
||||||
|
|
||||||
next.chunks.push.apply(next.chunks, chunks);
|
next.chunks.push(...chunks);
|
||||||
}
|
}
|
||||||
|
|
||||||
return next;
|
return next;
|
||||||
|
|||||||
@ -12,16 +12,18 @@ import { REACT_CHUNK_NAME } from './const';
|
|||||||
import { createReactNodeGenerator } from '../../../utils/nodeToJSX';
|
import { createReactNodeGenerator } from '../../../utils/nodeToJSX';
|
||||||
|
|
||||||
type PluginConfig = {
|
type PluginConfig = {
|
||||||
fileType: string;
|
fileType?: string;
|
||||||
}
|
nodeTypeMapping?: Record<string, string>;
|
||||||
|
};
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) => {
|
||||||
const cfg: PluginConfig = {
|
const cfg = {
|
||||||
fileType: FileType.JSX,
|
fileType: FileType.JSX,
|
||||||
|
nodeTypeMapping: {},
|
||||||
...config,
|
...config,
|
||||||
};
|
};
|
||||||
|
|
||||||
const generator = createReactNodeGenerator();
|
const generator = createReactNodeGenerator({ nodeTypeMapping: cfg.nodeTypeMapping });
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||||
const next: ICodeStruct = {
|
const next: ICodeStruct = {
|
||||||
@ -36,10 +38,7 @@ const pluginFactory: BuilderComponentPluginFactory<PluginConfig> = (config?) =>
|
|||||||
fileType: cfg.fileType,
|
fileType: cfg.fileType,
|
||||||
name: REACT_CHUNK_NAME.ClassRenderJSX,
|
name: REACT_CHUNK_NAME.ClassRenderJSX,
|
||||||
content: `return ${jsxContent};`,
|
content: `return ${jsxContent};`,
|
||||||
linkAfter: [
|
linkAfter: [REACT_CHUNK_NAME.ClassRenderStart, REACT_CHUNK_NAME.ClassRenderPre],
|
||||||
REACT_CHUNK_NAME.ClassRenderStart,
|
|
||||||
REACT_CHUNK_NAME.ClassRenderPre,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return next;
|
return next;
|
||||||
|
|||||||
@ -1,3 +0,0 @@
|
|||||||
export const RECORE_CHUNK_NAME = {
|
|
||||||
|
|
||||||
};
|
|
||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { JSExpression, CompositeValue } from '@ali/lowcode-types';
|
||||||
|
|
||||||
import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
import { CLASS_DEFINE_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -7,15 +9,13 @@ import {
|
|||||||
FileType,
|
FileType,
|
||||||
ICodeStruct,
|
ICodeStruct,
|
||||||
IContainerInfo,
|
IContainerInfo,
|
||||||
IJSExpression,
|
|
||||||
CompositeValue,
|
|
||||||
} from '../../../types';
|
} from '../../../types';
|
||||||
|
|
||||||
import { generateCompositeType, handleStringValueDefault } from '../../../utils/compositeType';
|
import { generateCompositeType } from '../../../utils/compositeType';
|
||||||
import { generateExpression } from '../../../utils/jsExpression';
|
import { generateExpression } from '../../../utils/jsExpression';
|
||||||
|
|
||||||
function packJsExpression(exp: unknown): string {
|
function packJsExpression(exp: unknown): string {
|
||||||
const expression = exp as IJSExpression;
|
const expression = exp as JSExpression;
|
||||||
const funcStr = generateExpression(expression);
|
const funcStr = generateExpression(expression);
|
||||||
return `function() { return (${funcStr}); }`;
|
return `function() { return (${funcStr}); }`;
|
||||||
}
|
}
|
||||||
@ -29,25 +29,15 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|||||||
const ir = next.ir as IContainerInfo;
|
const ir = next.ir as IContainerInfo;
|
||||||
if (ir.dataSource) {
|
if (ir.dataSource) {
|
||||||
const { dataSource } = ir;
|
const { dataSource } = ir;
|
||||||
const {
|
const { list } = dataSource;
|
||||||
list,
|
const attrs: string[] = [];
|
||||||
...rest
|
|
||||||
} = dataSource;
|
|
||||||
|
|
||||||
let attrs: string[] = [];
|
const listProp = generateCompositeType((list as unknown) as CompositeValue, {
|
||||||
|
handlers: {
|
||||||
const extConfigs = Object.keys(rest).map(extConfigName => {
|
expression: packJsExpression,
|
||||||
const value = (rest as Record<string, CompositeValue>)[extConfigName];
|
},
|
||||||
const [isString, valueStr] = generateCompositeType(value);
|
|
||||||
return `${extConfigName}: ${isString ? `'${valueStr}'` : valueStr}`;
|
|
||||||
});
|
});
|
||||||
|
|
||||||
attrs = [...attrs, ...extConfigs];
|
|
||||||
|
|
||||||
const listProp = handleStringValueDefault(generateCompositeType(list as unknown as CompositeValue, {
|
|
||||||
expression: packJsExpression,
|
|
||||||
}));
|
|
||||||
|
|
||||||
attrs.push(`list: ${listProp}`);
|
attrs.push(`list: ${listProp}`);
|
||||||
|
|
||||||
next.chunks.push({
|
next.chunks.push({
|
||||||
|
|||||||
@ -1,31 +1,35 @@
|
|||||||
|
import { NodeSchema } from '@ali/lowcode-types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
BuilderComponentPlugin,
|
BuilderComponentPlugin,
|
||||||
BuilderComponentPluginFactory,
|
BuilderComponentPluginFactory,
|
||||||
ChunkType,
|
ChunkType,
|
||||||
ICodeStruct,
|
ICodeStruct,
|
||||||
IContainerInfo,
|
IContainerInfo,
|
||||||
IComponentNodeItem,
|
INodeGeneratorContext,
|
||||||
CodePiece,
|
CodePiece,
|
||||||
PIECE_TYPE,
|
PIECE_TYPE,
|
||||||
} from '../../../types';
|
} from '../../../types';
|
||||||
import { COMMON_CHUNK_NAME, DEFAULT_LINK_AFTER } from '../../../const/generator';
|
import { COMMON_CHUNK_NAME } from '../../../const/generator';
|
||||||
|
|
||||||
import { createNodeGenerator, generateString } from '../../../utils/nodeToJSX';
|
import { createNodeGenerator, generateString } from '../../../utils/nodeToJSX';
|
||||||
import { generateExpression } from '../../../utils/jsExpression';
|
import { generateExpression } from '../../../utils/jsExpression';
|
||||||
import { generateCompositeType, handleStringValueDefault } from '../../../utils/compositeType';
|
import { generateCompositeType } from '../../../utils/compositeType';
|
||||||
|
|
||||||
const generateGlobalProps = (nodeItem: IComponentNodeItem): CodePiece[] => {
|
const generateGlobalProps = (ctx: INodeGeneratorContext, nodeItem: NodeSchema): CodePiece[] => {
|
||||||
return [{
|
return [
|
||||||
value: `{...globalProps.${nodeItem.componentName}}`,
|
{
|
||||||
type: PIECE_TYPE.ATTR,
|
value: `{...globalProps.${nodeItem.componentName}}`,
|
||||||
}];
|
type: PIECE_TYPE.ATTR,
|
||||||
|
},
|
||||||
|
];
|
||||||
};
|
};
|
||||||
|
|
||||||
const generateCtrlLine = (nodeItem: IComponentNodeItem): CodePiece[] => {
|
const generateCtrlLine = (ctx: INodeGeneratorContext, nodeItem: NodeSchema): CodePiece[] => {
|
||||||
const pieces: CodePiece[] = [];
|
const pieces: CodePiece[] = [];
|
||||||
|
|
||||||
if (nodeItem.loop && nodeItem.loopArgs) {
|
if (nodeItem.loop && nodeItem.loopArgs) {
|
||||||
const loopDataExp = handleStringValueDefault(generateCompositeType(nodeItem.loop));
|
const loopDataExp = generateCompositeType(nodeItem.loop);
|
||||||
pieces.push({
|
pieces.push({
|
||||||
type: PIECE_TYPE.ATTR,
|
type: PIECE_TYPE.ATTR,
|
||||||
value: `x-for={${loopDataExp}}`,
|
value: `x-for={${loopDataExp}}`,
|
||||||
@ -38,7 +42,7 @@ const generateCtrlLine = (nodeItem: IComponentNodeItem): CodePiece[] => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nodeItem.condition) {
|
if (nodeItem.condition) {
|
||||||
const conditionExp = handleStringValueDefault(generateCompositeType(nodeItem.condition));
|
const conditionExp = generateCompositeType(nodeItem.condition);
|
||||||
pieces.push({
|
pieces.push({
|
||||||
type: PIECE_TYPE.ATTR,
|
type: PIECE_TYPE.ATTR,
|
||||||
value: `x-if={${conditionExp}}`,
|
value: `x-if={${conditionExp}}`,
|
||||||
@ -49,13 +53,13 @@ const generateCtrlLine = (nodeItem: IComponentNodeItem): CodePiece[] => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
||||||
const generator = createNodeGenerator({
|
const generator = createNodeGenerator(
|
||||||
string: generateString,
|
{
|
||||||
expression: (input) => [generateExpression(input)],
|
string: generateString,
|
||||||
}, [
|
expression: (input) => [generateExpression(input)],
|
||||||
generateGlobalProps,
|
},
|
||||||
generateCtrlLine,
|
[generateGlobalProps, generateCtrlLine],
|
||||||
]);
|
);
|
||||||
|
|
||||||
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
const plugin: BuilderComponentPlugin = async (pre: ICodeStruct) => {
|
||||||
const next: ICodeStruct = {
|
const next: ICodeStruct = {
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|||||||
|
|
||||||
const ir = next.ir as IProjectInfo;
|
const ir = next.ir as IProjectInfo;
|
||||||
if (ir.constants) {
|
if (ir.constants) {
|
||||||
const [, constantStr] = generateCompositeType(ir.constants);
|
const constantStr = generateCompositeType(ir.constants);
|
||||||
|
|
||||||
next.chunks.push({
|
next.chunks.push({
|
||||||
type: ChunkType.STRING,
|
type: ChunkType.STRING,
|
||||||
@ -26,10 +26,7 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|||||||
content: `
|
content: `
|
||||||
const constantConfig = ${constantStr};
|
const constantConfig = ${constantStr};
|
||||||
`,
|
`,
|
||||||
linkAfter: [
|
linkAfter: [COMMON_CHUNK_NAME.ExternalDepsImport, COMMON_CHUNK_NAME.InternalDepsImport],
|
||||||
COMMON_CHUNK_NAME.ExternalDepsImport,
|
|
||||||
COMMON_CHUNK_NAME.InternalDepsImport,
|
|
||||||
],
|
|
||||||
});
|
});
|
||||||
|
|
||||||
next.chunks.push({
|
next.chunks.push({
|
||||||
|
|||||||
@ -1,3 +1,5 @@
|
|||||||
|
import { PackageJSON } from '@ali/lowcode-types';
|
||||||
|
|
||||||
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
import { COMMON_CHUNK_NAME } from '../../../../../const/generator';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
@ -6,11 +8,10 @@ import {
|
|||||||
ChunkType,
|
ChunkType,
|
||||||
FileType,
|
FileType,
|
||||||
ICodeStruct,
|
ICodeStruct,
|
||||||
IPackageJSON,
|
|
||||||
IProjectInfo,
|
IProjectInfo,
|
||||||
} from '../../../../../types';
|
} from '../../../../../types';
|
||||||
|
|
||||||
interface IIceJsPackageJSON extends IPackageJSON {
|
interface IIceJsPackageJSON extends PackageJSON {
|
||||||
ideMode: {
|
ideMode: {
|
||||||
name: string;
|
name: string;
|
||||||
};
|
};
|
||||||
@ -73,6 +74,8 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|||||||
originTemplate: '@alifd/scaffold-lite-js',
|
originTemplate: '@alifd/scaffold-lite-js',
|
||||||
};
|
};
|
||||||
|
|
||||||
|
ir.packages.forEach((packageInfo) => (packageJson.dependencies[packageInfo.package] = packageInfo.version));
|
||||||
|
|
||||||
next.chunks.push({
|
next.chunks.push({
|
||||||
type: ChunkType.JSON,
|
type: ChunkType.JSON,
|
||||||
fileType: FileType.JSON,
|
fileType: FileType.JSON,
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../types';
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'README',
|
'README',
|
||||||
'md',
|
'md',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,17 +1,17 @@
|
|||||||
import ResultFile from '../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../types';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
return [
|
||||||
'abc',
|
[],
|
||||||
'json',
|
{
|
||||||
`
|
name: 'abc',
|
||||||
|
ext: 'json',
|
||||||
|
content: `
|
||||||
{
|
{
|
||||||
"type": "ice-app",
|
"type": "ice-app",
|
||||||
"builder": "@ali/builder-ice-app"
|
"builder": "@ali/builder-ice-app"
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
);
|
},
|
||||||
|
];
|
||||||
return [[], file];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,11 +1,12 @@
|
|||||||
import ResultFile from '../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../types';
|
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
return [
|
||||||
'build',
|
[],
|
||||||
'json',
|
{
|
||||||
`
|
name: 'build',
|
||||||
|
ext: 'json',
|
||||||
|
content: `
|
||||||
{
|
{
|
||||||
"entry": "src/app.js",
|
"entry": "src/app.js",
|
||||||
"plugins": [
|
"plugins": [
|
||||||
@ -26,8 +27,7 @@ export default function getFile(): [string[], IResultFile] {
|
|||||||
"@ali/build-plugin-ice-def"
|
"@ali/build-plugin-ice-def"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
`,
|
`,
|
||||||
);
|
},
|
||||||
|
];
|
||||||
return [[], file];
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../types';
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'.editorconfig',
|
'.editorconfig',
|
||||||
'',
|
'',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../types';
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'.eslintignore',
|
'.eslintignore',
|
||||||
'',
|
'',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../types';
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'.eslintrc',
|
'.eslintrc',
|
||||||
'js',
|
'js',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../types';
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'.gitignore',
|
'.gitignore',
|
||||||
'',
|
'',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../types';
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'jsconfig',
|
'jsconfig',
|
||||||
'json',
|
'json',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../types';
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'.prettierignore',
|
'.prettierignore',
|
||||||
'',
|
'',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../types';
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'.prettierrc',
|
'.prettierrc',
|
||||||
'js',
|
'js',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../../../../../../types';
|
import { createResultFile } from '../../../../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'index',
|
'index',
|
||||||
'jsx',
|
'jsx',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../../../../../../types';
|
import { createResultFile } from '../../../../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'index',
|
'index',
|
||||||
'module.scss',
|
'module.scss',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../../../../../../types';
|
import { createResultFile } from '../../../../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'index',
|
'index',
|
||||||
'jsx',
|
'jsx',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../../../../../../types';
|
import { createResultFile } from '../../../../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'index',
|
'index',
|
||||||
'module.scss',
|
'module.scss',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../../../../../../types';
|
import { createResultFile } from '../../../../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'index',
|
'index',
|
||||||
'jsx',
|
'jsx',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../../../../types';
|
import { createResultFile } from '../../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'index',
|
'index',
|
||||||
'jsx',
|
'jsx',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../../../../types';
|
import { createResultFile } from '../../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'menuConfig',
|
'menuConfig',
|
||||||
'js',
|
'js',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../types';
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'.stylelintignore',
|
'.stylelintignore',
|
||||||
'',
|
'',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../types';
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'.stylelintrc',
|
'.stylelintrc',
|
||||||
'js',
|
'js',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import ResultFile from '../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../types';
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'tsconfig',
|
'tsconfig',
|
||||||
'json',
|
'json',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import ResultDir from '../../../../../model/ResultDir';
|
import { ResultDir } from '@ali/lowcode-types';
|
||||||
import {
|
import { IProjectTemplate } from '../../../../../types';
|
||||||
IProjectTemplate,
|
|
||||||
IResultDir,
|
import { createResultDir } from '../../../../../utils/resultHelper';
|
||||||
} from '../../../../../types';
|
|
||||||
import { runFileGenerator } from '../../../../../utils/templateHelper';
|
import { runFileGenerator } from '../../../../../utils/templateHelper';
|
||||||
|
|
||||||
import file12 from './files/abc.json';
|
import file12 from './files/abc.json';
|
||||||
@ -68,8 +67,8 @@ const icejsTemplate: IProjectTemplate = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
generateTemplate(): IResultDir {
|
generateTemplate(): ResultDir {
|
||||||
const root = new ResultDir('.');
|
const root = createResultDir('.');
|
||||||
|
|
||||||
runFileGenerator(root, file1);
|
runFileGenerator(root, file1);
|
||||||
runFileGenerator(root, file2);
|
runFileGenerator(root, file2);
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
import ResultFile from '../../../../../../model/ResultFile';
|
export default function getFile(): [string[], ResultFile] {
|
||||||
import { IResultFile } from '../../../../../../types';
|
const file = createResultFile(
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
|
||||||
const file = new ResultFile(
|
|
||||||
'.editorconfig',
|
'.editorconfig',
|
||||||
'',
|
'',
|
||||||
`
|
`
|
||||||
@ -29,4 +28,3 @@ trim_trailing_whitespace = false
|
|||||||
|
|
||||||
return [[], file];
|
return [[], file];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,9 +1,9 @@
|
|||||||
|
|
||||||
import ResultFile from '../../../../../../model/ResultFile';
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultFile } from '../../../../../../types';
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
export default function getFile(): [string[], ResultFile] {
|
||||||
const file = new ResultFile(
|
const file = createResultFile(
|
||||||
'.eslintignore',
|
'.eslintignore',
|
||||||
'',
|
'',
|
||||||
`
|
`
|
||||||
@ -23,4 +23,3 @@ packages/solution
|
|||||||
|
|
||||||
return [[], file];
|
return [[], file];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,9 +1,8 @@
|
|||||||
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
import ResultFile from '../../../../../../model/ResultFile';
|
export default function getFile(): [string[], ResultFile] {
|
||||||
import { IResultFile } from '../../../../../../types';
|
const file = createResultFile(
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
|
||||||
const file = new ResultFile(
|
|
||||||
'.gitignore',
|
'.gitignore',
|
||||||
'',
|
'',
|
||||||
`
|
`
|
||||||
@ -54,4 +53,3 @@ Thumbs.db
|
|||||||
|
|
||||||
return [[], file];
|
return [[], file];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,9 +1,8 @@
|
|||||||
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
import ResultFile from '../../../../../../model/ResultFile';
|
export default function getFile(): [string[], ResultFile] {
|
||||||
import { IResultFile } from '../../../../../../types';
|
const file = createResultFile(
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
|
||||||
const file = new ResultFile(
|
|
||||||
'.prettierrc',
|
'.prettierrc',
|
||||||
'',
|
'',
|
||||||
`
|
`
|
||||||
@ -19,4 +18,3 @@ export default function getFile(): [string[], IResultFile] {
|
|||||||
|
|
||||||
return [[], file];
|
return [[], file];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,9 +1,8 @@
|
|||||||
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
import ResultFile from '../../../../../../model/ResultFile';
|
export default function getFile(): [string[], ResultFile] {
|
||||||
import { IResultFile } from '../../../../../../types';
|
const file = createResultFile(
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
|
||||||
const file = new ResultFile(
|
|
||||||
'README',
|
'README',
|
||||||
'md',
|
'md',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
import ResultFile from '../../../../../../model/ResultFile';
|
export default function getFile(): [string[], ResultFile] {
|
||||||
import { IResultFile } from '../../../../../../types';
|
const file = createResultFile(
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
|
||||||
const file = new ResultFile(
|
|
||||||
'abc',
|
'abc',
|
||||||
'json',
|
'json',
|
||||||
`
|
`
|
||||||
@ -25,4 +24,3 @@ export default function getFile(): [string[], IResultFile] {
|
|||||||
|
|
||||||
return [[], file];
|
return [[], file];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,9 +1,8 @@
|
|||||||
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
import ResultFile from '../../../../../../model/ResultFile';
|
export default function getFile(): [string[], ResultFile] {
|
||||||
import { IResultFile } from '../../../../../../types';
|
const file = createResultFile(
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
|
||||||
const file = new ResultFile(
|
|
||||||
'build',
|
'build',
|
||||||
'json',
|
'json',
|
||||||
`
|
`
|
||||||
@ -29,4 +28,3 @@ export default function getFile(): [string[], IResultFile] {
|
|||||||
|
|
||||||
return [[], file];
|
return [[], file];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,9 +1,8 @@
|
|||||||
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
import ResultFile from '../../../../../../model/ResultFile';
|
export default function getFile(): [string[], ResultFile] {
|
||||||
import { IResultFile } from '../../../../../../types';
|
const file = createResultFile(
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
|
||||||
const file = new ResultFile(
|
|
||||||
'package',
|
'package',
|
||||||
'json',
|
'json',
|
||||||
`
|
`
|
||||||
@ -63,4 +62,3 @@ export default function getFile(): [string[], IResultFile] {
|
|||||||
|
|
||||||
return [[], file];
|
return [[], file];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,9 +1,8 @@
|
|||||||
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
import ResultFile from '../../../../../../../model/ResultFile';
|
export default function getFile(): [string[], ResultFile] {
|
||||||
import { IResultFile } from '../../../../../../../types';
|
const file = createResultFile(
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
|
||||||
const file = new ResultFile(
|
|
||||||
'index',
|
'index',
|
||||||
'html',
|
'html',
|
||||||
`
|
`
|
||||||
@ -48,4 +47,3 @@ export default function getFile(): [string[], IResultFile] {
|
|||||||
|
|
||||||
return [['public'], file];
|
return [['public'], file];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,9 +1,8 @@
|
|||||||
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
import ResultFile from '../../../../../../../../model/ResultFile';
|
export default function getFile(): [string[], ResultFile] {
|
||||||
import { IResultFile } from '../../../../../../../../types';
|
const file = createResultFile(
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
|
||||||
const file = new ResultFile(
|
|
||||||
'app',
|
'app',
|
||||||
'ts',
|
'ts',
|
||||||
`
|
`
|
||||||
@ -72,6 +71,5 @@ export default {
|
|||||||
`,
|
`,
|
||||||
);
|
);
|
||||||
|
|
||||||
return [['src','config'], file];
|
return [['src', 'config'], file];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,9 +1,8 @@
|
|||||||
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
import ResultFile from '../../../../../../../../model/ResultFile';
|
export default function getFile(): [string[], ResultFile] {
|
||||||
import { IResultFile } from '../../../../../../../../types';
|
const file = createResultFile(
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
|
||||||
const file = new ResultFile(
|
|
||||||
'components',
|
'components',
|
||||||
'ts',
|
'ts',
|
||||||
`
|
`
|
||||||
@ -38,6 +37,5 @@ export default componentsMap;
|
|||||||
`,
|
`,
|
||||||
);
|
);
|
||||||
|
|
||||||
return [['src','config'], file];
|
return [['src', 'config'], file];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,9 +1,8 @@
|
|||||||
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
import ResultFile from '../../../../../../../../model/ResultFile';
|
export default function getFile(): [string[], ResultFile] {
|
||||||
import { IResultFile } from '../../../../../../../../types';
|
const file = createResultFile(
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
|
||||||
const file = new ResultFile(
|
|
||||||
'utils',
|
'utils',
|
||||||
'ts',
|
'ts',
|
||||||
`
|
`
|
||||||
@ -24,6 +23,5 @@ export default {
|
|||||||
`,
|
`,
|
||||||
);
|
);
|
||||||
|
|
||||||
return [['src','config'], file];
|
return [['src', 'config'], file];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,9 +1,8 @@
|
|||||||
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
import ResultFile from '../../../../../../../model/ResultFile';
|
export default function getFile(): [string[], ResultFile] {
|
||||||
import { IResultFile } from '../../../../../../../types';
|
const file = createResultFile(
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
|
||||||
const file = new ResultFile(
|
|
||||||
'index',
|
'index',
|
||||||
'ts',
|
'ts',
|
||||||
`
|
`
|
||||||
@ -98,4 +97,3 @@ app.run();
|
|||||||
|
|
||||||
return [['src'], file];
|
return [['src'], file];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,9 +1,8 @@
|
|||||||
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
import ResultFile from '../../../../../../../model/ResultFile';
|
export default function getFile(): [string[], ResultFile] {
|
||||||
import { IResultFile } from '../../../../../../../types';
|
const file = createResultFile(
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
|
||||||
const file = new ResultFile(
|
|
||||||
'router',
|
'router',
|
||||||
'ts',
|
'ts',
|
||||||
`
|
`
|
||||||
|
|||||||
@ -1,9 +1,8 @@
|
|||||||
|
import { ResultFile } from '@ali/lowcode-types';
|
||||||
|
import { createResultFile } from '../../../../../../utils/resultHelper';
|
||||||
|
|
||||||
import ResultFile from '../../../../../../model/ResultFile';
|
export default function getFile(): [string[], ResultFile] {
|
||||||
import { IResultFile } from '../../../../../../types';
|
const file = createResultFile(
|
||||||
|
|
||||||
export default function getFile(): [string[], IResultFile] {
|
|
||||||
const file = new ResultFile(
|
|
||||||
'tsconfig',
|
'tsconfig',
|
||||||
'json',
|
'json',
|
||||||
`
|
`
|
||||||
@ -50,4 +49,3 @@ export default function getFile(): [string[], IResultFile] {
|
|||||||
|
|
||||||
return [[], file];
|
return [[], file];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1,8 +1,6 @@
|
|||||||
import ResultDir from '../../../../../model/ResultDir';
|
import { ResultDir } from '@ali/lowcode-types';
|
||||||
import {
|
import { IProjectTemplate } from '../../../../../types';
|
||||||
IProjectTemplate,
|
import { createResultDir } from '../../../../../utils/resultHelper';
|
||||||
IResultDir,
|
|
||||||
} from '../../../../../types';
|
|
||||||
import { runFileGenerator } from '../../../../../utils/templateHelper';
|
import { runFileGenerator } from '../../../../../utils/templateHelper';
|
||||||
|
|
||||||
import file1 from './files/abc.json';
|
import file1 from './files/abc.json';
|
||||||
@ -28,8 +26,8 @@ const icejsTemplate: IProjectTemplate = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
generateTemplate(): IResultDir {
|
generateTemplate(): ResultDir {
|
||||||
const root = new ResultDir('.');
|
const root = createResultDir('.');
|
||||||
|
|
||||||
runFileGenerator(root, file1);
|
runFileGenerator(root, file1);
|
||||||
runFileGenerator(root, file2);
|
runFileGenerator(root, file2);
|
||||||
|
|||||||
@ -17,7 +17,7 @@ const pluginFactory: BuilderComponentPluginFactory<unknown> = () => {
|
|||||||
|
|
||||||
const ir = next.ir as IProjectInfo;
|
const ir = next.ir as IProjectInfo;
|
||||||
if (ir.i18n) {
|
if (ir.i18n) {
|
||||||
const [, i18nStr] = generateCompositeType(ir.i18n);
|
const i18nStr = generateCompositeType(ir.i18n);
|
||||||
|
|
||||||
next.chunks.push({
|
next.chunks.push({
|
||||||
type: ChunkType.STRING,
|
type: ChunkType.STRING,
|
||||||
|
|||||||
@ -1,10 +1,5 @@
|
|||||||
import {
|
import { ResultDir } from '@ali/lowcode-types';
|
||||||
IResultDir,
|
import { PublisherFactory, IPublisher, IPublisherFactoryParams, PublisherError } from '../../types';
|
||||||
PublisherFactory,
|
|
||||||
IPublisher,
|
|
||||||
IPublisherFactoryParams,
|
|
||||||
PublisherError,
|
|
||||||
} from '../../types';
|
|
||||||
import { writeFolder } from './utils';
|
import { writeFolder } from './utils';
|
||||||
|
|
||||||
export interface IDiskFactoryParams extends IPublisherFactoryParams {
|
export interface IDiskFactoryParams extends IPublisherFactoryParams {
|
||||||
@ -18,19 +13,18 @@ export interface IDiskPublisher extends IPublisher<IDiskFactoryParams, string> {
|
|||||||
setOutputPath: (path: string) => void;
|
setOutputPath: (path: string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createDiskPublisher: PublisherFactory<
|
export const createDiskPublisher: PublisherFactory<IDiskFactoryParams, IDiskPublisher> = (
|
||||||
IDiskFactoryParams,
|
params: IDiskFactoryParams = {},
|
||||||
IDiskPublisher
|
): IDiskPublisher => {
|
||||||
> = (params: IDiskFactoryParams = {}): IDiskPublisher => {
|
|
||||||
let { project, outputPath = './' } = params;
|
let { project, outputPath = './' } = params;
|
||||||
|
|
||||||
const getProject = (): IResultDir => {
|
const getProject = (): ResultDir => {
|
||||||
if (!project) {
|
if (!project) {
|
||||||
throw new PublisherError('Missing Project');
|
throw new PublisherError('Missing Project');
|
||||||
}
|
}
|
||||||
return project;
|
return project;
|
||||||
};
|
};
|
||||||
const setProject = (projectToSet: IResultDir): void => {
|
const setProject = (projectToSet: ResultDir): void => {
|
||||||
project = projectToSet;
|
project = projectToSet;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -49,19 +43,14 @@ export const createDiskPublisher: PublisherFactory<
|
|||||||
|
|
||||||
const projectOutputPath = options.outputPath || outputPath;
|
const projectOutputPath = options.outputPath || outputPath;
|
||||||
const overrideProjectSlug = options.projectSlug || params.projectSlug;
|
const overrideProjectSlug = options.projectSlug || params.projectSlug;
|
||||||
const createProjectFolder =
|
const createProjectFolder = options.createProjectFolder || params.createProjectFolder;
|
||||||
options.createProjectFolder || params.createProjectFolder;
|
|
||||||
|
|
||||||
if (overrideProjectSlug) {
|
if (overrideProjectSlug) {
|
||||||
projectToPublish.name = overrideProjectSlug;
|
projectToPublish.name = overrideProjectSlug;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await writeFolder(
|
await writeFolder(projectToPublish, projectOutputPath, createProjectFolder);
|
||||||
projectToPublish,
|
|
||||||
projectOutputPath,
|
|
||||||
createProjectFolder,
|
|
||||||
);
|
|
||||||
return { success: true, payload: projectOutputPath };
|
return { success: true, payload: projectOutputPath };
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new PublisherError(error);
|
throw new PublisherError(error);
|
||||||
|
|||||||
@ -1,36 +1,27 @@
|
|||||||
import { existsSync, mkdir, writeFile } from 'fs';
|
import { existsSync, mkdir, writeFile } from 'fs';
|
||||||
import { join } from 'path';
|
import { join } from 'path';
|
||||||
|
import { ResultDir, ResultFile } from '@ali/lowcode-types';
|
||||||
import { IResultDir, IResultFile } from '../../types';
|
|
||||||
|
|
||||||
export const writeFolder = async (
|
export const writeFolder = async (
|
||||||
folder: IResultDir,
|
folder: ResultDir,
|
||||||
currentPath: string,
|
currentPath: string,
|
||||||
createProjectFolder = true,
|
createProjectFolder = true,
|
||||||
): Promise<void> => {
|
): Promise<void> => {
|
||||||
const { name, files, dirs } = folder;
|
const { name, files, dirs } = folder;
|
||||||
|
|
||||||
const folderPath = createProjectFolder
|
const folderPath = createProjectFolder ? join(currentPath, name) : currentPath;
|
||||||
? join(currentPath, name)
|
|
||||||
: currentPath;
|
|
||||||
|
|
||||||
if (!existsSync(folderPath)) {
|
if (!existsSync(folderPath)) {
|
||||||
await createDirectory(folderPath);
|
await createDirectory(folderPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
const promises = [
|
const promises = [writeFilesToFolder(folderPath, files), writeSubFoldersToFolder(folderPath, dirs)];
|
||||||
writeFilesToFolder(folderPath, files),
|
|
||||||
writeSubFoldersToFolder(folderPath, dirs),
|
|
||||||
];
|
|
||||||
|
|
||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
};
|
};
|
||||||
|
|
||||||
const writeFilesToFolder = async (
|
const writeFilesToFolder = async (folderPath: string, files: ResultFile[]): Promise<void> => {
|
||||||
folderPath: string,
|
const promises = files.map((file) => {
|
||||||
files: IResultFile[],
|
|
||||||
): Promise<void> => {
|
|
||||||
const promises = files.map(file => {
|
|
||||||
const fileName = file.ext ? `${file.name}.${file.ext}` : file.name;
|
const fileName = file.ext ? `${file.name}.${file.ext}` : file.name;
|
||||||
const filePath = join(folderPath, fileName);
|
const filePath = join(folderPath, fileName);
|
||||||
return writeContentToFile(filePath, file.content);
|
return writeContentToFile(filePath, file.content);
|
||||||
@ -39,11 +30,8 @@ const writeFilesToFolder = async (
|
|||||||
await Promise.all(promises);
|
await Promise.all(promises);
|
||||||
};
|
};
|
||||||
|
|
||||||
const writeSubFoldersToFolder = async (
|
const writeSubFoldersToFolder = async (folderPath: string, subFolders: ResultDir[]): Promise<void> => {
|
||||||
folderPath: string,
|
const promises = subFolders.map((subFolder) => {
|
||||||
subFolders: IResultDir[],
|
|
||||||
): Promise<void> => {
|
|
||||||
const promises = subFolders.map(subFolder => {
|
|
||||||
return writeFolder(subFolder, folderPath);
|
return writeFolder(subFolder, folderPath);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -52,19 +40,15 @@ const writeSubFoldersToFolder = async (
|
|||||||
|
|
||||||
const createDirectory = (pathToDir: string): Promise<void> => {
|
const createDirectory = (pathToDir: string): Promise<void> => {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
mkdir(pathToDir, { recursive: true }, err => {
|
mkdir(pathToDir, { recursive: true }, (err) => {
|
||||||
err ? reject(err) : resolve();
|
err ? reject(err) : resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
const writeContentToFile = (
|
const writeContentToFile = (filePath: string, fileContent: string, encoding = 'utf8'): Promise<void> => {
|
||||||
filePath: string,
|
|
||||||
fileContent: string,
|
|
||||||
encoding: string = 'utf8',
|
|
||||||
): Promise<void> => {
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
writeFile(filePath, fileContent, encoding, err => {
|
writeFile(filePath, fileContent, encoding, (err) => {
|
||||||
err ? reject(err) : resolve();
|
err ? reject(err) : resolve();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@ -1,11 +1,6 @@
|
|||||||
import {
|
import { ResultDir } from '@ali/lowcode-types';
|
||||||
IResultDir,
|
import { PublisherFactory, IPublisher, IPublisherFactoryParams, PublisherError } from '../../types';
|
||||||
PublisherFactory,
|
import { isNodeProcess, writeZipToDisk, generateProjectZip } from './utils';
|
||||||
IPublisher,
|
|
||||||
IPublisherFactoryParams,
|
|
||||||
PublisherError,
|
|
||||||
} from '../../types';
|
|
||||||
import { isNodeProcess, writeZipToDisk, generateProjectZip } from './utils'
|
|
||||||
|
|
||||||
// export type ZipBuffer = Buffer | Blob;
|
// export type ZipBuffer = Buffer | Blob;
|
||||||
export type ZipBuffer = Buffer;
|
export type ZipBuffer = Buffer;
|
||||||
@ -28,14 +23,14 @@ export const createZipPublisher: PublisherFactory<ZipFactoryParams, ZipPublisher
|
|||||||
let { project, outputPath } = params;
|
let { project, outputPath } = params;
|
||||||
|
|
||||||
const getProject = () => project;
|
const getProject = () => project;
|
||||||
const setProject = (projectToSet: IResultDir) => {
|
const setProject = (projectToSet: ResultDir) => {
|
||||||
project = projectToSet;
|
project = projectToSet;
|
||||||
}
|
};
|
||||||
|
|
||||||
const getOutputPath = () => outputPath;
|
const getOutputPath = () => outputPath;
|
||||||
const setOutputPath = (path: string) => {
|
const setOutputPath = (path: string) => {
|
||||||
outputPath = path;
|
outputPath = path;
|
||||||
}
|
};
|
||||||
|
|
||||||
const publish = async (options: ZipFactoryParams = {}) => {
|
const publish = async (options: ZipFactoryParams = {}) => {
|
||||||
const projectToPublish = options.project || project;
|
const projectToPublish = options.project || project;
|
||||||
@ -57,7 +52,7 @@ export const createZipPublisher: PublisherFactory<ZipFactoryParams, ZipPublisher
|
|||||||
} catch (error) {
|
} catch (error) {
|
||||||
throw new PublisherError(error);
|
throw new PublisherError(error);
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
publish,
|
publish,
|
||||||
@ -66,4 +61,4 @@ export const createZipPublisher: PublisherFactory<ZipFactoryParams, ZipPublisher
|
|||||||
getOutputPath,
|
getOutputPath,
|
||||||
setOutputPath,
|
setOutputPath,
|
||||||
};
|
};
|
||||||
}
|
};
|
||||||
|
|||||||
@ -1,21 +1,17 @@
|
|||||||
import JSZip from 'jszip';
|
import JSZip from 'jszip';
|
||||||
import { IResultDir, IResultFile } from '../../types';
|
import { ResultDir, ResultFile } from '@ali/lowcode-types';
|
||||||
import { ZipBuffer } from './index';
|
import { ZipBuffer } from './index';
|
||||||
|
|
||||||
export const isNodeProcess = (): boolean => {
|
export const isNodeProcess = (): boolean => {
|
||||||
return (
|
return (
|
||||||
typeof process === 'object' &&
|
typeof process === 'object' && typeof process.versions === 'object' && typeof process.versions.node !== 'undefined'
|
||||||
typeof process.versions === 'object' &&
|
|
||||||
typeof process.versions.node !== 'undefined'
|
|
||||||
);
|
);
|
||||||
}
|
};
|
||||||
|
|
||||||
export const writeZipToDisk = (
|
export const writeZipToDisk = (zipFolderPath: string, content: ZipBuffer, zipName: string): void => {
|
||||||
zipFolderPath: string,
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
content: ZipBuffer,
|
|
||||||
zipName: string,
|
|
||||||
): void => {
|
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
|
|
||||||
if (!fs.existsSync(zipFolderPath)) {
|
if (!fs.existsSync(zipFolderPath)) {
|
||||||
@ -27,34 +23,30 @@ export const writeZipToDisk = (
|
|||||||
const writeStream = fs.createWriteStream(zipPath);
|
const writeStream = fs.createWriteStream(zipPath);
|
||||||
writeStream.write(content);
|
writeStream.write(content);
|
||||||
writeStream.end();
|
writeStream.end();
|
||||||
}
|
};
|
||||||
|
|
||||||
export const generateProjectZip = async (project: IResultDir): Promise<ZipBuffer> => {
|
export const generateProjectZip = async (project: ResultDir): Promise<ZipBuffer> => {
|
||||||
let zip = new JSZip();
|
let zip = new JSZip();
|
||||||
zip = writeFolderToZip(project, zip, true);
|
zip = writeFolderToZip(project, zip, true);
|
||||||
// const zipType = isNodeProcess() ? 'nodebuffer' : 'blob';
|
// const zipType = isNodeProcess() ? 'nodebuffer' : 'blob';
|
||||||
const zipType = 'nodebuffer'; // 目前先只支持 node 调用
|
const zipType = 'nodebuffer'; // 目前先只支持 node 调用
|
||||||
return zip.generateAsync({ type: zipType });
|
return zip.generateAsync({ type: zipType });
|
||||||
}
|
};
|
||||||
|
|
||||||
const writeFolderToZip = (
|
const writeFolderToZip = (folder: ResultDir, parentFolder: JSZip, ignoreFolder = false) => {
|
||||||
folder: IResultDir,
|
|
||||||
parentFolder: JSZip,
|
|
||||||
ignoreFolder: boolean = false,
|
|
||||||
) => {
|
|
||||||
const zipFolder = ignoreFolder ? parentFolder : parentFolder.folder(folder.name);
|
const zipFolder = ignoreFolder ? parentFolder : parentFolder.folder(folder.name);
|
||||||
if (zipFolder !== null) {
|
if (zipFolder !== null) {
|
||||||
folder.files.forEach((file: IResultFile) => {
|
folder.files.forEach((file: ResultFile) => {
|
||||||
// const options = file.contentEncoding === 'base64' ? { base64: true } : {};
|
// const options = file.contentEncoding === 'base64' ? { base64: true } : {};
|
||||||
const options = {};
|
const options = {};
|
||||||
const fileName = file.ext ? `${file.name}.${file.ext}` : file.name;
|
const fileName = file.ext ? `${file.name}.${file.ext}` : file.name;
|
||||||
zipFolder.file(fileName, file.content, options);
|
zipFolder.file(fileName, file.content, options);
|
||||||
});
|
});
|
||||||
|
|
||||||
folder.dirs.forEach((subFolder: IResultDir) => {
|
folder.dirs.forEach((subFolder: ResultDir) => {
|
||||||
writeFolderToZip(subFolder, zipFolder);
|
writeFolderToZip(subFolder, zipFolder);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
return parentFolder;
|
return parentFolder;
|
||||||
}
|
};
|
||||||
|
|||||||
@ -5,7 +5,7 @@ import { createProjectBuilder } from '../generator/ProjectBuilder';
|
|||||||
import esmodule from '../plugins/common/esmodule';
|
import esmodule from '../plugins/common/esmodule';
|
||||||
import containerClass from '../plugins/component/react/containerClass';
|
import containerClass from '../plugins/component/react/containerClass';
|
||||||
import containerInitState from '../plugins/component/react/containerInitState';
|
import containerInitState from '../plugins/component/react/containerInitState';
|
||||||
import containerInjectUtils from '../plugins/component/react/containerInjectUtils';
|
// import containerInjectUtils from '../plugins/component/react/containerInjectUtils';
|
||||||
import containerLifeCycle from '../plugins/component/react/containerLifeCycle';
|
import containerLifeCycle from '../plugins/component/react/containerLifeCycle';
|
||||||
import containerMethod from '../plugins/component/react/containerMethod';
|
import containerMethod from '../plugins/component/react/containerMethod';
|
||||||
import jsx from '../plugins/component/react/jsx';
|
import jsx from '../plugins/component/react/jsx';
|
||||||
@ -29,11 +29,18 @@ export default function createIceJsProjectBuilder(): IProjectBuilder {
|
|||||||
fileType: 'jsx',
|
fileType: 'jsx',
|
||||||
}),
|
}),
|
||||||
containerClass(),
|
containerClass(),
|
||||||
containerInjectUtils(),
|
// containerInjectUtils(),
|
||||||
containerInitState(),
|
containerInitState(),
|
||||||
containerLifeCycle(),
|
containerLifeCycle(),
|
||||||
containerMethod(),
|
containerMethod(),
|
||||||
jsx(),
|
jsx({
|
||||||
|
nodeTypeMapping: {
|
||||||
|
Div: 'div',
|
||||||
|
Component: 'div',
|
||||||
|
Page: 'div',
|
||||||
|
Block: 'div',
|
||||||
|
},
|
||||||
|
}),
|
||||||
css(),
|
css(),
|
||||||
],
|
],
|
||||||
pages: [
|
pages: [
|
||||||
@ -42,11 +49,19 @@ export default function createIceJsProjectBuilder(): IProjectBuilder {
|
|||||||
fileType: 'jsx',
|
fileType: 'jsx',
|
||||||
}),
|
}),
|
||||||
containerClass(),
|
containerClass(),
|
||||||
containerInjectUtils(),
|
// containerInjectUtils(),
|
||||||
containerInitState(),
|
containerInitState(),
|
||||||
containerLifeCycle(),
|
containerLifeCycle(),
|
||||||
containerMethod(),
|
containerMethod(),
|
||||||
jsx(),
|
jsx({
|
||||||
|
nodeTypeMapping: {
|
||||||
|
Div: 'div',
|
||||||
|
Component: 'div',
|
||||||
|
Page: 'div',
|
||||||
|
Block: 'div',
|
||||||
|
// Box: 'div',
|
||||||
|
},
|
||||||
|
}),
|
||||||
css(),
|
css(),
|
||||||
],
|
],
|
||||||
router: [esmodule(), icejs.plugins.router()],
|
router: [esmodule(), icejs.plugins.router()],
|
||||||
@ -58,6 +73,6 @@ export default function createIceJsProjectBuilder(): IProjectBuilder {
|
|||||||
htmlEntry: [icejs.plugins.entryHtml()],
|
htmlEntry: [icejs.plugins.entryHtml()],
|
||||||
packageJSON: [icejs.plugins.packageJSON()],
|
packageJSON: [icejs.plugins.packageJSON()],
|
||||||
},
|
},
|
||||||
postProcessors: [prettier()],
|
postProcessors: [prettier()], // prettier()
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,6 @@
|
|||||||
import {
|
import { ResultDir, ResultFile, NodeData, NodeSchema, ProjectSchema, JSExpression } from '@ali/lowcode-types';
|
||||||
IBasicSchema,
|
|
||||||
IParseResult,
|
import { IParseResult } from './index';
|
||||||
IProjectSchema,
|
|
||||||
IResultDir,
|
|
||||||
IResultFile,
|
|
||||||
IComponentNodeItem,
|
|
||||||
IJSExpression,
|
|
||||||
} from './index';
|
|
||||||
|
|
||||||
export enum FileType {
|
export enum FileType {
|
||||||
CSS = 'css',
|
CSS = 'css',
|
||||||
@ -53,17 +47,12 @@ export interface ICodeStruct extends IBaseCodeStruct {
|
|||||||
chunks: ICodeChunk[];
|
chunks: ICodeChunk[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type BuilderComponentPlugin = (
|
export type BuilderComponentPlugin = (initStruct: ICodeStruct) => Promise<ICodeStruct>;
|
||||||
initStruct: ICodeStruct,
|
|
||||||
) => Promise<ICodeStruct>;
|
|
||||||
|
|
||||||
export type BuilderComponentPluginFactory<T> = (config?: T) => BuilderComponentPlugin;
|
export type BuilderComponentPluginFactory<T> = (config?: T) => BuilderComponentPlugin;
|
||||||
|
|
||||||
export interface IChunkBuilder {
|
export interface IChunkBuilder {
|
||||||
run(
|
run(ir: any, initialStructure?: ICodeStruct): Promise<{ chunks: ICodeChunk[][] }>;
|
||||||
ir: any,
|
|
||||||
initialStructure?: ICodeStruct,
|
|
||||||
): Promise<{ chunks: ICodeChunk[][] }>;
|
|
||||||
getPlugins(): BuilderComponentPlugin[];
|
getPlugins(): BuilderComponentPlugin[];
|
||||||
addPlugin(plugin: BuilderComponentPlugin): void;
|
addPlugin(plugin: BuilderComponentPlugin): void;
|
||||||
}
|
}
|
||||||
@ -74,16 +63,13 @@ export interface ICodeBuilder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface ICompiledModule {
|
export interface ICompiledModule {
|
||||||
files: IResultFile[];
|
files: ResultFile[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IModuleBuilder {
|
export interface IModuleBuilder {
|
||||||
generateModule(input: unknown): Promise<ICompiledModule>;
|
generateModule(input: unknown): Promise<ICompiledModule>;
|
||||||
generateModuleCode(schema: IBasicSchema | string): Promise<IResultDir>;
|
generateModuleCode(schema: ProjectSchema | string): Promise<ResultDir>;
|
||||||
linkCodeChunks(
|
linkCodeChunks(chunks: Record<string, ICodeChunk[]>, fileName: string): ResultFile[];
|
||||||
chunks: Record<string, ICodeChunk[]>,
|
|
||||||
fileName: string,
|
|
||||||
): IResultFile[];
|
|
||||||
addPlugin(plugin: BuilderComponentPlugin): void;
|
addPlugin(plugin: BuilderComponentPlugin): void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -97,21 +83,21 @@ export interface ICodeGenerator {
|
|||||||
/**
|
/**
|
||||||
* 出码接口,把 Schema 转换成代码文件系统描述
|
* 出码接口,把 Schema 转换成代码文件系统描述
|
||||||
*
|
*
|
||||||
* @param {(IBasicSchema)} schema 传入的 Schema
|
* @param {(ProjectSchema)} schema 传入的 Schema
|
||||||
* @returns {IResultDir}
|
* @returns {ResultDir}
|
||||||
* @memberof ICodeGenerator
|
* @memberof ICodeGenerator
|
||||||
*/
|
*/
|
||||||
toCode(schema: IBasicSchema): Promise<IResultDir>;
|
toCode(schema: ProjectSchema): Promise<ResultDir>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ISchemaParser {
|
export interface ISchemaParser {
|
||||||
validate(schema: IBasicSchema): boolean;
|
validate(schema: ProjectSchema): boolean;
|
||||||
parse(schema: IBasicSchema | string): IParseResult;
|
parse(schema: ProjectSchema | string): IParseResult;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IProjectTemplate {
|
export interface IProjectTemplate {
|
||||||
slots: Record<string, IProjectSlot>;
|
slots: Record<string, IProjectSlot>;
|
||||||
generateTemplate(): IResultDir;
|
generateTemplate(): ResultDir;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IProjectSlot {
|
export interface IProjectSlot {
|
||||||
@ -119,25 +105,12 @@ export interface IProjectSlot {
|
|||||||
fileName?: string;
|
fileName?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
// export interface IProjectSlots {
|
|
||||||
// components: IProjectSlot;
|
|
||||||
// pages: IProjectSlot;
|
|
||||||
// router: IProjectSlot;
|
|
||||||
// entry: IProjectSlot;
|
|
||||||
// constants?: IProjectSlot;
|
|
||||||
// utils?: IProjectSlot;
|
|
||||||
// i18n?: IProjectSlot;
|
|
||||||
// globalStyle: IProjectSlot;
|
|
||||||
// htmlEntry: IProjectSlot;
|
|
||||||
// packageJSON: IProjectSlot;
|
|
||||||
// }
|
|
||||||
|
|
||||||
export interface IProjectPlugins {
|
export interface IProjectPlugins {
|
||||||
[slotName: string]: BuilderComponentPlugin[];
|
[slotName: string]: BuilderComponentPlugin[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IProjectBuilder {
|
export interface IProjectBuilder {
|
||||||
generateProject(schema: IProjectSchema | string): Promise<IResultDir>;
|
generateProject(schema: ProjectSchema | string): Promise<ResultDir>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PostProcessorFactory<T> = (config?: T) => PostProcessor;
|
export type PostProcessorFactory<T> = (config?: T) => PostProcessor;
|
||||||
@ -154,7 +127,7 @@ export enum PIECE_TYPE {
|
|||||||
ATTR = 'NodeCodePieceAttr',
|
ATTR = 'NodeCodePieceAttr',
|
||||||
CHILDREN = 'NodeCodePieceChildren',
|
CHILDREN = 'NodeCodePieceChildren',
|
||||||
AFTER = 'NodeCodePieceAfter',
|
AFTER = 'NodeCodePieceAfter',
|
||||||
};
|
}
|
||||||
|
|
||||||
export interface CodePiece {
|
export interface CodePiece {
|
||||||
value: string;
|
value: string;
|
||||||
@ -163,15 +136,41 @@ export interface CodePiece {
|
|||||||
|
|
||||||
export interface HandlerSet<T> {
|
export interface HandlerSet<T> {
|
||||||
string?: (input: string) => T[];
|
string?: (input: string) => T[];
|
||||||
expression?: (input: IJSExpression) => T[];
|
expression?: (input: JSExpression) => T[];
|
||||||
node?: (input: IComponentNodeItem) => T[];
|
node?: (input: NodeSchema) => T[];
|
||||||
common?: (input: unknown) => T[];
|
common?: (input: unknown) => T[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ExtGeneratorPlugin = (nodeItem: IComponentNodeItem) => CodePiece[];
|
export type ExtGeneratorPlugin = (ctx: INodeGeneratorContext, nodeItem: NodeSchema) => CodePiece[];
|
||||||
|
|
||||||
// export interface InteratorScope {
|
export interface INodeGeneratorConfig {
|
||||||
// [$item: string]: string; // $item 默认取值 "item"
|
nodeTypeMapping?: Record<string, string>;
|
||||||
// [$index: string]: string | number; // $index 默认取值 "index"
|
}
|
||||||
// __proto__: BlockInstance;
|
|
||||||
// }
|
export type NodeGenerator = (nodeItem: NodeData) => string;
|
||||||
|
|
||||||
|
export interface INodeGeneratorContext {
|
||||||
|
generator: NodeGenerator;
|
||||||
|
}
|
||||||
|
|
||||||
|
export type CompositeValueCustomHandler = (data: unknown) => string;
|
||||||
|
export type CompositeTypeContainerHandler = (value: string) => string;
|
||||||
|
export interface CompositeValueCustomHandlerSet {
|
||||||
|
boolean?: CompositeValueCustomHandler;
|
||||||
|
number?: CompositeValueCustomHandler;
|
||||||
|
string?: CompositeValueCustomHandler;
|
||||||
|
array?: CompositeValueCustomHandler;
|
||||||
|
object?: CompositeValueCustomHandler;
|
||||||
|
expression?: CompositeValueCustomHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CompositeTypeContainerHandlerSet {
|
||||||
|
default?: CompositeTypeContainerHandler;
|
||||||
|
string?: CompositeValueCustomHandler;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CompositeValueGeneratorOptions {
|
||||||
|
handlers?: CompositeValueCustomHandlerSet;
|
||||||
|
containerHandlers?: CompositeTypeContainerHandlerSet;
|
||||||
|
nodeGenerator?: NodeGenerator;
|
||||||
|
}
|
||||||
|
|||||||
@ -1,13 +1,15 @@
|
|||||||
|
export interface INpmPackage {
|
||||||
|
package: string; // 组件包的名称
|
||||||
|
version: string; // 组件包的版本
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 外部依赖描述
|
* 外部依赖描述
|
||||||
*
|
*
|
||||||
* @export
|
* @export
|
||||||
* @interface IExternalDependency
|
* @interface IExternalDependency
|
||||||
*/
|
*/
|
||||||
export interface IExternalDependency extends IDependency {
|
export interface IExternalDependency extends INpmPackage, IDependency {}
|
||||||
package: string; // 组件包的名称
|
|
||||||
version: string; // 组件包的版本
|
|
||||||
}
|
|
||||||
|
|
||||||
export enum InternalDependencyType {
|
export enum InternalDependencyType {
|
||||||
PAGE = 'pages',
|
PAGE = 'pages',
|
||||||
@ -32,5 +34,5 @@ export interface IDependency {
|
|||||||
subName?: string; // 下标子组件名称
|
subName?: string; // 下标子组件名称
|
||||||
main?: string; // 包导出组件入口文件路径 /lib/input
|
main?: string; // 包导出组件入口文件路径 /lib/input
|
||||||
dependencyType?: DependencyType; // 依赖类型 内/外
|
dependencyType?: DependencyType; // 依赖类型 内/外
|
||||||
importName?: string; // 导入后名称
|
componentName?: string; // 导入后名称
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
/* eslint-disable @typescript-eslint/no-useless-constructor */
|
||||||
export class CodeGeneratorError extends Error {
|
export class CodeGeneratorError extends Error {
|
||||||
constructor(message: string) {
|
constructor(message: string) {
|
||||||
super(message);
|
super(message);
|
||||||
@ -5,21 +6,18 @@ export class CodeGeneratorError extends Error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// tslint:disable-next-line: max-classes-per-file
|
|
||||||
export class ComponentValidationError extends CodeGeneratorError {
|
export class ComponentValidationError extends CodeGeneratorError {
|
||||||
constructor(errorString: string) {
|
constructor(errorString: string) {
|
||||||
super(errorString);
|
super(errorString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// tslint:disable-next-line: max-classes-per-file
|
|
||||||
export class CompatibilityError extends CodeGeneratorError {
|
export class CompatibilityError extends CodeGeneratorError {
|
||||||
constructor(errorString: string) {
|
constructor(errorString: string) {
|
||||||
super(errorString);
|
super(errorString);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// tslint:disable-next-line: max-classes-per-file
|
|
||||||
export class PublisherError extends CodeGeneratorError {
|
export class PublisherError extends CodeGeneratorError {
|
||||||
constructor(errorString: string) {
|
constructor(errorString: string) {
|
||||||
super(errorString);
|
super(errorString);
|
||||||
|
|||||||
@ -1,7 +1,5 @@
|
|||||||
export * from './core';
|
export * from './core';
|
||||||
export * from './deps';
|
export * from './deps';
|
||||||
export * from './error';
|
export * from './error';
|
||||||
export * from './result';
|
|
||||||
export * from './schema';
|
|
||||||
export * from './intermediate';
|
export * from './intermediate';
|
||||||
export * from './publisher';
|
export * from './publisher';
|
||||||
|
|||||||
@ -1,32 +1,26 @@
|
|||||||
import {
|
import { I18nMap, UtilsMap, ContainerSchema, JSONObject } from '@ali/lowcode-types';
|
||||||
IAppConfig,
|
|
||||||
IAppMeta,
|
import { IDependency, INpmPackage } from './deps';
|
||||||
IContainerNodeItem,
|
|
||||||
IDependency,
|
|
||||||
II18nMap,
|
|
||||||
IInternalDependency,
|
|
||||||
IUtilItem,
|
|
||||||
} from './index';
|
|
||||||
|
|
||||||
export interface IParseResult {
|
export interface IParseResult {
|
||||||
containers: IContainerInfo[];
|
containers: IContainerInfo[];
|
||||||
globalUtils?: IUtilInfo;
|
globalUtils?: IUtilInfo;
|
||||||
globalI18n?: II18nMap;
|
globalI18n?: I18nMap;
|
||||||
globalRouter?: IRouterInfo;
|
globalRouter?: IRouterInfo;
|
||||||
project?: IProjectInfo;
|
project?: IProjectInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IContainerInfo extends IContainerNodeItem, IWithDependency {
|
|
||||||
containerType: string;
|
|
||||||
moduleName: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IWithDependency {
|
export interface IWithDependency {
|
||||||
deps?: IDependency[];
|
deps?: IDependency[];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface IContainerInfo extends ContainerSchema, IWithDependency {
|
||||||
|
containerType: string;
|
||||||
|
moduleName: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface IUtilInfo extends IWithDependency {
|
export interface IUtilInfo extends IWithDependency {
|
||||||
utils: IUtilItem[];
|
utils: UtilsMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IRouterInfo extends IWithDependency {
|
export interface IRouterInfo extends IWithDependency {
|
||||||
@ -37,11 +31,10 @@ export interface IRouterInfo extends IWithDependency {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface IProjectInfo {
|
export interface IProjectInfo {
|
||||||
config: IAppConfig;
|
|
||||||
meta: IAppMeta;
|
|
||||||
css?: string;
|
css?: string;
|
||||||
constants?: Record<string, string>;
|
constants?: JSONObject;
|
||||||
i18n?: II18nMap;
|
i18n?: I18nMap;
|
||||||
|
packages: INpmPackage[];
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@ -1,17 +1,15 @@
|
|||||||
import {
|
import { ResultDir } from '@ali/lowcode-types';
|
||||||
IResultDir,
|
|
||||||
} from './index';
|
|
||||||
|
|
||||||
export type PublisherFactory<T, U> = (configuration?: Partial<T>) => U;
|
export type PublisherFactory<T, U> = (configuration?: Partial<T>) => U;
|
||||||
|
|
||||||
export interface IPublisher<T, U> {
|
export interface IPublisher<T, U> {
|
||||||
publish: (options?: T) => Promise<IPublisherResponse<U>>;
|
publish: (options?: T) => Promise<IPublisherResponse<U>>;
|
||||||
getProject: () => IResultDir | void;
|
getProject: () => ResultDir | void;
|
||||||
setProject: (project: IResultDir) => void;
|
setProject: (project: ResultDir) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface IPublisherFactoryParams {
|
export interface IPublisherFactoryParams {
|
||||||
project?: IResultDir;
|
project?: ResultDir;
|
||||||
}
|
}
|
||||||
export interface IPublisherResponse<T> {
|
export interface IPublisherResponse<T> {
|
||||||
success: boolean;
|
success: boolean;
|
||||||
|
|||||||
@ -1,88 +0,0 @@
|
|||||||
/**
|
|
||||||
* 导出内容结构,文件夹
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @interface IResultDir
|
|
||||||
*/
|
|
||||||
export interface IResultDir {
|
|
||||||
/**
|
|
||||||
* 文件夹名称,Root 名称默认为 .
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof IResultDir
|
|
||||||
*/
|
|
||||||
name: string;
|
|
||||||
/**
|
|
||||||
* 子目录
|
|
||||||
*
|
|
||||||
* @type {IResultDir[]}
|
|
||||||
* @memberof IResultDir
|
|
||||||
*/
|
|
||||||
dirs: IResultDir[];
|
|
||||||
/**
|
|
||||||
* 文件夹内文件
|
|
||||||
*
|
|
||||||
* @type {IResultFile[]}
|
|
||||||
* @memberof IResultDir
|
|
||||||
*/
|
|
||||||
files: IResultFile[];
|
|
||||||
/**
|
|
||||||
* 添加文件
|
|
||||||
*
|
|
||||||
* @param {IResultFile} file
|
|
||||||
* @memberof IResultDir
|
|
||||||
*/
|
|
||||||
addFile(file: IResultFile): void;
|
|
||||||
/**
|
|
||||||
* 添加子目录
|
|
||||||
*
|
|
||||||
* @param {IResultDir} dir
|
|
||||||
* @memberof IResultDir
|
|
||||||
*/
|
|
||||||
addDirectory(dir: IResultDir): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 导出内容,对文件的描述
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @interface IResultFile
|
|
||||||
*/
|
|
||||||
export interface IResultFile {
|
|
||||||
/**
|
|
||||||
* 文件名
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof IResultFile
|
|
||||||
*/
|
|
||||||
name: string;
|
|
||||||
/**
|
|
||||||
* 文件类型扩展名,例如 .js .less
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof IResultFile
|
|
||||||
*/
|
|
||||||
ext: string;
|
|
||||||
/**
|
|
||||||
* 文件内容
|
|
||||||
*
|
|
||||||
* @type {string}
|
|
||||||
* @memberof IResultFile
|
|
||||||
*/
|
|
||||||
content: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IPackageJSON {
|
|
||||||
name: string;
|
|
||||||
version: string;
|
|
||||||
description?: string;
|
|
||||||
dependencies: Record<string, string>;
|
|
||||||
devDependencies: Record<string, string>;
|
|
||||||
scripts?: Record<string, string>;
|
|
||||||
engines?: Record<string, string>;
|
|
||||||
repository?: {
|
|
||||||
type: string;
|
|
||||||
url: string;
|
|
||||||
};
|
|
||||||
private?: boolean;
|
|
||||||
}
|
|
||||||
@ -1,226 +0,0 @@
|
|||||||
// 搭建基础协议、搭建入料协议的数据规范
|
|
||||||
import { IExternalDependency } from './index';
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 搭建基础协议 - 函数表达式
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @interface IJSExpression
|
|
||||||
*/
|
|
||||||
export interface IJSExpression {
|
|
||||||
type: 'JSExpression';
|
|
||||||
value: string;
|
|
||||||
[extConfigName: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
// JSON 基本类型
|
|
||||||
export interface IJSONObject {
|
|
||||||
[key: string]: JSONValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type JSONValue =
|
|
||||||
| boolean
|
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| null
|
|
||||||
| JSONArray
|
|
||||||
| IJSONObject;
|
|
||||||
export type JSONArray = JSONValue[];
|
|
||||||
|
|
||||||
export type CompositeArray = CompositeValue[];
|
|
||||||
export interface ICompositeObject {
|
|
||||||
[key: string]: CompositeValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 复合类型
|
|
||||||
export type CompositeValue =
|
|
||||||
| JSONValue
|
|
||||||
| IJSExpression
|
|
||||||
| CompositeArray
|
|
||||||
| ICompositeObject;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 搭建基础协议 - 多语言描述
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @interface II18nMap
|
|
||||||
*/
|
|
||||||
export interface II18nMap {
|
|
||||||
[lang: string]: {
|
|
||||||
[key: string]: string;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 搭建基础协议
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @interface IBasicSchema
|
|
||||||
*/
|
|
||||||
export interface IBasicSchema {
|
|
||||||
version: string; // 当前协议版本号
|
|
||||||
componentsMap: IComponentsMapItem[]; // 组件映射关系
|
|
||||||
componentsTree: Array<IContainerNodeItem | IComponentNodeItem>; // 描述模版/页面/区块/低代码业务组件的组件树 低代码业务组件树描述,固定长度为1,且顶层为低代码业务组件容器描述
|
|
||||||
utils?: IUtilItem[]; // 工具类扩展映射关系 低代码业务组件不包含
|
|
||||||
i18n?: II18nMap; // 国际化语料
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IProjectSchema extends IBasicSchema {
|
|
||||||
constants: Record<string, string>; // 应用范围内的全局常量;
|
|
||||||
css: string; // 应用范围内的全局样式;
|
|
||||||
config: IAppConfig; // 当前应用配置信息
|
|
||||||
meta: IAppMeta; // 当前应用元数据信息
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 搭建基础协议 - 单个组件描述
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @interface IComponentsMapItem
|
|
||||||
*/
|
|
||||||
export interface IComponentsMapItem extends IExternalDependency {
|
|
||||||
componentName: string; // 组件名称
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IUtilItem {
|
|
||||||
name: string;
|
|
||||||
type: 'npm' | 'tnpm' | 'function';
|
|
||||||
content: IExternalDependency | IJSExpression;
|
|
||||||
}
|
|
||||||
|
|
||||||
export type ChildNodeItem = string | IJSExpression | IComponentNodeItem;
|
|
||||||
export type ChildNodeType = ChildNodeItem | ChildNodeItem[];
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 搭建基础协议 - 单个组件树节点描述
|
|
||||||
* 转换成一个 .jsx 文件内 React Class 类 render 函数返回的 jsx 代码
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @interface IComponentNodeItem
|
|
||||||
*/
|
|
||||||
export interface IComponentNodeItem {
|
|
||||||
// TODO: 不需要 id 字段,暂时简单兼容
|
|
||||||
id?: string;
|
|
||||||
componentName: string; // 组件名称 必填、首字母大写
|
|
||||||
props: {
|
|
||||||
[propName: string]: CompositeValue; // 业务属性
|
|
||||||
}; // 组件属性对象
|
|
||||||
condition?: CompositeValue; // 渲染条件
|
|
||||||
loop?: CompositeValue; // 循环数据
|
|
||||||
loopArgs?: [string, string]; // 循环迭代对象、索引名称 ["item", "index"]
|
|
||||||
children?: ChildNodeType; // 子节点
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 搭建基础协议 - 单个容器节点描述
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @interface IContainerNodeItem
|
|
||||||
* @extends {IComponentNodeItem}
|
|
||||||
*/
|
|
||||||
export interface IContainerNodeItem extends IComponentNodeItem {
|
|
||||||
componentName: 'Page' | 'Block' | 'Component'; // 'Page' | 'Block' | 'Component' 组件类型 必填、首字母大写
|
|
||||||
fileName: string; // 文件名称 必填、英文
|
|
||||||
state?: {
|
|
||||||
[stateName: string]: CompositeValue; // 容器初始数据
|
|
||||||
};
|
|
||||||
css?: string; // 样式文件 用于描述容器组件内部节点的样式,对应生成一个独立的样式文件,在对应容器组件生成的 .jsx 文件中 import 引入;
|
|
||||||
/**
|
|
||||||
* LifeCycle
|
|
||||||
* • constructor(props, context)
|
|
||||||
* • 说明:初始化渲染时执行,常用于设置state值;
|
|
||||||
* • render()
|
|
||||||
* • 说明:执行于容器组件React Class的render方法最前,常用于计算变量挂载到this对象上,供props上属性绑定。此render()方法不需要设置return返回值。
|
|
||||||
* • componentDidMount()
|
|
||||||
* • componentDidUpdate(prevProps, prevState, snapshot)
|
|
||||||
* • componentWillUnmount()
|
|
||||||
* • componentDidCatch(error, info)
|
|
||||||
*/
|
|
||||||
lifeCycles?: Record<string, IJSExpression>; // 生命周期Hook方法
|
|
||||||
methods?: Record<string, IJSExpression>; // 自定义方法设置
|
|
||||||
dataSource?: {
|
|
||||||
list: IDataSourceConfig[];
|
|
||||||
}; // 异步数据源配置
|
|
||||||
meta?: IBasicMeta | IPageMeta;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 搭建基础协议 - 数据源单个配置
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @interface IDataSourceConfig
|
|
||||||
*/
|
|
||||||
export interface IDataSourceConfig {
|
|
||||||
id: string; // 数据请求ID标识
|
|
||||||
isInit: boolean; // 是否为初始数据 支持表达式 值为true时,将在组件初始化渲染时自动发送当前数据请求
|
|
||||||
type: string; // 数据请求类型 'fetch' | 'mtop' | 'jsonp' | 'custom'
|
|
||||||
requestHandler?: IJSExpression; // 自定义扩展的外部请求处理器 仅type='custom'时生效
|
|
||||||
options?: IFetchOptions; // 请求参数配置 每种请求类型对应不同参数
|
|
||||||
dataHandler?: IJSExpression; // 数据结果处理函数,形如:(data, err) => Object
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 搭建基础协议 - 请求参数配置
|
|
||||||
*
|
|
||||||
* @export
|
|
||||||
* @interface IFetchOptions
|
|
||||||
*/
|
|
||||||
export interface IFetchOptions {
|
|
||||||
url: string; // 请求地址 支持表达式
|
|
||||||
params?: {
|
|
||||||
// 请求参数
|
|
||||||
[key: string]: any;
|
|
||||||
};
|
|
||||||
method: 'GET' | 'POST';
|
|
||||||
isCors?: boolean; // 是否支持跨域,对应credentials = 'include'
|
|
||||||
timeout?: number; // 超时时长
|
|
||||||
headers?: {
|
|
||||||
// 自定义请求头
|
|
||||||
[key: string]: string;
|
|
||||||
};
|
|
||||||
[extConfigName: string]: any;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IBasicMeta {
|
|
||||||
title: string; // 标题描述
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IPageMeta extends IBasicMeta {
|
|
||||||
router: string; // 页面路由
|
|
||||||
spmb?: string; // spm
|
|
||||||
}
|
|
||||||
|
|
||||||
// "theme": {
|
|
||||||
// //for Fusion use dpl defined
|
|
||||||
// "package": "@alife/theme-fusion",
|
|
||||||
// "version": "^0.1.0",
|
|
||||||
|
|
||||||
// //for Antd use variable
|
|
||||||
// "primary": "#ff9966"
|
|
||||||
// }
|
|
||||||
|
|
||||||
// "layout": {
|
|
||||||
// "componentName": "BasicLayout",
|
|
||||||
// "props": {
|
|
||||||
// "logo": "...",
|
|
||||||
// "name": "测试网站"
|
|
||||||
// },
|
|
||||||
// },
|
|
||||||
|
|
||||||
export interface IAppConfig {
|
|
||||||
sdkVersion: string; // 渲染模块版本
|
|
||||||
historyMode: 'brower' | 'hash'; // 浏览器路由:brower 哈希路由:hash
|
|
||||||
targetRootID: string; // 渲染根节点 ID
|
|
||||||
layout: IComponentNodeItem;
|
|
||||||
theme: object; // 主题配置,根据接入的主题模块不同
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface IAppMeta {
|
|
||||||
name: string; // 应用中文名称
|
|
||||||
git_group?: string; // 应用对应git分组名
|
|
||||||
project_name?: string; // 应用对应git的project名称
|
|
||||||
description?: string; // 应用描述
|
|
||||||
spma?: string; // 应用spma A位信息
|
|
||||||
creator?: string; // author
|
|
||||||
[otherAttrName: string]: any;
|
|
||||||
}
|
|
||||||
@ -22,7 +22,10 @@ export function upperCaseFirst(inputValue: string): string {
|
|||||||
return changeCase.upperCaseFirst(inputValue);
|
return changeCase.upperCaseFirst(inputValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function uniqueArray<T>(arr: T[]) {
|
export function uniqueArray<T>(arr: T[], by: (i: T) => string) {
|
||||||
const uniqueItems = [...new Set<T>(arr)];
|
const map: Record<string, T> = {};
|
||||||
|
arr.forEach((item) => (map[by(item)] = item));
|
||||||
|
const uniqueKeys = [...new Set<string>(Object.keys(map))];
|
||||||
|
const uniqueItems = uniqueKeys.map((key) => map[key]);
|
||||||
return uniqueItems;
|
return uniqueItems;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,88 +1,109 @@
|
|||||||
import { CompositeArray, CompositeValue, ICompositeObject } from '../types';
|
import {
|
||||||
import { generateExpression, isJsExpression } from './jsExpression';
|
CompositeArray,
|
||||||
|
CompositeValue,
|
||||||
|
CompositeObject,
|
||||||
|
isJSExpression,
|
||||||
|
isJSFunction,
|
||||||
|
isJSSlot,
|
||||||
|
} from '@ali/lowcode-types';
|
||||||
|
|
||||||
type CustomHandler = (data: unknown) => string;
|
import { CompositeValueGeneratorOptions, CompositeTypeContainerHandlerSet, CodeGeneratorError } from '../types';
|
||||||
interface CustomHandlerSet {
|
|
||||||
boolean?: CustomHandler;
|
|
||||||
number?: CustomHandler;
|
|
||||||
string?: CustomHandler;
|
|
||||||
array?: CustomHandler;
|
|
||||||
object?: CustomHandler;
|
|
||||||
expression?: CustomHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
function generateArray(
|
import { generateExpression, generateFunction } from './jsExpression';
|
||||||
value: CompositeArray,
|
import { generateJsSlot } from './jsSlot';
|
||||||
handlers: CustomHandlerSet = {},
|
import { isValidIdentifier } from './validate';
|
||||||
): string {
|
import { camelize } from './common';
|
||||||
const body = value.map(v => generateUnknownType(v, handlers)).join(',');
|
|
||||||
|
const defaultContainerHandlers: CompositeTypeContainerHandlerSet = {
|
||||||
|
default: (v) => v,
|
||||||
|
string: (v) => `'${v}'`,
|
||||||
|
};
|
||||||
|
|
||||||
|
function generateArray(value: CompositeArray, options: CompositeValueGeneratorOptions = {}): string {
|
||||||
|
const body = value.map((v) => generateUnknownType(v, options)).join(',');
|
||||||
return `[${body}]`;
|
return `[${body}]`;
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateObject(
|
function generateObject(value: CompositeObject, options: CompositeValueGeneratorOptions = {}): string {
|
||||||
value: ICompositeObject,
|
if (isJSExpression(value)) {
|
||||||
handlers: CustomHandlerSet = {},
|
if (options.handlers && options.handlers.expression) {
|
||||||
): string {
|
return options.handlers.expression(value);
|
||||||
if (isJsExpression(value)) {
|
|
||||||
if (handlers.expression) {
|
|
||||||
return handlers.expression(value);
|
|
||||||
}
|
}
|
||||||
return generateExpression(value);
|
return generateExpression(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isJSFunction(value)) {
|
||||||
|
return generateFunction(value, { isArrow: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isJSSlot(value)) {
|
||||||
|
if (options.nodeGenerator) {
|
||||||
|
return generateJsSlot(value, options.nodeGenerator);
|
||||||
|
}
|
||||||
|
throw new CodeGeneratorError("Can't find Node Generator");
|
||||||
|
}
|
||||||
|
|
||||||
const body = Object.keys(value)
|
const body = Object.keys(value)
|
||||||
.map(key => {
|
.map((key) => {
|
||||||
const v = generateUnknownType(value[key], handlers);
|
let propName = key;
|
||||||
return `${key}: ${v}`;
|
|
||||||
|
// TODO: 可以增加更多智能修复的方法
|
||||||
|
const fixMethods: Array<(v: string) => string> = [camelize];
|
||||||
|
// Try to fix propName
|
||||||
|
while (!isValidIdentifier(propName)) {
|
||||||
|
const fixMethod = fixMethods.pop();
|
||||||
|
if (fixMethod) {
|
||||||
|
try {
|
||||||
|
propName = fixMethod(propName);
|
||||||
|
} catch (error) {
|
||||||
|
throw new CodeGeneratorError(error.message);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
throw new CodeGeneratorError(`Propname: ${key} is not a valid identifier.`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const v = generateUnknownType(value[key], options);
|
||||||
|
return `${propName}: ${v}`;
|
||||||
})
|
})
|
||||||
.join(',\n');
|
.join(',\n');
|
||||||
|
|
||||||
return `{${body}}`;
|
return `{${body}}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateUnknownType(
|
export function generateUnknownType(value: CompositeValue, options: CompositeValueGeneratorOptions = {}): string {
|
||||||
value: CompositeValue,
|
|
||||||
handlers: CustomHandlerSet = {},
|
|
||||||
): string {
|
|
||||||
if (Array.isArray(value)) {
|
if (Array.isArray(value)) {
|
||||||
if (handlers.array) {
|
if (options.handlers && options.handlers.array) {
|
||||||
return handlers.array(value);
|
return options.handlers.array(value);
|
||||||
}
|
}
|
||||||
return generateArray(value as CompositeArray, handlers);
|
return generateArray(value as CompositeArray, options);
|
||||||
} else if (typeof value === 'object') {
|
} else if (typeof value === 'object') {
|
||||||
if (handlers.object) {
|
if (options.handlers && options.handlers.object) {
|
||||||
return handlers.object(value);
|
return options.handlers.object(value);
|
||||||
}
|
}
|
||||||
return generateObject(value as ICompositeObject, handlers);
|
return generateObject(value as CompositeObject, options);
|
||||||
} else if (typeof value === 'string') {
|
} else if (typeof value === 'string') {
|
||||||
if (handlers.string) {
|
if (options.handlers && options.handlers.string) {
|
||||||
return handlers.string(value);
|
return options.handlers.string(value);
|
||||||
}
|
}
|
||||||
return `'${value}'`;
|
return `'${value}'`;
|
||||||
} else if (typeof value === 'number' && handlers.number) {
|
} else if (typeof value === 'number' && options.handlers && options.handlers.number) {
|
||||||
return handlers.number(value);
|
return options.handlers.number(value);
|
||||||
} else if (typeof value === 'boolean' && handlers.boolean) {
|
} else if (typeof value === 'boolean' && options.handlers && options.handlers.boolean) {
|
||||||
return handlers.boolean(value);
|
return options.handlers.boolean(value);
|
||||||
}
|
}
|
||||||
return `${value}`;
|
return `${value}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateCompositeType(
|
export function generateCompositeType(value: CompositeValue, options: CompositeValueGeneratorOptions = {}): string {
|
||||||
value: CompositeValue,
|
const result = generateUnknownType(value, options);
|
||||||
handlers: CustomHandlerSet = {},
|
const containerHandlers = {
|
||||||
): [boolean, string] {
|
...defaultContainerHandlers,
|
||||||
const result = generateUnknownType(value, handlers);
|
...(options.containerHandlers || {}),
|
||||||
|
};
|
||||||
|
|
||||||
if (result.substr(0, 1) === "'" && result.substr(-1, 1) === "'") {
|
const isStringType = result.substr(0, 1) === "'" && result.substr(-1, 1) === "'";
|
||||||
return [true, result.substring(1, result.length - 1)];
|
if (isStringType) {
|
||||||
|
return (containerHandlers.string && containerHandlers.string(result.substring(1, result.length - 1))) || '';
|
||||||
}
|
}
|
||||||
|
return (containerHandlers.default && containerHandlers.default(result)) || '';
|
||||||
return [false, result];
|
|
||||||
}
|
|
||||||
|
|
||||||
export function handleStringValueDefault([isString, result]: [boolean, string]) {
|
|
||||||
if (isString) {
|
|
||||||
return `'${result}'`;
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,39 +1,8 @@
|
|||||||
import traverse from '@babel/traverse';
|
import { JSExpression, JSFunction } from '@ali/lowcode-types';
|
||||||
import * as parser from '@babel/parser';
|
|
||||||
import { CodeGeneratorError, IJSExpression } from '../types';
|
|
||||||
|
|
||||||
let count = 0;
|
import { CodeGeneratorError } from '../types';
|
||||||
|
|
||||||
function test(functionBody: string) {
|
|
||||||
console.log(functionBody);
|
|
||||||
console.log('---->');
|
|
||||||
try {
|
|
||||||
const parseResult = parser.parse(functionBody);
|
|
||||||
// console.log(JSON.stringify(parseResult));
|
|
||||||
traverse(parseResult, {
|
|
||||||
enter(path) {
|
|
||||||
console.log('path: ', JSON.stringify(path));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (count === 0) {
|
|
||||||
count++;
|
|
||||||
|
|
||||||
test('this.aaa && this.bbb');
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
// console.log('Error');
|
|
||||||
console.log(error.message);
|
|
||||||
}
|
|
||||||
console.log('=====================');
|
|
||||||
}
|
|
||||||
|
|
||||||
export function transformFuncExpr2MethodMember(
|
|
||||||
methodName: string,
|
|
||||||
functionBody: string,
|
|
||||||
): string {
|
|
||||||
// test(functionBody);
|
|
||||||
|
|
||||||
|
export function transformFuncExpr2MethodMember(methodName: string, functionBody: string): string {
|
||||||
const args = getFuncExprArguments(functionBody);
|
const args = getFuncExprArguments(functionBody);
|
||||||
const body = getFuncExprBody(functionBody);
|
const body = getFuncExprBody(functionBody);
|
||||||
|
|
||||||
@ -66,20 +35,60 @@ export function getFuncExprBody(functionBody: string) {
|
|||||||
return body;
|
return body;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateExpression(value: any): string {
|
export function getArrowFunction(functionBody: string) {
|
||||||
if (value && (value as IJSExpression).type === 'JSExpression') {
|
const args = getFuncExprArguments(functionBody);
|
||||||
// test((value as IJSExpression).value);
|
const body = getFuncExprBody(functionBody);
|
||||||
|
|
||||||
return (value as IJSExpression).value || 'null';
|
return `(${args}) => { ${body} }`;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isJSExpression(value: unknown): boolean {
|
||||||
|
return value && typeof value === 'object' && (value as JSExpression).type === 'JSExpression';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isJSFunction(value: unknown): boolean {
|
||||||
|
return value && typeof value === 'object' && (value as JSFunction).type === 'JSFunction';
|
||||||
|
}
|
||||||
|
|
||||||
|
export function isJsCode(value: unknown): boolean {
|
||||||
|
return isJSExpression(value) || isJSFunction(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateExpression(value: any): string {
|
||||||
|
if (isJSExpression(value)) {
|
||||||
|
return (value as JSExpression).value || 'null';
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new CodeGeneratorError('Not a JSExpression');
|
throw new CodeGeneratorError('Not a JSExpression');
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isJsExpression(value: any): boolean {
|
export function generateFunction(
|
||||||
return (
|
value: any,
|
||||||
value &&
|
config: {
|
||||||
typeof value === 'object' &&
|
name?: string;
|
||||||
(value as IJSExpression).type === 'JSExpression'
|
isMember?: boolean;
|
||||||
);
|
isBlock?: boolean;
|
||||||
|
isArrow?: boolean;
|
||||||
|
} = {
|
||||||
|
name: undefined,
|
||||||
|
isMember: false,
|
||||||
|
isBlock: false,
|
||||||
|
isArrow: false,
|
||||||
|
},
|
||||||
|
) {
|
||||||
|
if (isJsCode(value)) {
|
||||||
|
const functionCfg = value as JSFunction;
|
||||||
|
if (config.isMember) {
|
||||||
|
return transformFuncExpr2MethodMember(config.name || '', functionCfg.value);
|
||||||
|
}
|
||||||
|
if (config.isBlock) {
|
||||||
|
return getFuncExprBody(functionCfg.value);
|
||||||
|
}
|
||||||
|
if (config.isArrow) {
|
||||||
|
return getArrowFunction(functionCfg.value);
|
||||||
|
}
|
||||||
|
return functionCfg.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new CodeGeneratorError('Not a JSFunction or JSExpression');
|
||||||
}
|
}
|
||||||
|
|||||||
25
packages/code-generator/src/utils/jsSlot.ts
Normal file
25
packages/code-generator/src/utils/jsSlot.ts
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
import { NodeData, JSSlot, isJSSlot } from '@ali/lowcode-types';
|
||||||
|
import { CodeGeneratorError, NodeGenerator } from '../types';
|
||||||
|
|
||||||
|
export function generateJsSlot(value: any, generator: NodeGenerator): string {
|
||||||
|
if (isJSSlot(value)) {
|
||||||
|
const slotCfg = value as JSSlot;
|
||||||
|
if (!slotCfg.value) {
|
||||||
|
return 'null';
|
||||||
|
}
|
||||||
|
const results: string[] = [];
|
||||||
|
if (Array.isArray(slotCfg.value)) {
|
||||||
|
const values: NodeData[] = slotCfg.value;
|
||||||
|
results.push(...values.map((n) => generator(n)));
|
||||||
|
} else {
|
||||||
|
results.push(generator(slotCfg.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (results.length === 1) {
|
||||||
|
return results[0];
|
||||||
|
}
|
||||||
|
return `[${results.join(',')}]`;
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new CodeGeneratorError('Not a JSSlot');
|
||||||
|
}
|
||||||
@ -1,13 +1,23 @@
|
|||||||
import {
|
import {
|
||||||
ChildNodeType,
|
JSSlot,
|
||||||
IComponentNodeItem,
|
JSExpression,
|
||||||
IJSExpression,
|
NodeData,
|
||||||
ChildNodeItem,
|
NodeSchema,
|
||||||
|
PropsMap,
|
||||||
|
isJSExpression,
|
||||||
|
isJSSlot,
|
||||||
|
isDOMText,
|
||||||
|
} from '@ali/lowcode-types';
|
||||||
|
|
||||||
|
import {
|
||||||
CodeGeneratorError,
|
CodeGeneratorError,
|
||||||
PIECE_TYPE,
|
PIECE_TYPE,
|
||||||
CodePiece,
|
CodePiece,
|
||||||
HandlerSet,
|
HandlerSet,
|
||||||
ExtGeneratorPlugin,
|
ExtGeneratorPlugin,
|
||||||
|
INodeGeneratorConfig,
|
||||||
|
INodeGeneratorContext,
|
||||||
|
NodeGenerator,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import { generateCompositeType } from './compositeType';
|
import { generateCompositeType } from './compositeType';
|
||||||
import { generateExpression } from './jsExpression';
|
import { generateExpression } from './jsExpression';
|
||||||
@ -15,73 +25,160 @@ import { generateExpression } from './jsExpression';
|
|||||||
// tslint:disable-next-line: no-empty
|
// tslint:disable-next-line: no-empty
|
||||||
const noop = () => [];
|
const noop = () => [];
|
||||||
|
|
||||||
export function handleChildren<T>(
|
const handleChildrenDefaultOptions = {
|
||||||
children: ChildNodeType,
|
rerun: false,
|
||||||
|
};
|
||||||
|
|
||||||
|
export function handleSubNodes<T>(
|
||||||
|
children: unknown,
|
||||||
handlers: HandlerSet<T>,
|
handlers: HandlerSet<T>,
|
||||||
|
options?: {
|
||||||
|
rerun?: boolean;
|
||||||
|
},
|
||||||
): T[] {
|
): T[] {
|
||||||
|
const opt = {
|
||||||
|
...handleChildrenDefaultOptions,
|
||||||
|
...(options || {}),
|
||||||
|
};
|
||||||
|
|
||||||
if (Array.isArray(children)) {
|
if (Array.isArray(children)) {
|
||||||
const list: ChildNodeItem[] = children as ChildNodeItem[];
|
const list: NodeData[] = children as NodeData[];
|
||||||
return list
|
return list.map((child) => handleSubNodes(child, handlers, opt)).reduce((p, c) => p.concat(c), []);
|
||||||
.map(child => handleChildren(child, handlers))
|
} else if (isDOMText(children)) {
|
||||||
.reduce((p, c) => p.concat(c), []);
|
|
||||||
} else if (typeof children === 'string') {
|
|
||||||
const handler = handlers.string || handlers.common || noop;
|
const handler = handlers.string || handlers.common || noop;
|
||||||
return handler(children as string);
|
return handler(children as string);
|
||||||
} else if ((children as IJSExpression).type === 'JSExpression') {
|
} else if (isJSExpression(children)) {
|
||||||
const handler = handlers.expression || handlers.common || noop;
|
const handler = handlers.expression || handlers.common || noop;
|
||||||
return handler(children as IJSExpression);
|
return handler(children as JSExpression);
|
||||||
} else {
|
} else {
|
||||||
const handler = handlers.node || handlers.common || noop;
|
const handler = handlers.node || handlers.common || noop;
|
||||||
return handler(children as IComponentNodeItem);
|
const child = children as NodeSchema;
|
||||||
|
let curRes = handler(child);
|
||||||
|
if (opt.rerun && child.children) {
|
||||||
|
const childRes = handleSubNodes(child.children, handlers, opt);
|
||||||
|
curRes = curRes.concat(childRes || []);
|
||||||
|
}
|
||||||
|
if (child.props) {
|
||||||
|
// FIXME: currently only support PropsMap
|
||||||
|
const childProps = child.props as PropsMap;
|
||||||
|
Object.keys(childProps)
|
||||||
|
.filter((propName) => isJSSlot(childProps[propName]))
|
||||||
|
.forEach((propName) => {
|
||||||
|
const soltVals = (childProps[propName] as JSSlot).value;
|
||||||
|
(soltVals || []).forEach((soltVal) => {
|
||||||
|
const childRes = handleSubNodes(soltVal, handlers, opt);
|
||||||
|
curRes = curRes.concat(childRes || []);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return curRes;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateAttr(attrName: string, attrValue: any): CodePiece[] {
|
export function handleChildren<T>(
|
||||||
if (attrName === 'initValue' || attrName === 'labelCol') {
|
ctx: INodeGeneratorContext,
|
||||||
|
children: unknown,
|
||||||
|
handlers: HandlerSet<T>,
|
||||||
|
options?: {
|
||||||
|
rerun?: boolean;
|
||||||
|
},
|
||||||
|
): T[] {
|
||||||
|
const opt = {
|
||||||
|
...handleChildrenDefaultOptions,
|
||||||
|
...(options || {}),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (Array.isArray(children)) {
|
||||||
|
const list: NodeData[] = children as NodeData[];
|
||||||
|
return list.map((child) => handleChildren(ctx, child, handlers, opt)).reduce((p, c) => p.concat(c), []);
|
||||||
|
} else if (isDOMText(children)) {
|
||||||
|
const handler = handlers.string || handlers.common || noop;
|
||||||
|
return handler(children as string);
|
||||||
|
} else if (isJSExpression(children)) {
|
||||||
|
const handler = handlers.expression || handlers.common || noop;
|
||||||
|
return handler(children as JSExpression);
|
||||||
|
} else {
|
||||||
|
const handler = handlers.node || handlers.common || noop;
|
||||||
|
const child = children as NodeSchema;
|
||||||
|
let curRes = handler(child);
|
||||||
|
if (opt.rerun && child.children) {
|
||||||
|
const childRes = handleChildren(ctx, child.children, handlers, opt);
|
||||||
|
curRes = curRes.concat(childRes || []);
|
||||||
|
}
|
||||||
|
return curRes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function generateAttr(ctx: INodeGeneratorContext, attrName: string, attrValue: any): CodePiece[] {
|
||||||
|
if (attrName === 'initValue') {
|
||||||
return [];
|
return [];
|
||||||
}
|
}
|
||||||
const [isString, valueStr] = generateCompositeType(attrValue);
|
const valueStr = generateCompositeType(attrValue, {
|
||||||
return [{
|
containerHandlers: {
|
||||||
value: `${attrName}=${isString ? `"${valueStr}"` : `{${valueStr}}`}`,
|
default: (v) => `{${v}}`,
|
||||||
type: PIECE_TYPE.ATTR,
|
string: (v) => `"${v}"`,
|
||||||
}];
|
},
|
||||||
|
nodeGenerator: ctx.generator,
|
||||||
|
});
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
value: `${attrName}=${valueStr}`,
|
||||||
|
type: PIECE_TYPE.ATTR,
|
||||||
|
},
|
||||||
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateAttrs(nodeItem: IComponentNodeItem): CodePiece[] {
|
export function generateAttrs(ctx: INodeGeneratorContext, nodeItem: NodeSchema): CodePiece[] {
|
||||||
const { props } = nodeItem;
|
const { props } = nodeItem;
|
||||||
let pieces: CodePiece[] = [];
|
let pieces: CodePiece[] = [];
|
||||||
|
|
||||||
Object.keys(props).forEach((propName: string) =>
|
Object.keys(props).forEach(
|
||||||
pieces = pieces.concat(generateAttr(propName, props[propName])),
|
(propName: string) => (pieces = pieces.concat(generateAttr(ctx, propName, props[propName]))),
|
||||||
);
|
);
|
||||||
|
|
||||||
return pieces;
|
return pieces;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mapNodeName(src: string): string {
|
function mapNodeName(src: string, mapping: Record<string, string>): string {
|
||||||
if (src === 'Div') {
|
if (mapping[src]) {
|
||||||
return 'div';
|
return mapping[src];
|
||||||
}
|
}
|
||||||
return src;
|
return src;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateBasicNode(nodeItem: IComponentNodeItem): CodePiece[] {
|
export function generateBasicNode(
|
||||||
|
ctx: INodeGeneratorContext,
|
||||||
|
nodeItem: NodeSchema,
|
||||||
|
mapping: Record<string, string>,
|
||||||
|
): CodePiece[] {
|
||||||
const pieces: CodePiece[] = [];
|
const pieces: CodePiece[] = [];
|
||||||
pieces.push({
|
pieces.push({
|
||||||
value: mapNodeName(nodeItem.componentName),
|
value: mapNodeName(nodeItem.componentName, mapping),
|
||||||
type: PIECE_TYPE.TAG,
|
type: PIECE_TYPE.TAG,
|
||||||
});
|
});
|
||||||
|
|
||||||
return pieces;
|
return pieces;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function generateReactCtrlLine(nodeItem: IComponentNodeItem): CodePiece[] {
|
// TODO: 生成文档
|
||||||
|
// 为包裹的代码片段生成子上下文,集成父级上下文,并传入子级上下文新增内容。(如果存在多级上下文怎么处理?)
|
||||||
|
// 创建新的上下文,并从作用域中取对应同名变量塞到作用域里面?
|
||||||
|
// export function createSubContext() {}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* JSX 生成逻辑插件。在 React 代码模式下生成 loop 与 condition 相关的逻辑代码
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @param {NodeSchema} nodeItem 当前 UI 节点
|
||||||
|
* @returns {CodePiece[]} 实现功能的相关代码片段
|
||||||
|
*/
|
||||||
|
export function generateReactCtrlLine(ctx: INodeGeneratorContext, nodeItem: NodeSchema): CodePiece[] {
|
||||||
const pieces: CodePiece[] = [];
|
const pieces: CodePiece[] = [];
|
||||||
|
|
||||||
if (nodeItem.loop && nodeItem.loopArgs) {
|
if (nodeItem.loop && nodeItem.loopArgs) {
|
||||||
let loopDataExp;
|
let loopDataExp;
|
||||||
if ((nodeItem.loop as IJSExpression).type === 'JSExpression') {
|
if (isJSExpression(nodeItem.loop)) {
|
||||||
loopDataExp = `(${(nodeItem.loop as IJSExpression).value})`;
|
loopDataExp = `(${generateExpression(nodeItem.loop)})`;
|
||||||
} else {
|
} else {
|
||||||
loopDataExp = JSON.stringify(nodeItem.loop);
|
loopDataExp = JSON.stringify(nodeItem.loop);
|
||||||
}
|
}
|
||||||
@ -96,10 +193,12 @@ export function generateReactCtrlLine(nodeItem: IComponentNodeItem): CodePiece[]
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (nodeItem.condition) {
|
if (nodeItem.condition) {
|
||||||
const [isString, value] = generateCompositeType(nodeItem.condition);
|
const value = generateCompositeType(nodeItem.condition, {
|
||||||
|
nodeGenerator: ctx.generator,
|
||||||
|
});
|
||||||
|
|
||||||
pieces.unshift({
|
pieces.unshift({
|
||||||
value: `(${isString ? `'${value}'` : value}) && (`,
|
value: `(${value}) && (`,
|
||||||
type: PIECE_TYPE.BEFORE,
|
type: PIECE_TYPE.BEFORE,
|
||||||
});
|
});
|
||||||
pieces.push({
|
pieces.push({
|
||||||
@ -123,29 +222,29 @@ export function generateReactCtrlLine(nodeItem: IComponentNodeItem): CodePiece[]
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function linkPieces(pieces: CodePiece[]): string {
|
export function linkPieces(pieces: CodePiece[]): string {
|
||||||
if (pieces.filter(p => p.type === PIECE_TYPE.TAG).length !== 1) {
|
if (pieces.filter((p) => p.type === PIECE_TYPE.TAG).length !== 1) {
|
||||||
throw new CodeGeneratorError('One node only need one tag define');
|
throw new CodeGeneratorError('One node only need one tag define');
|
||||||
}
|
}
|
||||||
const tagName = pieces.filter(p => p.type === PIECE_TYPE.TAG)[0].value;
|
const tagName = pieces.filter((p) => p.type === PIECE_TYPE.TAG)[0].value;
|
||||||
|
|
||||||
const beforeParts = pieces
|
const beforeParts = pieces
|
||||||
.filter(p => p.type === PIECE_TYPE.BEFORE)
|
.filter((p) => p.type === PIECE_TYPE.BEFORE)
|
||||||
.map(p => p.value)
|
.map((p) => p.value)
|
||||||
.join('');
|
.join('');
|
||||||
|
|
||||||
const afterParts = pieces
|
const afterParts = pieces
|
||||||
.filter(p => p.type === PIECE_TYPE.AFTER)
|
.filter((p) => p.type === PIECE_TYPE.AFTER)
|
||||||
.map(p => p.value)
|
.map((p) => p.value)
|
||||||
.join('');
|
.join('');
|
||||||
|
|
||||||
const childrenParts = pieces
|
const childrenParts = pieces
|
||||||
.filter(p => p.type === PIECE_TYPE.CHILDREN)
|
.filter((p) => p.type === PIECE_TYPE.CHILDREN)
|
||||||
.map(p => p.value)
|
.map((p) => p.value)
|
||||||
.join('');
|
.join('');
|
||||||
|
|
||||||
let attrsParts = pieces
|
let attrsParts = pieces
|
||||||
.filter(p => p.type === PIECE_TYPE.ATTR)
|
.filter((p) => p.type === PIECE_TYPE.ATTR)
|
||||||
.map(p => p.value)
|
.map((p) => p.value)
|
||||||
.join(' ');
|
.join(' ');
|
||||||
|
|
||||||
attrsParts = !!attrsParts ? ` ${attrsParts}` : '';
|
attrsParts = !!attrsParts ? ` ${attrsParts}` : '';
|
||||||
@ -157,37 +256,53 @@ export function linkPieces(pieces: CodePiece[]): string {
|
|||||||
return `${beforeParts}<${tagName}${attrsParts} />${afterParts}`;
|
return `${beforeParts}<${tagName}${attrsParts} />${afterParts}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function createNodeGenerator(handlers: HandlerSet<string>, plugins: ExtGeneratorPlugin[]) {
|
export function createNodeGenerator(
|
||||||
const generateNode = (nodeItem: IComponentNodeItem): string => {
|
handlers: HandlerSet<string>,
|
||||||
let pieces: CodePiece[] = [];
|
plugins: ExtGeneratorPlugin[],
|
||||||
|
cfg?: INodeGeneratorConfig,
|
||||||
|
): NodeGenerator {
|
||||||
|
let nodeTypeMapping: Record<string, string> = {};
|
||||||
|
if (cfg && cfg.nodeTypeMapping) {
|
||||||
|
nodeTypeMapping = cfg.nodeTypeMapping;
|
||||||
|
}
|
||||||
|
|
||||||
plugins.forEach(p => {
|
const generateNode = (nodeItem: NodeSchema): string => {
|
||||||
pieces = pieces.concat(p(nodeItem));
|
let pieces: CodePiece[] = [];
|
||||||
|
const ctx: INodeGeneratorContext = {
|
||||||
|
generator: generateNode,
|
||||||
|
};
|
||||||
|
|
||||||
|
plugins.forEach((p) => {
|
||||||
|
pieces = pieces.concat(p(ctx, nodeItem));
|
||||||
});
|
});
|
||||||
pieces = pieces.concat(generateBasicNode(nodeItem));
|
pieces = pieces.concat(generateBasicNode(ctx, nodeItem, nodeTypeMapping));
|
||||||
pieces = pieces.concat(generateAttrs(nodeItem));
|
pieces = pieces.concat(generateAttrs(ctx, nodeItem));
|
||||||
if (nodeItem.children && (nodeItem.children as unknown[]).length > 0) {
|
if (nodeItem.children && (nodeItem.children as unknown[]).length > 0) {
|
||||||
pieces = pieces.concat(handleChildren<string>(nodeItem.children, handlers).map(l => ({
|
pieces = pieces.concat(
|
||||||
type: PIECE_TYPE.CHILDREN,
|
handleChildren<string>(ctx, nodeItem.children, handlers).map((l) => ({
|
||||||
value: l,
|
type: PIECE_TYPE.CHILDREN,
|
||||||
})));
|
value: l,
|
||||||
|
})),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return linkPieces(pieces);
|
return linkPieces(pieces);
|
||||||
};
|
};
|
||||||
|
|
||||||
handlers.node = (input: IComponentNodeItem) => [generateNode(input)];
|
handlers.node = (input: NodeSchema) => [generateNode(input)];
|
||||||
|
|
||||||
return generateNode;
|
return generateNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const generateString = (input: string) => [input];
|
export const generateString = (input: string) => [input];
|
||||||
|
|
||||||
export function createReactNodeGenerator() {
|
export function createReactNodeGenerator(cfg?: INodeGeneratorConfig): NodeGenerator {
|
||||||
return createNodeGenerator({
|
return createNodeGenerator(
|
||||||
string: generateString,
|
{
|
||||||
expression: (input) => [generateExpression(input)],
|
string: generateString,
|
||||||
}, [
|
expression: (input) => [generateExpression(input)],
|
||||||
generateReactCtrlLine,
|
},
|
||||||
]);
|
[generateReactCtrlLine],
|
||||||
|
cfg,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
35
packages/code-generator/src/utils/resultHelper.ts
Normal file
35
packages/code-generator/src/utils/resultHelper.ts
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
import { ResultFile, ResultDir } from '@ali/lowcode-types';
|
||||||
|
|
||||||
|
import { CodeGeneratorError } from '../types/error';
|
||||||
|
|
||||||
|
export function createResultFile(name: string, ext = 'jsx', content = ''): ResultFile {
|
||||||
|
return {
|
||||||
|
name,
|
||||||
|
ext,
|
||||||
|
content,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createResultDir(name: string): ResultDir {
|
||||||
|
return {
|
||||||
|
name,
|
||||||
|
dirs: [],
|
||||||
|
files: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addDirectory(target: ResultDir, dir: ResultDir): void {
|
||||||
|
if (target.dirs.findIndex((d) => d.name === dir.name) < 0) {
|
||||||
|
target.dirs.push(dir);
|
||||||
|
} else {
|
||||||
|
throw new CodeGeneratorError('Adding same directory to one directory');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function addFile(target: ResultDir, file: ResultFile): void {
|
||||||
|
if (target.files.findIndex((f) => f.name === file.name && f.ext === file.ext) < 0) {
|
||||||
|
target.files.push(file);
|
||||||
|
} else {
|
||||||
|
throw new CodeGeneratorError('Adding same file to one directory');
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,25 +1,25 @@
|
|||||||
import { IResultFile, IResultDir } from '../types';
|
import { ResultDir, ResultFile } from '@ali/lowcode-types';
|
||||||
import ResultDir from '../model/ResultDir';
|
import { createResultDir, addDirectory, addFile } from '../utils/resultHelper';
|
||||||
|
|
||||||
type FuncFileGenerator = () => [string[], IResultFile];
|
type FuncFileGenerator = () => [string[], ResultFile];
|
||||||
|
|
||||||
export function insertFile(root: IResultDir, path: string[], file: IResultFile) {
|
export function insertFile(root: ResultDir, path: string[], file: ResultFile) {
|
||||||
let current: IResultDir = root;
|
let current: ResultDir = root;
|
||||||
path.forEach(pathNode => {
|
path.forEach((pathNode) => {
|
||||||
const dir = current.dirs.find(d => d.name === pathNode);
|
const dir = current.dirs.find((d) => d.name === pathNode);
|
||||||
if (dir) {
|
if (dir) {
|
||||||
current = dir;
|
current = dir;
|
||||||
} else {
|
} else {
|
||||||
const newDir = new ResultDir(pathNode);
|
const newDir = createResultDir(pathNode);
|
||||||
current.addDirectory(newDir);
|
addDirectory(current, newDir);
|
||||||
current = newDir;
|
current = newDir;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
current.addFile(file);
|
addFile(current, file);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function runFileGenerator(root: IResultDir, fun: FuncFileGenerator) {
|
export function runFileGenerator(root: ResultDir, fun: FuncFileGenerator) {
|
||||||
const [path, file] = fun();
|
const [path, file] = fun();
|
||||||
insertFile(root, path, file);
|
insertFile(root, path, file);
|
||||||
}
|
}
|
||||||
|
|||||||
3
packages/code-generator/src/utils/validate.ts
Normal file
3
packages/code-generator/src/utils/validate.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export const isValidIdentifier = (name: string) => {
|
||||||
|
return /^[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*$/.test(name);
|
||||||
|
};
|
||||||
14
packages/types/src/code-intermediate.ts
Normal file
14
packages/types/src/code-intermediate.ts
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
export interface PackageJSON {
|
||||||
|
name: string;
|
||||||
|
version: string;
|
||||||
|
description?: string;
|
||||||
|
dependencies: Record<string, string>;
|
||||||
|
devDependencies: Record<string, string>;
|
||||||
|
scripts?: Record<string, string>;
|
||||||
|
engines?: Record<string, string>;
|
||||||
|
repository?: {
|
||||||
|
type: string;
|
||||||
|
url: string;
|
||||||
|
};
|
||||||
|
private?: boolean;
|
||||||
|
}
|
||||||
59
packages/types/src/code-result.ts
Normal file
59
packages/types/src/code-result.ts
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
/**
|
||||||
|
* 导出内容结构,文件夹
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface ResultDir
|
||||||
|
*/
|
||||||
|
export interface ResultDir {
|
||||||
|
/**
|
||||||
|
* 文件夹名称,Root 名称默认为 .
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof ResultDir
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
/**
|
||||||
|
* 子目录
|
||||||
|
*
|
||||||
|
* @type {ResultDir[]}
|
||||||
|
* @memberof ResultDir
|
||||||
|
*/
|
||||||
|
dirs: ResultDir[];
|
||||||
|
/**
|
||||||
|
* 文件夹内文件
|
||||||
|
*
|
||||||
|
* @type {ResultFile[]}
|
||||||
|
* @memberof ResultDir
|
||||||
|
*/
|
||||||
|
files: ResultFile[];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 导出内容,对文件的描述
|
||||||
|
*
|
||||||
|
* @export
|
||||||
|
* @interface ResultFile
|
||||||
|
*/
|
||||||
|
export interface ResultFile {
|
||||||
|
/**
|
||||||
|
* 文件名
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof ResultFile
|
||||||
|
*/
|
||||||
|
name: string;
|
||||||
|
/**
|
||||||
|
* 文件类型扩展名,例如 .js .less
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof ResultFile
|
||||||
|
*/
|
||||||
|
ext: string;
|
||||||
|
/**
|
||||||
|
* 文件内容
|
||||||
|
*
|
||||||
|
* @type {string}
|
||||||
|
* @memberof ResultFile
|
||||||
|
*/
|
||||||
|
content: string;
|
||||||
|
}
|
||||||
@ -12,5 +12,5 @@ export interface DataSourceConfig {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface DataSource {
|
export interface DataSource {
|
||||||
items: DataSourceConfig[];
|
list: DataSourceConfig[];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -51,7 +51,7 @@ export interface FieldExtraProps {
|
|||||||
mode?: 'plaintext' | 'paragraph' | 'article';
|
mode?: 'plaintext' | 'paragraph' | 'article';
|
||||||
// 从 contentEditable 获取内容并设置到属性
|
// 从 contentEditable 获取内容并设置到属性
|
||||||
onSaveContent?: (content: string, prop: any) => any;
|
onSaveContent?: (content: string, prop: any) => any;
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface FieldConfig extends FieldExtraProps {
|
export interface FieldConfig extends FieldExtraProps {
|
||||||
|
|||||||
@ -15,3 +15,5 @@ export * from './setter-config';
|
|||||||
export * from './setting-target';
|
export * from './setting-target';
|
||||||
export * from './node';
|
export * from './node';
|
||||||
export * from './transform-stage';
|
export * from './transform-stage';
|
||||||
|
export * from './code-intermediate';
|
||||||
|
export * from './code-result';
|
||||||
|
|||||||
@ -1,18 +1,20 @@
|
|||||||
import { ComponentsMap } from './npm';
|
import { ComponentsMap } from './npm';
|
||||||
import { CompositeValue, JSExpression, CompositeObject, JSONObject } from './value-type';
|
import { CompositeValue, JSExpression, JSFunction, CompositeObject, JSONObject } from './value-type';
|
||||||
import { DataSource } from './data-source';
|
import { DataSource } from './data-source';
|
||||||
import { I18nMap } from './i18n';
|
import { I18nMap } from './i18n';
|
||||||
import { UtilsMap } from './utils';
|
import { UtilsMap } from './utils';
|
||||||
|
|
||||||
|
// 搭建基础协议 - 单个组件树节点描述
|
||||||
|
// 转换成一个 .jsx 文件内 React Class 类 render 函数返回的 jsx 代码
|
||||||
export interface NodeSchema {
|
export interface NodeSchema {
|
||||||
id?: string;
|
id?: string;
|
||||||
componentName: string;
|
componentName: string; // 组件名称 必填、首字母大写
|
||||||
props?: PropsMap | PropsList;
|
props?: PropsMap | PropsList; // 组件属性对象
|
||||||
leadingComponents?: string;
|
leadingComponents?: string;
|
||||||
condition?: CompositeValue;
|
condition?: CompositeValue; // 渲染条件
|
||||||
loop?: CompositeValue;
|
loop?: CompositeValue; // 循环数据
|
||||||
loopArgs?: [string, string];
|
loopArgs?: [string, string]; // 循环迭代对象、索引名称 ["item", "index"]
|
||||||
children?: NodeData | NodeData[];
|
children?: NodeData | NodeData[]; // 子节点
|
||||||
|
|
||||||
// ------- future support -----
|
// ------- future support -----
|
||||||
conditionGroup?: string;
|
conditionGroup?: string;
|
||||||
@ -30,6 +32,7 @@ export type PropsList = Array<{
|
|||||||
}>;
|
}>;
|
||||||
|
|
||||||
export type NodeData = NodeSchema | JSExpression | DOMText;
|
export type NodeData = NodeSchema | JSExpression | DOMText;
|
||||||
|
export type NodeDataType = NodeData | NodeData[];
|
||||||
|
|
||||||
export function isDOMText(data: any): data is DOMText {
|
export function isDOMText(data: any): data is DOMText {
|
||||||
return typeof data === 'string';
|
return typeof data === 'string';
|
||||||
@ -45,10 +48,10 @@ export interface ContainerSchema extends NodeSchema {
|
|||||||
[key: string]: CompositeValue;
|
[key: string]: CompositeValue;
|
||||||
};
|
};
|
||||||
methods?: {
|
methods?: {
|
||||||
[key: string]: JSExpression;
|
[key: string]: JSExpression | JSFunction;
|
||||||
};
|
};
|
||||||
lifeCycles?: {
|
lifeCycles?: {
|
||||||
[key: string]: JSExpression;
|
[key: string]: JSExpression | JSFunction;
|
||||||
};
|
};
|
||||||
css?: string;
|
css?: string;
|
||||||
dataSource?: DataSource;
|
dataSource?: DataSource;
|
||||||
@ -69,7 +72,6 @@ export interface BlockSchema extends NodeSchema {
|
|||||||
componentName: 'Block';
|
componentName: 'Block';
|
||||||
}
|
}
|
||||||
export interface SlotSchema extends NodeSchema {
|
export interface SlotSchema extends NodeSchema {
|
||||||
name?: string;
|
|
||||||
componentName: 'Slot';
|
componentName: 'Slot';
|
||||||
params?: string[];
|
params?: string[];
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,13 +1,17 @@
|
|||||||
import { NpmInfo } from './npm';
|
import { NpmInfo } from './npm';
|
||||||
|
import { JSFunction } from './value-type';
|
||||||
|
|
||||||
export type UtilsMap = Array<
|
export interface InternalUtils {
|
||||||
| {
|
name: string;
|
||||||
name: string;
|
type: 'function';
|
||||||
type: 'npm';
|
content: JSFunction;
|
||||||
content: NpmInfo;
|
}
|
||||||
}
|
|
||||||
| {
|
export interface ExternalUtils {
|
||||||
name: string;
|
name: string;
|
||||||
type: '';
|
type: 'npm' | 'tnpm';
|
||||||
}
|
content: NpmInfo;
|
||||||
>;
|
}
|
||||||
|
|
||||||
|
export type IUtilItem = InternalUtils | ExternalUtils;
|
||||||
|
export type UtilsMap = IUtilItem[];
|
||||||
|
|||||||
@ -11,14 +11,18 @@ export interface JSExpression {
|
|||||||
* 模拟值
|
* 模拟值
|
||||||
*/
|
*/
|
||||||
mock?: any;
|
mock?: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 函数
|
||||||
|
export interface JSFunction {
|
||||||
|
type: 'JSFunction';
|
||||||
/**
|
/**
|
||||||
* 额外扩展属性,如 extType、events
|
* 表达式字符串
|
||||||
*/
|
*/
|
||||||
[key: string]: any;
|
value: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface JSSlot {
|
export interface JSSlot {
|
||||||
name?: string;
|
|
||||||
type: 'JSSlot';
|
type: 'JSSlot';
|
||||||
title?: string;
|
title?: string;
|
||||||
// 函数的入参
|
// 函数的入参
|
||||||
@ -39,17 +43,20 @@ export interface JSONObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 复合类型
|
// 复合类型
|
||||||
export type CompositeValue = JSONValue | JSExpression | JSSlot | CompositeArray | CompositeObject;
|
export type CompositeValue = JSONValue | JSExpression | JSFunction | JSSlot | CompositeArray | CompositeObject;
|
||||||
export type CompositeArray = CompositeValue[];
|
export type CompositeArray = CompositeValue[];
|
||||||
export interface CompositeObject {
|
export interface CompositeObject {
|
||||||
[key: string]: CompositeValue;
|
[key: string]: CompositeValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
export function isJSExpression(data: any): data is JSExpression {
|
export function isJSExpression(data: any): data is JSExpression {
|
||||||
return data && data.type === 'JSExpression';
|
return data && data.type === 'JSExpression';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function isJSFunction(data: any): data is JSFunction {
|
||||||
|
return data && data.type === 'JSFunction';
|
||||||
|
}
|
||||||
|
|
||||||
export function isJSSlot(data: any): data is JSSlot {
|
export function isJSSlot(data: any): data is JSSlot {
|
||||||
return data && data.type === 'JSSlot';
|
return data && data.type === 'JSSlot';
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user