@lcap/nasl 2.20.0-beta.3 → 2.20.0-beta.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.
- package/out/automate/engine/index.d.ts +1 -1
- package/out/automate/engine/index.js +2 -3
- package/out/automate/engine/index.js.map +1 -1
- package/out/automate/engine/uniqueName.d.ts +1 -1
- package/out/automate/engine/uniqueName.js +2 -2
- package/out/automate/engine/uniqueName.js.map +1 -1
- package/out/automate/engine/utils.js +4 -1
- package/out/automate/engine/utils.js.map +1 -1
- package/out/automate/template/myProcess.d.ts +1 -1
- package/out/automate/template/myProcess.js +2 -2
- package/out/automate/template/myProcess.js.map +1 -1
- package/out/bak/translator.js +14 -22
- package/out/bak/translator.js.map +1 -1
- package/out/common/BaseNode.js +4 -1
- package/out/common/BaseNode.js.map +1 -1
- package/out/common/Command.d.ts +1 -0
- package/out/common/Command.js +5 -1
- package/out/common/Command.js.map +1 -1
- package/out/concepts/App__.d.ts +4 -0
- package/out/concepts/App__.js +30 -6
- package/out/concepts/App__.js.map +1 -1
- package/out/concepts/Assignee__.js +4 -3
- package/out/concepts/Assignee__.js.map +1 -1
- package/out/concepts/BatchAssignment__.js +3 -3
- package/out/concepts/BatchAssignment__.js.map +1 -1
- package/out/concepts/BindAttribute__.d.ts +7 -0
- package/out/concepts/BindAttribute__.js +271 -39
- package/out/concepts/BindAttribute__.js.map +1 -1
- package/out/concepts/BindDirective__.d.ts +7 -0
- package/out/concepts/BindDirective__.js +215 -16
- package/out/concepts/BindDirective__.js.map +1 -1
- package/out/concepts/BindStyle__.d.ts +7 -0
- package/out/concepts/BindStyle__.js +192 -2
- package/out/concepts/BindStyle__.js.map +1 -1
- package/out/concepts/CallFunction__.js +22 -8
- package/out/concepts/CallFunction__.js.map +1 -1
- package/out/concepts/CallInterface__.js +3 -2
- package/out/concepts/CallInterface__.js.map +1 -1
- package/out/concepts/CallLogic__.d.ts +3 -0
- package/out/concepts/CallLogic__.js +78 -89
- package/out/concepts/CallLogic__.js.map +1 -1
- package/out/concepts/CallQueryComponent__.js +20 -3
- package/out/concepts/CallQueryComponent__.js.map +1 -1
- package/out/concepts/ConfigGroup__.d.ts +1 -0
- package/out/concepts/ConfigGroup__.js +13 -0
- package/out/concepts/ConfigGroup__.js.map +1 -1
- package/out/concepts/ConfigProperty__.d.ts +19 -0
- package/out/concepts/ConfigProperty__.js +63 -0
- package/out/concepts/ConfigProperty__.js.map +1 -1
- package/out/concepts/Configuration__.d.ts +1 -0
- package/out/concepts/Configuration__.js +13 -0
- package/out/concepts/Configuration__.js.map +1 -1
- package/out/concepts/DataSource__.js +11 -3
- package/out/concepts/DataSource__.js.map +1 -1
- package/out/concepts/Destination__.d.ts +1 -0
- package/out/concepts/Destination__.js +61 -7
- package/out/concepts/Destination__.js.map +1 -1
- package/out/concepts/EntityProperty__.js +9 -1
- package/out/concepts/EntityProperty__.js.map +1 -1
- package/out/concepts/EnumItem__.d.ts +5 -5
- package/out/concepts/EnumItem__.js +6 -6
- package/out/concepts/Enum__.d.ts +20 -19
- package/out/concepts/Enum__.js +28 -1
- package/out/concepts/Enum__.js.map +1 -1
- package/out/concepts/ExternalDestination__.d.ts +1 -0
- package/out/concepts/ExternalDestination__.js +22 -4
- package/out/concepts/ExternalDestination__.js.map +1 -1
- package/out/concepts/ForEachStatement__.js +2 -0
- package/out/concepts/ForEachStatement__.js.map +1 -1
- package/out/concepts/Frontend__.d.ts +2 -1
- package/out/concepts/Frontend__.js.map +1 -1
- package/out/concepts/Identifier__.js +16 -5
- package/out/concepts/Identifier__.js.map +1 -1
- package/out/concepts/InterfaceParam__.js +9 -1
- package/out/concepts/InterfaceParam__.js.map +1 -1
- package/out/concepts/JSBlock__.js +5 -1
- package/out/concepts/JSBlock__.js.map +1 -1
- package/out/concepts/Logic__.d.ts +79 -79
- package/out/concepts/Logic__.js +30 -8
- package/out/concepts/Logic__.js.map +1 -1
- package/out/concepts/Match__.d.ts +2 -2
- package/out/concepts/Match__.js +29 -13
- package/out/concepts/Match__.js.map +1 -1
- package/out/concepts/MemberExpression__.js +9 -0
- package/out/concepts/MemberExpression__.js.map +1 -1
- package/out/concepts/Module__.d.ts +16 -0
- package/out/concepts/Module__.js +43 -0
- package/out/concepts/Module__.js.map +1 -1
- package/out/concepts/NewComposite__.d.ts +3 -4
- package/out/concepts/NewComposite__.js +99 -116
- package/out/concepts/NewComposite__.js.map +1 -1
- package/out/concepts/NewList__.d.ts +1 -0
- package/out/concepts/NewList__.js +22 -2
- package/out/concepts/NewList__.js.map +1 -1
- package/out/concepts/NewMap__.d.ts +1 -0
- package/out/concepts/NewMap__.js +43 -11
- package/out/concepts/NewMap__.js.map +1 -1
- package/out/concepts/OqlQueryComponent__.js +40 -12
- package/out/concepts/OqlQueryComponent__.js.map +1 -1
- package/out/concepts/Param__.js +10 -2
- package/out/concepts/Param__.js.map +1 -1
- package/out/concepts/ProcessElement__.js +2 -1
- package/out/concepts/ProcessElement__.js.map +1 -1
- package/out/concepts/ProcessOutcome__.js +1 -1
- package/out/concepts/ProcessOutcome__.js.map +1 -1
- package/out/concepts/ProcessOutcomes__.js +1 -1
- package/out/concepts/ProcessOutcomes__.js.map +1 -1
- package/out/concepts/Process__.js +1 -0
- package/out/concepts/Process__.js.map +1 -1
- package/out/concepts/Return__.js +13 -2
- package/out/concepts/Return__.js.map +1 -1
- package/out/concepts/StringInterpolation__.js +14 -2
- package/out/concepts/StringInterpolation__.js.map +1 -1
- package/out/concepts/StringLiteral__.js +6 -6
- package/out/concepts/StringLiteral__.js.map +1 -1
- package/out/concepts/StructureProperty__.js +9 -1
- package/out/concepts/StructureProperty__.js.map +1 -1
- package/out/concepts/TypeAnnotation__.d.ts +6 -3
- package/out/concepts/TypeAnnotation__.js +67 -13
- package/out/concepts/TypeAnnotation__.js.map +1 -1
- package/out/concepts/ValidationRule__.d.ts +1 -0
- package/out/concepts/ValidationRule__.js +53 -0
- package/out/concepts/ValidationRule__.js.map +1 -1
- package/out/concepts/Variable__.js +12 -1
- package/out/concepts/Variable__.js.map +1 -1
- package/out/concepts/ViewElement__.d.ts +1 -0
- package/out/concepts/ViewElement__.js +24 -1
- package/out/concepts/ViewElement__.js.map +1 -1
- package/out/concepts/View__.d.ts +1 -3
- package/out/concepts/View__.js +33 -12
- package/out/concepts/View__.js.map +1 -1
- package/out/concepts/basics/stdlib/nasl.collection.js +6 -1
- package/out/concepts/basics/stdlib/nasl.collection.js.map +1 -1
- package/out/concepts/basics/stdlib/nasl.configuration.js +3 -0
- package/out/concepts/basics/stdlib/nasl.configuration.js.map +1 -1
- package/out/concepts/basics/stdlib/nasl.core.d.ts +2 -0
- package/out/concepts/basics/stdlib/nasl.core.js +34 -0
- package/out/concepts/basics/stdlib/nasl.core.js.map +1 -1
- package/out/concepts/basics/stdlib/nasl.util.js +4 -2
- package/out/concepts/basics/stdlib/nasl.util.js.map +1 -1
- package/out/concepts/basics/types/index.d.ts +1 -0
- package/out/concepts/basics/types/index.js +3 -1
- package/out/concepts/basics/types/index.js.map +1 -1
- package/out/concepts/index__.d.ts +0 -1
- package/out/concepts/index__.js +0 -1
- package/out/concepts/index__.js.map +1 -1
- package/out/enums/KEYWORDS.js +8 -0
- package/out/enums/KEYWORDS.js.map +1 -1
- package/out/generator/genBundleFiles.js +24 -5
- package/out/generator/genBundleFiles.js.map +1 -1
- package/out/generator/genReleaseBody.d.ts +3 -3
- package/out/generator/genReleaseBody.js +98 -23
- package/out/generator/genReleaseBody.js.map +1 -1
- package/out/generator/permission.d.ts +3 -10
- package/out/generator/permission.js +43 -21
- package/out/generator/permission.js.map +1 -1
- package/out/index.d.ts +1 -1
- package/out/index.js +2 -1
- package/out/index.js.map +1 -1
- package/out/server/entity2LogicNamespace.js +2 -20
- package/out/server/entity2LogicNamespace.js.map +1 -1
- package/out/server/extendBaseNode.js +16 -5
- package/out/server/extendBaseNode.js.map +1 -1
- package/out/server/formatTsUtils.d.ts +2 -1
- package/out/server/formatTsUtils.js +40 -10
- package/out/server/formatTsUtils.js.map +1 -1
- package/out/server/getLogics.d.ts +2 -2
- package/out/server/getLogics.js +3 -3
- package/out/server/getLogics.js.map +1 -1
- package/out/server/getMemberIdentifier.d.ts +1 -0
- package/out/server/getMemberIdentifier.js +27 -1
- package/out/server/getMemberIdentifier.js.map +1 -1
- package/out/server/index.js +1 -0
- package/out/server/index.js.map +1 -1
- package/out/server/naslServer.d.ts +7 -1
- package/out/server/naslServer.js +558 -62
- package/out/server/naslServer.js.map +1 -1
- package/out/server/translator.js +109 -33
- package/out/server/translator.js.map +1 -1
- package/out/service/storage/init.js +22 -2
- package/out/service/storage/init.js.map +1 -1
- package/out/templator/genCreateBlock.js +1 -3
- package/out/templator/genCreateBlock.js.map +1 -1
- package/out/templator/genCurdEditMultipleKeyBlock.js +1 -3
- package/out/templator/genCurdEditMultipleKeyBlock.js.map +1 -1
- package/out/templator/genCurdMultipleKeyBlock.js +2 -4
- package/out/templator/genCurdMultipleKeyBlock.js.map +1 -1
- package/out/templator/genGetBlock.js +1 -1
- package/out/templator/genGetBlock.js.map +1 -1
- package/out/templator/genGridViewBlock.js +2 -2
- package/out/templator/genGridViewBlock.js.map +1 -1
- package/out/templator/genListViewBlock.js +7 -1
- package/out/templator/genListViewBlock.js.map +1 -1
- package/out/templator/genSelectBlock.js +1 -1
- package/out/templator/genSelectBlock.js.map +1 -1
- package/out/templator/genTableBlock.js +2 -2
- package/out/templator/genTableBlock.js.map +1 -1
- package/out/templator/genUpdateBlock.js +2 -3
- package/out/templator/genUpdateBlock.js.map +1 -1
- package/out/translator/index.js +4 -1
- package/out/translator/index.js.map +1 -1
- package/out/utils/traverse.js +8 -2
- package/out/utils/traverse.js.map +1 -1
- package/package.json +2 -2
- package/sandbox/stdlib/dist/nasl.logging.js +0 -0
- package/sandbox/stdlib/dist/nasl.util.js +0 -0
- package/sandbox/stdlib/nasl.collection.ts +1 -0
- package/sandbox/stdlib/nasl.core.ts +34 -0
- package/sandbox/stdlib/nasl.oql.ts +71 -15
- package/sandbox/stdlib/nasl.util.ts +9 -3
- package/src/automate/engine/dist/index.dev.js +517 -0
- package/src/automate/engine/index.js +2 -3
- package/src/automate/engine/uniqueName.js +2 -2
- package/src/automate/engine/utils.js +4 -2
- package/src/automate/template/myProcess.js +2 -2
- package/src/bak/translator.js +16 -25
- package/src/common/BaseNode.ts +3 -1
- package/src/common/Command.ts +4 -0
- package/src/common/dist/BaseNode.js +1101 -0
- package/src/concepts/App__.ts +36 -7
- package/src/concepts/Assignee__.ts +4 -3
- package/src/concepts/BatchAssignment__.ts +3 -3
- package/src/concepts/BindAttribute__.ts +301 -38
- package/src/concepts/BindDirective__.ts +205 -30
- package/src/concepts/BindStyle__.ts +188 -24
- package/src/concepts/CallFunction__.ts +55 -10
- package/src/concepts/CallInterface__.ts +3 -2
- package/src/concepts/CallLogic__.ts +110 -90
- package/src/concepts/CallQueryComponent__.ts +18 -3
- package/src/concepts/ConfigGroup__.ts +17 -4
- package/src/concepts/ConfigProperty__.ts +72 -4
- package/src/concepts/Configuration__.ts +14 -5
- package/src/concepts/DataSource__.ts +10 -3
- package/src/concepts/Destination__.ts +61 -7
- package/src/concepts/EntityProperty__.ts +7 -1
- package/src/concepts/EnumItem__.ts +6 -6
- package/src/concepts/Enum__.ts +22 -19
- package/src/concepts/ExternalDestination__.ts +29 -9
- package/src/concepts/ForEachStatement__.ts +2 -0
- package/src/concepts/Frontend__.ts +2 -1
- package/src/concepts/Identifier__.ts +16 -5
- package/src/concepts/InterfaceParam__.ts +7 -1
- package/src/concepts/JSBlock__.ts +3 -2
- package/src/concepts/Logic__.ts +110 -89
- package/src/concepts/Match__.ts +53 -14
- package/src/concepts/MemberExpression__.ts +6 -0
- package/src/concepts/Module__.ts +57 -0
- package/src/concepts/NewComposite__.ts +104 -131
- package/src/concepts/NewList__.ts +23 -2
- package/src/concepts/NewMap__.ts +48 -24
- package/src/concepts/OqlQueryComponent__.ts +40 -20
- package/src/concepts/Param__.ts +178 -176
- package/src/concepts/ProcessElement__.ts +2 -1
- package/src/concepts/ProcessOutcome__.ts +1 -1
- package/src/concepts/ProcessOutcomes__.ts +1 -1
- package/src/concepts/Process__.ts +1 -0
- package/src/concepts/Return__.ts +10 -2
- package/src/concepts/StringInterpolation__.ts +19 -7
- package/src/concepts/StringLiteral__.ts +7 -6
- package/src/concepts/StructureProperty__.ts +7 -1
- package/src/concepts/TypeAnnotation__.ts +102 -15
- package/src/concepts/ValidationRule__.ts +58 -9
- package/src/concepts/Variable__.ts +13 -1
- package/src/concepts/ViewElement__.ts +47 -2
- package/src/concepts/View__.ts +39 -18
- package/src/concepts/basics/stdlib/dist/nasl.util.js +1602 -0
- package/src/concepts/basics/stdlib/dist/reference2TypeAnnotationList.js +24 -0
- package/src/concepts/basics/stdlib/nasl.collection.ts +6 -1
- package/src/concepts/basics/stdlib/nasl.configuration.ts +3 -0
- package/src/concepts/basics/stdlib/nasl.core.ts +33 -2
- package/src/concepts/basics/stdlib/nasl.util.ts +4 -2
- package/src/concepts/basics/types/index.ts +1 -0
- package/src/concepts/dist/BindAttribute__.js +795 -0
- package/src/concepts/dist/BindEvent__.js +732 -0
- package/src/concepts/dist/CallFunction__.js +527 -0
- package/src/concepts/dist/CallLogic__.js +932 -0
- package/src/concepts/dist/Destination__.js +708 -0
- package/src/concepts/dist/ExternalDestination__.js +298 -0
- package/src/concepts/dist/Identifier__.js +311 -0
- package/src/concepts/dist/StringInterpolation__.js +231 -0
- package/src/concepts/dist/TypeAnnotation__.js +834 -0
- package/src/concepts/dist/ViewElement__.js +1692 -0
- package/src/concepts/dist/View__.js +1601 -0
- package/src/concepts/index__.ts +0 -1
- package/src/enums/KEYWORDS.ts +8 -0
- package/src/generator/dist/genBundleFiles.js +261 -0
- package/src/generator/dist/genMetaData.js +245 -0
- package/src/generator/dist/permission.js +405 -0
- package/src/generator/genBundleFiles.ts +24 -5
- package/src/generator/genReleaseBody.ts +77 -31
- package/src/generator/permission.ts +47 -21
- package/src/index.ts +1 -1
- package/src/server/entity2LogicNamespace.ts +2 -20
- package/src/server/extendBaseNode.ts +15 -5
- package/src/server/formatTsUtils.ts +41 -10
- package/src/server/getLogics.ts +4 -4
- package/src/server/getMemberIdentifier.ts +27 -1
- package/src/server/index.ts +2 -0
- package/src/server/naslServer.ts +555 -63
- package/src/server/translator.ts +96 -34
- package/src/service/storage/dist/init.js +579 -0
- package/src/service/storage/init.ts +23 -3
- package/src/templator/dist/genEditTableBlock.js +204 -0
- package/src/templator/dist/genGridViewBlock.js +265 -0
- package/src/templator/dist/genListViewBlock.js +84 -0
- package/src/templator/dist/genTableBlock.js +209 -0
- package/src/templator/dist/utils.js +527 -0
- package/src/templator/genCreateBlock.ts +1 -3
- package/src/templator/genCurdEditMultipleKeyBlock.ts +1 -3
- package/src/templator/genCurdMultipleKeyBlock.ts +2 -4
- package/src/templator/genGetBlock.ts +1 -1
- package/src/templator/genGridViewBlock.ts +3 -4
- package/src/templator/genListViewBlock.ts +9 -3
- package/src/templator/genSelectBlock.ts +1 -1
- package/src/templator/genTableBlock.ts +3 -3
- package/src/templator/genUpdateBlock.ts +2 -3
- package/src/translator/index.ts +3 -1
- package/src/utils/traverse.ts +10 -2
- package/ts-worker/lib/tsserver.js +10 -2
- package/ts-worker/package.json +1 -0
- package/ts-worker/webpack.config.js +11 -2
- package/out/concepts/ConstructArgument__.d.ts +0 -40
- package/out/concepts/ConstructArgument__.js +0 -108
- package/out/concepts/ConstructArgument__.js.map +0 -1
- package/out/concepts/Construct__.d.ts +0 -189
- package/out/concepts/Construct__.js +0 -340
- package/out/concepts/Construct__.js.map +0 -1
- package/out/templator/sql-parser/index.d.ts +0 -1
- package/out/templator/sql-parser/index.js +0 -228
- package/out/templator/sql-parser/index.js.map +0 -1
- package/out/templator/sql-parser/parser.js +0 -26664
- package/out/templator/sql-parser/parser.js.map +0 -1
package/src/server/naslServer.ts
CHANGED
|
@@ -62,6 +62,14 @@ import {
|
|
|
62
62
|
BatchAssignment,
|
|
63
63
|
ForEachStatement,
|
|
64
64
|
Frontend,
|
|
65
|
+
NewList,
|
|
66
|
+
NewMap,
|
|
67
|
+
ConfigProperty,
|
|
68
|
+
BindStyle,
|
|
69
|
+
BindDirective,
|
|
70
|
+
LogicItem,
|
|
71
|
+
JSBlock,
|
|
72
|
+
NewComposite,
|
|
65
73
|
} from '../concepts';
|
|
66
74
|
import { lsp2tspNumber, SourceMap, SourceMapItem } from '../translator';
|
|
67
75
|
import axios from '../service/storage';
|
|
@@ -71,16 +79,20 @@ import { DiagnosticRecord, Diagnostic, DiagnosticManager } from '../manager/diag
|
|
|
71
79
|
import formatUiTs from './createUiTs';
|
|
72
80
|
import { primitiveTypeList } from '../concepts/basics/types/coreTypeList';
|
|
73
81
|
import { getPlatformType, type2TypeAnnotation } from './formatTsUtils';
|
|
82
|
+
import * as utils from '../utils';
|
|
74
83
|
import naslStdlibMap from './naslStdlibMap';
|
|
75
84
|
import * as jsoner from '../service/storage/jsoner';
|
|
76
85
|
import { EventEmitter } from '../common/EventEmitter';
|
|
77
86
|
|
|
87
|
+
import { traverse } from '../utils';
|
|
88
|
+
|
|
78
89
|
const EmbeddedTSFileLineMap: { [name: string]: number } = {
|
|
79
90
|
Entity: 3,
|
|
80
91
|
};
|
|
81
92
|
|
|
82
93
|
const EmbeddedTSFileOffsetMap: { [name: string]: number } = {
|
|
83
94
|
Variable: 12,
|
|
95
|
+
ConfigProperty: 12,
|
|
84
96
|
};
|
|
85
97
|
|
|
86
98
|
export interface FileNode extends BaseNode {
|
|
@@ -169,6 +181,9 @@ export class NaslServer {
|
|
|
169
181
|
|
|
170
182
|
singleFileChangeIng: Boolean;
|
|
171
183
|
|
|
184
|
+
// 包含组件逻辑调用的逻辑map
|
|
185
|
+
logicSetWithComponentLogic: Set<string> = new Set<string>();
|
|
186
|
+
|
|
172
187
|
constructor() {
|
|
173
188
|
/// #if process.env.BUILD_TARGET === 'node'
|
|
174
189
|
if (globalThis.process) // For TS build
|
|
@@ -177,6 +192,7 @@ export class NaslServer {
|
|
|
177
192
|
/// #endif
|
|
178
193
|
/// #if process.env.BUILD_TARGET !== 'node'
|
|
179
194
|
if (globalThis.window) // For TS build
|
|
195
|
+
/* !!!如果改动这里需要看下关联的对应文件:webpack/ts-worker/loader.js */
|
|
180
196
|
this.worker = new Worker('/ts-worker.js');
|
|
181
197
|
/// #endif
|
|
182
198
|
|
|
@@ -386,6 +402,21 @@ export class NaslServer {
|
|
|
386
402
|
}
|
|
387
403
|
});
|
|
388
404
|
}
|
|
405
|
+
|
|
406
|
+
module.configuration?.groups?.forEach((_group) => {
|
|
407
|
+
if (_group.name === 'custom') {
|
|
408
|
+
_group.properties.forEach((_property) => {
|
|
409
|
+
try {
|
|
410
|
+
const result = _property.toEmbeddedTSFile();
|
|
411
|
+
results.push(result);
|
|
412
|
+
// sourceMap都存在目录级别内容下,在页面层级下去找
|
|
413
|
+
_property.sourceMap = result.sourceMap;
|
|
414
|
+
this.file2NodeMap.set(result.filePath, _property);
|
|
415
|
+
} catch (err) {
|
|
416
|
+
}
|
|
417
|
+
});
|
|
418
|
+
}
|
|
419
|
+
});
|
|
389
420
|
}
|
|
390
421
|
|
|
391
422
|
view2TSFile(viewsChildren: View[], results: Array<ReturnType<Structure['toEmbeddedTSFile']>>) {
|
|
@@ -788,6 +819,14 @@ export class NaslServer {
|
|
|
788
819
|
// diagnosticManager.pushAll(records);
|
|
789
820
|
}
|
|
790
821
|
|
|
822
|
+
/**
|
|
823
|
+
* 节点异常是只能挂载单个,如果已经了就不赋值了
|
|
824
|
+
*/
|
|
825
|
+
baseNodeAssignmentTsError(node: BaseNode, tsErrorDetail: Diagnostic) {
|
|
826
|
+
if (node.tsErrorDetail)
|
|
827
|
+
return;
|
|
828
|
+
node.tsErrorDetail = tsErrorDetail;
|
|
829
|
+
}
|
|
791
830
|
/**
|
|
792
831
|
* 处理诊断结果
|
|
793
832
|
* @param records 结果
|
|
@@ -846,6 +885,41 @@ export class NaslServer {
|
|
|
846
885
|
.filter((diag) => !!diag);
|
|
847
886
|
record.semanticDiagnostics.push(...this._attachDiagnostics(node));
|
|
848
887
|
|
|
888
|
+
// 报错降级逻辑
|
|
889
|
+
record.semanticDiagnostics = record.semanticDiagnostics
|
|
890
|
+
.map((diagnostic) => {
|
|
891
|
+
// 错误降级如果属于草稿态的就降级
|
|
892
|
+
if (diagnostic?.node) {
|
|
893
|
+
let currentNode = diagnostic.node;
|
|
894
|
+
while (currentNode?.parentNode?.concept !== 'App') {
|
|
895
|
+
if (currentNode.parentKey?.toLowerCase()?.includes('playground')) {
|
|
896
|
+
// 草稿区降级
|
|
897
|
+
// 重置 图标和错误等级
|
|
898
|
+
diagnostic.severity = 'warning';
|
|
899
|
+
if (diagnostic.node?.tsErrorDetail) {
|
|
900
|
+
// 重置组件节点上的错误信息
|
|
901
|
+
diagnostic.node.tsErrorDetail.severity = 'warning';
|
|
902
|
+
}
|
|
903
|
+
record.suggestionDiagnostics.push(diagnostic);
|
|
904
|
+
return null;
|
|
905
|
+
} else if (currentNode.concept === 'OqlQueryComponent') {
|
|
906
|
+
// OQL别名错误降级为警告
|
|
907
|
+
if (diagnostic.originalDiagnostic && diagnostic.originalDiagnostic?.text.includes('__OQL_ALIAS_WARNING__')) {
|
|
908
|
+
// 重置 图标和错误等级
|
|
909
|
+
diagnostic.severity = 'warning';
|
|
910
|
+
if (diagnostic.node?.tsErrorDetail) {
|
|
911
|
+
// 重置组件节点上的错误信息
|
|
912
|
+
diagnostic.node.tsErrorDetail.severity = 'warning';
|
|
913
|
+
}
|
|
914
|
+
record.suggestionDiagnostics.push(diagnostic);
|
|
915
|
+
return null;
|
|
916
|
+
}
|
|
917
|
+
}
|
|
918
|
+
currentNode = currentNode.parentNode;
|
|
919
|
+
}
|
|
920
|
+
}
|
|
921
|
+
return diagnostic;
|
|
922
|
+
}).filter((diag) => !!diag);
|
|
849
923
|
// 建议诊断
|
|
850
924
|
// 实体下的建议不用展示,因为都是平台自己写的逻辑
|
|
851
925
|
// if (node instanceof Entity) {
|
|
@@ -859,11 +933,49 @@ export class NaslServer {
|
|
|
859
933
|
// // logic在for循环中,不展示any提示
|
|
860
934
|
// record.suggestionDiagnostics = record.suggestionDiagnostics.filter((item) => !item.text.includes(`implicitly has an 'any' type, but a better type may be inferred from usage.`));
|
|
861
935
|
// }
|
|
862
|
-
|
|
863
|
-
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
936
|
+
|
|
937
|
+
// 处理后的警告异常提示信息
|
|
938
|
+
record.suggestionDiagnostics = record.suggestionDiagnostics.map((diag) => {
|
|
939
|
+
// 上面错误降级下来的
|
|
940
|
+
if (diag?.node) {
|
|
941
|
+
return diag;
|
|
942
|
+
// 一些已知警告的单独处理
|
|
943
|
+
} else if ([`'__LogicEmpty' is declared but its value is never read.`,
|
|
944
|
+
`'__destinationEmpty__' is declared but its value is never read.`,
|
|
945
|
+
`'__devConfigValueEmpty' is declared but its value is never read.`,
|
|
946
|
+
`'__onlineConfigValueEmpty' is declared but its value is never read.`,
|
|
947
|
+
`'__UpdateNoProperty__' is declared but its value is never read.`].includes(diag.text)) {
|
|
948
|
+
return this._resolveDiagnostic(diag as unknown as tsProtocol.DiagnosticWithFileName, node as FileNode, record);
|
|
949
|
+
} else if ((diag.text).includes(` is declared but its value is never read.`)) {
|
|
950
|
+
// 局部变量和输入变量未使用的警告
|
|
951
|
+
if ((node.concept === 'View' || node.concept === 'Logic') && node.parentNode.concept !== 'Module') {
|
|
952
|
+
const minRange = this._findMinRange(diag as unknown as tsProtocol.DiagnosticWithFileName, node as FileNode);
|
|
953
|
+
if (minRange) {
|
|
954
|
+
/**
|
|
955
|
+
* 如果节点是入参类型
|
|
956
|
+
* 而且不是foreach中
|
|
957
|
+
* 而且不是事件逻辑的入参
|
|
958
|
+
*/
|
|
959
|
+
if (minRange.node instanceof Param && minRange.node.parentNode.concept !== 'ForEachStatement' && !minRange.node.getAncestor('BindEvent')) {
|
|
960
|
+
const diagnostic = {
|
|
961
|
+
node: minRange.node,
|
|
962
|
+
severity: 'warning',
|
|
963
|
+
message: `未使用的输入参数${minRange.node.name}`,
|
|
964
|
+
};
|
|
965
|
+
return diagnostic;
|
|
966
|
+
} else if (minRange.node instanceof Variable) {
|
|
967
|
+
const diagnostic = {
|
|
968
|
+
node: minRange.node,
|
|
969
|
+
severity: 'warning',
|
|
970
|
+
message: `未使用的变量${minRange.node.name}`,
|
|
971
|
+
};
|
|
972
|
+
return diagnostic;
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
}
|
|
977
|
+
return null;
|
|
978
|
+
}).filter((diag) => !!diag);
|
|
867
979
|
|
|
868
980
|
record.suggestionDiagnostics.push(...this._attachSuggestionDiagnostics(node));
|
|
869
981
|
});
|
|
@@ -878,22 +990,6 @@ export class NaslServer {
|
|
|
878
990
|
_attachSuggestionDiagnostics(fileNode: BaseNode): Diagnostic[] {
|
|
879
991
|
const diagnostics: Diagnostic[] = [];
|
|
880
992
|
if (fileNode instanceof Logic || fileNode instanceof View) {
|
|
881
|
-
// 判断逻辑是否已经删除
|
|
882
|
-
if (fileNode instanceof Logic && fileNode.parentNode instanceof App && !fileNode.parentNode.logics.includes(fileNode))
|
|
883
|
-
return diagnostics;
|
|
884
|
-
// 判断页面是否已经删除
|
|
885
|
-
let removed = false;
|
|
886
|
-
let curNode: Logic | View | App | Frontend = fileNode;
|
|
887
|
-
// 递归检查,防止从顶层页面开始删除影响子页面内容检查
|
|
888
|
-
while (curNode instanceof View && !removed) {
|
|
889
|
-
if (curNode.parentNode instanceof View && !curNode.parentNode.children.includes(curNode)
|
|
890
|
-
|| curNode.parentNode instanceof Frontend && !curNode.parentNode.views.includes(curNode)) {
|
|
891
|
-
removed = true;
|
|
892
|
-
}
|
|
893
|
-
curNode = curNode.parentNode as View | Frontend;
|
|
894
|
-
}
|
|
895
|
-
if (removed)
|
|
896
|
-
return diagnostics;
|
|
897
993
|
fileNode?.sourceMap.forEach((value, node) => {
|
|
898
994
|
if (node instanceof Match) {
|
|
899
995
|
const { cases, expression } = node || {};
|
|
@@ -1008,42 +1104,238 @@ export class NaslServer {
|
|
|
1008
1104
|
if (Array.isArray(body) && body.length) {
|
|
1009
1105
|
const lastExpression = body[body.length - 1];
|
|
1010
1106
|
diagnostic.node = lastExpression;
|
|
1011
|
-
diagnostic.message =
|
|
1012
|
-
lastExpression
|
|
1107
|
+
diagnostic.message = `匹配:该分支类型与多数类型不一致,将产生Union类型。当前类型:${typeAnnotation?.headTitle},多数类型:${maxTypeAnnotation?.headTitle}`;
|
|
1108
|
+
this.baseNodeAssignmentTsError(lastExpression, diagnostic);
|
|
1013
1109
|
diagnostics.push(diagnostic);
|
|
1014
1110
|
}
|
|
1015
1111
|
});
|
|
1016
1112
|
}
|
|
1017
1113
|
}
|
|
1018
1114
|
}
|
|
1115
|
+
} else if (node instanceof NewList && !node.typeAnnotation) {
|
|
1116
|
+
// 匿名函数返回值有可能是newList,需要过滤。代码来源:AnonymousFunction.__ts
|
|
1117
|
+
const grandParent = node.parentNode?.parentNode?.parentNode;
|
|
1118
|
+
if (grandParent instanceof CallLogic
|
|
1119
|
+
&& /dataSources\.[^.]+\.entities\.[^.]+\.logics/.test(grandParent.calleeNamespace)
|
|
1120
|
+
&& ['update', 'updateBy', 'createOrUpdate', 'batchUpdate'].includes(grandParent.calleeName)) {
|
|
1121
|
+
return;
|
|
1122
|
+
}
|
|
1123
|
+
const { items } = node || {};
|
|
1124
|
+
const typeAnnotationMap: any = {};
|
|
1125
|
+
// 最多数的类型
|
|
1126
|
+
let maxTypeAnnotationInfo: any = {
|
|
1127
|
+
typeAnnotation: null,
|
|
1128
|
+
count: 0,
|
|
1129
|
+
};
|
|
1130
|
+
if (Array.isArray(items)) {
|
|
1131
|
+
items.forEach((item) => {
|
|
1132
|
+
const typeAnnotation = item.__TypeAnnotation;
|
|
1133
|
+
// 仅处理有类型的情况,返回类型为void的情况由其他地方处理成报错
|
|
1134
|
+
if (typeAnnotation) {
|
|
1135
|
+
const sortedTypeKey = typeAnnotation.sortedTypeKey;
|
|
1136
|
+
if (!typeAnnotationMap[sortedTypeKey]) {
|
|
1137
|
+
typeAnnotationMap[sortedTypeKey] = {
|
|
1138
|
+
typeAnnotation,
|
|
1139
|
+
items: [],
|
|
1140
|
+
count: 0,
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
1143
|
+
const typeAnnotationInfo = typeAnnotationMap[sortedTypeKey];
|
|
1144
|
+
typeAnnotationInfo.items.push(item);
|
|
1145
|
+
typeAnnotationInfo.count++;
|
|
1146
|
+
const { count } = typeAnnotationInfo;
|
|
1147
|
+
if (maxTypeAnnotationInfo.count < count) {
|
|
1148
|
+
maxTypeAnnotationInfo = {
|
|
1149
|
+
typeAnnotation,
|
|
1150
|
+
count,
|
|
1151
|
+
};
|
|
1152
|
+
}
|
|
1153
|
+
}
|
|
1154
|
+
});
|
|
1155
|
+
}
|
|
1156
|
+
const {
|
|
1157
|
+
typeAnnotation: maxTypeAnnotation,
|
|
1158
|
+
} = maxTypeAnnotationInfo;
|
|
1159
|
+
for (const sortedTypeKey in typeAnnotationMap) {
|
|
1160
|
+
const { typeAnnotation, items } = typeAnnotationMap[sortedTypeKey];
|
|
1161
|
+
if (maxTypeAnnotation?.sortedTypeKey !== typeAnnotation?.sortedTypeKey) {
|
|
1162
|
+
if (Array.isArray(items)) {
|
|
1163
|
+
items.forEach((item) => {
|
|
1164
|
+
const diagnostic = {
|
|
1165
|
+
node: item,
|
|
1166
|
+
severity: 'warning',
|
|
1167
|
+
message: `NewList期望的类型是${maxTypeAnnotation?.headTitle}`,
|
|
1168
|
+
};
|
|
1169
|
+
this.baseNodeAssignmentTsError(item, diagnostic);
|
|
1170
|
+
diagnostics.push(diagnostic);
|
|
1171
|
+
});
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
}
|
|
1175
|
+
} else if (node instanceof NewMap && !node.typeAnnotation) {
|
|
1176
|
+
const { values } = node || {};
|
|
1177
|
+
const typeAnnotationMap: any = {};
|
|
1178
|
+
// 最多数的类型
|
|
1179
|
+
let maxTypeAnnotationInfo: any = {
|
|
1180
|
+
typeAnnotation: null,
|
|
1181
|
+
count: 0,
|
|
1182
|
+
};
|
|
1183
|
+
if (Array.isArray(values)) {
|
|
1184
|
+
values.forEach((value) => {
|
|
1185
|
+
if (!value)
|
|
1186
|
+
return;
|
|
1187
|
+
const typeAnnotation = value.__TypeAnnotation;
|
|
1188
|
+
// 仅处理有类型的情况,返回类型为void的情况由其他地方处理成报错
|
|
1189
|
+
if (typeAnnotation) {
|
|
1190
|
+
const sortedTypeKey = typeAnnotation.sortedTypeKey;
|
|
1191
|
+
if (!typeAnnotationMap[sortedTypeKey]) {
|
|
1192
|
+
typeAnnotationMap[sortedTypeKey] = {
|
|
1193
|
+
typeAnnotation,
|
|
1194
|
+
values: [],
|
|
1195
|
+
count: 0,
|
|
1196
|
+
};
|
|
1197
|
+
}
|
|
1198
|
+
const typeAnnotationInfo = typeAnnotationMap[sortedTypeKey];
|
|
1199
|
+
typeAnnotationInfo.values.push(value);
|
|
1200
|
+
typeAnnotationInfo.count++;
|
|
1201
|
+
const { count } = typeAnnotationInfo;
|
|
1202
|
+
if (maxTypeAnnotationInfo.count < count) {
|
|
1203
|
+
maxTypeAnnotationInfo = {
|
|
1204
|
+
typeAnnotation,
|
|
1205
|
+
count,
|
|
1206
|
+
};
|
|
1207
|
+
}
|
|
1208
|
+
}
|
|
1209
|
+
});
|
|
1210
|
+
}
|
|
1211
|
+
const {
|
|
1212
|
+
typeAnnotation: maxTypeAnnotation,
|
|
1213
|
+
} = maxTypeAnnotationInfo;
|
|
1214
|
+
for (const sortedTypeKey in typeAnnotationMap) {
|
|
1215
|
+
const { typeAnnotation, values } = typeAnnotationMap[sortedTypeKey];
|
|
1216
|
+
if (maxTypeAnnotation?.sortedTypeKey !== typeAnnotation?.sortedTypeKey) {
|
|
1217
|
+
if (Array.isArray(values)) {
|
|
1218
|
+
values.forEach((value) => {
|
|
1219
|
+
const diagnostic = {
|
|
1220
|
+
node: value,
|
|
1221
|
+
severity: 'warning',
|
|
1222
|
+
message: `NewMap中values值所期望的类型是${maxTypeAnnotation?.headTitle}`,
|
|
1223
|
+
};
|
|
1224
|
+
this.baseNodeAssignmentTsError(value, diagnostic);
|
|
1225
|
+
diagnostics.push(diagnostic);
|
|
1226
|
+
});
|
|
1227
|
+
}
|
|
1228
|
+
}
|
|
1229
|
+
}
|
|
1230
|
+
} else if (node.concept === 'JSBlock') {
|
|
1231
|
+
// 初始js代码块先屏蔽掉
|
|
1232
|
+
if ((node as JSBlock).code === `location.href = '/';`) {
|
|
1233
|
+
return null;
|
|
1234
|
+
}
|
|
1235
|
+
const diagnostic = {
|
|
1236
|
+
node,
|
|
1237
|
+
severity: 'warning',
|
|
1238
|
+
message: '不建议使用js代码块',
|
|
1239
|
+
};
|
|
1240
|
+
diagnostics.push(diagnostic);
|
|
1241
|
+
} else if (node.concept === 'Unparsed') {
|
|
1242
|
+
const diagnostic = {
|
|
1243
|
+
node,
|
|
1244
|
+
severity: 'warning',
|
|
1245
|
+
message: '不建议使用自定义表达式',
|
|
1246
|
+
};
|
|
1247
|
+
diagnostics.push(diagnostic);
|
|
1248
|
+
} else if (node instanceof CallQueryComponent) {
|
|
1249
|
+
// 可视化查询中不允许有复杂的数据结构
|
|
1250
|
+
const contentVariables: Array<Identifier | MemberExpression> = [];
|
|
1251
|
+
utils.traverse(({ node }) => {
|
|
1252
|
+
if ((node as any)?.parentNode?.concept !== 'MemberExpression') {
|
|
1253
|
+
if ((node as any)?.concept === 'MemberExpression') {
|
|
1254
|
+
contentVariables.push(node as any);
|
|
1255
|
+
} else if ((node as any)?.concept === 'Identifier') {
|
|
1256
|
+
// 因为要是父级是MemberExpression, 就放入了父级,子级就不需要了
|
|
1257
|
+
contentVariables.push(node as any);
|
|
1258
|
+
// QueryFromExpression QueryJoinExpression
|
|
1259
|
+
} else if ((node as any)?.concept === 'QueryFieldExpression' || (node as any)?.concept === 'QueryGroupByExpression') {
|
|
1260
|
+
contentVariables.push(node as any);
|
|
1261
|
+
}
|
|
1262
|
+
}
|
|
1263
|
+
}, { node }, {
|
|
1264
|
+
mode: 'anyObject',
|
|
1265
|
+
excludedKeySet: new Set(['parentNode', '_events', 'globalDataMap', 'havingPlayground', 'wherePlayground']),
|
|
1266
|
+
});
|
|
1267
|
+
contentVariables?.forEach((variable) => {
|
|
1268
|
+
// 如果是复杂数据结构
|
|
1269
|
+
if (variable.__TypeAnnotation?.isComplexType()) {
|
|
1270
|
+
const diagnostic = {
|
|
1271
|
+
node,
|
|
1272
|
+
severity: 'warning',
|
|
1273
|
+
message: `数据查询中不可以使用复杂类型!当前类型:${variable.__TypeAnnotation?.typeChineseTitle}。`,
|
|
1274
|
+
};
|
|
1275
|
+
this.baseNodeAssignmentTsError(variable, diagnostic);
|
|
1276
|
+
diagnostics.push(diagnostic);
|
|
1277
|
+
}
|
|
1278
|
+
});
|
|
1019
1279
|
}
|
|
1020
1280
|
});
|
|
1021
1281
|
}
|
|
1022
1282
|
return diagnostics;
|
|
1023
1283
|
}
|
|
1024
1284
|
|
|
1285
|
+
// 是否包含组件逻辑
|
|
1286
|
+
hasComponentLogics(expression: BaseNode) {
|
|
1287
|
+
let flag = false;
|
|
1288
|
+
traverse((current: any) => {
|
|
1289
|
+
const { node } = current || {};
|
|
1290
|
+
const { concept } = node || {};
|
|
1291
|
+
if (concept === 'CallLogic') {
|
|
1292
|
+
// 调用组件逻辑
|
|
1293
|
+
if (node.isComponentLogic) {
|
|
1294
|
+
flag = true;
|
|
1295
|
+
} else if (node.isViewLogic) { // 调用页面逻辑
|
|
1296
|
+
const logicNode = node.view?.logics?.find?.((viewLogic: Logic) => viewLogic.name === node.calleeName);
|
|
1297
|
+
if (logicNode) {
|
|
1298
|
+
if (this.logicSetWithComponentLogic.has(logicNode.nodePath)) {
|
|
1299
|
+
flag = true;
|
|
1300
|
+
} else {
|
|
1301
|
+
const logicItem = logicNode.body?.find?.((logicItem: LogicItem) => this.hasComponentLogics(logicItem));
|
|
1302
|
+
if (logicItem) {
|
|
1303
|
+
flag = true;
|
|
1304
|
+
this.logicSetWithComponentLogic.add(logicNode.nodePath);
|
|
1305
|
+
}
|
|
1306
|
+
}
|
|
1307
|
+
}
|
|
1308
|
+
}
|
|
1309
|
+
}
|
|
1310
|
+
}, {
|
|
1311
|
+
node: expression,
|
|
1312
|
+
}, {
|
|
1313
|
+
mode: 'anyObject',
|
|
1314
|
+
excludedKeySet: new Set([
|
|
1315
|
+
'parentNode',
|
|
1316
|
+
'sourceMap',
|
|
1317
|
+
'storageJSON',
|
|
1318
|
+
'tsErrorDetail',
|
|
1319
|
+
'NaslAnnotatedJSON',
|
|
1320
|
+
'calledFrom',
|
|
1321
|
+
'_events',
|
|
1322
|
+
'_collectingList',
|
|
1323
|
+
'_historyList',
|
|
1324
|
+
]),
|
|
1325
|
+
});
|
|
1326
|
+
return flag;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1025
1329
|
/**
|
|
1026
1330
|
* 额外的诊断
|
|
1027
1331
|
* @param fileNode 文件级别的节点
|
|
1028
1332
|
* @returns 诊断结果
|
|
1029
1333
|
*/
|
|
1030
1334
|
_attachDiagnostics(fileNode: BaseNode): Diagnostic[] {
|
|
1335
|
+
// 每次诊断前先清空这个Set
|
|
1336
|
+
this.logicSetWithComponentLogic = new Set<string>();
|
|
1031
1337
|
const diagnostics: Diagnostic[] = [];
|
|
1032
1338
|
if (fileNode instanceof View) {
|
|
1033
|
-
// 判断页面是否已经删除
|
|
1034
|
-
let removed = false;
|
|
1035
|
-
let curNode: View | App | Frontend = fileNode;
|
|
1036
|
-
// 递归检查,防止从顶层页面开始删除影响子页面内容检查
|
|
1037
|
-
while (curNode instanceof View && !removed) {
|
|
1038
|
-
if (curNode.parentNode instanceof View && !curNode.parentNode.children.includes(curNode)
|
|
1039
|
-
|| curNode.parentNode instanceof Frontend && !curNode.parentNode.views.includes(curNode)) {
|
|
1040
|
-
removed = true;
|
|
1041
|
-
}
|
|
1042
|
-
curNode = curNode.parentNode as View | Frontend;
|
|
1043
|
-
}
|
|
1044
|
-
if (removed)
|
|
1045
|
-
return diagnostics;
|
|
1046
|
-
|
|
1047
1339
|
fileNode?.sourceMap.forEach((value, node) => {
|
|
1048
1340
|
if (node instanceof ViewElement && node.view === fileNode) {
|
|
1049
1341
|
if (node.tag) {
|
|
@@ -1086,7 +1378,12 @@ export class NaslServer {
|
|
|
1086
1378
|
if (node.logic && node.logic !== nodeIn.logic)
|
|
1087
1379
|
return;
|
|
1088
1380
|
// 跟变量无关的赋值过滤
|
|
1089
|
-
|
|
1381
|
+
let jsCode = '';
|
|
1382
|
+
try {
|
|
1383
|
+
jsCode = nodeIn.toJS();
|
|
1384
|
+
} catch (err) {
|
|
1385
|
+
console.log(err);
|
|
1386
|
+
}
|
|
1090
1387
|
if (!jsCode.includes(`${node.name} = `))
|
|
1091
1388
|
return;
|
|
1092
1389
|
// 页面局部变量
|
|
@@ -1123,7 +1420,7 @@ export class NaslServer {
|
|
|
1123
1420
|
}
|
|
1124
1421
|
});
|
|
1125
1422
|
if (!msg)
|
|
1126
|
-
msg = '
|
|
1423
|
+
msg = '未设置类型或未赋值。直接赋值系统可以自动推断类型。';
|
|
1127
1424
|
const diagnostic = {
|
|
1128
1425
|
node,
|
|
1129
1426
|
severity: 'error',
|
|
@@ -1132,6 +1429,30 @@ export class NaslServer {
|
|
|
1132
1429
|
node.tsErrorDetail = diagnostic;
|
|
1133
1430
|
diagnostics.push(diagnostic);
|
|
1134
1431
|
}
|
|
1432
|
+
} else if (node instanceof BindAttribute || node instanceof BindDirective || node instanceof BindStyle) {
|
|
1433
|
+
if (Array.isArray(node.bindExpressions)) {
|
|
1434
|
+
const exp = node.bindExpressions.find((bindExpression) => this.hasComponentLogics(bindExpression));
|
|
1435
|
+
if (exp) {
|
|
1436
|
+
//const element: any = node.getAncestor('ViewElement');
|
|
1437
|
+
//const api = config.allNodesAPI[element?.tag];
|
|
1438
|
+
//const attr = api?.attrs?.find?.((attr) => {
|
|
1439
|
+
// return attr.name === node.name;
|
|
1440
|
+
//});
|
|
1441
|
+
const map = {
|
|
1442
|
+
BindAttribute: '属性',
|
|
1443
|
+
BindDirective: '指令',
|
|
1444
|
+
BindStyle: '样式属性',
|
|
1445
|
+
};
|
|
1446
|
+
//“${attr?.title || node.title || node.name}”
|
|
1447
|
+
const diagnostic = {
|
|
1448
|
+
node,
|
|
1449
|
+
severity: 'error',
|
|
1450
|
+
message: `${map[node.concept]}表达式不能绑定组件逻辑`,
|
|
1451
|
+
};
|
|
1452
|
+
node.tsErrorDetail = diagnostic;
|
|
1453
|
+
diagnostics.push(diagnostic);
|
|
1454
|
+
}
|
|
1455
|
+
}
|
|
1135
1456
|
} else {
|
|
1136
1457
|
this.checkNodeError(node, diagnostics);
|
|
1137
1458
|
}
|
|
@@ -1198,10 +1519,6 @@ export class NaslServer {
|
|
|
1198
1519
|
}
|
|
1199
1520
|
}
|
|
1200
1521
|
if (fileNode instanceof Logic) {
|
|
1201
|
-
// 判断逻辑是否已经删除
|
|
1202
|
-
if (fileNode.parentNode instanceof App && !fileNode.parentNode.logics.includes(fileNode))
|
|
1203
|
-
return diagnostics;
|
|
1204
|
-
|
|
1205
1522
|
fileNode?.sourceMap.forEach((value, node) => {
|
|
1206
1523
|
//OQL支持返回复合类型数据了
|
|
1207
1524
|
// SqlQueryComponent内部返回值类型,如果是嵌套的就需要报错
|
|
@@ -1214,6 +1531,24 @@ export class NaslServer {
|
|
|
1214
1531
|
// node.tsErrorDetail = diagnostic;
|
|
1215
1532
|
// diagnostics.push(diagnostic);
|
|
1216
1533
|
// }
|
|
1534
|
+
if (node instanceof OqlQueryComponent) {
|
|
1535
|
+
// 自动推导情况
|
|
1536
|
+
const typeAnnotation = type2TypeAnnotation((node as any).__nodeType);
|
|
1537
|
+
if (!node.typeAnnotation && typeAnnotation) {
|
|
1538
|
+
if (typeAnnotation.typeName === 'List' && typeAnnotation.typeKind === 'generic') {
|
|
1539
|
+
const typeArguments = typeAnnotation.typeArguments;
|
|
1540
|
+
if (typeArguments.length && typeArguments[0].isComplexType()) {
|
|
1541
|
+
const diagnostic = {
|
|
1542
|
+
node,
|
|
1543
|
+
severity: 'error',
|
|
1544
|
+
message: `SQL查询:返回类型不支持单个复杂类型 ${typeArguments[0].headTitle}。`,
|
|
1545
|
+
};
|
|
1546
|
+
node.tsErrorDetail = diagnostic;
|
|
1547
|
+
diagnostics.push(diagnostic);
|
|
1548
|
+
}
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1217
1552
|
if (node instanceof Return || node instanceof Variable) {
|
|
1218
1553
|
if (!node.typeAnnotation && !node.__TypeAnnotation) {
|
|
1219
1554
|
const nodeTypeName = node.concept === 'Return' ? '输出参数' : '局部变量';
|
|
@@ -1221,16 +1556,24 @@ export class NaslServer {
|
|
|
1221
1556
|
fileNode?.sourceMap.forEach((valueIn, nodeIn) => {
|
|
1222
1557
|
if (!used && nodeIn
|
|
1223
1558
|
&& (nodeIn instanceof BatchAssignment || (nodeIn instanceof Assignment && nodeIn.left?.name))
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
|
|
1559
|
+
) {
|
|
1560
|
+
let jsCode = '';
|
|
1561
|
+
try {
|
|
1562
|
+
jsCode = nodeIn.toJS();
|
|
1563
|
+
} catch (err) {
|
|
1564
|
+
console.log(err);
|
|
1565
|
+
}
|
|
1566
|
+
if (jsCode.includes(`${node.name} = `)) {
|
|
1567
|
+
used = true;
|
|
1568
|
+
if (!nodeIn.tsErrorDetail) {
|
|
1569
|
+
const diagnostic = {
|
|
1570
|
+
node: nodeIn,
|
|
1571
|
+
severity: 'error',
|
|
1572
|
+
message: `${nodeIn.label}左边 ${node.name} 未设置类型,右边必须为有返回值的内容。`,
|
|
1573
|
+
};
|
|
1574
|
+
nodeIn.tsErrorDetail = diagnostic;
|
|
1575
|
+
diagnostics.push(diagnostic);
|
|
1576
|
+
}
|
|
1234
1577
|
}
|
|
1235
1578
|
}
|
|
1236
1579
|
});
|
|
@@ -1257,7 +1600,7 @@ export class NaslServer {
|
|
|
1257
1600
|
return diagnostics;
|
|
1258
1601
|
}
|
|
1259
1602
|
|
|
1260
|
-
checkNodeError(node: BaseNode, diagnostics: Diagnostic[]) {
|
|
1603
|
+
checkNodeError(node: BaseNode, diagnostics: Diagnostic[]): any {
|
|
1261
1604
|
if (!node)
|
|
1262
1605
|
return;
|
|
1263
1606
|
// 如果节点是match的看看节点里是不是有重复的
|
|
@@ -1313,6 +1656,19 @@ export class NaslServer {
|
|
|
1313
1656
|
}
|
|
1314
1657
|
});
|
|
1315
1658
|
}
|
|
1659
|
+
if (node instanceof MatchCase && (node.getAncestor('Match') as Match)?.isExpression && node.body.length === 0) {
|
|
1660
|
+
// 如果不是其他就标红
|
|
1661
|
+
if ((node?.getIndexOfParent() !== ((node.getAncestor('Match') as Match)?.cases?.length || 0) - 1)) {
|
|
1662
|
+
const diagnostic = {
|
|
1663
|
+
node,
|
|
1664
|
+
severity: 'error',
|
|
1665
|
+
message: '匹配分支:返回内容不能为空',
|
|
1666
|
+
titleTip: '返回内容不能为空',
|
|
1667
|
+
};
|
|
1668
|
+
node.tsErrorDetail = diagnostic;
|
|
1669
|
+
diagnostics.push(diagnostic);
|
|
1670
|
+
}
|
|
1671
|
+
}
|
|
1316
1672
|
// 如果节点是match的patterns 里的
|
|
1317
1673
|
if (node?.parentKey === 'patterns' && node.parentNode instanceof MatchCase) {
|
|
1318
1674
|
const matchNode = node.getAncestor('Match');
|
|
@@ -1385,11 +1741,57 @@ export class NaslServer {
|
|
|
1385
1741
|
const diagnostic = {
|
|
1386
1742
|
node,
|
|
1387
1743
|
severity: 'error',
|
|
1388
|
-
message:
|
|
1744
|
+
message: `类型不匹配,传入类型:void`,
|
|
1389
1745
|
};
|
|
1390
1746
|
node.tsErrorDetail = diagnostic;
|
|
1391
1747
|
diagnostics.push(diagnostic);
|
|
1392
1748
|
}
|
|
1749
|
+
// newMap key或者value没填都要有报错
|
|
1750
|
+
if (node instanceof NewMap) {
|
|
1751
|
+
// 如果一项没有key 或者没有 value 就报错
|
|
1752
|
+
const findFlag = node.keys?.some((key, index) => !key || !node.values?.[index]);
|
|
1753
|
+
if (findFlag) {
|
|
1754
|
+
const diagnostic = {
|
|
1755
|
+
node,
|
|
1756
|
+
severity: 'error',
|
|
1757
|
+
message: `新建Map的key和value应该都必填`,
|
|
1758
|
+
};
|
|
1759
|
+
node.tsErrorDetail = diagnostic;
|
|
1760
|
+
diagnostics.push(diagnostic);
|
|
1761
|
+
}
|
|
1762
|
+
}
|
|
1763
|
+
// 赋值语句左右list 和 map等可以 必须都一样
|
|
1764
|
+
if (node instanceof Assignment && !node.tsErrorDetail) {
|
|
1765
|
+
const leftType = node.left?.__TypeAnnotation || {} as TypeAnnotation;
|
|
1766
|
+
const rightType = node.right?.__TypeAnnotation || {} as TypeAnnotation;
|
|
1767
|
+
// 如果左边节点是 泛型,而且 左边泛型的名字 和 右边一样, 而且是list 或者map 就强制报错
|
|
1768
|
+
// 而且右边原来没有报错
|
|
1769
|
+
if (leftType.typeKind === 'generic' && leftType.typeKind === rightType.typeKind && leftType.typeName === rightType.typeName && ['Map', 'List'].includes(leftType.typeName)) {
|
|
1770
|
+
if (!(node.right.tsErrorDetail) && leftType.sortedTypeKey !== rightType.sortedTypeKey) {
|
|
1771
|
+
const excludeList = [
|
|
1772
|
+
'nasl.collection.List<nasl.core.String>',
|
|
1773
|
+
'nasl.collection.List<nasl.core.Text>',
|
|
1774
|
+
'nasl.collection.List<nasl.core.Email>',
|
|
1775
|
+
'nasl.collection.Map<nasl.core.String, nasl.core.String>',
|
|
1776
|
+
'nasl.collection.Map<nasl.core.String, nasl.core.Text>',
|
|
1777
|
+
'nasl.collection.Map<nasl.core.String, nasl.core.Email>',
|
|
1778
|
+
];
|
|
1779
|
+
// 先特殊处理等 类型合并后就可以去掉了
|
|
1780
|
+
if (excludeList.includes(leftType.sortedTypeKey) && excludeList.includes(rightType.sortedTypeKey)) {
|
|
1781
|
+
return null;
|
|
1782
|
+
} else if (['nasl.collection.List<>'].includes(leftType.sortedTypeKey) || ['nasl.collection.List<>'].includes(rightType.sortedTypeKey)) {
|
|
1783
|
+
return null;
|
|
1784
|
+
}
|
|
1785
|
+
const diagnostic = {
|
|
1786
|
+
node: node.right,
|
|
1787
|
+
severity: 'error',
|
|
1788
|
+
message: `左右参数类型不一致!左边类型:${leftType.typeChineseTitle},右边类型:${rightType.typeChineseTitle}。`,
|
|
1789
|
+
};
|
|
1790
|
+
node.right.tsErrorDetail = diagnostic;
|
|
1791
|
+
diagnostics.push(diagnostic);
|
|
1792
|
+
}
|
|
1793
|
+
}
|
|
1794
|
+
}
|
|
1393
1795
|
}
|
|
1394
1796
|
|
|
1395
1797
|
/* 接口导入查找 */
|
|
@@ -1457,7 +1859,7 @@ export class NaslServer {
|
|
|
1457
1859
|
*/
|
|
1458
1860
|
_resolveDiagnostic(diagnostic: tsProtocol.DiagnosticWithFileName, fileNode: FileNode, record: DiagnosticRecord): Diagnostic {
|
|
1459
1861
|
// 拓展模块中的翻译先过滤掉,因为有错用户也不能修改
|
|
1460
|
-
if ((fileNode as any).module)
|
|
1862
|
+
if ((fileNode as any).module && !(fileNode instanceof ConfigProperty))
|
|
1461
1863
|
return;
|
|
1462
1864
|
|
|
1463
1865
|
const minRange = this._findMinRange(diagnostic, fileNode);
|
|
@@ -1684,6 +2086,53 @@ export class NaslServer {
|
|
|
1684
2086
|
refsList = [...methodRefs];
|
|
1685
2087
|
}
|
|
1686
2088
|
}
|
|
2089
|
+
if (node instanceof Process) {
|
|
2090
|
+
if (currentSource) {
|
|
2091
|
+
const code = currentSource.code;
|
|
2092
|
+
const prefix = '__ProcessIdentification__';
|
|
2093
|
+
let positions = [];
|
|
2094
|
+
let pos = code.indexOf(prefix);
|
|
2095
|
+
while (pos !== -1) {
|
|
2096
|
+
positions.push(pos);
|
|
2097
|
+
pos = code.indexOf(prefix, pos + prefix.length);
|
|
2098
|
+
}
|
|
2099
|
+
positions.shift();
|
|
2100
|
+
// 拿到标识下定义的const process = {...}
|
|
2101
|
+
positions = positions.map((position) => code.indexOf('const', position + prefix.length));
|
|
2102
|
+
const promises = positions.map((item) => this.references({
|
|
2103
|
+
file: (fileNode as FileNode).getEmbeddedFilePath(),
|
|
2104
|
+
line: lsp2tspNumber(currentSource.range.start.line),
|
|
2105
|
+
offset: lsp2tspNumber(currentSource.range.start.character + item),
|
|
2106
|
+
}));
|
|
2107
|
+
const results = await Promise.all(promises);
|
|
2108
|
+
results.forEach((constRefs) => {
|
|
2109
|
+
refsList = [...refsList, ...constRefs.refs];
|
|
2110
|
+
});
|
|
2111
|
+
}
|
|
2112
|
+
}
|
|
2113
|
+
if (node instanceof ProcessElement) {
|
|
2114
|
+
if (currentSource) {
|
|
2115
|
+
const code = currentSource.code;
|
|
2116
|
+
const prefix = '__ProcessIdentification__';
|
|
2117
|
+
let positions = [];
|
|
2118
|
+
let pos = code.indexOf(prefix);
|
|
2119
|
+
while (pos !== -1) {
|
|
2120
|
+
positions.push(pos);
|
|
2121
|
+
pos = code.indexOf(prefix, pos + prefix.length);
|
|
2122
|
+
}
|
|
2123
|
+
// 拿到标识下定义的const process = {...}
|
|
2124
|
+
positions = positions.map((position) => code.indexOf(`${node.name}:`, position + prefix.length));
|
|
2125
|
+
const promises = positions.map((item) => this.references({
|
|
2126
|
+
file: (fileNode as FileNode).getEmbeddedFilePath(),
|
|
2127
|
+
line: lsp2tspNumber(currentSource.range.start.line),
|
|
2128
|
+
offset: lsp2tspNumber(currentSource.range.start.character + item),
|
|
2129
|
+
}));
|
|
2130
|
+
const results = await Promise.all(promises);
|
|
2131
|
+
results.forEach((constRefs) => {
|
|
2132
|
+
refsList = [...refsList, ...constRefs.refs];
|
|
2133
|
+
});
|
|
2134
|
+
}
|
|
2135
|
+
}
|
|
1687
2136
|
// console.log(refsList, 'refsList');
|
|
1688
2137
|
return refsList;
|
|
1689
2138
|
}
|
|
@@ -2334,13 +2783,16 @@ export class NaslServer {
|
|
|
2334
2783
|
// 如果没有sourceMap,就继续向上找 ,或者到module结束
|
|
2335
2784
|
// 如果 节点找到 app 或者module 停止 或者entity找到DataSource为止
|
|
2336
2785
|
// 如果当前节点是view就不要向上查找了
|
|
2786
|
+
// 配置参数的ConfigProperty也不需要向上找
|
|
2337
2787
|
while (
|
|
2338
2788
|
!sourceMap
|
|
2339
2789
|
&& fileNode
|
|
2340
2790
|
&& !(fileNode.parentNode instanceof App)
|
|
2341
2791
|
&& !(fileNode.parentNode instanceof Module)
|
|
2342
2792
|
&& !(fileNode.parentNode instanceof DataSource)
|
|
2793
|
+
&& !(fileNode.parentNode instanceof Frontend)
|
|
2343
2794
|
&& !(fileNode instanceof View)
|
|
2795
|
+
&& !(fileNode instanceof ConfigProperty)
|
|
2344
2796
|
) {
|
|
2345
2797
|
fileNode = fileNode.parentNode;
|
|
2346
2798
|
sourceMap = fileNode?.sourceMap;
|
|
@@ -2434,7 +2886,7 @@ export class NaslServer {
|
|
|
2434
2886
|
* @returns 不需要去查就可以返回类型的节点
|
|
2435
2887
|
*/
|
|
2436
2888
|
getCurrentNodeKnownTypeAnnotation(node: BaseNode) {
|
|
2437
|
-
if (node.concept === 'StringLiteral' || node.concept === 'BooleanLiteral' || node.concept === 'NullLiteral') {
|
|
2889
|
+
if (node.concept === 'StringLiteral' || node.concept === 'StringInterpolation' || node.concept === 'BooleanLiteral' || node.concept === 'NullLiteral') {
|
|
2438
2890
|
let type = 'String';
|
|
2439
2891
|
switch (node.concept) {
|
|
2440
2892
|
case 'NullLiteral':
|
|
@@ -2544,6 +2996,9 @@ export class NaslServer {
|
|
|
2544
2996
|
'NewComposite',
|
|
2545
2997
|
'NewList',
|
|
2546
2998
|
'NewMap',
|
|
2999
|
+
'OqlQueryComponent',
|
|
3000
|
+
'QueryFieldExpression',
|
|
3001
|
+
'QueryGroupByExpression',
|
|
2547
3002
|
].includes(node.concept))
|
|
2548
3003
|
return;
|
|
2549
3004
|
// 要去ls那边获取的
|
|
@@ -2575,7 +3030,7 @@ export class NaslServer {
|
|
|
2575
3030
|
indexOf = subStr.length - lastLen;
|
|
2576
3031
|
}
|
|
2577
3032
|
fileDetail.offset = fileDetail.offset + indexOf;
|
|
2578
|
-
} else if (node.concept === 'MemberExpression' || node.concept === 'Identifier') {
|
|
3033
|
+
} else if (node.concept === 'MemberExpression' || node.concept === 'Identifier' || node.concept === 'QueryFieldExpression' || node.concept === 'QueryGroupByExpression') {
|
|
2579
3034
|
if (item.code.includes('.')) {
|
|
2580
3035
|
const codeArr = item.code?.split('.');
|
|
2581
3036
|
const lastLen = codeArr?.[codeArr.length - 1]?.length;
|
|
@@ -2585,7 +3040,11 @@ export class NaslServer {
|
|
|
2585
3040
|
}
|
|
2586
3041
|
} else if (node.concept === 'Match') {
|
|
2587
3042
|
// 去查return 后面的返回值,变成函数调用
|
|
2588
|
-
|
|
3043
|
+
if (item.code?.endsWith(';\n')) {
|
|
3044
|
+
fileDetail.line = item.range.end.line - 1;
|
|
3045
|
+
} else {
|
|
3046
|
+
fileDetail.line = item.range.end.line;
|
|
3047
|
+
}
|
|
2589
3048
|
const indexOf = item.code.indexOf('return __MatchExpressionFuntion');
|
|
2590
3049
|
let newCode = item.code.substring(0, indexOf);
|
|
2591
3050
|
newCode = newCode.substring(newCode.lastIndexOf('\n'), indexOf);
|
|
@@ -2596,6 +3055,8 @@ export class NaslServer {
|
|
|
2596
3055
|
let newCode = item.code.substring(0, indexOf);
|
|
2597
3056
|
newCode = newCode.substring(newCode.lastIndexOf('\n'), indexOf);
|
|
2598
3057
|
fileDetail.offset = newCode.length + 'return '.length;
|
|
3058
|
+
} else if (['OqlQueryComponent'].includes(node.concept)) {
|
|
3059
|
+
fileDetail.offset += 10;
|
|
2599
3060
|
}
|
|
2600
3061
|
args.push(fileDetail);
|
|
2601
3062
|
});
|
|
@@ -2635,8 +3096,8 @@ export class NaslServer {
|
|
|
2635
3096
|
// 直接从最后一项的返回值取,有就有没有就没有
|
|
2636
3097
|
if (node.body?.length) {
|
|
2637
3098
|
const last = node.body[node.body.length - 1];
|
|
2638
|
-
if (last
|
|
2639
|
-
types.set(node, last
|
|
3099
|
+
if (types.get(last)) {
|
|
3100
|
+
types.set(node, types.get(last));
|
|
2640
3101
|
}
|
|
2641
3102
|
}
|
|
2642
3103
|
}
|
|
@@ -2648,11 +3109,27 @@ export class NaslServer {
|
|
|
2648
3109
|
// 因为node可能是经过处理的TypeAnnotation
|
|
2649
3110
|
node.__isCorrectTypeAnnotation = true;
|
|
2650
3111
|
if (value) {
|
|
3112
|
+
if (node instanceof OqlQueryComponent) {
|
|
3113
|
+
// 自动推导情况
|
|
3114
|
+
const typeAnnotation = value as TypeAnnotation;
|
|
3115
|
+
if (!node.typeAnnotation && typeAnnotation) {
|
|
3116
|
+
if (typeAnnotation.typeName === 'List' && typeAnnotation.typeKind === 'generic') {
|
|
3117
|
+
const typeArguments = typeAnnotation.typeArguments;
|
|
3118
|
+
if (typeArguments.length && typeArguments[0].isComplexType()) {
|
|
3119
|
+
node.__TypeAnnotation = null;
|
|
3120
|
+
return;
|
|
3121
|
+
}
|
|
3122
|
+
}
|
|
3123
|
+
}
|
|
3124
|
+
}
|
|
2651
3125
|
if (value instanceof TypeAnnotation) {
|
|
2652
3126
|
node.__TypeAnnotation = (Object.freeze(value) as TypeAnnotation);
|
|
2653
3127
|
} else if (value.typeAnnotation) {
|
|
2654
3128
|
node.__TypeAnnotation = (Object.freeze(value.typeAnnotation) as TypeAnnotation);
|
|
2655
3129
|
}
|
|
3130
|
+
} else {
|
|
3131
|
+
// 清空原来已经赋值上去的类型,可能原来有现在没有了
|
|
3132
|
+
node.__TypeAnnotation = null;
|
|
2656
3133
|
}
|
|
2657
3134
|
} catch (err) {
|
|
2658
3135
|
if (globalThis.window) {
|
|
@@ -2878,6 +3355,10 @@ export class NaslServer {
|
|
|
2878
3355
|
jsonNode.typeAnnotation = (value as TypeAnnotation).toJSON();
|
|
2879
3356
|
}
|
|
2880
3357
|
}
|
|
3358
|
+
if (node instanceof NewComposite && node.typeAnnotation.typeKind === 'anonymousStructure') {
|
|
3359
|
+
const jsonNode = jsoner.queryNodeByPath(json, node.getNodePath(false));
|
|
3360
|
+
jsonNode.typeAnnotation = (value as TypeAnnotation).toJSON();
|
|
3361
|
+
}
|
|
2881
3362
|
});
|
|
2882
3363
|
}
|
|
2883
3364
|
|
|
@@ -3023,6 +3504,13 @@ export class NaslServer {
|
|
|
3023
3504
|
// 如果是要删除的内容,就是当前的file节点,要关闭当前文件,就把内容置为空
|
|
3024
3505
|
if (fileNode === targetNode) {
|
|
3025
3506
|
outputFiles = [{ file: filePath, fileContent: '' }];
|
|
3507
|
+
|
|
3508
|
+
// 去掉原来存储的当前节点的nasl内存的存储,和错误的存储
|
|
3509
|
+
// 已经删除的就不用在去check错误了
|
|
3510
|
+
// check就会去取类型啥的,没有必要
|
|
3511
|
+
this.diagnosticManager.deleteOwn(fileNode.id);
|
|
3512
|
+
// 删除文件同时删除ls存储nasl 的引用
|
|
3513
|
+
this.file2NodeMap.delete(filePath);
|
|
3026
3514
|
} else {
|
|
3027
3515
|
// 如果是要删除logic一个小内容,要覆盖全部内容
|
|
3028
3516
|
// 其余要删除的都是把原来的file节点的内容全部覆盖一把
|
|
@@ -3054,13 +3542,17 @@ export class NaslServer {
|
|
|
3054
3542
|
offset: EmbeddedTSFileOffsetMap[fileNode.concept] ?? 6,
|
|
3055
3543
|
});
|
|
3056
3544
|
|
|
3057
|
-
|
|
3545
|
+
const files = new Set();
|
|
3546
|
+
newRefs.refs.forEach((ref) => {
|
|
3547
|
+
this.filesToCheck.add(ref.file);
|
|
3548
|
+
files.add(ref.file);
|
|
3549
|
+
});
|
|
3058
3550
|
// 唤起建立连接弹框
|
|
3059
3551
|
// 文件级别的建立连接采取提醒
|
|
3060
3552
|
if (action === 'create' && (targetNode as any).__init) {
|
|
3061
3553
|
// 清除临时状态, 完成本次创建
|
|
3062
3554
|
delete (targetNode as any).__init;
|
|
3063
|
-
if (fileNode === targetNode &&
|
|
3555
|
+
if (fileNode === targetNode && files.size > 1) {
|
|
3064
3556
|
const confirmParms = {
|
|
3065
3557
|
actionType: 'createEstablishConnection',
|
|
3066
3558
|
node: fileNode,
|