@flow-scanner/lightning-flow-scanner-core 6.0.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.
Files changed (128) hide show
  1. package/CONTRIBUTING.md +30 -0
  2. package/LICENSE.md +21 -0
  3. package/README.md +314 -0
  4. package/SECURITY.md +26 -0
  5. package/assets/media/bannerslim.png +0 -0
  6. package/index.d.ts +21 -0
  7. package/index.js +83 -0
  8. package/main/interfaces/AdvancedRuleConfig.d.ts +11 -0
  9. package/main/interfaces/AdvancedRuleConfig.js +4 -0
  10. package/main/interfaces/AdvancedRuleDefintion.d.ts +5 -0
  11. package/main/interfaces/AdvancedRuleDefintion.js +4 -0
  12. package/main/interfaces/AdvancedSuppression.d.ts +21 -0
  13. package/main/interfaces/AdvancedSuppression.js +4 -0
  14. package/main/interfaces/AutoFixable.d.ts +10 -0
  15. package/main/interfaces/AutoFixable.js +4 -0
  16. package/main/interfaces/IExceptions.d.ts +5 -0
  17. package/main/interfaces/IExceptions.js +4 -0
  18. package/main/interfaces/IRuleConfig.d.ts +3 -0
  19. package/main/interfaces/IRuleConfig.js +4 -0
  20. package/main/interfaces/IRuleDefinition.d.ts +17 -0
  21. package/main/interfaces/IRuleDefinition.js +4 -0
  22. package/main/interfaces/IRuleOptions.d.ts +4 -0
  23. package/main/interfaces/IRuleOptions.js +4 -0
  24. package/main/interfaces/IRulesConfig.d.ts +8 -0
  25. package/main/interfaces/IRulesConfig.js +4 -0
  26. package/main/internals/internals.d.ts +17 -0
  27. package/main/internals/internals.js +64 -0
  28. package/main/libs/BuildFlow.d.ts +1 -0
  29. package/main/libs/BuildFlow.js +20 -0
  30. package/main/libs/Compiler.d.ts +8 -0
  31. package/main/libs/Compiler.js +70 -0
  32. package/main/libs/ConvertFlowNodes.d.ts +1 -0
  33. package/main/libs/ConvertFlowNodes.js +14 -0
  34. package/main/libs/DynamicRule.d.ts +5 -0
  35. package/main/libs/DynamicRule.js +19 -0
  36. package/main/libs/FixFlows.d.ts +3 -0
  37. package/main/libs/FixFlows.js +110 -0
  38. package/main/libs/GetRuleDefinitions.d.ts +5 -0
  39. package/main/libs/GetRuleDefinitions.js +81 -0
  40. package/main/libs/ParseFlows.d.ts +2 -0
  41. package/main/libs/ParseFlows.js +111 -0
  42. package/main/libs/Scan2.d.ts +3 -0
  43. package/main/libs/Scan2.js +124 -0
  44. package/main/libs/ScanFlows.d.ts +4 -0
  45. package/main/libs/ScanFlows.js +103 -0
  46. package/main/models/AdvancedRule.d.ts +44 -0
  47. package/main/models/AdvancedRule.js +84 -0
  48. package/main/models/Flow.d.ts +33 -0
  49. package/main/models/Flow.js +277 -0
  50. package/main/models/FlowAttribute.d.ts +7 -0
  51. package/main/models/FlowAttribute.js +34 -0
  52. package/main/models/FlowElement.d.ts +10 -0
  53. package/main/models/FlowElement.js +37 -0
  54. package/main/models/FlowElementConnector.d.ts +15 -0
  55. package/main/models/FlowElementConnector.js +50 -0
  56. package/main/models/FlowMetadata.d.ts +4 -0
  57. package/main/models/FlowMetadata.js +16 -0
  58. package/main/models/FlowNode.d.ts +10 -0
  59. package/main/models/FlowNode.js +169 -0
  60. package/main/models/FlowResource.d.ts +5 -0
  61. package/main/models/FlowResource.js +30 -0
  62. package/main/models/FlowType.d.ts +23 -0
  63. package/main/models/FlowType.js +80 -0
  64. package/main/models/FlowVariable.d.ts +6 -0
  65. package/main/models/FlowVariable.js +31 -0
  66. package/main/models/LoopRuleCommon.d.ts +9 -0
  67. package/main/models/LoopRuleCommon.js +48 -0
  68. package/main/models/ParsedFlow.d.ts +7 -0
  69. package/main/models/ParsedFlow.js +35 -0
  70. package/main/models/ResultDetails.d.ts +10 -0
  71. package/main/models/ResultDetails.js +57 -0
  72. package/main/models/RuleCommon.d.ts +19 -0
  73. package/main/models/RuleCommon.js +48 -0
  74. package/main/models/RuleInfo.d.ts +55 -0
  75. package/main/models/RuleInfo.js +61 -0
  76. package/main/models/RuleResult.d.ts +11 -0
  77. package/main/models/RuleResult.js +44 -0
  78. package/main/models/ScanResult.d.ts +7 -0
  79. package/main/models/ScanResult.js +31 -0
  80. package/main/rules/APIVersion.d.ts +8 -0
  81. package/main/rules/APIVersion.js +86 -0
  82. package/main/rules/ActionCallsInLoop.d.ts +6 -0
  83. package/main/rules/ActionCallsInLoop.js +38 -0
  84. package/main/rules/AutoLayout.d.ts +8 -0
  85. package/main/rules/AutoLayout.js +78 -0
  86. package/main/rules/CopyAPIName.d.ts +6 -0
  87. package/main/rules/CopyAPIName.js +82 -0
  88. package/main/rules/CyclomaticComplexity.d.ts +10 -0
  89. package/main/rules/CyclomaticComplexity.js +111 -0
  90. package/main/rules/DMLStatementInLoop.d.ts +6 -0
  91. package/main/rules/DMLStatementInLoop.js +37 -0
  92. package/main/rules/DuplicateDMLOperation.d.ts +8 -0
  93. package/main/rules/DuplicateDMLOperation.js +153 -0
  94. package/main/rules/FlowDescription.d.ts +6 -0
  95. package/main/rules/FlowDescription.js +76 -0
  96. package/main/rules/FlowName.d.ts +7 -0
  97. package/main/rules/FlowName.js +80 -0
  98. package/main/rules/GetRecordAllFields.d.ts +6 -0
  99. package/main/rules/GetRecordAllFields.js +101 -0
  100. package/main/rules/HardcodedId.d.ts +6 -0
  101. package/main/rules/HardcodedId.js +87 -0
  102. package/main/rules/HardcodedUrl.d.ts +6 -0
  103. package/main/rules/HardcodedUrl.js +50 -0
  104. package/main/rules/InactiveFlow.d.ts +6 -0
  105. package/main/rules/InactiveFlow.js +73 -0
  106. package/main/rules/MissingFaultPath.d.ts +12 -0
  107. package/main/rules/MissingFaultPath.js +161 -0
  108. package/main/rules/MissingNullHandler.d.ts +6 -0
  109. package/main/rules/MissingNullHandler.js +152 -0
  110. package/main/rules/ProcessBuilder.d.ts +8 -0
  111. package/main/rules/ProcessBuilder.js +77 -0
  112. package/main/rules/RecursiveAfterUpdate.d.ts +7 -0
  113. package/main/rules/RecursiveAfterUpdate.js +124 -0
  114. package/main/rules/SOQLQueryInLoop.d.ts +6 -0
  115. package/main/rules/SOQLQueryInLoop.js +35 -0
  116. package/main/rules/SameRecordFieldUpdates.d.ts +7 -0
  117. package/main/rules/SameRecordFieldUpdates.js +111 -0
  118. package/main/rules/TriggerOrder.d.ts +7 -0
  119. package/main/rules/TriggerOrder.js +101 -0
  120. package/main/rules/UnconnectedElement.d.ts +7 -0
  121. package/main/rules/UnconnectedElement.js +93 -0
  122. package/main/rules/UnsafeRunningContext.d.ts +6 -0
  123. package/main/rules/UnsafeRunningContext.js +86 -0
  124. package/main/rules/UnusedVariable.d.ts +6 -0
  125. package/main/rules/UnusedVariable.js +100 -0
  126. package/main/store/DefaultRuleStore.d.ts +2 -0
  127. package/main/store/DefaultRuleStore.js +68 -0
  128. package/package.json +88 -0
@@ -0,0 +1,111 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "CyclomaticComplexity", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return CyclomaticComplexity;
9
+ }
10
+ });
11
+ const _AdvancedRule = require("../models/AdvancedRule");
12
+ const _internals = /*#__PURE__*/ _interop_require_wildcard(require("../internals/internals"));
13
+ function _define_property(obj, key, value) {
14
+ if (key in obj) {
15
+ Object.defineProperty(obj, key, {
16
+ value: value,
17
+ enumerable: true,
18
+ configurable: true,
19
+ writable: true
20
+ });
21
+ } else {
22
+ obj[key] = value;
23
+ }
24
+ return obj;
25
+ }
26
+ function _getRequireWildcardCache(nodeInterop) {
27
+ if (typeof WeakMap !== "function") return null;
28
+ var cacheBabelInterop = new WeakMap();
29
+ var cacheNodeInterop = new WeakMap();
30
+ return (_getRequireWildcardCache = function(nodeInterop) {
31
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
32
+ })(nodeInterop);
33
+ }
34
+ function _interop_require_wildcard(obj, nodeInterop) {
35
+ if (!nodeInterop && obj && obj.__esModule) {
36
+ return obj;
37
+ }
38
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
39
+ return {
40
+ default: obj
41
+ };
42
+ }
43
+ var cache = _getRequireWildcardCache(nodeInterop);
44
+ if (cache && cache.has(obj)) {
45
+ return cache.get(obj);
46
+ }
47
+ var newObj = {
48
+ __proto__: null
49
+ };
50
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
51
+ for(var key in obj){
52
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
53
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
54
+ if (desc && (desc.get || desc.set)) {
55
+ Object.defineProperty(newObj, key, desc);
56
+ } else {
57
+ newObj[key] = obj[key];
58
+ }
59
+ }
60
+ }
61
+ newObj.default = obj;
62
+ if (cache) {
63
+ cache.set(obj, newObj);
64
+ }
65
+ return newObj;
66
+ }
67
+ let CyclomaticComplexity = class CyclomaticComplexity extends _AdvancedRule.AdvancedRule {
68
+ execute(flow, options) {
69
+ var _flow_elements, _flow_elements1;
70
+ // Set Threshold
71
+ const threshold = (options === null || options === void 0 ? void 0 : options.threshold) || this.defaultThreshold;
72
+ // Calculate Cyclomatic Complexity based on the number of decision rules and loops, adding the number of decisions plus 1.
73
+ let cyclomaticComplexity = 1;
74
+ const flowDecisions = flow === null || flow === void 0 ? void 0 : (_flow_elements = flow.elements) === null || _flow_elements === void 0 ? void 0 : _flow_elements.filter((node)=>node.subtype === "decisions");
75
+ const flowLoops = flow === null || flow === void 0 ? void 0 : (_flow_elements1 = flow.elements) === null || _flow_elements1 === void 0 ? void 0 : _flow_elements1.filter((node)=>node.subtype === "loops");
76
+ for (const decision of flowDecisions || []){
77
+ const rules = decision.element["rules"];
78
+ if (Array.isArray(rules)) {
79
+ cyclomaticComplexity += rules.length + 1;
80
+ } else {
81
+ cyclomaticComplexity += 1;
82
+ }
83
+ }
84
+ var _flowLoops_length;
85
+ cyclomaticComplexity += (_flowLoops_length = flowLoops === null || flowLoops === void 0 ? void 0 : flowLoops.length) !== null && _flowLoops_length !== void 0 ? _flowLoops_length : 0;
86
+ this.cyclomaticComplexityUnit = cyclomaticComplexity; // for unit testing
87
+ const results = [];
88
+ if (cyclomaticComplexity > threshold) {
89
+ results.push(new _internals.ResultDetails(new _internals.FlowAttribute(`${cyclomaticComplexity}`, "CyclomaticComplexity", `>${threshold}`)));
90
+ }
91
+ return new _internals.RuleResult(this, results);
92
+ }
93
+ constructor(){
94
+ super({
95
+ name: "CyclomaticComplexity",
96
+ label: "Cyclomatic Complexity",
97
+ 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.`,
98
+ supportedTypes: _internals.FlowType.backEndTypes,
99
+ docRefs: [
100
+ {
101
+ 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.`,
102
+ path: "https://en.wikipedia.org/wiki/Cyclomatic_complexity"
103
+ }
104
+ ],
105
+ isConfigurable: true,
106
+ autoFixable: false
107
+ }, {
108
+ severity: "note"
109
+ }), _define_property(this, "defaultThreshold", 25), _define_property(this, "cyclomaticComplexityUnit", 0);
110
+ }
111
+ };
@@ -0,0 +1,6 @@
1
+ import { IRuleDefinition } from "../internals/internals";
2
+ import { LoopRuleCommon } from "../models/LoopRuleCommon";
3
+ export declare class DMLStatementInLoop extends LoopRuleCommon implements IRuleDefinition {
4
+ constructor();
5
+ protected getStatementTypes(): string[];
6
+ }
@@ -0,0 +1,37 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "DMLStatementInLoop", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return DMLStatementInLoop;
9
+ }
10
+ });
11
+ const _internals = require("../internals/internals");
12
+ const _LoopRuleCommon = require("../models/LoopRuleCommon");
13
+ let DMLStatementInLoop = class DMLStatementInLoop extends _LoopRuleCommon.LoopRuleCommon {
14
+ getStatementTypes() {
15
+ return [
16
+ "recordDeletes",
17
+ "recordUpdates",
18
+ "recordCreates"
19
+ ];
20
+ }
21
+ constructor(){
22
+ super({
23
+ autoFixable: false,
24
+ description: "To prevent exceeding Apex governor limits, it is advisable to consolidate all your database operations, including record creation, updates, or deletions, at the conclusion of the flow.",
25
+ docRefs: [
26
+ {
27
+ label: "Flow Best Practices",
28
+ path: "https://help.salesforce.com/s/articleView?id=sf.flow_prep_bestpractices.htm&type=5"
29
+ }
30
+ ],
31
+ isConfigurable: false,
32
+ label: "DML Statement In A Loop",
33
+ name: "DMLStatementInLoop",
34
+ supportedTypes: _internals.FlowType.backEndTypes
35
+ });
36
+ }
37
+ };
@@ -0,0 +1,8 @@
1
+ import { AdvancedRule } from "../models/AdvancedRule";
2
+ import * as core from "../internals/internals";
3
+ export declare class DuplicateDMLOperation extends AdvancedRule implements core.IRuleDefinition {
4
+ constructor();
5
+ execute(flow: core.Flow): core.RuleResult;
6
+ private flagDML;
7
+ private findStart;
8
+ }
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "DuplicateDMLOperation", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return DuplicateDMLOperation;
9
+ }
10
+ });
11
+ const _AdvancedRule = require("../models/AdvancedRule");
12
+ const _internals = /*#__PURE__*/ _interop_require_wildcard(require("../internals/internals"));
13
+ function _getRequireWildcardCache(nodeInterop) {
14
+ if (typeof WeakMap !== "function") return null;
15
+ var cacheBabelInterop = new WeakMap();
16
+ var cacheNodeInterop = new WeakMap();
17
+ return (_getRequireWildcardCache = function(nodeInterop) {
18
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
19
+ })(nodeInterop);
20
+ }
21
+ function _interop_require_wildcard(obj, nodeInterop) {
22
+ if (!nodeInterop && obj && obj.__esModule) {
23
+ return obj;
24
+ }
25
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
26
+ return {
27
+ default: obj
28
+ };
29
+ }
30
+ var cache = _getRequireWildcardCache(nodeInterop);
31
+ if (cache && cache.has(obj)) {
32
+ return cache.get(obj);
33
+ }
34
+ var newObj = {
35
+ __proto__: null
36
+ };
37
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
38
+ for(var key in obj){
39
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
40
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
41
+ if (desc && (desc.get || desc.set)) {
42
+ Object.defineProperty(newObj, key, desc);
43
+ } else {
44
+ newObj[key] = obj[key];
45
+ }
46
+ }
47
+ }
48
+ newObj.default = obj;
49
+ if (cache) {
50
+ cache.set(obj, newObj);
51
+ }
52
+ return newObj;
53
+ }
54
+ let DuplicateDMLOperation = class DuplicateDMLOperation extends _AdvancedRule.AdvancedRule {
55
+ execute(flow) {
56
+ const flowElements = flow.elements.filter((node)=>node instanceof _internals.FlowNode);
57
+ const processedElementIndexes = [];
58
+ const unconnectedElementIndexes = [];
59
+ const DuplicateDMLOperations = [];
60
+ const startingNode = this.findStart(flow);
61
+ if (!startingNode || startingNode === -1) {
62
+ throw "Can not find starting element";
63
+ }
64
+ let dmlFlag = false;
65
+ let indexesToProcess = [
66
+ startingNode
67
+ ];
68
+ do {
69
+ indexesToProcess = indexesToProcess.filter((index)=>!processedElementIndexes.includes(index));
70
+ if (indexesToProcess.length > 0) {
71
+ for (const [index, element] of flowElements.entries()){
72
+ if (indexesToProcess.includes(index)) {
73
+ const references = [];
74
+ if (element.connectors && element.connectors.length > 0) {
75
+ for (const connector of element.connectors){
76
+ if (connector.reference) {
77
+ references.push(connector.reference);
78
+ }
79
+ }
80
+ }
81
+ dmlFlag = this.flagDML(element, dmlFlag);
82
+ if (references.length > 0) {
83
+ const elementsByReferences = flowElements.filter((element)=>references.includes(element.name));
84
+ for (const nextElement of elementsByReferences){
85
+ const nextIndex = flowElements.findIndex((element)=>nextElement.name === element.name);
86
+ if ("screens" === nextElement.subtype) {
87
+ if (dmlFlag && nextElement.element["allowBack"] && nextElement.element["allowBack"] == "true" && nextElement.element["showFooter"] == "true") {
88
+ DuplicateDMLOperations.push(nextElement);
89
+ }
90
+ }
91
+ if (!processedElementIndexes.includes(nextIndex)) {
92
+ indexesToProcess.push(nextIndex);
93
+ }
94
+ }
95
+ }
96
+ processedElementIndexes.push(index);
97
+ }
98
+ }
99
+ } else {
100
+ // skip unconnected elements
101
+ for (const index of flowElements.keys()){
102
+ if (!processedElementIndexes.includes(index)) {
103
+ unconnectedElementIndexes.push(index);
104
+ }
105
+ }
106
+ }
107
+ }while (processedElementIndexes.length + unconnectedElementIndexes.length < flowElements.length)
108
+ const results = [];
109
+ for (const det of DuplicateDMLOperations){
110
+ results.push(new _internals.ResultDetails(det));
111
+ }
112
+ return new _internals.RuleResult(this, results);
113
+ }
114
+ flagDML(element, dmlFlag) {
115
+ const dmlStatementTypes = [
116
+ "recordDeletes",
117
+ "recordUpdates",
118
+ "recordCreates"
119
+ ];
120
+ if (dmlStatementTypes.includes(element.subtype)) {
121
+ return true;
122
+ } else if (dmlFlag === true && element.subtype === "screens" && element.element["allowBack"] && element.element["allowBack"] == "true") {
123
+ return false;
124
+ } else {
125
+ return dmlFlag;
126
+ }
127
+ }
128
+ findStart(flow) {
129
+ const flowElements = flow.elements.filter((node)=>node instanceof _internals.FlowNode);
130
+ let start;
131
+ if (flow.startElementReference) {
132
+ start = flowElements.findIndex((n)=>{
133
+ return n.name == flow.startElementReference;
134
+ });
135
+ } else {
136
+ start = flowElements.findIndex((n)=>{
137
+ return n.subtype === "start";
138
+ });
139
+ }
140
+ return start;
141
+ }
142
+ constructor(){
143
+ super({
144
+ name: "DuplicateDMLOperation",
145
+ label: "Duplicate DML Operation",
146
+ description: "When the flow executes database changes or actions between two screens, it's important to prevent users from navigating back between screens. Failure to do so may result in duplicate database operations being performed within the flow.",
147
+ supportedTypes: _internals.FlowType.visualTypes,
148
+ docRefs: [],
149
+ isConfigurable: false,
150
+ autoFixable: false
151
+ });
152
+ }
153
+ };
@@ -0,0 +1,6 @@
1
+ import * as core from "../internals/internals";
2
+ import { AdvancedRule } from "../models/AdvancedRule";
3
+ export declare class FlowDescription extends AdvancedRule implements core.IRuleDefinition {
4
+ constructor();
5
+ execute(flow: core.Flow): core.RuleResult;
6
+ }
@@ -0,0 +1,76 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "FlowDescription", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return FlowDescription;
9
+ }
10
+ });
11
+ const _internals = /*#__PURE__*/ _interop_require_wildcard(require("../internals/internals"));
12
+ const _AdvancedRule = require("../models/AdvancedRule");
13
+ function _getRequireWildcardCache(nodeInterop) {
14
+ if (typeof WeakMap !== "function") return null;
15
+ var cacheBabelInterop = new WeakMap();
16
+ var cacheNodeInterop = new WeakMap();
17
+ return (_getRequireWildcardCache = function(nodeInterop) {
18
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
19
+ })(nodeInterop);
20
+ }
21
+ function _interop_require_wildcard(obj, nodeInterop) {
22
+ if (!nodeInterop && obj && obj.__esModule) {
23
+ return obj;
24
+ }
25
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
26
+ return {
27
+ default: obj
28
+ };
29
+ }
30
+ var cache = _getRequireWildcardCache(nodeInterop);
31
+ if (cache && cache.has(obj)) {
32
+ return cache.get(obj);
33
+ }
34
+ var newObj = {
35
+ __proto__: null
36
+ };
37
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
38
+ for(var key in obj){
39
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
40
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
41
+ if (desc && (desc.get || desc.set)) {
42
+ Object.defineProperty(newObj, key, desc);
43
+ } else {
44
+ newObj[key] = obj[key];
45
+ }
46
+ }
47
+ }
48
+ newObj.default = obj;
49
+ if (cache) {
50
+ cache.set(obj, newObj);
51
+ }
52
+ return newObj;
53
+ }
54
+ let FlowDescription = class FlowDescription extends _AdvancedRule.AdvancedRule {
55
+ execute(flow) {
56
+ var _flow_xmldata;
57
+ const missingFlowDescription = !((_flow_xmldata = flow.xmldata) === null || _flow_xmldata === void 0 ? void 0 : _flow_xmldata.description);
58
+ return missingFlowDescription ? new _internals.RuleResult(this, [
59
+ new _internals.ResultDetails(new _internals.FlowAttribute("undefined", "description", "!==null"))
60
+ ]) : new _internals.RuleResult(this, []);
61
+ }
62
+ constructor(){
63
+ super({
64
+ autoFixable: false,
65
+ description: "Descriptions play a vital role in documentation. We highly recommend including details about where they are used and their intended purpose.",
66
+ docRefs: [],
67
+ isConfigurable: false,
68
+ label: "Missing Flow Description",
69
+ name: "FlowDescription",
70
+ supportedTypes: [
71
+ ..._internals.FlowType.backEndTypes,
72
+ ..._internals.FlowType.visualTypes
73
+ ]
74
+ });
75
+ }
76
+ };
@@ -0,0 +1,7 @@
1
+ import { AdvancedConfig } from "../interfaces/AdvancedRuleConfig";
2
+ import * as core from "../internals/internals";
3
+ import { AdvancedRule } from "../models/AdvancedRule";
4
+ export declare class FlowName extends AdvancedRule implements core.IRuleDefinition {
5
+ constructor();
6
+ execute(flow: core.Flow, advancedConfig?: AdvancedConfig): core.RuleResult;
7
+ }
@@ -0,0 +1,80 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "FlowName", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return FlowName;
9
+ }
10
+ });
11
+ const _internals = /*#__PURE__*/ _interop_require_wildcard(require("../internals/internals"));
12
+ const _AdvancedRule = require("../models/AdvancedRule");
13
+ function _getRequireWildcardCache(nodeInterop) {
14
+ if (typeof WeakMap !== "function") return null;
15
+ var cacheBabelInterop = new WeakMap();
16
+ var cacheNodeInterop = new WeakMap();
17
+ return (_getRequireWildcardCache = function(nodeInterop) {
18
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
19
+ })(nodeInterop);
20
+ }
21
+ function _interop_require_wildcard(obj, nodeInterop) {
22
+ if (!nodeInterop && obj && obj.__esModule) {
23
+ return obj;
24
+ }
25
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
26
+ return {
27
+ default: obj
28
+ };
29
+ }
30
+ var cache = _getRequireWildcardCache(nodeInterop);
31
+ if (cache && cache.has(obj)) {
32
+ return cache.get(obj);
33
+ }
34
+ var newObj = {
35
+ __proto__: null
36
+ };
37
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
38
+ for(var key in obj){
39
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
40
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
41
+ if (desc && (desc.get || desc.set)) {
42
+ Object.defineProperty(newObj, key, desc);
43
+ } else {
44
+ newObj[key] = obj[key];
45
+ }
46
+ }
47
+ }
48
+ newObj.default = obj;
49
+ if (cache) {
50
+ cache.set(obj, newObj);
51
+ }
52
+ return newObj;
53
+ }
54
+ let FlowName = class FlowName extends _AdvancedRule.AdvancedRule {
55
+ execute(flow, advancedConfig) {
56
+ const rawRegexp = advancedConfig && advancedConfig.expression ? advancedConfig.expression : "[A-Za-z0-9]+_[A-Za-z0-9]+";
57
+ const regexExp = rawRegexp;
58
+ const flowName = flow.name;
59
+ const conventionApplied = new RegExp(regexExp).test(flowName);
60
+ return !conventionApplied ? new _internals.RuleResult(this, [
61
+ new _internals.ResultDetails(new _internals.FlowAttribute(flowName, "name", regexExp))
62
+ ]) : new _internals.RuleResult(this, []);
63
+ }
64
+ constructor(){
65
+ super({
66
+ autoFixable: false,
67
+ description: "The readability of a flow is of utmost importance. Establishing a naming convention for the Flow Name significantly enhances findability, searchability, and maintains overall consistency. It is advisable to include at least a domain and a brief description of the actions carried out in the flow, for instance, 'Service_OrderFulfillment'.",
68
+ docRefs: [
69
+ {
70
+ label: "Naming your Flows is more critical than ever. By Stephen Church",
71
+ path: "https://www.linkedin.com/posts/stephen-n-church_naming-your-flows-this-is-more-critical-activity-7099733198175158274-1sPx?utm_source=share&utm_medium=member_desktop"
72
+ }
73
+ ],
74
+ isConfigurable: true,
75
+ label: "Flow Naming Convention",
76
+ name: "FlowName",
77
+ supportedTypes: _internals.FlowType.allTypes()
78
+ });
79
+ }
80
+ };
@@ -0,0 +1,6 @@
1
+ import * as core from "../internals/internals";
2
+ import { AdvancedRule } from "../models/AdvancedRule";
3
+ export declare class GetRecordAllFields extends AdvancedRule implements core.IRuleDefinition {
4
+ constructor();
5
+ execute(flow: core.Flow): core.RuleResult;
6
+ }
@@ -0,0 +1,101 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", {
3
+ value: true
4
+ });
5
+ Object.defineProperty(exports, "GetRecordAllFields", {
6
+ enumerable: true,
7
+ get: function() {
8
+ return GetRecordAllFields;
9
+ }
10
+ });
11
+ const _internals = /*#__PURE__*/ _interop_require_wildcard(require("../internals/internals"));
12
+ const _AdvancedRule = require("../models/AdvancedRule");
13
+ function _getRequireWildcardCache(nodeInterop) {
14
+ if (typeof WeakMap !== "function") return null;
15
+ var cacheBabelInterop = new WeakMap();
16
+ var cacheNodeInterop = new WeakMap();
17
+ return (_getRequireWildcardCache = function(nodeInterop) {
18
+ return nodeInterop ? cacheNodeInterop : cacheBabelInterop;
19
+ })(nodeInterop);
20
+ }
21
+ function _interop_require_wildcard(obj, nodeInterop) {
22
+ if (!nodeInterop && obj && obj.__esModule) {
23
+ return obj;
24
+ }
25
+ if (obj === null || typeof obj !== "object" && typeof obj !== "function") {
26
+ return {
27
+ default: obj
28
+ };
29
+ }
30
+ var cache = _getRequireWildcardCache(nodeInterop);
31
+ if (cache && cache.has(obj)) {
32
+ return cache.get(obj);
33
+ }
34
+ var newObj = {
35
+ __proto__: null
36
+ };
37
+ var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor;
38
+ for(var key in obj){
39
+ if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) {
40
+ var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null;
41
+ if (desc && (desc.get || desc.set)) {
42
+ Object.defineProperty(newObj, key, desc);
43
+ } else {
44
+ newObj[key] = obj[key];
45
+ }
46
+ }
47
+ }
48
+ newObj.default = obj;
49
+ if (cache) {
50
+ cache.set(obj, newObj);
51
+ }
52
+ return newObj;
53
+ }
54
+ let GetRecordAllFields = class GetRecordAllFields extends _AdvancedRule.AdvancedRule {
55
+ execute(flow) {
56
+ var _flow_elements;
57
+ const results = [];
58
+ const getElementNodes = (_flow_elements = flow.elements) === null || _flow_elements === void 0 ? void 0 : _flow_elements.filter((element)=>element.subtype === "recordLookups");
59
+ if (getElementNodes == null || getElementNodes.length === 0) {
60
+ return new _internals.RuleResult(this, results);
61
+ }
62
+ const errorNodes = getElementNodes.filter((element)=>{
63
+ const getRecordElement = element;
64
+ const hasQualifiedElementDefinition = typeof getRecordElement.element === "object";
65
+ if (!hasQualifiedElementDefinition) {
66
+ return false;
67
+ }
68
+ const concreteChildElement = getRecordElement.element;
69
+ const storeAllFields = "storeOutputAutomatically" in concreteChildElement && concreteChildElement["storeOutputAutomatically"];
70
+ const hasQueriedFields = "queriedFields" in concreteChildElement && concreteChildElement["queriedFields"].length > 0;
71
+ return storeAllFields && !hasQueriedFields;
72
+ }).map((element)=>{
73
+ const getRecordElement = element;
74
+ return new _internals.ResultDetails(getRecordElement);
75
+ });
76
+ results.push(...errorNodes);
77
+ return new _internals.RuleResult(this, results);
78
+ }
79
+ constructor(){
80
+ super({
81
+ autoFixable: false,
82
+ description: "Following the principle of least privilege (PoLP), avoid using Get Records with 'Automatically store all fields' unless necessary.",
83
+ docRefs: [
84
+ {
85
+ label: "SOQL and SOSL | Best Practices for Deployments with Large Data Volumes",
86
+ path: "https://developer.salesforce.com/docs/atlas.en-us.salesforce_large_data_volumes_bp.meta/salesforce_large_data_volumes_bp/ldv_deployments_best_practices_soql_and_sosl.htm"
87
+ },
88
+ {
89
+ label: "Indexes | Best Practices",
90
+ path: "https://developer.salesforce.com/docs/atlas.en-us.salesforce_large_data_volumes_bp.meta/salesforce_large_data_volumes_bp/ldv_deployments_infrastructure_indexes.htm"
91
+ }
92
+ ],
93
+ isConfigurable: false,
94
+ label: "Get Record All Fields",
95
+ name: "GetRecordAllFields",
96
+ supportedTypes: _internals.FlowType.allTypes()
97
+ }, {
98
+ severity: "warning"
99
+ });
100
+ }
101
+ };
@@ -0,0 +1,6 @@
1
+ import { AdvancedRule } from "../models/AdvancedRule";
2
+ import * as core from "../internals/internals";
3
+ export declare class HardcodedId extends AdvancedRule implements core.IRuleDefinition {
4
+ constructor();
5
+ execute(flow: core.Flow): core.RuleResult;
6
+ }