@flow-scanner/lightning-flow-scanner-core 6.17.1 → 6.17.3
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/README.md +642 -0
- package/{types/main → main}/models/FlowGraph.d.ts +11 -1
- package/{out/main → main}/models/FlowGraph.js +18 -7
- package/{out/main → main}/rules/MissingRecordTriggerFilter.js +4 -2
- package/package.json +9 -58
- package/.husky/pre-commit +0 -1
- package/.husky/pre-push +0 -1
- package/.prettierignore +0 -5
- package/.swcrc +0 -26
- package/.turbo/turbo-build.log +0 -17
- package/.turbo/turbo-test.log +0 -144
- package/.turbo/turbo-vite$colon$dist.log +0 -21
- package/coverage/coverage-final.json +0 -63
- package/coverage/lcov-report/base.css +0 -224
- package/coverage/lcov-report/block-navigation.js +0 -87
- package/coverage/lcov-report/favicon.png +0 -0
- package/coverage/lcov-report/index.html +0 -236
- package/coverage/lcov-report/prettify.css +0 -1
- package/coverage/lcov-report/prettify.js +0 -2
- package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
- package/coverage/lcov-report/sorter.js +0 -210
- package/coverage/lcov-report/src/index.html +0 -116
- package/coverage/lcov-report/src/index.ts.html +0 -238
- package/coverage/lcov-report/src/main/adapters/RegexAdapter.ts.html +0 -118
- package/coverage/lcov-report/src/main/adapters/index.html +0 -116
- package/coverage/lcov-report/src/main/config/NodeIcons.ts.html +0 -376
- package/coverage/lcov-report/src/main/config/RuleRegistry.ts.html +0 -646
- package/coverage/lcov-report/src/main/config/VariableIcons.ts.html +0 -253
- package/coverage/lcov-report/src/main/config/index.html +0 -146
- package/coverage/lcov-report/src/main/enums/MetaType.ts.html +0 -100
- package/coverage/lcov-report/src/main/enums/MetadataType.ts.html +0 -103
- package/coverage/lcov-report/src/main/enums/MetadataTypes.ts.html +0 -100
- package/coverage/lcov-report/src/main/enums/index.html +0 -116
- package/coverage/lcov-report/src/main/interfaces/IRulesConfig.ts.html +0 -133
- package/coverage/lcov-report/src/main/interfaces/index.html +0 -116
- package/coverage/lcov-report/src/main/internals/index.html +0 -116
- package/coverage/lcov-report/src/main/internals/internals.ts.html +0 -190
- package/coverage/lcov-report/src/main/libs/BuildFlow.ts.html +0 -127
- package/coverage/lcov-report/src/main/libs/Compiler.ts.html +0 -241
- package/coverage/lcov-report/src/main/libs/ConvertFlowNodes.ts.html +0 -97
- package/coverage/lcov-report/src/main/libs/DynamicRule.ts.html +0 -118
- package/coverage/lcov-report/src/main/libs/ExportDetails.ts.html +0 -256
- package/coverage/lcov-report/src/main/libs/ExportDiagram.ts.html +0 -331
- package/coverage/lcov-report/src/main/libs/ExportSarif.ts.html +0 -358
- package/coverage/lcov-report/src/main/libs/FixFlows.ts.html +0 -265
- package/coverage/lcov-report/src/main/libs/GenerateMarkdown.ts.html +0 -331
- package/coverage/lcov-report/src/main/libs/GetRuleDefinitions.ts.html +0 -274
- package/coverage/lcov-report/src/main/libs/ParseFlows.ts.html +0 -184
- package/coverage/lcov-report/src/main/libs/RuleDocumentation.ts.html +0 -190
- package/coverage/lcov-report/src/main/libs/ScanFlows.ts.html +0 -508
- package/coverage/lcov-report/src/main/libs/exportAsDetails.ts.html +0 -160
- package/coverage/lcov-report/src/main/libs/exportAsSarif.ts.html +0 -346
- package/coverage/lcov-report/src/main/libs/index.html +0 -251
- package/coverage/lcov-report/src/main/models/FlatViolation.ts.html +0 -106
- package/coverage/lcov-report/src/main/models/Flow.ts.html +0 -1057
- package/coverage/lcov-report/src/main/models/FlowAttribute.ts.html +0 -115
- package/coverage/lcov-report/src/main/models/FlowElement.ts.html +0 -133
- package/coverage/lcov-report/src/main/models/FlowElementConnector.ts.html +0 -169
- package/coverage/lcov-report/src/main/models/FlowGraph.ts.html +0 -1672
- package/coverage/lcov-report/src/main/models/FlowMetadata.ts.html +0 -106
- package/coverage/lcov-report/src/main/models/FlowNode.ts.html +0 -1252
- package/coverage/lcov-report/src/main/models/FlowResource.ts.html +0 -106
- package/coverage/lcov-report/src/main/models/FlowType.ts.html +0 -244
- package/coverage/lcov-report/src/main/models/FlowVariable.ts.html +0 -553
- package/coverage/lcov-report/src/main/models/LoopRuleCommon.ts.html +0 -235
- package/coverage/lcov-report/src/main/models/ParsedFlow.ts.html +0 -121
- package/coverage/lcov-report/src/main/models/RuleCommon.ts.html +0 -442
- package/coverage/lcov-report/src/main/models/RuleResult.ts.html +0 -172
- package/coverage/lcov-report/src/main/models/ScanResult.ts.html +0 -121
- package/coverage/lcov-report/src/main/models/Violation.ts.html +0 -316
- package/coverage/lcov-report/src/main/models/index.html +0 -341
- package/coverage/lcov-report/src/main/rules/APIVersion.ts.html +0 -361
- package/coverage/lcov-report/src/main/rules/ActionCallsInLoop.ts.html +0 -157
- package/coverage/lcov-report/src/main/rules/AutoLayout.ts.html +0 -220
- package/coverage/lcov-report/src/main/rules/CopyAPIName.ts.html +0 -175
- package/coverage/lcov-report/src/main/rules/CyclomaticComplexity.ts.html +0 -292
- package/coverage/lcov-report/src/main/rules/DMLStatementInLoop.ts.html +0 -163
- package/coverage/lcov-report/src/main/rules/DuplicateDMLOperation.ts.html +0 -334
- package/coverage/lcov-report/src/main/rules/FlowDescription.ts.html +0 -184
- package/coverage/lcov-report/src/main/rules/FlowName.ts.html +0 -229
- package/coverage/lcov-report/src/main/rules/GetRecordAllFields.ts.html +0 -280
- package/coverage/lcov-report/src/main/rules/HardcodedId.ts.html +0 -238
- package/coverage/lcov-report/src/main/rules/HardcodedSecret.ts.html +0 -238
- package/coverage/lcov-report/src/main/rules/HardcodedUrl.ts.html +0 -247
- package/coverage/lcov-report/src/main/rules/InactiveFlow.ts.html +0 -184
- package/coverage/lcov-report/src/main/rules/MissingFaultPath.ts.html +0 -397
- package/coverage/lcov-report/src/main/rules/MissingFilterRecordTrigger.ts.html +0 -229
- package/coverage/lcov-report/src/main/rules/MissingMetadataDescription.ts.html +0 -211
- package/coverage/lcov-report/src/main/rules/MissingNullHandler.ts.html +0 -460
- package/coverage/lcov-report/src/main/rules/MissingRecordTriggerFilter.ts.html +0 -235
- package/coverage/lcov-report/src/main/rules/ProcessBuilder.ts.html +0 -190
- package/coverage/lcov-report/src/main/rules/RecordIdAsString.ts.html +0 -274
- package/coverage/lcov-report/src/main/rules/RecursiveAfterUpdate.ts.html +0 -364
- package/coverage/lcov-report/src/main/rules/SOQLQueryInLoop.ts.html +0 -160
- package/coverage/lcov-report/src/main/rules/SameRecordFieldUpdates.ts.html +0 -283
- package/coverage/lcov-report/src/main/rules/TransformInsteadOfLoop.ts.html +0 -250
- package/coverage/lcov-report/src/main/rules/TriggerOrder.ts.html +0 -238
- package/coverage/lcov-report/src/main/rules/UnconnectedElement.ts.html +0 -178
- package/coverage/lcov-report/src/main/rules/UnsafeRunningContext.ts.html +0 -226
- package/coverage/lcov-report/src/main/rules/UnusedVariable.ts.html +0 -283
- package/coverage/lcov-report/src/main/rules/index.html +0 -521
- package/coverage/lcov-report/src/main/store/DefaultRuleStore.ts.html +0 -265
- package/coverage/lcov-report/src/main/store/RuleRegistry.ts.html +0 -118
- package/coverage/lcov-report/src/main/store/index.html +0 -116
- package/coverage/lcov.info +0 -6261
- package/eslint.config.mjs +0 -36
- package/jest.config.cjs +0 -32
- package/jest.env-setup.js +0 -101
- package/lint-staged.config.mjs +0 -8
- package/out/main/models/FlowGraph.d.ts +0 -85
- package/prettier.config.mjs +0 -5
- package/src/index.ts +0 -52
- package/src/main/config/NodeIcons.ts +0 -98
- package/src/main/config/RegexAdapter.ts +0 -98
- package/src/main/config/RuleRegistry.ts +0 -188
- package/src/main/config/VariableIcons.ts +0 -57
- package/src/main/enums/MetadataTypes.ts +0 -6
- package/src/main/interfaces/IExceptions.ts +0 -6
- package/src/main/interfaces/IRuleConfig.ts +0 -6
- package/src/main/interfaces/IRuleDefinition.ts +0 -15
- package/src/main/interfaces/IRuleOptions.ts +0 -5
- package/src/main/interfaces/IRulesConfig.ts +0 -17
- package/src/main/internals/internals.ts +0 -35
- package/src/main/libs/BuildFlow.ts +0 -14
- package/src/main/libs/Compiler.ts +0 -53
- package/src/main/libs/ExportDetails.ts +0 -58
- package/src/main/libs/ExportDiagram.ts +0 -83
- package/src/main/libs/ExportSarif.ts +0 -92
- package/src/main/libs/FixFlows.ts +0 -61
- package/src/main/libs/GetRuleDefinitions.ts +0 -64
- package/src/main/libs/ParseFlows.ts +0 -34
- package/src/main/libs/RuleDocumentation.ts +0 -35
- package/src/main/libs/ScanFlows.ts +0 -142
- package/src/main/models/FlatViolation.ts +0 -16
- package/src/main/models/Flow.ts +0 -325
- package/src/main/models/FlowAttribute.ts +0 -11
- package/src/main/models/FlowElement.ts +0 -16
- package/src/main/models/FlowElementConnector.ts +0 -28
- package/src/main/models/FlowGraph.ts +0 -530
- package/src/main/models/FlowMetadata.ts +0 -8
- package/src/main/models/FlowNode.ts +0 -390
- package/src/main/models/FlowResource.ts +0 -8
- package/src/main/models/FlowType.ts +0 -53
- package/src/main/models/FlowVariable.ts +0 -157
- package/src/main/models/LoopRuleCommon.ts +0 -51
- package/src/main/models/ParsedFlow.ts +0 -13
- package/src/main/models/RuleCommon.ts +0 -120
- package/src/main/models/RuleInfo.ts +0 -54
- package/src/main/models/RuleResult.ts +0 -29
- package/src/main/models/ScanResult.ts +0 -12
- package/src/main/models/Violation.ts +0 -78
- package/src/main/rules/APIVersion.ts +0 -93
- package/src/main/rules/ActionCallsInLoop.ts +0 -25
- package/src/main/rules/AutoLayout.ts +0 -46
- package/src/main/rules/CopyAPIName.ts +0 -31
- package/src/main/rules/CyclomaticComplexity.ts +0 -70
- package/src/main/rules/DMLStatementInLoop.ts +0 -26
- package/src/main/rules/DuplicateDMLOperation.ts +0 -83
- package/src/main/rules/FlowDescription.ts +0 -34
- package/src/main/rules/FlowName.ts +0 -49
- package/src/main/rules/GetRecordAllFields.ts +0 -65
- package/src/main/rules/HardcodedId.ts +0 -51
- package/src/main/rules/HardcodedSecret.ts +0 -51
- package/src/main/rules/HardcodedUrl.ts +0 -54
- package/src/main/rules/InactiveFlow.ts +0 -33
- package/src/main/rules/MissingFaultPath.ts +0 -105
- package/src/main/rules/MissingMetadataDescription.ts +0 -42
- package/src/main/rules/MissingNullHandler.ts +0 -126
- package/src/main/rules/MissingRecordTriggerFilter.ts +0 -51
- package/src/main/rules/ProcessBuilder.ts +0 -35
- package/src/main/rules/RecordIdAsString.ts +0 -64
- package/src/main/rules/RecursiveAfterUpdate.ts +0 -94
- package/src/main/rules/SOQLQueryInLoop.ts +0 -26
- package/src/main/rules/SameRecordFieldUpdates.ts +0 -66
- package/src/main/rules/TransformInsteadOfLoop.ts +0 -56
- package/src/main/rules/TriggerOrder.ts +0 -51
- package/src/main/rules/UnconnectedElement.ts +0 -32
- package/src/main/rules/UnsafeRunningContext.ts +0 -47
- package/src/main/rules/UnusedVariable.ts +0 -66
- package/stryker.config.mjs +0 -23
- package/tests/APIVersion.test.ts +0 -87
- package/tests/AutoLayout.test.ts +0 -41
- package/tests/Config.test.ts +0 -122
- package/tests/ConfigBetaMode.test.ts +0 -26
- package/tests/CopyAPIName.test.ts +0 -45
- package/tests/CyclomaticComplexity.test.ts +0 -125
- package/tests/DMLStatementInLoop.test.ts +0 -32
- package/tests/DuplicateDMLOperation.test.ts +0 -43
- package/tests/EnabledFalse.test.ts +0 -63
- package/tests/Exceptions.test.ts +0 -815
- package/tests/ExportSarif.test.ts +0 -62
- package/tests/FlowDescription.test.ts +0 -44
- package/tests/FlowDocumentation.test.ts +0 -74
- package/tests/FlowName.test.ts +0 -61
- package/tests/GetRecordElementAllFields.test.ts +0 -182
- package/tests/HardcodedId.test.ts +0 -16
- package/tests/HardcodedSecret.test.ts +0 -32
- package/tests/HardcodedUrl.test.ts +0 -253
- package/tests/InactiveFlow.test.ts +0 -103
- package/tests/MissingFaultPath.test.ts +0 -52
- package/tests/MissingMetadataDescription.test.ts +0 -25
- package/tests/MissingNullHandler.test.ts +0 -45
- package/tests/MissingRecordTriggerFilter.test.ts +0 -54
- package/tests/RecordIdAsString.test.ts +0 -60
- package/tests/RecursiveAfterUpdate.test.ts +0 -183
- package/tests/SOQLQueryInLoop.test.ts +0 -33
- package/tests/SameRecordFieldUpdates.test.ts +0 -205
- package/tests/SanityTest.test.ts +0 -15
- package/tests/TransformInsteadOfLoop.test.ts +0 -33
- package/tests/TriggerOrder.test.ts +0 -112
- package/tests/UnconnectedElement.test.ts +0 -76
- package/tests/UnsafeRunningContext.test.ts +0 -46
- package/tests/UnusedVariable.test.ts +0 -59
- package/tests/UnusedVariableExceptions.test.ts +0 -87
- package/tests/jsonfiles/MissingFaultPath_BeforeSave_Bypass.json +0 -128
- package/tests/jsonfiles/MissingFaultPath_WaitConditions.json +0 -102
- package/tests/jsonfiles/MissingFaultPath_WaitDate.json +0 -88
- package/tests/jsonfiles/MissingFaultPath_WaitDuration.json +0 -90
- package/tests/models/Flow.test.ts +0 -107
- package/tests/models/LoopRuleCommon.test.ts +0 -246
- package/tests/models/RuleCommon.test.ts +0 -41
- package/tsconfig.json +0 -28
- package/tsconfig.types.json +0 -26
- package/types/index.d.ts +0 -27
- package/types/index.d.ts.map +0 -1
- package/types/main/adapters/RegexAdapter.d.ts +0 -33
- package/types/main/adapters/RegexAdapter.d.ts.map +0 -1
- package/types/main/config/NodeIcons.d.ts +0 -25
- package/types/main/config/NodeIcons.d.ts.map +0 -1
- package/types/main/config/RegexAdapter.d.ts +0 -33
- package/types/main/config/RegexAdapter.d.ts.map +0 -1
- package/types/main/config/RuleRegistry.d.ts +0 -23
- package/types/main/config/RuleRegistry.d.ts.map +0 -1
- package/types/main/config/VariableIcons.d.ts +0 -26
- package/types/main/config/VariableIcons.d.ts.map +0 -1
- package/types/main/enums/MetadataTypes.d.ts +0 -7
- package/types/main/enums/MetadataTypes.d.ts.map +0 -1
- package/types/main/interfaces/IExceptions.d.ts +0 -6
- package/types/main/interfaces/IExceptions.d.ts.map +0 -1
- package/types/main/interfaces/IRuleConfig.d.ts +0 -7
- package/types/main/interfaces/IRuleConfig.d.ts.map +0 -1
- package/types/main/interfaces/IRuleDefinition.d.ts +0 -18
- package/types/main/interfaces/IRuleDefinition.d.ts.map +0 -1
- package/types/main/interfaces/IRuleOptions.d.ts +0 -5
- package/types/main/interfaces/IRuleOptions.d.ts.map +0 -1
- package/types/main/interfaces/IRulesConfig.d.ts +0 -16
- package/types/main/interfaces/IRulesConfig.d.ts.map +0 -1
- package/types/main/internals/internals.d.ts +0 -19
- package/types/main/internals/internals.d.ts.map +0 -1
- package/types/main/libs/BuildFlow.d.ts +0 -2
- package/types/main/libs/BuildFlow.d.ts.map +0 -1
- package/types/main/libs/Compiler.d.ts +0 -8
- package/types/main/libs/Compiler.d.ts.map +0 -1
- package/types/main/libs/ConvertFlowNodes.d.ts +0 -2
- package/types/main/libs/ConvertFlowNodes.d.ts.map +0 -1
- package/types/main/libs/DynamicRule.d.ts +0 -5
- package/types/main/libs/DynamicRule.d.ts.map +0 -1
- package/types/main/libs/ExportDetails.d.ts +0 -4
- package/types/main/libs/ExportDetails.d.ts.map +0 -1
- package/types/main/libs/ExportDiagram.d.ts +0 -42
- package/types/main/libs/ExportDiagram.d.ts.map +0 -1
- package/types/main/libs/ExportSarif.d.ts +0 -3
- package/types/main/libs/ExportSarif.d.ts.map +0 -1
- package/types/main/libs/FixFlows.d.ts +0 -4
- package/types/main/libs/FixFlows.d.ts.map +0 -1
- package/types/main/libs/GetRuleDefinitions.d.ts +0 -5
- package/types/main/libs/GetRuleDefinitions.d.ts.map +0 -1
- package/types/main/libs/ParseFlows.d.ts +0 -3
- package/types/main/libs/ParseFlows.d.ts.map +0 -1
- package/types/main/libs/RuleDocumentation.d.ts +0 -21
- package/types/main/libs/RuleDocumentation.d.ts.map +0 -1
- package/types/main/libs/ScanFlows.d.ts +0 -5
- package/types/main/libs/ScanFlows.d.ts.map +0 -1
- package/types/main/libs/exportAsDetails.d.ts +0 -4
- package/types/main/libs/exportAsDetails.d.ts.map +0 -1
- package/types/main/libs/exportAsSarif.d.ts +0 -3
- package/types/main/libs/exportAsSarif.d.ts.map +0 -1
- package/types/main/models/FlatViolation.d.ts +0 -16
- package/types/main/models/FlatViolation.d.ts.map +0 -1
- package/types/main/models/Flow.d.ts +0 -70
- package/types/main/models/Flow.d.ts.map +0 -1
- package/types/main/models/FlowAttribute.d.ts +0 -6
- package/types/main/models/FlowAttribute.d.ts.map +0 -1
- package/types/main/models/FlowElement.d.ts +0 -11
- package/types/main/models/FlowElement.d.ts.map +0 -1
- package/types/main/models/FlowElementConnector.d.ts +0 -16
- package/types/main/models/FlowElementConnector.d.ts.map +0 -1
- package/types/main/models/FlowGraph.d.ts.map +0 -1
- package/types/main/models/FlowMetadata.d.ts +0 -5
- package/types/main/models/FlowMetadata.d.ts.map +0 -1
- package/types/main/models/FlowNode.d.ts +0 -66
- package/types/main/models/FlowNode.d.ts.map +0 -1
- package/types/main/models/FlowResource.d.ts +0 -5
- package/types/main/models/FlowResource.d.ts.map +0 -1
- package/types/main/models/FlowType.d.ts +0 -24
- package/types/main/models/FlowType.d.ts.map +0 -1
- package/types/main/models/FlowVariable.d.ts +0 -64
- package/types/main/models/FlowVariable.d.ts.map +0 -1
- package/types/main/models/LoopRuleCommon.d.ts +0 -15
- package/types/main/models/LoopRuleCommon.d.ts.map +0 -1
- package/types/main/models/ParsedFlow.d.ts +0 -8
- package/types/main/models/ParsedFlow.d.ts.map +0 -1
- package/types/main/models/RuleCommon.d.ts +0 -58
- package/types/main/models/RuleCommon.d.ts.map +0 -1
- package/types/main/models/RuleInfo.d.ts +0 -50
- package/types/main/models/RuleInfo.d.ts.map +0 -1
- package/types/main/models/RuleResult.d.ts +0 -15
- package/types/main/models/RuleResult.d.ts.map +0 -1
- package/types/main/models/ScanResult.d.ts +0 -8
- package/types/main/models/ScanResult.d.ts.map +0 -1
- package/types/main/models/Violation.d.ts +0 -12
- package/types/main/models/Violation.d.ts.map +0 -1
- package/types/main/rules/APIVersion.d.ts +0 -10
- package/types/main/rules/APIVersion.d.ts.map +0 -1
- package/types/main/rules/ActionCallsInLoop.d.ts +0 -7
- package/types/main/rules/ActionCallsInLoop.d.ts.map +0 -1
- package/types/main/rules/AutoLayout.d.ts +0 -8
- package/types/main/rules/AutoLayout.d.ts.map +0 -1
- package/types/main/rules/CopyAPIName.d.ts +0 -8
- package/types/main/rules/CopyAPIName.d.ts.map +0 -1
- package/types/main/rules/CyclomaticComplexity.d.ts +0 -12
- package/types/main/rules/CyclomaticComplexity.d.ts.map +0 -1
- package/types/main/rules/DMLStatementInLoop.d.ts +0 -7
- package/types/main/rules/DMLStatementInLoop.d.ts.map +0 -1
- package/types/main/rules/DuplicateDMLOperation.d.ts +0 -9
- package/types/main/rules/DuplicateDMLOperation.d.ts.map +0 -1
- package/types/main/rules/FlowDescription.d.ts +0 -8
- package/types/main/rules/FlowDescription.d.ts.map +0 -1
- package/types/main/rules/FlowName.d.ts +0 -16
- package/types/main/rules/FlowName.d.ts.map +0 -1
- package/types/main/rules/GetRecordAllFields.d.ts +0 -8
- package/types/main/rules/GetRecordAllFields.d.ts.map +0 -1
- package/types/main/rules/HardcodedId.d.ts +0 -14
- package/types/main/rules/HardcodedId.d.ts.map +0 -1
- package/types/main/rules/HardcodedSecret.d.ts +0 -14
- package/types/main/rules/HardcodedSecret.d.ts.map +0 -1
- package/types/main/rules/HardcodedUrl.d.ts +0 -14
- package/types/main/rules/HardcodedUrl.d.ts.map +0 -1
- package/types/main/rules/InactiveFlow.d.ts +0 -8
- package/types/main/rules/InactiveFlow.d.ts.map +0 -1
- package/types/main/rules/MissingFaultPath.d.ts +0 -15
- package/types/main/rules/MissingFaultPath.d.ts.map +0 -1
- package/types/main/rules/MissingFilterRecordTrigger.d.ts +0 -8
- package/types/main/rules/MissingFilterRecordTrigger.d.ts.map +0 -1
- package/types/main/rules/MissingMetadataDescription.d.ts +0 -8
- package/types/main/rules/MissingMetadataDescription.d.ts.map +0 -1
- package/types/main/rules/MissingNullHandler.d.ts +0 -8
- package/types/main/rules/MissingNullHandler.d.ts.map +0 -1
- package/types/main/rules/MissingRecordTriggerFilter.d.ts +0 -8
- package/types/main/rules/MissingRecordTriggerFilter.d.ts.map +0 -1
- package/types/main/rules/ProcessBuilder.d.ts +0 -8
- package/types/main/rules/ProcessBuilder.d.ts.map +0 -1
- package/types/main/rules/RecordIdAsString.d.ts +0 -8
- package/types/main/rules/RecordIdAsString.d.ts.map +0 -1
- package/types/main/rules/RecursiveAfterUpdate.d.ts +0 -9
- package/types/main/rules/RecursiveAfterUpdate.d.ts.map +0 -1
- package/types/main/rules/SOQLQueryInLoop.d.ts +0 -7
- package/types/main/rules/SOQLQueryInLoop.d.ts.map +0 -1
- package/types/main/rules/SameRecordFieldUpdates.d.ts +0 -9
- package/types/main/rules/SameRecordFieldUpdates.d.ts.map +0 -1
- package/types/main/rules/TransformInsteadOfLoop.d.ts +0 -8
- package/types/main/rules/TransformInsteadOfLoop.d.ts.map +0 -1
- package/types/main/rules/TriggerOrder.d.ts +0 -8
- package/types/main/rules/TriggerOrder.d.ts.map +0 -1
- package/types/main/rules/UnconnectedElement.d.ts +0 -8
- package/types/main/rules/UnconnectedElement.d.ts.map +0 -1
- package/types/main/rules/UnsafeRunningContext.d.ts +0 -8
- package/types/main/rules/UnsafeRunningContext.d.ts.map +0 -1
- package/types/main/rules/UnusedVariable.d.ts +0 -8
- package/types/main/rules/UnusedVariable.d.ts.map +0 -1
- package/types/main/store/DefaultRuleStore.d.ts +0 -3
- package/types/main/store/DefaultRuleStore.d.ts.map +0 -1
- package/types/main/store/RuleRegistry.d.ts +0 -23
- package/types/main/store/RuleRegistry.d.ts.map +0 -1
- package/vite.config.ts +0 -33
- /package/{out/index.d.ts → index.d.ts} +0 -0
- /package/{out/index.js → index.js} +0 -0
- /package/{out/main → main}/config/NodeIcons.d.ts +0 -0
- /package/{out/main → main}/config/NodeIcons.js +0 -0
- /package/{out/main → main}/config/RegexAdapter.d.ts +0 -0
- /package/{out/main → main}/config/RegexAdapter.js +0 -0
- /package/{out/main → main}/config/RuleRegistry.d.ts +0 -0
- /package/{out/main → main}/config/RuleRegistry.js +0 -0
- /package/{out/main → main}/config/VariableIcons.d.ts +0 -0
- /package/{out/main → main}/config/VariableIcons.js +0 -0
- /package/{out/main → main}/enums/MetadataTypes.d.ts +0 -0
- /package/{out/main → main}/enums/MetadataTypes.js +0 -0
- /package/{out/main → main}/interfaces/IExceptions.d.ts +0 -0
- /package/{out/main → main}/interfaces/IExceptions.js +0 -0
- /package/{out/main → main}/interfaces/IRuleConfig.d.ts +0 -0
- /package/{out/main → main}/interfaces/IRuleConfig.js +0 -0
- /package/{out/main → main}/interfaces/IRuleDefinition.d.ts +0 -0
- /package/{out/main → main}/interfaces/IRuleDefinition.js +0 -0
- /package/{out/main → main}/interfaces/IRuleOptions.d.ts +0 -0
- /package/{out/main → main}/interfaces/IRuleOptions.js +0 -0
- /package/{out/main → main}/interfaces/IRulesConfig.d.ts +0 -0
- /package/{out/main → main}/interfaces/IRulesConfig.js +0 -0
- /package/{out/main → main}/internals/internals.d.ts +0 -0
- /package/{out/main → main}/internals/internals.js +0 -0
- /package/{out/main → main}/libs/BuildFlow.d.ts +0 -0
- /package/{out/main → main}/libs/BuildFlow.js +0 -0
- /package/{out/main → main}/libs/Compiler.d.ts +0 -0
- /package/{out/main → main}/libs/Compiler.js +0 -0
- /package/{out/main → main}/libs/ExportDetails.d.ts +0 -0
- /package/{out/main → main}/libs/ExportDetails.js +0 -0
- /package/{out/main → main}/libs/ExportDiagram.d.ts +0 -0
- /package/{out/main → main}/libs/ExportDiagram.js +0 -0
- /package/{out/main → main}/libs/ExportSarif.d.ts +0 -0
- /package/{out/main → main}/libs/ExportSarif.js +0 -0
- /package/{out/main → main}/libs/FixFlows.d.ts +0 -0
- /package/{out/main → main}/libs/FixFlows.js +0 -0
- /package/{out/main → main}/libs/GetRuleDefinitions.d.ts +0 -0
- /package/{out/main → main}/libs/GetRuleDefinitions.js +0 -0
- /package/{out/main → main}/libs/ParseFlows.d.ts +0 -0
- /package/{out/main → main}/libs/ParseFlows.js +0 -0
- /package/{out/main → main}/libs/RuleDocumentation.d.ts +0 -0
- /package/{out/main → main}/libs/RuleDocumentation.js +0 -0
- /package/{out/main → main}/libs/ScanFlows.d.ts +0 -0
- /package/{out/main → main}/libs/ScanFlows.js +0 -0
- /package/{out/main → main}/models/FlatViolation.d.ts +0 -0
- /package/{out/main → main}/models/FlatViolation.js +0 -0
- /package/{out/main → main}/models/Flow.d.ts +0 -0
- /package/{out/main → main}/models/Flow.js +0 -0
- /package/{out/main → main}/models/FlowAttribute.d.ts +0 -0
- /package/{out/main → main}/models/FlowAttribute.js +0 -0
- /package/{out/main → main}/models/FlowElement.d.ts +0 -0
- /package/{out/main → main}/models/FlowElement.js +0 -0
- /package/{out/main → main}/models/FlowElementConnector.d.ts +0 -0
- /package/{out/main → main}/models/FlowElementConnector.js +0 -0
- /package/{out/main → main}/models/FlowMetadata.d.ts +0 -0
- /package/{out/main → main}/models/FlowMetadata.js +0 -0
- /package/{out/main → main}/models/FlowNode.d.ts +0 -0
- /package/{out/main → main}/models/FlowNode.js +0 -0
- /package/{out/main → main}/models/FlowResource.d.ts +0 -0
- /package/{out/main → main}/models/FlowResource.js +0 -0
- /package/{out/main → main}/models/FlowType.d.ts +0 -0
- /package/{out/main → main}/models/FlowType.js +0 -0
- /package/{out/main → main}/models/FlowVariable.d.ts +0 -0
- /package/{out/main → main}/models/FlowVariable.js +0 -0
- /package/{out/main → main}/models/LoopRuleCommon.d.ts +0 -0
- /package/{out/main → main}/models/LoopRuleCommon.js +0 -0
- /package/{out/main → main}/models/ParsedFlow.d.ts +0 -0
- /package/{out/main → main}/models/ParsedFlow.js +0 -0
- /package/{out/main → main}/models/RuleCommon.d.ts +0 -0
- /package/{out/main → main}/models/RuleCommon.js +0 -0
- /package/{out/main → main}/models/RuleInfo.d.ts +0 -0
- /package/{out/main → main}/models/RuleInfo.js +0 -0
- /package/{out/main → main}/models/RuleResult.d.ts +0 -0
- /package/{out/main → main}/models/RuleResult.js +0 -0
- /package/{out/main → main}/models/ScanResult.d.ts +0 -0
- /package/{out/main → main}/models/ScanResult.js +0 -0
- /package/{out/main → main}/models/Violation.d.ts +0 -0
- /package/{out/main → main}/models/Violation.js +0 -0
- /package/{out/main → main}/rules/APIVersion.d.ts +0 -0
- /package/{out/main → main}/rules/APIVersion.js +0 -0
- /package/{out/main → main}/rules/ActionCallsInLoop.d.ts +0 -0
- /package/{out/main → main}/rules/ActionCallsInLoop.js +0 -0
- /package/{out/main → main}/rules/AutoLayout.d.ts +0 -0
- /package/{out/main → main}/rules/AutoLayout.js +0 -0
- /package/{out/main → main}/rules/CopyAPIName.d.ts +0 -0
- /package/{out/main → main}/rules/CopyAPIName.js +0 -0
- /package/{out/main → main}/rules/CyclomaticComplexity.d.ts +0 -0
- /package/{out/main → main}/rules/CyclomaticComplexity.js +0 -0
- /package/{out/main → main}/rules/DMLStatementInLoop.d.ts +0 -0
- /package/{out/main → main}/rules/DMLStatementInLoop.js +0 -0
- /package/{out/main → main}/rules/DuplicateDMLOperation.d.ts +0 -0
- /package/{out/main → main}/rules/DuplicateDMLOperation.js +0 -0
- /package/{out/main → main}/rules/FlowDescription.d.ts +0 -0
- /package/{out/main → main}/rules/FlowDescription.js +0 -0
- /package/{out/main → main}/rules/FlowName.d.ts +0 -0
- /package/{out/main → main}/rules/FlowName.js +0 -0
- /package/{out/main → main}/rules/GetRecordAllFields.d.ts +0 -0
- /package/{out/main → main}/rules/GetRecordAllFields.js +0 -0
- /package/{out/main → main}/rules/HardcodedId.d.ts +0 -0
- /package/{out/main → main}/rules/HardcodedId.js +0 -0
- /package/{out/main → main}/rules/HardcodedSecret.d.ts +0 -0
- /package/{out/main → main}/rules/HardcodedSecret.js +0 -0
- /package/{out/main → main}/rules/HardcodedUrl.d.ts +0 -0
- /package/{out/main → main}/rules/HardcodedUrl.js +0 -0
- /package/{out/main → main}/rules/InactiveFlow.d.ts +0 -0
- /package/{out/main → main}/rules/InactiveFlow.js +0 -0
- /package/{out/main → main}/rules/MissingFaultPath.d.ts +0 -0
- /package/{out/main → main}/rules/MissingFaultPath.js +0 -0
- /package/{out/main → main}/rules/MissingMetadataDescription.d.ts +0 -0
- /package/{out/main → main}/rules/MissingMetadataDescription.js +0 -0
- /package/{out/main → main}/rules/MissingNullHandler.d.ts +0 -0
- /package/{out/main → main}/rules/MissingNullHandler.js +0 -0
- /package/{out/main → main}/rules/MissingRecordTriggerFilter.d.ts +0 -0
- /package/{out/main → main}/rules/ProcessBuilder.d.ts +0 -0
- /package/{out/main → main}/rules/ProcessBuilder.js +0 -0
- /package/{out/main → main}/rules/RecordIdAsString.d.ts +0 -0
- /package/{out/main → main}/rules/RecordIdAsString.js +0 -0
- /package/{out/main → main}/rules/RecursiveAfterUpdate.d.ts +0 -0
- /package/{out/main → main}/rules/RecursiveAfterUpdate.js +0 -0
- /package/{out/main → main}/rules/SOQLQueryInLoop.d.ts +0 -0
- /package/{out/main → main}/rules/SOQLQueryInLoop.js +0 -0
- /package/{out/main → main}/rules/SameRecordFieldUpdates.d.ts +0 -0
- /package/{out/main → main}/rules/SameRecordFieldUpdates.js +0 -0
- /package/{out/main → main}/rules/TransformInsteadOfLoop.d.ts +0 -0
- /package/{out/main → main}/rules/TransformInsteadOfLoop.js +0 -0
- /package/{out/main → main}/rules/TriggerOrder.d.ts +0 -0
- /package/{out/main → main}/rules/TriggerOrder.js +0 -0
- /package/{out/main → main}/rules/UnconnectedElement.d.ts +0 -0
- /package/{out/main → main}/rules/UnconnectedElement.js +0 -0
- /package/{out/main → main}/rules/UnsafeRunningContext.d.ts +0 -0
- /package/{out/main → main}/rules/UnsafeRunningContext.js +0 -0
- /package/{out/main → main}/rules/UnusedVariable.d.ts +0 -0
- /package/{out/main → main}/rules/UnusedVariable.js +0 -0
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
import * as core from "../internals/internals";
|
|
2
|
-
import { BuildFlow } from "./BuildFlow";
|
|
3
|
-
|
|
4
|
-
export function fix(results: core.ScanResult[]): core.ScanResult[] {
|
|
5
|
-
const newResults: core.ScanResult[] = [];
|
|
6
|
-
|
|
7
|
-
for (const result of results) {
|
|
8
|
-
if (!result.ruleResults || result.ruleResults.length === 0) continue;
|
|
9
|
-
|
|
10
|
-
const fixables: core.RuleResult[] = result.ruleResults.filter(
|
|
11
|
-
(r) =>
|
|
12
|
-
(r.ruleName === "UnusedVariable" && r.occurs) ||
|
|
13
|
-
(r.ruleName === "UnconnectedElement" && r.occurs)
|
|
14
|
-
);
|
|
15
|
-
|
|
16
|
-
if (fixables.length === 0) continue;
|
|
17
|
-
|
|
18
|
-
const newFlow = FixFlows(result.flow, fixables);
|
|
19
|
-
|
|
20
|
-
const hasRemainingElements = newFlow.elements && newFlow.elements.length > 0;
|
|
21
|
-
if (hasRemainingElements) {
|
|
22
|
-
result.flow = newFlow;
|
|
23
|
-
newResults.push(result);
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
return newResults;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export function FixFlows(flow: core.Flow, ruleResults: core.RuleResult[]): core.Flow {
|
|
31
|
-
const unusedVariableRes = ruleResults.find((r) => r.ruleName === "UnusedVariable");
|
|
32
|
-
const unusedVariableNames = new Set(
|
|
33
|
-
unusedVariableRes?.details?.map((d) => d.name) ?? []
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
const unconnectedElementsRes = ruleResults.find((r) => r.ruleName === "UnconnectedElement");
|
|
37
|
-
const unconnectedElementNames = new Set(
|
|
38
|
-
unconnectedElementsRes?.details?.map((d) => d.name) ?? []
|
|
39
|
-
);
|
|
40
|
-
|
|
41
|
-
const nodesToKeep = flow.elements?.filter((node) => {
|
|
42
|
-
switch (node.metaType) {
|
|
43
|
-
case "attribute":
|
|
44
|
-
case "resource":
|
|
45
|
-
return true;
|
|
46
|
-
case "node": {
|
|
47
|
-
const nodeElement = node as core.FlowNode;
|
|
48
|
-
return !unconnectedElementNames.has(nodeElement.name);
|
|
49
|
-
}
|
|
50
|
-
case "variable": {
|
|
51
|
-
const nodeVar = node as core.FlowVariable;
|
|
52
|
-
return !unusedVariableNames.has(nodeVar.name);
|
|
53
|
-
}
|
|
54
|
-
default:
|
|
55
|
-
return false;
|
|
56
|
-
}
|
|
57
|
-
}) ?? [];
|
|
58
|
-
|
|
59
|
-
const xmldata = BuildFlow(nodesToKeep);
|
|
60
|
-
return new core.Flow(flow.fsPath, xmldata);
|
|
61
|
-
}
|
|
@@ -1,64 +0,0 @@
|
|
|
1
|
-
import { IRuleConfig } from "../interfaces/IRuleConfig";
|
|
2
|
-
import { IRuleDefinition } from "../interfaces/IRuleDefinition";
|
|
3
|
-
import { IRulesConfig } from "../interfaces/IRulesConfig";
|
|
4
|
-
import { ruleRegistry } from "../config/RuleRegistry";
|
|
5
|
-
|
|
6
|
-
export function GetRuleDefinitions(
|
|
7
|
-
ruleConfig?: Map<string, unknown>,
|
|
8
|
-
options?: IRulesConfig
|
|
9
|
-
): IRuleDefinition[] {
|
|
10
|
-
const includeBeta = options?.betaMode === true || options?.betamode === true;
|
|
11
|
-
const rulesMode = options?.ruleMode || "merged";
|
|
12
|
-
const selectedRules: IRuleDefinition[] = [];
|
|
13
|
-
|
|
14
|
-
const ruleIds = ruleRegistry.getAllRuleIds(includeBeta);
|
|
15
|
-
|
|
16
|
-
// ISOLATED MODE
|
|
17
|
-
if (rulesMode === "isolated" && ruleConfig && ruleConfig.size > 0) {
|
|
18
|
-
for (const key of ruleConfig.keys()) {
|
|
19
|
-
// key can now be either ruleId (new) or legacyName (old config compatibility)
|
|
20
|
-
const entry = ruleRegistry.get(key);
|
|
21
|
-
if (!entry) continue;
|
|
22
|
-
|
|
23
|
-
const config = ruleConfig.get(key) as IRuleConfig | undefined;
|
|
24
|
-
if (config?.enabled === false) continue;
|
|
25
|
-
|
|
26
|
-
const rule = ruleRegistry.createInstance(entry.ruleId); // Always use ruleId to instantiate
|
|
27
|
-
|
|
28
|
-
if (config?.severity) {
|
|
29
|
-
rule.severity = config.severity;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
selectedRules.push(rule);
|
|
33
|
-
}
|
|
34
|
-
return selectedRules;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// MERGED MODE (default)
|
|
38
|
-
for (const ruleId of ruleIds) {
|
|
39
|
-
const rule = ruleRegistry.createInstance(ruleId);
|
|
40
|
-
|
|
41
|
-
// Try to find config by ruleId first, then fall back to legacy name
|
|
42
|
-
const config = (
|
|
43
|
-
ruleConfig?.get(rule.ruleId) ??
|
|
44
|
-
ruleConfig?.get(rule.name) // rule.name is the legacy camelCase name (e.g. "ActionCallsInLoop")
|
|
45
|
-
) as IRuleConfig | undefined;
|
|
46
|
-
|
|
47
|
-
if (config?.enabled === false) continue;
|
|
48
|
-
|
|
49
|
-
if (config?.severity) {
|
|
50
|
-
rule.severity = config.severity;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
selectedRules.push(rule);
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
return selectedRules;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
export function getRules(
|
|
60
|
-
ruleNames?: string[],
|
|
61
|
-
options?: IRulesConfig
|
|
62
|
-
): IRuleDefinition[] {
|
|
63
|
-
return ruleRegistry.getRulesByNames(ruleNames, options);
|
|
64
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import { XMLParser } from "fast-xml-parser";
|
|
2
|
-
import { promises as fs } from "fs";
|
|
3
|
-
import * as p from "path";
|
|
4
|
-
|
|
5
|
-
import { Flow } from "../models/Flow";
|
|
6
|
-
import { ParsedFlow } from "../models/ParsedFlow";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
export async function parse(selectedUris: string[]): Promise<ParsedFlow[]> {
|
|
10
|
-
const parseResults: ParsedFlow[] = [];
|
|
11
|
-
const parser = new XMLParser({
|
|
12
|
-
attributeNamePrefix: "@_",
|
|
13
|
-
ignoreAttributes: false,
|
|
14
|
-
// @ts-expect-error type issue
|
|
15
|
-
ignoreNameSpace: false,
|
|
16
|
-
parseTagValue: false,
|
|
17
|
-
textNodeName: "#text"
|
|
18
|
-
});
|
|
19
|
-
|
|
20
|
-
for (const uri of selectedUris) {
|
|
21
|
-
try {
|
|
22
|
-
const normalizedURI = p.normalize(uri);
|
|
23
|
-
const content = await fs.readFile(normalizedURI, "utf8");
|
|
24
|
-
const parsed = parser.parse(content);
|
|
25
|
-
const flowObj = parsed.Flow;
|
|
26
|
-
parseResults.push(new ParsedFlow(uri, new Flow(uri, flowObj)));
|
|
27
|
-
} catch (e: any) {
|
|
28
|
-
parseResults.push(
|
|
29
|
-
new ParsedFlow(uri, undefined, e.message ?? e.toString())
|
|
30
|
-
);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
return parseResults;
|
|
34
|
-
}
|
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Converts a rule label to a documentation URL anchor.
|
|
3
|
-
*
|
|
4
|
-
* Rules:
|
|
5
|
-
* - Lowercase
|
|
6
|
-
* - Spaces → hyphens
|
|
7
|
-
* - Remove special characters and badges
|
|
8
|
-
*
|
|
9
|
-
* @param label - The rule display label (e.g., "DML Statement In A Loop")
|
|
10
|
-
* @returns The anchor slug (e.g., "dml-statement-in-a-loop")
|
|
11
|
-
*/
|
|
12
|
-
export function labelToAnchor(label: string): string {
|
|
13
|
-
return label
|
|
14
|
-
.toLowerCase()
|
|
15
|
-
.replace(/\s+/g, '-') // Replace spaces with hyphens
|
|
16
|
-
.replace(/[^a-z0-9-]/g, '') // Remove non-alphanumeric except hyphens
|
|
17
|
-
.replace(/-+/g, '-') // Collapse multiple hyphens
|
|
18
|
-
.replace(/^-|-$/g, ''); // Trim leading/trailing hyphens
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Generates a documentation URL for a rule.
|
|
23
|
-
*
|
|
24
|
-
* @param label - The rule display label
|
|
25
|
-
* @param customUrl - Optional custom URL override
|
|
26
|
-
* @returns The documentation URL
|
|
27
|
-
*/
|
|
28
|
-
export function getRuleDocumentationUrl(label: string, customUrl?: string): string {
|
|
29
|
-
if (customUrl) {
|
|
30
|
-
return customUrl;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
const anchor = labelToAnchor(label);
|
|
34
|
-
return `https://flow-scanner.github.io/lightning-flow-scanner/#${anchor}`;
|
|
35
|
-
}
|
|
@@ -1,142 +0,0 @@
|
|
|
1
|
-
import type { IRuleDefinition } from "../interfaces/IRuleDefinition";
|
|
2
|
-
import {
|
|
3
|
-
Flow,
|
|
4
|
-
IRulesConfig,
|
|
5
|
-
RuleResult,
|
|
6
|
-
ScanResult,
|
|
7
|
-
} from "../../main/internals/internals";
|
|
8
|
-
import { DetailLevel } from "../interfaces/IRulesConfig";
|
|
9
|
-
import { ParsedFlow } from "../models/ParsedFlow";
|
|
10
|
-
import { enrichViolationsWithLineNumbers } from "../models/Violation";
|
|
11
|
-
import { GetRuleDefinitions } from "./GetRuleDefinitions";
|
|
12
|
-
import { getRuleDocumentationUrl } from "./RuleDocumentation";
|
|
13
|
-
|
|
14
|
-
function getRuleConfigByIdOrName(
|
|
15
|
-
rule: IRuleDefinition,
|
|
16
|
-
rulesConfig?: Record<string, any>
|
|
17
|
-
): any | undefined {
|
|
18
|
-
if (!rulesConfig) return undefined;
|
|
19
|
-
// Try ruleId first, then fall back to name
|
|
20
|
-
return rulesConfig[rule.ruleId] || rulesConfig[rule.name];
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function getSuppressionsForRule(
|
|
24
|
-
rule: IRuleDefinition,
|
|
25
|
-
flowName: string,
|
|
26
|
-
exceptions?: Record<string, Record<string, string[]>>
|
|
27
|
-
): string[] {
|
|
28
|
-
if (!exceptions?.[flowName]) return [];
|
|
29
|
-
const flowExceptions = exceptions[flowName];
|
|
30
|
-
// Try ruleId first, then fall back to name
|
|
31
|
-
const rawSuppressions = flowExceptions[rule.ruleId] || flowExceptions[rule.name];
|
|
32
|
-
// If wildcard exists, return only wildcard; otherwise return array or empty
|
|
33
|
-
return rawSuppressions?.includes("*") ? ["*"] : (rawSuppressions ?? []);
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
export function scan(parsedFlows: ParsedFlow[], ruleOptions?: IRulesConfig): ScanResult[] {
|
|
37
|
-
const flows: Flow[] = [];
|
|
38
|
-
const ignoreFlows = ruleOptions?.ignoreFlows || [];
|
|
39
|
-
|
|
40
|
-
for (const flow of parsedFlows) {
|
|
41
|
-
if (!flow.errorMessage && flow.flow) {
|
|
42
|
-
// Filter out flows whose names are in the ignore list
|
|
43
|
-
if (ignoreFlows.length > 0 && ignoreFlows.includes(flow.flow.name)) {
|
|
44
|
-
continue;
|
|
45
|
-
}
|
|
46
|
-
flows.push(flow.flow);
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
const scanResults = ScanFlows(flows, ruleOptions);
|
|
50
|
-
return scanResults;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export function ScanFlows(flows: Flow[], ruleOptions?: IRulesConfig): ScanResult[] {
|
|
54
|
-
const flowResults: ScanResult[] = [];
|
|
55
|
-
const rawMode = ruleOptions?.detailLevel;
|
|
56
|
-
const detailLevel =
|
|
57
|
-
typeof rawMode === 'string' && rawMode.toLowerCase() === 'simple'
|
|
58
|
-
? DetailLevel.SIMPLE
|
|
59
|
-
: DetailLevel.ENRICHED;
|
|
60
|
-
|
|
61
|
-
let ruleMap: Map<string, object> | undefined = undefined;
|
|
62
|
-
if (ruleOptions?.rules && Object.keys(ruleOptions.rules).length > 0) {
|
|
63
|
-
ruleMap = new Map<string, object>();
|
|
64
|
-
for (const [ruleName, config] of Object.entries(ruleOptions.rules)) {
|
|
65
|
-
ruleMap.set(ruleName, config);
|
|
66
|
-
}
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// This ensures default rules are loaded and merged with any custom configs
|
|
70
|
-
const selectedRules = GetRuleDefinitions(ruleMap, ruleOptions);
|
|
71
|
-
|
|
72
|
-
const flowXmlCache = new Map<string, string>();
|
|
73
|
-
|
|
74
|
-
for (const flowInput of flows) {
|
|
75
|
-
const flow = flowInput instanceof Flow ? flowInput : Flow.from(flowInput);
|
|
76
|
-
const ruleResults: RuleResult[] = [];
|
|
77
|
-
|
|
78
|
-
for (const rule of selectedRules) {
|
|
79
|
-
try {
|
|
80
|
-
if (!rule.supportedTypes.includes(flow.type)) {
|
|
81
|
-
ruleResults.push(new RuleResult(rule, []));
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
const config = getRuleConfigByIdOrName(rule, ruleOptions?.rules);
|
|
86
|
-
const suppressions = getSuppressionsForRule(rule, flow.name, ruleOptions?.exceptions);
|
|
87
|
-
|
|
88
|
-
const result =
|
|
89
|
-
config && Object.keys(config).length > 0
|
|
90
|
-
? rule.execute(flow, config, suppressions)
|
|
91
|
-
: rule.execute(flow, undefined, suppressions);
|
|
92
|
-
|
|
93
|
-
// Apply custom message if provided in config, otherwise use summary
|
|
94
|
-
if (config && typeof config === 'object' && 'message' in config && typeof config.message === 'string') {
|
|
95
|
-
result.message = config.message;
|
|
96
|
-
} else {
|
|
97
|
-
// Use summary if available, otherwise fallback to description
|
|
98
|
-
result.message = result.ruleDefinition.summary || result.ruleDefinition.description;
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
// Apply custom messageUrl if provided in config, otherwise auto-generate from rule label
|
|
102
|
-
const customUrl = config && typeof config === 'object' && 'messageUrl' in config && typeof config.messageUrl === 'string'
|
|
103
|
-
? config.messageUrl
|
|
104
|
-
: undefined;
|
|
105
|
-
result.messageUrl = getRuleDocumentationUrl(result.ruleDefinition.label, customUrl);
|
|
106
|
-
|
|
107
|
-
if (result.details.length > 0) {
|
|
108
|
-
let flowXml = flowXmlCache.get(flow.name);
|
|
109
|
-
if (!flowXml) {
|
|
110
|
-
flowXml = flow.toXMLString();
|
|
111
|
-
flowXmlCache.set(flow.name, flowXml);
|
|
112
|
-
}
|
|
113
|
-
if (flowXml) {
|
|
114
|
-
enrichViolationsWithLineNumbers(result.details, flowXml);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
ruleResults.push(result);
|
|
119
|
-
} catch (error) {
|
|
120
|
-
const message = `Something went wrong while executing ${rule.name} in the Flow: ${flow.name} with error ${error}`;
|
|
121
|
-
ruleResults.push(new RuleResult(rule, [], message));
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
flowResults.push(new ScanResult(flow, ruleResults));
|
|
126
|
-
flowXmlCache.delete(flow.name);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
flowXmlCache.clear();
|
|
130
|
-
|
|
131
|
-
if (detailLevel === DetailLevel.SIMPLE) {
|
|
132
|
-
flowResults.forEach(scanResult => {
|
|
133
|
-
scanResult.ruleResults.forEach(ruleResult => {
|
|
134
|
-
ruleResult.details.forEach(violation => {
|
|
135
|
-
delete violation.details;
|
|
136
|
-
});
|
|
137
|
-
});
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
|
|
141
|
-
return flowResults;
|
|
142
|
-
}
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { Violation } from "./Violation";
|
|
2
|
-
|
|
3
|
-
export interface FlatViolation extends Omit<Violation, 'details'> {
|
|
4
|
-
flowFile: string;
|
|
5
|
-
flowName: string;
|
|
6
|
-
ruleId: string; // Canonical rule ID (e.g., "dml-in-loop")
|
|
7
|
-
ruleName: string; // Legacy class name (e.g., "DMLStatementInLoop")
|
|
8
|
-
severity: string;
|
|
9
|
-
message?: string; // Custom message overriding the default rule description
|
|
10
|
-
messageUrl?: string; // URL to custom documentation
|
|
11
|
-
dataType?: string;
|
|
12
|
-
locationX?: string;
|
|
13
|
-
locationY?: string;
|
|
14
|
-
connectsTo?: string;
|
|
15
|
-
expression?: string;
|
|
16
|
-
}
|
package/src/main/models/Flow.ts
DELETED
|
@@ -1,325 +0,0 @@
|
|
|
1
|
-
import { XMLBuilder } from "fast-xml-parser";
|
|
2
|
-
import * as p from "path";
|
|
3
|
-
import { FlowElement } from "./FlowElement";
|
|
4
|
-
import { FlowMetadata } from "./FlowMetadata";
|
|
5
|
-
import { FlowNode } from "./FlowNode";
|
|
6
|
-
import { FlowResource } from "./FlowResource";
|
|
7
|
-
import { FlowVariable } from "./FlowVariable";
|
|
8
|
-
import { FlowGraph } from "./FlowGraph";
|
|
9
|
-
|
|
10
|
-
export class Flow {
|
|
11
|
-
/**
|
|
12
|
-
* Metadata Tags of Salesforce Flow Attributes
|
|
13
|
-
*/
|
|
14
|
-
public static readonly ATTRIBUTE_TAGS = [
|
|
15
|
-
"apiVersion",
|
|
16
|
-
"areMetricsLoggedToDataCloud",
|
|
17
|
-
"description",
|
|
18
|
-
"environments",
|
|
19
|
-
"fullName",
|
|
20
|
-
"interviewLabel",
|
|
21
|
-
"isAdditionalPermissionRequiredToRun",
|
|
22
|
-
"isTemplate",
|
|
23
|
-
"label",
|
|
24
|
-
"migratedFromWorkflowRuleName",
|
|
25
|
-
"processMetadataValues",
|
|
26
|
-
"processType",
|
|
27
|
-
"runInMode",
|
|
28
|
-
"segment",
|
|
29
|
-
"startElementReference",
|
|
30
|
-
"status",
|
|
31
|
-
"timeZoneSidKey",
|
|
32
|
-
"triggerOrder"
|
|
33
|
-
] as const;
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* Metadata Tags of Salesforce Flow Nodes
|
|
37
|
-
*/
|
|
38
|
-
public static readonly NODE_TAGS = [
|
|
39
|
-
"actionCalls",
|
|
40
|
-
"apexPluginCalls",
|
|
41
|
-
"assignments",
|
|
42
|
-
"collectionProcessors",
|
|
43
|
-
"decisions",
|
|
44
|
-
"loops",
|
|
45
|
-
"orchestratedStages",
|
|
46
|
-
"recordCreates",
|
|
47
|
-
"recordDeletes",
|
|
48
|
-
"recordLookups",
|
|
49
|
-
"recordUpdates",
|
|
50
|
-
"recordRollbacks",
|
|
51
|
-
"screens",
|
|
52
|
-
"steps",
|
|
53
|
-
"subflows",
|
|
54
|
-
"waits",
|
|
55
|
-
"transforms",
|
|
56
|
-
"customErrors",
|
|
57
|
-
] as const;
|
|
58
|
-
|
|
59
|
-
public static readonly RESOURCE_TAGS = ["textTemplates", "stages"] as const;
|
|
60
|
-
public static readonly VARIABLE_TAGS = ["choices", "constants", "dynamicChoiceSets", "formulas", "variables"] as const;
|
|
61
|
-
|
|
62
|
-
// Flow elements (excludes legacy start nodes)
|
|
63
|
-
public elements: FlowElement[] = [];
|
|
64
|
-
|
|
65
|
-
// Path properties
|
|
66
|
-
public fsPath?: string; // Resolved absolute path (Node.js only)
|
|
67
|
-
public uri?: string; // Input path (could be relative, absolute, or virtual)
|
|
68
|
-
|
|
69
|
-
// Flow metadata
|
|
70
|
-
public label: string = "";
|
|
71
|
-
public interviewLabel?: string;
|
|
72
|
-
public name: string = "unnamed";
|
|
73
|
-
public processMetadataValues?: any;
|
|
74
|
-
public processType: string = "AutoLaunchedFlow";
|
|
75
|
-
public type: string = ""; // Alias for processType (backward compatibility)
|
|
76
|
-
public status: string = "";
|
|
77
|
-
public triggerOrder?: number;
|
|
78
|
-
|
|
79
|
-
// Start-related properties
|
|
80
|
-
/**
|
|
81
|
-
* @deprecated Use startNode.element instead. Kept for backward compatibility.
|
|
82
|
-
*/
|
|
83
|
-
public start?: any;
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Direct reference to first element (from XML attribute).
|
|
87
|
-
* Used in newer flows as an alternative to the start element.
|
|
88
|
-
*/
|
|
89
|
-
public startElementReference?: string;
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* Computed reference to the first element to execute.
|
|
93
|
-
* This is what rules should use for traversal.
|
|
94
|
-
*/
|
|
95
|
-
public startReference?: string;
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Parsed FlowNode object of the start element.
|
|
99
|
-
* Contains trigger information and connectors.
|
|
100
|
-
* Access start element data via startNode.element
|
|
101
|
-
*/
|
|
102
|
-
public startNode?: FlowNode;
|
|
103
|
-
|
|
104
|
-
private _graph?: FlowGraph;
|
|
105
|
-
|
|
106
|
-
public get graph(): FlowGraph {
|
|
107
|
-
if (!this._graph) {
|
|
108
|
-
const flowNodes = this.elements.filter((e): e is FlowNode => e instanceof FlowNode);
|
|
109
|
-
this.startReference ||= this.findStart();
|
|
110
|
-
this._graph = new FlowGraph(flowNodes, this.startReference, this.startNode);
|
|
111
|
-
}
|
|
112
|
-
return this._graph;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
// Legacy/internal
|
|
116
|
-
public root?: any;
|
|
117
|
-
public xmldata: any;
|
|
118
|
-
|
|
119
|
-
constructor(path?: string, data?: unknown) {
|
|
120
|
-
if (path) {
|
|
121
|
-
this.uri = path;
|
|
122
|
-
|
|
123
|
-
if (typeof process !== 'undefined' && typeof process.cwd === 'function') {
|
|
124
|
-
this.fsPath = p.resolve(path);
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
let flowName = p.basename(p.basename(path), p.extname(path));
|
|
128
|
-
if (flowName.includes(".")) {
|
|
129
|
-
flowName = flowName.split(".")[0];
|
|
130
|
-
}
|
|
131
|
-
this.name = flowName || "unnamed";
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
if (data) {
|
|
135
|
-
const hasFlowElement = typeof data === "object" && data !== null && "Flow" in data;
|
|
136
|
-
if (hasFlowElement) {
|
|
137
|
-
this.xmldata = (data as any).Flow;
|
|
138
|
-
} else {
|
|
139
|
-
this.xmldata = data;
|
|
140
|
-
}
|
|
141
|
-
this.preProcessNodes();
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
public static from(obj: Partial<Flow>): Flow {
|
|
146
|
-
if (obj instanceof Flow) {
|
|
147
|
-
return obj;
|
|
148
|
-
}
|
|
149
|
-
const flow = Object.create(Flow.prototype);
|
|
150
|
-
Object.assign(flow, obj);
|
|
151
|
-
if (!flow.toXMLString) {
|
|
152
|
-
flow.toXMLString = () => '';
|
|
153
|
-
}
|
|
154
|
-
return flow;
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
public preProcessNodes() {
|
|
158
|
-
if (!this.xmldata) {
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
// Extract top-level attributes
|
|
163
|
-
this.label = this.xmldata.label || "";
|
|
164
|
-
this.interviewLabel = this.xmldata.interviewLabel;
|
|
165
|
-
this.processType = this.xmldata.processType || "AutoLaunchedFlow";
|
|
166
|
-
this.type = this.processType;
|
|
167
|
-
this.processMetadataValues = this.xmldata.processMetadataValues;
|
|
168
|
-
this.startElementReference = this.xmldata.startElementReference;
|
|
169
|
-
this.status = this.xmldata.status || "Draft";
|
|
170
|
-
this.triggerOrder = this.xmldata.triggerOrder;
|
|
171
|
-
|
|
172
|
-
const allNodes: Array<FlowMetadata | FlowNode | FlowVariable | FlowResource> = [];
|
|
173
|
-
|
|
174
|
-
for (const nodeType in this.xmldata) {
|
|
175
|
-
// Skip xmlns and attributes
|
|
176
|
-
if (nodeType.startsWith("@_") || nodeType === "@xmlns") {
|
|
177
|
-
continue;
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
const data = this.xmldata[nodeType];
|
|
181
|
-
|
|
182
|
-
// Handle start nodes separately - store in startNode property
|
|
183
|
-
if (nodeType === "start") {
|
|
184
|
-
if (Array.isArray(data) && data.length > 0) {
|
|
185
|
-
this.startNode = new FlowNode(data[0].name || "start", "start", data[0]);
|
|
186
|
-
} else if (!Array.isArray(data)) {
|
|
187
|
-
this.startNode = new FlowNode(data.name || "start", "start", data);
|
|
188
|
-
}
|
|
189
|
-
continue;
|
|
190
|
-
}
|
|
191
|
-
|
|
192
|
-
// Process other node types
|
|
193
|
-
if (Flow.ATTRIBUTE_TAGS.includes(nodeType as any)) {
|
|
194
|
-
this.processNodeType(data, nodeType, allNodes, FlowMetadata);
|
|
195
|
-
} else if (Flow.VARIABLE_TAGS.includes(nodeType as any)) {
|
|
196
|
-
this.processNodeType(data, nodeType, allNodes, FlowVariable);
|
|
197
|
-
} else if (Flow.NODE_TAGS.includes(nodeType as any)) {
|
|
198
|
-
this.processNodeType(data, nodeType, allNodes, FlowNode);
|
|
199
|
-
} else if (Flow.RESOURCE_TAGS.includes(nodeType as any)) {
|
|
200
|
-
this.processNodeType(data, nodeType, allNodes, FlowResource);
|
|
201
|
-
}
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
this.elements = allNodes;
|
|
205
|
-
this.startReference = this.findStart();
|
|
206
|
-
|
|
207
|
-
// Build the connectivity graph
|
|
208
|
-
const flowNodes = allNodes.filter((e): e is FlowNode => e instanceof FlowNode);
|
|
209
|
-
this._graph = new FlowGraph(flowNodes, this.startReference, this.startNode);
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
public visualize(
|
|
213
|
-
format: 'mermaid' | 'plantuml' = 'mermaid',
|
|
214
|
-
options: {
|
|
215
|
-
includeDetails?: boolean;
|
|
216
|
-
includeMarkdownDocs?: boolean;
|
|
217
|
-
collapsedDetails?: boolean;
|
|
218
|
-
} = {}
|
|
219
|
-
): string {
|
|
220
|
-
if (format === 'mermaid') {
|
|
221
|
-
return this.graph.toMermaid({
|
|
222
|
-
...options,
|
|
223
|
-
flowMetadata: {
|
|
224
|
-
label: this.label,
|
|
225
|
-
processType: this.processType,
|
|
226
|
-
status: this.status,
|
|
227
|
-
description: this.xmldata?.description,
|
|
228
|
-
triggerType: this.startNode?.element?.['triggerType'],
|
|
229
|
-
object: this.startNode?.element?.['object'],
|
|
230
|
-
}
|
|
231
|
-
});
|
|
232
|
-
} else if (format === 'plantuml') {
|
|
233
|
-
return this.graph.toPlantUML();
|
|
234
|
-
}
|
|
235
|
-
throw new Error('Unsupported format');
|
|
236
|
-
}
|
|
237
|
-
private processNodeType<T extends FlowElement>(
|
|
238
|
-
data: any,
|
|
239
|
-
nodeType: string,
|
|
240
|
-
allNodes: FlowElement[],
|
|
241
|
-
NodeClass: new (name: string, subtype: string, data: any) => T
|
|
242
|
-
) {
|
|
243
|
-
if (Array.isArray(data)) {
|
|
244
|
-
for (const node of data) {
|
|
245
|
-
allNodes.push(new NodeClass(node.name, nodeType, node));
|
|
246
|
-
}
|
|
247
|
-
} else {
|
|
248
|
-
allNodes.push(new NodeClass(data.name, nodeType, data));
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
|
|
252
|
-
/**
|
|
253
|
-
* Find the name of the first element to execute.
|
|
254
|
-
* Priority order:
|
|
255
|
-
* 1. startElementReference (newer flows, direct XML attribute)
|
|
256
|
-
* 2. Start node connector (older flows, points to first element)
|
|
257
|
-
* 3. Start node scheduledPaths (async flows)
|
|
258
|
-
*/
|
|
259
|
-
private findStart(): string {
|
|
260
|
-
// Priority 1: Explicit startElementReference
|
|
261
|
-
if (this.startElementReference) {
|
|
262
|
-
return this.startElementReference;
|
|
263
|
-
}
|
|
264
|
-
|
|
265
|
-
// Priority 2: Start node with regular connector
|
|
266
|
-
if (this.startNode && this.startNode.connectors && this.startNode.connectors.length > 0) {
|
|
267
|
-
const connector = this.startNode.connectors[0];
|
|
268
|
-
if (connector.reference) {
|
|
269
|
-
return connector.reference;
|
|
270
|
-
}
|
|
271
|
-
}
|
|
272
|
-
|
|
273
|
-
// Priority 3: Start node with scheduledPaths (async flows)
|
|
274
|
-
if (this.startNode?.element) {
|
|
275
|
-
const scheduledPaths = this.startNode.element['scheduledPaths'];
|
|
276
|
-
if (scheduledPaths) {
|
|
277
|
-
const paths = Array.isArray(scheduledPaths) ? scheduledPaths : [scheduledPaths];
|
|
278
|
-
if (paths.length > 0 && paths[0]?.connector) {
|
|
279
|
-
const targetRef = paths[0].connector.targetReference;
|
|
280
|
-
if (targetRef) {
|
|
281
|
-
return targetRef;
|
|
282
|
-
}
|
|
283
|
-
}
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
|
|
287
|
-
// No valid start found
|
|
288
|
-
return "";
|
|
289
|
-
}
|
|
290
|
-
|
|
291
|
-
public toXMLString(): string {
|
|
292
|
-
try {
|
|
293
|
-
return this.generateDoc();
|
|
294
|
-
} catch (exception) {
|
|
295
|
-
const errorMsg = exception instanceof Error ? exception.message : String(exception);
|
|
296
|
-
console.warn(`Unable to write xml, caught an error: ${errorMsg}`);
|
|
297
|
-
return "";
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
|
|
301
|
-
private generateDoc(): string {
|
|
302
|
-
const flowXmlNamespace = "http://soap.sforce.com/2006/04/metadata";
|
|
303
|
-
const builderOptions = {
|
|
304
|
-
attributeNamePrefix: "@_",
|
|
305
|
-
format: true,
|
|
306
|
-
ignoreAttributes: false,
|
|
307
|
-
suppressBooleanAttributes: false,
|
|
308
|
-
suppressEmptyNode: false
|
|
309
|
-
};
|
|
310
|
-
|
|
311
|
-
const builder = new XMLBuilder(builderOptions);
|
|
312
|
-
const xmldataWithNs = { ...this.xmldata };
|
|
313
|
-
|
|
314
|
-
if (!xmldataWithNs["@_xmlns"]) {
|
|
315
|
-
xmldataWithNs["@_xmlns"] = flowXmlNamespace;
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
if (!xmldataWithNs["@_xmlns:xsi"]) {
|
|
319
|
-
xmldataWithNs["@_xmlns:xsi"] = "http://www.w3.org/2001/XMLSchema-instance";
|
|
320
|
-
}
|
|
321
|
-
|
|
322
|
-
const rootObj = { Flow: xmldataWithNs };
|
|
323
|
-
return builder.build(rootObj);
|
|
324
|
-
}
|
|
325
|
-
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { MetaType } from "../enums/MetadataTypes";
|
|
2
|
-
import { FlowElement } from "./FlowElement";
|
|
3
|
-
|
|
4
|
-
export class FlowAttribute extends FlowElement {
|
|
5
|
-
public expression?: string;
|
|
6
|
-
|
|
7
|
-
constructor(name: string, subtype: string, expression?: string) {
|
|
8
|
-
super(MetaType.ATTRIBUTE, subtype, name); // No element passed, or pass {} if needed
|
|
9
|
-
this.expression = expression;
|
|
10
|
-
}
|
|
11
|
-
}
|