@flow-scanner/lightning-flow-scanner-core 6.17.2 β 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 +216 -216
- package/main/models/FlowGraph.d.ts +11 -0
- package/main/models/FlowGraph.js +18 -7
- package/main/rules/MissingRecordTriggerFilter.js +4 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -55,221 +55,221 @@
|
|
|
55
55
|
|
|
56
56
|
> Want to help improve this project? See our [Contributing Guidelines](https://github.com/Flow-Scanner/lightning-flow-scanner?tab=contributing-ov-file)
|
|
57
57
|
|
|
58
|
-
<!-- START GENERATED_RULES -->
|
|
59
|
-
|
|
60
|
-
---
|
|
61
|
-
|
|
62
|
-
### Problems
|
|
63
|
-
|
|
64
|
-
These rules detect anti-patterns and unsafe practices in your Flows that could break functionality, compromise security, or cause deployment failures.
|
|
65
|
-
|
|
66
|
-
#### DML Statement In A Loop
|
|
67
|
-
Executing DML operations (insert, update, delete) inside a loop is a high-risk anti-pattern that frequently causes governor limit exceptions. All database operations should be collected and executed once, outside the loop.
|
|
68
|
-
|
|
69
|
-
**Rule ID:** `dml-in-loop`
|
|
70
|
-
**Class Name:** _[DMLStatementInLoop](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/DMLStatementInLoop.ts)_
|
|
71
|
-
**Severity:** π΄ *Error*
|
|
72
|
-
|
|
73
|
-
#### Hardcoded Salesforce Id
|
|
74
|
-
Avoid hard-coding record IDs, as they are unique to a specific org and will not work in other environments. Instead, store IDs in variablesβsuch as merge-field URL parameters or a **Get Records** elementβto make the Flow portable, maintainable, and flexible.
|
|
75
|
-
|
|
76
|
-
**Rule ID:** `hardcoded-id`
|
|
77
|
-
**Class Name:** _[HardcodedId](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/HardcodedId.ts)_
|
|
78
|
-
**Severity:** π΄ *Error*
|
|
79
|
-
|
|
80
|
-
#### Hardcoded Salesforce Url
|
|
81
|
-
Avoid hard-coding URLs, as they may change between environments or over time. Instead, store URLs in variables or custom settings to make the Flow adaptable, maintainable, and environment-independent.
|
|
82
|
-
|
|
83
|
-
**Rule ID:** `hardcoded-url`
|
|
84
|
-
**Class Name:** _[HardcodedUrl](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/HardcodedUrl.ts)_
|
|
85
|
-
**Severity:** π΄ *Error*
|
|
86
|
-
|
|
87
|
-
#### Hardcoded Secret 
|
|
88
|
-
Avoid hardcoding secrets, API keys, tokens, or credentials in Flows. These should be stored securely in Named Credentials, Custom Settings, Custom Metadata, or external secret management systems.
|
|
89
|
-
|
|
90
|
-
**Rule ID:** `hardcoded-secret`
|
|
91
|
-
**Class Name:** _[HardcodedSecret](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/HardcodedSecret.ts)_
|
|
92
|
-
**Severity:** π΄ *Error*
|
|
93
|
-
|
|
94
|
-
#### Process Builder
|
|
95
|
-
Process Builder is retired. Continuing to use it increases maintenance overhead and risks future compatibility issues. Migrating automation to Flow reduces risk and improves maintainability.
|
|
96
|
-
|
|
97
|
-
**Rule ID:** `process-builder-usage`
|
|
98
|
-
**Class Name:** _[ProcessBuilder](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/ProcessBuilder.ts)_
|
|
99
|
-
**Severity:** π΄ *Error*
|
|
100
|
-
|
|
101
|
-
#### SOQL Query In A Loop
|
|
102
|
-
Running SOQL queries inside a loop can rapidly exceed query limits and severely degrade performance. Queries should be executed once, with results reused throughout the loop.
|
|
103
|
-
|
|
104
|
-
**Rule ID:** `soql-in-loop`
|
|
105
|
-
**Class Name:** _[SOQLQueryInLoop](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/SOQLQueryInLoop.ts)_
|
|
106
|
-
**Severity:** π΄ *Error*
|
|
107
|
-
|
|
108
|
-
#### Unsafe Running Context
|
|
109
|
-
Flows configured to run in System Mode without Sharing grant access to all data, bypassing user permissions. Avoid this setting to prevent security risks and protect sensitive data.
|
|
110
|
-
|
|
111
|
-
**Rule ID:** `unsafe-running-context`
|
|
112
|
-
**Class Name:** _[UnsafeRunningContext](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/UnsafeRunningContext.ts)_
|
|
113
|
-
**Severity:** π΄ *Error*
|
|
114
|
-
|
|
115
|
-
#### Duplicate DML Operation
|
|
116
|
-
When a Flow performs database operations across multiple screens, users navigating backward can cause the same actions to run multiple times. To prevent unintended changes, either restrict backward navigation or redesign the Flow so database operations execute in a single, forward-moving step.
|
|
117
|
-
|
|
118
|
-
**Rule ID:** `duplicate-dml`
|
|
119
|
-
**Class Name:** _[DuplicateDMLOperation](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/DuplicateDMLOperation.ts)_
|
|
120
|
-
**Severity:** π‘ *Warning*
|
|
121
|
-
|
|
122
|
-
#### Missing Fault Path
|
|
123
|
-
Elements that can fail should include a Fault Path to handle errors gracefully. Without it, failures show generic errors to users. Fault Paths improve reliability and user experience.
|
|
124
|
-
|
|
125
|
-
**Rule ID:** `missing-fault-path`
|
|
126
|
-
**Class Name:** _[MissingFaultPath](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/MissingFaultPath.ts)_
|
|
127
|
-
**Severity:** π‘ *Warning*
|
|
128
|
-
|
|
129
|
-
#### Missing Null Handler
|
|
130
|
-
Get Records operations return null when no data is found. Without handling these null values, Flows can fail or produce unintended results. Adding a null check improves reliability and ensures the Flow behaves as expected.
|
|
131
|
-
|
|
132
|
-
**Rule ID:** `missing-null-handler`
|
|
133
|
-
**Class Name:** _[MissingNullHandler](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/MissingNullHandler.ts)_
|
|
134
|
-
**Severity:** π‘ *Warning*
|
|
135
|
-
|
|
136
|
-
#### Recursive After Update
|
|
137
|
-
After-save Flows that update the same record can trigger recursion, causing unintended behavior or performance issues. Avoid updating the triggering record in after-save Flows; use before-save Flows instead to prevent recursion.
|
|
138
|
-
|
|
139
|
-
**Rule ID:** `recursive-record-update`
|
|
140
|
-
**Class Name:** _[RecursiveAfterUpdate](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/RecursiveAfterUpdate.ts)_
|
|
141
|
-
**Severity:** π‘ *Warning*
|
|
142
|
-
|
|
143
|
-
---
|
|
144
|
-
|
|
145
|
-
### Suggestions
|
|
146
|
-
|
|
147
|
-
These rules highlight areas where Flows can be improved. Following them increases reliability and long-term maintainability.
|
|
148
|
-
|
|
149
|
-
#### Action Call In A Loop
|
|
150
|
-
Repeatedly invoking Apex actions inside a loop can exhaust governor limits and lead to performance issues. Where possible, bulkify your logic by moving the action call outside the loop and passing a collection variable instead.
|
|
151
|
-
|
|
152
|
-
**Rule ID:** `action-call-in-loop`
|
|
153
|
-
**Class Name:** _[ActionCallsInLoop](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/ActionCallsInLoop.ts)_
|
|
154
|
-
**Severity:** π‘ *Warning*
|
|
155
|
-
|
|
156
|
-
#### Get Record All Fields
|
|
157
|
-
Avoid using Get Records to retrieve all fields unless necessary. This improves performance, reduces processing time, and limits exposure of unnecessary data.
|
|
158
|
-
|
|
159
|
-
**Rule ID:** `get-record-all-fields`
|
|
160
|
-
**Class Name:** _[GetRecordAllFields](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/GetRecordAllFields.ts)_
|
|
161
|
-
**Severity:** π‘ *Warning*
|
|
162
|
-
|
|
163
|
-
#### Inactive Flow
|
|
164
|
-
Inactive Flows should be deleted or archived to reduce risk. Even when inactive, they can cause unintended record changes during testing or be activated as subflows. Keeping only active, relevant Flows improves safety and maintainability.
|
|
165
|
-
|
|
166
|
-
**Rule ID:** `inactive-flow`
|
|
167
|
-
**Class Name:** _[InactiveFlow](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/InactiveFlow.ts)_
|
|
168
|
-
**Severity:** π‘ *Warning*
|
|
169
|
-
|
|
170
|
-
#### Invalid API Version
|
|
171
|
-
Flows running on outdated API versions may behave inconsistently when newer platform features or components are used. From API version 50.0 onward, the API Version attribute explicitly controls Flow runtime behavior. Keeping Flows aligned with a supported API version helps prevent compatibility issues and ensures predictable execution.
|
|
172
|
-
|
|
173
|
-
**Rule ID:** `invalid-api-version`
|
|
174
|
-
**Class Name:** _[APIVersion](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/APIVersion.ts)_
|
|
175
|
-
**Severity:** π‘ *Warning*
|
|
176
|
-
|
|
177
|
-
#### Missing Filter Record Trigger 
|
|
178
|
-
Record-triggered Flows without filters on changed fields or entry conditions execute on every record change. Adding filters ensures the Flow runs only when needed, improving performance.
|
|
179
|
-
|
|
180
|
-
**Rule ID:** `missing-record-trigger-filter`
|
|
181
|
-
**Class Name:** _[MissingFilterRecordTrigger](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/MissingFilterRecordTrigger.ts)_
|
|
182
|
-
**Severity:** π‘ *Warning*
|
|
183
|
-
|
|
184
|
-
#### Same Record Field Updates
|
|
185
|
-
Before-save Flows can safely update the triggering record directly via $Record, applying changes efficiently without extra DML operations. Using before-save updates improves performance
|
|
186
|
-
|
|
187
|
-
**Rule ID:** `same-record-field-updates`
|
|
188
|
-
**Class Name:** _[SameRecordFieldUpdates](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/SameRecordFieldUpdates.ts)_
|
|
189
|
-
**Severity:** π‘ *Warning*
|
|
190
|
-
|
|
191
|
-
#### Excessive Cyclomatic Complexity
|
|
192
|
-
High numbers of loops and decision elements increase a Flow's cyclomatic complexity. To maintain simplicity and readability, consider using subflows or splitting a Flow into smaller, ordered Flows.
|
|
193
|
-
|
|
194
|
-
**Rule ID:** `excessive-cyclomatic-complexity`
|
|
195
|
-
**Class Name:** _[CyclomaticComplexity](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/CyclomaticComplexity.ts)_
|
|
196
|
-
**Severity:** π΅ *Note*
|
|
197
|
-
|
|
198
|
-
#### Missing Trigger Order
|
|
199
|
-
Record-triggered Flows without a specified Trigger Order may execute in an unpredictable sequence. Setting a Trigger Order ensures your Flows run in the intended order.
|
|
200
|
-
|
|
201
|
-
**Rule ID:** `unspecified-trigger-order`
|
|
202
|
-
**Class Name:** _[TriggerOrder](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/TriggerOrder.ts)_
|
|
203
|
-
**Severity:** π΅ *Note*
|
|
204
|
-
|
|
205
|
-
#### Record ID as String 
|
|
206
|
-
Flows that use a String variable for a record ID instead of receiving the full record introduce unnecessary complexity and additional Get Records queries. Using the complete record simplifies the Flow and improves performance.
|
|
207
|
-
|
|
208
|
-
**Rule ID:** `record-id-as-string`
|
|
209
|
-
**Class Name:** _[RecordIdAsString](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/RecordIdAsString.ts)_
|
|
210
|
-
**Severity:** π΅ *Note*
|
|
211
|
-
|
|
212
|
-
#### Transform Instead of Loop 
|
|
213
|
-
Loop elements that perform direct Assignments on each item can slow down Flows. Using Transform elements allows bulk operations on collections, improving performance and reducing complexity.
|
|
214
|
-
|
|
215
|
-
**Rule ID:** `transform-instead-of-loop`
|
|
216
|
-
**Class Name:** _[TransformInsteadOfLoop](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/TransformInsteadOfLoop.ts)_
|
|
217
|
-
**Severity:** π΅ *Note*
|
|
218
|
-
|
|
219
|
-
---
|
|
220
|
-
|
|
221
|
-
### Layout
|
|
222
|
-
|
|
223
|
-
Focused on naming, documentation, and organization, these rules ensure Flows remain clear, easy to understand, and maintainable as automations grow.
|
|
224
|
-
|
|
225
|
-
#### Flow Naming Convention
|
|
226
|
-
Using clear and consistent Flow names improves readability, discoverability, and maintainability. A good naming convention helps team members quickly understand a Flow's purposeβfor example, including a domain and brief description like Service_OrderFulfillment. Adopt a naming pattern that aligns with your organization's standards.
|
|
227
|
-
|
|
228
|
-
**Rule ID:** `invalid-naming-convention`
|
|
229
|
-
**Class Name:** _[FlowName](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/FlowName.ts)_
|
|
230
|
-
**Severity:** π΄ *Error*
|
|
231
|
-
|
|
232
|
-
#### Missing Flow Description
|
|
233
|
-
Flow descriptions are essential for documentation and maintainability. Include a description for each Flow, explaining its purpose and where it's used.
|
|
234
|
-
|
|
235
|
-
**Rule ID:** `missing-flow-description`
|
|
236
|
-
**Class Name:** _[FlowDescription](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/FlowDescription.ts)_
|
|
237
|
-
**Severity:** π΄ *Error*
|
|
238
|
-
|
|
239
|
-
#### Missing Metadata Description 
|
|
240
|
-
Elements and metadata without a description reduce clarity and maintainability. Adding descriptions improves readability and makes your automation easier to understand.
|
|
241
|
-
|
|
242
|
-
**Rule ID:** `missing-metadata-description`
|
|
243
|
-
**Class Name:** _[MissingMetadataDescription](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/MissingMetadataDescription.ts)_
|
|
244
|
-
**Severity:** π‘ *Warning*
|
|
245
|
-
|
|
246
|
-
#### Unclear API Name
|
|
247
|
-
Elements with unclear or duplicated API names, like Copy_X_Of_Element, reduce Flow readability. Make sure to update the API name when copying elements to keep your Flow organized.
|
|
248
|
-
|
|
249
|
-
**Rule ID:** `unclear-api-naming`
|
|
250
|
-
**Class Name:** _[CopyAPIName](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/CopyAPIName.ts)_
|
|
251
|
-
**Severity:** π‘ *Warning*
|
|
252
|
-
|
|
253
|
-
#### Unreachable Element
|
|
254
|
-
Unconnected elements never execute and add unnecessary clutter. Remove or connect unused Flow elements to keep Flows clean and efficient.
|
|
255
|
-
|
|
256
|
-
**Rule ID:** `unreachable-element`
|
|
257
|
-
**Class Name:** _[UnconnectedElement](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/UnconnectedElement.ts)_
|
|
258
|
-
**Severity:** π‘ *Warning*
|
|
259
|
-
|
|
260
|
-
#### Unused Variable
|
|
261
|
-
Unused variables are never referenced and add unnecessary clutter. Remove them to keep Flows efficient and easy to maintain.
|
|
262
|
-
|
|
263
|
-
**Rule ID:** `unused-variable`
|
|
264
|
-
**Class Name:** _[UnusedVariable](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/UnusedVariable.ts)_
|
|
265
|
-
**Severity:** π‘ *Warning*
|
|
266
|
-
|
|
267
|
-
#### Missing Auto Layout
|
|
268
|
-
Auto-Layout automatically arranges and aligns Flow elements, keeping the canvas organized and easier to maintain. Enabling it saves time and improves readability.
|
|
269
|
-
|
|
270
|
-
**Rule ID:** `missing-auto-layout`
|
|
271
|
-
**Class Name:** _[AutoLayout](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/AutoLayout.ts)_
|
|
272
|
-
**Severity:** π΅ *Note*
|
|
58
|
+
<!-- START GENERATED_RULES -->
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
### Problems
|
|
63
|
+
|
|
64
|
+
These rules detect anti-patterns and unsafe practices in your Flows that could break functionality, compromise security, or cause deployment failures.
|
|
65
|
+
|
|
66
|
+
#### DML Statement In A Loop
|
|
67
|
+
Executing DML operations (insert, update, delete) inside a loop is a high-risk anti-pattern that frequently causes governor limit exceptions. All database operations should be collected and executed once, outside the loop.
|
|
68
|
+
|
|
69
|
+
**Rule ID:** `dml-in-loop`
|
|
70
|
+
**Class Name:** _[DMLStatementInLoop](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/DMLStatementInLoop.ts)_
|
|
71
|
+
**Severity:** π΄ *Error*
|
|
72
|
+
|
|
73
|
+
#### Hardcoded Salesforce Id
|
|
74
|
+
Avoid hard-coding record IDs, as they are unique to a specific org and will not work in other environments. Instead, store IDs in variablesβsuch as merge-field URL parameters or a **Get Records** elementβto make the Flow portable, maintainable, and flexible.
|
|
75
|
+
|
|
76
|
+
**Rule ID:** `hardcoded-id`
|
|
77
|
+
**Class Name:** _[HardcodedId](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/HardcodedId.ts)_
|
|
78
|
+
**Severity:** π΄ *Error*
|
|
79
|
+
|
|
80
|
+
#### Hardcoded Salesforce Url
|
|
81
|
+
Avoid hard-coding URLs, as they may change between environments or over time. Instead, store URLs in variables or custom settings to make the Flow adaptable, maintainable, and environment-independent.
|
|
82
|
+
|
|
83
|
+
**Rule ID:** `hardcoded-url`
|
|
84
|
+
**Class Name:** _[HardcodedUrl](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/HardcodedUrl.ts)_
|
|
85
|
+
**Severity:** π΄ *Error*
|
|
86
|
+
|
|
87
|
+
#### Hardcoded Secret 
|
|
88
|
+
Avoid hardcoding secrets, API keys, tokens, or credentials in Flows. These should be stored securely in Named Credentials, Custom Settings, Custom Metadata, or external secret management systems.
|
|
89
|
+
|
|
90
|
+
**Rule ID:** `hardcoded-secret`
|
|
91
|
+
**Class Name:** _[HardcodedSecret](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/HardcodedSecret.ts)_
|
|
92
|
+
**Severity:** π΄ *Error*
|
|
93
|
+
|
|
94
|
+
#### Process Builder
|
|
95
|
+
Process Builder is retired. Continuing to use it increases maintenance overhead and risks future compatibility issues. Migrating automation to Flow reduces risk and improves maintainability.
|
|
96
|
+
|
|
97
|
+
**Rule ID:** `process-builder-usage`
|
|
98
|
+
**Class Name:** _[ProcessBuilder](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/ProcessBuilder.ts)_
|
|
99
|
+
**Severity:** π΄ *Error*
|
|
100
|
+
|
|
101
|
+
#### SOQL Query In A Loop
|
|
102
|
+
Running SOQL queries inside a loop can rapidly exceed query limits and severely degrade performance. Queries should be executed once, with results reused throughout the loop.
|
|
103
|
+
|
|
104
|
+
**Rule ID:** `soql-in-loop`
|
|
105
|
+
**Class Name:** _[SOQLQueryInLoop](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/SOQLQueryInLoop.ts)_
|
|
106
|
+
**Severity:** π΄ *Error*
|
|
107
|
+
|
|
108
|
+
#### Unsafe Running Context
|
|
109
|
+
Flows configured to run in System Mode without Sharing grant access to all data, bypassing user permissions. Avoid this setting to prevent security risks and protect sensitive data.
|
|
110
|
+
|
|
111
|
+
**Rule ID:** `unsafe-running-context`
|
|
112
|
+
**Class Name:** _[UnsafeRunningContext](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/UnsafeRunningContext.ts)_
|
|
113
|
+
**Severity:** π΄ *Error*
|
|
114
|
+
|
|
115
|
+
#### Duplicate DML Operation
|
|
116
|
+
When a Flow performs database operations across multiple screens, users navigating backward can cause the same actions to run multiple times. To prevent unintended changes, either restrict backward navigation or redesign the Flow so database operations execute in a single, forward-moving step.
|
|
117
|
+
|
|
118
|
+
**Rule ID:** `duplicate-dml`
|
|
119
|
+
**Class Name:** _[DuplicateDMLOperation](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/DuplicateDMLOperation.ts)_
|
|
120
|
+
**Severity:** π‘ *Warning*
|
|
121
|
+
|
|
122
|
+
#### Missing Fault Path
|
|
123
|
+
Elements that can fail should include a Fault Path to handle errors gracefully. Without it, failures show generic errors to users. Fault Paths improve reliability and user experience.
|
|
124
|
+
|
|
125
|
+
**Rule ID:** `missing-fault-path`
|
|
126
|
+
**Class Name:** _[MissingFaultPath](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/MissingFaultPath.ts)_
|
|
127
|
+
**Severity:** π‘ *Warning*
|
|
128
|
+
|
|
129
|
+
#### Missing Null Handler
|
|
130
|
+
Get Records operations return null when no data is found. Without handling these null values, Flows can fail or produce unintended results. Adding a null check improves reliability and ensures the Flow behaves as expected.
|
|
131
|
+
|
|
132
|
+
**Rule ID:** `missing-null-handler`
|
|
133
|
+
**Class Name:** _[MissingNullHandler](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/MissingNullHandler.ts)_
|
|
134
|
+
**Severity:** π‘ *Warning*
|
|
135
|
+
|
|
136
|
+
#### Recursive After Update
|
|
137
|
+
After-save Flows that update the same record can trigger recursion, causing unintended behavior or performance issues. Avoid updating the triggering record in after-save Flows; use before-save Flows instead to prevent recursion.
|
|
138
|
+
|
|
139
|
+
**Rule ID:** `recursive-record-update`
|
|
140
|
+
**Class Name:** _[RecursiveAfterUpdate](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/RecursiveAfterUpdate.ts)_
|
|
141
|
+
**Severity:** π‘ *Warning*
|
|
142
|
+
|
|
143
|
+
---
|
|
144
|
+
|
|
145
|
+
### Suggestions
|
|
146
|
+
|
|
147
|
+
These rules highlight areas where Flows can be improved. Following them increases reliability and long-term maintainability.
|
|
148
|
+
|
|
149
|
+
#### Action Call In A Loop
|
|
150
|
+
Repeatedly invoking Apex actions inside a loop can exhaust governor limits and lead to performance issues. Where possible, bulkify your logic by moving the action call outside the loop and passing a collection variable instead.
|
|
151
|
+
|
|
152
|
+
**Rule ID:** `action-call-in-loop`
|
|
153
|
+
**Class Name:** _[ActionCallsInLoop](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/ActionCallsInLoop.ts)_
|
|
154
|
+
**Severity:** π‘ *Warning*
|
|
155
|
+
|
|
156
|
+
#### Get Record All Fields
|
|
157
|
+
Avoid using Get Records to retrieve all fields unless necessary. This improves performance, reduces processing time, and limits exposure of unnecessary data.
|
|
158
|
+
|
|
159
|
+
**Rule ID:** `get-record-all-fields`
|
|
160
|
+
**Class Name:** _[GetRecordAllFields](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/GetRecordAllFields.ts)_
|
|
161
|
+
**Severity:** π‘ *Warning*
|
|
162
|
+
|
|
163
|
+
#### Inactive Flow
|
|
164
|
+
Inactive Flows should be deleted or archived to reduce risk. Even when inactive, they can cause unintended record changes during testing or be activated as subflows. Keeping only active, relevant Flows improves safety and maintainability.
|
|
165
|
+
|
|
166
|
+
**Rule ID:** `inactive-flow`
|
|
167
|
+
**Class Name:** _[InactiveFlow](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/InactiveFlow.ts)_
|
|
168
|
+
**Severity:** π‘ *Warning*
|
|
169
|
+
|
|
170
|
+
#### Invalid API Version
|
|
171
|
+
Flows running on outdated API versions may behave inconsistently when newer platform features or components are used. From API version 50.0 onward, the API Version attribute explicitly controls Flow runtime behavior. Keeping Flows aligned with a supported API version helps prevent compatibility issues and ensures predictable execution.
|
|
172
|
+
|
|
173
|
+
**Rule ID:** `invalid-api-version`
|
|
174
|
+
**Class Name:** _[APIVersion](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/APIVersion.ts)_
|
|
175
|
+
**Severity:** π‘ *Warning*
|
|
176
|
+
|
|
177
|
+
#### Missing Filter Record Trigger 
|
|
178
|
+
Record-triggered Flows without filters on changed fields or entry conditions execute on every record change. Adding filters ensures the Flow runs only when needed, improving performance.
|
|
179
|
+
|
|
180
|
+
**Rule ID:** `missing-record-trigger-filter`
|
|
181
|
+
**Class Name:** _[MissingFilterRecordTrigger](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/MissingFilterRecordTrigger.ts)_
|
|
182
|
+
**Severity:** π‘ *Warning*
|
|
183
|
+
|
|
184
|
+
#### Same Record Field Updates
|
|
185
|
+
Before-save Flows can safely update the triggering record directly via $Record, applying changes efficiently without extra DML operations. Using before-save updates improves performance
|
|
186
|
+
|
|
187
|
+
**Rule ID:** `same-record-field-updates`
|
|
188
|
+
**Class Name:** _[SameRecordFieldUpdates](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/SameRecordFieldUpdates.ts)_
|
|
189
|
+
**Severity:** π‘ *Warning*
|
|
190
|
+
|
|
191
|
+
#### Excessive Cyclomatic Complexity
|
|
192
|
+
High numbers of loops and decision elements increase a Flow's cyclomatic complexity. To maintain simplicity and readability, consider using subflows or splitting a Flow into smaller, ordered Flows.
|
|
193
|
+
|
|
194
|
+
**Rule ID:** `excessive-cyclomatic-complexity`
|
|
195
|
+
**Class Name:** _[CyclomaticComplexity](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/CyclomaticComplexity.ts)_
|
|
196
|
+
**Severity:** π΅ *Note*
|
|
197
|
+
|
|
198
|
+
#### Missing Trigger Order
|
|
199
|
+
Record-triggered Flows without a specified Trigger Order may execute in an unpredictable sequence. Setting a Trigger Order ensures your Flows run in the intended order.
|
|
200
|
+
|
|
201
|
+
**Rule ID:** `unspecified-trigger-order`
|
|
202
|
+
**Class Name:** _[TriggerOrder](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/TriggerOrder.ts)_
|
|
203
|
+
**Severity:** π΅ *Note*
|
|
204
|
+
|
|
205
|
+
#### Record ID as String 
|
|
206
|
+
Flows that use a String variable for a record ID instead of receiving the full record introduce unnecessary complexity and additional Get Records queries. Using the complete record simplifies the Flow and improves performance.
|
|
207
|
+
|
|
208
|
+
**Rule ID:** `record-id-as-string`
|
|
209
|
+
**Class Name:** _[RecordIdAsString](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/RecordIdAsString.ts)_
|
|
210
|
+
**Severity:** π΅ *Note*
|
|
211
|
+
|
|
212
|
+
#### Transform Instead of Loop 
|
|
213
|
+
Loop elements that perform direct Assignments on each item can slow down Flows. Using Transform elements allows bulk operations on collections, improving performance and reducing complexity.
|
|
214
|
+
|
|
215
|
+
**Rule ID:** `transform-instead-of-loop`
|
|
216
|
+
**Class Name:** _[TransformInsteadOfLoop](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/TransformInsteadOfLoop.ts)_
|
|
217
|
+
**Severity:** π΅ *Note*
|
|
218
|
+
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
### Layout
|
|
222
|
+
|
|
223
|
+
Focused on naming, documentation, and organization, these rules ensure Flows remain clear, easy to understand, and maintainable as automations grow.
|
|
224
|
+
|
|
225
|
+
#### Flow Naming Convention
|
|
226
|
+
Using clear and consistent Flow names improves readability, discoverability, and maintainability. A good naming convention helps team members quickly understand a Flow's purposeβfor example, including a domain and brief description like Service_OrderFulfillment. Adopt a naming pattern that aligns with your organization's standards.
|
|
227
|
+
|
|
228
|
+
**Rule ID:** `invalid-naming-convention`
|
|
229
|
+
**Class Name:** _[FlowName](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/FlowName.ts)_
|
|
230
|
+
**Severity:** π΄ *Error*
|
|
231
|
+
|
|
232
|
+
#### Missing Flow Description
|
|
233
|
+
Flow descriptions are essential for documentation and maintainability. Include a description for each Flow, explaining its purpose and where it's used.
|
|
234
|
+
|
|
235
|
+
**Rule ID:** `missing-flow-description`
|
|
236
|
+
**Class Name:** _[FlowDescription](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/FlowDescription.ts)_
|
|
237
|
+
**Severity:** π΄ *Error*
|
|
238
|
+
|
|
239
|
+
#### Missing Metadata Description 
|
|
240
|
+
Elements and metadata without a description reduce clarity and maintainability. Adding descriptions improves readability and makes your automation easier to understand.
|
|
241
|
+
|
|
242
|
+
**Rule ID:** `missing-metadata-description`
|
|
243
|
+
**Class Name:** _[MissingMetadataDescription](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/MissingMetadataDescription.ts)_
|
|
244
|
+
**Severity:** π‘ *Warning*
|
|
245
|
+
|
|
246
|
+
#### Unclear API Name
|
|
247
|
+
Elements with unclear or duplicated API names, like Copy_X_Of_Element, reduce Flow readability. Make sure to update the API name when copying elements to keep your Flow organized.
|
|
248
|
+
|
|
249
|
+
**Rule ID:** `unclear-api-naming`
|
|
250
|
+
**Class Name:** _[CopyAPIName](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/CopyAPIName.ts)_
|
|
251
|
+
**Severity:** π‘ *Warning*
|
|
252
|
+
|
|
253
|
+
#### Unreachable Element
|
|
254
|
+
Unconnected elements never execute and add unnecessary clutter. Remove or connect unused Flow elements to keep Flows clean and efficient.
|
|
255
|
+
|
|
256
|
+
**Rule ID:** `unreachable-element`
|
|
257
|
+
**Class Name:** _[UnconnectedElement](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/UnconnectedElement.ts)_
|
|
258
|
+
**Severity:** π‘ *Warning*
|
|
259
|
+
|
|
260
|
+
#### Unused Variable
|
|
261
|
+
Unused variables are never referenced and add unnecessary clutter. Remove them to keep Flows efficient and easy to maintain.
|
|
262
|
+
|
|
263
|
+
**Rule ID:** `unused-variable`
|
|
264
|
+
**Class Name:** _[UnusedVariable](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/UnusedVariable.ts)_
|
|
265
|
+
**Severity:** π‘ *Warning*
|
|
266
|
+
|
|
267
|
+
#### Missing Auto Layout
|
|
268
|
+
Auto-Layout automatically arranges and aligns Flow elements, keeping the canvas organized and easier to maintain. Enabling it saves time and improves readability.
|
|
269
|
+
|
|
270
|
+
**Rule ID:** `missing-auto-layout`
|
|
271
|
+
**Class Name:** _[AutoLayout](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/packages/core/src/main/rules/AutoLayout.ts)_
|
|
272
|
+
**Severity:** π΅ *Note*
|
|
273
273
|
<!-- END GENERATED_RULES -->
|
|
274
274
|
|
|
275
275
|
---
|
|
@@ -628,7 +628,7 @@ For more on Programmatic API, types, and advanced usage of `@flow-scanner/lightn
|
|
|
628
628
|
6. Deploy Demo Flows (Optional):
|
|
629
629
|
|
|
630
630
|
```bash
|
|
631
|
-
|
|
631
|
+
sf project deploy start
|
|
632
632
|
```
|
|
633
633
|
|
|
634
634
|
Navigate to the [Demo Readme](https://github.com/Flow-Scanner/lightning-flow-scanner/blob/main/example-flows/README.md) for full details
|
|
@@ -8,6 +8,7 @@ import { FlowNode } from "./FlowNode";
|
|
|
8
8
|
export declare class FlowGraph {
|
|
9
9
|
private nodeMap;
|
|
10
10
|
private reachableFromStart;
|
|
11
|
+
private normalReachableFromStart;
|
|
11
12
|
private elementsInLoop;
|
|
12
13
|
private faultConnectors;
|
|
13
14
|
private normalConnectors;
|
|
@@ -35,6 +36,11 @@ export declare class FlowGraph {
|
|
|
35
36
|
* This reuses the existing IDDFS traversal logic!
|
|
36
37
|
*/
|
|
37
38
|
private computeReachability;
|
|
39
|
+
/**
|
|
40
|
+
* Compute which elements are reachable from start using ONLY normal connectors (not fault connectors).
|
|
41
|
+
* Elements that are reachable overall but NOT reachable via normal connectors are part of fault handling.
|
|
42
|
+
*/
|
|
43
|
+
private computeNormalReachability;
|
|
38
44
|
/**
|
|
39
45
|
* Use Compiler to compute which elements are inside loops.
|
|
40
46
|
* Calls Compiler.traverseFlow() for each loop with endElementName.
|
|
@@ -51,6 +57,11 @@ export declare class FlowGraph {
|
|
|
51
57
|
getAllNextElements(elementName: string): string[];
|
|
52
58
|
getPreviousElements(elementName: string): string[];
|
|
53
59
|
getNode(elementName: string): FlowNode | undefined;
|
|
60
|
+
/**
|
|
61
|
+
* Check if an element is part of fault handling flow.
|
|
62
|
+
* An element is part of fault handling if it's only reachable through fault paths
|
|
63
|
+
* (i.e., reachable overall but NOT reachable via normal connectors from START).
|
|
64
|
+
*/
|
|
54
65
|
isPartOfFaultHandling(elementName: string): boolean;
|
|
55
66
|
getLoopNodes(): FlowNode[];
|
|
56
67
|
forEachReachable(callback: (node: FlowNode) => void): void;
|
package/main/models/FlowGraph.js
CHANGED
|
@@ -110,6 +110,15 @@ let FlowGraph = class FlowGraph {
|
|
|
110
110
|
}, this.nodeMap, this.allConnectors);
|
|
111
111
|
}
|
|
112
112
|
/**
|
|
113
|
+
* Compute which elements are reachable from start using ONLY normal connectors (not fault connectors).
|
|
114
|
+
* Elements that are reachable overall but NOT reachable via normal connectors are part of fault handling.
|
|
115
|
+
*/ computeNormalReachability(startReference) {
|
|
116
|
+
const compiler = new _Compiler.Compiler();
|
|
117
|
+
compiler.traverseFlow(startReference, (element)=>{
|
|
118
|
+
this.normalReachableFromStart.add(element.name);
|
|
119
|
+
}, this.nodeMap, this.normalConnectors);
|
|
120
|
+
}
|
|
121
|
+
/**
|
|
113
122
|
* Use Compiler to compute which elements are inside loops.
|
|
114
123
|
* Calls Compiler.traverseFlow() for each loop with endElementName.
|
|
115
124
|
*/ computeLoopBoundaries() {
|
|
@@ -167,13 +176,13 @@ let FlowGraph = class FlowGraph {
|
|
|
167
176
|
getNode(elementName) {
|
|
168
177
|
return this.nodeMap.get(elementName);
|
|
169
178
|
}
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
179
|
+
/**
|
|
180
|
+
* Check if an element is part of fault handling flow.
|
|
181
|
+
* An element is part of fault handling if it's only reachable through fault paths
|
|
182
|
+
* (i.e., reachable overall but NOT reachable via normal connectors from START).
|
|
183
|
+
*/ isPartOfFaultHandling(elementName) {
|
|
184
|
+
// Element is part of fault handling if it's reachable but NOT reachable via normal paths
|
|
185
|
+
return this.reachableFromStart.has(elementName) && !this.normalReachableFromStart.has(elementName);
|
|
177
186
|
}
|
|
178
187
|
getLoopNodes() {
|
|
179
188
|
return Array.from(this.nodeMap.values()).filter((n)=>n.subtype === "loops");
|
|
@@ -508,6 +517,7 @@ let FlowGraph = class FlowGraph {
|
|
|
508
517
|
_define_property(this, "nodeMap", new Map());
|
|
509
518
|
// Pre-computed sets for common queries (built using Compiler)
|
|
510
519
|
_define_property(this, "reachableFromStart", new Set());
|
|
520
|
+
_define_property(this, "normalReachableFromStart", new Set()); // Elements reachable via normal (non-fault) connectors only
|
|
511
521
|
_define_property(this, "elementsInLoop", new Map()); // element -> loop name
|
|
512
522
|
// Connector metadata (extracted during node processing)
|
|
513
523
|
_define_property(this, "faultConnectors", new Map());
|
|
@@ -527,6 +537,7 @@ let FlowGraph = class FlowGraph {
|
|
|
527
537
|
this.computeLoopBoundaries();
|
|
528
538
|
if (startReference) {
|
|
529
539
|
this.computeReachability(startReference);
|
|
540
|
+
this.computeNormalReachability(startReference);
|
|
530
541
|
}
|
|
531
542
|
}
|
|
532
543
|
};
|
|
@@ -66,11 +66,13 @@ let MissingRecordTriggerFilter = class MissingRecordTriggerFilter extends _RuleC
|
|
|
66
66
|
}
|
|
67
67
|
// Check if the flow has filters or entry conditions at the flow level
|
|
68
68
|
const filters = this.getStartProperty(flow, 'filters');
|
|
69
|
+
const filterFormula = this.getStartProperty(flow, 'filterFormula');
|
|
69
70
|
const hasFilters = !!filters;
|
|
71
|
+
const hasFilterFormula = !!filterFormula;
|
|
70
72
|
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
73
|
const hasScheduledPaths = !!scheduledPaths;
|
|
72
|
-
// If no filters or scheduled paths (which have their own conditions), flag as violation
|
|
73
|
-
if (!hasFilters && !hasScheduledPaths) {
|
|
74
|
+
// If no filters, formula conditions, or scheduled paths (which have their own conditions), flag as violation
|
|
75
|
+
if (!hasFilters && !hasFilterFormula && !hasScheduledPaths) {
|
|
74
76
|
violations.push(new _internals.Violation(new _internals.FlowAttribute(triggerType, "triggerType", "autolaunched && triggerType")));
|
|
75
77
|
}
|
|
76
78
|
return violations;
|
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.17.
|
|
4
|
+
"version": "6.17.3",
|
|
5
5
|
"main": "index.js",
|
|
6
6
|
"exports": {
|
|
7
7
|
".": {
|