@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.
- package/CONTRIBUTING.md +30 -0
- package/LICENSE.md +21 -0
- package/README.md +314 -0
- package/SECURITY.md +26 -0
- package/assets/media/bannerslim.png +0 -0
- package/index.d.ts +21 -0
- package/index.js +83 -0
- package/main/interfaces/AdvancedRuleConfig.d.ts +11 -0
- package/main/interfaces/AdvancedRuleConfig.js +4 -0
- package/main/interfaces/AdvancedRuleDefintion.d.ts +5 -0
- package/main/interfaces/AdvancedRuleDefintion.js +4 -0
- package/main/interfaces/AdvancedSuppression.d.ts +21 -0
- package/main/interfaces/AdvancedSuppression.js +4 -0
- package/main/interfaces/AutoFixable.d.ts +10 -0
- package/main/interfaces/AutoFixable.js +4 -0
- package/main/interfaces/IExceptions.d.ts +5 -0
- package/main/interfaces/IExceptions.js +4 -0
- package/main/interfaces/IRuleConfig.d.ts +3 -0
- package/main/interfaces/IRuleConfig.js +4 -0
- package/main/interfaces/IRuleDefinition.d.ts +17 -0
- package/main/interfaces/IRuleDefinition.js +4 -0
- package/main/interfaces/IRuleOptions.d.ts +4 -0
- package/main/interfaces/IRuleOptions.js +4 -0
- package/main/interfaces/IRulesConfig.d.ts +8 -0
- package/main/interfaces/IRulesConfig.js +4 -0
- package/main/internals/internals.d.ts +17 -0
- package/main/internals/internals.js +64 -0
- package/main/libs/BuildFlow.d.ts +1 -0
- package/main/libs/BuildFlow.js +20 -0
- package/main/libs/Compiler.d.ts +8 -0
- package/main/libs/Compiler.js +70 -0
- package/main/libs/ConvertFlowNodes.d.ts +1 -0
- package/main/libs/ConvertFlowNodes.js +14 -0
- package/main/libs/DynamicRule.d.ts +5 -0
- package/main/libs/DynamicRule.js +19 -0
- package/main/libs/FixFlows.d.ts +3 -0
- package/main/libs/FixFlows.js +110 -0
- package/main/libs/GetRuleDefinitions.d.ts +5 -0
- package/main/libs/GetRuleDefinitions.js +81 -0
- package/main/libs/ParseFlows.d.ts +2 -0
- package/main/libs/ParseFlows.js +111 -0
- package/main/libs/Scan2.d.ts +3 -0
- package/main/libs/Scan2.js +124 -0
- package/main/libs/ScanFlows.d.ts +4 -0
- package/main/libs/ScanFlows.js +103 -0
- package/main/models/AdvancedRule.d.ts +44 -0
- package/main/models/AdvancedRule.js +84 -0
- package/main/models/Flow.d.ts +33 -0
- package/main/models/Flow.js +277 -0
- package/main/models/FlowAttribute.d.ts +7 -0
- package/main/models/FlowAttribute.js +34 -0
- package/main/models/FlowElement.d.ts +10 -0
- package/main/models/FlowElement.js +37 -0
- package/main/models/FlowElementConnector.d.ts +15 -0
- package/main/models/FlowElementConnector.js +50 -0
- package/main/models/FlowMetadata.d.ts +4 -0
- package/main/models/FlowMetadata.js +16 -0
- package/main/models/FlowNode.d.ts +10 -0
- package/main/models/FlowNode.js +169 -0
- package/main/models/FlowResource.d.ts +5 -0
- package/main/models/FlowResource.js +30 -0
- package/main/models/FlowType.d.ts +23 -0
- package/main/models/FlowType.js +80 -0
- package/main/models/FlowVariable.d.ts +6 -0
- package/main/models/FlowVariable.js +31 -0
- package/main/models/LoopRuleCommon.d.ts +9 -0
- package/main/models/LoopRuleCommon.js +48 -0
- package/main/models/ParsedFlow.d.ts +7 -0
- package/main/models/ParsedFlow.js +35 -0
- package/main/models/ResultDetails.d.ts +10 -0
- package/main/models/ResultDetails.js +57 -0
- package/main/models/RuleCommon.d.ts +19 -0
- package/main/models/RuleCommon.js +48 -0
- package/main/models/RuleInfo.d.ts +55 -0
- package/main/models/RuleInfo.js +61 -0
- package/main/models/RuleResult.d.ts +11 -0
- package/main/models/RuleResult.js +44 -0
- package/main/models/ScanResult.d.ts +7 -0
- package/main/models/ScanResult.js +31 -0
- package/main/rules/APIVersion.d.ts +8 -0
- package/main/rules/APIVersion.js +86 -0
- package/main/rules/ActionCallsInLoop.d.ts +6 -0
- package/main/rules/ActionCallsInLoop.js +38 -0
- package/main/rules/AutoLayout.d.ts +8 -0
- package/main/rules/AutoLayout.js +78 -0
- package/main/rules/CopyAPIName.d.ts +6 -0
- package/main/rules/CopyAPIName.js +82 -0
- package/main/rules/CyclomaticComplexity.d.ts +10 -0
- package/main/rules/CyclomaticComplexity.js +111 -0
- package/main/rules/DMLStatementInLoop.d.ts +6 -0
- package/main/rules/DMLStatementInLoop.js +37 -0
- package/main/rules/DuplicateDMLOperation.d.ts +8 -0
- package/main/rules/DuplicateDMLOperation.js +153 -0
- package/main/rules/FlowDescription.d.ts +6 -0
- package/main/rules/FlowDescription.js +76 -0
- package/main/rules/FlowName.d.ts +7 -0
- package/main/rules/FlowName.js +80 -0
- package/main/rules/GetRecordAllFields.d.ts +6 -0
- package/main/rules/GetRecordAllFields.js +101 -0
- package/main/rules/HardcodedId.d.ts +6 -0
- package/main/rules/HardcodedId.js +87 -0
- package/main/rules/HardcodedUrl.d.ts +6 -0
- package/main/rules/HardcodedUrl.js +50 -0
- package/main/rules/InactiveFlow.d.ts +6 -0
- package/main/rules/InactiveFlow.js +73 -0
- package/main/rules/MissingFaultPath.d.ts +12 -0
- package/main/rules/MissingFaultPath.js +161 -0
- package/main/rules/MissingNullHandler.d.ts +6 -0
- package/main/rules/MissingNullHandler.js +152 -0
- package/main/rules/ProcessBuilder.d.ts +8 -0
- package/main/rules/ProcessBuilder.js +77 -0
- package/main/rules/RecursiveAfterUpdate.d.ts +7 -0
- package/main/rules/RecursiveAfterUpdate.js +124 -0
- package/main/rules/SOQLQueryInLoop.d.ts +6 -0
- package/main/rules/SOQLQueryInLoop.js +35 -0
- package/main/rules/SameRecordFieldUpdates.d.ts +7 -0
- package/main/rules/SameRecordFieldUpdates.js +111 -0
- package/main/rules/TriggerOrder.d.ts +7 -0
- package/main/rules/TriggerOrder.js +101 -0
- package/main/rules/UnconnectedElement.d.ts +7 -0
- package/main/rules/UnconnectedElement.js +93 -0
- package/main/rules/UnsafeRunningContext.d.ts +6 -0
- package/main/rules/UnsafeRunningContext.js +86 -0
- package/main/rules/UnusedVariable.d.ts +6 -0
- package/main/rules/UnusedVariable.js +100 -0
- package/main/store/DefaultRuleStore.d.ts +2 -0
- package/main/store/DefaultRuleStore.js +68 -0
- package/package.json +88 -0
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "RecursiveAfterUpdate", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return RecursiveAfterUpdate;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _internals = /*#__PURE__*/ _interop_require_wildcard(require("../internals/internals"));
|
|
12
|
+
const _AdvancedRule = require("../models/AdvancedRule");
|
|
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 RecursiveAfterUpdate = class RecursiveAfterUpdate extends _AdvancedRule.AdvancedRule {
|
|
68
|
+
execute(flow) {
|
|
69
|
+
var _flow_start, _flow_start1, _flow_elements, _flow_elements_filter, _flow_elements1;
|
|
70
|
+
const results = [];
|
|
71
|
+
const isAfterSave = ((_flow_start = flow.start) === null || _flow_start === void 0 ? void 0 : _flow_start.triggerType) === "RecordAfterSave";
|
|
72
|
+
const isQualifiedTriggerTypes = this.qualifiedRecordTriggerTypes.has((_flow_start1 = flow.start) === null || _flow_start1 === void 0 ? void 0 : _flow_start1.recordTriggerType);
|
|
73
|
+
if (!isAfterSave || !isQualifiedTriggerTypes) {
|
|
74
|
+
return new _internals.RuleResult(this, results);
|
|
75
|
+
}
|
|
76
|
+
const potentialElements = (_flow_elements = flow.elements) === null || _flow_elements === void 0 ? void 0 : _flow_elements.filter((node)=>node.subtype === "recordUpdates");
|
|
77
|
+
if (potentialElements == null || typeof potentialElements[Symbol.iterator] !== "function") {
|
|
78
|
+
return new _internals.RuleResult(this, results);
|
|
79
|
+
}
|
|
80
|
+
for (const node of potentialElements){
|
|
81
|
+
if (typeof node.element === "object" && "inputReference" in node.element && node.element.inputReference === "$Record") {
|
|
82
|
+
results.push(new _internals.ResultDetails(node));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
// do another search for record updates from lookups with the same object type
|
|
86
|
+
// and check whether there is references on record updates
|
|
87
|
+
const lookupElementsWithTheSameObjectType = (_flow_elements1 = flow.elements) === null || _flow_elements1 === void 0 ? void 0 : (_flow_elements_filter = _flow_elements1.filter((node)=>node.subtype === "recordLookups" && typeof node.element === "object" && "object" in node.element && flow.start.object === node.element["object"])) === null || _flow_elements_filter === void 0 ? void 0 : _flow_elements_filter.map((node)=>{
|
|
88
|
+
return node.name;
|
|
89
|
+
});
|
|
90
|
+
if (lookupElementsWithTheSameObjectType == null || typeof lookupElementsWithTheSameObjectType[Symbol.iterator] !== "function") {
|
|
91
|
+
return new _internals.RuleResult(this, results);
|
|
92
|
+
}
|
|
93
|
+
for (const node of potentialElements){
|
|
94
|
+
if (typeof node.element === "object" && "inputReference" in node.element && lookupElementsWithTheSameObjectType.includes(node.element.inputReference)) {
|
|
95
|
+
results.push(new _internals.ResultDetails(node));
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return new _internals.RuleResult(this, results);
|
|
99
|
+
}
|
|
100
|
+
constructor(){
|
|
101
|
+
super({
|
|
102
|
+
autoFixable: false,
|
|
103
|
+
description: "After updates are meant to be used for record modifications that are not the same record that triggered the flow. Using after updates on the same record can lead to recursion and unexpected behavior. Consider using before save flows for same record updates.",
|
|
104
|
+
docRefs: [
|
|
105
|
+
{
|
|
106
|
+
label: "Learn about same record field updates",
|
|
107
|
+
path: "https://architect.salesforce.com/decision-guides/trigger-automation#Same_Record_Field_Updates"
|
|
108
|
+
}
|
|
109
|
+
],
|
|
110
|
+
isConfigurable: false,
|
|
111
|
+
label: "Recursive After Update",
|
|
112
|
+
name: "RecursiveAfterUpdate",
|
|
113
|
+
supportedTypes: [
|
|
114
|
+
..._internals.FlowType.backEndTypes
|
|
115
|
+
]
|
|
116
|
+
}, {
|
|
117
|
+
severity: "warning"
|
|
118
|
+
}), _define_property(this, "qualifiedRecordTriggerTypes", new Set([
|
|
119
|
+
"Create",
|
|
120
|
+
"CreateAndUpdate",
|
|
121
|
+
"Update"
|
|
122
|
+
]));
|
|
123
|
+
}
|
|
124
|
+
};
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { IRuleDefinition } from "../internals/internals";
|
|
2
|
+
import { LoopRuleCommon } from "../models/LoopRuleCommon";
|
|
3
|
+
export declare class SOQLQueryInLoop extends LoopRuleCommon implements IRuleDefinition {
|
|
4
|
+
constructor();
|
|
5
|
+
protected getStatementTypes(): string[];
|
|
6
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "SOQLQueryInLoop", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return SOQLQueryInLoop;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _internals = require("../internals/internals");
|
|
12
|
+
const _LoopRuleCommon = require("../models/LoopRuleCommon");
|
|
13
|
+
let SOQLQueryInLoop = class SOQLQueryInLoop extends _LoopRuleCommon.LoopRuleCommon {
|
|
14
|
+
getStatementTypes() {
|
|
15
|
+
return [
|
|
16
|
+
"recordLookups"
|
|
17
|
+
];
|
|
18
|
+
}
|
|
19
|
+
constructor(){
|
|
20
|
+
super({
|
|
21
|
+
autoFixable: false,
|
|
22
|
+
description: "To prevent exceeding Apex governor limits, it is advisable to consolidate all your SOQL queries at the conclusion of the flow.",
|
|
23
|
+
docRefs: [
|
|
24
|
+
{
|
|
25
|
+
label: "Flow Best Practices",
|
|
26
|
+
path: "https://help.salesforce.com/s/articleView?id=sf.flow_prep_bestpractices.htm&type=5"
|
|
27
|
+
}
|
|
28
|
+
],
|
|
29
|
+
isConfigurable: false,
|
|
30
|
+
label: "SOQL Query In A Loop",
|
|
31
|
+
name: "SOQLQueryInLoop",
|
|
32
|
+
supportedTypes: _internals.FlowType.backEndTypes
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as core from "../internals/internals";
|
|
2
|
+
import { AdvancedRule } from "../models/AdvancedRule";
|
|
3
|
+
export declare class SameRecordFieldUpdates extends AdvancedRule implements core.IRuleDefinition {
|
|
4
|
+
protected qualifiedRecordTriggerTypes: Set<string>;
|
|
5
|
+
constructor();
|
|
6
|
+
execute(flow: core.Flow): core.RuleResult;
|
|
7
|
+
}
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "SameRecordFieldUpdates", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return SameRecordFieldUpdates;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _internals = /*#__PURE__*/ _interop_require_wildcard(require("../internals/internals"));
|
|
12
|
+
const _AdvancedRule = require("../models/AdvancedRule");
|
|
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 SameRecordFieldUpdates = class SameRecordFieldUpdates extends _AdvancedRule.AdvancedRule {
|
|
68
|
+
execute(flow) {
|
|
69
|
+
var _flow_start, _flow_start1, _flow_elements;
|
|
70
|
+
const results = [];
|
|
71
|
+
const isBeforeSaveType = ((_flow_start = flow.start) === null || _flow_start === void 0 ? void 0 : _flow_start.triggerType) === "RecordBeforeSave";
|
|
72
|
+
const isQualifiedTriggerTypes = this.qualifiedRecordTriggerTypes.has((_flow_start1 = flow.start) === null || _flow_start1 === void 0 ? void 0 : _flow_start1.recordTriggerType);
|
|
73
|
+
if (!isBeforeSaveType || !isQualifiedTriggerTypes) {
|
|
74
|
+
return new _internals.RuleResult(this, results);
|
|
75
|
+
}
|
|
76
|
+
const potentialElements = (_flow_elements = flow.elements) === null || _flow_elements === void 0 ? void 0 : _flow_elements.filter((node)=>node.subtype === "recordUpdates");
|
|
77
|
+
if (potentialElements == null || typeof potentialElements[Symbol.iterator] !== "function") {
|
|
78
|
+
return new _internals.RuleResult(this, results);
|
|
79
|
+
}
|
|
80
|
+
for (const node of potentialElements){
|
|
81
|
+
if (typeof node.element === "object" && "inputReference" in node.element && node.element.inputReference === "$Record") {
|
|
82
|
+
results.push(new _internals.ResultDetails(node));
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
return new _internals.RuleResult(this, results);
|
|
86
|
+
}
|
|
87
|
+
constructor(){
|
|
88
|
+
super({
|
|
89
|
+
name: "SameRecordFieldUpdates",
|
|
90
|
+
label: "Same Record Field Updates",
|
|
91
|
+
description: "Before-save same-record field updates allows you to update the record using variable assignments to `$Record`. This is significantly faster than doing another DML on the same-record that triggered the flow",
|
|
92
|
+
supportedTypes: [
|
|
93
|
+
..._internals.FlowType.backEndTypes
|
|
94
|
+
],
|
|
95
|
+
docRefs: [
|
|
96
|
+
{
|
|
97
|
+
label: "Learn about same record field updates",
|
|
98
|
+
path: "https://architect.salesforce.com/decision-guides/trigger-automation#Same_Record_Field_Updates"
|
|
99
|
+
}
|
|
100
|
+
],
|
|
101
|
+
isConfigurable: false,
|
|
102
|
+
autoFixable: false
|
|
103
|
+
}, {
|
|
104
|
+
severity: "warning"
|
|
105
|
+
}), _define_property(this, "qualifiedRecordTriggerTypes", new Set([
|
|
106
|
+
"Create",
|
|
107
|
+
"Update",
|
|
108
|
+
"CreateAndUpdate"
|
|
109
|
+
]));
|
|
110
|
+
}
|
|
111
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as core from "../internals/internals";
|
|
2
|
+
import { AdvancedRule } from "../models/AdvancedRule";
|
|
3
|
+
export declare class TriggerOrder extends AdvancedRule implements core.IRuleDefinition {
|
|
4
|
+
protected qualifiedRecordTriggerTypes: Set<string>;
|
|
5
|
+
constructor();
|
|
6
|
+
execute(flow: core.Flow): core.RuleResult;
|
|
7
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "TriggerOrder", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return TriggerOrder;
|
|
9
|
+
}
|
|
10
|
+
});
|
|
11
|
+
const _internals = /*#__PURE__*/ _interop_require_wildcard(require("../internals/internals"));
|
|
12
|
+
const _AdvancedRule = require("../models/AdvancedRule");
|
|
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 TriggerOrder = class TriggerOrder extends _AdvancedRule.AdvancedRule {
|
|
68
|
+
execute(flow) {
|
|
69
|
+
const results = [];
|
|
70
|
+
if (!("object" in flow.start)) {
|
|
71
|
+
return new _internals.RuleResult(this, results);
|
|
72
|
+
}
|
|
73
|
+
if (!flow.triggerOrder) {
|
|
74
|
+
results.push(new _internals.ResultDetails(new _internals.FlowAttribute("TriggerOrder", "TriggerOrder", "10, 20, 30 ...")));
|
|
75
|
+
}
|
|
76
|
+
return new _internals.RuleResult(this, results);
|
|
77
|
+
}
|
|
78
|
+
constructor(){
|
|
79
|
+
super({
|
|
80
|
+
name: "TriggerOrder",
|
|
81
|
+
label: "Trigger Order",
|
|
82
|
+
description: "With flow trigger ordering, introduced in Spring '22, admins can now assign a priority value to their flows and guarantee their execution order. This priority value is not an absolute value, so the values need not be sequentially numbered as 1, 2, 3, and so on.",
|
|
83
|
+
supportedTypes: [
|
|
84
|
+
_internals.FlowType.autolaunchedType
|
|
85
|
+
],
|
|
86
|
+
docRefs: [
|
|
87
|
+
{
|
|
88
|
+
label: "Learn more about flow ordering orchestration",
|
|
89
|
+
path: "https://architect.salesforce.com/decision-guides/trigger-automation#Ordering___Orchestration"
|
|
90
|
+
}
|
|
91
|
+
],
|
|
92
|
+
isConfigurable: false,
|
|
93
|
+
autoFixable: false
|
|
94
|
+
}, {
|
|
95
|
+
severity: "note"
|
|
96
|
+
}), _define_property(this, "qualifiedRecordTriggerTypes", new Set([
|
|
97
|
+
"Create",
|
|
98
|
+
"Update"
|
|
99
|
+
]));
|
|
100
|
+
}
|
|
101
|
+
};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import * as core from "../internals/internals";
|
|
2
|
+
import { AdvancedRule } from "../models/AdvancedRule";
|
|
3
|
+
export declare class UnconnectedElement extends AdvancedRule implements core.IRuleDefinition {
|
|
4
|
+
constructor();
|
|
5
|
+
execute(flow: core.Flow): core.RuleResult;
|
|
6
|
+
private findStart;
|
|
7
|
+
}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "UnconnectedElement", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return UnconnectedElement;
|
|
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 UnconnectedElement = class UnconnectedElement extends _AdvancedRule.AdvancedRule {
|
|
55
|
+
execute(flow) {
|
|
56
|
+
const connectedElements = new Set();
|
|
57
|
+
// Callback function to log connected elements
|
|
58
|
+
const logConnected = (element)=>{
|
|
59
|
+
connectedElements.add(element.name);
|
|
60
|
+
};
|
|
61
|
+
// Get Traversable Nodes
|
|
62
|
+
const flowElements = flow.elements.filter((node)=>node instanceof _internals.FlowNode);
|
|
63
|
+
// Find start of Flow
|
|
64
|
+
const startIndex = this.findStart(flowElements);
|
|
65
|
+
// Start traversal from the start node
|
|
66
|
+
if (startIndex !== -1) {
|
|
67
|
+
new _internals.Compiler().traverseFlow(flow, flowElements[startIndex].name, logConnected);
|
|
68
|
+
}
|
|
69
|
+
const unconnectedElements = flowElements.filter((element)=>!connectedElements.has(element.name));
|
|
70
|
+
// Create result details
|
|
71
|
+
const results = unconnectedElements.map((det)=>new _internals.ResultDetails(det));
|
|
72
|
+
return new _internals.RuleResult(this, results);
|
|
73
|
+
}
|
|
74
|
+
findStart(nodes) {
|
|
75
|
+
return nodes.findIndex((n)=>{
|
|
76
|
+
return n.subtype === "start";
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
constructor(){
|
|
80
|
+
super({
|
|
81
|
+
autoFixable: true,
|
|
82
|
+
description: "To maintain the efficiency and manageability of your Flow, it's best to avoid including unconnected elements that are not in use.",
|
|
83
|
+
docRefs: [],
|
|
84
|
+
isConfigurable: false,
|
|
85
|
+
label: "Unconnected Element",
|
|
86
|
+
name: "UnconnectedElement",
|
|
87
|
+
supportedTypes: [
|
|
88
|
+
..._internals.FlowType.backEndTypes,
|
|
89
|
+
..._internals.FlowType.visualTypes
|
|
90
|
+
]
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
};
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", {
|
|
3
|
+
value: true
|
|
4
|
+
});
|
|
5
|
+
Object.defineProperty(exports, "UnsafeRunningContext", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
8
|
+
return UnsafeRunningContext;
|
|
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 UnsafeRunningContext = class UnsafeRunningContext extends _AdvancedRule.AdvancedRule {
|
|
55
|
+
execute(flow) {
|
|
56
|
+
const hasRunInMode = "runInMode" in flow.xmldata;
|
|
57
|
+
const runInMode = hasRunInMode ? flow.xmldata.runInMode : undefined;
|
|
58
|
+
const riskyMode = "SystemModeWithoutSharing";
|
|
59
|
+
const results = [];
|
|
60
|
+
if (hasRunInMode && runInMode === riskyMode) {
|
|
61
|
+
results.push(new _internals.ResultDetails(new _internals.FlowAttribute(runInMode, "runInMode", `== ${riskyMode}`)));
|
|
62
|
+
}
|
|
63
|
+
return new _internals.RuleResult(this, results);
|
|
64
|
+
}
|
|
65
|
+
constructor(){
|
|
66
|
+
super({
|
|
67
|
+
name: "UnsafeRunningContext",
|
|
68
|
+
label: "Unsafe Running Context",
|
|
69
|
+
description: `This flow is configured to run in System Mode without Sharing. This system context grants all running users the permission to view and edit all data in your org. Running a flow in System Mode without Sharing can lead to unsafe data access.`,
|
|
70
|
+
supportedTypes: [
|
|
71
|
+
..._internals.FlowType.backEndTypes,
|
|
72
|
+
..._internals.FlowType.visualTypes
|
|
73
|
+
],
|
|
74
|
+
docRefs: [
|
|
75
|
+
{
|
|
76
|
+
label: "Learn about data safety when running flows in system context in Salesforce Help",
|
|
77
|
+
path: "https://help.salesforce.com/s/articleView?id=sf.flow_distribute_context_data_safety_system_context.htm&type=5"
|
|
78
|
+
}
|
|
79
|
+
],
|
|
80
|
+
isConfigurable: false,
|
|
81
|
+
autoFixable: false
|
|
82
|
+
}, {
|
|
83
|
+
severity: "warning"
|
|
84
|
+
});
|
|
85
|
+
}
|
|
86
|
+
};
|