@lcap/nasl
Version:
NetEase Application Specific Language
722 lines • 37.1 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.parseNaturalTSXView = exports.transformTSDeclareFunction2View = exports.transform2View = exports.transformJSXElement2ViewElement = exports.transform2Variables = 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 transform2Logic_1 = require("./transforms/transform2Logic");
const transform2ValidationRule_1 = require("./transforms/transform2ValidationRule");
const transformThemeAndStyle_1 = require("./transforms/transformThemeAndStyle");
function transform2Variables(node, options) {
const variables = [];
const declList = node?.declarations || [];
declList.forEach((decl) => {
const variableName = decl.id.name;
let typeAnnotation = (0, transform2TypeAnnotation_1.transform2TypeAnnotation)(decl.id.typeAnnotation?.typeAnnotation, options) || undefined;
const variable = new utils_1.naslTypes.Variable({
name: variableName,
typeAnnotation,
});
if (decl.init) {
variable.defaultValue = new utils_1.naslTypes.DefaultValue({
expression: (0, transform2LogicItem_1.transform2LogicItem)(decl.init, { ...options, transformType: 'attr', typeAnnotation, isRestricted: true, isInFrontend: true }),
});
}
variables.push(variable);
});
return variables;
}
exports.transform2Variables = transform2Variables;
function transform2EventLogics(node, eventName, options) {
if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') {
const logic = (0, transform2Logic_1.transform2Logic)(node, eventName, { ...options, logicType: 'event_logic' });
logic.params = [];
return [logic];
}
else if (node.type === 'CallExpression') {
if (node.callee.type === 'Identifier' && node.callee.name === '$all') {
const args = node.arguments;
return args.map((node) => {
if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') {
const logic = (0, transform2Logic_1.transform2Logic)(node, eventName, { ...options, logicType: 'event_logic' });
logic.params = [];
return logic;
}
else {
return (0, utils_1.throwError)(options, '事件逻辑参数不支持的类型', node.type, node);
}
}).filter(Boolean);
}
else {
return (0, utils_1.throwError)(options, '事件逻辑参数不正确', node);
}
}
else if (node.type === 'Identifier' || node.type === 'MemberExpression') {
return (0, utils_1.throwError)(options, '事件逻辑参数不正确,不支持绑定逻辑,需要直接写在元素中', node);
}
else {
return (0, utils_1.throwError)(options, '事件逻辑参数不正确', node);
}
}
function handleDirectoryItem(directoryItem, nextStatement, view, options, callerName) {
let definitionItem = null;
if (nextStatement.type === 'VariableDeclaration') {
// 处理变量声明
const variables = transform2Variables(nextStatement, options);
definitionItem = variables[0];
}
else if (nextStatement.type === 'FunctionDeclaration') {
// 处理函数/逻辑声明
definitionItem = (0, transform2Logic_1.transform2Logic)(nextStatement, undefined, { ...options, logicType: 'view_logic' });
}
else {
const functionName = callerName || '$Variable';
(0, utils_1.throwError)(options, `${functionName} 后面必须跟变量声明或函数声明`, nextStatement);
}
if (!definitionItem)
return null;
const referredConcept = definitionItem.concept;
const definition = new utils_1.naslTypes.ReferredDefinition({
referredConcept,
name: definitionItem.name,
namespace: '',
});
// 将定义添加到目录
if (!view.directories?.find((dir) => dir.name === directoryItem.name)) {
directoryItem.definitions = [definition];
view.addDirectory(directoryItem);
}
else {
const existingDirectory = view.directories.find((dir) => dir.name === directoryItem.name);
const hasDefinition = existingDirectory?.definitions.find((def) => def.name === definitionItem.name && def.referredConcept === referredConcept);
if (!hasDefinition) {
existingDirectory?.definitions.push(definition);
}
}
// 将实际的变量或逻辑添加到视图
if (referredConcept === 'Variable') {
view.addVariable(definitionItem);
}
else if (referredConcept === 'Logic') {
view.addLogic(definitionItem);
}
return definitionItem;
}
function transformJSXElement2ViewElement(node, options) {
const el = node.openingElement;
if (el.name.type === 'JSXIdentifier') {
let tag = (0, lodash_1.kebabCase)(el.name.name);
if (tag === 'el-form-date-time-picker')
tag = 'el-form-date-picker';
if (tag === 'el-form-input-date')
tag = 'el-form-date-picker';
if (tag === 'el-form-textarea')
tag = 'el-form-input';
if (tag === 'el-form-item')
tag = 'el-form-input';
const viewElement = new utils_1.naslTypes.ViewElement({
tag,
});
const attrs = el.attributes;
let directivePrefix = '$';
let eventPrefix = 'on';
let slotPrefix = 'slot';
function addJSXChild(node, slotTarget = 'default', slotScope = '') {
if (node.type === 'JSXElement') {
if (slotTarget === 'default' && !slotScope) {
const child = transformJSXElement2ViewElement(node, options);
child && viewElement.children.push(child);
}
else {
const child = transformJSXElement2ViewElement(node, options);
let templateName = 'template_' + (0, utils_2.uuidv4)().slice(0, 5);
// 确保模板名称也不重复
while (options.nameMap.has(templateName)) {
templateName = 'template_' + (0, utils_2.uuidv4)().slice(0, 5);
}
options.nameMap.set(templateName, true);
const templateChild = new utils_1.naslTypes.ViewElement({
tag: 'template',
name: templateName,
slotTarget,
slotScope,
children: child ? [child] : [],
});
if (viewElement.children.some((child) => child.tag === 'template' && child.slotTarget === slotTarget))
(0, utils_1.throwError)(options, `slot${(0, utils_2.firstUpperCase)(slotTarget)} 不能重复`, node);
viewElement.children.push(templateChild);
}
}
else if (node.type === 'JSXFragment') {
const children = node.children;
if (slotTarget === 'default' && !slotScope) {
viewElement.children.push(...children.filter((child) => child.type === 'JSXElement').map((child) => transformJSXElement2ViewElement(child, options)).filter(Boolean));
}
else {
let templateName = 'template_' + (0, utils_2.uuidv4)().slice(0, 5);
// 确保模板名称也不重复
while (options.nameMap.has(templateName)) {
templateName = 'template_' + (0, utils_2.uuidv4)().slice(0, 5);
}
options.nameMap.set(templateName, true);
const templateChild = new utils_1.naslTypes.ViewElement({
tag: 'template',
name: templateName,
slotTarget,
slotScope,
children: children.filter((child) => child.type === 'JSXElement').map((child) => transformJSXElement2ViewElement(child, options)).filter(Boolean),
});
if (viewElement.children.some((child) => child.tag === 'template' && child.slotTarget === slotTarget))
(0, utils_1.throwError)(options, `slot${(0, utils_2.firstUpperCase)(slotTarget)} 不能重复`, node);
viewElement.children.push(templateChild);
}
}
else {
return (0, utils_1.throwError)(options, '不支持的JSX子元素类型', node);
}
}
function addArrowFunctionJSXChild(node, slotTarget = 'default') {
const slotScopeName = node.params[0]?.name;
if (slotScopeName && slotScopeName !== 'current' && !slotScopeName?.startsWith('current')) {
return (0, utils_1.throwError)(options, `slotScope 需以 current 参数名开头`, node);
}
let slotScope = '';
if (slotScopeName) {
slotScope = 'current';
}
const body = node.body;
if (body.type === 'JSXElement' || body.type === 'JSXFragment') {
addJSXChild(body, slotTarget, slotScope);
}
else if (body.type === 'ArrayExpression') {
const elements = body.elements;
elements.forEach((element) => {
addJSXChild(element, slotTarget, slotScope);
});
}
else {
return (0, utils_1.throwError)(options, '不支持的JSX子元素类型', body.type, body);
}
}
attrs.forEach((attr) => {
if (attr.type === 'JSXAttribute') {
const attrName = attr.name.name;
if (!attrName)
(0, utils_1.throwError)(options, '属性名不能为空', attr);
if (attrName === 'ref') {
if (attr.value?.type === 'StringLiteral') {
const proposedName = attr.value.value;
if (options.nameMap.has(proposedName)) {
return (0, utils_1.throwError)(options, `ref 属性值 "${proposedName}" 已存在,不能重复使用`, attr);
}
viewElement.name = proposedName;
options.nameMap.set(proposedName, true);
}
else {
return (0, utils_1.throwError)(options, 'ref 属性值不正确', attr.value);
}
}
else if (attrName === 'style') {
if (attr.value?.type === 'StringLiteral') {
viewElement.staticStyle = attr.value.value;
}
else {
return (0, utils_1.throwError)(options, 'style 属性只能用字符串字面量', attr.value);
}
}
else if (attrName === '$extraStyle') {
if (!attr.value) {
(0, utils_1.throwError)(options, '$extraStyle 属性只能用字符串字面量', attr);
}
else if (attr.value.type === 'StringLiteral') {
viewElement.cssRules = (0, transformThemeAndStyle_1.transformStyle)(attr.value.value, options);
}
else if (attr.value.type === 'JSXExpressionContainer') {
const templateLiteral = attr.value.expression;
if (templateLiteral.type === 'TemplateLiteral') {
if (templateLiteral.expressions.length > 0) {
return (0, utils_1.throwError)(options, '不支持在 $theme 中使用动态表达式');
}
const css = templateLiteral.quasis[0].value.raw;
viewElement.cssRules = (0, transformThemeAndStyle_1.transformStyle)(css, options);
}
else {
return (0, utils_1.throwError)(options, '$extraStyle 属性只能用字符串字面量', attr.value);
}
}
else {
return (0, utils_1.throwError)(options, '$extraStyle 属性只能用字符串字面量', attr.value);
}
}
else if (attrName === '$dynamicStyle') {
if (!attr.value) {
(0, utils_1.throwError)(options, '$dynamicStyle 属性只能用字符串字面量', attr);
}
else if (attr.value.type === 'JSXExpressionContainer') {
const expression = attr.value.expression;
if (expression.type === 'ObjectExpression') {
const properties = expression.properties;
properties.forEach((property) => {
if (property.type === 'ObjectProperty') {
const name = (0, lodash_1.kebabCase)(property.key.name);
viewElement.bindStyles = viewElement.bindStyles || [];
viewElement.addBindStyle(new utils_1.naslTypes.BindStyle({
name,
expression: (0, transform2LogicItem_1.transform2LogicItem)(property.value, {
...options,
transformType: 'attr',
isRestricted: true,
isInFrontend: true,
}),
}));
}
});
}
}
else {
return (0, utils_1.throwError)(options, 'style 属性值不正确', attr.value);
}
}
else if (attrName.startsWith(directivePrefix)) {
const directiveName = attrName.slice(directivePrefix.length);
const directive = new utils_1.naslTypes.BindDirective({
name: directiveName,
});
if (!attr.value) {
directive.type = 'static';
directive.value = 'true';
}
else if (attr.value.type === 'StringLiteral') {
directive.type = 'string';
directive.value = attr.value.value;
}
else if (attr.value.type === 'JSXExpressionContainer') {
if (attr.value.expression.type === 'BooleanLiteral' || attr.value.expression.type === 'NumericLiteral' || attr.value.expression.type === 'NullLiteral' || attr.value.expression.type === 'StringLiteral') {
directive.type = 'static';
directive.value = (0, utils_1.generate)(attr.value.expression).code;
}
else {
directive.type = 'dynamic';
if (attr.value.expression.type === 'FunctionExpression')
return (0, utils_1.throwError)(options, '指令不支持传函数表达式', attr);
directive.expression = (0, transform2LogicItem_1.transform2LogicItem)(attr.value.expression, {
...options,
transformType: 'attr',
isRestricted: true,
isInFrontend: true,
});
}
}
else {
return (0, utils_1.throwError)(options, '不支持的指令类型', attr.value.type, attr.value);
}
if (directiveName !== 'for') {
viewElement.addBindDirective(directive);
}
}
else if (attrName.startsWith(eventPrefix)) {
const eventName = (0, utils_2.firstLowerCase)(attrName.slice(eventPrefix.length));
if (attr.value?.type === 'JSXExpressionContainer') {
const bindEvent = new utils_1.naslTypes.BindEvent({
name: eventName,
logics: transform2EventLogics(attr.value.expression, eventName, options) || [],
});
viewElement.addBindEvent(bindEvent);
}
else {
return (0, utils_1.throwError)(options, '事件逻辑参数不正确', attr.value);
}
}
else if (attrName.startsWith(slotPrefix)) {
const slotTarget = (0, utils_2.firstLowerCase)(attrName.slice(slotPrefix.length));
if (attr.value?.type === 'JSXExpressionContainer') {
const expression = attr.value.expression;
if (expression.type === 'JSXElement' || expression.type === 'JSXFragment') {
addJSXChild(expression, slotTarget);
}
else if (expression.type === 'ArrowFunctionExpression') {
addArrowFunctionJSXChild(expression, slotTarget);
}
else {
return (0, utils_1.throwError)(options, 'slot 属性值不正确', attr.value);
}
}
}
else if (attrName === 'rules') {
const bindAttribute = new utils_1.naslTypes.BindAttribute({
name: attrName,
});
if (attr.value?.type === 'JSXExpressionContainer') {
if (attr.value.expression.type === 'ArrayExpression') {
const elements = attr.value.expression.elements;
bindAttribute.rules = elements.map((node) => (0, transform2ValidationRule_1.transform2ValidationRule)(node, options)).filter(Boolean);
}
else if (attr.value.expression.type === 'CallExpression') {
const callee = (0, utils_1.generate)(attr.value.expression.callee).code;
if (callee === 'nasl.util.NewList' || callee === 'NewList') {
const elements = attr.value.expression.arguments[0].elements;
bindAttribute.rules = elements.map((node) => (0, transform2ValidationRule_1.transform2ValidationRule)(node, options)).filter(Boolean);
}
else {
return (0, utils_1.throwError)(options, 'rules 属性值不正确', attr.value);
}
}
else {
return (0, utils_1.throwError)(options, 'rules 属性值不正确', attr.value);
}
}
else {
return (0, utils_1.throwError)(options, 'rules 属性值不正确', attr.value);
}
viewElement.addBindAttribute(bindAttribute);
}
else {
const bindAttribute = new utils_1.naslTypes.BindAttribute({
name: attrName,
});
if (!attr.value) {
bindAttribute.type = 'static';
bindAttribute.value = 'true';
}
else if (attr.value.type === 'StringLiteral') {
bindAttribute.type = 'string';
bindAttribute.value = attr.value.value;
}
else if (attr.value.type === 'JSXExpressionContainer') {
if (attr.value.expression.type === 'BooleanLiteral' || attr.value.expression.type === 'NumericLiteral' || attr.value.expression.type === 'NullLiteral' || attr.value.expression.type === 'StringLiteral') {
bindAttribute.type = 'static';
bindAttribute.value = (0, utils_1.generate)(attr.value.expression).code;
}
else {
let expr = attr.value.expression;
if (attrName === 'prop' || attrName.endsWith('Field')) {
if (expr.type === 'ArrowFunctionExpression') {
bindAttribute.type = 'string';
const paramName = expr.params[0]?.name || 'item';
const code = (0, utils_1.generate)(expr.body).code;
bindAttribute.value = code.replace(new RegExp(`${paramName}\\.`, 'g'), '');
if (bindAttribute.value === 'item' && code !== 'item.item')
bindAttribute.value = '';
viewElement.addBindAttribute(bindAttribute);
return;
}
}
bindAttribute.type = 'dynamic';
if (expr.type === 'CallExpression' && expr.callee.type === 'Identifier' && expr.callee.name === '$sync') {
bindAttribute.sync = true;
if (expr.arguments.length === 0) {
return (0, utils_1.throwError)(options, '$sync 的参数不能为空', attr);
}
else if (expr.arguments.length > 0) {
expr = expr.arguments[0];
if (!expr)
return (0, utils_1.throwError)(options, '$sync 的参数不能为空', attr);
}
}
if (expr.type === 'FunctionExpression')
return (0, utils_1.throwError)(options, '属性不支持传函数表达式', attr);
const expression = (0, transform2LogicItem_1.transform2LogicItem)(expr, {
...options,
transformType: 'attr',
isRestricted: attrName !== 'dataSource',
isInFrontend: true,
});
if (expression?.concept === 'Destination') {
bindAttribute.destination = expression;
}
else if (expression?.concept === 'ExternalDestination') {
bindAttribute.externalDestination = expression;
}
else {
bindAttribute.expression = expression;
}
}
}
else {
return (0, utils_1.throwError)(options, '不支持的指令类型', attr.value.type, attr.value);
}
viewElement.addBindAttribute(bindAttribute);
}
}
else {
return (0, utils_1.throwError)(options, '不支持的JSX属性类型', attr.type, attr);
}
});
{ /* 临时补救 EnumToList 问题 */
if (viewElement.bindAttrs.some((bindAttr) => bindAttr.name === 'dataSource' && bindAttr.expression?.concept === 'CallFunction' && bindAttr.expression?.calleeName === 'EnumToList')) {
const index = viewElement.bindAttrs.findIndex((bindAttr) => bindAttr.name === 'valueField');
~index && viewElement.bindAttrs.splice(index, 1);
}
}
node.children.forEach((child) => {
if (child.type === 'JSXElement' || child.type === 'JSXFragment') {
addJSXChild(child);
}
else if (child.type === 'JSXExpressionContainer') {
const expression = child.expression;
if (expression.type === 'JSXElement' || expression.type === 'JSXFragment') {
addJSXChild(expression);
}
else if (expression.type === 'ArrowFunctionExpression') {
addArrowFunctionJSXChild(expression);
}
else if (expression.type === 'JSXEmptyExpression') {
// ignore
}
else {
return (0, utils_1.throwError)(options, '不支持的JSX子元素类型', expression.type, expression);
}
}
else if (child.type === 'JSXText') {
// ignore
}
else {
return (0, utils_1.throwError)(options, '不支持的JSX子元素类型', child.type, child);
}
});
if (!viewElement.name) {
let generatedName = viewElement.tag.replace(/-/g, '_') + '_' + (0, utils_2.uuidv4)().slice(0, 5);
// 确保生成的名称也不重复
while (options.nameMap.has(generatedName)) {
generatedName = viewElement.tag.replace(/-/g, '_') + '_' + (0, utils_2.uuidv4)().slice(0, 5);
}
viewElement.name = generatedName;
options.nameMap.set(generatedName, true);
}
return viewElement;
}
else {
return (0, utils_1.throwError)(options, '不支持的JSX元素类型', el.name.type, el);
}
}
exports.transformJSXElement2ViewElement = transformJSXElement2ViewElement;
function transform2View(func, decorator, options) {
const statements = func.body.body;
// 为每个视图创建独立的 nameMap
const nameMap = new Map();
const view = new utils_1.naslTypes.View({
name: func.id?.name,
});
options.nodeName = view.name;
const opts = { ...options, nameMap };
if (decorator) {
if (decorator.arguments[0].type === 'ObjectExpression') {
const viewObj = (0, utils_1.pickDecoratorObject)(decorator.arguments[0], new Set([
'pageTemplateId',
'uuid',
'title',
'crumb',
'auth',
'authDescription',
'isIndex',
]), options);
Object.assign(view, viewObj);
view.crumb = new utils_1.naslTypes.StaticString({
value: viewObj.crumb,
});
}
else {
return (0, utils_1.throwError)(options, '不支持的装饰器类型', decorator.type, decorator);
}
}
func.params.forEach((param) => {
if (param.type === 'Identifier') {
const _param = (0, transform2LogicItem_1.transform2Param)(param, { ...options, transformType: 'attr' });
_param && view.params.push(_param);
}
else if (param.type === 'ObjectPattern') {
const propertyMap = {};
param.properties.forEach((property) => {
if (property.type === 'ObjectProperty') {
if (property.value.type === 'Identifier') {
propertyMap[property.value.name] = {
type: 'AssignmentPattern',
left: property.value,
right: undefined,
};
}
else if (property.value.type === 'AssignmentPattern') {
propertyMap[property.value.left.name] = property.value;
}
else {
return (0, utils_1.throwError)(options, '不支持的参数类型', property.value.type, property.value);
}
}
});
const type = param.typeAnnotation?.typeAnnotation;
if (!type)
return (0, utils_1.throwError)(options, 'param 没有对应的类型', param);
type.members.forEach((member) => {
if (member.type === 'TSPropertySignature') {
const name = member.key.name;
if (propertyMap[name]) {
propertyMap[name].left.typeAnnotation = member.typeAnnotation;
}
}
});
Object.values(propertyMap).forEach((property) => {
const param = (0, transform2LogicItem_1.transform2Param)(property, { ...options, transformType: 'attr' });
param && view.params.push(param);
});
}
});
for (let index = 0; index < statements.length; index++) {
const statement = statements[index];
if (statement.type === 'VariableDeclaration') {
const variables = transform2Variables(statement, { ...options });
variables.forEach((variable) => {
view.addVariable(variable);
});
}
else if (statement.type === 'FunctionDeclaration') {
const logic = (0, transform2Logic_1.transform2Logic)(statement, undefined, { ...options, logicType: 'view_logic' });
view.addLogic(logic);
}
else if (statement.type === 'ExpressionStatement' && statement.expression.type === 'CallExpression') {
const expression = statement.expression;
if (expression.callee.type == 'Identifier' && expression.callee.name.startsWith('on')) {
const eventName = (0, utils_2.firstLowerCase)(expression.callee.name.slice(2));
const arg = expression.arguments[0];
const bindEvent = new utils_1.naslTypes.BindEvent({
name: eventName,
logics: transform2EventLogics(arg, eventName, { ...options }) || [],
});
view.addBindEvent(bindEvent);
}
else if (expression.callee.type == 'Identifier' && expression.callee.name.startsWith('$')) {
if (expression?.arguments[0]?.type === 'ObjectExpression') {
const { properties } = expression?.arguments[0];
const directoryNode = properties.find((item) => item.key?.name === 'directory');
if (directoryNode) {
const directoryItem = (0, transform2LogicItem_1.transformNode2Directory)(directoryNode);
if (directoryItem) {
const nextStatement = statements[index + 1];
if (nextStatement) {
const definitionItem = handleDirectoryItem(directoryItem, nextStatement, view, { ...options }, expression.callee.name);
if (definitionItem) {
// 跳过下一个语句,因为已经处理过了
index++;
}
}
}
else {
return (0, utils_1.throwError)(options, '不支持的定义类型', directoryNode);
}
}
}
else {
return (0, utils_1.throwError)(options, '不支持的表达式', statement);
}
}
else {
return (0, utils_1.throwError)(options, '不支持的表达式', statement);
}
}
else if (statement.type === 'ReturnStatement') {
const arg = statement.argument;
if (arg.type === 'JSXElement') {
const child = transformJSXElement2ViewElement(arg, opts);
view.elements = child ? [child] : [];
}
else if (arg.type === 'JSXFragment') {
view.elements = arg.children.filter((child) => child.type === 'JSXElement').map((child) => transformJSXElement2ViewElement(child, opts)).filter(Boolean);
}
else {
return (0, utils_1.throwError)(options, '返回值不正确', arg);
}
}
else {
return (0, utils_1.throwError)(options, '不支持的表达式', statement);
}
}
return view;
}
exports.transform2View = transform2View;
function transformTSDeclareFunction2View(func, decorator, options) {
const view = new utils_1.naslTypes.View({
name: func.id?.name,
});
options.nodeName = view.name;
if (decorator) {
if (decorator.arguments[0].type === 'ObjectExpression') {
const viewObj = (0, utils_1.pickDecoratorObject)(decorator.arguments[0], new Set([
'pageTemplateId',
'uuid',
'title',
'crumb',
'auth',
'authDescription',
'isIndex',
]), options);
Object.assign(view, viewObj);
view.crumb = new utils_1.naslTypes.StaticString({
value: viewObj.crumb,
});
}
else {
return (0, utils_1.throwError)(options, '不支持的装饰器类型', decorator.type, decorator);
}
}
func.params.forEach((param) => {
if (param.type === 'Identifier') {
const _param = (0, transform2LogicItem_1.transform2Param)(param, { ...options, transformType: 'attr' });
_param && view.params.push(_param);
}
});
return view;
}
exports.transformTSDeclareFunction2View = transformTSDeclareFunction2View;
function parseNaturalTSXView(tsCode, options) {
const root = babel.parseSync(tsCode, {
filename: 'result.tsx',
presets: [require('@babel/preset-typescript')],
});
let func;
let funcIndex = 0;
let decorator;
root.program.body.forEach((statement, index) => {
if (statement.type === 'ExportNamedDeclaration' && statement.declaration.type === 'FunctionDeclaration') {
func = statement.declaration;
funcIndex = index;
}
else if (statement.type === 'FunctionDeclaration') {
func = statement;
funcIndex = index;
}
const prevStatement = root.program.body[index - 1];
if (prevStatement?.type === 'ExpressionStatement' && prevStatement.expression.type === 'CallExpression' && prevStatement.expression.callee.type === 'Identifier' && prevStatement.expression.callee.name === '$View') {
decorator = prevStatement.expression;
}
});
return transform2View(func, decorator, options);
}
exports.parseNaturalTSXView = parseNaturalTSXView;
//# sourceMappingURL=parseNaturalTSXView.js.map