@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 @@
1
+ npm run precommit
@@ -0,0 +1 @@
1
+ npm run prepush
@@ -0,0 +1,5 @@
1
+ assets/example-flows/**
2
+ out/**
3
+ tests/**/*.test.ts
4
+ jest.config.ts
5
+ vite.config.ts
package/.swcrc ADDED
@@ -0,0 +1,26 @@
1
+ {
2
+ "$schema": "https://swc.rs/schema.json",
3
+ "sourceMaps": false,
4
+ "module": {
5
+ "type": "commonjs",
6
+ "strictMode": true,
7
+ "noInterop": false,
8
+ "resolveFully": true
9
+ },
10
+ "jsc": {
11
+ "externalHelpers": false,
12
+ "target": "es2015",
13
+ "parser": {
14
+ "syntax": "typescript",
15
+ "tsx": true,
16
+ "decorators": true,
17
+ "dynamicImport": true
18
+ },
19
+ "transform": {
20
+ "legacyDecorator": true,
21
+ "decoratorMetadata": false
22
+ },
23
+ "keepClassNames": true
24
+ },
25
+ "minify": false // Disable for now; re-enable post-debug if needed for smaller JS
26
+ }
@@ -0,0 +1,36 @@
1
+ import deMorgan from "eslint-plugin-de-morgan";
2
+ import github from "eslint-plugin-github";
3
+ import pluginJest from "eslint-plugin-jest";
4
+ import perfectionist from "eslint-plugin-perfectionist";
5
+ import sonarjs from "eslint-plugin-sonarjs";
6
+ import globals from "globals";
7
+ import tseslint from "typescript-eslint";
8
+
9
+ export default [
10
+ { languageOptions: { globals: globals.browser } },
11
+ ...tseslint.configs.recommended,
12
+ {
13
+ files: ["tests/*.test.ts"],
14
+ languageOptions: {
15
+ globals: pluginJest.environments.globals.globals,
16
+ },
17
+ plugins: { jest: pluginJest },
18
+ rules: {
19
+ "jest/no-alias-methods": "error",
20
+ "jest/no-disabled-tests": "warn",
21
+ "jest/no-focused-tests": "error",
22
+ "jest/no-identical-title": "error",
23
+ "jest/prefer-to-have-length": "warn",
24
+ "jest/valid-expect": "error",
25
+ },
26
+ },
27
+ {
28
+ ignores: ["jest.config.ts", "assets/example-flows/**"],
29
+ },
30
+ perfectionist.configs["recommended-alphabetical"],
31
+ perfectionist.configs["recommended-line-length"],
32
+ perfectionist.configs["recommended-natural"],
33
+ sonarjs.configs.recommended,
34
+ deMorgan.configs.recommended,
35
+ ...github.getFlatConfigs().typescript,
36
+ ];
@@ -0,0 +1,32 @@
1
+ module.exports = {
2
+ automock: false,
3
+ clearMocks: true,
4
+ collectCoverage: true,
5
+ coverageDirectory: "coverage",
6
+ coverageProvider: "v8",
7
+ coverageReporters: ["json", "text", "lcov"],
8
+ modulePathIgnorePatterns: ["./jest.config.cjs", "./out/"],
9
+ setupFilesAfterEnv: ["<rootDir>/jest.env-setup.js"],
10
+ testEnvironment: "node",
11
+ testPathIgnorePatterns: ["/node_modules/"],
12
+ transform: {
13
+ "^.+\\.(t|j)sx?$": [
14
+ "@swc-node/jest",
15
+ {
16
+ module: "commonjs",
17
+ swc: {
18
+ jsc: {
19
+ target: "es2020",
20
+ parser: {
21
+ syntax: "typescript",
22
+ tsx: false,
23
+ },
24
+ },
25
+ sourceMaps: "inline",
26
+ minify: false,
27
+ },
28
+ },
29
+ ],
30
+ },
31
+ transformIgnorePatterns: ["/node_modules/", "\\.pnp\\.[^\\/]+$"],
32
+ };
@@ -0,0 +1,101 @@
1
+ const fs = require("fs");
2
+ const path = require("path");
3
+
4
+ module.exports = () => {
5
+ if (!process.env.UMD_PATH) {
6
+ console.log("UMD Setup: No UMD_PATH—skipping (Node-only mode)");
7
+ return;
8
+ }
9
+
10
+ const umdFilePath = path.resolve(process.env.UMD_PATH);
11
+
12
+ if (!fs.existsSync(umdFilePath)) {
13
+ console.warn("UMD Setup: File not found at", umdFilePath, "—skipping.");
14
+ return;
15
+ }
16
+
17
+ let umdCode = fs.readFileSync(umdFilePath, "utf8");
18
+ const fastXmlParser = require("fast-xml-parser");
19
+
20
+ // Vite UMD pattern: (function(global, factory) { ... })(this, function(exports, dependency) { ... });
21
+ // We need to extract and execute the factory function
22
+
23
+ // Try to match Vite's UMD pattern more flexibly
24
+ const viteUmdMatch = umdCode.match(
25
+ /\(function\s*\([^,]+,\s*(\w+)\)\s*\{[\s\S]*?\}\)\s*\(this,\s*function\s*\((\w+)(?:,\s*(\w+))?\)\s*\{([\s\S]+)\}\s*\)\s*;?\s*$/
26
+ );
27
+
28
+ if (viteUmdMatch) {
29
+ const factoryBody = viteUmdMatch[4];
30
+ const exportsParam = viteUmdMatch[2];
31
+ const depParam = viteUmdMatch[3];
32
+
33
+ try {
34
+ // Create the factory function with proper parameters
35
+ const factoryFn = depParam
36
+ ? new Function(exportsParam, depParam, factoryBody)
37
+ : new Function(exportsParam, factoryBody);
38
+
39
+ // Create exports object and invoke factory
40
+ const exports = {};
41
+ if (depParam) {
42
+ factoryFn(exports, fastXmlParser);
43
+ } else {
44
+ factoryFn(exports);
45
+ }
46
+
47
+ // Assign to global
48
+ global.lightningflowscanner = exports;
49
+
50
+ if (Object.keys(exports).length === 0) {
51
+ console.error("UMD Setup: WARNING - exports object is empty!");
52
+ }
53
+ } catch (e) {
54
+ console.error("UMD Factory error:", e.message);
55
+ console.error("Stack:", e.stack);
56
+ }
57
+ } else {
58
+ // Fallback: Try direct execution approach
59
+
60
+ try {
61
+ // Create a mock global/window context
62
+ const mockGlobal = {};
63
+ const mockFactory = new Function(
64
+ "global",
65
+ "factory",
66
+ `
67
+ return (function(root, factoryFn) {
68
+ if (typeof exports === 'object' && typeof module !== 'undefined') {
69
+ factoryFn(exports, require('fast-xml-parser'));
70
+ } else {
71
+ factoryFn((root.lightningflowscanner = {}), root.fastXmlParser);
72
+ }
73
+ })(global, factory);
74
+ `
75
+ );
76
+
77
+ // Execute in controlled context
78
+ const vm = require("vm");
79
+ const sandbox = {
80
+ exports: {},
81
+ require: (id) => (id === "fast-xml-parser" ? fastXmlParser : require(id)),
82
+ module: { exports: {} },
83
+ console: console,
84
+ };
85
+
86
+ vm.runInNewContext(umdCode, sandbox);
87
+
88
+ // Check what got exported
89
+ const exports = sandbox.exports.default || sandbox.exports || sandbox.module.exports;
90
+
91
+ if (exports && Object.keys(exports).length > 0) {
92
+ global.lightningflowscanner = exports;
93
+ } else {
94
+ console.error("UMD Setup: Direct execution failed - no exports found");
95
+ }
96
+ } catch (e) {
97
+ console.error("UMD Direct execution error:", e.message);
98
+ console.error("Stack:", e.stack.slice(0, 400));
99
+ }
100
+ }
101
+ };
@@ -0,0 +1,8 @@
1
+ import micromatch from "micromatch";
2
+
3
+ const isNotExampleFlows = (files) => micromatch.not(files, ["assets/example-flows/**"]);
4
+
5
+ export default {
6
+ "**/*.{js,json,md,xml,yaml,yml}": (files) =>
7
+ isNotExampleFlows(files).map((f) => `prettier --write "${f}"`),
8
+ };
Binary file
@@ -1,6 +1,5 @@
1
1
  import { Flow, RuleResult } from "../internals/internals";
2
2
  export interface IRuleDefinition {
3
- autoFixable: boolean;
4
3
  description: string;
5
4
  docRefs: Array<{
6
5
  label: string;
@@ -14,5 +14,5 @@ import { RuleCommon } from "../models/RuleCommon";
14
14
  import { RuleResult } from "../models/RuleResult";
15
15
  import { ScanResult } from "../models/ScanResult";
16
16
  import { Violation } from "../models/Violation";
17
- export { FlatViolation, FlowAttribute, FlowElement, FlowNode, FlowType, FlowVariable, FlowResource, Flow, Compiler, ScanResult, RuleResult, Violation, RuleCommon, ParsedFlow, };
18
- export type { IRuleDefinition, IRulesConfig };
17
+ export { FlowAttribute, FlowElement, FlowNode, FlowType, FlowVariable, FlowResource, Flow, Compiler, ScanResult, RuleResult, Violation, RuleCommon, ParsedFlow, };
18
+ export type { IRuleDefinition, IRulesConfig, FlatViolation };
@@ -12,9 +12,6 @@ _export(exports, {
12
12
  get Compiler () {
13
13
  return _Compiler.Compiler;
14
14
  },
15
- get FlatViolation () {
16
- return _FlatViolation.FlatViolation;
17
- },
18
15
  get Flow () {
19
16
  return _Flow.Flow;
20
17
  },
@@ -53,7 +50,6 @@ _export(exports, {
53
50
  }
54
51
  });
55
52
  const _Compiler = require("../libs/Compiler");
56
- const _FlatViolation = require("../models/FlatViolation");
57
53
  const _Flow = require("../models/Flow");
58
54
  const _FlowAttribute = require("../models/FlowAttribute");
59
55
  const _FlowElement = require("../models/FlowElement");
@@ -1,7 +1,6 @@
1
1
  import { RuleInfo } from "./RuleInfo";
2
2
  import * as core from "../internals/internals";
3
3
  export declare abstract class RuleCommon {
4
- autoFixable: boolean;
5
4
  description: string;
6
5
  docRefs: Array<{
7
6
  label: string;
@@ -86,10 +86,9 @@ let RuleCommon = class RuleCommon {
86
86
  return suppressions.has(name);
87
87
  }
88
88
  constructor(info, optional){
89
- _define_property(this, "autoFixable", void 0);
90
89
  _define_property(this, "description", void 0);
91
90
  _define_property(this, "docRefs", []);
92
- _define_property(this, "isConfigurable", void 0);
91
+ _define_property(this, "isConfigurable", void 0); // Auto-detected by checking if the implemented check() method actually uses "options."
93
92
  _define_property(this, "label", void 0);
94
93
  _define_property(this, "name", void 0);
95
94
  _define_property(this, "severity", void 0);
@@ -102,8 +101,13 @@ let RuleCommon = class RuleCommon {
102
101
  this.description = info.description;
103
102
  this.uri = `https://github.com/Lightning-Flow-Scanner/lightning-flow-scanner-core/tree/main/src/main/rules/${info.name}.ts`;
104
103
  this.docRefs = info.docRefs;
105
- this.isConfigurable = info.isConfigurable;
106
- this.autoFixable = info.autoFixable;
104
+ const checkImpl = this.check;
105
+ if (typeof checkImpl === "function") {
106
+ const source = checkImpl.toString();
107
+ this.isConfigurable = /options[.\?]/.test(source);
108
+ } else {
109
+ this.isConfigurable = false;
110
+ }
107
111
  var _optional_severity;
108
112
  this.severity = (_optional_severity = optional === null || optional === void 0 ? void 0 : optional.severity) !== null && _optional_severity !== void 0 ? _optional_severity : "error";
109
113
  this.suppressionElement = info.suppressionElement;
@@ -7,11 +7,6 @@ export type RuleDefinitionExpression = {
7
7
  * Represents a rule metadata; this contains properties to describe the rule
8
8
  */
9
9
  export declare class RuleInfo {
10
- /**
11
- * Indicates whether the rule can be automatically fixed.
12
- * When the rule is autofixable, implement @see {AutoFixable}
13
- */
14
- autoFixable: boolean;
15
10
  /**
16
11
  * A human-readable description of the rule.
17
12
  */
@@ -23,16 +18,6 @@ export declare class RuleInfo {
23
18
  label: string;
24
19
  path: string;
25
20
  }>;
26
- /**
27
- * Specifies if the rule's behavior can be configured.
28
- * When configurable, execute should take in a second parameter @see RuleDefinitionExpression
29
- * @example
30
- * ```typescript
31
- * public execute(flow: core.Flow, options?: { expression: string }): core.RuleResult {
32
- * // your rule
33
- * }
34
- */
35
- isConfigurable: boolean;
36
21
  /**
37
22
  * The display label for the rule.
38
23
  * This property is being displayed on sf cli and on vsce
@@ -24,25 +24,12 @@ function _define_property(obj, key, value) {
24
24
  let RuleInfo = class RuleInfo {
25
25
  constructor(){
26
26
  /**
27
- * Indicates whether the rule can be automatically fixed.
28
- * When the rule is autofixable, implement @see {AutoFixable}
29
- */ _define_property(this, "autoFixable", void 0);
30
- /**
31
27
  * A human-readable description of the rule.
32
28
  */ _define_property(this, "description", void 0);
33
29
  /**
34
30
  * An array of documentation references related to the rule.
35
31
  */ _define_property(this, "docRefs", void 0);
36
32
  /**
37
- * Specifies if the rule's behavior can be configured.
38
- * When configurable, execute should take in a second parameter @see RuleDefinitionExpression
39
- * @example
40
- * ```typescript
41
- * public execute(flow: core.Flow, options?: { expression: string }): core.RuleResult {
42
- * // your rule
43
- * }
44
- */ _define_property(this, "isConfigurable", void 0);
45
- /**
46
33
  * The display label for the rule.
47
34
  * This property is being displayed on sf cli and on vsce
48
35
  */ _define_property(this, "label", void 0);
@@ -80,9 +80,7 @@ let APIVersion = class APIVersion extends _RuleCommon.RuleCommon {
80
80
  label: "Outdated API Version",
81
81
  description: "Introducing newer API components may lead to unexpected issues with older versions of Flows, as they might not align with the underlying mechanics. Starting from API version 50.0, the 'Api Version' attribute has been readily available on the Flow Object. To ensure smooth operation and reduce discrepancies between API versions, it is strongly advised to regularly update and maintain them.",
82
82
  supportedTypes: _internals.FlowType.allTypes(),
83
- docRefs: [],
84
- isConfigurable: true,
85
- autoFixable: false
83
+ docRefs: []
86
84
  });
87
85
  }
88
86
  };
@@ -19,7 +19,6 @@ let ActionCallsInLoop = class ActionCallsInLoop extends _LoopRuleCommon.LoopRule
19
19
  }
20
20
  constructor(){
21
21
  super({
22
- autoFixable: false,
23
22
  description: "To prevent exceeding Apex governor limits, it is advisable to consolidate and bulkify your apex calls, utilize a single action call containing a collection variable at the end of the loop.",
24
23
  docRefs: [
25
24
  {
@@ -27,7 +26,6 @@ let ActionCallsInLoop = class ActionCallsInLoop extends _LoopRuleCommon.LoopRule
27
26
  path: "https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_annotation_InvocableMethod.htm"
28
27
  }
29
28
  ],
30
- isConfigurable: false,
31
29
  label: "Action Call In Loop",
32
30
  name: "ActionCallsInLoop",
33
31
  supportedTypes: _internals.FlowType.backEndTypes
@@ -69,9 +69,7 @@ let AutoLayout = class AutoLayout extends _RuleCommon.RuleCommon {
69
69
  label: "Auto-Layout Mode",
70
70
  description: "With Canvas Mode set to Auto-Layout, Elements are spaced, connected, and aligned automatically, keeping your Flow neatly organized thus saving you time.",
71
71
  supportedTypes: _internals.FlowType.allTypes(),
72
- docRefs: [],
73
- isConfigurable: true,
74
- autoFixable: false
72
+ docRefs: []
75
73
  });
76
74
  }
77
75
  };
@@ -63,9 +63,7 @@ let CopyAPIName = class CopyAPIName extends _RuleCommon.RuleCommon {
63
63
  label: "Copy API Name",
64
64
  description: "Maintaining multiple elements with a similar name, like 'Copy_X_Of_Element,' can diminish the overall readability of your Flow. When copying and pasting these elements, it's crucial to remember to update the API name of the newly created copy.",
65
65
  supportedTypes: _internals.FlowType.allTypes(),
66
- docRefs: [],
67
- isConfigurable: false,
68
- autoFixable: false
66
+ docRefs: []
69
67
  });
70
68
  }
71
69
  };
@@ -96,9 +96,7 @@ let CyclomaticComplexity = class CyclomaticComplexity extends _RuleCommon.RuleCo
96
96
  label: `Cyclomatic complexity is a software metric used to indicate the complexity of a program. It is a quantitative measure of the number of linearly independent paths through a program's source code.`,
97
97
  path: "https://en.wikipedia.org/wiki/Cyclomatic_complexity"
98
98
  }
99
- ],
100
- isConfigurable: true,
101
- autoFixable: false
99
+ ]
102
100
  }, {
103
101
  severity: "note"
104
102
  }), _define_property(this, "defaultThreshold", 25), _define_property(this, "cyclomaticComplexityUnit", 0);
@@ -20,7 +20,6 @@ let DMLStatementInLoop = class DMLStatementInLoop extends _LoopRuleCommon.LoopRu
20
20
  }
21
21
  constructor(){
22
22
  super({
23
- autoFixable: false,
24
23
  description: "To prevent exceeding Apex governor limits, it is advisable to consolidate all your database operations, including record creation, updates, or deletions, at the conclusion of the flow.",
25
24
  docRefs: [
26
25
  {
@@ -28,7 +27,6 @@ let DMLStatementInLoop = class DMLStatementInLoop extends _LoopRuleCommon.LoopRu
28
27
  path: "https://help.salesforce.com/s/articleView?id=sf.flow_prep_bestpractices.htm&type=5"
29
28
  }
30
29
  ],
31
- isConfigurable: false,
32
30
  label: "DML Statement In A Loop",
33
31
  name: "DMLStatementInLoop",
34
32
  supportedTypes: _internals.FlowType.backEndTypes
@@ -136,9 +136,7 @@ let DuplicateDMLOperation = class DuplicateDMLOperation extends _RuleCommon.Rule
136
136
  label: "Duplicate DML Operation",
137
137
  description: "When the flow executes database changes or actions between two screens, it's important to prevent users from navigating back between screens. Failure to do so may result in duplicate database operations being performed within the flow.",
138
138
  supportedTypes: _internals.FlowType.visualTypes,
139
- docRefs: [],
140
- isConfigurable: false,
141
- autoFixable: false
139
+ docRefs: []
142
140
  });
143
141
  }
144
142
  };
@@ -63,10 +63,8 @@ let FlowDescription = class FlowDescription extends _RuleCommon.RuleCommon {
63
63
  }
64
64
  constructor(){
65
65
  super({
66
- autoFixable: false,
67
66
  description: "Descriptions play a vital role in documentation. We highly recommend including details about where they are used and their intended purpose.",
68
67
  docRefs: [],
69
- isConfigurable: false,
70
68
  label: "Missing Flow Description",
71
69
  name: "FlowDescription",
72
70
  supportedTypes: [
@@ -66,7 +66,6 @@ let FlowName = class FlowName extends _RuleCommon.RuleCommon {
66
66
  }
67
67
  constructor(){
68
68
  super({
69
- autoFixable: false,
70
69
  description: "The readability of a flow is of utmost importance. Establishing a naming convention for the Flow Name significantly enhances findability, searchability, and maintains overall consistency. It is advisable to include at least a domain and a brief description of the actions carried out in the flow, for instance, 'Service_OrderFulfillment'.",
71
70
  docRefs: [
72
71
  {
@@ -74,7 +73,6 @@ let FlowName = class FlowName extends _RuleCommon.RuleCommon {
74
73
  path: "https://www.linkedin.com/posts/stephen-n-church_naming-your-flows-this-is-more-critical-activity-7099733198175158274-1sPx"
75
74
  }
76
75
  ],
77
- isConfigurable: true,
78
76
  label: "Flow Naming Convention",
79
77
  name: "FlowName",
80
78
  supportedTypes: _internals.FlowType.allTypes()
@@ -66,7 +66,6 @@ let GetRecordAllFields = class GetRecordAllFields extends _RuleCommon.RuleCommon
66
66
  }
67
67
  constructor(){
68
68
  super({
69
- autoFixable: false,
70
69
  description: "Following the principle of least privilege (PoLP), avoid using Get Records with 'Automatically store all fields' unless necessary.",
71
70
  docRefs: [
72
71
  {
@@ -78,7 +77,6 @@ let GetRecordAllFields = class GetRecordAllFields extends _RuleCommon.RuleCommon
78
77
  path: "https://developer.salesforce.com/docs/atlas.en-us.salesforce_large_data_volumes_bp.meta/salesforce_large_data_volumes_bp/ldv_deployments_infrastructure_indexes.htm"
79
78
  }
80
79
  ],
81
- isConfigurable: false,
82
80
  label: "Get Record All Fields",
83
81
  name: "GetRecordAllFields",
84
82
  supportedTypes: _internals.FlowType.allTypes()
@@ -71,9 +71,7 @@ let HardcodedId = class HardcodedId extends _RuleCommon.RuleCommon {
71
71
  label: "Don't hard code Record Type IDs in Flow. By Stephen Church.",
72
72
  path: "https://www.linkedin.com/feed/update/urn:li:activity:6947530300012826624/"
73
73
  }
74
- ],
75
- isConfigurable: false,
76
- autoFixable: false
74
+ ]
77
75
  });
78
76
  }
79
77
  };
@@ -18,7 +18,6 @@ let HardcodedUrl = class HardcodedUrl extends _RuleCommon.RuleCommon {
18
18
  }
19
19
  constructor(){
20
20
  super({
21
- autoFixable: false,
22
21
  description: "Avoid hard-coding URLs as they are org-specific. Instead, use a $API formula (preferred) or you can use an environment-specific such as custom labels, custom metadata, or custom settings.",
23
22
  docRefs: [
24
23
  {
@@ -30,7 +29,6 @@ let HardcodedUrl = class HardcodedUrl extends _RuleCommon.RuleCommon {
30
29
  path: "https://admin.salesforce.com/blog/2021/why-you-should-avoid-hard-coding-and-three-alternative-solutions"
31
30
  }
32
31
  ],
33
- isConfigurable: false,
34
32
  label: "Hardcoded Url",
35
33
  name: "HardcodedUrl",
36
34
  supportedTypes: _internals.FlowType.allTypes()
@@ -66,9 +66,7 @@ let InactiveFlow = class InactiveFlow extends _RuleCommon.RuleCommon {
66
66
  label: "Inactive Flow",
67
67
  description: "Like cleaning out your closet: deleting unused flows is essential. Inactive flows can still cause trouble, like accidentally deleting records during testing, or being activated as subflows within parent flows.",
68
68
  supportedTypes: _internals.FlowType.allTypes(),
69
- docRefs: [],
70
- isConfigurable: false,
71
- autoFixable: false
69
+ docRefs: []
72
70
  });
73
71
  }
74
72
  };
@@ -120,7 +120,6 @@ let MissingFaultPath = class MissingFaultPath extends _RuleCommon.RuleCommon {
120
120
  }
121
121
  constructor(){
122
122
  super({
123
- autoFixable: false,
124
123
  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.",
125
124
  docRefs: [
126
125
  {
@@ -128,7 +127,6 @@ let MissingFaultPath = class MissingFaultPath extends _RuleCommon.RuleCommon {
128
127
  path: "https://help.salesforce.com/s/articleView?id=sf.flow_prep_bestpractices.htm&type=5"
129
128
  }
130
129
  ],
131
- isConfigurable: false,
132
130
  label: "Missing Fault Path",
133
131
  name: "MissingFaultPath",
134
132
  supportedTypes: [
@@ -65,10 +65,8 @@ let MissingMetadataDescription = class MissingMetadataDescription extends _RuleC
65
65
  }
66
66
  constructor(){
67
67
  super({
68
- autoFixable: false,
69
68
  description: "Every element must have a meaningful description",
70
69
  docRefs: [],
71
- isConfigurable: false,
72
70
  label: "Missing Metadata Description",
73
71
  name: "MissingMetadataDescription",
74
72
  supportedTypes: _internals.FlowType.allTypes()
@@ -130,10 +130,8 @@ let MissingNullHandler = class MissingNullHandler extends _RuleCommon.RuleCommon
130
130
  }
131
131
  constructor(){
132
132
  super({
133
- autoFixable: false,
134
133
  description: "When a Get Records operation doesn't find any data, it returns null. To ensure data validation, utilize a decision element on the operation result variable to check for a non-null result.",
135
134
  docRefs: [],
136
- isConfigurable: false,
137
135
  label: "Missing Null Handler",
138
136
  name: "MissingNullHandler",
139
137
  supportedTypes: [
@@ -68,9 +68,7 @@ let ProcessBuilder = class ProcessBuilder extends _RuleCommon.RuleCommon {
68
68
  label: "Process Builder Retirement",
69
69
  path: "https://help.salesforce.com/s/articleView?id=000389396&type=1"
70
70
  }
71
- ],
72
- isConfigurable: true,
73
- autoFixable: false
71
+ ]
74
72
  });
75
73
  }
76
74
  };
@@ -101,7 +101,6 @@ let RecursiveAfterUpdate = class RecursiveAfterUpdate extends _RuleCommon.RuleCo
101
101
  }
102
102
  constructor(){
103
103
  super({
104
- autoFixable: false,
105
104
  description: "After updates are meant to be used for record modifications that are not the same record that triggered the flow. Using after updates on the same record can lead to recursion and unexpected behavior. Consider using before save flows for same record updates.",
106
105
  docRefs: [
107
106
  {
@@ -109,7 +108,6 @@ let RecursiveAfterUpdate = class RecursiveAfterUpdate extends _RuleCommon.RuleCo
109
108
  path: "https://architect.salesforce.com/decision-guides/trigger-automation#Same_Record_Field_Updates"
110
109
  }
111
110
  ],
112
- isConfigurable: false,
113
111
  label: "Recursive After Update",
114
112
  name: "RecursiveAfterUpdate",
115
113
  supportedTypes: [
@@ -18,7 +18,6 @@ let SOQLQueryInLoop = class SOQLQueryInLoop extends _LoopRuleCommon.LoopRuleComm
18
18
  }
19
19
  constructor(){
20
20
  super({
21
- autoFixable: false,
22
21
  description: "To prevent exceeding Apex governor limits, it is advisable to consolidate all your SOQL queries at the conclusion of the flow.",
23
22
  docRefs: [
24
23
  {
@@ -26,7 +25,6 @@ let SOQLQueryInLoop = class SOQLQueryInLoop extends _LoopRuleCommon.LoopRuleComm
26
25
  path: "https://help.salesforce.com/s/articleView?id=sf.flow_prep_bestpractices.htm&type=5"
27
26
  }
28
27
  ],
29
- isConfigurable: false,
30
28
  label: "SOQL Query In A Loop",
31
29
  name: "SOQLQueryInLoop",
32
30
  supportedTypes: _internals.FlowType.backEndTypes
@@ -95,9 +95,7 @@ let SameRecordFieldUpdates = class SameRecordFieldUpdates extends _RuleCommon.Ru
95
95
  label: "Learn about same record field updates",
96
96
  path: "https://architect.salesforce.com/decision-guides/trigger-automation#Same_Record_Field_Updates"
97
97
  }
98
- ],
99
- isConfigurable: false,
100
- autoFixable: false
98
+ ]
101
99
  }, {
102
100
  severity: "warning"
103
101
  }), _define_property(this, "qualifiedRecordTriggerTypes", new Set([
@@ -87,9 +87,7 @@ let TriggerOrder = class TriggerOrder extends _RuleCommon.RuleCommon {
87
87
  label: "Learn more about flow ordering orchestration",
88
88
  path: "https://architect.salesforce.com/decision-guides/trigger-automation#Ordering___Orchestration"
89
89
  }
90
- ],
91
- isConfigurable: false,
92
- autoFixable: false
90
+ ]
93
91
  }, {
94
92
  severity: "note"
95
93
  }), _define_property(this, "qualifiedRecordTriggerTypes", new Set([