|
1 |
| -import { AdvancedRule } from "../models/AdvancedRule"; |
2 |
| -import * as core from "../internals/internals"; |
3 |
| - |
4 |
| -export class CyclomaticComplexity extends AdvancedRule implements core.IRuleDefinition { |
5 |
| - constructor() { |
6 |
| - super( |
7 |
| - { |
8 |
| - name: "CyclomaticComplexity", |
9 |
| - label: "Cyclomatic Complexity", |
10 |
| - description: `The number of loops and decision rules, plus the number of decisions. Use a combination of 1) subflows and 2) breaking flows into multiple concise trigger ordered flows, to reduce the cyclomatic complexity within a single flow, ensuring maintainability and simplicity.`, |
11 |
| - supportedTypes: core.FlowType.backEndTypes, |
12 |
| - docRefs: [ |
13 |
| - { |
14 |
| - label: `Cyclomatic complexity is a software metric used to indicate the complexity of a program. It is a quantitative measure of the number of linearly independent paths through a program's source code.`, |
15 |
| - path: "https://en.wikipedia.org/wiki/Cyclomatic_complexity", |
16 |
| - }, |
17 |
| - ], |
18 |
| - isConfigurable: true, |
19 |
| - autoFixable: false, |
20 |
| - }, |
21 |
| - { severity: "note" } |
22 |
| - ); |
23 |
| - } |
24 |
| - |
25 |
| - private defaultThreshold: number = 25; |
26 |
| - |
27 |
| - private cyclomaticComplexityUnit: number = 0; |
28 |
| - |
29 |
| - public execute(flow: core.Flow, options?: { threshold: number }): core.RuleResult { |
30 |
| - // Set Threshold |
31 |
| - const threshold = options?.threshold || this.defaultThreshold; |
32 |
| - |
33 |
| - // Calculate Cyclomatic Complexity based on the number of decision rules and loops, adding the number of decisions plus 1. |
34 |
| - let cyclomaticComplexity = 1; |
35 |
| - |
36 |
| - const flowDecisions = flow?.elements?.filter( |
37 |
| - (node) => node.subtype === "decisions" |
38 |
| - ) as core.FlowElement[]; |
39 |
| - const flowLoops = flow?.elements?.filter((node) => node.subtype === "loops"); |
40 |
| - |
41 |
| - for (const decision of flowDecisions || []) { |
42 |
| - const rules = decision.element["rules"]; |
43 |
| - if (Array.isArray(rules)) { |
44 |
| - cyclomaticComplexity += rules.length + 1; |
45 |
| - } else { |
46 |
| - cyclomaticComplexity += 1; |
47 |
| - } |
48 |
| - } |
49 |
| - cyclomaticComplexity += flowLoops?.length ?? 0; |
50 |
| - |
51 |
| - this.cyclomaticComplexityUnit = cyclomaticComplexity; // for unit testing |
52 |
| - |
53 |
| - const results: core.ResultDetails[] = []; |
54 |
| - if (cyclomaticComplexity > threshold) { |
55 |
| - results.push( |
56 |
| - new core.ResultDetails( |
57 |
| - new core.FlowAttribute(`${cyclomaticComplexity}`, "CyclomaticComplexity", `>${threshold}`) |
58 |
| - ) |
59 |
| - ); |
60 |
| - } |
61 |
| - return new core.RuleResult(this, results); |
62 |
| - } |
63 |
| -} |
| 1 | +/** |
| 2 | + * ⚠️ WARNING! |
| 3 | + * |
| 4 | + * This is a version of Flow Scanner that contains known vulnerabilities. |
| 5 | + * |
| 6 | + * Please use a version >= 5.1.0 immidiately. |
| 7 | + * Failure to upgrade may expose your project to security risks. |
| 8 | + * |
| 9 | + * Follow 👉 https://github.com/Flow-Scanner/ |
| 10 | + * Details 👉 https://github.com/orgs/Flow-Scanner/discussions/263 |
| 11 | + * |
| 12 | + */ |
0 commit comments