@lcap/nasl 4.3.0-creator.3 → 4.3.0-creator.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (79) hide show
  1. package/out/generator/genSimpleBundleFile.js +1 -1
  2. package/out/generator/genSimpleBundleFile.js.map +1 -1
  3. package/out/natural/parseNaturalTS.d.ts +7 -0
  4. package/out/natural/parseNaturalTS.d.ts.map +1 -1
  5. package/out/natural/parseNaturalTS.js +93 -98
  6. package/out/natural/parseNaturalTS.js.map +1 -1
  7. package/out/natural/parseNaturalTSXView.d.ts +6 -17
  8. package/out/natural/parseNaturalTSXView.d.ts.map +1 -1
  9. package/out/natural/parseNaturalTSXView.js +128 -59
  10. package/out/natural/parseNaturalTSXView.js.map +1 -1
  11. package/out/natural/transformTS2UI.d.ts.map +1 -1
  12. package/out/natural/transformTS2UI.js +4 -4
  13. package/out/natural/transformTS2UI.js.map +1 -1
  14. package/out/natural/transformTSCode.d.ts.map +1 -1
  15. package/out/natural/transformTSCode.js +8 -1
  16. package/out/natural/transformTSCode.js.map +1 -1
  17. package/out/natural/transforms/transform2Entity.d.ts +2 -4
  18. package/out/natural/transforms/transform2Entity.d.ts.map +1 -1
  19. package/out/natural/transforms/transform2Entity.js +5 -5
  20. package/out/natural/transforms/transform2Entity.js.map +1 -1
  21. package/out/natural/transforms/transform2Enum.d.ts +2 -4
  22. package/out/natural/transforms/transform2Enum.d.ts.map +1 -1
  23. package/out/natural/transforms/transform2Enum.js +5 -5
  24. package/out/natural/transforms/transform2Enum.js.map +1 -1
  25. package/out/natural/transforms/transform2GlobalLogicDeclaration.d.ts +2 -4
  26. package/out/natural/transforms/transform2GlobalLogicDeclaration.d.ts.map +1 -1
  27. package/out/natural/transforms/transform2GlobalLogicDeclaration.js +4 -4
  28. package/out/natural/transforms/transform2GlobalLogicDeclaration.js.map +1 -1
  29. package/out/natural/transforms/transform2Logic.d.ts +4 -10
  30. package/out/natural/transforms/transform2Logic.d.ts.map +1 -1
  31. package/out/natural/transforms/transform2Logic.js +3 -2
  32. package/out/natural/transforms/transform2Logic.js.map +1 -1
  33. package/out/natural/transforms/transform2LogicItem.d.ts +6 -6
  34. package/out/natural/transforms/transform2LogicItem.d.ts.map +1 -1
  35. package/out/natural/transforms/transform2LogicItem.js +198 -114
  36. package/out/natural/transforms/transform2LogicItem.js.map +1 -1
  37. package/out/natural/transforms/transform2MetadataType.d.ts +2 -4
  38. package/out/natural/transforms/transform2MetadataType.d.ts.map +1 -1
  39. package/out/natural/transforms/transform2MetadataType.js +3 -3
  40. package/out/natural/transforms/transform2MetadataType.js.map +1 -1
  41. package/out/natural/transforms/transform2Structure.d.ts +2 -4
  42. package/out/natural/transforms/transform2Structure.d.ts.map +1 -1
  43. package/out/natural/transforms/transform2Structure.js +5 -5
  44. package/out/natural/transforms/transform2Structure.js.map +1 -1
  45. package/out/natural/transforms/transform2TypeAnnotation.d.ts +2 -4
  46. package/out/natural/transforms/transform2TypeAnnotation.d.ts.map +1 -1
  47. package/out/natural/transforms/transform2TypeAnnotation.js +10 -13
  48. package/out/natural/transforms/transform2TypeAnnotation.js.map +1 -1
  49. package/out/natural/transforms/transform2ValidationRule.d.ts +2 -4
  50. package/out/natural/transforms/transform2ValidationRule.d.ts.map +1 -1
  51. package/out/natural/transforms/transform2ValidationRule.js +3 -3
  52. package/out/natural/transforms/transform2ValidationRule.js.map +1 -1
  53. package/out/natural/transforms/transform2Variable.d.ts +3 -7
  54. package/out/natural/transforms/transform2Variable.d.ts.map +1 -1
  55. package/out/natural/transforms/transform2Variable.js +10 -10
  56. package/out/natural/transforms/transform2Variable.js.map +1 -1
  57. package/out/natural/transforms/transformThemeAndStyle.d.ts +3 -7
  58. package/out/natural/transforms/transformThemeAndStyle.d.ts.map +1 -1
  59. package/out/natural/transforms/transformThemeAndStyle.js +7 -7
  60. package/out/natural/transforms/transformThemeAndStyle.js.map +1 -1
  61. package/out/natural/transforms/utils.d.ts +99 -7
  62. package/out/natural/transforms/utils.d.ts.map +1 -1
  63. package/out/natural/transforms/utils.js +336 -14
  64. package/out/natural/transforms/utils.js.map +1 -1
  65. package/out/server/naslServer.d.ts +0 -1
  66. package/out/server/naslServer.d.ts.map +1 -1
  67. package/out/server/naslServer.js +19 -8
  68. package/out/server/naslServer.js.map +1 -1
  69. package/out/service/initial/form-designer.d.ts +1 -1
  70. package/out/service/initial/form-designer.d.ts.map +1 -1
  71. package/out/service/initial/form-designer.js +2 -2
  72. package/out/service/initial/form-designer.js.map +1 -1
  73. package/out/service/initial/processV2.d.ts +1 -1
  74. package/out/service/initial/processV2.d.ts.map +1 -1
  75. package/out/service/initial/processV2.js +2 -2
  76. package/out/service/initial/processV2.js.map +1 -1
  77. package/out/service/initial/types.d.ts +1 -1
  78. package/out/service/initial/types.d.ts.map +1 -1
  79. package/package.json +11 -11
@@ -57,7 +57,7 @@ function transform2Variables(node, options) {
57
57
  exports.transform2Variables = transform2Variables;
58
58
  function transform2EventLogics(node, eventName, options) {
59
59
  if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') {
60
- const logic = (0, transform2Logic_1.transform2Logic)(node, eventName, options);
60
+ const logic = (0, transform2Logic_1.transform2Logic)(node, eventName, { ...options, logicType: 'event_logic' });
61
61
  logic.params = [];
62
62
  return [logic];
63
63
  }
@@ -66,21 +66,24 @@ function transform2EventLogics(node, eventName, options) {
66
66
  const args = node.arguments;
67
67
  return args.map((node) => {
68
68
  if (node.type === 'FunctionExpression' || node.type === 'ArrowFunctionExpression') {
69
- const logic = (0, transform2Logic_1.transform2Logic)(node, eventName, options);
69
+ const logic = (0, transform2Logic_1.transform2Logic)(node, eventName, { ...options, logicType: 'event_logic' });
70
70
  logic.params = [];
71
71
  return logic;
72
72
  }
73
73
  else {
74
- return (0, utils_1.throwError)(options?.parsingId, '事件逻辑参数不支持的类型', node.type, node);
74
+ return (0, utils_1.throwError)(options, '事件逻辑参数不支持的类型', node.type, node);
75
75
  }
76
76
  }).filter(Boolean);
77
77
  }
78
78
  else {
79
- return (0, utils_1.throwError)(options?.parsingId, '事件逻辑参数不正确', node);
79
+ return (0, utils_1.throwError)(options, '事件逻辑参数不正确', node);
80
80
  }
81
81
  }
82
+ else if (node.type === 'Identifier' || node.type === 'MemberExpression') {
83
+ return (0, utils_1.throwError)(options, '事件逻辑参数不正确,不支持绑定逻辑,需要直接写在元素中', node);
84
+ }
82
85
  else {
83
- return (0, utils_1.throwError)(options?.parsingId, '事件逻辑参数不正确', node);
86
+ return (0, utils_1.throwError)(options, '事件逻辑参数不正确', node);
84
87
  }
85
88
  }
86
89
  function handleDirectoryItem(directoryItem, nextStatement, view, options, callerName) {
@@ -92,11 +95,11 @@ function handleDirectoryItem(directoryItem, nextStatement, view, options, caller
92
95
  }
93
96
  else if (nextStatement.type === 'FunctionDeclaration') {
94
97
  // 处理函数/逻辑声明
95
- definitionItem = (0, transform2Logic_1.transform2Logic)(nextStatement, undefined, options);
98
+ definitionItem = (0, transform2Logic_1.transform2Logic)(nextStatement, undefined, { ...options, logicType: 'view_logic' });
96
99
  }
97
100
  else {
98
101
  const functionName = callerName || '$Variable';
99
- (0, utils_1.throwError)(options?.parsingId, `${functionName} 后面必须跟变量声明或函数声明`, nextStatement);
102
+ (0, utils_1.throwError)(options, `${functionName} 后面必须跟变量声明或函数声明`, nextStatement);
100
103
  }
101
104
  if (!definitionItem)
102
105
  return null;
@@ -131,6 +134,9 @@ function transformJSXElement2ViewElement(node, options) {
131
134
  const el = node.openingElement;
132
135
  if (el.name.type === 'JSXIdentifier') {
133
136
  let tag = (0, lodash_1.kebabCase)(el.name.name);
137
+ if (['span', 'div'].includes(tag)) {
138
+ return (0, utils_1.throwError)(options, `不支持的JSX子元素 ${tag}, 请使用 ElFlex`, node);
139
+ }
134
140
  if (tag === 'el-form-date-time-picker')
135
141
  tag = 'el-form-date-picker';
136
142
  if (tag === 'el-form-input-date')
@@ -139,6 +145,8 @@ function transformJSXElement2ViewElement(node, options) {
139
145
  tag = 'el-form-input';
140
146
  if (tag === 'el-form-item')
141
147
  tag = 'el-form-input';
148
+ // 检查父组件约束
149
+ (0, utils_1.validateParentConstraints)(tag, options, node);
142
150
  const viewElement = new utils_1.naslTypes.ViewElement({
143
151
  tag,
144
152
  });
@@ -149,11 +157,11 @@ function transformJSXElement2ViewElement(node, options) {
149
157
  function addJSXChild(node, slotTarget = 'default', slotScope = '') {
150
158
  if (node.type === 'JSXElement') {
151
159
  if (slotTarget === 'default' && !slotScope) {
152
- const child = transformJSXElement2ViewElement(node, options);
160
+ const child = transformJSXElement2ViewElement(node, { ...options, parentTag: tag });
153
161
  child && viewElement.children.push(child);
154
162
  }
155
163
  else {
156
- const child = transformJSXElement2ViewElement(node, options);
164
+ const child = transformJSXElement2ViewElement(node, { ...options, parentTag: tag });
157
165
  let templateName = 'template_' + (0, utils_2.uuidv4)().slice(0, 5);
158
166
  // 确保模板名称也不重复
159
167
  while (options.nameMap.has(templateName)) {
@@ -168,14 +176,14 @@ function transformJSXElement2ViewElement(node, options) {
168
176
  children: child ? [child] : [],
169
177
  });
170
178
  if (viewElement.children.some((child) => child.tag === 'template' && child.slotTarget === slotTarget))
171
- (0, utils_1.throwError)(options?.parsingId, `slot${(0, utils_2.firstUpperCase)(slotTarget)} 不能重复`, node);
179
+ (0, utils_1.throwError)(options, `slot${(0, utils_2.firstUpperCase)(slotTarget)} 不能重复`, node);
172
180
  viewElement.children.push(templateChild);
173
181
  }
174
182
  }
175
183
  else if (node.type === 'JSXFragment') {
176
184
  const children = node.children;
177
185
  if (slotTarget === 'default' && !slotScope) {
178
- viewElement.children.push(...children.filter((child) => child.type === 'JSXElement').map((child) => transformJSXElement2ViewElement(child, options)).filter(Boolean));
186
+ viewElement.children.push(...children.filter((child) => child.type === 'JSXElement').map((child) => transformJSXElement2ViewElement(child, { ...options, parentTag: tag })).filter(Boolean));
179
187
  }
180
188
  else {
181
189
  let templateName = 'template_' + (0, utils_2.uuidv4)().slice(0, 5);
@@ -189,21 +197,21 @@ function transformJSXElement2ViewElement(node, options) {
189
197
  name: templateName,
190
198
  slotTarget,
191
199
  slotScope,
192
- children: children.filter((child) => child.type === 'JSXElement').map((child) => transformJSXElement2ViewElement(child, options)).filter(Boolean),
200
+ children: children.filter((child) => child.type === 'JSXElement').map((child) => transformJSXElement2ViewElement(child, { ...options, parentTag: tag })).filter(Boolean),
193
201
  });
194
202
  if (viewElement.children.some((child) => child.tag === 'template' && child.slotTarget === slotTarget))
195
- (0, utils_1.throwError)(options?.parsingId, `slot${(0, utils_2.firstUpperCase)(slotTarget)} 不能重复`, node);
203
+ (0, utils_1.throwError)(options, `slot${(0, utils_2.firstUpperCase)(slotTarget)} 不能重复`, node);
196
204
  viewElement.children.push(templateChild);
197
205
  }
198
206
  }
199
207
  else {
200
- return (0, utils_1.throwError)(options?.parsingId, '不支持的JSX子元素类型', node);
208
+ return (0, utils_1.throwError)(options, '不支持的JSX子元素类型', node);
201
209
  }
202
210
  }
203
211
  function addArrowFunctionJSXChild(node, slotTarget = 'default') {
204
212
  const slotScopeName = node.params[0]?.name;
205
213
  if (slotScopeName && slotScopeName !== 'current' && !slotScopeName?.startsWith('current')) {
206
- return (0, utils_1.throwError)(options?.parsingId, `slotScope 需以 current 参数名开头`, node);
214
+ return (0, utils_1.throwError)(options, `slotScope 需以 current 参数名开头`, node);
207
215
  }
208
216
  let slotScope = '';
209
217
  if (slotScopeName) {
@@ -220,23 +228,25 @@ function transformJSXElement2ViewElement(node, options) {
220
228
  });
221
229
  }
222
230
  else {
223
- return (0, utils_1.throwError)(options?.parsingId, '不支持的JSX子元素类型', body.type, body);
231
+ return (0, utils_1.throwError)(options, '不支持的JSX子元素类型', body.type, body);
224
232
  }
225
233
  }
226
234
  attrs.forEach((attr) => {
227
235
  if (attr.type === 'JSXAttribute') {
228
236
  const attrName = attr.name.name;
237
+ if (!attrName)
238
+ (0, utils_1.throwError)(options, '属性名不能为空', attr);
229
239
  if (attrName === 'ref') {
230
240
  if (attr.value?.type === 'StringLiteral') {
231
241
  const proposedName = attr.value.value;
232
242
  if (options.nameMap.has(proposedName)) {
233
- return (0, utils_1.throwError)(options?.parsingId, `ref 属性值 "${proposedName}" 已存在,不能重复使用`, attr);
243
+ return (0, utils_1.throwError)(options, `ref 属性值 "${proposedName}" 已存在,不能重复使用`, attr);
234
244
  }
235
245
  viewElement.name = proposedName;
236
246
  options.nameMap.set(proposedName, true);
237
247
  }
238
248
  else {
239
- return (0, utils_1.throwError)(options?.parsingId, 'ref 属性值不正确', attr.value);
249
+ return (0, utils_1.throwError)(options, 'ref 属性值不正确', attr.value);
240
250
  }
241
251
  }
242
252
  else if (attrName === 'style') {
@@ -244,12 +254,12 @@ function transformJSXElement2ViewElement(node, options) {
244
254
  viewElement.staticStyle = attr.value.value;
245
255
  }
246
256
  else {
247
- return (0, utils_1.throwError)(options?.parsingId, 'style 属性只能用字符串字面量', attr.value);
257
+ return (0, utils_1.throwError)(options, 'style 属性只能用字符串字面量', attr.value);
248
258
  }
249
259
  }
250
260
  else if (attrName === '$extraStyle') {
251
261
  if (!attr.value) {
252
- (0, utils_1.throwError)(options?.parsingId, '$extraStyle 属性只能用字符串字面量', attr);
262
+ (0, utils_1.throwError)(options, '$extraStyle 属性只能用字符串字面量', attr);
253
263
  }
254
264
  else if (attr.value.type === 'StringLiteral') {
255
265
  viewElement.cssRules = (0, transformThemeAndStyle_1.transformStyle)(attr.value.value, options);
@@ -258,22 +268,22 @@ function transformJSXElement2ViewElement(node, options) {
258
268
  const templateLiteral = attr.value.expression;
259
269
  if (templateLiteral.type === 'TemplateLiteral') {
260
270
  if (templateLiteral.expressions.length > 0) {
261
- return (0, utils_1.throwError)(options?.parsingId, '不支持在 $theme 中使用动态表达式');
271
+ return (0, utils_1.throwError)(options, '不支持在 $theme 中使用动态表达式');
262
272
  }
263
273
  const css = templateLiteral.quasis[0].value.raw;
264
274
  viewElement.cssRules = (0, transformThemeAndStyle_1.transformStyle)(css, options);
265
275
  }
266
276
  else {
267
- return (0, utils_1.throwError)(options?.parsingId, '$extraStyle 属性只能用字符串字面量', attr.value);
277
+ return (0, utils_1.throwError)(options, '$extraStyle 属性只能用字符串字面量', attr.value);
268
278
  }
269
279
  }
270
280
  else {
271
- return (0, utils_1.throwError)(options?.parsingId, '$extraStyle 属性只能用字符串字面量', attr.value);
281
+ return (0, utils_1.throwError)(options, '$extraStyle 属性只能用字符串字面量', attr.value);
272
282
  }
273
283
  }
274
284
  else if (attrName === '$dynamicStyle') {
275
285
  if (!attr.value) {
276
- (0, utils_1.throwError)(options?.parsingId, '$dynamicStyle 属性只能用字符串字面量', attr);
286
+ (0, utils_1.throwError)(options, '$dynamicStyle 属性只能用字符串字面量', attr);
277
287
  }
278
288
  else if (attr.value.type === 'JSXExpressionContainer') {
279
289
  const expression = attr.value.expression;
@@ -297,7 +307,7 @@ function transformJSXElement2ViewElement(node, options) {
297
307
  }
298
308
  }
299
309
  else {
300
- return (0, utils_1.throwError)(options?.parsingId, 'style 属性值不正确', attr.value);
310
+ return (0, utils_1.throwError)(options, 'style 属性值不正确', attr.value);
301
311
  }
302
312
  }
303
313
  else if (attrName.startsWith(directivePrefix)) {
@@ -321,7 +331,7 @@ function transformJSXElement2ViewElement(node, options) {
321
331
  else {
322
332
  directive.type = 'dynamic';
323
333
  if (attr.value.expression.type === 'FunctionExpression')
324
- return (0, utils_1.throwError)(options?.parsingId, '指令不支持传函数表达式', attr);
334
+ return (0, utils_1.throwError)(options, '指令不支持传函数表达式', attr);
325
335
  directive.expression = (0, transform2LogicItem_1.transform2LogicItem)(attr.value.expression, {
326
336
  ...options,
327
337
  transformType: 'attr',
@@ -331,7 +341,7 @@ function transformJSXElement2ViewElement(node, options) {
331
341
  }
332
342
  }
333
343
  else {
334
- return (0, utils_1.throwError)(options?.parsingId, '不支持的指令类型', attr.value.type, attr.value);
344
+ return (0, utils_1.throwError)(options, '不支持的指令类型', attr.value.type, attr.value);
335
345
  }
336
346
  if (directiveName !== 'for') {
337
347
  viewElement.addBindDirective(directive);
@@ -339,6 +349,7 @@ function transformJSXElement2ViewElement(node, options) {
339
349
  }
340
350
  else if (attrName.startsWith(eventPrefix)) {
341
351
  const eventName = (0, utils_2.firstLowerCase)(attrName.slice(eventPrefix.length));
352
+ (0, utils_1.validateComponentFeature)(tag, 'event', attrName, options, attr);
342
353
  if (attr.value?.type === 'JSXExpressionContainer') {
343
354
  const bindEvent = new utils_1.naslTypes.BindEvent({
344
355
  name: eventName,
@@ -347,11 +358,12 @@ function transformJSXElement2ViewElement(node, options) {
347
358
  viewElement.addBindEvent(bindEvent);
348
359
  }
349
360
  else {
350
- return (0, utils_1.throwError)(options?.parsingId, '事件逻辑参数不正确', attr.value);
361
+ return (0, utils_1.throwError)(options, '事件逻辑参数不正确', attr.value);
351
362
  }
352
363
  }
353
364
  else if (attrName.startsWith(slotPrefix)) {
354
365
  const slotTarget = (0, utils_2.firstLowerCase)(attrName.slice(slotPrefix.length));
366
+ (0, utils_1.validateComponentFeature)(tag, 'slot', attrName, options, attr);
355
367
  if (attr.value?.type === 'JSXExpressionContainer') {
356
368
  const expression = attr.value.expression;
357
369
  if (expression.type === 'JSXElement' || expression.type === 'JSXFragment') {
@@ -361,7 +373,7 @@ function transformJSXElement2ViewElement(node, options) {
361
373
  addArrowFunctionJSXChild(expression, slotTarget);
362
374
  }
363
375
  else {
364
- return (0, utils_1.throwError)(options?.parsingId, 'slot 属性值不正确', attr.value);
376
+ return (0, utils_1.throwError)(options, 'slot 属性值不正确', attr.value);
365
377
  }
366
378
  }
367
379
  }
@@ -381,19 +393,20 @@ function transformJSXElement2ViewElement(node, options) {
381
393
  bindAttribute.rules = elements.map((node) => (0, transform2ValidationRule_1.transform2ValidationRule)(node, options)).filter(Boolean);
382
394
  }
383
395
  else {
384
- return (0, utils_1.throwError)(options?.parsingId, 'rules 属性值不正确', attr.value);
396
+ return (0, utils_1.throwError)(options, 'rules 属性值不正确', attr.value);
385
397
  }
386
398
  }
387
399
  else {
388
- return (0, utils_1.throwError)(options?.parsingId, 'rules 属性值不正确', attr.value);
400
+ return (0, utils_1.throwError)(options, 'rules 属性值不正确', attr.value);
389
401
  }
390
402
  }
391
403
  else {
392
- return (0, utils_1.throwError)(options?.parsingId, 'rules 属性值不正确', attr.value);
404
+ return (0, utils_1.throwError)(options, 'rules 属性值不正确', attr.value);
393
405
  }
394
406
  viewElement.addBindAttribute(bindAttribute);
395
407
  }
396
408
  else {
409
+ (0, utils_1.validateComponentFeature)(tag, 'prop', attrName, options, attr);
397
410
  const bindAttribute = new utils_1.naslTypes.BindAttribute({
398
411
  name: attrName,
399
412
  });
@@ -406,19 +419,23 @@ function transformJSXElement2ViewElement(node, options) {
406
419
  bindAttribute.value = attr.value.value;
407
420
  }
408
421
  else if (attr.value.type === 'JSXExpressionContainer') {
409
- if (attr.value.expression.type === 'BooleanLiteral' || attr.value.expression.type === 'NumericLiteral' || attr.value.expression.type === 'NullLiteral' || attr.value.expression.type === 'StringLiteral') {
422
+ if (attr.value.expression.type === 'BooleanLiteral') {
423
+ bindAttribute.type = 'static';
424
+ bindAttribute.value = attr.value.expression.value;
425
+ }
426
+ else if (attr.value.expression.type === 'NumericLiteral' || attr.value.expression.type === 'NullLiteral' || attr.value.expression.type === 'StringLiteral') {
410
427
  bindAttribute.type = 'static';
411
428
  bindAttribute.value = (0, utils_1.generate)(attr.value.expression).code;
412
429
  }
413
430
  else {
414
431
  let expr = attr.value.expression;
415
- if (attrName === 'prop' || attrName.endsWith('Field')) {
432
+ if (attrName === 'prop' || attrName.endsWith('Field') || attrName === 'rowKey') {
416
433
  if (expr.type === 'ArrowFunctionExpression') {
417
434
  bindAttribute.type = 'string';
418
435
  const paramName = expr.params[0]?.name || 'item';
419
436
  const code = (0, utils_1.generate)(expr.body).code;
420
437
  bindAttribute.value = code.replace(new RegExp(`${paramName}\\.`, 'g'), '');
421
- if (bindAttribute.value === 'item')
438
+ if (bindAttribute.value === 'item' && code !== 'item.item')
422
439
  bindAttribute.value = '';
423
440
  viewElement.addBindAttribute(bindAttribute);
424
441
  return;
@@ -427,20 +444,29 @@ function transformJSXElement2ViewElement(node, options) {
427
444
  bindAttribute.type = 'dynamic';
428
445
  if (expr.type === 'CallExpression' && expr.callee.type === 'Identifier' && expr.callee.name === '$sync') {
429
446
  bindAttribute.sync = true;
430
- if (expr.arguments.length > 0) {
447
+ if (expr.arguments.length === 0) {
448
+ return (0, utils_1.throwError)(options, '$sync 的参数不能为空', attr);
449
+ }
450
+ else if (expr.arguments.length > 0) {
431
451
  expr = expr.arguments[0];
432
452
  if (!expr)
433
- return (0, utils_1.throwError)(options?.parsingId, '$sync 的参数不能为空', attr);
453
+ return (0, utils_1.throwError)(options, '$sync 的参数不能为空', attr);
434
454
  }
435
455
  }
436
456
  if (expr.type === 'FunctionExpression')
437
- return (0, utils_1.throwError)(options?.parsingId, '属性不支持传函数表达式', attr);
457
+ return (0, utils_1.throwError)(options, '属性不支持传函数表达式', attr);
438
458
  const expression = (0, transform2LogicItem_1.transform2LogicItem)(expr, {
439
459
  ...options,
440
460
  transformType: 'attr',
441
461
  isRestricted: attrName !== 'dataSource',
442
462
  isInFrontend: true,
443
463
  });
464
+ if (attr.name.name === 'destination' && expression.concept !== 'Destination') {
465
+ return (0, utils_1.throwError)(options, 'destination 属性值必须使用 nasl.ui.destination', attr);
466
+ }
467
+ if (attr.name.name === 'externalDestination' && expression.concept !== 'ExternalDestination') {
468
+ return (0, utils_1.throwError)(options, 'externalDestination 属性值必须使用 nasl.ui.gotoLink', attr);
469
+ }
444
470
  if (expression?.concept === 'Destination') {
445
471
  bindAttribute.destination = expression;
446
472
  }
@@ -453,13 +479,13 @@ function transformJSXElement2ViewElement(node, options) {
453
479
  }
454
480
  }
455
481
  else {
456
- return (0, utils_1.throwError)(options?.parsingId, '不支持的指令类型', attr.value.type, attr.value);
482
+ return (0, utils_1.throwError)(options, '不支持的指令类型', attr.value.type, attr.value);
457
483
  }
458
484
  viewElement.addBindAttribute(bindAttribute);
459
485
  }
460
486
  }
461
487
  else {
462
- return (0, utils_1.throwError)(options?.parsingId, '不支持的JSX属性类型', attr.type, attr);
488
+ return (0, utils_1.throwError)(options, '不支持的JSX属性类型', attr.type, attr);
463
489
  }
464
490
  });
465
491
  { /* 临时补救 EnumToList 问题 */
@@ -468,7 +494,7 @@ function transformJSXElement2ViewElement(node, options) {
468
494
  ~index && viewElement.bindAttrs.splice(index, 1);
469
495
  }
470
496
  }
471
- node.children.forEach((child) => {
497
+ node.children.forEach((child, index) => {
472
498
  if (child.type === 'JSXElement' || child.type === 'JSXFragment') {
473
499
  addJSXChild(child);
474
500
  }
@@ -478,22 +504,62 @@ function transformJSXElement2ViewElement(node, options) {
478
504
  addJSXChild(expression);
479
505
  }
480
506
  else if (expression.type === 'ArrowFunctionExpression') {
507
+ if (index > 0) {
508
+ const previousNode = node.children[index - 1];
509
+ if (previousNode?.type === 'JSXText') {
510
+ const trimmedValue = previousNode.value.trim();
511
+ const isSlotAssignment = trimmedValue.startsWith('slot') && trimmedValue.endsWith('=');
512
+ if (isSlotAssignment) {
513
+ const positionCode = (0, utils_1.generate)(previousNode).code + '{' + (0, utils_1.generate)(expression).code + '}';
514
+ return (0, utils_1.throwError)(options, '不支持的JSX子元素类型', positionCode, node);
515
+ }
516
+ }
517
+ }
481
518
  addArrowFunctionJSXChild(expression);
482
519
  }
483
520
  else if (expression.type === 'JSXEmptyExpression') {
484
521
  // ignore
485
522
  }
486
523
  else {
487
- return (0, utils_1.throwError)(options?.parsingId, '不支持的JSX子元素类型', expression.type, expression);
524
+ return (0, utils_1.throwError)(options, '不支持的JSX子元素类型', expression.type, expression);
488
525
  }
489
526
  }
490
527
  else if (child.type === 'JSXText') {
491
528
  // ignore
492
529
  }
493
530
  else {
494
- return (0, utils_1.throwError)(options?.parsingId, '不支持的JSX子元素类型', child.type, child);
531
+ return (0, utils_1.throwError)(options, '不支持的JSX子元素类型', child.type, child);
495
532
  }
496
533
  });
534
+ if (viewElement.tag === 'el-table') {
535
+ (0, utils_1.addLint)(options, {
536
+ name: '表格列不推荐全设置宽度',
537
+ description: '从表格列中选取几个较长文本字段(如名称、地址、描述等)不设置宽度,以便自适应显示,其他列可根据展示内容和表格整体宽度酌情设置宽度。 使用style属性进行宽度设置。',
538
+ }, (rule) => {
539
+ // 检查所有子元素是否都是 el-table-column 且都有 width 样式
540
+ const allColumnsHaveWidth = viewElement.children.every((child) => {
541
+ return (child.tag === 'el-table-column' &&
542
+ child.staticStyle &&
543
+ child.staticStyle.includes('width:'));
544
+ });
545
+ if (allColumnsHaveWidth) {
546
+ return (0, utils_1.throwError)(options, `${rule.name}: ${rule.description}`, node);
547
+ }
548
+ });
549
+ }
550
+ if (viewElement.tag === 'el-form') {
551
+ (0, utils_1.addLint)(options, {
552
+ name: '表单缺少校验',
553
+ description: '表单定义中包含校验规则,需要为 ElForm 设置 ref 属性,并在提交前调用 validated() 方法进行校验',
554
+ }, (rule) => {
555
+ // 需检测ElForm在其子项有rules的情况下,无ref或者代码中无ref对应validated的情况
556
+ const hasRule = viewElement.children.some((child) => child.bindAttrs.some((bindAttr) => bindAttr.name === 'rules'));
557
+ const hasRef = viewElement.name;
558
+ if (hasRule && !hasRef) {
559
+ return (0, utils_1.throwError)(options, `${rule.name}: ${rule.description}`, node);
560
+ }
561
+ });
562
+ }
497
563
  if (!viewElement.name) {
498
564
  let generatedName = viewElement.tag.replace(/-/g, '_') + '_' + (0, utils_2.uuidv4)().slice(0, 5);
499
565
  // 确保生成的名称也不重复
@@ -506,7 +572,7 @@ function transformJSXElement2ViewElement(node, options) {
506
572
  return viewElement;
507
573
  }
508
574
  else {
509
- return (0, utils_1.throwError)(options?.parsingId, '不支持的JSX元素类型', el.name.type, el);
575
+ return (0, utils_1.throwError)(options, '不支持的JSX元素类型', el.name.type, el);
510
576
  }
511
577
  }
512
578
  exports.transformJSXElement2ViewElement = transformJSXElement2ViewElement;
@@ -517,6 +583,8 @@ function transform2View(func, decorator, options) {
517
583
  const view = new utils_1.naslTypes.View({
518
584
  name: func.id?.name,
519
585
  });
586
+ options.nodeName = view.name;
587
+ const opts = { ...options, nameMap };
520
588
  if (decorator) {
521
589
  if (decorator.arguments[0].type === 'ObjectExpression') {
522
590
  const viewObj = (0, utils_1.pickDecoratorObject)(decorator.arguments[0], new Set([
@@ -534,7 +602,7 @@ function transform2View(func, decorator, options) {
534
602
  });
535
603
  }
536
604
  else {
537
- return (0, utils_1.throwError)(options?.parsingId, '不支持的装饰器类型', decorator.type, decorator);
605
+ return (0, utils_1.throwError)(options, '不支持的装饰器类型', decorator.type, decorator);
538
606
  }
539
607
  }
540
608
  func.params.forEach((param) => {
@@ -557,13 +625,13 @@ function transform2View(func, decorator, options) {
557
625
  propertyMap[property.value.left.name] = property.value;
558
626
  }
559
627
  else {
560
- return (0, utils_1.throwError)(options?.parsingId, '不支持的参数类型', property.value.type, property.value);
628
+ return (0, utils_1.throwError)(options, '不支持的参数类型', property.value.type, property.value);
561
629
  }
562
630
  }
563
631
  });
564
632
  const type = param.typeAnnotation?.typeAnnotation;
565
633
  if (!type)
566
- return (0, utils_1.throwError)(options?.parsingId, 'param 没有对应的类型', param);
634
+ return (0, utils_1.throwError)(options, 'param 没有对应的类型', param);
567
635
  type.members.forEach((member) => {
568
636
  if (member.type === 'TSPropertySignature') {
569
637
  const name = member.key.name;
@@ -581,13 +649,13 @@ function transform2View(func, decorator, options) {
581
649
  for (let index = 0; index < statements.length; index++) {
582
650
  const statement = statements[index];
583
651
  if (statement.type === 'VariableDeclaration') {
584
- const variables = transform2Variables(statement);
652
+ const variables = transform2Variables(statement, { ...options });
585
653
  variables.forEach((variable) => {
586
654
  view.addVariable(variable);
587
655
  });
588
656
  }
589
657
  else if (statement.type === 'FunctionDeclaration') {
590
- const logic = (0, transform2Logic_1.transform2Logic)(statement, undefined, options);
658
+ const logic = (0, transform2Logic_1.transform2Logic)(statement, undefined, { ...options, logicType: 'view_logic' });
591
659
  view.addLogic(logic);
592
660
  }
593
661
  else if (statement.type === 'ExpressionStatement' && statement.expression.type === 'CallExpression') {
@@ -597,7 +665,7 @@ function transform2View(func, decorator, options) {
597
665
  const arg = expression.arguments[0];
598
666
  const bindEvent = new utils_1.naslTypes.BindEvent({
599
667
  name: eventName,
600
- logics: transform2EventLogics(arg, eventName, options) || [],
668
+ logics: transform2EventLogics(arg, eventName, { ...options }) || [],
601
669
  });
602
670
  view.addBindEvent(bindEvent);
603
671
  }
@@ -610,7 +678,7 @@ function transform2View(func, decorator, options) {
610
678
  if (directoryItem) {
611
679
  const nextStatement = statements[index + 1];
612
680
  if (nextStatement) {
613
- const definitionItem = handleDirectoryItem(directoryItem, nextStatement, view, options, expression.callee.name);
681
+ const definitionItem = handleDirectoryItem(directoryItem, nextStatement, view, { ...options }, expression.callee.name);
614
682
  if (definitionItem) {
615
683
  // 跳过下一个语句,因为已经处理过了
616
684
  index++;
@@ -618,33 +686,33 @@ function transform2View(func, decorator, options) {
618
686
  }
619
687
  }
620
688
  else {
621
- return (0, utils_1.throwError)(options?.parsingId, '不支持的定义类型', directoryNode);
689
+ return (0, utils_1.throwError)(options, '不支持的定义类型', directoryNode);
622
690
  }
623
691
  }
624
692
  }
625
693
  else {
626
- return (0, utils_1.throwError)(options?.parsingId, '不支持的表达式', statement);
694
+ return (0, utils_1.throwError)(options, '不支持的表达式', statement);
627
695
  }
628
696
  }
629
697
  else {
630
- return (0, utils_1.throwError)(options?.parsingId, '不支持的表达式', statement);
698
+ return (0, utils_1.throwError)(options, '不支持的表达式', statement);
631
699
  }
632
700
  }
633
701
  else if (statement.type === 'ReturnStatement') {
634
702
  const arg = statement.argument;
635
703
  if (arg.type === 'JSXElement') {
636
- const child = transformJSXElement2ViewElement(arg, { ...options, nameMap });
704
+ const child = transformJSXElement2ViewElement(arg, opts);
637
705
  view.elements = child ? [child] : [];
638
706
  }
639
707
  else if (arg.type === 'JSXFragment') {
640
- view.elements = arg.children.filter((child) => child.type === 'JSXElement').map((child) => transformJSXElement2ViewElement(child, { ...options, nameMap })).filter(Boolean);
708
+ view.elements = arg.children.filter((child) => child.type === 'JSXElement').map((child) => transformJSXElement2ViewElement(child, opts)).filter(Boolean);
641
709
  }
642
710
  else {
643
- return (0, utils_1.throwError)(options?.parsingId, '返回值不正确', arg);
711
+ return (0, utils_1.throwError)(options, '返回值不正确', arg);
644
712
  }
645
713
  }
646
714
  else {
647
- return (0, utils_1.throwError)(options?.parsingId, '不支持的表达式', statement);
715
+ return (0, utils_1.throwError)(options, '不支持的表达式', statement);
648
716
  }
649
717
  }
650
718
  return view;
@@ -654,6 +722,7 @@ function transformTSDeclareFunction2View(func, decorator, options) {
654
722
  const view = new utils_1.naslTypes.View({
655
723
  name: func.id?.name,
656
724
  });
725
+ options.nodeName = view.name;
657
726
  if (decorator) {
658
727
  if (decorator.arguments[0].type === 'ObjectExpression') {
659
728
  const viewObj = (0, utils_1.pickDecoratorObject)(decorator.arguments[0], new Set([
@@ -671,7 +740,7 @@ function transformTSDeclareFunction2View(func, decorator, options) {
671
740
  });
672
741
  }
673
742
  else {
674
- return (0, utils_1.throwError)(options?.parsingId, '不支持的装饰器类型', decorator.type, decorator);
743
+ return (0, utils_1.throwError)(options, '不支持的装饰器类型', decorator.type, decorator);
675
744
  }
676
745
  }
677
746
  func.params.forEach((param) => {