@lcap/nasl 3.8.2-beta.9 → 3.8.3-beta.2

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 (233) hide show
  1. package/ai-engineer.config.js +617 -0
  2. package/out/common/BaseNode.d.ts +9 -4
  3. package/out/common/BaseNode.js +43 -10
  4. package/out/common/BaseNode.js.map +1 -1
  5. package/out/concepts/AuthLogicForCallInterface__.js +2 -50
  6. package/out/concepts/AuthLogicForCallInterface__.js.map +1 -1
  7. package/out/concepts/BackendVariable__.js +16 -1
  8. package/out/concepts/BackendVariable__.js.map +1 -1
  9. package/out/concepts/BindAttribute__.js +12 -4
  10. package/out/concepts/BindAttribute__.js.map +1 -1
  11. package/out/concepts/BindDirective__.js +1 -1
  12. package/out/concepts/BindDirective__.js.map +1 -1
  13. package/out/concepts/BindStyle__.js +1 -1
  14. package/out/concepts/BindStyle__.js.map +1 -1
  15. package/out/concepts/BusinessComponent__.js +2 -42
  16. package/out/concepts/BusinessComponent__.js.map +1 -1
  17. package/out/concepts/BusinessLogic__.js +2 -50
  18. package/out/concepts/BusinessLogic__.js.map +1 -1
  19. package/out/concepts/CallFunction__.d.ts +1 -1
  20. package/out/concepts/CallFunction__.js +1 -1
  21. package/out/concepts/CallLogic__.js +7 -1
  22. package/out/concepts/CallLogic__.js.map +1 -1
  23. package/out/concepts/CallQueryComponent__.d.ts +1 -0
  24. package/out/concepts/CallQueryComponent__.js +23 -12
  25. package/out/concepts/CallQueryComponent__.js.map +1 -1
  26. package/out/concepts/Destination__.js +11 -8
  27. package/out/concepts/Destination__.js.map +1 -1
  28. package/out/concepts/EntityProperty__.js +3 -2
  29. package/out/concepts/EntityProperty__.js.map +1 -1
  30. package/out/concepts/Entity__.js +1 -1
  31. package/out/concepts/Entity__.js.map +1 -1
  32. package/out/concepts/Identifier__.d.ts +2 -0
  33. package/out/concepts/Identifier__.js +51 -5
  34. package/out/concepts/Identifier__.js.map +1 -1
  35. package/out/concepts/Interface__.js +1 -1
  36. package/out/concepts/Interface__.js.map +1 -1
  37. package/out/concepts/Logic__.js +33 -111
  38. package/out/concepts/Logic__.js.map +1 -1
  39. package/out/concepts/MemberExpression__.d.ts +1 -1
  40. package/out/concepts/MemberExpression__.js +15 -3
  41. package/out/concepts/MemberExpression__.js.map +1 -1
  42. package/out/concepts/OqlQueryComponent__.js +37 -12
  43. package/out/concepts/OqlQueryComponent__.js.map +1 -1
  44. package/out/concepts/OverriddenLogic__.js +2 -50
  45. package/out/concepts/OverriddenLogic__.js.map +1 -1
  46. package/out/concepts/Param__.js +5 -4
  47. package/out/concepts/Param__.js.map +1 -1
  48. package/out/concepts/ProcessElementV2__.js +4 -0
  49. package/out/concepts/ProcessElementV2__.js.map +1 -1
  50. package/out/concepts/ProcessElement__.js +4 -0
  51. package/out/concepts/ProcessElement__.js.map +1 -1
  52. package/out/concepts/ProcessV2__.js +4 -0
  53. package/out/concepts/ProcessV2__.js.map +1 -1
  54. package/out/concepts/Process__.js +4 -0
  55. package/out/concepts/Process__.js.map +1 -1
  56. package/out/concepts/QueryOrderByExpression__.d.ts +0 -1
  57. package/out/concepts/QueryOrderByExpression__.js +0 -1
  58. package/out/concepts/QueryOrderByExpression__.js.map +1 -1
  59. package/out/concepts/Structure__.js +5 -7
  60. package/out/concepts/Structure__.js.map +1 -1
  61. package/out/concepts/SubLogic__.js +5 -50
  62. package/out/concepts/SubLogic__.js.map +1 -1
  63. package/out/concepts/Variable__.js +5 -0
  64. package/out/concepts/Variable__.js.map +1 -1
  65. package/out/concepts/ViewElement__.d.ts +1 -0
  66. package/out/concepts/ViewElement__.js +16 -6
  67. package/out/concepts/ViewElement__.js.map +1 -1
  68. package/out/concepts/View__.js +48 -49
  69. package/out/concepts/View__.js.map +1 -1
  70. package/out/natural/genNaturalTS.d.ts +45 -10
  71. package/out/natural/genNaturalTS.js +57 -33
  72. package/out/natural/genNaturalTS.js.map +1 -1
  73. package/out/natural/getContext/getUILib.js +6 -3
  74. package/out/natural/getContext/getUILib.js.map +1 -1
  75. package/out/natural/getContext/index.d.ts +20 -7
  76. package/out/natural/getContext/index.js +143 -23
  77. package/out/natural/getContext/index.js.map +1 -1
  78. package/out/natural/getContext/naslStdlibMap.js +8 -8
  79. package/out/natural/getContext/naslStdlibMap.js.map +1 -1
  80. package/out/natural/tools.d.ts +16 -0
  81. package/out/natural/tools.js +110 -2
  82. package/out/natural/tools.js.map +1 -1
  83. package/out/natural/transformTS2UI.js +343 -292
  84. package/out/natural/transformTS2UI.js.map +1 -1
  85. package/out/natural/transformTSCode.d.ts +3 -5
  86. package/out/natural/transformTSCode.js +30 -1089
  87. package/out/natural/transformTSCode.js.map +1 -1
  88. package/out/natural/transforms/registerTransform.d.ts +7 -0
  89. package/out/natural/transforms/registerTransform.js +24 -0
  90. package/out/natural/transforms/registerTransform.js.map +1 -0
  91. package/out/natural/transforms/transform2LogicItem.d.ts +24 -0
  92. package/out/natural/transforms/transform2LogicItem.js +1240 -0
  93. package/out/natural/transforms/transform2LogicItem.js.map +1 -0
  94. package/out/natural/transforms/transform2TypeAnnotation.d.ts +2 -0
  95. package/out/natural/transforms/transform2TypeAnnotation.js +86 -0
  96. package/out/natural/transforms/transform2TypeAnnotation.js.map +1 -0
  97. package/out/natural/transforms/utils.d.ts +8 -0
  98. package/out/natural/transforms/utils.js +59 -0
  99. package/out/natural/transforms/utils.js.map +1 -0
  100. package/out/server/getLogics.js +12 -12
  101. package/out/server/getLogics.js.map +1 -1
  102. package/out/server/naslServer.d.ts +2 -2
  103. package/out/server/naslServer.js +48 -18
  104. package/out/server/naslServer.js.map +1 -1
  105. package/out/server/semanticData.d.ts +32 -0
  106. package/out/server/semanticData.js +371 -0
  107. package/out/server/semanticData.js.map +1 -0
  108. package/out/server/translator.js +5 -0
  109. package/out/server/translator.js.map +1 -1
  110. package/out/templator/block2nasl/jsx2nasl/index.d.ts +5 -0
  111. package/out/templator/block2nasl/jsx2nasl/index.js +15 -0
  112. package/out/templator/block2nasl/jsx2nasl/index.js.map +1 -0
  113. package/out/templator/block2nasl/jsx2nasl/transform-expression2nasl.d.ts +3 -0
  114. package/out/templator/block2nasl/jsx2nasl/transform-expression2nasl.js +213 -0
  115. package/out/templator/block2nasl/jsx2nasl/transform-expression2nasl.js.map +1 -0
  116. package/out/templator/block2nasl/jsx2nasl/transform-func2nasl.d.ts +14 -0
  117. package/out/templator/block2nasl/jsx2nasl/transform-func2nasl.js +201 -0
  118. package/out/templator/block2nasl/jsx2nasl/transform-func2nasl.js.map +1 -0
  119. package/out/templator/block2nasl/jsx2nasl/transform-tstype2nasl.d.ts +4 -0
  120. package/out/templator/block2nasl/jsx2nasl/transform-tstype2nasl.js +186 -0
  121. package/out/templator/block2nasl/jsx2nasl/transform-tstype2nasl.js.map +1 -0
  122. package/out/templator/block2nasl/jsx2nasl/transform-tsx2nasl.d.ts +28 -0
  123. package/out/templator/block2nasl/jsx2nasl/transform-tsx2nasl.js +336 -0
  124. package/out/templator/block2nasl/jsx2nasl/transform-tsx2nasl.js.map +1 -0
  125. package/out/templator/block2nasl/jsx2nasl/utils.d.ts +2 -0
  126. package/out/templator/block2nasl/jsx2nasl/utils.js +26 -0
  127. package/out/templator/block2nasl/jsx2nasl/utils.js.map +1 -0
  128. package/out/templator/block2nasl/transformBlock2Nasl.d.ts +10 -0
  129. package/out/templator/block2nasl/transformBlock2Nasl.js +122 -0
  130. package/out/templator/block2nasl/transformBlock2Nasl.js.map +1 -0
  131. package/out/templator/block2nasl/viewMergeBlock.d.ts +9 -0
  132. package/out/templator/block2nasl/viewMergeBlock.js +111 -0
  133. package/out/templator/block2nasl/viewMergeBlock.js.map +1 -0
  134. package/out/translator/types.d.ts +2 -0
  135. package/out/translator/utils.js +1 -1
  136. package/out/translator/utils.js.map +1 -1
  137. package/out/utils/index.js +0 -4
  138. package/out/utils/index.js.map +1 -1
  139. package/out/utils/language-cache/constant.d.ts +2 -1
  140. package/out/utils/language-cache/constant.js +1 -0
  141. package/out/utils/language-cache/constant.js.map +1 -1
  142. package/out/utils/language-cache/nasl.d.ts +1 -0
  143. package/out/utils/language-cache/nasl.js +9 -1
  144. package/out/utils/language-cache/nasl.js.map +1 -1
  145. package/package.json +6 -2
  146. package/sandbox-natural/stdlib/nasl.core.d.ts +54 -0
  147. package/sandbox-natural/stdlib/nasl.oql.d.ts +22 -0
  148. package/sandbox-natural/stdlib/nasl.ui.d.ts +78 -0
  149. package/sandbox-natural/stdlib/nasl.ui.h5.d.ts +1684 -1643
  150. package/sandbox-natural/stdlib/nasl.ui.h5.json +15746 -15045
  151. package/sandbox-natural/stdlib/nasl.ui.pc.d.ts +5341 -5154
  152. package/sandbox-natural/stdlib/nasl.ui.pc.json +31176 -30681
  153. package/sandbox-natural/stdlib/{nasl.util.ts → nasl.util.d.ts} +49 -43
  154. package/src/common/BaseNode.ts +50 -8
  155. package/src/concepts/AuthLogicForCallInterface__.ts +3 -56
  156. package/src/concepts/BackendVariable__.ts +16 -1
  157. package/src/concepts/BindAttribute__.ts +18 -13
  158. package/src/concepts/BindDirective__.ts +1 -1
  159. package/src/concepts/BindStyle__.ts +1 -1
  160. package/src/concepts/BusinessComponent__.ts +6 -51
  161. package/src/concepts/BusinessLogic__.ts +4 -56
  162. package/src/concepts/CallFunction__.ts +1 -1
  163. package/src/concepts/CallLogic__.ts +21 -16
  164. package/src/concepts/CallQueryComponent__.ts +26 -12
  165. package/src/concepts/Destination__.ts +14 -12
  166. package/src/concepts/EntityProperty__.ts +5 -5
  167. package/src/concepts/Entity__.ts +1 -1
  168. package/src/concepts/Identifier__.ts +57 -6
  169. package/src/concepts/Interface__.ts +1 -1
  170. package/src/concepts/Logic__.ts +44 -134
  171. package/src/concepts/MemberExpression__.ts +21 -7
  172. package/src/concepts/OqlQueryComponent__.ts +29 -5
  173. package/src/concepts/OverriddenLogic__.ts +4 -56
  174. package/src/concepts/Param__.ts +5 -4
  175. package/src/concepts/ProcessElementV2__.ts +4 -0
  176. package/src/concepts/ProcessElement__.ts +4 -0
  177. package/src/concepts/ProcessV2__.ts +5 -0
  178. package/src/concepts/Process__.ts +4 -0
  179. package/src/concepts/QueryOrderByExpression__.ts +0 -1
  180. package/src/concepts/Structure__.ts +5 -7
  181. package/src/concepts/SubLogic__.ts +6 -56
  182. package/src/concepts/Variable__.ts +9 -5
  183. package/src/concepts/ViewElement__.ts +24 -7
  184. package/src/concepts/View__.ts +75 -76
  185. package/src/natural/genNaturalTS.ts +88 -39
  186. package/src/natural/getContext/getUILib.ts +6 -3
  187. package/src/natural/getContext/index.ts +125 -23
  188. package/src/natural/getContext/naslStdlibMap.ts +8 -8
  189. package/src/natural/tools.ts +107 -2
  190. package/src/natural/transformTS2UI.ts +190 -137
  191. package/src/natural/transformTSCode.ts +29 -1055
  192. package/src/natural/transforms/registerTransform.ts +34 -0
  193. package/src/natural/transforms/transform2LogicItem.ts +1335 -0
  194. package/src/natural/transforms/transform2TypeAnnotation.ts +77 -0
  195. package/src/natural/transforms/utils.ts +25 -0
  196. package/src/server/getLogics.ts +12 -12
  197. package/src/server/naslServer.ts +54 -19
  198. package/src/server/semanticData.ts +447 -0
  199. package/src/server/translator.ts +5 -0
  200. package/src/templator/block2nasl/jsx2nasl/index.ts +11 -0
  201. package/src/templator/block2nasl/jsx2nasl/transform-expression2nasl.ts +238 -0
  202. package/src/templator/block2nasl/jsx2nasl/transform-func2nasl.ts +241 -0
  203. package/src/templator/block2nasl/jsx2nasl/transform-tstype2nasl.ts +213 -0
  204. package/src/templator/block2nasl/jsx2nasl/transform-tsx2nasl.ts +422 -0
  205. package/src/templator/block2nasl/jsx2nasl/utils.ts +19 -0
  206. package/src/templator/block2nasl/transformBlock2Nasl.ts +99 -0
  207. package/src/templator/block2nasl/viewMergeBlock.ts +150 -0
  208. package/src/translator/types.ts +2 -0
  209. package/src/translator/utils.ts +2 -2
  210. package/src/utils/index.ts +0 -4
  211. package/src/utils/language-cache/constant.ts +1 -0
  212. package/src/utils/language-cache/nasl.ts +6 -0
  213. package/test/concepts/logic/__snapshots__/toEmbeddedTS.spec.ts.snap +182 -0
  214. package/test/concepts/logic/constant.ts +5 -0
  215. package/test/concepts/logic/fixtures/variable-host-call-logic-member-expression.json +267 -0
  216. package/test/concepts/logic/fixtures/variable-host-call-logic-nested-member-expression copy.json +457 -0
  217. package/test/concepts/logic/fixtures/variable-host-call-logic-with-handle-error-member-expression.json +267 -0
  218. package/test/concepts/logic/toEmbeddedTS.spec.ts +15 -0
  219. package/test/tdd/dataQuery/QueryFieldExpression/case1/ast.json +7 -0
  220. package/test/tdd/dataQuery/QueryFieldExpression/case1/natural.ts.txt +1 -0
  221. package/test/tdd/dataQuery/QueryFieldExpression/case2/ast.json +7 -0
  222. package/test/tdd/dataQuery/QueryFieldExpression/case2/natural.ts.txt +1 -0
  223. package/test/tdd/transform/case1/ast.json +243 -0
  224. package/test/tdd/transform/case1/natural.ts.md +20 -0
  225. package/test/tdd/transform/case2/ast.json +207 -0
  226. package/test/tdd/transform/case2/natural.ts.md +12 -0
  227. package/test/tdd.test.js +10 -0
  228. package/test/tdd.transform.test.js +38 -0
  229. package/test/utils.js +40 -0
  230. package/sandbox-natural/stdlib/nasl.core.ts +0 -36
  231. package/sandbox-natural/stdlib/nasl.oql.ts +0 -14
  232. package/sandbox-natural/stdlib/nasl.ui.pre.d.ts +0 -90
  233. package/sandbox-natural/stdlib/nasl.ui.ts +0 -63
@@ -0,0 +1,422 @@
1
+ /* eslint-disable no-use-before-define */
2
+ // @ts-nocheck
3
+ import {
4
+ ArrayExpression,
5
+ JSXAttribute,
6
+ JSXElement,
7
+ JSXExpressionContainer,
8
+ JSXFragment,
9
+ JSXIdentifier,
10
+ JSXMemberExpression,
11
+ JSXNamespacedName,
12
+ JSXSpreadAttribute,
13
+ JSXText,
14
+ JSXSpreadChild,
15
+ Expression,
16
+ } from '@babel/types';
17
+ import reactStyleToCSS from 'react-style-object-to-css';
18
+ import { kebabCase, lowerFirst } from 'lodash';
19
+ import { getNodeCode } from './utils';
20
+ import transformExpression2Nasl from './transform-expression2nasl';
21
+ import transformFunc2Nasl from './transform-func2nasl';
22
+
23
+ export interface NaslViewContext {
24
+ variableNames?: string[];
25
+ logics?: string[];
26
+ }
27
+
28
+ export interface NaslViewElement {
29
+ concept: 'ViewElement';
30
+ tag: string;
31
+ name: string;
32
+ staticStyle?: string;
33
+ staticClass?: string;
34
+ slotTarget?: string;
35
+ slotScope?: string;
36
+ bindAttrs: any[];
37
+ bindEvents: any[];
38
+ bindDirectives: any[];
39
+ bindRoles: any[];
40
+ bindStyles: any[];
41
+ children: NaslViewElement[];
42
+ }
43
+
44
+ export const EVENT_REGEX = /^on[A-Z].*/;
45
+
46
+ export function getJSXName(ast: JSXIdentifier | JSXNamespacedName | JSXMemberExpression) {
47
+ if (ast.type !== 'JSXIdentifier') {
48
+ throw new Error(`解析 JSXElement 异常, TagName 只运行命名标识, ${getNodeCode(ast)}`);
49
+ }
50
+
51
+ return ast.name;
52
+ }
53
+
54
+ const parseJSXStyle = (node) => {
55
+ if (node.type === 'StringLiteral') {
56
+ return node.value;
57
+ }
58
+
59
+ if (node.type === 'JSXExpressionContainer' && node.expression.type === 'ObjectExpression') {
60
+ // eslint-disable-next-line no-eval
61
+ const styleObj = eval(`(${getNodeCode(node.expression)})`);
62
+ return reactStyleToCSS(styleObj);
63
+ }
64
+
65
+ return null;
66
+ };
67
+
68
+ const getSlotName = (attrName: string) => {
69
+ const slotRegex = /^slot[A-Z].*/;
70
+ if (slotRegex.test(attrName)) {
71
+ return lowerFirst(attrName.substring(4));
72
+ }
73
+ const slotPrefix = 'slot-';
74
+ if (attrName.startsWith(slotPrefix)) {
75
+ return attrName.substring(slotPrefix.length);
76
+ }
77
+
78
+ return attrName;
79
+ };
80
+
81
+ const isJSXEleArray = (ast: ArrayExpression) => ast.elements.findIndex((n) => !n || (n.type !== 'JSXElement' && n.type !== 'JSXFragment')) === -1;
82
+
83
+ const createTextNode = (str = '') => {
84
+ if (!str || !str.trim()) {
85
+ return null;
86
+ }
87
+
88
+ return {
89
+ concept: 'ViewElement',
90
+ tag: 'Text',
91
+ name: '',
92
+ bindAttrs: [{
93
+ concept: 'BindAttribute',
94
+ type: 'string',
95
+ name: 'children',
96
+ value: str,
97
+ }],
98
+ bindEvents: [],
99
+ bindDirectives: [],
100
+ bindRoles: [],
101
+ bindStyles: [],
102
+ children: [],
103
+ } as NaslViewElement;
104
+ };
105
+
106
+ const SYNC_KEY = '$sync';
107
+
108
+ export function transformJSXChildNode(node: JSXText | JSXExpressionContainer | JSXSpreadChild | JSXElement | JSXFragment) {
109
+ if (node.type === 'JSXText') {
110
+ return createTextNode(node.value);
111
+ }
112
+
113
+ if (node.type === 'JSXElement') {
114
+ return transformJSXElement2Nasl(node);
115
+ }
116
+
117
+ if (node.type === 'JSXExpressionContainer' && ['NumericLiteral', 'StringLiteral', 'MemberExpression'].indexOf(node.expression.type) !== -1) {
118
+ if (node.expression.type === 'MemberExpression') {
119
+ return {
120
+ concept: 'ViewElement',
121
+ tag: 'Text',
122
+ name: '',
123
+ bindAttrs: [{
124
+ concept: 'BindAttribute',
125
+ type: 'dynamic',
126
+ name: 'children',
127
+ expression: transformExpression2Nasl(node.expression),
128
+ }],
129
+ bindEvents: [],
130
+ bindDirectives: [],
131
+ bindRoles: [],
132
+ bindStyles: [],
133
+ children: [],
134
+ } as NaslViewElement;
135
+ }
136
+ return createTextNode(getNodeCode(node.expression));
137
+ }
138
+
139
+ throw new Error(`JSX 解析异常,子节点仅允许是,JSXText 或 JSXElement, code: ${getNodeCode(node)}`);
140
+ }
141
+
142
+ export function parseJSXElement2Slot(ele: JSXElement | JSXFragment | Array<JSXElement | JSXFragment>, attrName: string, argName: string) {
143
+ const templateAST: NaslViewElement = {
144
+ concept: 'ViewElement',
145
+ tag: 'template',
146
+ name: '',
147
+ bindAttrs: [],
148
+ bindEvents: [],
149
+ bindDirectives: [],
150
+ bindRoles: [],
151
+ bindStyles: [],
152
+ children: [],
153
+ slotTarget: getSlotName(attrName),
154
+ };
155
+
156
+ const eles = Array.isArray(ele) ? ele : [ele];
157
+
158
+ eles.forEach((node) => {
159
+ if (node.type === 'JSXElement') {
160
+ templateAST.children.push(transformJSXElement2Nasl(node));
161
+ return;
162
+ }
163
+
164
+ node.children.forEach((n) => {
165
+ const naslEle = transformJSXChildNode(n);
166
+
167
+ if (naslEle) {
168
+ templateAST.children.push(naslEle);
169
+ }
170
+ });
171
+ });
172
+
173
+ if (argName) {
174
+ templateAST.slotScope = argName;
175
+ }
176
+ return templateAST;
177
+ }
178
+
179
+ export function parseJSXExpression(ast: JSXElement | JSXFragment | JSXExpressionContainer, attrName: string, element: NaslViewElement) {
180
+ if (ast.type === 'JSXElement') {
181
+ element.children.push(parseJSXElement2Slot(ast, attrName, ''));
182
+ return;
183
+ }
184
+ if (ast.type === 'JSXFragment') {
185
+ element.children.push(parseJSXElement2Slot(ast, attrName, ''));
186
+ return;
187
+ }
188
+
189
+ if (ast.expression.type === 'JSXEmptyExpression') {
190
+ throw new Error('解析JSX Expression 异常, 不支持空的Expression');
191
+ }
192
+
193
+ if (ast.expression.type === 'JSXElement') {
194
+ element.children.push(parseJSXElement2Slot(ast.expression, attrName, ''));
195
+ return;
196
+ }
197
+
198
+ if (ast.expression.type === 'JSXFragment') {
199
+ element.children.push(parseJSXElement2Slot(ast.expression, attrName, ''));
200
+ return;
201
+ }
202
+
203
+ if (ast.expression.type === 'ArrayExpression' && isJSXEleArray(ast.expression)) {
204
+ element.children.push(parseJSXElement2Slot(ast.expression.elements as any[], attrName, ''));
205
+ return;
206
+ }
207
+
208
+ if (
209
+ ast.expression.type === 'ArrowFunctionExpression' && (
210
+ ast.expression.body.type === 'JSXElement'
211
+ || ast.expression.body.type === 'JSXFragment'
212
+ )
213
+ ) {
214
+ let argName = '';
215
+ if (ast.expression.params && ast.expression.params[0] && ast.expression.params[0].type === 'Identifier') {
216
+ argName = ast.expression.params[0].name;
217
+ }
218
+
219
+ element.children.push(parseJSXElement2Slot(ast.expression.body, attrName, argName));
220
+ return;
221
+ }
222
+
223
+ if (ast.expression.type === 'CallExpression' && getNodeCode(ast.expression.callee) === SYNC_KEY) {
224
+ if (ast.expression.arguments.length !== 1) {
225
+ throw new Error(`解析 JSX Expression 异常,$sync 仅允许传一个参数,${getNodeCode(ast)}`);
226
+ }
227
+
228
+ const arg = ast.expression.arguments[0];
229
+ if (['JSXNamespacedName', 'SpreadElement', 'ArgumentPlaceholder'].indexOf(arg.type) !== -1) {
230
+ throw new Error(`解析 JSX Expression 异常,不支持该表达式,${getNodeCode(ast)}`);
231
+ }
232
+
233
+ element.bindAttrs.push({
234
+ concept: 'BindAttribute',
235
+ name: attrName,
236
+ type: 'dynamic',
237
+ sync: true,
238
+ expression: transformExpression2Nasl(arg as Expression),
239
+ });
240
+ return;
241
+ }
242
+
243
+ if (['NumericLiteral', 'BooleanLiteral', 'ArrayExpression', 'ObjectExpression'].indexOf(ast.expression.type) !== -1) {
244
+ element.bindAttrs.push({
245
+ concept: 'BindAttribute',
246
+ name: attrName,
247
+ type: 'static',
248
+ value: getNodeCode(ast.expression),
249
+ });
250
+ return;
251
+ }
252
+
253
+ if (EVENT_REGEX.test(attrName)) {
254
+ const eventName = kebabCase(attrName.substring(2));
255
+ const bindEvent: any = {
256
+ concept: 'BindEvent',
257
+ name: eventName,
258
+ logics: [],
259
+ };
260
+
261
+ if (ast.expression.type === 'FunctionExpression') {
262
+ const logicNode = transformFunc2Nasl(ast.expression);
263
+ logicNode.params = [];
264
+ bindEvent.logics.push(logicNode);
265
+ } else if (ast.expression.type === 'ArrayExpression' && ast.expression.elements.findIndex((eleNode) => !eleNode || eleNode.type !== 'FunctionExpression') === -1) {
266
+ bindEvent.logics.push(...ast.expression.elements.map((eleNode) => {
267
+ const logicNode = transformFunc2Nasl(eleNode as any);
268
+ logicNode.params = [];
269
+ return logicNode;
270
+ }));
271
+ } else {
272
+ throw new Error(`JSX 解析失败,事件绑定仅支持函数或函数数组, ${getNodeCode(ast)}`);
273
+ }
274
+
275
+ element.bindEvents.push(bindEvent);
276
+ return;
277
+ }
278
+
279
+ element.bindAttrs.push({
280
+ concept: 'BindAttribute',
281
+ name: attrName,
282
+ type: 'dynamic',
283
+ expression: transformExpression2Nasl(ast.expression),
284
+ });
285
+ }
286
+
287
+ export function parseJSXAttr(attr: JSXAttribute | JSXSpreadAttribute, element: NaslViewElement) {
288
+ if (attr.type === 'JSXSpreadAttribute') {
289
+ throw new Error(`解析 JSXElement 异常, 不支持 ...rest 属性, ${getNodeCode(attr)}`);
290
+ }
291
+
292
+ const attrName = getJSXName(attr.name);
293
+
294
+ if (attrName === 'ref') {
295
+ if (!attr.value || attr.value.type !== 'StringLiteral') {
296
+ throw new Error(`解析 JSXElement 异常, ref 仅允许设置静态字符串, 例如 ref="button", ${getNodeCode(attr)}`);
297
+ }
298
+ element.name = attr.value.value;
299
+ return;
300
+ }
301
+
302
+ if (attrName === 'style') {
303
+ const value = parseJSXStyle(attr.value);
304
+ if (value) {
305
+ element.staticStyle = value;
306
+ }
307
+ return;
308
+ }
309
+
310
+ if ((attrName === 'className' || attrName === 'class') && attr.value) {
311
+ if (attr.value.type === 'StringLiteral' && attr.value.value) {
312
+ element.staticClass = attr.value.value;
313
+ }
314
+ return;
315
+ }
316
+
317
+ if (attrName === 'rules') {
318
+ if (!attr.value || attr.value.type !== 'JSXExpressionContainer' || attr.value.expression.type !== 'ArrayExpression') {
319
+ throw new Error(`解析 JSXElement 异常, rules 仅允许设置内置验证规则, 例如 rules=[nasl.validation.required()], ${getNodeCode(attr)}`);
320
+ }
321
+
322
+ element.bindAttrs.push({
323
+ concept: 'BindAttribute',
324
+ name: attrName,
325
+ rules: attr.value.expression.elements.map((exp) => {
326
+ if (!exp || exp.type !== 'CallExpression') {
327
+ throw new Error(`解析 JSXElement 异常, rules 仅允许设置内置验证规则, 例如 rules=[nasl.validation.required()], ${getNodeCode(attr)}`);
328
+ }
329
+ const callLogic = transformExpression2Nasl(exp);
330
+
331
+ return {
332
+ concept: 'ValidationRule',
333
+ calleeNamespace: callLogic.calleeNamespace,
334
+ calleeName: callLogic.calleeName,
335
+ arguments: callLogic.arguments,
336
+ };
337
+ }),
338
+ });
339
+ return;
340
+ }
341
+
342
+ if (!attr.value) {
343
+ element.bindAttrs.push({
344
+ concept: 'BindAttribute',
345
+ name: attrName,
346
+ type: 'static',
347
+ value: 'true',
348
+ });
349
+ return;
350
+ }
351
+
352
+ if (attr.value.type === 'JSXExpressionContainer' || attr.value.type === 'JSXElement' || attr.value.type === 'JSXFragment') {
353
+ parseJSXExpression(attr.value, attrName, element);
354
+ return;
355
+ }
356
+
357
+ element.bindAttrs.push({
358
+ concept: 'BindAttribute',
359
+ name: attrName,
360
+ type: 'string',
361
+ value: attr.value ? attr.value.value : '',
362
+ });
363
+ }
364
+
365
+ export function transformJSXElement2Nasl(element: JSXElement) {
366
+ const node = element.openingElement;
367
+
368
+ const elementAST: NaslViewElement = {
369
+ concept: 'ViewElement',
370
+ tag: '',
371
+ name: '',
372
+ bindAttrs: [],
373
+ bindEvents: [],
374
+ bindDirectives: [],
375
+ bindRoles: [],
376
+ bindStyles: [],
377
+ children: [],
378
+ };
379
+
380
+ if (node.name.type !== 'JSXIdentifier') {
381
+ throw new Error(`解析 JSXElement 异常, TagName 只运行命名标识, ${getNodeCode(node)}`);
382
+ }
383
+
384
+ elementAST.tag = node.name.name;
385
+
386
+ node.attributes.forEach((attr) => parseJSXAttr(attr, elementAST));
387
+
388
+ const DIRECTIVE_PREFIX = '_';
389
+ elementAST.bindAttrs = elementAST.bindAttrs.filter((attr) => {
390
+ if (attr.name.startsWith(DIRECTIVE_PREFIX)) {
391
+ elementAST.bindDirectives.push({
392
+ concept: 'BindDirective',
393
+ name: attr.name.substring(DIRECTIVE_PREFIX.length),
394
+ type: attr.type,
395
+ expression: attr.expression,
396
+ value: attr.value,
397
+ playground: [],
398
+ });
399
+ return false;
400
+ }
401
+
402
+ return true;
403
+ });
404
+
405
+ const childNodes: NaslViewElement[] = [];
406
+ element.children.forEach((childNode) => {
407
+ const result = transformJSXChildNode(childNode);
408
+ if (result) {
409
+ childNodes.push(result);
410
+ }
411
+ });
412
+
413
+ if (elementAST.tag === 'Text' && childNodes.length > 0) {
414
+ throw new Error('JSX解析异常, Text 组件不允许有子节点,请写children属性');
415
+ }
416
+
417
+ elementAST.children.push(...childNodes);
418
+
419
+ return elementAST;
420
+ }
421
+
422
+ export default transformJSXElement2Nasl;
@@ -0,0 +1,19 @@
1
+ // @ts-nocheck
2
+ import generate from '@babel/generator';
3
+
4
+ export const getNodeCode = (node) => {
5
+ try {
6
+ const { code: text = '' } = generate(node);
7
+ return text.replace(/\n/g, ' ');
8
+ } catch (e) {
9
+ throw new Error(`生成code 错误,${JSON.stringify(node)}`);
10
+ }
11
+ };
12
+
13
+ export const normalizeArray = (arr) => {
14
+ if (!arr) {
15
+ return [];
16
+ }
17
+
18
+ return Array.isArray(arr) ? arr : [arr];
19
+ };
@@ -0,0 +1,99 @@
1
+ import * as parser from '@babel/parser';
2
+ import generate from '@babel/generator';
3
+ import { Logic, View, ViewElement, Structure, LogicItem } from '../../concepts';
4
+ import { transformTSX2Nasl } from './jsx2nasl';
5
+ import { tryTransformTS2UI } from '../../natural/transformTS2UI';
6
+ import { transformTSCode } from '../../natural/transformTSCode';
7
+
8
+ const traverse = require('@babel/traverse').default;
9
+
10
+ export interface Block2NaslResult {
11
+ json: {
12
+ logics: Array<Logic>;
13
+ structures?: Array<Structure>;
14
+ };
15
+ view: View;
16
+ }
17
+
18
+ export function tryTransformJSX2UI(tsCode: string): any {
19
+ let naslViewElement: ViewElement = null;
20
+ const ast = parser.parse(tsCode, {
21
+ sourceType: 'module',
22
+ plugins: ['typescript', 'jsx'],
23
+ });
24
+ traverse(ast, {
25
+ JSXElement: (p: any) => {
26
+ try {
27
+ naslViewElement = transformTSX2Nasl(p.node) as ViewElement;
28
+ } catch (e) {}
29
+ p.parent.argument = null;
30
+ p.stop();
31
+ },
32
+ });
33
+ const result = generate(ast).code;
34
+ const tsCode1 = `\`\`\`ts
35
+ ${result}
36
+ \`\`\``;
37
+ const { view } = tryTransformTS2UI(tsCode1);
38
+ view.elements = view.elements || [];
39
+ view.elements.push(naslViewElement);
40
+ return view;
41
+ }
42
+
43
+ export function tryTransformBlock2Nasl(tsCode: string) {
44
+ console.log('tsCode', tsCode);
45
+ const ast = parser.parse(tsCode, {
46
+ sourceType: 'module',
47
+ plugins: ['typescript', 'jsx'],
48
+ });
49
+ const result : Block2NaslResult = {
50
+ json: {
51
+ logics: [],
52
+ },
53
+ view: null,
54
+ }
55
+ ast.program.body.forEach((node: any) => {
56
+ if (node.type === 'ExportNamedDeclaration') {
57
+ if (node.declaration?.id?.name === 'view') {
58
+ const viewCode = generate(node).code;
59
+ // 转jsx
60
+ result.view = tryTransformJSX2UI(viewCode);
61
+ } else if(node.declaration?.type === 'TSModuleDeclaration'){
62
+ const jsonName = node.declaration?.body?.id?.name;
63
+ if(jsonName === 'logics') {
64
+ node.declaration?.body?.body?.body?.forEach((logicNode: any) => {
65
+ const logicCode = generate(logicNode).code;
66
+ const logicName = logicNode.declaration?.id?.name;
67
+ // 转后端逻辑
68
+ let logic = transformTSCode(logicCode, logicName);
69
+ if(logic.toJSON) {
70
+ logic = logic.toJSON();
71
+ }
72
+ logic.name = logicName;
73
+ if(logic.body) {
74
+ if(logic.body[0]?.concept !== 'Start') {
75
+ logic.body.unshift(LogicItem.from({
76
+ concept: 'Start',
77
+ name: '',
78
+ label: '开始',
79
+ kind: 'Statement',
80
+ }));
81
+ }
82
+ if(logic.body[logic.body.length - 1]?.concept !== 'End') {
83
+ logic.body.push(LogicItem.from({
84
+ concept: 'End',
85
+ name: '',
86
+ label: '结束',
87
+ kind: 'Statement',
88
+ }));
89
+ }
90
+ }
91
+ result.json.logics.push(logic);
92
+ });
93
+ }
94
+ }
95
+ }
96
+ });
97
+ console.log(result);
98
+ return result;
99
+ }
@@ -0,0 +1,150 @@
1
+ import { App, BindEvent, View, ViewElement, Param, Variable, Logic, Structure, FrontendType, Frontend } from '../../concepts';
2
+ import { tryTransformBlock2Nasl } from './transformBlock2Nasl';
3
+ import { Camel2kebab } from '../../utils/string';
4
+ import { traverse } from '../../utils';
5
+
6
+
7
+ export function viewMergeBlock({
8
+ app,
9
+ view,
10
+ code,
11
+ nodePath,
12
+ position,
13
+ cb,
14
+ }: {
15
+ app: App,
16
+ view: View,
17
+ code: string;
18
+ nodePath: string;
19
+ position: string;
20
+ cb?: Function;
21
+ }) {
22
+ let targetNode = app.findNodeByPath(nodePath);
23
+ let parentNode = position === 'append' ? targetNode : targetNode.parentNode;
24
+ if (parentNode.concept === 'View') {
25
+ parentNode = targetNode;
26
+ if (position === 'insertBefore') {
27
+ targetNode = parentNode.children[0];
28
+ } else if (position === 'insertAfter') {
29
+ const len = parentNode.children.length;
30
+ targetNode = parentNode.children[len - 1];
31
+ }
32
+ }
33
+ // 页面元素
34
+ if (!parentNode) {
35
+ return;
36
+ }
37
+ const naslCode = tryTransformBlock2Nasl(code);
38
+ const blockView = naslCode.view;
39
+ // vue2需要对tag进行转换 kebab-case
40
+ const frontendType = (view as any)?.getAncestor('FrontendType');
41
+ if((frontendType as any)?.frameworkKind === 'vue2') {
42
+ traverse(({ node }) => {
43
+ if (node.concept === 'ViewElement') {
44
+ node.tag = Camel2kebab(node.tag);
45
+ }
46
+ }, { node: blockView.elements[0] }, { mode: 'anyObject' });
47
+ }
48
+
49
+ const node = ViewElement.from(
50
+ {
51
+ ...blockView.elements[0],
52
+ },
53
+ view,
54
+ 'elements',
55
+ );
56
+ if (position === 'append') {
57
+ parentNode.addViewElement(node);
58
+ cb && cb(parentNode, node);
59
+ } else {
60
+ const index = targetNode.getIndexOfParent();
61
+ if (position === 'insertBefore') {
62
+ parentNode.insertViewElementAt(node, index);
63
+ } else if (position === 'insertAfter') {
64
+ parentNode.insertViewElementAt(node, index + 1);
65
+ }
66
+ }
67
+ // 页面入参
68
+ blockView.params.forEach((paramsOption: Param) => {
69
+ const param = Param.from(
70
+ {
71
+ ...paramsOption,
72
+ },
73
+ view,
74
+ 'params',
75
+ );
76
+ view.addParam(param);
77
+ });
78
+ // 页面变量
79
+ blockView.variables.forEach((variableOption: Variable) => {
80
+ const variable = Variable.from(
81
+ {
82
+ ...variableOption,
83
+ },
84
+ view,
85
+ 'variables',
86
+ );
87
+ view.addVariable(variable);
88
+ });
89
+ // 页面生命周期函数
90
+ blockView.bindEvents?.forEach((eventOption: BindEvent) => {
91
+ const bindEvent = view.bindEvents.find((currentEventItem: BindEvent) => currentEventItem.name === eventOption.name);
92
+ if (bindEvent) {
93
+ eventOption.logics.forEach((logic: Logic) => {
94
+ bindEvent.addLogic(logic);
95
+ });
96
+ } else {
97
+ const event = BindEvent.from(
98
+ {
99
+ ...eventOption,
100
+ calleeName: '',
101
+ logics: [...eventOption.logics],
102
+ },
103
+ view,
104
+ 'bindEvents',
105
+ );
106
+ view.addBindEvent(event);
107
+ }
108
+ });
109
+ // 页面逻辑
110
+ blockView.logics.forEach((logicOption: Logic) => {
111
+ const logic = Logic.from(
112
+ {
113
+ ...logicOption,
114
+ },
115
+ view,
116
+ 'logics',
117
+ );
118
+ view.addLogic(logic);
119
+ });
120
+
121
+
122
+ // 全局逻辑
123
+ const logics = naslCode.json?.logics || [];
124
+ logics.forEach((logicOption: Logic) => {
125
+ const logic = Logic.from(
126
+ {
127
+ ...logicOption,
128
+ },
129
+ app,
130
+ 'logics',
131
+ );
132
+ app.addLogic(logic);
133
+ });
134
+
135
+ // 全局数据结构
136
+ const structures = naslCode.json?.structures || [];
137
+ if (Array.isArray(structures)) {
138
+ structures.forEach((structureOption: Structure) => {
139
+ const structure = Structure.from(
140
+ {
141
+ ...structureOption,
142
+ },
143
+ app,
144
+ 'structures',
145
+ );
146
+ app.addStructure(structure);
147
+ });
148
+ }
149
+ return node;
150
+ }
@@ -96,6 +96,8 @@ export interface TranslatorState {
96
96
  isVariableHost?: boolean;
97
97
  /** DataSource 声明 */
98
98
  isDataSource?: boolean;
99
+ /** 推导类型集合,toNaturalTS 使用 */
100
+ typeMap?: any;
99
101
  }
100
102
 
101
103
  export type SourceMapItem = Range;