@flow-scanner/lightning-flow-scanner-core 6.6.3 → 6.6.4

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 (231) hide show
  1. package/.husky/pre-commit +1 -0
  2. package/.husky/pre-push +1 -0
  3. package/.prettierignore +5 -0
  4. package/.swcrc +26 -0
  5. package/eslint.config.mjs +36 -0
  6. package/jest.config.cjs +32 -0
  7. package/jest.env-setup.js +101 -0
  8. package/lint-staged.config.mjs +8 -0
  9. package/out/assets/media/banner.png +0 -0
  10. package/{main → out/main}/interfaces/IRuleDefinition.d.ts +0 -1
  11. package/{main → out/main}/internals/internals.d.ts +2 -2
  12. package/{main → out/main}/internals/internals.js +0 -4
  13. package/{main → out/main}/models/RuleCommon.d.ts +0 -1
  14. package/{main → out/main}/models/RuleCommon.js +8 -4
  15. package/{main → out/main}/models/RuleInfo.d.ts +0 -15
  16. package/{main → out/main}/models/RuleInfo.js +0 -13
  17. package/{main → out/main}/rules/APIVersion.js +1 -3
  18. package/{main → out/main}/rules/ActionCallsInLoop.js +0 -2
  19. package/{main → out/main}/rules/AutoLayout.js +1 -3
  20. package/{main → out/main}/rules/CopyAPIName.js +1 -3
  21. package/{main → out/main}/rules/CyclomaticComplexity.js +1 -3
  22. package/{main → out/main}/rules/DMLStatementInLoop.js +0 -2
  23. package/{main → out/main}/rules/DuplicateDMLOperation.js +1 -3
  24. package/{main → out/main}/rules/FlowDescription.js +0 -2
  25. package/{main → out/main}/rules/FlowName.js +0 -2
  26. package/{main → out/main}/rules/GetRecordAllFields.js +0 -2
  27. package/{main → out/main}/rules/HardcodedId.js +1 -3
  28. package/{main → out/main}/rules/HardcodedUrl.js +0 -2
  29. package/{main → out/main}/rules/InactiveFlow.js +1 -3
  30. package/{main → out/main}/rules/MissingFaultPath.js +0 -2
  31. package/{main → out/main}/rules/MissingMetadataDescription.js +0 -2
  32. package/{main → out/main}/rules/MissingNullHandler.js +0 -2
  33. package/{main → out/main}/rules/ProcessBuilder.js +1 -3
  34. package/{main → out/main}/rules/RecursiveAfterUpdate.js +0 -2
  35. package/{main → out/main}/rules/SOQLQueryInLoop.js +0 -2
  36. package/{main → out/main}/rules/SameRecordFieldUpdates.js +1 -3
  37. package/{main → out/main}/rules/TriggerOrder.js +1 -3
  38. package/{main → out/main}/rules/UnconnectedElement.js +0 -2
  39. package/{main → out/main}/rules/UnsafeRunningContext.js +1 -3
  40. package/{main → out/main}/rules/UnusedVariable.js +1 -3
  41. package/package.json +58 -8
  42. package/prettier.config.mjs +5 -0
  43. package/src/index.ts +44 -0
  44. package/src/main/interfaces/IExceptions.ts +6 -0
  45. package/src/main/interfaces/IRuleConfig.ts +3 -0
  46. package/src/main/interfaces/IRuleDefinition.ts +12 -0
  47. package/src/main/interfaces/IRuleOptions.ts +5 -0
  48. package/src/main/interfaces/IRulesConfig.ts +15 -0
  49. package/src/main/internals/internals.ts +35 -0
  50. package/src/main/libs/BuildFlow.ts +11 -0
  51. package/src/main/libs/Compiler.ts +69 -0
  52. package/src/main/libs/ConvertFlowNodes.ts +4 -0
  53. package/src/main/libs/DynamicRule.ts +11 -0
  54. package/src/main/libs/FixFlows.ts +61 -0
  55. package/src/main/libs/GetRuleDefinitions.ts +65 -0
  56. package/src/main/libs/ParseFlows.ts +34 -0
  57. package/src/main/libs/ScanFlows.ts +112 -0
  58. package/src/main/libs/exportAsDetails.ts +26 -0
  59. package/src/main/libs/exportAsSarif.ts +88 -0
  60. package/src/main/models/FlatViolation.ts +8 -0
  61. package/src/main/models/Flow.ts +214 -0
  62. package/src/main/models/FlowAttribute.ts +12 -0
  63. package/src/main/models/FlowElement.ts +15 -0
  64. package/src/main/models/FlowElementConnector.ts +28 -0
  65. package/src/main/models/FlowMetadata.ts +7 -0
  66. package/src/main/models/FlowNode.ts +171 -0
  67. package/src/main/models/FlowResource.ts +10 -0
  68. package/src/main/models/FlowType.ts +52 -0
  69. package/src/main/models/FlowVariable.ts +12 -0
  70. package/src/main/models/LoopRuleCommon.ts +55 -0
  71. package/src/main/models/ParsedFlow.ts +15 -0
  72. package/src/main/models/RuleCommon.ts +68 -0
  73. package/src/main/models/RuleInfo.ts +43 -0
  74. package/src/main/models/RuleResult.ts +25 -0
  75. package/src/main/models/ScanResult.ts +12 -0
  76. package/src/main/models/Violation.ts +78 -0
  77. package/src/main/rules/APIVersion.ts +59 -0
  78. package/src/main/rules/ActionCallsInLoop.ts +24 -0
  79. package/src/main/rules/AutoLayout.ts +44 -0
  80. package/src/main/rules/CopyAPIName.ts +29 -0
  81. package/src/main/rules/CyclomaticComplexity.ts +67 -0
  82. package/src/main/rules/DMLStatementInLoop.ts +24 -0
  83. package/src/main/rules/DuplicateDMLOperation.ts +114 -0
  84. package/src/main/rules/FlowDescription.ts +32 -0
  85. package/src/main/rules/FlowName.ts +40 -0
  86. package/src/main/rules/GetRecordAllFields.ts +59 -0
  87. package/src/main/rules/HardcodedId.ts +37 -0
  88. package/src/main/rules/HardcodedUrl.ts +42 -0
  89. package/src/main/rules/InactiveFlow.ts +31 -0
  90. package/src/main/rules/MissingFaultPath.ts +89 -0
  91. package/src/main/rules/MissingMetadataDescription.ts +39 -0
  92. package/src/main/rules/MissingNullHandler.ts +95 -0
  93. package/src/main/rules/ProcessBuilder.ts +33 -0
  94. package/src/main/rules/RecursiveAfterUpdate.ts +88 -0
  95. package/src/main/rules/SOQLQueryInLoop.ts +24 -0
  96. package/src/main/rules/SameRecordFieldUpdates.ts +64 -0
  97. package/src/main/rules/TriggerOrder.ts +44 -0
  98. package/src/main/rules/UnconnectedElement.ts +48 -0
  99. package/src/main/rules/UnsafeRunningContext.ts +44 -0
  100. package/src/main/rules/UnusedVariable.ts +64 -0
  101. package/src/main/store/DefaultRuleStore.ts +54 -0
  102. package/stryker.config.mjs +23 -0
  103. package/tests/APIVersion.test.ts +83 -0
  104. package/tests/AutoLayout.test.ts +39 -0
  105. package/tests/Config.test.ts +119 -0
  106. package/tests/ConfigBetaMode.test.ts +26 -0
  107. package/tests/CopyAPIName.test.ts +43 -0
  108. package/tests/CyclomaticComplexity.test.ts +123 -0
  109. package/tests/DMLStatementInLoop.test.ts +31 -0
  110. package/tests/DuplicateDMLOperation.test.ts +41 -0
  111. package/tests/Exceptions.test.ts +813 -0
  112. package/tests/ExportSarif.test.ts +61 -0
  113. package/tests/FlowDescription.test.ts +42 -0
  114. package/tests/FlowName.test.ts +62 -0
  115. package/tests/GetRecordElementAllFields.test.ts +180 -0
  116. package/tests/HardcodedId.test.ts +16 -0
  117. package/tests/HardcodedUrl.test.ts +252 -0
  118. package/tests/InactiveFlow.test.ts +99 -0
  119. package/tests/MissingFaultPath.test.ts +50 -0
  120. package/tests/MissingMetadataDescription.test.ts +24 -0
  121. package/tests/MissingNullHandler.test.ts +43 -0
  122. package/tests/No_Missing_Null_Handler.test.ts +30 -0
  123. package/tests/RecursiveAfterUpdate.test.ts +160 -0
  124. package/tests/SOQLQueryInLoop.test.ts +32 -0
  125. package/tests/SameRecordFieldUpdates.test.ts +241 -0
  126. package/tests/SanityTest.test.ts +15 -0
  127. package/tests/TriggerOrder.test.ts +92 -0
  128. package/tests/UnconnectedElement.test.ts +74 -0
  129. package/tests/UnsafeRunningContext.test.ts +46 -0
  130. package/tests/UnusedVariable.test.ts +56 -0
  131. package/tests/jsonfiles/MissingFaultPath_BeforeSave_Bypass.json +128 -0
  132. package/tests/jsonfiles/MissingFaultPath_WaitConditions.json +102 -0
  133. package/tests/jsonfiles/MissingFaultPath_WaitDate.json +88 -0
  134. package/tests/jsonfiles/MissingFaultPath_WaitDuration.json +90 -0
  135. package/tests/models/Flow.test.ts +107 -0
  136. package/tests/models/LoopRuleCommon.test.ts +253 -0
  137. package/tests/models/RuleCommon.test.ts +47 -0
  138. package/tsconfig.json +19 -0
  139. package/tsconfig.tsbuildinfo +1 -0
  140. package/tsconfig.types.json +25 -0
  141. package/vite.config.ts +28 -0
  142. package/CONTRIBUTING.md +0 -31
  143. package/README.md +0 -443
  144. package/SECURITY.md +0 -44
  145. /package/{index.d.ts → out/index.d.ts} +0 -0
  146. /package/{index.js → out/index.js} +0 -0
  147. /package/{main → out/main}/interfaces/IExceptions.d.ts +0 -0
  148. /package/{main → out/main}/interfaces/IExceptions.js +0 -0
  149. /package/{main → out/main}/interfaces/IRuleConfig.d.ts +0 -0
  150. /package/{main → out/main}/interfaces/IRuleConfig.js +0 -0
  151. /package/{main → out/main}/interfaces/IRuleDefinition.js +0 -0
  152. /package/{main → out/main}/interfaces/IRuleOptions.d.ts +0 -0
  153. /package/{main → out/main}/interfaces/IRuleOptions.js +0 -0
  154. /package/{main → out/main}/interfaces/IRulesConfig.d.ts +0 -0
  155. /package/{main → out/main}/interfaces/IRulesConfig.js +0 -0
  156. /package/{main → out/main}/libs/BuildFlow.d.ts +0 -0
  157. /package/{main → out/main}/libs/BuildFlow.js +0 -0
  158. /package/{main → out/main}/libs/Compiler.d.ts +0 -0
  159. /package/{main → out/main}/libs/Compiler.js +0 -0
  160. /package/{main → out/main}/libs/ConvertFlowNodes.d.ts +0 -0
  161. /package/{main → out/main}/libs/ConvertFlowNodes.js +0 -0
  162. /package/{main → out/main}/libs/DynamicRule.d.ts +0 -0
  163. /package/{main → out/main}/libs/DynamicRule.js +0 -0
  164. /package/{main → out/main}/libs/FixFlows.d.ts +0 -0
  165. /package/{main → out/main}/libs/FixFlows.js +0 -0
  166. /package/{main → out/main}/libs/GetRuleDefinitions.d.ts +0 -0
  167. /package/{main → out/main}/libs/GetRuleDefinitions.js +0 -0
  168. /package/{main → out/main}/libs/ParseFlows.d.ts +0 -0
  169. /package/{main → out/main}/libs/ParseFlows.js +0 -0
  170. /package/{main → out/main}/libs/ScanFlows.d.ts +0 -0
  171. /package/{main → out/main}/libs/ScanFlows.js +0 -0
  172. /package/{main → out/main}/libs/exportAsDetails.d.ts +0 -0
  173. /package/{main → out/main}/libs/exportAsDetails.js +0 -0
  174. /package/{main → out/main}/libs/exportAsSarif.d.ts +0 -0
  175. /package/{main → out/main}/libs/exportAsSarif.js +0 -0
  176. /package/{main → out/main}/models/FlatViolation.d.ts +0 -0
  177. /package/{main → out/main}/models/FlatViolation.js +0 -0
  178. /package/{main → out/main}/models/Flow.d.ts +0 -0
  179. /package/{main → out/main}/models/Flow.js +0 -0
  180. /package/{main → out/main}/models/FlowAttribute.d.ts +0 -0
  181. /package/{main → out/main}/models/FlowAttribute.js +0 -0
  182. /package/{main → out/main}/models/FlowElement.d.ts +0 -0
  183. /package/{main → out/main}/models/FlowElement.js +0 -0
  184. /package/{main → out/main}/models/FlowElementConnector.d.ts +0 -0
  185. /package/{main → out/main}/models/FlowElementConnector.js +0 -0
  186. /package/{main → out/main}/models/FlowMetadata.d.ts +0 -0
  187. /package/{main → out/main}/models/FlowMetadata.js +0 -0
  188. /package/{main → out/main}/models/FlowNode.d.ts +0 -0
  189. /package/{main → out/main}/models/FlowNode.js +0 -0
  190. /package/{main → out/main}/models/FlowResource.d.ts +0 -0
  191. /package/{main → out/main}/models/FlowResource.js +0 -0
  192. /package/{main → out/main}/models/FlowType.d.ts +0 -0
  193. /package/{main → out/main}/models/FlowType.js +0 -0
  194. /package/{main → out/main}/models/FlowVariable.d.ts +0 -0
  195. /package/{main → out/main}/models/FlowVariable.js +0 -0
  196. /package/{main → out/main}/models/LoopRuleCommon.d.ts +0 -0
  197. /package/{main → out/main}/models/LoopRuleCommon.js +0 -0
  198. /package/{main → out/main}/models/ParsedFlow.d.ts +0 -0
  199. /package/{main → out/main}/models/ParsedFlow.js +0 -0
  200. /package/{main → out/main}/models/RuleResult.d.ts +0 -0
  201. /package/{main → out/main}/models/RuleResult.js +0 -0
  202. /package/{main → out/main}/models/ScanResult.d.ts +0 -0
  203. /package/{main → out/main}/models/ScanResult.js +0 -0
  204. /package/{main → out/main}/models/Violation.d.ts +0 -0
  205. /package/{main → out/main}/models/Violation.js +0 -0
  206. /package/{main → out/main}/rules/APIVersion.d.ts +0 -0
  207. /package/{main → out/main}/rules/ActionCallsInLoop.d.ts +0 -0
  208. /package/{main → out/main}/rules/AutoLayout.d.ts +0 -0
  209. /package/{main → out/main}/rules/CopyAPIName.d.ts +0 -0
  210. /package/{main → out/main}/rules/CyclomaticComplexity.d.ts +0 -0
  211. /package/{main → out/main}/rules/DMLStatementInLoop.d.ts +0 -0
  212. /package/{main → out/main}/rules/DuplicateDMLOperation.d.ts +0 -0
  213. /package/{main → out/main}/rules/FlowDescription.d.ts +0 -0
  214. /package/{main → out/main}/rules/FlowName.d.ts +0 -0
  215. /package/{main → out/main}/rules/GetRecordAllFields.d.ts +0 -0
  216. /package/{main → out/main}/rules/HardcodedId.d.ts +0 -0
  217. /package/{main → out/main}/rules/HardcodedUrl.d.ts +0 -0
  218. /package/{main → out/main}/rules/InactiveFlow.d.ts +0 -0
  219. /package/{main → out/main}/rules/MissingFaultPath.d.ts +0 -0
  220. /package/{main → out/main}/rules/MissingMetadataDescription.d.ts +0 -0
  221. /package/{main → out/main}/rules/MissingNullHandler.d.ts +0 -0
  222. /package/{main → out/main}/rules/ProcessBuilder.d.ts +0 -0
  223. /package/{main → out/main}/rules/RecursiveAfterUpdate.d.ts +0 -0
  224. /package/{main → out/main}/rules/SOQLQueryInLoop.d.ts +0 -0
  225. /package/{main → out/main}/rules/SameRecordFieldUpdates.d.ts +0 -0
  226. /package/{main → out/main}/rules/TriggerOrder.d.ts +0 -0
  227. /package/{main → out/main}/rules/UnconnectedElement.d.ts +0 -0
  228. /package/{main → out/main}/rules/UnsafeRunningContext.d.ts +0 -0
  229. /package/{main → out/main}/rules/UnusedVariable.d.ts +0 -0
  230. /package/{main → out/main}/store/DefaultRuleStore.d.ts +0 -0
  231. /package/{main → out/main}/store/DefaultRuleStore.js +0 -0
@@ -0,0 +1,813 @@
1
+ import * as core from "../src";
2
+ import { ParsedFlow } from "../src/main/models/ParsedFlow";
3
+
4
+ import { describe, it, expect } from "@jest/globals";
5
+
6
+ describe("Exceptions", () => {
7
+ it("should show exceptions on wrong configuration", async () => {
8
+ const flows: ParsedFlow[] = [
9
+ {
10
+ uri: "something",
11
+ flow: {
12
+ flowVariables: ["choices", "constants", "dynamicChoiceSets", "formulas", "variables"],
13
+ flowResources: ["textTemplates", "stages"],
14
+ flowMetadata: [
15
+ "description",
16
+ "apiVersion",
17
+ "processMetadataValues",
18
+ "processType",
19
+ "interviewLabel",
20
+ "label",
21
+ "status",
22
+ "runInMode",
23
+ "startElementReference",
24
+ "isTemplate",
25
+ "fullName",
26
+ "timeZoneSidKey",
27
+ "isAdditionalPermissionRequiredToRun",
28
+ "migratedFromWorkflowRuleName",
29
+ "triggerOrder",
30
+ "environments",
31
+ "segment",
32
+ ],
33
+ flowNodes: [
34
+ "actionCalls",
35
+ "apexPluginCalls",
36
+ "assignments",
37
+ "collectionProcessors",
38
+ "decisions",
39
+ "loops",
40
+ "orchestratedStages",
41
+ "recordCreates",
42
+ "recordDeletes",
43
+ "recordLookups",
44
+ "recordUpdates",
45
+ "recordRollbacks",
46
+ "screens",
47
+ "start",
48
+ "steps",
49
+ "subflows",
50
+ "waits",
51
+ ],
52
+ fsPath: "./tests/xmlfiles/random.flow-meta.xml",
53
+ name: "Flow1API60",
54
+ xmldata: {
55
+ "@xmlns": "http://soap.sforce.com/2006/04/metadata",
56
+ apiVersion: "60.0",
57
+ environments: "Default",
58
+ interviewLabel: "test {!$Flow.CurrentDateTime}",
59
+ label: "test",
60
+ processMetadataValues: [
61
+ {
62
+ name: "BuilderType",
63
+ value: { stringValue: "LightningFlowBuilder" },
64
+ },
65
+ {
66
+ name: "CanvasMode",
67
+ value: { stringValue: "AUTO_LAYOUT_CANVAS" },
68
+ },
69
+ {
70
+ name: "OriginBuilderType",
71
+ value: { stringValue: "LightningFlowBuilder" },
72
+ },
73
+ ],
74
+ processType: "Flow",
75
+ runInMode: "SystemModeWithoutSharing",
76
+ screens: {
77
+ name: "testtest",
78
+ label: "test",
79
+ locationX: "176",
80
+ locationY: "134",
81
+ allowBack: "true",
82
+ allowFinish: "true",
83
+ allowPause: "true",
84
+ showFooter: "true",
85
+ showHeader: "true",
86
+ },
87
+ start: {
88
+ locationX: "50",
89
+ locationY: "0",
90
+ connector: { targetReference: "testtest" },
91
+ },
92
+ status: "Draft",
93
+ },
94
+ label: "test",
95
+ interviewLabel: "test {!$Flow.CurrentDateTime}",
96
+ processType: "Flow",
97
+ processMetadataValues: [
98
+ {
99
+ name: "BuilderType",
100
+ value: { stringValue: "LightningFlowBuilder" },
101
+ },
102
+ { name: "CanvasMode", value: { stringValue: "AUTO_LAYOUT_CANVAS" } },
103
+ {
104
+ name: "OriginBuilderType",
105
+ value: { stringValue: "LightningFlowBuilder" },
106
+ },
107
+ ],
108
+ start: {
109
+ locationX: "50",
110
+ locationY: "0",
111
+ connector: { targetReference: "testtest" },
112
+ },
113
+ status: "Draft",
114
+ type: "Flow",
115
+ elements: [
116
+ { element: "61.0", subtype: "apiVersion", metaType: "metadata" },
117
+ { element: "Default", subtype: "environments", metaType: "metadata" },
118
+ {
119
+ element: "test {!$Flow.CurrentDateTime}",
120
+ subtype: "interviewLabel",
121
+ metaType: "metadata",
122
+ },
123
+ { element: "test", subtype: "label", metaType: "metadata" },
124
+ {
125
+ element: {
126
+ name: "BuilderType",
127
+ value: { stringValue: "LightningFlowBuilder" },
128
+ },
129
+ subtype: "processMetadataValues",
130
+ metaType: "metadata",
131
+ },
132
+ {
133
+ element: {
134
+ name: "CanvasMode",
135
+ value: { stringValue: "AUTO_LAYOUT_CANVAS" },
136
+ },
137
+ subtype: "processMetadataValues",
138
+ metaType: "metadata",
139
+ },
140
+ {
141
+ element: {
142
+ name: "OriginBuilderType",
143
+ value: { stringValue: "LightningFlowBuilder" },
144
+ },
145
+ subtype: "processMetadataValues",
146
+ metaType: "metadata",
147
+ },
148
+ { element: "Flow", subtype: "processType", metaType: "metadata" },
149
+ {
150
+ element: "SystemModeWithoutSharing",
151
+ subtype: "runInMode",
152
+ metaType: "metadata",
153
+ },
154
+ {
155
+ element: {
156
+ name: "testtest",
157
+ label: "test",
158
+ locationX: "176",
159
+ locationY: "134",
160
+ allowBack: "true",
161
+ allowFinish: "true",
162
+ allowPause: "true",
163
+ showFooter: "true",
164
+ showHeader: "true",
165
+ },
166
+ subtype: "screens",
167
+ metaType: "node",
168
+ connectors: [],
169
+ name: "testtest",
170
+ locationX: "176",
171
+ locationY: "134",
172
+ },
173
+ {
174
+ element: {
175
+ locationX: "50",
176
+ locationY: "0",
177
+ connector: { targetReference: "testtest" },
178
+ },
179
+ subtype: "start",
180
+ metaType: "node",
181
+ connectors: [
182
+ {
183
+ element: { targetReference: "testtest" },
184
+ processed: false,
185
+ type: "connector",
186
+ reference: "testtest",
187
+ },
188
+ ],
189
+ name: "flowstart",
190
+ locationX: "50",
191
+ locationY: "0",
192
+ },
193
+ { element: "Draft", subtype: "status", metaType: "metadata" },
194
+ ],
195
+ startReference: "testtest",
196
+ } as Partial<core.Flow> as core.Flow,
197
+ },
198
+ ];
199
+ const ruleConfig = {
200
+ rules: {
201
+ APIVersion: {
202
+ severity: "error",
203
+ expression: "===62",
204
+ },
205
+ },
206
+ exceptions: {
207
+ Flow1API60: { APIVersion: ["60.0"] },
208
+ Flow2API61: { APIVersion: ["60.0"] },
209
+ Flow3API59: { APIVersion: ["60.0"] },
210
+ },
211
+ };
212
+ const results: core.ScanResult[] = core.scan(flows, ruleConfig);
213
+ const { ruleResults } = results.pop() as core.ScanResult;
214
+ expect(
215
+ ruleResults.filter((rule) => {
216
+ return rule.occurs;
217
+ })
218
+ ).toHaveLength(1);
219
+ });
220
+
221
+ it("should show not show any exceptions on api version", async () => {
222
+ const flows: ParsedFlow[] = [
223
+ {
224
+ uri: "something",
225
+ flow: {
226
+ flowVariables: ["choices", "constants", "dynamicChoiceSets", "formulas", "variables"],
227
+ flowResources: ["textTemplates", "stages"],
228
+ flowMetadata: [
229
+ "description",
230
+ "apiVersion",
231
+ "processMetadataValues",
232
+ "processType",
233
+ "interviewLabel",
234
+ "label",
235
+ "status",
236
+ "runInMode",
237
+ "startElementReference",
238
+ "isTemplate",
239
+ "fullName",
240
+ "timeZoneSidKey",
241
+ "isAdditionalPermissionRequiredToRun",
242
+ "migratedFromWorkflowRuleName",
243
+ "triggerOrder",
244
+ "environments",
245
+ "segment",
246
+ ],
247
+ flowNodes: [
248
+ "actionCalls",
249
+ "apexPluginCalls",
250
+ "assignments",
251
+ "collectionProcessors",
252
+ "decisions",
253
+ "loops",
254
+ "orchestratedStages",
255
+ "recordCreates",
256
+ "recordDeletes",
257
+ "recordLookups",
258
+ "recordUpdates",
259
+ "recordRollbacks",
260
+ "screens",
261
+ "start",
262
+ "steps",
263
+ "subflows",
264
+ "waits",
265
+ ],
266
+ fsPath: "./tests/xmlfiles/random.flow-meta.xml",
267
+ name: "Flow1API60",
268
+ xmldata: {
269
+ "@xmlns": "http://soap.sforce.com/2006/04/metadata",
270
+ apiVersion: "60.0",
271
+ environments: "Default",
272
+ interviewLabel: "test {!$Flow.CurrentDateTime}",
273
+ label: "test",
274
+ processMetadataValues: [
275
+ {
276
+ name: "BuilderType",
277
+ value: { stringValue: "LightningFlowBuilder" },
278
+ },
279
+ {
280
+ name: "CanvasMode",
281
+ value: { stringValue: "AUTO_LAYOUT_CANVAS" },
282
+ },
283
+ {
284
+ name: "OriginBuilderType",
285
+ value: { stringValue: "LightningFlowBuilder" },
286
+ },
287
+ ],
288
+ processType: "Flow",
289
+ runInMode: "SystemModeWithoutSharing",
290
+ screens: {
291
+ name: "testtest",
292
+ label: "test",
293
+ locationX: "176",
294
+ locationY: "134",
295
+ allowBack: "true",
296
+ allowFinish: "true",
297
+ allowPause: "true",
298
+ showFooter: "true",
299
+ showHeader: "true",
300
+ },
301
+ start: {
302
+ locationX: "50",
303
+ locationY: "0",
304
+ connector: { targetReference: "testtest" },
305
+ },
306
+ status: "Draft",
307
+ },
308
+ label: "test",
309
+ interviewLabel: "test {!$Flow.CurrentDateTime}",
310
+ processType: "Flow",
311
+ processMetadataValues: [
312
+ {
313
+ name: "BuilderType",
314
+ value: { stringValue: "LightningFlowBuilder" },
315
+ },
316
+ { name: "CanvasMode", value: { stringValue: "AUTO_LAYOUT_CANVAS" } },
317
+ {
318
+ name: "OriginBuilderType",
319
+ value: { stringValue: "LightningFlowBuilder" },
320
+ },
321
+ ],
322
+ start: {
323
+ locationX: "50",
324
+ locationY: "0",
325
+ connector: { targetReference: "testtest" },
326
+ },
327
+ status: "Draft",
328
+ type: "Flow",
329
+ elements: [
330
+ { element: "61.0", subtype: "apiVersion", metaType: "metadata" },
331
+ { element: "Default", subtype: "environments", metaType: "metadata" },
332
+ {
333
+ element: "test {!$Flow.CurrentDateTime}",
334
+ subtype: "interviewLabel",
335
+ metaType: "metadata",
336
+ },
337
+ { element: "test", subtype: "label", metaType: "metadata" },
338
+ {
339
+ element: {
340
+ name: "BuilderType",
341
+ value: { stringValue: "LightningFlowBuilder" },
342
+ },
343
+ subtype: "processMetadataValues",
344
+ metaType: "metadata",
345
+ },
346
+ {
347
+ element: {
348
+ name: "CanvasMode",
349
+ value: { stringValue: "AUTO_LAYOUT_CANVAS" },
350
+ },
351
+ subtype: "processMetadataValues",
352
+ metaType: "metadata",
353
+ },
354
+ {
355
+ element: {
356
+ name: "OriginBuilderType",
357
+ value: { stringValue: "LightningFlowBuilder" },
358
+ },
359
+ subtype: "processMetadataValues",
360
+ metaType: "metadata",
361
+ },
362
+ { element: "Flow", subtype: "processType", metaType: "metadata" },
363
+ {
364
+ element: "SystemModeWithoutSharing",
365
+ subtype: "runInMode",
366
+ metaType: "metadata",
367
+ },
368
+ {
369
+ element: {
370
+ name: "testtest",
371
+ label: "test",
372
+ locationX: "176",
373
+ locationY: "134",
374
+ allowBack: "true",
375
+ allowFinish: "true",
376
+ allowPause: "true",
377
+ showFooter: "true",
378
+ showHeader: "true",
379
+ },
380
+ subtype: "screens",
381
+ metaType: "node",
382
+ connectors: [],
383
+ name: "testtest",
384
+ locationX: "176",
385
+ locationY: "134",
386
+ },
387
+ {
388
+ element: {
389
+ locationX: "50",
390
+ locationY: "0",
391
+ connector: { targetReference: "testtest" },
392
+ },
393
+ subtype: "start",
394
+ metaType: "node",
395
+ connectors: [
396
+ {
397
+ element: { targetReference: "testtest" },
398
+ processed: false,
399
+ type: "connector",
400
+ reference: "testtest",
401
+ },
402
+ ],
403
+ name: "flowstart",
404
+ locationX: "50",
405
+ locationY: "0",
406
+ },
407
+ { element: "Draft", subtype: "status", metaType: "metadata" },
408
+ ],
409
+ startReference: "testtest",
410
+ } as Partial<core.Flow> as core.Flow,
411
+ },
412
+ {
413
+ uri: "something",
414
+ flow: {
415
+ flowVariables: ["choices", "constants", "dynamicChoiceSets", "formulas", "variables"],
416
+ flowResources: ["textTemplates", "stages"],
417
+ flowMetadata: [
418
+ "description",
419
+ "apiVersion",
420
+ "processMetadataValues",
421
+ "processType",
422
+ "interviewLabel",
423
+ "label",
424
+ "status",
425
+ "runInMode",
426
+ "startElementReference",
427
+ "isTemplate",
428
+ "fullName",
429
+ "timeZoneSidKey",
430
+ "isAdditionalPermissionRequiredToRun",
431
+ "migratedFromWorkflowRuleName",
432
+ "triggerOrder",
433
+ "environments",
434
+ "segment",
435
+ ],
436
+ flowNodes: [
437
+ "actionCalls",
438
+ "apexPluginCalls",
439
+ "assignments",
440
+ "collectionProcessors",
441
+ "decisions",
442
+ "loops",
443
+ "orchestratedStages",
444
+ "recordCreates",
445
+ "recordDeletes",
446
+ "recordLookups",
447
+ "recordUpdates",
448
+ "recordRollbacks",
449
+ "screens",
450
+ "start",
451
+ "steps",
452
+ "subflows",
453
+ "waits",
454
+ ],
455
+ fsPath: "./tests/xmlfiles/random.flow-meta.xml",
456
+ name: "Flow2API61",
457
+ xmldata: {
458
+ "@xmlns": "http://soap.sforce.com/2006/04/metadata",
459
+ apiVersion: "61.0",
460
+ environments: "Default",
461
+ interviewLabel: "test {!$Flow.CurrentDateTime}",
462
+ label: "test",
463
+ processMetadataValues: [
464
+ {
465
+ name: "BuilderType",
466
+ value: { stringValue: "LightningFlowBuilder" },
467
+ },
468
+ {
469
+ name: "CanvasMode",
470
+ value: { stringValue: "AUTO_LAYOUT_CANVAS" },
471
+ },
472
+ {
473
+ name: "OriginBuilderType",
474
+ value: { stringValue: "LightningFlowBuilder" },
475
+ },
476
+ ],
477
+ processType: "Flow",
478
+ runInMode: "SystemModeWithoutSharing",
479
+ screens: {
480
+ name: "testtest",
481
+ label: "test",
482
+ locationX: "176",
483
+ locationY: "134",
484
+ allowBack: "true",
485
+ allowFinish: "true",
486
+ allowPause: "true",
487
+ showFooter: "true",
488
+ showHeader: "true",
489
+ },
490
+ start: {
491
+ locationX: "50",
492
+ locationY: "0",
493
+ connector: { targetReference: "testtest" },
494
+ },
495
+ status: "Draft",
496
+ },
497
+ label: "test",
498
+ interviewLabel: "test {!$Flow.CurrentDateTime}",
499
+ processType: "Flow",
500
+ processMetadataValues: [
501
+ {
502
+ name: "BuilderType",
503
+ value: { stringValue: "LightningFlowBuilder" },
504
+ },
505
+ { name: "CanvasMode", value: { stringValue: "AUTO_LAYOUT_CANVAS" } },
506
+ {
507
+ name: "OriginBuilderType",
508
+ value: { stringValue: "LightningFlowBuilder" },
509
+ },
510
+ ],
511
+ start: {
512
+ locationX: "50",
513
+ locationY: "0",
514
+ connector: { targetReference: "testtest" },
515
+ },
516
+ status: "Draft",
517
+ type: "Flow",
518
+ elements: [
519
+ { element: "61.0", subtype: "apiVersion", metaType: "metadata" },
520
+ { element: "Default", subtype: "environments", metaType: "metadata" },
521
+ {
522
+ element: "test {!$Flow.CurrentDateTime}",
523
+ subtype: "interviewLabel",
524
+ metaType: "metadata",
525
+ },
526
+ { element: "test", subtype: "label", metaType: "metadata" },
527
+ {
528
+ element: {
529
+ name: "BuilderType",
530
+ value: { stringValue: "LightningFlowBuilder" },
531
+ },
532
+ subtype: "processMetadataValues",
533
+ metaType: "metadata",
534
+ },
535
+ {
536
+ element: {
537
+ name: "CanvasMode",
538
+ value: { stringValue: "AUTO_LAYOUT_CANVAS" },
539
+ },
540
+ subtype: "processMetadataValues",
541
+ metaType: "metadata",
542
+ },
543
+ {
544
+ element: {
545
+ name: "OriginBuilderType",
546
+ value: { stringValue: "LightningFlowBuilder" },
547
+ },
548
+ subtype: "processMetadataValues",
549
+ metaType: "metadata",
550
+ },
551
+ { element: "Flow", subtype: "processType", metaType: "metadata" },
552
+ {
553
+ element: "SystemModeWithoutSharing",
554
+ subtype: "runInMode",
555
+ metaType: "metadata",
556
+ },
557
+ {
558
+ element: {
559
+ name: "testtest",
560
+ label: "test",
561
+ locationX: "176",
562
+ locationY: "134",
563
+ allowBack: "true",
564
+ allowFinish: "true",
565
+ allowPause: "true",
566
+ showFooter: "true",
567
+ showHeader: "true",
568
+ },
569
+ subtype: "screens",
570
+ metaType: "node",
571
+ connectors: [],
572
+ name: "testtest",
573
+ locationX: "176",
574
+ locationY: "134",
575
+ },
576
+ {
577
+ element: {
578
+ locationX: "50",
579
+ locationY: "0",
580
+ connector: { targetReference: "testtest" },
581
+ },
582
+ subtype: "start",
583
+ metaType: "node",
584
+ connectors: [
585
+ {
586
+ element: { targetReference: "testtest" },
587
+ processed: false,
588
+ type: "connector",
589
+ reference: "testtest",
590
+ },
591
+ ],
592
+ name: "flowstart",
593
+ locationX: "50",
594
+ locationY: "0",
595
+ },
596
+ { element: "Draft", subtype: "status", metaType: "metadata" },
597
+ ],
598
+ startReference: "testtest",
599
+ } as Partial<core.Flow> as core.Flow,
600
+ },
601
+ {
602
+ uri: "something",
603
+ flow: {
604
+ flowVariables: ["choices", "constants", "dynamicChoiceSets", "formulas", "variables"],
605
+ flowResources: ["textTemplates", "stages"],
606
+ flowMetadata: [
607
+ "description",
608
+ "apiVersion",
609
+ "processMetadataValues",
610
+ "processType",
611
+ "interviewLabel",
612
+ "label",
613
+ "status",
614
+ "runInMode",
615
+ "startElementReference",
616
+ "isTemplate",
617
+ "fullName",
618
+ "timeZoneSidKey",
619
+ "isAdditionalPermissionRequiredToRun",
620
+ "migratedFromWorkflowRuleName",
621
+ "triggerOrder",
622
+ "environments",
623
+ "segment",
624
+ ],
625
+ flowNodes: [
626
+ "actionCalls",
627
+ "apexPluginCalls",
628
+ "assignments",
629
+ "collectionProcessors",
630
+ "decisions",
631
+ "loops",
632
+ "orchestratedStages",
633
+ "recordCreates",
634
+ "recordDeletes",
635
+ "recordLookups",
636
+ "recordUpdates",
637
+ "recordRollbacks",
638
+ "screens",
639
+ "start",
640
+ "steps",
641
+ "subflows",
642
+ "waits",
643
+ ],
644
+ fsPath: "./tests/xmlfiles/random.flow-meta.xml",
645
+ name: "Flow3API59",
646
+ xmldata: {
647
+ "@xmlns": "http://soap.sforce.com/2006/04/metadata",
648
+ apiVersion: "59.0",
649
+ environments: "Default",
650
+ interviewLabel: "test {!$Flow.CurrentDateTime}",
651
+ label: "test",
652
+ processMetadataValues: [
653
+ {
654
+ name: "BuilderType",
655
+ value: { stringValue: "LightningFlowBuilder" },
656
+ },
657
+ {
658
+ name: "CanvasMode",
659
+ value: { stringValue: "AUTO_LAYOUT_CANVAS" },
660
+ },
661
+ {
662
+ name: "OriginBuilderType",
663
+ value: { stringValue: "LightningFlowBuilder" },
664
+ },
665
+ ],
666
+ processType: "Flow",
667
+ runInMode: "SystemModeWithoutSharing",
668
+ screens: {
669
+ name: "testtest",
670
+ label: "test",
671
+ locationX: "176",
672
+ locationY: "134",
673
+ allowBack: "true",
674
+ allowFinish: "true",
675
+ allowPause: "true",
676
+ showFooter: "true",
677
+ showHeader: "true",
678
+ },
679
+ start: {
680
+ locationX: "50",
681
+ locationY: "0",
682
+ connector: { targetReference: "testtest" },
683
+ },
684
+ status: "Draft",
685
+ },
686
+ label: "test",
687
+ interviewLabel: "test {!$Flow.CurrentDateTime}",
688
+ processType: "Flow",
689
+ processMetadataValues: [
690
+ {
691
+ name: "BuilderType",
692
+ value: { stringValue: "LightningFlowBuilder" },
693
+ },
694
+ { name: "CanvasMode", value: { stringValue: "AUTO_LAYOUT_CANVAS" } },
695
+ {
696
+ name: "OriginBuilderType",
697
+ value: { stringValue: "LightningFlowBuilder" },
698
+ },
699
+ ],
700
+ start: {
701
+ locationX: "50",
702
+ locationY: "0",
703
+ connector: { targetReference: "testtest" },
704
+ },
705
+ status: "Draft",
706
+ type: "Flow",
707
+ elements: [
708
+ { element: "59.0", subtype: "apiVersion", metaType: "metadata" },
709
+ { element: "Default", subtype: "environments", metaType: "metadata" },
710
+ {
711
+ element: "test {!$Flow.CurrentDateTime}",
712
+ subtype: "interviewLabel",
713
+ metaType: "metadata",
714
+ },
715
+ { element: "test", subtype: "label", metaType: "metadata" },
716
+ {
717
+ element: {
718
+ name: "BuilderType",
719
+ value: { stringValue: "LightningFlowBuilder" },
720
+ },
721
+ subtype: "processMetadataValues",
722
+ metaType: "metadata",
723
+ },
724
+ {
725
+ element: {
726
+ name: "CanvasMode",
727
+ value: { stringValue: "AUTO_LAYOUT_CANVAS" },
728
+ },
729
+ subtype: "processMetadataValues",
730
+ metaType: "metadata",
731
+ },
732
+ {
733
+ element: {
734
+ name: "OriginBuilderType",
735
+ value: { stringValue: "LightningFlowBuilder" },
736
+ },
737
+ subtype: "processMetadataValues",
738
+ metaType: "metadata",
739
+ },
740
+ { element: "Flow", subtype: "processType", metaType: "metadata" },
741
+ {
742
+ element: "SystemModeWithoutSharing",
743
+ subtype: "runInMode",
744
+ metaType: "metadata",
745
+ },
746
+ {
747
+ element: {
748
+ name: "testtest",
749
+ label: "test",
750
+ locationX: "176",
751
+ locationY: "134",
752
+ allowBack: "true",
753
+ allowFinish: "true",
754
+ allowPause: "true",
755
+ showFooter: "true",
756
+ showHeader: "true",
757
+ },
758
+ subtype: "screens",
759
+ metaType: "node",
760
+ connectors: [],
761
+ name: "testtest",
762
+ locationX: "176",
763
+ locationY: "134",
764
+ },
765
+ {
766
+ element: {
767
+ locationX: "50",
768
+ locationY: "0",
769
+ connector: { targetReference: "testtest" },
770
+ },
771
+ subtype: "start",
772
+ metaType: "node",
773
+ connectors: [
774
+ {
775
+ element: { targetReference: "testtest" },
776
+ processed: false,
777
+ type: "connector",
778
+ reference: "testtest",
779
+ },
780
+ ],
781
+ name: "flowstart",
782
+ locationX: "50",
783
+ locationY: "0",
784
+ },
785
+ { element: "Draft", subtype: "status", metaType: "metadata" },
786
+ ],
787
+ startReference: "testtest",
788
+ } as Partial<core.Flow> as core.Flow,
789
+ },
790
+ ];
791
+ const ruleConfig = {
792
+ rules: {
793
+ APIVersion: {
794
+ severity: "error",
795
+ expression: "===62",
796
+ },
797
+ },
798
+ exceptions: {
799
+ Flow1API60: { APIVersion: ["60"] },
800
+ Flow2API61: { APIVersion: ["61"] },
801
+ Flow3API59: { APIVersion: ["59"] },
802
+ },
803
+ };
804
+ const results: core.ScanResult[] = core.scan(flows, ruleConfig);
805
+ results.forEach(({ ruleResults }) => {
806
+ expect(
807
+ ruleResults.filter((result) => {
808
+ return result.occurs;
809
+ })
810
+ ).toHaveLength(0);
811
+ });
812
+ });
813
+ });