@lcap/nasl
Version:
NetEase Application Specific Language
826 lines • 38.6 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.transformCallLogic2Match = exports.tryTransformTS2UI = exports.transformNode2Expression = void 0;
/* eslint-disable global-require */
/* eslint-disable @typescript-eslint/no-use-before-define */
const utils_1 = require("./transforms/utils");
const lodash_1 = require("lodash");
const babel = __importStar(require("@babel/core"));
const utils_2 = require("../utils");
const transform2TypeAnnotation_1 = require("./transforms/transform2TypeAnnotation");
const transform2LogicItem_1 = require("./transforms/transform2LogicItem");
const tools_1 = require("./tools");
const nasl_concepts_1 = require("@lcap/nasl-concepts");
function getLastAlternate(node) {
let target;
if (node.alternate.type === 'IfStatement') {
return getLastAlternate(node.alternate);
}
else if (Array.isArray(node.alternate.body)) {
if (node.alternate.body.length === 1) {
target = node.alternate.body[0]?.argument || node.alternate.body[0]?.expression;
}
else {
return node.alternate.body;
}
}
return target;
}
// 处理生命周期函数
function transformLifecycle(node) {
const bindEvents = [];
node.properties?.forEach((property) => {
const eventName = property?.key?.name?.replace(/^on/, '')?.toLowerCase();
const bindEvent = new utils_1.naslTypes.BindEvent({ name: eventName });
property.value.elements.forEach((element) => {
let logicName = element?.id?.name || '';
logicName = bindEvent.getLogicUniqueName(logicName);
const curLogic = transformNode2Logic(element, logicName, 'view_logic');
bindEvent.addLogic(curLogic);
});
bindEvents.push(bindEvent);
});
return bindEvents;
}
// 处理变量
function transformVariableDeclaration(node, options) {
const declList = node?.declarations || [];
let newNode;
declList?.forEach((decl) => {
const variableName = decl.id.name;
const varTypeAnnotation = decl.id.typeAnnotation?.typeAnnotation;
newNode = new utils_1.naslTypes.Variable({
name: variableName,
typeAnnotation: varTypeAnnotation && (0, transform2TypeAnnotation_1.transform2TypeAnnotation)(varTypeAnnotation),
});
if (decl.init) {
if (decl.init.type !== 'ArrayExpression') {
// 变量值需要默认值还是赋值,在使用的地方处理
newNode.defaultValue = new utils_1.naslTypes.DefaultValue({
expression: transformNode2Expression(decl.init, options),
});
}
}
});
// 注释添加到描述
const comments = node?.trailingComments || [];
comments?.forEach((comment) => {
if (comment?.type === 'CommentLine') {
newNode.description = comment?.value;
}
});
return newNode;
}
// 处理表达式
function transformNode2Expression(node, options) {
if (!options?.transformNodeFunction) {
options.transformNodeFunction = transformNode2Expression;
}
if (!node)
return null;
(0, transform2LogicItem_1.fixLogicNode)(node);
// console.log('lemon ~~~ transformNode2Expression:', node);
if (node.type === 'VariableDeclaration') {
return transformVariableDeclaration(node, options);
}
if (node.type === 'CommentLine' || node.type === "CommentBlock") {
return (0, transform2LogicItem_1.transform2Comment)(node, options);
}
if (node.type === 'CallExpression') {
const callee = (0, transform2LogicItem_1.flatMemberExpression)(node.callee);
const calleeName = (0, utils_1.generate)(node.callee).code;
const transformCalleeParams = [node, calleeName, callee, options];
// console.log('lemon ~~~ CallExpression', node, callee, calleeName);
if (callee.length === 1 && (node.callee.type === 'FunctionExpression' && node.callee.id?.name === 'match' || node.callee.type === 'ArrowFunctionExpression')) {
// (function match() {})(...) 的情况
return (0, transform2LogicItem_1.transformCallFunctionExpression2Match)(node, calleeName, callee, options);
}
if (/^\$refs\./.test(calleeName)) {
return (0, transform2LogicItem_1.transformCall2CallViewElementLogic)(...transformCalleeParams);
}
if (callee.length === 2 && callee[0].type === 'Identifier' && callee[0].name.endsWith('Entity')) {
return (0, transform2LogicItem_1.transformCall2CallEntityLogic)(...transformCalleeParams);
}
// 需求变更 consoleLog 都转成nasl.logging
if (calleeName === 'nasl.util.consoleLog' || calleeName === 'console.log') {
return (0, transform2LogicItem_1.transformCall2ConsoleLog)(...transformCalleeParams);
}
if (calleeName.startsWith('nasl.logging.')) {
return (0, transform2LogicItem_1.transformCall2Logging)(...transformCalleeParams);
}
if (calleeName === 'nasl.util.jsonSerialize' || calleeName === 'nasl.util.jsonDeserialize') {
return (0, transform2LogicItem_1.transformCall2JSONFunctions)(...transformCalleeParams);
}
;
if (calleeName.startsWith('function match')) {
return transformCallLogic2Match(node, options);
}
if (calleeName.startsWith('nasl.util.')) {
return (0, transform2LogicItem_1.transformCall2CallFunction)(...transformCalleeParams);
}
if (callee.length === 3 && calleeName.startsWith('nasl.ui.')) {
return (0, transform2LogicItem_1.transform2UIFunction)(...transformCalleeParams);
}
if (calleeName.endsWith('.map')) {
return (0, transform2LogicItem_1.transformMap2ListTransform)(...transformCalleeParams);
}
if (calleeName === 'PAGINATE') {
return (0, transform2LogicItem_1.transformCall2Paginate)(...transformCalleeParams);
}
if (calleeName === 'ForEach') {
return (0, transform2LogicItem_1.transform2ForEachStatement)(...transformCalleeParams);
}
if (callee.length === 2 && calleeName.endsWith('.forEach')) {
return (0, transform2LogicItem_1.transformForEach2ForEachStatement)(...transformCalleeParams);
}
else if (['plus', 'minus', 'multiply', 'divide', 'remainder'].includes(calleeName)) {
return (0, transform2LogicItem_1.transformCallExpressionToBinaryExpression)(...transformCalleeParams);
}
else if (calleeName === 'alert') {
return (0, transform2LogicItem_1.transformAlert2ShowMessage)(...transformCalleeParams);
}
else if (/^app.dataSources|app.logics/.test(calleeName)) {
return (0, transform2LogicItem_1.transformCall2CallDataSourceLogic)(...transformCalleeParams);
}
else if (callee.length === 1) {
if (calleeName.startsWith('viewLogic_')) {
return (0, transform2LogicItem_1.transformCall2CallViewLogic)(...transformCalleeParams);
}
if (calleeName === 'FROM') {
// TODO
return new utils_1.naslTypes.CallLogic({
calleeNamespace: `app.logics`,
calleeName,
arguments: [],
});
}
return (0, transform2LogicItem_1.transformCall2Logic)(...transformCalleeParams);
}
else if (/interfaces/.test(calleeName)) {
return (0, transform2LogicItem_1.transformCall2Interface)(...transformCalleeParams);
}
else if (/connector./.test(calleeName)) {
return (0, transform2LogicItem_1.transformCall2Connector)(...transformCalleeParams);
}
else if (/extensions./.test(calleeName)) {
return (0, transform2LogicItem_1.transformCall2Extension)(...transformCalleeParams);
}
else if (/nasl.auth./.test(calleeName)) {
return (0, transform2LogicItem_1.transformCall2LogicWithAuth)(...transformCalleeParams);
}
else if (/nasl.processV2./.test(calleeName)) {
return transformExpression2ProcessV2(node, calleeName, options);
}
else if (calleeName === 'nasl.js.block') { // 兼容JS代码块
const code = (0, utils_1.generate)(node.arguments[0]).code.trim().slice(1, -1);
return new utils_1.naslTypes.JSBlock({ code });
}
else {
(0, utils_1.throwError)(`Unhandled node ${callee.map((item) => item.name).join('.')} ${node.type}`);
}
}
else if (node.type === 'IfStatement') {
return (0, transform2LogicItem_1.transform2IfStatement)(node, options);
}
else if (node.type === 'WhileStatement') {
return (0, transform2LogicItem_1.transform2WhileStatement)(node, options);
}
else if (node.type === 'SwitchStatement') {
return (0, transform2LogicItem_1.transformSwitchStatement2Match)(node, options);
}
else if (node.type === 'MemberExpression') {
return (0, transform2LogicItem_1.transformMemberExpression)(node, options);
}
else if (node.type === 'Identifier') {
if (node.name === 'undefined')
return void 0;
return (0, transform2LogicItem_1.transformIdentifier)(node, options);
}
else if (node.type === 'ExpressionStatement') {
return transformNode2Expression(node.expression, options);
}
else if (node.type === 'AssignmentExpression') {
return (0, transform2LogicItem_1.transform2Assignment)(node, options);
}
else if (node.type === 'NewExpression') {
return (0, transform2LogicItem_1.transformNewExpression)(node, options);
}
else if (node.type === 'ArrowFunctionExpression') {
return (0, transform2LogicItem_1.transform2AnonymousFunction)(node, options);
}
else if (node.type === 'BooleanLiteral') {
return (0, transform2LogicItem_1.transform2BooleanLiteral)(node, options);
}
else if (node.type === 'StringLiteral') {
return (0, transform2LogicItem_1.transform2StringLiteral)(node, options);
}
else if (node.type === 'NumericLiteral') {
return (0, transform2LogicItem_1.transform2NumericLiteral)(node, options);
}
else if (node.type === 'NullLiteral') {
return (0, transform2LogicItem_1.transform2NullLiteral)(node, options);
}
else if (node.type === 'TemplateLiteral') {
return (0, transform2LogicItem_1.transform2StringInterpolation)(node, options);
}
else if (node.type === 'BinaryExpression' || node.type === 'LogicalExpression') {
return (0, transform2LogicItem_1.transform2BinaryExpression)(node, options);
}
else if (node.type === 'UnaryExpression') {
if (['!'].includes(node.operator)) {
return new utils_1.naslTypes.UnaryExpression({
operator: node.operator,
argument: transformNode2Expression(node.argument, options),
});
}
if (['-'].includes(node.operator) && node.argument.type === 'NumericLiteral') {
return transformNode2Expression({
type: 'NumericLiteral',
value: -node.argument.value,
}, options);
}
(0, utils_1.throwError)(`Unhandled node ${node.type}`);
}
else if (node.type === 'UpdateExpression') {
return (0, transform2LogicItem_1.transformUpdateExpression2Assignment)(node, options);
}
else if (node.type === 'ReturnStatement') {
return (0, transform2LogicItem_1.transformReturnStatement2AssignmentOrEnd)(node, options);
}
else if (node.type === 'EmptyStatement') {
return (0, transform2LogicItem_1.transform2Comment)(node, options);
}
else if (node.type === 'BlockStatement') {
return transformNode2Expression(node?.body?.[0], options);
}
else if (node.type === 'ObjectExpression' && node?.properties?.length > 0) {
return (0, transform2LogicItem_1.transform2PartialNewComposite)(node, options);
}
else if (node.type === 'FunctionExpression') { // 处理子逻辑
const curLogic = new utils_1.naslTypes.SubLogic({
name: node.id.name,
});
const statements = node.body.body;
statements?.forEach((item) => {
const logicItem = transformNode2Expression(item, { transformType: 'logic', logicType: 'event_logic', logic: curLogic, transformNodeFunction: transformNode2Expression });
if (logicItem) {
curLogic.insertItemInBodyAt(logicItem, curLogic.body.length - 1);
}
});
return curLogic;
}
else if (node.type === 'ContinueStatement') {
return (0, transform2LogicItem_1.transform2Continue)();
}
else if (node.type === 'BreakStatement') {
return (0, transform2LogicItem_1.transform2Break)();
}
else if (node.type === 'ForOfStatement') {
return (0, transform2LogicItem_1.transformForOf2ForEachStatement)(node, { isPageLogic: true });
}
else {
(0, utils_1.throwError)(`Unhandled node ${node.type}`);
}
}
exports.transformNode2Expression = transformNode2Expression;
// 处理逻辑
function transformNode2Logic(node, name, logicType) {
const parameters = node.params;
const statements = node.body.body;
const curLogic = new utils_1.naslTypes.Logic({ name: name ?? node.id.name });
const options = { transformType: 'logic', logicType, logic: curLogic, transformNodeFunction: transformNode2Expression };
if (options.transformType === 'logic' && options.logicType !== 'event_logic') {
parameters.forEach((item) => {
const param = (0, transform2LogicItem_1.transform2Param)(item);
if (param && param.name !== 'event' && !curLogic.params.find((_) => _.name === param.name))
curLogic.addParam(param);
});
}
const newStatements = [];
statements.forEach((node, index) => {
if (node?.leadingComments?.length) {
newStatements.push(...node?.leadingComments);
}
newStatements.push(node);
if (node?.trailingComments?.length && index === statements.length - 1) {
newStatements.push(...node?.trailingComments);
}
});
newStatements?.forEach((item) => {
let logicItem = transformNode2Expression(item, options);
if (logicItem && logicItem?.concept !== 'End') {
if (logicItem.concept === 'Variable') {
if (!curLogic.variables.find((_) => _.name === logicItem.name))
curLogic.addVariable({ ...logicItem, defaultValue: undefined });
logicItem = new utils_1.naslTypes.Assignment({
left: new utils_1.naslTypes.Identifier({ name: logicItem?.name }),
right: logicItem.defaultValue?.expression || '',
});
if (logicItem.right)
curLogic.insertItemInBodyAt(logicItem, curLogic.body.length - 1);
}
else {
curLogic.insertItemInBodyAt(logicItem, curLogic.body.length - 1);
}
}
});
if (options.transformType === 'logic' && options.logicType === 'event_logic') {
// 事件逻辑将返回值添加到变量中
if (curLogic?.returns?.length) {
if (!curLogic.variables.find((_) => _.name === curLogic?.returns?.[0]?.name))
curLogic.addVariable(curLogic.returns[0]);
curLogic.returns = [];
}
}
// 注释添加到描述
const comments = node?.trailingComments || [];
comments?.forEach((comment) => {
if (comment?.type === 'CommentLine') {
curLogic.description = comment?.value;
}
});
return curLogic;
}
// 处理属性
function transformNode2Attribute(node) {
const options = { transformType: 'attr', transformNodeFunction: transformNode2Expression };
let item = {};
let newNode = {};
if (['StringLiteral', 'NumericLiteral'].includes(node.value.type)) {
const type = node.value.type === 'StringLiteral' ? 'string' : 'static';
item = {
name: node.key.name,
type,
value: node.value.value,
};
}
else if (['ArrowFunctionExpression'].includes(node.value.type)) {
item = {
name: node.key.name,
type: 'string',
value: (0, utils_1.generate)(node.value.body).code,
};
}
else if (['CallExpression'].includes(node.value.type) && node.value?.callee?.name === 'sync') {
item = {
name: node.key.name,
type: 'dynamic',
sync: true,
expression: transformNode2Expression(node.value.arguments[0], options),
};
}
else if (['destination'].includes(node.key.name)) {
const namespace = node?.value?.arguments?.[0]?.value;
const nsArr = namespace.split('.').map((it) => it.replace(/_view$/, ''));
const pageType = nsArr.shift();
const viewName = nsArr.pop();
const newArguments = node?.value?.arguments?.slice(1);
let argument = [];
if (newArguments?.[0]?.type === 'ObjectExpression') {
argument = newArguments?.[0]?.properties?.map((property) => new utils_1.naslTypes.Argument({
keyword: property?.key?.name,
expression: (0, transform2LogicItem_1.fixExpression)(property?.value, options),
}));
}
else {
argument = node?.arguments?.slice(1)?.map((arg) => new utils_1.naslTypes.Argument({
expression: (0, transform2LogicItem_1.fixExpression)(arg, options),
}));
}
const destination = new utils_1.naslTypes.Destination({
viewNamespace: `app.frontendTypes.${pageType}.frontends.${pageType}.views${nsArr?.map((it) => `.${it}.views`)?.join('')}`,
viewName,
arguments: argument,
});
item = {
name: node?.key?.name,
type: 'dynamic',
destination,
};
}
else {
// ['TemplateLiteral', 'BooleanLiteral', 'NullLiteral', 'CallExpression']
item = {
name: node.key.name,
type: 'dynamic',
expression: transformNode2Expression(node.value, options),
};
}
if (['_if', '_tooltip'].includes(node.key.name)) {
// 指令
const propertyName = node.key.name.replace(/^_/, '').replace(/([A-Z])/g, '-$1').toLowerCase();
if (propertyName === 'tooltip') {
item.rawName = 'v-tooltip';
}
newNode = new utils_1.naslTypes.BindDirective({ ...item, name: propertyName });
}
else if (['_staticStyle'].includes(node.key.name)) {
newNode = {
concept: 'staticStyle',
value: item.value
};
// 自定义样式
}
else if (['_color', '_backgroundColor', '_backgroundImage'].includes(node.key.name)) {
// 样式属性
const propertyName = node.key?.name?.replace(/^_/, '').replace(/([A-Z])/g, '-$1').toLowerCase();
newNode = new utils_1.naslTypes.BindStyle({ ...item, name: propertyName });
}
else {
// 组件属性
newNode = new utils_1.naslTypes.BindAttribute(item);
}
return newNode;
}
function transformNode2ViewElement(node, componentName) {
const viewNode = node.arguments?.[0];
if (viewNode.type === 'ObjectExpression') {
const tag = (0, lodash_1.kebabCase)((node?.callee).name);
const name = componentName?.replace(/-/g, '_');
const newViewElement = new utils_1.naslTypes.ViewElement({
tag,
name,
});
viewNode.properties?.forEach((prop, propIndex) => {
if (prop?.value?.type === 'ArrayExpression' && ['FunctionExpression', 'ArrowFunctionExpression'].includes(prop?.value?.elements?.[0]?.type)) {
// 事件逻辑
const eventName = prop?.key?.name?.replace(/^on/, '')?.toLowerCase();
const bindEvent = new utils_1.naslTypes.BindEvent({ name: eventName });
prop.value.elements.forEach((element) => {
const logicName = bindEvent.getLogicUniqueName();
const curLogic = transformNode2Logic(element, logicName, 'event_logic');
bindEvent.addLogic(curLogic);
});
newViewElement.addBindEvent(bindEvent);
}
else if (['FunctionExpression', 'ArrowFunctionExpression'].includes(prop?.value?.type) && /^on/.test(prop.key.name)) {
// 事件逻辑
const eventName = prop?.key?.name?.replace(/^on/, '')?.toLowerCase();
const bindEvent = new utils_1.naslTypes.BindEvent({ name: eventName });
const logicName = bindEvent.getLogicUniqueName();
bindEvent.addLogic(transformNode2Logic(prop.value, logicName, 'event_logic'));
newViewElement.addBindEvent(bindEvent);
}
else if (['FunctionExpression', 'ArrowFunctionExpression'].includes(prop?.value?.type) && ['ArrayExpression'].includes(prop.value.body?.type)) {
// 子组件
const slotTarget = prop.key.name.replace(/^slot/, '').toLowerCase();
if (slotTarget === 'default') {
// 默认插槽,不需要 template
if (prop.value.body?.elements?.length) {
prop.value.body.elements.forEach((element, index) => {
// $ref.componentName = new xxx({}) 形式,这种是标准的
if (element.type === 'AssignmentExpression' && element.right?.type === 'NewExpression') {
const elementName = element?.left?.property?.name;
newViewElement.addViewElement(transformNode2ViewElement(element.right, elementName));
}
// new xxx({}) 形式,这种是没有组件名称,为了兼容,自己建一个
if (element.type === 'NewExpression') {
const eleTag = (0, lodash_1.kebabCase)((element?.callee).name);
const eleName = `${eleTag}_${index}_${newViewElement.name}`;
newViewElement.addViewElement(transformNode2ViewElement(element, eleName));
}
});
}
}
else {
const slotScope = prop.value?.params[0]?.name || '';
const newTemplateElement = new utils_1.naslTypes.ViewElement({
tag: 'template',
slotTarget,
slotScope,
});
if (prop.value.body?.elements?.length) {
prop.value.body.elements.forEach((element, index) => {
// $ref.componentName = new xxx({}) 形式,这种是标准的
if (element.type === 'AssignmentExpression' && element.right?.type === 'NewExpression') {
newTemplateElement.name = `template_${(0, utils_2.genHash)(`${slotTarget}_template_${propIndex}_${name}`)}`;
const elementName = element?.left?.property?.name;
newTemplateElement.addViewElement(transformNode2ViewElement(element.right, elementName));
}
// new xxx({}) 形式,这种是没有组件名称,为了兼容,自己建一个
if (element.type === 'NewExpression') {
newTemplateElement.name = `template_${(0, utils_2.genHash)(`${slotTarget}_template_${propIndex}_${name}`)}`;
const eleTag = (0, lodash_1.kebabCase)((element?.callee).name);
const eleName = `${eleTag}_${index}_${newTemplateElement.name}`;
newTemplateElement.addViewElement(transformNode2ViewElement(element, eleName));
}
});
}
newViewElement.addViewElement(newTemplateElement);
}
}
else {
const newNode = transformNode2Attribute(prop);
if (newNode.concept === 'BindDirective') {
newViewElement.addBindDirective(newNode);
}
else if (newNode.concept === 'BindStyle') {
newViewElement.addBindStyle(newNode);
}
else if (newNode.concept === 'BindAttribute') {
newViewElement.addBindAttribute(newNode);
}
else if (newNode.concept === 'StaticStyle') {
newViewElement.setStaticStyle(newNode.value);
}
}
});
return newViewElement;
}
}
/**
* 转换Node为View下的构件
*/
function transformNode2ViewConstruct(node) {
// console.log("lemon ~ transformNode2ViewConstruct ~ node:", node);
const attrOptions = { transformType: 'attr', transformNodeFunction: transformNode2Expression };
// 变量声明
if (node.type === 'VariableDeclaration') {
const declList = node?.declarations || [];
const declListFirstNodde = declList[0];
const variableName = declListFirstNodde?.id?.name;
if (variableName === '$lifecycles' && declListFirstNodde.init) {
return transformLifecycle(declListFirstNodde.init);
}
return transformVariableDeclaration(node, attrOptions);
}
// 页面逻辑
if (node.type === 'FunctionDeclaration') {
const logicName = node.id.name.replace(/^viewLogic_/, '');
return transformNode2Logic(node, logicName, 'view_logic');
}
if (node.type === 'ExpressionStatement') {
return transformNode2ViewConstruct(node.expression);
}
// 组件
if (node.type === 'AssignmentExpression' && node.right?.type === 'NewExpression') {
const componentName = node?.left?.property?.name;
return transformNode2ViewElement(node.right, componentName);
}
if (node.type === 'ReturnStatement' && node?.argument?.type === 'CallExpression') {
if (node?.argument?.callee?.name === 'remove') {
return null;
}
return transformNode2ViewConstruct(node.argument.arguments?.[1]);
}
if (node.type === 'ReturnStatement' && node?.argument?.type === 'ArrayExpression') {
const newViewElement = [];
node?.argument.elements.forEach((item) => {
const { properties } = item;
if (properties?.[0].value.value === 'remove' && properties?.[2].value.value === 'ViewElement') {
newViewElement.push({
aiParams: {
action: properties?.[0].value.value,
selectedNodeName: properties?.[1].value.value,
concept: properties?.[2].value.value,
object: {}
}
});
}
else {
properties?.[3].value.elements.forEach((element) => {
let newNode = {};
const propertiesMap = ['BindDirective', 'BindStyle', 'BindAttribute'];
if (properties?.[2].value.value === 'ViewElement') {
newNode = transformNode2ViewConstruct(element);
}
else if (propertiesMap.includes(properties?.[2]?.value?.value)) {
newNode = transformNode2Attribute({ key: element.left, value: element.right });
}
else if (properties?.[2]?.value?.value === 'BindEvent') {
const eventName = element?.left?.name?.replace(/^on/, '')?.toLowerCase();
const bindEvent = new utils_1.naslTypes.BindEvent({ name: eventName });
const logicName = bindEvent.getLogicUniqueName();
bindEvent.addLogic(transformNode2Logic(element?.right?.elements[0], logicName, 'event_logic'));
newNode = bindEvent;
}
const newNodeBackup = (0, lodash_1.cloneDeep)(newNode);
newNode.aiParams = {
action: properties?.[0].value.value,
selectedNodeName: properties?.[1].value.value,
concept: properties?.[2].value.value,
object: newNodeBackup
};
newViewElement.push(newNode);
});
}
});
return newViewElement;
}
// throwError(`Unhandled node ${ node }`);
console.error('warning: Unhandled node', node);
return null;
}
/**
* 转换Node为View
*/
function transformNode2View(node, root, unNeedUID) {
const parameters = node.params;
let statements = node.body.body;
const currentPositionComment = root?.comments.find((comment) => comment.type === 'CommentLine' && comment.value === ' 当前页面');
if (currentPositionComment) {
statements = statements.filter((stat) => stat.start > currentPositionComment.start);
}
const view = new utils_1.naslTypes.View();
if (parameters?.length === 1 && parameters?.[0]?.type === 'ObjectPattern') {
const { properties } = parameters[0] || {};
properties?.forEach((item) => {
const param = (0, transform2LogicItem_1.transform2Param)(item);
view.params = view.params || [];
param && view.params.push(param);
});
}
else {
parameters?.forEach((item) => {
const param = (0, transform2LogicItem_1.transform2Param)(item);
view.params = view.params || [];
param && view.params.push(param);
});
}
const json = [];
statements.forEach((item) => {
const viewItem = transformNode2ViewConstruct(item);
if (item.type === 'ReturnStatement' && item?.argument?.type === 'CallExpression') {
const action = item.argument?.callee?.name;
const selectedNodeName = item.argument.arguments?.[0]?.property?.name;
const newNodeBackup = (0, lodash_1.cloneDeep)(viewItem);
viewItem.aiParams = { selectedNodeName, action, concept: 'ViewElement', object: newNodeBackup };
}
if (item.type === 'ReturnStatement' && item?.argument?.type === 'ArrayExpression') {
viewItem?.forEach((element) => {
if (element.aiParams)
json.push(element.aiParams);
if (element?.concept === 'ViewElement')
view.addViewElement(element);
});
}
if (viewItem?.concept === 'Variable') {
if (!view.variables.find((_) => _.name === viewItem.name))
view.addVariable(viewItem);
}
if (viewItem?.concept === 'Logic') {
if (!view.logics.find((_) => _.name === viewItem.name))
view.addLogic(viewItem);
}
if (viewItem?.concept === 'ViewElement') {
view.addViewElement(viewItem);
if (viewItem.aiParams)
json.push(viewItem.aiParams);
}
// 生命周期函数
if (item.type === 'VariableDeclaration' && Array.isArray(viewItem) && viewItem[0]?.concept === 'BindEvent') {
viewItem.forEach((bindEvent) => {
view.addBindEvent(bindEvent);
});
}
});
// console.log("lemon ~ 转换出的 view:", view);
if (!unNeedUID) {
const { node: newView } = (0, tools_1.genAIUID)(view, 'nl2ui');
const { node: newJSON } = (0, tools_1.genAIUID)(json, 'nl2ui');
return { view: newView.toJSON(), json: newJSON };
}
else {
return { view: view.toJSON(), json: json };
}
}
/**
* 转换ts代码为View
*/
const transformTS2View = (tsCode, unNeedUID) => {
const root = babel.parseSync(tsCode, {
filename: 'result.ts',
presets: [require('@babel/preset-typescript')],
});
let func;
if (root.program?.body[0]?.type === 'ExportNamedDeclaration') {
func = root.program?.body[0]?.declaration;
}
else {
func = root.program?.body[0];
}
// console.log("lemon ~ 初始 node", func);
return transformNode2View(func, root, unNeedUID);
};
const handleNodeName = (curView, object, memory) => {
const list = [...memory || []];
if (object.concept === 'ViewElement') {
const oldName = object.name;
const newName = curView?.getViewElementUniqueNameOld(oldName);
if (oldName !== newName) {
object.name = `${newName}_${(0, utils_2.genHash)(new Date().getTime() + newName)}`;
list.push({ oldName, newName: object.name });
}
if (object?.children?.length) {
object.children.forEach((child) => {
const { list: childList } = handleNodeName(curView, child, list);
// 去重并合并
list.push(...childList?.filter((item) => !list?.find((it) => it.oldName === item.oldName)));
});
}
}
return { list };
};
function tryTransformTS2UI(tsCode, curView, unNeedUID) {
if (tsCode.includes('```')) {
const cap = tsCode.match(/```.*\n([\s\S]+?)```/);
if (cap)
tsCode = cap[1].trim();
}
if (!curView)
return transformTS2View(tsCode, unNeedUID);
const newView = new utils_1.naslTypes.View(curView);
const { json } = transformTS2View(tsCode);
const replaceNameList = [];
const selectedNodeNames = [];
json.forEach((item) => {
if (item && item.concept === 'ViewElement' && item.action !== 'remove') {
selectedNodeNames.push(item.selectedNodeName.replace('$refs.', ''));
const { list } = handleNodeName(newView, item.object.toJSON());
replaceNameList.push(...list);
}
});
replaceNameList.forEach((item) => {
if (!selectedNodeNames.includes(item.oldName)) {
tsCode = tsCode.replace(new RegExp(item.oldName, 'g'), item.newName);
}
});
return transformTS2View(tsCode);
}
exports.tryTransformTS2UI = tryTransformTS2UI;
// 流程2.0的接口定义
function transformExpression2ProcessV2(node, calleeName, options) {
const processV2Logics = (0, nasl_concepts_1.getStdlibNamespace)().findChild('processV2').logics || [];
const funcName = calleeName.split('.').pop();
const args = node.arguments;
const logicDefinition = processV2Logics.find((item) => item.name === funcName);
const argsList = logicDefinition?.params?.map((param, index) => new utils_1.naslTypes.Argument({
expression: transformNode2Expression(args?.[index], options),
keyword: param.name,
})) ?? [];
return new utils_1.naslTypes.CallLogic({
calleeNamespace: 'nasl.processV2',
calleeName: funcName,
arguments: argsList,
});
}
function transformCallLogic2Match(node, options) {
if (node.callee.type === 'FunctionExpression') {
const lastAlternate = getLastAlternate(node.callee.body.body[0]);
// 有额外标记时,isExpression根据额外标记来判断
const extraMark = node?.leadingComments?.find?.((comment) => comment.type === 'CommentBlock' && comment.value.startsWith('isExpression'));
const isExpression = extraMark ? extraMark.value === 'isExpression=true' : options.transformType === 'attr';
return new utils_1.naslTypes.Match({
expression: transformNode2Expression(node.arguments[0], options),
isExpression,
cases: [
...(0, transform2LogicItem_1.flatIfStatementForMatch)(node.callee.body.body[0]).map((_case) => {
return new utils_1.naslTypes.MatchCase({
isMatchedTypeEnumable: _case.test?.left?.name === '_value',
patterns: !_case.test
? []
: (0, transform2LogicItem_1.flatMatchPatternsExpression)(transformNode2Expression(_case.test, options)),
body: _case.consequent.body
.filter((item) => item.type !== 'BreakStatement')
.map((item) => transformNode2Expression(item?.argument || item?.expression || item, options))
.filter((item) => !!item),
});
}),
new utils_1.naslTypes.MatchCase({
isMatchedTypeEnumable: false,
patterns: [],
body: lastAlternate
? Array.isArray(lastAlternate)
? lastAlternate.map((item) => transformNode2Expression(item, options))
: [transformNode2Expression(lastAlternate, options)]
: [],
}),
],
});
}
}
exports.transformCallLogic2Match = transformCallLogic2Match;
//# sourceMappingURL=transformTS2UI.js.map