@flow-scanner/lightning-flow-scanner-core 6.10.5 → 6.11.0
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 +19 -16
- package/index.d.ts +5 -2
- package/index.js +19 -0
- package/main/config/NodeIcons.d.ts +24 -0
- package/main/config/NodeIcons.js +122 -0
- package/main/config/VariableIcons.d.ts +25 -0
- package/main/config/VariableIcons.js +53 -0
- package/main/libs/Compiler.d.ts +1 -2
- package/main/libs/Compiler.js +10 -16
- package/main/libs/ExportDiagram.d.ts +41 -0
- package/main/libs/ExportDiagram.js +40 -0
- package/main/libs/ExportSarif.js +1 -1
- package/main/models/Flow.d.ts +42 -11
- package/main/models/Flow.js +164 -76
- package/main/models/FlowGraph.d.ts +85 -0
- package/main/models/FlowGraph.js +532 -0
- package/main/models/FlowNode.d.ts +58 -2
- package/main/models/FlowNode.js +161 -3
- package/main/models/FlowVariable.d.ts +59 -1
- package/main/models/FlowVariable.js +118 -1
- package/main/models/LoopRuleCommon.js +11 -12
- package/main/models/ParsedFlow.d.ts +1 -1
- package/main/models/RuleCommon.d.ts +30 -7
- package/main/models/RuleCommon.js +49 -11
- package/main/rules/APIVersion.js +31 -1
- package/main/rules/DuplicateDMLOperation.d.ts +1 -2
- package/main/rules/DuplicateDMLOperation.js +35 -73
- package/main/rules/MissingFaultPath.d.ts +4 -0
- package/main/rules/MissingFaultPath.js +19 -15
- package/main/rules/MissingFilterRecordTrigger.js +4 -4
- package/main/rules/RecordIdAsString.js +3 -2
- package/main/rules/RecursiveAfterUpdate.js +7 -4
- package/main/rules/SameRecordFieldUpdates.js +5 -3
- package/main/rules/TriggerOrder.d.ts +0 -1
- package/main/rules/TriggerOrder.js +8 -19
- package/main/rules/UnconnectedElement.d.ts +0 -1
- package/main/rules/UnconnectedElement.js +2 -13
- package/package.json +2 -2
|
@@ -53,88 +53,50 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
53
53
|
}
|
|
54
54
|
let DuplicateDMLOperation = class DuplicateDMLOperation extends _RuleCommon.RuleCommon {
|
|
55
55
|
check(flow, _options, suppressions) {
|
|
56
|
-
const
|
|
57
|
-
const
|
|
58
|
-
|
|
59
|
-
const
|
|
60
|
-
const
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
startingNode
|
|
56
|
+
const graph = flow.graph;
|
|
57
|
+
const start = flow.startReference;
|
|
58
|
+
if (!start) return [];
|
|
59
|
+
const violations = [];
|
|
60
|
+
const visited = new Set();
|
|
61
|
+
const stack = [
|
|
62
|
+
{
|
|
63
|
+
name: start,
|
|
64
|
+
seenDML: false
|
|
65
|
+
}
|
|
67
66
|
];
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
DuplicateDMLOperations.push(nextElement);
|
|
90
|
-
}
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
if (!processedElementIndexes.includes(nextIndex)) {
|
|
94
|
-
indexesToProcess.push(nextIndex);
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
processedElementIndexes.push(index);
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
} else {
|
|
102
|
-
for (const index of flowElements.keys()){
|
|
103
|
-
if (!processedElementIndexes.includes(index)) {
|
|
104
|
-
unconnectedElementIndexes.push(index);
|
|
105
|
-
}
|
|
106
|
-
}
|
|
67
|
+
while(stack.length > 0){
|
|
68
|
+
const { name, seenDML } = stack.pop();
|
|
69
|
+
const stateKey = `${name}:${seenDML}`;
|
|
70
|
+
if (visited.has(stateKey)) continue;
|
|
71
|
+
visited.add(stateKey);
|
|
72
|
+
const node = graph.getNode(name);
|
|
73
|
+
if (!node) continue;
|
|
74
|
+
let nextSeenDML = seenDML || this.isDML(node);
|
|
75
|
+
if (nextSeenDML && node.subtype === "screens" && node.element["allowBack"] === "true" && node.element["showFooter"] === "true" && !suppressions.has(node.name)) {
|
|
76
|
+
violations.push(new _internals.Violation(node));
|
|
77
|
+
// Note: do NOT return early; multiple violations possible
|
|
78
|
+
}
|
|
79
|
+
// Reset DML flag after screen with back disabled
|
|
80
|
+
if (nextSeenDML && node.subtype === "screens" && node.element["allowBack"] !== "true") {
|
|
81
|
+
nextSeenDML = false;
|
|
82
|
+
}
|
|
83
|
+
for (const next of graph.getNextElements(name)){
|
|
84
|
+
stack.push({
|
|
85
|
+
name: next,
|
|
86
|
+
seenDML: nextSeenDML
|
|
87
|
+
});
|
|
107
88
|
}
|
|
108
|
-
}while (processedElementIndexes.length + unconnectedElementIndexes.length < flowElements.length)
|
|
109
|
-
return DuplicateDMLOperations.map((det)=>new _internals.Violation(det));
|
|
110
|
-
}
|
|
111
|
-
findStart(flow) {
|
|
112
|
-
const flowElements = flow.elements.filter((node)=>node instanceof _internals.FlowNode);
|
|
113
|
-
if (flow.startElementReference) {
|
|
114
|
-
return flowElements.findIndex((n)=>n.name === flow.startElementReference);
|
|
115
|
-
} else {
|
|
116
|
-
return flowElements.findIndex((n)=>n.subtype === "start");
|
|
117
89
|
}
|
|
90
|
+
return violations;
|
|
118
91
|
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
"recordDeletes",
|
|
122
|
-
"recordUpdates",
|
|
123
|
-
"recordCreates"
|
|
124
|
-
];
|
|
125
|
-
if (dmlStatementTypes.includes(element.subtype)) {
|
|
126
|
-
return true;
|
|
127
|
-
} else if (dmlFlag === true && element.subtype === "screens" && element.element["allowBack"] === "true") {
|
|
128
|
-
return false;
|
|
129
|
-
} else {
|
|
130
|
-
return dmlFlag;
|
|
131
|
-
}
|
|
92
|
+
isDML(node) {
|
|
93
|
+
return node.subtype === "recordCreates" || node.subtype === "recordUpdates" || node.subtype === "recordDeletes";
|
|
132
94
|
}
|
|
133
95
|
constructor(){
|
|
134
96
|
super({
|
|
135
97
|
name: "DuplicateDMLOperation",
|
|
136
98
|
label: "Duplicate DML Operation",
|
|
137
|
-
description: "When the flow executes database changes
|
|
99
|
+
description: "When the flow executes database changes between screens, users must not be allowed to navigate back, or duplicate DML operations may occur.",
|
|
138
100
|
supportedTypes: _internals.FlowType.visualTypes,
|
|
139
101
|
docRefs: []
|
|
140
102
|
});
|
|
@@ -6,5 +6,9 @@ export declare class MissingFaultPath extends RuleCommon implements IRuleDefinit
|
|
|
6
6
|
constructor();
|
|
7
7
|
private isValidSubtype;
|
|
8
8
|
protected check(flow: core.Flow, _options: object | undefined, suppressions: Set<string>): core.Violation[];
|
|
9
|
+
/**
|
|
10
|
+
* Determine if this is a RecordBeforeSave flow.
|
|
11
|
+
*/
|
|
12
|
+
private isRecordBeforeSaveFlow;
|
|
9
13
|
private isPartOfFaultHandlingFlow;
|
|
10
14
|
}
|
|
@@ -82,14 +82,14 @@ let MissingFaultPath = class MissingFaultPath extends _RuleCommon.RuleCommon {
|
|
|
82
82
|
return true;
|
|
83
83
|
}
|
|
84
84
|
check(flow, _options, suppressions) {
|
|
85
|
-
var
|
|
86
|
-
const compiler = new _internals.Compiler();
|
|
85
|
+
var _flow_graph;
|
|
87
86
|
const results = [];
|
|
88
|
-
const elementsWhereFaultPathIsApplicable =
|
|
87
|
+
const elementsWhereFaultPathIsApplicable = flow.elements.filter((node)=>{
|
|
89
88
|
const proxyNode = node;
|
|
90
89
|
return this.isValidSubtype(proxyNode);
|
|
91
|
-
})
|
|
92
|
-
|
|
90
|
+
}).map((e)=>e.name);
|
|
91
|
+
// Check if this is a RecordBeforeSave flow
|
|
92
|
+
const isRecordBeforeSave = this.isRecordBeforeSaveFlow(flow);
|
|
93
93
|
const visitCallback = (element)=>{
|
|
94
94
|
var _element_connectors;
|
|
95
95
|
if (!(element === null || element === void 0 ? void 0 : (_element_connectors = element.connectors) === null || _element_connectors === void 0 ? void 0 : _element_connectors.find((connector)=>connector.type === "faultConnector")) && elementsWhereFaultPathIsApplicable.includes(element.name)) {
|
|
@@ -104,22 +104,26 @@ let MissingFaultPath = class MissingFaultPath extends _RuleCommon.RuleCommon {
|
|
|
104
104
|
}
|
|
105
105
|
}
|
|
106
106
|
};
|
|
107
|
-
|
|
107
|
+
(_flow_graph = flow.graph) === null || _flow_graph === void 0 ? void 0 : _flow_graph.forEachReachable(visitCallback);
|
|
108
108
|
return results;
|
|
109
109
|
}
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
110
|
+
/**
|
|
111
|
+
* Determine if this is a RecordBeforeSave flow.
|
|
112
|
+
*/ isRecordBeforeSaveFlow(flow) {
|
|
113
|
+
var _flow_startNode;
|
|
114
|
+
if ((_flow_startNode = flow.startNode) === null || _flow_startNode === void 0 ? void 0 : _flow_startNode.element) {
|
|
115
|
+
var _flow_startNode_element;
|
|
116
|
+
const triggerType = (_flow_startNode_element = flow.startNode.element) === null || _flow_startNode_element === void 0 ? void 0 : _flow_startNode_element["triggerType"];
|
|
117
|
+
if (triggerType === "RecordBeforeSave") {
|
|
118
|
+
return true;
|
|
119
119
|
}
|
|
120
120
|
}
|
|
121
121
|
return false;
|
|
122
122
|
}
|
|
123
|
+
isPartOfFaultHandlingFlow(element, flow) {
|
|
124
|
+
var _flow_graph;
|
|
125
|
+
return ((_flow_graph = flow.graph) === null || _flow_graph === void 0 ? void 0 : _flow_graph.isPartOfFaultHandling(element.name)) || false;
|
|
126
|
+
}
|
|
123
127
|
constructor(){
|
|
124
128
|
super({
|
|
125
129
|
description: "At times, a flow may fail to execute a configured operation as intended. By default, the flow displays an error message to the user and notifies the admin who created the flow via email. However, you can customize this behavior by incorporating a Fault Path. This rule checks DML operations, actions (Send Email, Quick Actions), and Invocable Apex Actions for proper error handling.",
|
|
@@ -53,10 +53,10 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
53
53
|
}
|
|
54
54
|
let MissingFilterRecordTrigger = class MissingFilterRecordTrigger extends _RuleCommon.RuleCommon {
|
|
55
55
|
check(flow, _options, _suppressions) {
|
|
56
|
-
var _flow_xmldata_start, _flow_xmldata
|
|
56
|
+
var _flow_xmldata_start, _flow_xmldata;
|
|
57
57
|
const violations = [];
|
|
58
58
|
// Check if this is a record-triggered flow
|
|
59
|
-
const triggerType = (
|
|
59
|
+
const triggerType = this.getStartProperty(flow, 'triggerType');
|
|
60
60
|
// Only check flows with record trigger types
|
|
61
61
|
if (!triggerType || ![
|
|
62
62
|
"RecordAfterSave",
|
|
@@ -65,9 +65,9 @@ let MissingFilterRecordTrigger = class MissingFilterRecordTrigger extends _RuleC
|
|
|
65
65
|
return violations;
|
|
66
66
|
}
|
|
67
67
|
// Check if the flow has filters or entry conditions at the flow level
|
|
68
|
-
const filters = (
|
|
68
|
+
const filters = this.getStartProperty(flow, 'filters');
|
|
69
69
|
const hasFilters = !!filters;
|
|
70
|
-
const scheduledPaths = (
|
|
70
|
+
const scheduledPaths = (_flow_xmldata = flow.xmldata) === null || _flow_xmldata === void 0 ? void 0 : (_flow_xmldata_start = _flow_xmldata.start) === null || _flow_xmldata_start === void 0 ? void 0 : _flow_xmldata_start.scheduledPaths;
|
|
71
71
|
const hasScheduledPaths = !!scheduledPaths;
|
|
72
72
|
// If no filters or scheduled paths (which have their own conditions), flag as violation
|
|
73
73
|
if (!hasFilters && !hasScheduledPaths) {
|
|
@@ -53,10 +53,11 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
53
53
|
}
|
|
54
54
|
let RecordIdAsString = class RecordIdAsString extends _RuleCommon.RuleCommon {
|
|
55
55
|
check(flow, _options, _suppressions) {
|
|
56
|
-
var
|
|
56
|
+
var _flow_elements;
|
|
57
57
|
const violations = [];
|
|
58
58
|
// Skip record-triggered flows - they don't support this pattern
|
|
59
|
-
const
|
|
59
|
+
const triggerType = this.getStartProperty(flow, 'triggerType');
|
|
60
|
+
const isRecordTriggered = triggerType === "RecordAfterSave" || triggerType === "RecordBeforeDelete" || triggerType === "RecordBeforeSave";
|
|
60
61
|
if (isRecordTriggered) {
|
|
61
62
|
return violations;
|
|
62
63
|
}
|
|
@@ -66,10 +66,12 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
66
66
|
}
|
|
67
67
|
let RecursiveAfterUpdate = class RecursiveAfterUpdate extends _RuleCommon.RuleCommon {
|
|
68
68
|
check(flow, _options, suppressions) {
|
|
69
|
-
var
|
|
69
|
+
var _flow_elements, _flow_elements_filter, _flow_elements1;
|
|
70
70
|
const results = [];
|
|
71
|
-
const
|
|
72
|
-
const
|
|
71
|
+
const triggerType = this.getStartProperty(flow, 'triggerType');
|
|
72
|
+
const recordTriggerType = this.getStartProperty(flow, 'recordTriggerType');
|
|
73
|
+
const isAfterSave = triggerType === "RecordAfterSave";
|
|
74
|
+
const isQualifiedTriggerTypes = this.qualifiedRecordTriggerTypes.has(recordTriggerType);
|
|
73
75
|
if (!isAfterSave || !isQualifiedTriggerTypes) {
|
|
74
76
|
return results;
|
|
75
77
|
}
|
|
@@ -86,7 +88,8 @@ let RecursiveAfterUpdate = class RecursiveAfterUpdate extends _RuleCommon.RuleCo
|
|
|
86
88
|
}
|
|
87
89
|
}
|
|
88
90
|
// === Lookup → same object type updates ===
|
|
89
|
-
const
|
|
91
|
+
const flowObject = this.getStartProperty(flow, 'object');
|
|
92
|
+
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 && flowObject === node.element["object"])) === null || _flow_elements_filter === void 0 ? void 0 : _flow_elements_filter.map((node)=>node.name);
|
|
90
93
|
if (lookupElementsWithTheSameObjectType == null || typeof lookupElementsWithTheSameObjectType[Symbol.iterator] !== "function") {
|
|
91
94
|
return results;
|
|
92
95
|
}
|
|
@@ -66,10 +66,12 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
66
66
|
}
|
|
67
67
|
let SameRecordFieldUpdates = class SameRecordFieldUpdates extends _RuleCommon.RuleCommon {
|
|
68
68
|
check(flow, _options, _suppressions) {
|
|
69
|
-
var
|
|
69
|
+
var _flow_elements;
|
|
70
70
|
const results = [];
|
|
71
|
-
const
|
|
72
|
-
const
|
|
71
|
+
const triggerType = this.getStartProperty(flow, 'triggerType');
|
|
72
|
+
const recordTriggerType = this.getStartProperty(flow, 'recordTriggerType');
|
|
73
|
+
const isBeforeSaveType = triggerType === "RecordBeforeSave";
|
|
74
|
+
const isQualifiedTriggerTypes = this.qualifiedRecordTriggerTypes.has(recordTriggerType);
|
|
73
75
|
if (!isBeforeSaveType || !isQualifiedTriggerTypes) {
|
|
74
76
|
return results;
|
|
75
77
|
}
|
|
@@ -2,7 +2,6 @@ import * as core from "../internals/internals";
|
|
|
2
2
|
import { RuleCommon } from "../models/RuleCommon";
|
|
3
3
|
import { IRuleDefinition } from "../interfaces/IRuleDefinition";
|
|
4
4
|
export declare class TriggerOrder extends RuleCommon implements IRuleDefinition {
|
|
5
|
-
protected qualifiedRecordTriggerTypes: Set<string>;
|
|
6
5
|
constructor();
|
|
7
6
|
protected check(flow: core.Flow, _options: object | undefined, _suppressions: Set<string>): core.Violation[];
|
|
8
7
|
}
|
|
@@ -10,19 +10,6 @@ Object.defineProperty(exports, "TriggerOrder", {
|
|
|
10
10
|
});
|
|
11
11
|
const _internals = /*#__PURE__*/ _interop_require_wildcard(require("../internals/internals"));
|
|
12
12
|
const _RuleCommon = require("../models/RuleCommon");
|
|
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
13
|
function _getRequireWildcardCache(nodeInterop) {
|
|
27
14
|
if (typeof WeakMap !== "function") return null;
|
|
28
15
|
var cacheBabelInterop = new WeakMap();
|
|
@@ -66,7 +53,12 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
66
53
|
}
|
|
67
54
|
let TriggerOrder = class TriggerOrder extends _RuleCommon.RuleCommon {
|
|
68
55
|
check(flow, _options, _suppressions) {
|
|
69
|
-
|
|
56
|
+
const startObject = this.getStartProperty(flow, "object");
|
|
57
|
+
// If there's no `object` on the start node, this is NOT a record-triggered flow
|
|
58
|
+
if (!startObject) {
|
|
59
|
+
return [];
|
|
60
|
+
}
|
|
61
|
+
// This *is* a record-triggered flow → should have triggerOrder
|
|
70
62
|
if (!flow.triggerOrder) {
|
|
71
63
|
return [
|
|
72
64
|
new _internals.Violation(new _internals.FlowAttribute("TriggerOrder", "TriggerOrder", "10, 20, 30 ..."))
|
|
@@ -78,7 +70,7 @@ let TriggerOrder = class TriggerOrder extends _RuleCommon.RuleCommon {
|
|
|
78
70
|
super({
|
|
79
71
|
name: "TriggerOrder",
|
|
80
72
|
label: "Trigger Order",
|
|
81
|
-
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.",
|
|
73
|
+
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.",
|
|
82
74
|
supportedTypes: [
|
|
83
75
|
_internals.FlowType.autolaunchedType
|
|
84
76
|
],
|
|
@@ -90,9 +82,6 @@ let TriggerOrder = class TriggerOrder extends _RuleCommon.RuleCommon {
|
|
|
90
82
|
]
|
|
91
83
|
}, {
|
|
92
84
|
severity: "note"
|
|
93
|
-
})
|
|
94
|
-
"Create",
|
|
95
|
-
"Update"
|
|
96
|
-
]));
|
|
85
|
+
});
|
|
97
86
|
}
|
|
98
87
|
};
|
|
@@ -4,5 +4,4 @@ import { IRuleDefinition } from "../interfaces/IRuleDefinition";
|
|
|
4
4
|
export declare class UnconnectedElement extends RuleCommon implements IRuleDefinition {
|
|
5
5
|
constructor();
|
|
6
6
|
protected check(flow: core.Flow, _options: object | undefined, suppressions: Set<string>): core.Violation[];
|
|
7
|
-
private findStart;
|
|
8
7
|
}
|
|
@@ -53,23 +53,12 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
53
53
|
}
|
|
54
54
|
let UnconnectedElement = class UnconnectedElement extends _RuleCommon.RuleCommon {
|
|
55
55
|
check(flow, _options, suppressions) {
|
|
56
|
-
|
|
57
|
-
const
|
|
58
|
-
connectedElements.add(element.name);
|
|
59
|
-
};
|
|
56
|
+
var _flow_graph;
|
|
57
|
+
const connectedElements = ((_flow_graph = flow.graph) === null || _flow_graph === void 0 ? void 0 : _flow_graph.getReachableElements()) || new Set();
|
|
60
58
|
const flowElements = flow.elements.filter((node)=>node instanceof _internals.FlowNode);
|
|
61
|
-
const startIndex = this.findStart(flowElements);
|
|
62
|
-
if (startIndex !== -1) {
|
|
63
|
-
new _internals.Compiler().traverseFlow(flow, flowElements[startIndex].name, logConnected);
|
|
64
|
-
}
|
|
65
59
|
const unconnectedElements = flowElements.filter((element)=>!connectedElements.has(element.name) && !suppressions.has(element.name));
|
|
66
60
|
return unconnectedElements.map((det)=>new _internals.Violation(det));
|
|
67
61
|
}
|
|
68
|
-
findStart(nodes) {
|
|
69
|
-
return nodes.findIndex((n)=>{
|
|
70
|
-
return n.subtype === "start";
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
62
|
constructor(){
|
|
74
63
|
super({
|
|
75
64
|
description: "To maintain the efficiency and manageability of your Flow, it's best to avoid including unconnected elements that are not in use.",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@flow-scanner/lightning-flow-scanner-core",
|
|
3
3
|
"description": "A lightweight engine for Flow metadata in Node.js, and browser environments. Assess and enhance Salesforce Flow automations for best practices, security, governor limits, and performance issues.",
|
|
4
|
-
"version": "6.
|
|
4
|
+
"version": "6.11.0",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
"dependencies": {
|
|
23
23
|
"fast-xml-parser": "^5.3.0"
|
|
24
24
|
},
|
|
25
|
-
"homepage": "https://
|
|
25
|
+
"homepage": "https://flow-scanner.github.io/lightning-flow-scanner/",
|
|
26
26
|
"author": {
|
|
27
27
|
"name": "Ruben Halman",
|
|
28
28
|
"url": "https://github.com/RubenHalman"
|