@lcap/nasl 3.8.2-beta.3 → 3.8.2-beta.4

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 (212) hide show
  1. package/.mocharc.js +1 -0
  2. package/out/common/BaseNode.d.ts +19 -3
  3. package/out/common/BaseNode.js +85 -7
  4. package/out/common/BaseNode.js.map +1 -1
  5. package/out/concepts/AbstractInterface__.js.map +1 -1
  6. package/out/concepts/Annotation__.js +1 -1
  7. package/out/concepts/Annotation__.js.map +1 -1
  8. package/out/concepts/App__.d.ts +3 -0
  9. package/out/concepts/App__.js +964 -4
  10. package/out/concepts/App__.js.map +1 -1
  11. package/out/concepts/Argument__.js +3 -3
  12. package/out/concepts/Argument__.js.map +1 -1
  13. package/out/concepts/BatchAssignment__.d.ts +1 -1
  14. package/out/concepts/BatchAssignment__.js +3 -3
  15. package/out/concepts/BatchAssignment__.js.map +1 -1
  16. package/out/concepts/BindAttribute__.js +5 -6
  17. package/out/concepts/BindAttribute__.js.map +1 -1
  18. package/out/concepts/BindDirective__.js +3 -4
  19. package/out/concepts/BindDirective__.js.map +1 -1
  20. package/out/concepts/BusinessComponent__.d.ts +2 -0
  21. package/out/concepts/BusinessComponent__.js +48 -0
  22. package/out/concepts/BusinessComponent__.js.map +1 -1
  23. package/out/concepts/BusinessLogic__.d.ts +1 -0
  24. package/out/concepts/BusinessLogic__.js +10 -0
  25. package/out/concepts/BusinessLogic__.js.map +1 -1
  26. package/out/concepts/CallEvent__.d.ts +2 -0
  27. package/out/concepts/CallEvent__.js +75 -0
  28. package/out/concepts/CallEvent__.js.map +1 -1
  29. package/out/concepts/CallInterface__.d.ts +1 -0
  30. package/out/concepts/CallInterface__.js +26 -15
  31. package/out/concepts/CallInterface__.js.map +1 -1
  32. package/out/concepts/CallLogic__.d.ts +4 -0
  33. package/out/concepts/CallLogic__.js +60 -4
  34. package/out/concepts/CallLogic__.js.map +1 -1
  35. package/out/concepts/Entity__.d.ts +3 -3
  36. package/out/concepts/Entity__.js +4 -0
  37. package/out/concepts/Entity__.js.map +1 -1
  38. package/out/concepts/Event__.d.ts +2 -0
  39. package/out/concepts/Event__.js +30 -0
  40. package/out/concepts/Event__.js.map +1 -1
  41. package/out/concepts/FrontendType__.d.ts +2 -0
  42. package/out/concepts/FrontendType__.js +32 -0
  43. package/out/concepts/FrontendType__.js.map +1 -1
  44. package/out/concepts/Frontend__.d.ts +2 -0
  45. package/out/concepts/Frontend__.js +48 -0
  46. package/out/concepts/Frontend__.js.map +1 -1
  47. package/out/concepts/IfStatement__.js +6 -6
  48. package/out/concepts/IfStatement__.js.map +1 -1
  49. package/out/concepts/InterfaceParam__.d.ts +1 -0
  50. package/out/concepts/InterfaceParam__.js +23 -4
  51. package/out/concepts/InterfaceParam__.js.map +1 -1
  52. package/out/concepts/Interface__.d.ts +2 -1
  53. package/out/concepts/Interface__.js +29 -5
  54. package/out/concepts/Interface__.js.map +1 -1
  55. package/out/concepts/JSBlock__.d.ts +1 -0
  56. package/out/concepts/JSBlock__.js +6 -0
  57. package/out/concepts/JSBlock__.js.map +1 -1
  58. package/out/concepts/LogicDeclaration__.d.ts +1 -0
  59. package/out/concepts/LogicDeclaration__.js +58 -7
  60. package/out/concepts/LogicDeclaration__.js.map +1 -1
  61. package/out/concepts/Logic__.js +43 -24
  62. package/out/concepts/Logic__.js.map +1 -1
  63. package/out/concepts/MatchCase__.js +1 -2
  64. package/out/concepts/MatchCase__.js.map +1 -1
  65. package/out/concepts/Match__.js +3 -18
  66. package/out/concepts/Match__.js.map +1 -1
  67. package/out/concepts/Module__.d.ts +2 -0
  68. package/out/concepts/Module__.js +64 -0
  69. package/out/concepts/Module__.js.map +1 -1
  70. package/out/concepts/NewComposite__.d.ts +1 -1
  71. package/out/concepts/NewComposite__.js +3 -3
  72. package/out/concepts/NewComposite__.js.map +1 -1
  73. package/out/concepts/NullLiteral__.js +6 -0
  74. package/out/concepts/NullLiteral__.js.map +1 -1
  75. package/out/concepts/Paginate__.d.ts +1 -0
  76. package/out/concepts/Paginate__.js +15 -7
  77. package/out/concepts/Paginate__.js.map +1 -1
  78. package/out/concepts/QueryFromExpression__.js +2 -2
  79. package/out/concepts/QueryFromExpression__.js.map +1 -1
  80. package/out/concepts/StringLiteral__.js +3 -4
  81. package/out/concepts/StringLiteral__.js.map +1 -1
  82. package/out/concepts/TypeAnnotation__.js +1 -0
  83. package/out/concepts/TypeAnnotation__.js.map +1 -1
  84. package/out/concepts/ViewElement__.d.ts +2 -0
  85. package/out/concepts/ViewElement__.js +10 -7
  86. package/out/concepts/ViewElement__.js.map +1 -1
  87. package/out/concepts/View__.d.ts +1 -0
  88. package/out/concepts/View__.js +55 -1
  89. package/out/concepts/View__.js.map +1 -1
  90. package/out/generator/genBundleFiles.js +61 -51
  91. package/out/generator/genBundleFiles.js.map +1 -1
  92. package/out/generator/genHash.d.ts +2 -2
  93. package/out/generator/genHash.js +30 -30
  94. package/out/generator/genHash.js.map +1 -1
  95. package/out/generator/permission.d.ts +8 -1
  96. package/out/generator/permission.js +321 -23
  97. package/out/generator/permission.js.map +1 -1
  98. package/out/generator/release-body/body.d.ts +4 -0
  99. package/out/generator/release-body/body.js +20 -6
  100. package/out/generator/release-body/body.js.map +1 -1
  101. package/out/generator/release-body/data.js +6 -2
  102. package/out/generator/release-body/data.js.map +1 -1
  103. package/out/generator/release-body/index.d.ts +1 -0
  104. package/out/generator/release-body/index.js +1 -0
  105. package/out/generator/release-body/index.js.map +1 -1
  106. package/out/generator/release-body/utils.js +3 -3
  107. package/out/generator/release-body/utils.js.map +1 -1
  108. package/out/generator/release-body/validation.js +2 -2
  109. package/out/generator/release-body/validation.js.map +1 -1
  110. package/out/index.d.ts +1 -1
  111. package/out/index.js.map +1 -1
  112. package/out/natural/genNaturalTS.d.ts +2 -2
  113. package/out/natural/genNaturalTS.js +5 -5
  114. package/out/natural/genNaturalTS.js.map +1 -1
  115. package/out/natural/getContext/index.d.ts +1 -1
  116. package/out/natural/getContext/index.js +15 -9
  117. package/out/natural/getContext/index.js.map +1 -1
  118. package/out/server/entity2LogicNamespace.d.ts +2 -2
  119. package/out/server/entity2LogicNamespace.js +321 -310
  120. package/out/server/entity2LogicNamespace.js.map +1 -1
  121. package/out/server/extendBaseNode.js +29 -18
  122. package/out/server/extendBaseNode.js.map +1 -1
  123. package/out/server/naslServer.d.ts +1 -1
  124. package/out/server/naslServer.js +35 -21
  125. package/out/server/naslServer.js.map +1 -1
  126. package/out/server/translator.js +12 -0
  127. package/out/server/translator.js.map +1 -1
  128. package/out/service/storage/init.d.ts +2 -0
  129. package/out/service/storage/init.js +20 -1
  130. package/out/service/storage/init.js.map +1 -1
  131. package/out/templator/genCreateBlock.js +3 -3
  132. package/out/templator/genCreateBlock.js.map +1 -1
  133. package/out/templator/genCurdEditMultipleKeyBlock.js +2 -2
  134. package/out/templator/genCurdEditMultipleKeyBlock.js.map +1 -1
  135. package/out/templator/genCurdMultipleKeyBlock.js +4 -4
  136. package/out/templator/genCurdMultipleKeyBlock.js.map +1 -1
  137. package/out/templator/genEditTableBlock.js +1 -1
  138. package/out/templator/genEditTableBlock.js.map +1 -1
  139. package/out/templator/genGetBlock.js.map +1 -1
  140. package/out/templator/genGridViewBlock.js.map +1 -1
  141. package/out/templator/genSelectBlock.js.map +1 -1
  142. package/out/templator/genTableBlock.js.map +1 -1
  143. package/out/templator/genUpdateBlock.js +3 -3
  144. package/out/templator/genUpdateBlock.js.map +1 -1
  145. package/out/templator/utils.js +1 -1
  146. package/out/templator/utils.js.map +1 -1
  147. package/package.json +5 -5
  148. package/sandbox/stdlib/nasl.util.ts +4 -1
  149. package/src/common/BaseNode.ts +91 -11
  150. package/src/concepts/AbstractInterface__.ts +1 -0
  151. package/src/concepts/Annotation__.ts +1 -1
  152. package/src/concepts/App__.ts +104 -4
  153. package/src/concepts/Argument__.ts +3 -3
  154. package/src/concepts/BatchAssignment__.ts +3 -3
  155. package/src/concepts/BindAttribute__.ts +5 -6
  156. package/src/concepts/BindDirective__.ts +3 -4
  157. package/src/concepts/BusinessComponent__.ts +54 -1
  158. package/src/concepts/BusinessLogic__.ts +10 -1
  159. package/src/concepts/CallEvent__.ts +66 -0
  160. package/src/concepts/CallInterface__.ts +21 -9
  161. package/src/concepts/CallLogic__.ts +60 -4
  162. package/src/concepts/Entity__.ts +7 -1
  163. package/src/concepts/Event__.ts +32 -0
  164. package/src/concepts/FrontendType__.ts +34 -1
  165. package/src/concepts/Frontend__.ts +51 -0
  166. package/src/concepts/IfStatement__.ts +6 -6
  167. package/src/concepts/InterfaceParam__.ts +23 -4
  168. package/src/concepts/Interface__.ts +29 -5
  169. package/src/concepts/JSBlock__.ts +5 -0
  170. package/src/concepts/LogicDeclaration__.ts +65 -7
  171. package/src/concepts/Logic__.ts +45 -27
  172. package/src/concepts/MatchCase__.ts +1 -2
  173. package/src/concepts/Match__.ts +3 -21
  174. package/src/concepts/Module__.ts +75 -0
  175. package/src/concepts/NewComposite__.ts +3 -3
  176. package/src/concepts/NullLiteral__.ts +7 -0
  177. package/src/concepts/Paginate__.ts +14 -7
  178. package/src/concepts/QueryFromExpression__.ts +2 -2
  179. package/src/concepts/StringLiteral__.ts +3 -4
  180. package/src/concepts/TypeAnnotation__.ts +1 -0
  181. package/src/concepts/ViewElement__.ts +11 -7
  182. package/src/concepts/View__.ts +56 -1
  183. package/src/generator/genBundleFiles.ts +67 -54
  184. package/src/generator/genHash.ts +32 -6
  185. package/src/generator/permission.ts +333 -23
  186. package/src/generator/release-body/body.ts +31 -12
  187. package/src/generator/release-body/data.ts +7 -2
  188. package/src/generator/release-body/index.ts +1 -0
  189. package/src/generator/release-body/utils.ts +3 -3
  190. package/src/generator/release-body/validation.ts +1 -1
  191. package/src/index.ts +13 -1
  192. package/src/natural/genNaturalTS.ts +5 -2
  193. package/src/natural/getContext/index.ts +17 -11
  194. package/src/server/entity2LogicNamespace.ts +13 -1
  195. package/src/server/extendBaseNode.ts +32 -22
  196. package/src/server/naslServer.ts +45 -28
  197. package/src/server/translator.ts +15 -0
  198. package/src/service/storage/init.ts +26 -0
  199. package/src/templator/genCreateBlock.ts +4 -4
  200. package/src/templator/genCurdEditMultipleKeyBlock.ts +2 -2
  201. package/src/templator/genCurdMultipleKeyBlock.ts +7 -7
  202. package/src/templator/genEditTableBlock.ts +4 -4
  203. package/src/templator/genGetBlock.ts +1 -1
  204. package/src/templator/genGridViewBlock.ts +2 -2
  205. package/src/templator/genSelectBlock.ts +3 -3
  206. package/src/templator/genTableBlock.ts +2 -2
  207. package/src/templator/genUpdateBlock.ts +6 -6
  208. package/src/templator/utils.ts +1 -1
  209. package/test/concepts/call-logic/__snapshots__/getQuickInfoOffset.spec.ts.snap +1 -1
  210. package/test/concepts/call-logic/__snapshots__/toEmbeddedTS.spec.ts.snap +1 -1
  211. package/test/concepts/string-literal/__snapshots__/toVue.spec.ts.snap +1 -1
  212. package/test/concepts/view-element/__snapshots__/toEmbeddedTS.spec.ts.snap +75 -75
@@ -6,11 +6,11 @@ import {
6
6
  import { genFrontendBundleFiles } from '../genBundleFiles';
7
7
  import { InternalReleaseData } from './internal';
8
8
  import { replaceAssetUrl, getAuthReport, getFrontendByTypes, findAllReportIdList, getProcessFormDefinitions } from './utils';
9
- import { genPermissionData, genLogicAuthFlag } from '../permission';
9
+ import { genPermissionDataOld, genPermissionData, genLogicAuthFlag, testWithOldPermissionResult } from '../permission';
10
10
  import { getCallLogicData } from './validation';
11
11
 
12
12
  import * as utils from '../../utils';
13
- import { config as globalConfig } from '../../config'
13
+ import { config as globalConfig } from '../../config';
14
14
  import type { Asset } from '../release-body/internal';
15
15
 
16
16
  /**
@@ -44,6 +44,7 @@ export function replaceFrontendTypesAssets(frontendTypes: FrontendType[], fn: Fu
44
44
  });
45
45
  });
46
46
  }
47
+
47
48
  export function replaceFrontendAssets(frontendTypes: FrontendType[], fn: Function) {
48
49
  frontendTypes.forEach((frontendType: FrontendType) => {
49
50
  frontendType?.frontends?.forEach((frontend: Frontend) => {
@@ -74,15 +75,12 @@ export function replaceFrontendAssets(frontendTypes: FrontendType[], fn: Functio
74
75
  });
75
76
  }
76
77
 
77
-
78
-
79
- async function getNaslAnnotatedJSON(app: App, opt: InternalReleaseData) {
80
- await utils.delay(500);
81
-
78
+ export async function getNaslAnnotatedJSON(app: App, opt: InternalReleaseData) {
82
79
  let NaslAnnotatedJSON: any;
80
+
83
81
  try {
84
82
  NaslAnnotatedJSON = await app.naslServer.getNaslAnnotatedJSON(app, true);
85
- await opt.logPublishFunc?.('语言', '获取类型标注成功');
83
+ await opt.logPublishFunc?.('语言', '获取全量类型标注成功');
86
84
 
87
85
  // // 打印传给服务端的 nasl,为了服务端排查问题方便
88
86
  // if (globalThis.window) {
@@ -92,6 +90,7 @@ async function getNaslAnnotatedJSON(app: App, opt: InternalReleaseData) {
92
90
  console.error(err);
93
91
  throw new Error('代码标注失败,请稍后重试!或刷新后重试!');
94
92
  }
93
+
95
94
  // 如果是发布,就排除 views,导出源码就不排除
96
95
  if (opt.realRelease) {
97
96
  NaslAnnotatedJSON.frontendTypes.forEach((frontendType: FrontendType) => {
@@ -102,7 +101,8 @@ async function getNaslAnnotatedJSON(app: App, opt: InternalReleaseData) {
102
101
  }
103
102
 
104
103
  const assets = opt.assets;
105
- app.curDeployEnv = opt.env
104
+ app.curDeployEnv = opt.env;
105
+
106
106
  // 导出前端源码+后端源码
107
107
  if (opt.isExport && opt.ignoreFiles && Array.isArray(assets) && assets.length) {
108
108
  const assetsMap = opt.assetsMap;
@@ -165,6 +165,8 @@ async function getNaslAnnotatedJSON(app: App, opt: InternalReleaseData) {
165
165
  }
166
166
  });
167
167
 
168
+ await opt.logPublishFunc?.('资源', '前端静态资源替换完成');
169
+
168
170
  return {
169
171
  name: 'nasl-annotated.json',
170
172
  content: JSON.stringify(NaslAnnotatedJSON),
@@ -203,12 +205,16 @@ async function getFrontendBundleFiles(app: App, opt: InternalReleaseData) {
203
205
  return files;
204
206
  }
205
207
 
208
+
206
209
  async function mergeBodyData(app: App, opt: InternalReleaseData) {
207
210
  await utils.delay(500);
208
211
 
209
212
  const authReport: ReturnType<typeof getAuthReport> = getAuthReport(app, opt.frontends);
210
213
  await opt.logPublishFunc?.('权限', '分析权限数据成功!');
211
- const logicPageResourceDtoList = await genPermissionData(app);
214
+ const logicPageResourceDtoList = genPermissionData(app);
215
+
216
+ // 与老板逻辑权限数据对比
217
+ // await testWithOldPermissionResult(app, logicPageResourceDtoList);
212
218
  const allFrontends = getFrontendByTypes(app?.frontendTypes);
213
219
  const releaseFrontends = allFrontends.map((frontend: Frontend) => ({
214
220
  name: frontend.name,
@@ -217,6 +223,8 @@ async function mergeBodyData(app: App, opt: InternalReleaseData) {
217
223
  selected: opt.frontends.includes(frontend),
218
224
  title: frontend.title,
219
225
  }));
226
+ const callbackLogicsName = app.getExtensionsCallbackLogics()
227
+
220
228
  const body = {
221
229
  ...authReport, // 如果发布需要上报权限,导出源码不需要
222
230
  logicPageResourceDtoList,
@@ -228,7 +236,7 @@ async function mergeBodyData(app: App, opt: InternalReleaseData) {
228
236
  branchId: opt.branchId,
229
237
  replicas: opt.replicas,
230
238
  appSpecification: opt.appSpecification,
231
- callbackLogicsName: app.getExtensionsCallbackLogics(),
239
+ callbackLogicsName,
232
240
  frontends: releaseFrontends,
233
241
  callLogicValidations: {},
234
242
  files: [] as Array<{ name: string; content: string }>,
@@ -242,14 +250,25 @@ async function mergeBodyData(app: App, opt: InternalReleaseData) {
242
250
  }
243
251
 
244
252
  export async function genReleaseBody(app: App, opt: InternalReleaseData) {
253
+ console.time('--backend--');
254
+ console.time('mergeBodyData');
245
255
  const body = await mergeBodyData(app, opt);
256
+ console.timeEnd('mergeBodyData');
246
257
  const callLogicValidations = await getCallLogicData(app, opt.validations);
258
+ console.timeEnd('--backend--');
259
+
260
+ console.time('--frontend--');
261
+ console.time('getNaslAnnotatedJSON');
247
262
  const annotationFile = await getNaslAnnotatedJSON(app, opt);
263
+ console.timeEnd('getNaslAnnotatedJSON');
264
+ console.time('getFrontendBundleFiles');
248
265
  const files = opt.ignoreFiles ? [] : await getFrontendBundleFiles(app, opt);
266
+ console.timeEnd('getFrontendBundleFiles');
267
+ console.timeEnd('--frontend--');
249
268
 
250
269
  files.push(annotationFile);
251
270
 
252
- // nodejs 环境下某些情况下字符会发生错误,需要转译
271
+ // nodejs 环境下的极速开发模式,在某些情况下字符会发生错误,需要转译
253
272
  if (utils.isNode) {
254
273
  files.forEach((file) => {
255
274
  file.name = encodeURIComponent(file.name);
@@ -18,7 +18,8 @@ import { Logger, File } from '../../utils';
18
18
  export async function getReleaseData(app: App, data: ReleaseData, naslServer: NaslServer, inputLogger?: Logger) {
19
19
  const { http, logger: defaultLogger } = naslServer;
20
20
  const logger = inputLogger ?? defaultLogger;
21
- defaultLogger.time('前端构建');
21
+ console.time('all');
22
+ console.time('request');
22
23
  const appInfo = await getAppInfo(http, data);
23
24
  await logger.info('构建环境', '获取环境信息成功');
24
25
  const { version, fullVersion, dependencies } = await getVersionDetail(http, app);
@@ -77,7 +78,9 @@ export async function getReleaseData(app: App, data: ReleaseData, naslServer: Na
77
78
  await logger.info('生成器', '服务端验证数据获取成功');
78
79
  }
79
80
  }
81
+ console.timeEnd('request');
80
82
 
83
+ console.time('前端构建');
81
84
  await logger.info('构建环境', '构建环境完成,开始拼装发布数据');
82
85
 
83
86
  const releaseBody = await genReleaseBody(app, {
@@ -86,7 +89,9 @@ export async function getReleaseData(app: App, data: ReleaseData, naslServer: Na
86
89
  });
87
90
 
88
91
  await logger.info('前端生成器', '应用发布数据准备完成');
89
- defaultLogger.timeEnd('前端构建');
92
+ console.timeEnd('前端构建');
93
+
94
+ console.timeEnd('all');
90
95
 
91
96
  return releaseBody;
92
97
  }
@@ -1,3 +1,4 @@
1
1
  export * from './types';
2
2
  export * from './data';
3
3
  export * from './utils';
4
+ export * from './body';
@@ -80,7 +80,7 @@ export function getAuthReport(app: App, frontends: Array<Frontend>) {
80
80
  * 获取页面中所有 分析报告组件 的reportId
81
81
  */
82
82
  export function findAllReportIdList(app: App, frontends: Array<Frontend>) {
83
- const reportIds: string[] = [];
83
+ const reportIds: Set<string> = new Set();
84
84
 
85
85
  frontends.forEach((frontend) => {
86
86
  frontend.views.forEach((view) => loop(view));
@@ -90,7 +90,7 @@ export function findAllReportIdList(app: App, frontends: Array<Frontend>) {
90
90
  if (root.concept === 'ViewElement') {
91
91
  root.bindAttrs.forEach((attr) => {
92
92
  if (attr.name === 'reportId') {
93
- reportIds.push(JSON.parse(attr.value || '{}').id);
93
+ reportIds.add(JSON.parse(attr.value || '{}').id);
94
94
  }
95
95
  });
96
96
  }
@@ -101,7 +101,7 @@ export function findAllReportIdList(app: App, frontends: Array<Frontend>) {
101
101
  root.elements.forEach((item) => loop(item));
102
102
  }
103
103
  }
104
- return [...new Set(reportIds)].filter(Boolean);
104
+ return Array.from(reportIds).filter(Boolean);
105
105
  }
106
106
 
107
107
  export function replaceAssetUrl(
@@ -31,9 +31,9 @@ export async function getCallLogicData(app: App, validations: InputServerValidat
31
31
 
32
32
  nasl.traverseStrictChildren((node) => {
33
33
  if (
34
- 'uuid' in node &&
35
34
  node.concept === 'CallLogic' &&
36
35
  node.validation &&
36
+ 'uuid' in node &&
37
37
  map.has(node.uuid)
38
38
  ) {
39
39
  const data = map.get(node.uuid)!;
package/src/index.ts CHANGED
@@ -8,7 +8,19 @@ export * as utils from './utils';
8
8
  export * from './config';
9
9
  export * from './eventBus';
10
10
  export * as breakpoint from './breakpoint';
11
- export { getOperationRecords, operationRecordInfoMap, doOperationRecord, operationRecordQuery, operationRecordPlayback, loadApp, loadAppSync, handleApp, batchAction, batchQuery, mountDatabaseTypes } from './service/storage/init';
11
+ export {
12
+ getOperationRecords,
13
+ operationRecordInfoMap,
14
+ doOperationRecord,
15
+ operationRecordQuery,
16
+ operationRecordPlayback,
17
+ loadApp,
18
+ loadAppSync,
19
+ handleApp,
20
+ batchAction,
21
+ batchQuery,
22
+ mountDatabaseTypes,
23
+ } from './service/storage/init';
12
24
  export { createService } from './service/creator';
13
25
  export { stepRecorder } from './manager/stepRecorder';
14
26
  export * from './natural';
@@ -52,6 +52,7 @@ export function genNaturalTSContextJSONForLogic(
52
52
  app: App,
53
53
  currentNode?: BaseNode,
54
54
  focusedNodePath?: string,
55
+ experimental?: boolean,
55
56
  material?: {
56
57
  moduleInterfaces: any;
57
58
  connectors: any;
@@ -60,7 +61,7 @@ export function genNaturalTSContextJSONForLogic(
60
61
  ) {
61
62
  const frontend = currentNode?.getAncestor('Frontend') as Frontend;
62
63
  const logicType = currentNode?.parentNode?.concept === 'App' ? 'global_logic' : 'view_logic';
63
- const state = createCompilerState();
64
+ const state = createCompilerState('', { descriptionComment: true });
64
65
 
65
66
  const { naslCore } = getNaslCore(logicType);
66
67
  const { naslUtil } = getNaslUtil();
@@ -93,7 +94,7 @@ export function genNaturalTSContextJSONForLogic(
93
94
  state
94
95
  );
95
96
  const { views } = getFrontendViews(frontend, state, currentNode, false);
96
- const { currentLogic } = getCurrentNodeContext(currentNode, focusedNodePath);
97
+ const { currentLogic } = getCurrentNodeContext(currentNode, focusedNodePath, experimental);
97
98
 
98
99
  return {
99
100
  naslCore,
@@ -226,6 +227,7 @@ export function genNaturalTSContextForLogic(
226
227
  currentNode?: BaseNode,
227
228
  focusedNodePath?: string,
228
229
  requiredIndexes?: string[],
230
+ experimental?: boolean,
229
231
  material?: {
230
232
  moduleInterfaces: any;
231
233
  connectors: any;
@@ -239,6 +241,7 @@ export function genNaturalTSContextForLogic(
239
241
  app,
240
242
  currentNode,
241
243
  focusedNodePath,
244
+ experimental,
242
245
  material
243
246
  );
244
247
  const code = genNaturalTSContextFromJSONForLogic(
@@ -603,7 +603,7 @@ export const getFrontendViewsCode = (views: any) => {
603
603
  return wrapTSBlock(code);
604
604
  };
605
605
 
606
- export function getCurrentNodeContext(currentNode: BaseNode, focusedNodePath?: string) {
606
+ export function getCurrentNodeContext(currentNode: BaseNode, focusedNodePath?: string, experimental?: boolean) {
607
607
  let code = '';
608
608
  let view: View;
609
609
  if (currentNode?.concept === 'View') {
@@ -631,16 +631,22 @@ export function getCurrentNodeContext(currentNode: BaseNode, focusedNodePath?: s
631
631
  }),
632
632
  function (state) {
633
633
  let code = '';
634
- code += `\n${indent(state.tabSize + 1)}const $refs = {\n`;
635
- // 生成所有的name和类型定义
636
- this.elements.forEach((element) => {
637
- code += element.toNaturalTSDefinition(
638
- shiftState(state, code, {
639
- tabSize: state.tabSize + 1,
640
- })
641
- );
642
- });
643
- code += `${indent(state.tabSize + 1)}}\n`;
634
+ code += `\n${indent(state.tabSize)}`;
635
+
636
+ if (experimental) {
637
+ code += this.elements[0].toNaturalTS(shiftState(state, code, { tabSize: state.tabSize + 1 }));
638
+ } else {
639
+ code += `const $refs = {\n`;
640
+ // 生成所有的name和类型定义
641
+ this.elements.forEach((element) => {
642
+ code += element.toNaturalTSDefinition(
643
+ shiftState(state, code, {
644
+ tabSize: state.tabSize + 1,
645
+ })
646
+ );
647
+ });
648
+ code += `${indent(state.tabSize + 1)}}\n`;
649
+ }
644
650
  // 逻辑
645
651
  if (currentNode?.concept === 'Logic') {
646
652
  code += '\n';
@@ -15,7 +15,17 @@ import {
15
15
  NewList,
16
16
  } from '..';
17
17
 
18
+ const entityNsMap = new Map();
19
+
18
20
  export function entity2LogicNamespace(entity: Entity) {
21
+ let nsInfo = entityNsMap.get(entity);
22
+ if (!nsInfo) {
23
+ nsInfo = {
24
+ contentUniqueKey: entity.contentUniqueKey
25
+ };
26
+ entityNsMap.set(entity, nsInfo);
27
+ }
28
+ if (!nsInfo.ns || nsInfo.contentUniqueKey !== entity.contentUniqueKey) {
19
29
  const { properties } = entity;
20
30
  const keys = properties.filter((item) => item.primaryKey);
21
31
  const params = keys.map(
@@ -368,7 +378,9 @@ export function entity2LogicNamespace(entity: Entity) {
368
378
  ],
369
379
  });
370
380
  ns.parentNode = entity;
371
- return ns;
381
+ nsInfo.ns = ns;
382
+ }
383
+ return nsInfo.ns;
372
384
  }
373
385
 
374
386
  interface entityTreeFragment {
@@ -538,6 +538,30 @@ BaseNode.prototype.prepareDelete = async function prepareDelete(cb?: Function) {
538
538
  const naslServer = (app as any).naslServer as NaslServer;
539
539
  const node = this;
540
540
  let refsList = await naslServer._isHaveRef(node);
541
+ const handleComposeDel = () => {
542
+ // // 删除页面或端的时候,如果存在组合节点,需要同步删除封装态分组内容
543
+ const excludedKeySet = new Set([
544
+ 'parentNode',
545
+ 'sourceMap',
546
+ 'storageJSON',
547
+ 'tsErrorDetail',
548
+ 'NaslAnnotatedJSON',
549
+ 'calledFrom',
550
+ '_events',
551
+ '_collectingList',
552
+ '_historyList',
553
+ ]);
554
+ traverse(
555
+ (current) => {
556
+ const currentNode: any = current.node;
557
+ if (currentNode && currentNode?.concept === 'ViewElement' && currentNode?.name === currentNode?.composedBy?.[0]) {
558
+ currentNode.app.deleteCompose(currentNode.composedBy);
559
+ }
560
+ },
561
+ { node: this },
562
+ { mode: 'anyObject', excludedKeySet }
563
+ );
564
+ }
541
565
  if (this.concept === 'ViewElement') {
542
566
  // 删除的时候过滤一把组件删除提示
543
567
  refsList = refsList.filter(
@@ -590,28 +614,7 @@ BaseNode.prototype.prepareDelete = async function prepareDelete(cb?: Function) {
590
614
  (this as any).app.emit('collect:start', {
591
615
  actionMsg: `删除节点`,
592
616
  });
593
- // 删除页面或端的时候,如果存在表单设计器,需要同步删除分组内容
594
- const excludedKeySet = new Set([
595
- 'parentNode',
596
- 'sourceMap',
597
- 'storageJSON',
598
- 'tsErrorDetail',
599
- 'NaslAnnotatedJSON',
600
- 'calledFrom',
601
- '_events',
602
- '_collectingList',
603
- '_historyList',
604
- ]);
605
- traverse(
606
- (current) => {
607
- const currentNode: any = current.node;
608
- if (currentNode && currentNode?.concept === 'ViewElement' && currentNode?.name === currentNode?.composedBy?.[0]) {
609
- currentNode.app.deleteCompose(currentNode.composedBy);
610
- }
611
- },
612
- { node: this },
613
- { mode: 'anyObject', excludedKeySet }
614
- );
617
+ handleComposeDel();
615
618
  this.delete();
616
619
  (this as any).app.emit('collect:end');
617
620
  } else if (isSubLogic(node)) {
@@ -660,6 +663,7 @@ BaseNode.prototype.prepareDelete = async function prepareDelete(cb?: Function) {
660
663
  this.delete();
661
664
  App.emit('collect:end');
662
665
  } else {
666
+ if (node instanceof View || node instanceof Frontend) handleComposeDel();
663
667
  this.delete();
664
668
  if (node instanceof Frontend) {
665
669
  return;
@@ -689,6 +693,7 @@ BaseNode.prototype.prepareDelete = async function prepareDelete(cb?: Function) {
689
693
  actionMsg: `删除端${node.name}`,
690
694
  });
691
695
  await Promise.all(result.map((ele) => ele.delete()));
696
+ handleComposeDel();
692
697
  this.delete();
693
698
  App.emit('collect:end');
694
699
  return;
@@ -832,7 +837,12 @@ BaseNode.prototype.prepareDelete = async function prepareDelete(cb?: Function) {
832
837
 
833
838
  // 删除页面或者流程,如果上一步没有return 就说明他是有别的引用的,会有引用弹框
834
839
  if (node instanceof View) {
840
+ (this as any).app.emit('collect:start', {
841
+ actionMsg: `删除节点`,
842
+ });
843
+ handleComposeDel();
835
844
  this.delete();
845
+ (this as any).app.emit('collect:end');
836
846
  }
837
847
  if (node instanceof Process) {
838
848
  const App = this.rootNode;
@@ -2245,8 +2245,8 @@ class NaslServer {
2245
2245
  if(decimalPlaces > +scale) {
2246
2246
  const diag: any = {
2247
2247
  node: property,
2248
- severity: 'error',
2249
- message: `实体字段${property.name}默认值的小数位数不能大于设置的小数位数${scale}`,
2248
+ severity: 'warning',
2249
+ message: `实体字段${property.name}默认值的小数位数不能大于设置的小数位数${scale},否则将会按照小数位数自动截断`,
2250
2250
  };
2251
2251
  diagnostics.push(diag);
2252
2252
  }
@@ -2986,7 +2986,7 @@ class NaslServer {
2986
2986
  const typesArg = node.arguments?.find((arg) => {
2987
2987
  return arg?.keyword === 'types';
2988
2988
  });
2989
- if (typesArg?.expression?.concept !== 'NewList' || !((typesArg?.expression as NewList)?.items?.length)) {
2989
+ if (typesArg?.expression && (typesArg?.expression?.concept !== 'NewList' || !((typesArg?.expression as NewList)?.items?.length))) {
2990
2990
  const diagnostic = {
2991
2991
  node: typesArg?.expression,
2992
2992
  severity: 'error',
@@ -4736,7 +4736,7 @@ class NaslServer {
4736
4736
  const item = (resultMap as any)?.[file]?.[line]?.[offset];
4737
4737
  const itemType = item?.[0]?.nodeType;
4738
4738
  const nodeTypeAnnotation = yield* type2TypeAnnotation(itemType);
4739
- const {node} = newQuickInfoNodes[index];
4739
+ const { node } = newQuickInfoNodes[index];
4740
4740
 
4741
4741
  types.set(node, Object.freeze(nodeTypeAnnotation) as TypeAnnotation);
4742
4742
 
@@ -4919,7 +4919,13 @@ class NaslServer {
4919
4919
  });
4920
4920
  const typesMap = await this.getQuickInfoNodesTypeMap(nodes, true);
4921
4921
 
4922
- const json = app.toJSON();
4922
+ console.time('app toJSON');
4923
+ const jsonMap = new Map();
4924
+ const json = app._toJSON((source, instance) => {
4925
+ jsonMap.set(instance, source);
4926
+ return source;
4927
+ });
4928
+ console.timeEnd('app toJSON');
4923
4929
 
4924
4930
  this.logger.timeEnd('全量标注');
4925
4931
 
@@ -4929,8 +4935,10 @@ class NaslServer {
4929
4935
  }
4930
4936
 
4931
4937
  if (releaseFlag) {
4938
+ console.time('annotationToJson');
4932
4939
  // 全量标注后对json进行一些修改,为了服务端翻译处理
4933
- this.annotationToJson(typesMap, json);
4940
+ this.annotationToJson(typesMap, json, jsonMap);
4941
+ console.timeEnd('annotationToJson');
4934
4942
  }
4935
4943
 
4936
4944
  return json;
@@ -4974,31 +4982,32 @@ class NaslServer {
4974
4982
  BaseNode,
4975
4983
  | TypeAnnotation
4976
4984
  | {
4977
- typeAnnotation: TypeAnnotation;
4978
- option: any;
4979
- }
4985
+ typeAnnotation: TypeAnnotation;
4986
+ option: any;
4987
+ }
4980
4988
  >,
4981
- json: {}
4989
+ json: {},
4990
+ jsonMap: Map<BaseNode, any>,
4982
4991
  ) {
4983
4992
  typesMap.forEach((value, node) => {
4984
4993
  // 如果节点本身有类型就不去在塞一遍了
4985
4994
  // 有值而且没有类型再去设置
4986
4995
  // 但是Identifier 和 MemberExpression 都用标注出来的因为本身是变量,有类型也需要覆盖一下
4987
- if (value && (node instanceof Argument ) && node.getAncestor('Connector')?.concept === 'Connector') {
4988
- const jsonNode = jsoner.queryNodeByPath(json, node.getNodePath(false));
4996
+ if (value && (node instanceof Argument) && node.getAncestor('Connector')?.concept === 'Connector') {
4997
+ const jsonNode = jsonMap.get(node);
4989
4998
  if (jsonNode) {
4990
- jsonNode.typeAnnotation = (value as TypeAnnotation)?.toJSON();
4999
+ jsonNode.typeAnnotation = (value as TypeAnnotation)?.toJSON();
4991
5000
  }
4992
5001
  }
4993
5002
  if (value && (!(node as any).typeAnnotation || node instanceof Identifier || node instanceof MemberExpression)) {
4994
- const jsonNode = jsoner.queryNodeByPath(json, node.getNodePath(false));
5003
+ const jsonNode = jsonMap.get(node);
4995
5004
  if (jsonNode) {
4996
- jsonNode.typeAnnotation = (value as TypeAnnotation)?.toJSON();
5005
+ jsonNode.typeAnnotation = (value as TypeAnnotation)?.toJSON();
4997
5006
  }
4998
5007
  }
4999
5008
  // 旧版本数据查询需要确认是匿名数据结构的 ListTotal 类型
5000
5009
  if (node instanceof CallQueryComponent && !node.isAutoInfer()) {
5001
- const jsonNode = jsoner.queryNodeByPath(json, node.getNodePath(false));
5010
+ const jsonNode = jsonMap.get(node);
5002
5011
  jsonNode.typeAnnotation = {
5003
5012
  concept: 'TypeAnnotation',
5004
5013
  typeKind: 'anonymousStructure',
@@ -5047,7 +5056,7 @@ class NaslServer {
5047
5056
  if (node instanceof Param) {
5048
5057
  // index在nasl foreach上有脏数据
5049
5058
  if (node.parentKey === 'index' && node.parentNode instanceof ForEachStatement) {
5050
- const jsonNode = jsoner.queryNodeByPath(json, node.getNodePath(false));
5059
+ const jsonNode = jsonMap.get(node);
5051
5060
  jsonNode.typeAnnotation = TypeAnnotation.createPrimitive('Long').toJSON();
5052
5061
  }
5053
5062
  }
@@ -5064,7 +5073,7 @@ class NaslServer {
5064
5073
  const itemCode = this.getNodeCode(fileNode, item);
5065
5074
 
5066
5075
  if (itemNode.concept === matchExpression.concept && itemCode === currentCode) {
5067
- const jsonNode = jsoner.queryNodeByPath(json, itemNode.getNodePath(false));
5076
+ const jsonNode = jsonMap.get(itemNode);
5068
5077
  jsonNode.typeAnnotation = matchExpression.__TypeAnnotation;
5069
5078
  }
5070
5079
  });
@@ -5074,12 +5083,12 @@ class NaslServer {
5074
5083
  if (value && (node instanceof Param)) {
5075
5084
  // index在nasl foreach上有脏数据
5076
5085
  if (node.parentKey === 'index' && node.parentNode instanceof ForEachStatement) {
5077
- const jsonNode = jsoner.queryNodeByPath(json, node.getNodePath(false));
5086
+ const jsonNode = jsonMap.get(node);
5078
5087
  jsonNode.typeAnnotation = (value as TypeAnnotation).toJSON();
5079
5088
  }
5080
5089
  }
5081
5090
  if (value && (node instanceof NewComposite) && (node.typeAnnotation?.typeKind === 'anonymousStructure' || node.typeAnnotation?.typeKind === 'generic')) {
5082
- const jsonNode = jsoner.queryNodeByPath(json, node.getNodePath(false));
5091
+ const jsonNode = jsonMap.get(node);
5083
5092
  jsonNode.typeAnnotation = (value as TypeAnnotation).toJSON();
5084
5093
  }
5085
5094
 
@@ -5099,7 +5108,7 @@ class NaslServer {
5099
5108
  * 特殊处理,不想去查两次类型, 因为是从函数签名上拿类型,所以直接合并在一起,先这样
5100
5109
  */
5101
5110
  if (node instanceof CallLogic && node.__TypeArguments?.length) {
5102
- const jsonNode = jsoner.queryNodeByPath(json, node.getNodePath(false));
5111
+ const jsonNode = jsonMap.get(node);
5103
5112
  jsonNode.typeArguments = node.__TypeArguments.map((type) => type?.toJSON());
5104
5113
  jsonNode.typeAnnotation = node.__TypeAnnotation?.toJSON();
5105
5114
  }
@@ -5135,13 +5144,13 @@ class NaslServer {
5135
5144
  if (itemExpression) {
5136
5145
  const listTypeArgument = list.__TypeAnnotation?.typeArguments?.[0]?.toJSON();
5137
5146
  if (listTypeArgument) {
5138
- const jsonNode = jsoner.queryNodeByPath(json, item.getNodePath(false));
5147
+ const jsonNode = jsonMap.get(item);
5139
5148
  jsonNode.typeAnnotation = listTypeArgument;
5140
5149
  }
5141
5150
  }
5142
5151
  } else {
5143
5152
  const mapParamIndex = mapFunctionParamIndexMaps.get(calleeName);
5144
- if(mapParamIndex){
5153
+ if (mapParamIndex) {
5145
5154
  const map = node.arguments[mapParamIndex.collection];
5146
5155
  const key = node.arguments[mapParamIndex.key];
5147
5156
  const value = node.arguments[mapParamIndex.value];
@@ -5150,14 +5159,14 @@ class NaslServer {
5150
5159
  if (keyExpression) {
5151
5160
  const mapKeyTypeArgument = map.__TypeAnnotation?.typeArguments?.[0]?.toJSON();
5152
5161
  if (mapKeyTypeArgument) {
5153
- const jsonNode = jsoner.queryNodeByPath(json, key.getNodePath(false));
5162
+ const jsonNode = jsonMap.get(key);
5154
5163
  jsonNode.typeAnnotation = mapKeyTypeArgument;
5155
5164
  }
5156
5165
  }
5157
5166
  if (valueExpression) {
5158
5167
  const mapValueTypeArgument = map.__TypeAnnotation?.typeArguments?.[1]?.toJSON();
5159
5168
  if (mapValueTypeArgument) {
5160
- const jsonNode = jsoner.queryNodeByPath(json, value.getNodePath(false));
5169
+ const jsonNode = jsonMap.get(value);
5161
5170
  jsonNode.typeAnnotation = mapValueTypeArgument;
5162
5171
  }
5163
5172
  }
@@ -5169,7 +5178,7 @@ class NaslServer {
5169
5178
 
5170
5179
  // 服务端需要默认值节点有类型来判断父节点是否是日期类型
5171
5180
  if (node instanceof DefaultValue && !value) {
5172
- const jsonNode = jsoner.queryNodeByPath(json, node.getNodePath(false));
5181
+ const jsonNode = jsonMap.get(node);
5173
5182
  const parentNodeType = (node.parentNode as any)?.typeAnnotation || (node.parentNode as any)?.__TypeAnnotation;
5174
5183
  if (parentNodeType && jsonNode) {
5175
5184
  jsonNode.typeAnnotation = (parentNodeType as TypeAnnotation)?.toJSON();
@@ -5295,11 +5304,19 @@ class NaslServer {
5295
5304
  async getBindAttributeType(node: BindAttribute) {
5296
5305
  // 过滤掉一些不需要查找的属性
5297
5306
  const excludes = ['dataSource']
5298
- const excludeReg = /.*(f|F)ield/
5299
- if (excludes.includes(node.name) || excludeReg.test(node.name)) {
5307
+ if (excludes.includes(node.name)) {
5300
5308
  return null;
5301
5309
  }
5302
5310
 
5311
+ const element: any = node.getAncestor('ViewElement');
5312
+ const api = config.allNodesAPI[element?.tag];
5313
+ const prop = api?.props?.find?.((prop) => {
5314
+ return prop.name === node.name;
5315
+ });
5316
+ if (/\(\s*item\s*:\s*T\s*\)\s*=>\s*.+/.test(prop?.tsType)) {
5317
+ return TypeAnnotation.createPrimitive('String');
5318
+ }
5319
+
5303
5320
  const { currentSource, fileNode } = node?.getCurrentSource() || {};
5304
5321
 
5305
5322
  if (!currentSource && !fileNode) {
@@ -328,6 +328,10 @@ const TS_RULES: Array<{
328
328
  re: /Cannot find name '__UNCERTAIN__INTERMEDIATE__FIELDS__'./,
329
329
  result: '来自不确定结构或实体的字段',
330
330
  },
331
+ {
332
+ re: /Cannot find name '__UNSUPPORTED__ENTITY__FIELDS__'./,
333
+ result: '可能为实体属性别名,动态条件中仅支持使用变量',
334
+ },
331
335
  {
332
336
  re: /No value exists in scope for the shorthand property '__(?:IDENTIFIER|LEFT|RIGHT)__'. Either declare one or provide an initializer./,
333
337
  result: '用户任务未关联页面',
@@ -900,6 +904,17 @@ export function naslNodeTranslateMessage(minRange: MinRange, tsErrorDetail: Diag
900
904
  });
901
905
  }
902
906
  }
907
+
908
+ if (node instanceof BindAttribute && node.parentNode instanceof ViewElement) {
909
+ const reg = /左边类型:\s*(.*)[,,]\s*右边类型:\s*(.*)[.。]/
910
+ const left = reg.exec(tsErrorDetail.message)?.[1];
911
+ const right = reg.exec(tsErrorDetail.message)?.[2];
912
+
913
+ if (left && right) {
914
+ tsErrorDetail.message = `页面组件:属性类型不一致!接收类型:${left},传入类型:${right}。`;
915
+ }
916
+ }
917
+
903
918
  if (node && tsErrorDetail) {
904
919
  node.tsErrorDetail = tsErrorDetail;
905
920
  }