@lcap/asl
Version:
NetEase Application Specific Language
1,278 lines • 47.2 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ExpressionNode = exports.LogicNode = exports.LogicItem = exports.logicItemArrayKeyOfLogicItem = exports.logicItemKeyOfLogicItem = exports.evaluate = exports.LOGIC_TYPE = void 0;
const decorators_1 = require("../decorators");
const __1 = require("..");
const logic_1 = require("../../service/logic");
const utils_1 = require("../utils");
const cacheData_1 = require("../cacheData");
const tools_1 = require("./tools");
const Structure_1 = __importDefault(require("../data/Structure"));
var LOGIC_TYPE;
(function (LOGIC_TYPE) {
// LogicNode
LOGIC_TYPE["Start"] = "Start";
LOGIC_TYPE["ProcessOutcome"] = "ProcessOutcome";
LOGIC_TYPE["End"] = "End";
LOGIC_TYPE["IfStatement"] = "IfStatement";
LOGIC_TYPE["SwitchStatement"] = "SwitchStatement";
LOGIC_TYPE["SwitchCase"] = "SwitchCase";
LOGIC_TYPE["ForEachStatement"] = "ForEachStatement";
LOGIC_TYPE["WhileStatement"] = "WhileStatement";
LOGIC_TYPE["AssignmentExpression"] = "AssignmentExpression";
LOGIC_TYPE["Comment"] = "Comment";
LOGIC_TYPE["CallLogic"] = "CallLogic";
LOGIC_TYPE["CallInterface"] = "CallInterface";
LOGIC_TYPE["CallInterParam"] = "CallInterParam";
LOGIC_TYPE["CallGraphQL"] = "CallGraphQL";
LOGIC_TYPE["DBQuery"] = "DBQuery";
LOGIC_TYPE["CronJob"] = "CronJob";
LOGIC_TYPE["JSONSerialize"] = "JSONSerialize";
LOGIC_TYPE["JSONDeserialize"] = "JSONDeserialize";
LOGIC_TYPE["CallMessageShow"] = "CallMessageShow";
LOGIC_TYPE["CallConsoleLog"] = "CallConsoleLog";
LOGIC_TYPE["JSBlock"] = "JSBlock";
LOGIC_TYPE["TypeNote"] = "TypeNote";
LOGIC_TYPE["CallQueryComponent"] = "CallQueryComponent";
// Expression
LOGIC_TYPE["Identifier"] = "Identifier";
LOGIC_TYPE["NumericLiteral"] = "NumericLiteral";
LOGIC_TYPE["BooleanLiteral"] = "BooleanLiteral";
LOGIC_TYPE["StringLiteral"] = "StringLiteral";
LOGIC_TYPE["NullLiteral"] = "NullLiteral";
LOGIC_TYPE["UnaryExpression"] = "UnaryExpression";
LOGIC_TYPE["BinaryExpression"] = "BinaryExpression";
LOGIC_TYPE["LogicalExpression"] = "LogicalExpression";
LOGIC_TYPE["MemberExpression"] = "MemberExpression";
LOGIC_TYPE["CallExpression"] = "CallExpression";
LOGIC_TYPE["ObjectExpression"] = "ObjectExpression";
LOGIC_TYPE["ArrayExpression"] = "ArrayExpression";
LOGIC_TYPE["Destination"] = "Destination";
LOGIC_TYPE["DestinationParam"] = "DestinationParam";
LOGIC_TYPE["BuiltInFunction"] = "BuiltInFunction";
LOGIC_TYPE["BuiltInFuncParam"] = "BuiltInFuncParam";
LOGIC_TYPE["Unparsed"] = "Unparsed";
LOGIC_TYPE["QuerySelectExpression"] = "QuerySelectExpression";
LOGIC_TYPE["QueryFromExpression"] = "QueryFromExpression";
LOGIC_TYPE["QueryJoinExpression"] = "QueryJoinExpression";
LOGIC_TYPE["QueryAggregateExpression"] = "QueryAggregateExpression";
})(LOGIC_TYPE = exports.LOGIC_TYPE || (exports.LOGIC_TYPE = {}));
function evaluate(node, finalCode = true) {
if (!node)
return '';
if (node.type === 'Identifier')
return node.code || node.name;
if (node.type === 'NumericLiteral')
return node.value;
if (node.type === 'BooleanLiteral')
return `${node.value}`;
if (node.type === 'StringLiteral')
return `'${node.value}'`;
if (node.type === 'NullLiteral')
return 'null';
if (node.type === 'BinaryExpression') {
let left = evaluate(node.left, finalCode);
if (!finalCode && node.left?.type === LOGIC_TYPE.MemberExpression)
left = `(${left})`;
let right = evaluate(node.right, finalCode);
if (!finalCode && node.right?.type === LOGIC_TYPE.MemberExpression)
right = `(${right})`;
return `${left} ${node.operator} ${right}`;
}
if (node.type === 'LogicalExpression') {
let left = evaluate(node.left, finalCode);
if (!finalCode && node.left?.type === LOGIC_TYPE.MemberExpression)
left = `(${left})`;
let right = evaluate(node.right, finalCode);
if (!finalCode && node.right?.type === LOGIC_TYPE.MemberExpression)
right = `(${right})`;
return `${left} ${node.operator} ${right}`;
}
if (node.type === LOGIC_TYPE.UnaryExpression && node.operator === '!') {
const argument = node.argument;
const code = evaluate(argument, finalCode);
const arr = [LOGIC_TYPE.BinaryExpression, LOGIC_TYPE.LogicalExpression];
if (!finalCode)
arr.push(LOGIC_TYPE.MemberExpression);
return arr.includes(argument?.type) ? `!(${code})` : `!${code}`;
}
if (node.type === 'Unparsed') {
return node.code;
}
if (node.type === 'MemberExpression') {
const object = evaluate(node.object, finalCode);
const property = node.property;
if (finalCode || property.code?.includes('ID_ENUMVALUE_')) {
if (property.type === 'Identifier')
return `${object}.${property.code || property.name}`;
else if (property.type === 'StringLiteral')
return `${object}['${property.value}']`;
else if (property.type === 'NumericLiteral')
return `${object}[${property.value}]`;
}
else {
const lastPart = object.split(' && ').pop();
if (property.type === 'Identifier')
return `${object} && ${lastPart}.${property.code || property.name}`;
else if (property.type === 'StringLiteral')
return `${object} && ${lastPart}['${property.value}']`;
else if (property.type === 'NumericLiteral')
return `${object} && ${lastPart}[${property.value}]`;
}
}
if (node.type === 'CallExpression') {
const args = [];
for (const argumentNode of node.arguments) {
args.push(evaluate(argumentNode, finalCode));
}
const name = node.callee.name;
return `${name}(${args.join(', ')})`;
}
if (node.type === 'ObjectExpression') {
const obj = {};
for (let { key, value } of node.properties) {
let keyValue = evaluate(key, finalCode);
if (/^"(.*)"$/.test(keyValue))
keyValue = RegExp.$1;
const valueTemp = evaluate(value, finalCode);
if (/^"(.*)"$/.test(valueTemp))
value = RegExp.$1;
obj[keyValue] = value;
}
return JSON.stringify(obj);
}
if (node.type === 'ArrayExpression') {
const arr = [];
for (const elementNode of node.elements) {
arr.push(evaluate(elementNode, finalCode));
}
return '[' + arr.join(', ') + ']';
}
if (node.type === 'Destination') {
const params = (node.params || [])
.filter((param) => param.pageParamKey && param.pageParamKeyValue)
.map((param) => evaluate(param.pageParamKey, finalCode) + '=${' + evaluate(param.pageParamKeyValue, finalCode) + '}');
let result = node.code;
if (params.length) {
result = '`' + `${node.code}?${params.join('&')}` + '`';
}
else {
result = '`' + `${result}` + '`';
}
return result.replace(/"/g, "'");
}
if (node.type === 'BuiltInFunction') {
const calleeCode = `$utils['${node.calleeCode}']`;
if (!calleeCode)
return;
// 需要保持params顺序
const params = (node.builtInFuncParams || [])
.map((param) => param.builtInFuncParamValue ? evaluate(param.builtInFuncParamValue, finalCode) : null);
let paramResult = params.join(',');
if (paramResult === ',') {
paramResult = '';
}
else {
paramResult = params.join(',');
}
return `${calleeCode}(${paramResult})`.replace(/"/g, "'");
}
if (node.type === 'TypeNote') {
const { type, format } = node.schema;
return `{ type: '${type}', format: '${format}' }`;
}
}
exports.evaluate = evaluate;
exports.logicItemKeyOfLogicItem = ['test', 'left', 'right', 'each', 'item', 'index', 'start', 'end', 'variables', 'taskId', 'processInstanceId', 'startedBy', 'errorMessage', 'callInterParamValue', 'builtInFuncParamValue', 'pageParamKey', 'pageParamKeyValue', 'argument',
'select', 'from', 'limit', 'orderElement', 'aggregateParam', 'order', 'pageElement', 'pageSizeElement', 'groupElement',
];
exports.logicItemArrayKeyOfLogicItem = ['body', 'consequent', 'alternate', 'cases', 'params', 'arguments', 'builtInFuncParams',
'groupBy', 'orderBy', 'selectElementList', 'joinPartList', 'onExpressionList', 'where', 'having',
];
/**
* 逻辑项类
*/
class LogicItem extends __1.Vertex {
/**
* @param source 需要合并的部分参数
*/
constructor(source) {
super();
/**
* 概念类型
*/
this.level = __1.LEVEL_ENUM.logicItem;
/**
* Id
*/
this.id = undefined;
/**
* 父级 Id
*/
this.parentId = undefined;
/**
* 所属父级属性
*/
this.parentAttr = undefined;
this.parent = undefined;
this.logicId = undefined;
this.logic = undefined;
/**
* 标题
*/
this.label = undefined;
this.folded = false;
this.placeholderName = undefined;
/**
* OffsetX
*/
this.offsetX = undefined;
/**
* OffsetY
*/
this.offsetY = undefined;
/**
* 所在位置
*/
this._posIndex = undefined;
/**
* 标题
*/
this.type = undefined;
/**
* Ref
*/
this.refTarget = undefined;
this.callInterParam = undefined;
this.callInterParamValue = undefined;
this.builtInFuncParamValue = undefined;
this.pageParamKey = undefined;
this.pageParamKeyValue = undefined;
/**
* CallQueryComponent 对应的 structure 的 id
*/
this.structureRef = undefined;
this.schema = undefined;
/**
* 类型校验结果
*/
this.typeCheckNote = undefined;
source && this.assign(source);
}
/**
* 纯前端添加
*/
addIn(parent, parentId, parentAttr, _posIndex) {
if (!parent) {
if (!this.logic)
return;
if (this.logic.playgroundId === parentId) { // In playgroundId
const index = _posIndex || this.logic.playground.length;
this.logic.playground.splice(index, 0, this);
}
else { // In main body 这个后面让忠杰改成数组吧
const index = this.logic.body.findIndex((item) => item.id === parentId);
~index && this.logic.body.splice(index + 1, 0, this);
this.logic.body.forEach((item, index) => {
if (index) {
item.assign({ parentId: this.logic.body[index - 1].id });
}
});
}
}
else {
this.assign({ parent, parentAttr });
const attr = parent[parentAttr];
if (Array.isArray(attr)) {
const index = _posIndex;
~index && attr.splice(index, 0, this);
}
else {
if (!parentAttr)
return;
parent.assign({ [parentAttr]: this });
}
}
}
/**
* @temp 临时的
* @param body
*/
static preprocess(body) {
utils_1.traverse((current) => {
delete current.node.editable;
if (current.node.type !== 'ForEachStatement')
delete current.node.index;
// 处理 CallGraphQL
if (current.node.type === 'CallGraphQL') {
const body = current.node;
delete body.paramsType;
delete body.optionalParams;
body.params && body.params.forEach((param, index) => {
param._posIndex = index;
});
delete body.querySchemaMap;
delete body.singularResolverName;
body.querySchemaList = JSON.stringify(body.querySchemaList || []);
}
}, { node: body }, { mode: 'anyObject' });
// 处理 CallInterface
if (body.type === 'CallInterface') {
delete body.paramsType;
delete body.optionalParams;
body.params.forEach((param, index) => {
param._posIndex = index;
});
}
}
/**
* 创建
* @requires this.logic
* @param parent
* @param parentId
* @param parentAttr
* @param _posIndex
* @param cache 在前端不处理节点
*/
async create({ parent, parentId, parentAttr, _posIndex, cache, offsetX, offsetY, }, actionOptions) {
__1.config.defaultApp?.emit('saving');
const prevParent = this.parent;
if (parent) {
const attr = parent[parentAttr];
if (_posIndex === undefined && Array.isArray(attr))
_posIndex = attr.length;
}
offsetX = offsetX ?? this.offsetX;
offsetY = offsetY ?? this.offsetY;
const body = this.toJSON();
body.parentId = parentId;
body.parentAttr = parentAttr;
body._posIndex = _posIndex;
body.offsetX = offsetX;
body.offsetY = offsetY;
LogicItem.preprocess(body);
let result;
if (actionOptions?.actionMode !== __1.ACTION_MODE.undoRedo) {
__1.utils.logger.debug(`在该逻辑节点的属性"${parentAttr}"上插入一个节点"`, body);
body.logicId = this.logic && this.logic.id;
result = await logic_1.logicService.addItem({
headers: {
appId: __1.config.defaultApp?.id,
serviceId: this.logic?.interface?.serviceId,
operationAction: 'LogicItem.create',
operationDesc: actionOptions?.actionDesc || `添加逻辑项"${this.label || this.type}"`,
operationIgnore: actionOptions?.actionIgnore,
},
body,
});
this.deepPick(result, ['id', 'parentId', 'parentAttr', 'joinPartRef', 'structureRef']);
}
this.assign({
parent,
parentId,
parentAttr,
offsetX,
offsetY,
logicId: this.logic && this.logic.id,
});
LogicItem.from(this, this.logic, this.parent, false);
!cache && this.addIn(parent, parentId, parentAttr, _posIndex);
__1.utils.traverse(({ node }) => {
if (node.type === LOGIC_TYPE.CallQueryComponent) {
// 兼容 流程-流程节点 内部逻辑
const service = this.logic.processComponent ? this.logic.processComponent.process?.service : this.logic.interface?.service;
const structure = Structure_1.default.from({
id: node.structureRef,
}, service);
structure.loadPro();
}
}, { node: this }, {
mode: 'anyObject',
excludedKeySet: this.JSON_EXCLUDED_KEYS,
});
this.logic && this.logic.emit('change');
if (actionOptions?.checkTypeIgnore !== true) {
this.checkType();
prevParent && prevParent.checkType();
}
await __1.config.defaultApp?.history.load(actionOptions?.actionMode !== __1.ACTION_MODE.undoRedo && {
operationAction: 'LogicItem.create',
operationBeforeImage: null,
operationAfterImage: JSON.parse(JSON.stringify(this)),
operationDesc: `添加逻辑项"${this.label || this.type}"`,
});
__1.config.defaultApp?.emit('saved');
}
/**
* 创建或移动
* @requires this.logic
* @param parent
* @param parentId
* @param parentAttr
* @param _posIndex
* @param cache 在前端不处理节点
*/
async move({ parent, parentId, parentAttr, _posIndex, cache, offsetX, offsetY, }, actionOptions) {
__1.config.defaultApp?.emit('saving');
const prevParent = this.parent;
if (parentAttr && !parent) {
parent = cacheData_1.vertexsMap.get(parentId);
}
if (parent) {
const attr = parent[parentAttr];
if (_posIndex === undefined && Array.isArray(attr))
_posIndex = attr.length;
}
const body = this.toJSON();
body.parentId = parentId;
body.parentAttr = parentAttr;
body._posIndex = _posIndex;
LogicItem.preprocess(body);
if (actionOptions?.actionMode !== __1.ACTION_MODE.undoRedo) {
__1.utils.logger.debug(`在该逻辑节点的属性"${parentAttr}"上插入一个节点"`, body);
const result = await logic_1.logicService.moveItem({
headers: {
appId: __1.config.defaultApp?.id,
operationAction: 'LogicItem.move',
operationDesc: actionOptions?.actionDesc || `移动逻辑项"${this.label || this.type}"`,
},
body: {
id: body.id,
moveFromLogicItem: {
parentId: this.parentId,
parentAttr: this.parentAttr,
_posIndex: this._posIndex,
offsetX: this.offsetX,
offsetY: this.offsetY,
},
moveToLogicItem: {
parentId,
parentAttr,
_posIndex,
offsetX,
offsetY,
},
},
});
}
if (!(this.parentId === parentId && this.parentId === this.logic.playgroundId && this.parentAttr === parentAttr)) {
// 以下几句顺序不能变,注意!
!cache && this.remove();
this.assign({
parent,
parentId,
parentAttr,
offsetX,
offsetY,
});
!cache && this.addIn(parent, parentId, parentAttr, _posIndex);
}
else {
this.assign({
offsetX,
offsetY,
});
}
this.logic && this.logic.emit('change');
this.checkType();
prevParent && prevParent.checkType();
await __1.config.defaultApp?.history.load(actionOptions?.actionMode !== __1.ACTION_MODE.undoRedo && {
operationAction: 'LogicItem.move',
operationBeforeImage: null,
operationAfterImage: null,
operationDesc: `移动逻辑项"${this.label || this.type}"`,
});
__1.config.defaultApp?.emit('saved');
}
/**
* 创建或移动
* @requires this.logic
* @param parent
* @param parentId
* @param parentAttr
* @param _posIndex
* @param cache 在前端不处理节点
*/
createOrMove(options, actionOptions) {
if (this.id)
return this.move(options, actionOptions);
else
return this.create(options, actionOptions);
}
/**
* 粘贴
* @param logicItems
* @param targetType
* @param targetId
*/
static async paste(logicItems, targetType, targetId) {
if (!Array.isArray(logicItems))
logicItems = [logicItems];
logicItems.forEach((logicItem) => {
LogicItem.preprocess(logicItem);
});
const res = await logic_1.logicService.paste({
body: {
type: 'logicItem',
logicItems,
targetId,
targetType,
},
headers: {
appId: __1.config.defaultApp?.id,
operationAction: 'LogicItem.paste',
operationDesc: `粘贴逻辑项"${logicItems[0].label || logicItems[0].type}"`,
},
});
LogicItem.redoPaste(res);
}
static async redoPaste(res) {
const logic = cacheData_1.vertexsMap.get(res.targetId);
res.logicItems.forEach((logicItem) => {
logicItem = LogicItem.from(logicItem, logic, null);
logic.playground.push(logicItem);
logicItem.checkType();
__1.utils.traverse(({ node }) => {
if (node.type === LOGIC_TYPE.CallQueryComponent) {
// 兼容 流程-流程节点 内部逻辑
const service = node.logic.processComponent ? node.logic.processComponent.process?.service : node.logic.interface?.service;
const structure = Structure_1.default.from({
id: node.structureRef,
}, service);
structure.loadPro();
}
}, { node: logicItem }, {
mode: 'anyObject',
excludedKeySet: logicItem.JSON_EXCLUDED_KEYS,
});
});
await __1.config.defaultApp?.history.load();
__1.config.defaultApp?.emit('saved');
}
static async undoPaste(res) {
const logic = cacheData_1.vertexsMap.get(res.targetId);
const { playground } = logic;
for (let i = playground.length - 1; i >= 0; i--) {
if (res.logicItems.find((item) => item.id === playground[i].id)) {
__1.typeCheck.delete(playground[i].id);
playground.splice(i, 1);
}
}
logic.interface?.service?.syncStructures(); // 处理 CallQueryComponent 嵌套的情形
await __1.config.defaultApp?.history.load();
__1.config.defaultApp?.emit('saved');
}
/**
* 粘贴预处理,用于粘贴到表达式输入弹窗。此处,粘贴没有立即提交到后端,点击确定按钮后才提交。
* @param logicItems
* @param targetType
* @param targetId
*/
static async pretreatmentBeforePaste(logicItems, targetType, targetId) {
if (!Array.isArray(logicItems))
logicItems = [logicItems];
logicItems.forEach((logicItem) => {
LogicItem.preprocess(logicItem);
});
function removeId(logicItems) {
return JSON.parse(JSON.stringify(logicItems, (key, value) => key === 'id' ? undefined : value));
}
return logic_1.logicService.pretreatmentBeforePaste({
body: {
type: 'logicItem',
logicItems,
targetId,
targetType,
},
}).then((res) => {
res.logicItems = removeId(res.logicItems);
return res;
});
}
/**
* 纯前端创建
*/
virtualCreate(parent, parentId, parentAttr, _posIndex, cache) {
if (parent) {
const attr = parent[parentAttr];
if (_posIndex === undefined && Array.isArray(attr))
_posIndex = attr.length;
}
this.addIn(parent, parentId, parentAttr, _posIndex);
}
/**
* 纯前端 replaceWith
*/
async virtualReplaceWith(logicItem) {
this.remove();
let _posIndex;
if (this.parent) {
const attr = this.parent[this.parentAttr];
if (Array.isArray(attr))
_posIndex = attr.indexOf(this);
}
logicItem.virtualCreate(this.parent, this.parentId, this.parentAttr, _posIndex, false);
this.assign(logicItem);
return this;
}
/**
* 纯前端删除
*/
remove() {
// 处理 old
if (!this.parent) {
if (!this.logic)
return;
if (this.logic.playgroundId === this.parentId) { // In playgroundId
const index = this.logic.playground.indexOf(this);
~index && this.logic.playground.splice(index, 1);
}
else { // In main body 这个后面让忠杰改成数组吧
const index = this.logic.body.indexOf(this);
~index && this.logic.body.splice(index, 1);
this.logic.body.forEach((item, index) => {
if (index) {
item.assign({ parentId: this.logic.body[index - 1].id });
}
});
}
}
else {
const attr = this.parent[this.parentAttr];
if (Array.isArray(attr)) {
const index = attr.indexOf(this);
~index && attr.splice(index, 1);
}
else {
this.parent.assign({ [this.parentAttr]: null });
}
}
}
/**
* 删除逻辑节点
* @param cache 在前端不处理节点
*/
async delete(cache, actionOptions) {
__1.config.defaultApp?.emit('saving');
if (actionOptions?.actionMode !== __1.ACTION_MODE.undoRedo) {
if (this.id) {
const body = this.toPlainJSON();
/// @TODO: 不知道哪里来的 index
delete body.index;
///
try {
await logic_1.logicService.removeItem({
headers: {
appId: __1.config.defaultApp?.id,
serviceId: this.logic?.interface?.serviceId,
operationAction: 'LogicItem.delete',
operationDesc: `删除逻辑项"${this.label || this.type}"`,
},
body,
});
}
catch (err) {
await __1.config.defaultApp?.history.load();
throw err;
}
}
}
if (this.id) {
__1.typeCheck.delete(this.id);
this.logic.interface?.service?.syncStructures(); // 处理 CallQueryComponent 嵌套的情形
const parent = this.parent;
if (parent && parent.checkType) {
parent.checkType();
}
}
!cache && this.remove();
this.destroy();
this.logic && this.logic.emit('change');
await __1.config.defaultApp?.history.load(actionOptions?.actionMode !== __1.ACTION_MODE.undoRedo && {
operationAction: 'LogicItem.delete',
operationBeforeImage: JSON.parse(JSON.stringify(this)),
operationAfterImage: null,
operationDesc: `删除逻辑项"${this.label || this.type}"`,
});
__1.config.defaultApp?.emit('saved');
}
/**
* LogicItem 有选择框的情况,为了减少变量变更,使用 replaceWith 的方式
*/
async replaceWith(logicItem) {
await this.delete(true);
let _posIndex;
if (this.parent) {
const attr = this.parent[this.parentAttr];
if (Array.isArray(attr))
_posIndex = attr.indexOf(this);
}
await logicItem.createOrMove({
parent: this.parent,
parentId: this.parentId,
parentAttr: this.parentAttr,
_posIndex,
cache: true,
});
logicItem.assign({
offsetX: this.offsetX,
offsetY: this.offsetY,
});
this.assign(logicItem);
this.logic && this.logic.emit('change');
return this;
}
/**
* 修改逻辑项
*/
async update(source, actionOptions) {
__1.config.defaultApp?.emit('saving');
if (source) {
// 处理子节点
if (Object.values(source).some((value) => typeof value === 'object')) {
source = LogicItem.from(source, this.logic, this.parent);
__1.utils.clearObject(source);
}
this.assign(source);
}
// const body = this.toPlainJSON();
const body = this.toJSON();
body.params = this.params && JSON.parse(JSON.stringify(this.params));
body.querySchemaList = this.querySchemaList && Array.from(this.querySchemaList);
body.returnSchema = this.returnSchema;
if (this.parentAttr === 'item')
body.schema = this.schema;
if (this.type === 'TypeNote')
body.schema = this.schema;
LogicItem.preprocess(body);
__1.utils.logger.debug('修改逻辑项', body);
if (actionOptions?.actionMode !== __1.ACTION_MODE.undoRedo) {
const result = await logic_1.logicService.updateItem({
headers: {
appId: __1.config.defaultApp?.id,
operationAction: 'LogicItem.update',
operationDesc: `修改逻辑项"${this.label || this.type}"`,
operationIgnore: actionOptions?.actionIgnore,
},
body,
});
// this.deepPick(result, ['id', 'parentId', 'parentAttr']);
// 合并params里的id
if (body.params && body.params.length) {
const logicItem = LogicItem.from(result, this.logic, this.parent);
this.assign({ params: logicItem.params });
}
if (body.builtInFuncParams && body.builtInFuncParams.length) {
const logicItem = LogicItem.from(result, this.logic, this.parent);
this.assign({ builtInFuncParams: logicItem.builtInFuncParams });
}
}
// 处理 each 的问题
if (this.parentAttr === 'each') {
const each = this;
const item = this.parent.item;
let eachSchema = tools_1.getSchemaOfExpressionNode(each);
if (eachSchema) {
eachSchema = eachSchema.schema || eachSchema;
// eachSchema = convert2SchemaType(eachSchema);
item.schema = eachSchema.items; // 兼容老的items形式
if (eachSchema.type === 'genericType') {
item.schema = eachSchema.typeInstantiation.typeParams[0].typeParamValue;
}
if (!item.schema) {
item.schema = eachSchema;
}
return item.update(undefined, {
actionIgnore: true,
});
}
}
this.emitVertexIdToNameChange();
this.logic && this.logic.emit('change');
this.checkType();
await __1.config.defaultApp?.history.load(actionOptions?.actionMode !== __1.ACTION_MODE.undoRedo && {
operationAction: 'LogicItem.update',
operationBeforeImage: null,
operationAfterImage: null,
operationDesc: `修改逻辑项"${this.label || this.type}"`,
});
__1.config.defaultApp?.emit('saved');
return this;
}
/**
* 设置逻辑项标题
* @param label 标题
*/
async setLabel(label) {
this.assign({ label });
await this.update(undefined, {
actionDesc: '设置逻辑项标题',
});
}
/**
* 从后端 JSON 生成规范的 ExpressionNode 对象
* @param source JSON
* @param logic 父级 logic
*/
static from(source, logic, parent, shouldCreateNewItem = true) {
if (source.level === __1.LEVEL_ENUM.variable && source.type === LOGIC_TYPE.Identifier)
source.code = `ID_${source.id}`;
let logicItem;
if (!shouldCreateNewItem && (source instanceof LogicItem))
logicItem = source;
else
logicItem = source.level === 'logicNode' ? new LogicNode(source) : new ExpressionNode(source);
logicItem.assign({
logic,
parent,
});
if (logicItem.type === LOGIC_TYPE.CallGraphQL) {
const querySchemaList = logicItem.querySchemaList;
logicItem.assign({ querySchemaList: querySchemaList && typeof querySchemaList === 'string' ? JSON.parse(querySchemaList || '[]') : querySchemaList });
}
if (logicItem.type === LOGIC_TYPE.CallQueryComponent) {
logicItem.assign({
logicName: logic.name,
serviceId: logic.interface?.serviceId,
});
}
if (['QueryFromExpression', 'QueryJoinExpression', 'QueryAggregateExpression'].includes(logicItem.type)) {
logicItem.assign({
serviceId: logic?.interface?.serviceId,
});
}
exports.logicItemKeyOfLogicItem.forEach((key) => {
if (source[key]) {
if (source[key].level === __1.LEVEL_ENUM.logicNode)
logicItem.assign({ [key]: LogicNode.from(source[key], logic, logicItem) });
else if (source[key].level === __1.LEVEL_ENUM.expressionNode || source[key].level === __1.LEVEL_ENUM.variable)
logicItem.assign({ [key]: ExpressionNode.from(source[key], logic, logicItem) });
else if (!Array.isArray(source[key]) && !Object.keys(source[key]).length)
logicItem.assign({ [key]: null });
}
});
exports.logicItemArrayKeyOfLogicItem.forEach((key) => {
if (Array.isArray(source[key]))
logicItem.assign({ [key]: source[key].map((item) => LogicItem.from(item, logic, logicItem)) });
});
if (logicItem.callInterParam) {
logicItem.assign({ refTarget: LogicItem.getVertexByRef(logicItem.callInterParam) });
}
else if (logicItem.interfaceKey) {
logicItem.assign({ refTarget: LogicItem.getVertexByRef(logicItem.interfaceKey) });
}
return logicItem;
}
/**
* 校验类型
*/
async checkType() {
let crt = this;
const nodes = [];
do {
if (!['builtInFuncParams'].includes(crt.parentAttr)
&& !(crt instanceof ExpressionNode && crt.parent instanceof LogicNode)
&& (crt instanceof ExpressionNode || !crt.parent))
nodes.push(crt);
// CallQueryComponent 内部的节点不用checkType
if (crt.parent?.type === LOGIC_TYPE.CallQueryComponent)
nodes.splice(0, nodes.length);
crt = crt.parent;
} while (crt instanceof LogicItem);
for (const node of nodes) {
await this._checkType(node);
}
}
async _checkType(node) {
const res = await logic_1.logicService.checkType({
query: {
logicId: this.logic && this.logic.id,
loItemId: node.id,
},
});
if (res) {
res.logicId = this.logic && this.logic.id;
__1.typeCheck.pushAll([res]);
LogicItem.assignTypeCheckResult(node, res);
}
return res;
}
static assignTypeCheckResult(logicItem, typeCheckResult) {
if (Array.isArray(logicItem)) {
const map = new Map();
for (const item of typeCheckResult) {
map.set(item.id, item);
}
for (let i = 0; i < logicItem.length; i++) {
LogicItem.assignTypeCheckResult(logicItem[i], map.get(logicItem[i].id));
}
return;
}
if (!typeCheckResult || !logicItem || typeof typeCheckResult !== 'object')
return;
// if(logicItem.id === typeCheckResult.id)
logicItem.typeCheckNote = typeCheckResult.typeCheckNote;
for (const [key, object] of Object.entries(typeCheckResult)) {
if (['id', 'typeCheckNote', 'processComponentId', 'attributes'].includes(key))
continue;
LogicItem.assignTypeCheckResult(logicItem[key], object);
}
}
/**
* 生成 JS 脚本
*/
toScript() { return ''; }
getLogicItem(type) {
let node = this;
while (node) {
if (node.type === LOGIC_TYPE[type])
return node;
node = node.parent;
}
return undefined;
}
getSelectedTabOfCallQueryComponent(activeImage) {
const map = {
where: 'where',
from: 'from',
groupBy: 'groupBy',
select: 'groupBy',
having: 'groupBy',
orderBy: 'orderBy',
limit: 'orderBy',
};
let node = this;
while (node) {
if (node.parent?.type === LOGIC_TYPE.CallQueryComponent) {
const parentAttr = node.parentAttr;
return {
tab: map[parentAttr],
parentAttr,
};
}
node = node.parent;
}
if (activeImage?.parentAttr && map[activeImage.parentAttr])
return {
tab: map[activeImage.parentAttr],
parentAttr: activeImage.parentAttr,
};
}
}
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "level", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "id", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "parentId", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "parentAttr", void 0);
__decorate([
decorators_1.excludedInJSON(),
decorators_1.immutable()
], LogicItem.prototype, "parent", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "logicId", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "logic", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "label", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "folded", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "placeholderName", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "offsetX", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "offsetY", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "_posIndex", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "type", void 0);
__decorate([
decorators_1.excludedInJSON(),
decorators_1.immutable()
], LogicItem.prototype, "refTarget", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "callInterParam", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "callInterParamValue", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "builtInFuncParamValue", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "pageParamKey", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "pageParamKeyValue", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "structureRef", void 0);
__decorate([
decorators_1.immutable()
], LogicItem.prototype, "schema", void 0);
__decorate([
decorators_1.excludedInJSON()
], LogicItem.prototype, "typeCheckNote", void 0);
__decorate([
decorators_1.action('删除逻辑节点')
], LogicItem.prototype, "delete", null);
__decorate([
decorators_1.action('设置逻辑项标题')
], LogicItem.prototype, "setLabel", null);
exports.LogicItem = LogicItem;
class LogicNode extends LogicItem {
/**
* @param source 需要合并的部分参数
*/
constructor(source) {
super();
/**
* 逻辑节点类型
*/
this.type = undefined;
this.test = undefined;
this.consequent = undefined;
this.alternate = undefined;
this.cases = undefined;
this.each = undefined;
this.item = undefined;
this.index = undefined;
this.start = undefined;
this.end = undefined;
this.body = undefined;
this.operator = undefined;
this.left = undefined;
this.right = undefined;
this.arguments = undefined;
this.params = undefined;
this.value = undefined;
this.method = undefined;
this.entity = undefined;
this.action = undefined;
this.processDefinitionKey = undefined;
this.taskId = undefined;
this.finished = undefined;
this.processInstanceId = undefined;
this.schemaRef = undefined;
this.returnSchema = undefined;
this.cron = undefined;
this.page = undefined;
this.url = undefined;
this.code = undefined;
this.calleeCode = undefined;
this.interfaceKey = undefined;
this.name = undefined;
this.from = undefined;
const hasInstantiated = source && source.id && cacheData_1.vertexsMap.get(source.id) instanceof LogicNode;
if (hasInstantiated) {
console.warn(`LogicNode (${source.id}) 多次实例化`);
// Object.assign(vertexsMap.get(source.id), source);
// return vertexsMap.get(source.id) as LogicNode;
}
source && this.assign(source);
}
}
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "type", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "test", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "consequent", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "each", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "item", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "index", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "start", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "end", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "body", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "operator", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "left", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "right", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "arguments", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "params", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "value", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "method", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "entity", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "action", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "processDefinitionKey", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "taskId", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "finished", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "processInstanceId", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "schemaRef", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "returnSchema", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "cron", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "page", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "url", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "code", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "calleeCode", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "interfaceKey", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "name", void 0);
__decorate([
decorators_1.immutable()
], LogicNode.prototype, "from", void 0);
exports.LogicNode = LogicNode;
class ExpressionNode extends LogicItem {
/**
* @param source 需要合并的部分参数
*/
constructor(source) {
super();
/**
* 逻辑节点类型
*/
this.type = undefined;
this.left = undefined;
this.right = undefined;
this.code = undefined;
this.name = undefined;
this.key = undefined;
this.value = undefined;
this.object = undefined;
this.property = undefined;
this.operator = undefined;
this.properties = undefined;
this.elements = undefined;
this.callee = undefined;
this.argument = undefined;
/**
* SchemaRef
*/
this.schemaRef = undefined;
this.joinType = undefined;
source && this.assign(source);
}
}
__decorate([
decorators_1.immutable()
], ExpressionNode.prototype, "type", void 0);
__decorate([
decorators_1.immutable()
], ExpressionNode.prototype, "left", void 0);
__decorate([
decorators_1.immutable()
], ExpressionNode.prototype, "right", void 0);
__decorate([
decorators_1.immutable()
], ExpressionNode.prototype, "code", void 0);
__decorate([
decorators_1.immutable()
], ExpressionNode.prototype, "name", void 0);
__decorate([
decorators_1.immutable()
], ExpressionNode.prototype, "key", void 0);
__decorate([
decorators_1.immutable()
], ExpressionNode.prototype, "value", void 0);
__decorate([
decorators_1.immutable()
], ExpressionNode.prototype, "object", void 0);
__decorate([
decorators_1.immutable()
], ExpressionNode.prototype, "property", void 0);
__decorate([
decorators_1.immutable()
], ExpressionNode.prototype, "operator", void 0);
__decorate([
decorators_1.immutable()
], ExpressionNode.prototype, "properties", void 0);
__decorate([
decorators_1.immutable()
], ExpressionNode.prototype, "elements", void 0);
__decorate([
decorators_1.immutable()
], ExpressionNode.prototype, "callee", void 0);
__decorate([
decorators_1.immutable()
], ExpressionNode.prototype, "argument", void 0);
__decorate([
decorators_1.immutable()
], ExpressionNode.prototype, "schemaRef", void 0);
__decorate([
decorators_1.immutable()
], ExpressionNode.prototype, "joinType", void 0);
exports.ExpressionNode = ExpressionNode;
//# sourceMappingURL=LogicItem.js.map