@sfdxy/mule-lint 1.19.0 → 1.21.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (154) hide show
  1. package/README.md +128 -73
  2. package/dist/package.json +1 -1
  3. package/dist/src/core/XPathHelper.d.ts.map +1 -1
  4. package/dist/src/core/XPathHelper.js +8 -0
  5. package/dist/src/core/XPathHelper.js.map +1 -1
  6. package/dist/src/engine/LintEngine.d.ts +32 -0
  7. package/dist/src/engine/LintEngine.d.ts.map +1 -1
  8. package/dist/src/engine/LintEngine.js +166 -15
  9. package/dist/src/engine/LintEngine.js.map +1 -1
  10. package/dist/src/rules/api-led/ApikitConsoleProductionRule.d.ts +22 -0
  11. package/dist/src/rules/api-led/ApikitConsoleProductionRule.d.ts.map +1 -0
  12. package/dist/src/rules/api-led/ApikitConsoleProductionRule.js +43 -0
  13. package/dist/src/rules/api-led/ApikitConsoleProductionRule.js.map +1 -0
  14. package/dist/src/rules/api-led/ApikitMainFlowStructureRule.d.ts +24 -0
  15. package/dist/src/rules/api-led/ApikitMainFlowStructureRule.d.ts.map +1 -0
  16. package/dist/src/rules/api-led/ApikitMainFlowStructureRule.js +53 -0
  17. package/dist/src/rules/api-led/ApikitMainFlowStructureRule.js.map +1 -0
  18. package/dist/src/rules/api-led/ApikitStatusCodeVariableRule.d.ts +25 -0
  19. package/dist/src/rules/api-led/ApikitStatusCodeVariableRule.d.ts.map +1 -0
  20. package/dist/src/rules/api-led/ApikitStatusCodeVariableRule.js +59 -0
  21. package/dist/src/rules/api-led/ApikitStatusCodeVariableRule.js.map +1 -0
  22. package/dist/src/rules/connector/EventListenerNullGuardRule.d.ts +24 -0
  23. package/dist/src/rules/connector/EventListenerNullGuardRule.d.ts.map +1 -0
  24. package/dist/src/rules/connector/EventListenerNullGuardRule.js +58 -0
  25. package/dist/src/rules/connector/EventListenerNullGuardRule.js.map +1 -0
  26. package/dist/src/rules/connector/ReplayChannelConfigRule.d.ts +23 -0
  27. package/dist/src/rules/connector/ReplayChannelConfigRule.d.ts.map +1 -0
  28. package/dist/src/rules/connector/ReplayChannelConfigRule.js +52 -0
  29. package/dist/src/rules/connector/ReplayChannelConfigRule.js.map +1 -0
  30. package/dist/src/rules/dataweave/DataWeaveRules.d.ts +17 -4
  31. package/dist/src/rules/dataweave/DataWeaveRules.d.ts.map +1 -1
  32. package/dist/src/rules/dataweave/DataWeaveRules.js +36 -20
  33. package/dist/src/rules/dataweave/DataWeaveRules.js.map +1 -1
  34. package/dist/src/rules/dataweave/DuplicateTransformLogicRule.d.ts +25 -0
  35. package/dist/src/rules/dataweave/DuplicateTransformLogicRule.d.ts.map +1 -0
  36. package/dist/src/rules/dataweave/DuplicateTransformLogicRule.js +63 -0
  37. package/dist/src/rules/dataweave/DuplicateTransformLogicRule.js.map +1 -0
  38. package/dist/src/rules/error-handling/CatchAllLastRule.d.ts +24 -0
  39. package/dist/src/rules/error-handling/CatchAllLastRule.d.ts.map +1 -0
  40. package/dist/src/rules/error-handling/CatchAllLastRule.js +65 -0
  41. package/dist/src/rules/error-handling/CatchAllLastRule.js.map +1 -0
  42. package/dist/src/rules/error-handling/CorrelationIdRule.d.ts +22 -1
  43. package/dist/src/rules/error-handling/CorrelationIdRule.d.ts.map +1 -1
  44. package/dist/src/rules/error-handling/CorrelationIdRule.js +107 -6
  45. package/dist/src/rules/error-handling/CorrelationIdRule.js.map +1 -1
  46. package/dist/src/rules/error-handling/ErrorHandlerTypeCoverageRule.d.ts +28 -0
  47. package/dist/src/rules/error-handling/ErrorHandlerTypeCoverageRule.d.ts.map +1 -0
  48. package/dist/src/rules/error-handling/ErrorHandlerTypeCoverageRule.js +70 -0
  49. package/dist/src/rules/error-handling/ErrorHandlerTypeCoverageRule.js.map +1 -0
  50. package/dist/src/rules/error-handling/ErrorResponseStructureRule.d.ts +23 -0
  51. package/dist/src/rules/error-handling/ErrorResponseStructureRule.d.ts.map +1 -0
  52. package/dist/src/rules/error-handling/ErrorResponseStructureRule.js +73 -0
  53. package/dist/src/rules/error-handling/ErrorResponseStructureRule.js.map +1 -0
  54. package/dist/src/rules/error-handling/GenericErrorRule.d.ts +15 -3
  55. package/dist/src/rules/error-handling/GenericErrorRule.d.ts.map +1 -1
  56. package/dist/src/rules/error-handling/GenericErrorRule.js +58 -18
  57. package/dist/src/rules/error-handling/GenericErrorRule.js.map +1 -1
  58. package/dist/src/rules/error-handling/GlobalErrorHandlerRule.d.ts +16 -5
  59. package/dist/src/rules/error-handling/GlobalErrorHandlerRule.d.ts.map +1 -1
  60. package/dist/src/rules/error-handling/GlobalErrorHandlerRule.js +64 -21
  61. package/dist/src/rules/error-handling/GlobalErrorHandlerRule.js.map +1 -1
  62. package/dist/src/rules/error-handling/HttpStatusRule.d.ts +5 -0
  63. package/dist/src/rules/error-handling/HttpStatusRule.d.ts.map +1 -1
  64. package/dist/src/rules/error-handling/HttpStatusRule.js +15 -0
  65. package/dist/src/rules/error-handling/HttpStatusRule.js.map +1 -1
  66. package/dist/src/rules/error-handling/TryScopeRule.d.ts +5 -0
  67. package/dist/src/rules/error-handling/TryScopeRule.d.ts.map +1 -1
  68. package/dist/src/rules/error-handling/TryScopeRule.js +30 -7
  69. package/dist/src/rules/error-handling/TryScopeRule.js.map +1 -1
  70. package/dist/src/rules/http/ConnectionIdleTimeoutRule.d.ts +27 -0
  71. package/dist/src/rules/http/ConnectionIdleTimeoutRule.d.ts.map +1 -0
  72. package/dist/src/rules/http/ConnectionIdleTimeoutRule.js +46 -0
  73. package/dist/src/rules/http/ConnectionIdleTimeoutRule.js.map +1 -0
  74. package/dist/src/rules/http/HttpContentTypeRule.d.ts +28 -1
  75. package/dist/src/rules/http/HttpContentTypeRule.d.ts.map +1 -1
  76. package/dist/src/rules/http/HttpContentTypeRule.js +68 -7
  77. package/dist/src/rules/http/HttpContentTypeRule.js.map +1 -1
  78. package/dist/src/rules/index.d.ts +1 -1
  79. package/dist/src/rules/index.d.ts.map +1 -1
  80. package/dist/src/rules/index.js +50 -8
  81. package/dist/src/rules/index.js.map +1 -1
  82. package/dist/src/rules/logging/LoggerPayloadRule.d.ts +15 -0
  83. package/dist/src/rules/logging/LoggerPayloadRule.d.ts.map +1 -1
  84. package/dist/src/rules/logging/LoggerPayloadRule.js +48 -4
  85. package/dist/src/rules/logging/LoggerPayloadRule.js.map +1 -1
  86. package/dist/src/rules/operations/FlowRefTargetExistsRule.d.ts +23 -0
  87. package/dist/src/rules/operations/FlowRefTargetExistsRule.d.ts.map +1 -0
  88. package/dist/src/rules/operations/FlowRefTargetExistsRule.js +58 -0
  89. package/dist/src/rules/operations/FlowRefTargetExistsRule.js.map +1 -0
  90. package/dist/src/rules/operations/UnusedFlowRule.d.ts +26 -1
  91. package/dist/src/rules/operations/UnusedFlowRule.d.ts.map +1 -1
  92. package/dist/src/rules/operations/UnusedFlowRule.js +96 -16
  93. package/dist/src/rules/operations/UnusedFlowRule.js.map +1 -1
  94. package/dist/src/rules/operations/UnusedVariableRule.d.ts +31 -0
  95. package/dist/src/rules/operations/UnusedVariableRule.d.ts.map +1 -0
  96. package/dist/src/rules/operations/UnusedVariableRule.js +103 -0
  97. package/dist/src/rules/operations/UnusedVariableRule.js.map +1 -0
  98. package/dist/src/rules/performance/ConnectionPoolingRule.d.ts +5 -0
  99. package/dist/src/rules/performance/ConnectionPoolingRule.d.ts.map +1 -1
  100. package/dist/src/rules/performance/ConnectionPoolingRule.js +18 -5
  101. package/dist/src/rules/performance/ConnectionPoolingRule.js.map +1 -1
  102. package/dist/src/rules/performance/ListenerReconnectForeverRule.d.ts +28 -0
  103. package/dist/src/rules/performance/ListenerReconnectForeverRule.d.ts.map +1 -0
  104. package/dist/src/rules/performance/ListenerReconnectForeverRule.js +56 -0
  105. package/dist/src/rules/performance/ListenerReconnectForeverRule.js.map +1 -0
  106. package/dist/src/rules/performance/ReconnectionStrategyRule.d.ts +10 -0
  107. package/dist/src/rules/performance/ReconnectionStrategyRule.d.ts.map +1 -1
  108. package/dist/src/rules/performance/ReconnectionStrategyRule.js +47 -14
  109. package/dist/src/rules/performance/ReconnectionStrategyRule.js.map +1 -1
  110. package/dist/src/rules/security/ConnectorCredentialsSecuredRule.d.ts +36 -0
  111. package/dist/src/rules/security/ConnectorCredentialsSecuredRule.d.ts.map +1 -0
  112. package/dist/src/rules/security/ConnectorCredentialsSecuredRule.js +124 -0
  113. package/dist/src/rules/security/ConnectorCredentialsSecuredRule.js.map +1 -0
  114. package/dist/src/rules/security/HardcodedCredentialsRule.d.ts +4 -0
  115. package/dist/src/rules/security/HardcodedCredentialsRule.d.ts.map +1 -1
  116. package/dist/src/rules/security/HardcodedCredentialsRule.js +15 -0
  117. package/dist/src/rules/security/HardcodedCredentialsRule.js.map +1 -1
  118. package/dist/src/rules/security/SecurePropertiesEncryptionRule.d.ts +25 -0
  119. package/dist/src/rules/security/SecurePropertiesEncryptionRule.d.ts.map +1 -0
  120. package/dist/src/rules/security/SecurePropertiesEncryptionRule.js +59 -0
  121. package/dist/src/rules/security/SecurePropertiesEncryptionRule.js.map +1 -0
  122. package/dist/src/rules/security/SecurePropertiesKeyRule.d.ts +23 -0
  123. package/dist/src/rules/security/SecurePropertiesKeyRule.d.ts.map +1 -0
  124. package/dist/src/rules/security/SecurePropertiesKeyRule.js +45 -0
  125. package/dist/src/rules/security/SecurePropertiesKeyRule.js.map +1 -0
  126. package/dist/src/rules/security/TlsKeystorePasswordRule.d.ts +25 -0
  127. package/dist/src/rules/security/TlsKeystorePasswordRule.d.ts.map +1 -0
  128. package/dist/src/rules/security/TlsKeystorePasswordRule.js +63 -0
  129. package/dist/src/rules/security/TlsKeystorePasswordRule.js.map +1 -0
  130. package/dist/src/rules/standards/ApikitRouteVariableConsistencyRule.d.ts +26 -0
  131. package/dist/src/rules/standards/ApikitRouteVariableConsistencyRule.d.ts.map +1 -0
  132. package/dist/src/rules/standards/ApikitRouteVariableConsistencyRule.js +61 -0
  133. package/dist/src/rules/standards/ApikitRouteVariableConsistencyRule.js.map +1 -0
  134. package/dist/src/rules/standards/ConfigPropertiesOrderingRule.d.ts +34 -0
  135. package/dist/src/rules/standards/ConfigPropertiesOrderingRule.d.ts.map +1 -0
  136. package/dist/src/rules/standards/ConfigPropertiesOrderingRule.js +76 -0
  137. package/dist/src/rules/standards/ConfigPropertiesOrderingRule.js.map +1 -0
  138. package/dist/src/rules/standards/MissingEnvPropertiesDeclarationRule.d.ts +25 -0
  139. package/dist/src/rules/standards/MissingEnvPropertiesDeclarationRule.d.ts.map +1 -0
  140. package/dist/src/rules/standards/MissingEnvPropertiesDeclarationRule.js +111 -0
  141. package/dist/src/rules/standards/MissingEnvPropertiesDeclarationRule.js.map +1 -0
  142. package/dist/src/rules/structure/StructureRules.d.ts +8 -1
  143. package/dist/src/rules/structure/StructureRules.d.ts.map +1 -1
  144. package/dist/src/rules/structure/StructureRules.js +11 -7
  145. package/dist/src/rules/structure/StructureRules.js.map +1 -1
  146. package/dist/src/rules/yaml/YamlRules.d.ts +6 -2
  147. package/dist/src/rules/yaml/YamlRules.d.ts.map +1 -1
  148. package/dist/src/rules/yaml/YamlRules.js +15 -11
  149. package/dist/src/rules/yaml/YamlRules.js.map +1 -1
  150. package/dist/src/types/Rule.d.ts +35 -0
  151. package/dist/src/types/Rule.d.ts.map +1 -1
  152. package/docs/best-practices/rules-catalog.md +444 -42
  153. package/docs/linter/architecture.md +119 -64
  154. package/package.json +1 -1
@@ -1,8 +1,8 @@
1
1
  # Rules Catalog
2
2
 
3
- > **Version:** 3.0.0
4
- > **Total Rules:** 56 implemented across 14 categories
5
- > **Last Updated:** February 2026
3
+ > **Version:** 1.21.0
4
+ > **Total Rules:** 82 implemented across 16 categories
5
+ > **Last Updated:** April 2026
6
6
 
7
7
  ---
8
8
 
@@ -22,6 +22,7 @@
22
22
  - [YAML Rules](#yaml-rules)
23
23
  - [DataWeave Rules](#dataweave-rules)
24
24
  - [API-Led Rules](#api-led-rules)
25
+ - [Connector Rules](#connector-rules)
25
26
  - [Operations & Hygiene Rules](#operations--hygiene-rules)
26
27
  - [Governance Rules](#governance-rules)
27
28
  - [Experimental Rules](#experimental-rules)
@@ -30,24 +31,25 @@
30
31
 
31
32
  ## Rule Categories
32
33
 
33
- | Family | Prefix | Count | Description |
34
- | -------------- | ------------------------------------------ | ----- | ---------------------------------------------- |
35
- | Error Handling | MULE-001/003/005/007/009, ERR-001 | 6 | Error handler configuration and best practices |
36
- | Naming | MULE-002/101/102 | 3 | Naming conventions for flows and variables |
37
- | Security | MULE-004/201/202, SEC-002/003/004/006 | 7 | Security vulnerabilities, TLS, rate limiting |
38
- | Logging | MULE-006/301/303, LOG-001/004, HYG-001 | 6 | Logging standards, structured logging, hygiene |
39
- | HTTP | MULE-401/402/403 | 3 | HTTP configuration and headers |
40
- | Performance | MULE-501/502/503, PERF-002, RES-001 | 5 | Performance anti-patterns and resilience |
41
- | Documentation | MULE-601/604, DOC-001 | 3 | Documentation requirements |
42
- | Standards | MULE-008/010/701, OPS-001/002/003, API-005 | 7 | Coding standards and operations |
43
- | Complexity | MULE-801 | 1 | Code complexity |
44
- | Structure | MULE-802/803/804 | 3 | Project structure |
45
- | YAML | YAML-001/003/004 | 3 | YAML configuration validation |
46
- | DataWeave | DW-001/002/003/004 | 4 | DataWeave file validation |
47
- | API-Led | API-001/002/003/004 | 4 | API-Led connectivity patterns |
48
- | Governance | PROJ-001/002 | 2 | POM and Git hygiene |
49
- | Code Hygiene | HYG-002/003 | 2 | Commented code and unused flows |
50
- | Experimental | EXP-001/002/003 | 3 | Beta rules for evaluation |
34
+ | Family | Prefix | Count | Description |
35
+ | -------------- | ------------------------------------------------------------ | ----- | ---------------------------------------------- |
36
+ | Error Handling | MULE-001/003/005/007/009, ERR-001–004 | 9 | Error handler configuration and best practices |
37
+ | Naming | MULE-002/101/102 | 3 | Naming conventions for flows and variables |
38
+ | Security | MULE-004/201/202, SEC-002004/006–010 | 11 | Security vulnerabilities, TLS, credentials |
39
+ | Logging | MULE-006/301/303, LOG-001/004, HYG-001 | 6 | Logging standards, structured logging, hygiene |
40
+ | HTTP | MULE-401/402/403, HTTP-004 | 4 | HTTP configuration and headers |
41
+ | Performance | MULE-501/502/503, PERF-002, RES-001/002 | 6 | Performance anti-patterns and resilience |
42
+ | Documentation | MULE-601/604, DOC-001 | 3 | Documentation requirements |
43
+ | Standards | MULE-008/010/701, OPS-001003, API-005, CFG-001/002, STD-001 | 10 | Coding standards and operations |
44
+ | Complexity | MULE-801 | 1 | Code complexity |
45
+ | Structure | MULE-802/803/804 | 3 | Project structure |
46
+ | YAML | YAML-001/003/004 | 3 | YAML configuration validation |
47
+ | DataWeave | DW-001/002/003/004/005 | 5 | DataWeave file validation |
48
+ | API-Led | API-001–004/006–008 | 7 | API-Led connectivity patterns |
49
+ | Connectors | SF-001/002 | 2 | Salesforce and event connector rules |
50
+ | Governance | PROJ-001/002 | 2 | POM and Git hygiene |
51
+ | Code Hygiene | HYG-002–005 | 4 | Commented code, unused flows/variables |
52
+ | Experimental | EXP-001/002/003 | 3 | Beta rules for evaluation |
51
53
 
52
54
  ### MULE Category ID Ranges
53
55
 
@@ -75,16 +77,24 @@
75
77
 
76
78
  | Property | Value |
77
79
  | ------------ | -------------- |
78
- | **Severity** | Error |
80
+ | **Severity** | Warning |
79
81
  | **Category** | Error Handling |
80
82
  | **Fixable** | No |
81
83
 
82
- **Description:** Every Mule project should have a global error handler file with a reusable error-handler configuration.
84
+ **Description:** Every Mule project should have a global error handler — either a dedicated file (`src/main/mule/global-error-handler.xml` by default) **or** any XML flow file that contains a named `<error-handler>` element.
83
85
 
84
86
  **Check Logic:**
85
87
 
86
- 1. Verify file exists: `src/main/mule/global-error-handler.xml`
87
- 2. Verify contains: `<error-handler name="global-error-handler">`
88
+ 1. If the expected file exists (`src/main/mule/global-error-handler.xml`), the rule passes.
89
+ 2. Otherwise, checks each flow file for a named `<error-handler name="...">` or `<error-handler ref="...">` element.
90
+ 3. If neither is found in a flow file (a file containing `<flow>` or `<sub-flow>` elements), a warning is reported.
91
+ 4. Pure configuration files (no flows) are skipped to reduce noise.
92
+
93
+ **Options:**
94
+
95
+ | Option | Default | Description |
96
+ | ---------- | ---------------------------------------- | ------------------------------ |
97
+ | `filePath` | `src/main/mule/global-error-handler.xml` | Relative path to expected file |
88
98
 
89
99
  **Why This Matters:** A global error handler ensures consistent error responses across all flows and reduces code duplication.
90
100
 
@@ -118,6 +128,14 @@
118
128
 
119
129
  **Description:** Error handlers should set an `httpStatus` variable for proper API responses.
120
130
 
131
+ **Project Detection:** This rule is automatically skipped for non-HTTP projects. When `mule-lint` scans a project, it detects whether any `http:listener` or `apikit:router` element is present. If neither is found, the rule is suppressed to avoid false positives in event-driven or batch Mule applications.
132
+
133
+ **Options:**
134
+
135
+ | Option | Default | Description |
136
+ | -------------- | ------------ | --------------------------- |
137
+ | `variableName` | `httpStatus` | Name of the variable to set |
138
+
121
139
  **Best Practice:** Always set httpStatus in error handlers to return appropriate HTTP codes (400, 404, 500, etc.).
122
140
 
123
141
  ---
@@ -132,6 +150,24 @@
132
150
 
133
151
  **Description:** Error handlers should reference `correlationId` for traceability across distributed systems.
134
152
 
153
+ **Check Logic:**
154
+
155
+ 1. Checks inline XML text and attributes for correlation ID patterns (`correlationId`, `correlation_id`, `x-correlation-id`, `x-request-id`, etc.)
156
+ 2. For `ee:set-payload` elements with a `resource="..."` attribute, reads the referenced `.dwl` file from `src/main/resources/<resourcePath>` and checks its content.
157
+ 3. If a resource file is referenced but cannot be read (e.g. not yet generated), downgrades to `info` severity to avoid false positives.
158
+
159
+ **Example (inline):**
160
+
161
+ ```xml
162
+ <on-error-continue>
163
+ <ee:transform>
164
+ <ee:set-payload resource="classpath:dwl/error-response.dwl"/>
165
+ </ee:transform>
166
+ </on-error-continue>
167
+ ```
168
+
169
+ The DWL file at `src/main/resources/dwl/error-response.dwl` will be checked for `correlationId` usage.
170
+
135
171
  ---
136
172
 
137
173
  ### MULE-009: Generic Error Type
@@ -146,6 +182,8 @@
146
182
 
147
183
  **Why This Matters:** Catching `ANY` can mask important errors and make debugging difficult.
148
184
 
185
+ > **Note (v1.21):** The rule now skips `type="ANY"` when it is the **last** `on-error` block in the chain. Using `type="ANY"` as a catch-all fallback (returning HTTP 500) is an accepted MuleSoft pattern per accelerator best practices.
186
+
149
187
  ---
150
188
 
151
189
  ### ERR-001: Try Scope Best Practice
@@ -185,6 +223,73 @@
185
223
 
186
224
  ---
187
225
 
226
+ ### ERR-002: Error Handler Type Coverage
227
+
228
+ | Property | Value |
229
+ | -------------- | -------------- |
230
+ | **Severity** | Warning |
231
+ | **Category** | Error Handling |
232
+ | **Issue Type** | Bug |
233
+ | **Fixable** | No |
234
+
235
+ **Description:** APIKit-based flows should handle common HTTP error types. Error handlers should cover at least the standard set: `APIKIT:BAD_REQUEST`, `APIKIT:NOT_FOUND`, `APIKIT:METHOD_NOT_ALLOWED`, and `APIKIT:NOT_ACCEPTABLE`.
236
+
237
+ **Example:**
238
+
239
+ ```xml
240
+ <!-- ✅ Good - covers common error types -->
241
+ <error-handler>
242
+ <on-error-propagate type="APIKIT:BAD_REQUEST">...</on-error-propagate>
243
+ <on-error-propagate type="APIKIT:NOT_FOUND">...</on-error-propagate>
244
+ <on-error-propagate type="APIKIT:METHOD_NOT_ALLOWED">...</on-error-propagate>
245
+ <on-error-propagate type="ANY">...</on-error-propagate>
246
+ </error-handler>
247
+ ```
248
+
249
+ ---
250
+
251
+ ### ERR-003: Error Response Structure
252
+
253
+ | Property | Value |
254
+ | -------------- | -------------- |
255
+ | **Severity** | Warning |
256
+ | **Category** | Error Handling |
257
+ | **Issue Type** | Bug |
258
+ | **Fixable** | No |
259
+
260
+ **Description:** Error handlers should set both an `httpStatus` variable and a response body (via `set-payload` or `ee:set-payload`). Missing either results in incomplete error responses to API consumers.
261
+
262
+ ---
263
+
264
+ ### ERR-004: Catch-All Must Be Last
265
+
266
+ | Property | Value |
267
+ | -------------- | -------------- |
268
+ | **Severity** | Error |
269
+ | **Category** | Error Handling |
270
+ | **Issue Type** | Bug |
271
+ | **Fixable** | No |
272
+
273
+ **Description:** An `on-error-propagate` or `on-error-continue` with `type="ANY"` must be the **last** handler in the `error-handler` block. Placing it before specific error type handlers would shadow those handlers.
274
+
275
+ **Example:**
276
+
277
+ ````xml
278
+ <!-- ❌ Bad - ANY shadows subsequent handlers -->
279
+ <error-handler>
280
+ <on-error-propagate type="ANY">...</on-error-propagate>
281
+ <on-error-propagate type="HTTP:CONNECTIVITY">...</on-error-propagate>
282
+ </error-handler>
283
+
284
+ <!-- ✅ Good - ANY is last -->
285
+ <error-handler>
286
+ <on-error-propagate type="HTTP:CONNECTIVITY">...</on-error-propagate>
287
+ <on-error-propagate type="ANY">...</on-error-propagate>
288
+ </error-handler>
289
+ ```
290
+
291
+ ---
292
+
188
293
  ## Naming Rules
189
294
 
190
295
  > **Best Practice**: Consistent naming conventions improve readability and maintainability. Use kebab-case for flows and camelCase for variables.
@@ -197,7 +302,7 @@
197
302
  | **Category** | Naming |
198
303
  | **Fixable** | Yes |
199
304
 
200
- **Description:** Flows must end with `-flow` suffix, sub-flows with `-subflow`.
305
+ **Description:** Flows must end with `-flow` suffix, sub-flows with `-subflow`. Both flow and sub-flow naming are enforced by this rule.
201
306
 
202
307
  **Examples:**
203
308
 
@@ -209,7 +314,15 @@
209
314
  <!-- ❌ Bad -->
210
315
  <flow name="processOrder">
211
316
  <sub-flow name="validateInput">
212
- ```
317
+ ````
318
+
319
+ **Options:**
320
+
321
+ | Option | Default | Description |
322
+ | ----------------- | -------------------------------------------------- | ----------------------------------------- |
323
+ | `flowSuffix` | `-flow` | Required suffix for `<flow>` elements |
324
+ | `subflowSuffix` | `-subflow` | Required suffix for `<sub-flow>` elements |
325
+ | `excludePatterns` | `['*-api-main', '*-main', 'get:*', 'post:*', ...]` | Glob patterns to skip |
213
326
 
214
327
  ---
215
328
 
@@ -386,6 +499,68 @@
386
499
 
387
500
  ---
388
501
 
502
+ ### SEC-007: Connector Credentials Secured
503
+
504
+ | Property | Value |
505
+ | -------------- | ------------- |
506
+ | **Severity** | Error |
507
+ | **Category** | Security |
508
+ | **Issue Type** | Vulnerability |
509
+ | **Fixable** | No |
510
+
511
+ **Description:** Connector configurations (Salesforce, Database, HTTP, etc.) must use `${secure::...}` property placeholders for credential attributes like `username`, `password`, `clientId`, and `clientSecret`. Plain `${...}` placeholders are accepted but `${secure::...}` is recommended.
512
+
513
+ ---
514
+
515
+ ### SEC-008: Secure Properties Key
516
+
517
+ | Property | Value |
518
+ | -------------- | ------------- |
519
+ | **Severity** | Error |
520
+ | **Category** | Security |
521
+ | **Issue Type** | Vulnerability |
522
+ | **Fixable** | No |
523
+
524
+ **Description:** The `secure-properties:config` element's encryption `key` attribute must use a property placeholder (`${...}`), not a hardcoded value. Hardcoding the encryption key defeats the purpose of encrypted properties.
525
+
526
+ **Example:**
527
+
528
+ ```xml
529
+ <!-- ❌ Bad - hardcoded key -->
530
+ <secure-properties:config key="mySecretKey123" file="secure.yaml"/>
531
+
532
+ <!-- ✅ Good - externalized key -->
533
+ <secure-properties:config key="${mule.key}" file="secure.yaml"/>
534
+ ```
535
+
536
+ ---
537
+
538
+ ### SEC-009: TLS Keystore Password
539
+
540
+ | Property | Value |
541
+ | -------------- | ------------- |
542
+ | **Severity** | Error |
543
+ | **Category** | Security |
544
+ | **Issue Type** | Vulnerability |
545
+ | **Fixable** | No |
546
+
547
+ **Description:** TLS keystore and truststore passwords must use secure property placeholders, not hardcoded values.
548
+
549
+ ---
550
+
551
+ ### SEC-010: Secure Properties Encryption
552
+
553
+ | Property | Value |
554
+ | -------------- | ------------- |
555
+ | **Severity** | Warning |
556
+ | **Category** | Security |
557
+ | **Issue Type** | Vulnerability |
558
+ | **Fixable** | No |
559
+
560
+ **Description:** Secure properties configuration should use a strong encryption algorithm. DES is considered weak; AES or Blowfish are recommended.
561
+
562
+ ---
563
+
389
564
  ## Logging Rules
390
565
 
391
566
  > **Best Practice**: Use structured logging with categories. Never log full payloads in production - they may contain PII or be excessively large.
@@ -535,6 +710,16 @@
535
710
 
536
711
  **Description:** POST/PUT HTTP requests should include a `Content-Type` header.
537
712
 
713
+ **Detection Patterns:**
714
+
715
+ | Pattern | Description |
716
+ | ------------------------- | ------------------------------------------------------------------------------------------------- |
717
+ | A — Static header | `<http:header headerName="Content-Type" value="..."/>` inside `<http:headers>` |
718
+ | B — CDATA DataWeave block | `<http:headers><![CDATA[#[output application/java --- {"Content-Type": "..."}]]]></http:headers>` |
719
+ | C — Inline DW expression | `<http:headers value='#[{"Content-Type": "..."}]'/>` |
720
+
721
+ When headers are set via a DataWeave expression (patterns B/C) but `Content-Type` is not visible in the expression text, the issue is downgraded to **info** severity to acknowledge the static analysis limitation of evaluating dynamic expressions.
722
+
538
723
  ---
539
724
 
540
725
  ### MULE-403: HTTP Request Timeout
@@ -603,13 +788,20 @@
603
788
 
604
789
  **Description:** DB and HTTP connectors should configure connection pools for optimal performance and resource management.
605
790
 
606
- **Check Logic:** Flags HTTP request configs missing `maxConnections`/`connectionIdleTimeout` and DB configs missing `pooling-profile`.
791
+ **Check Logic:** Flags HTTP `request-config` elements missing `maxConnections`/`connectionIdleTimeout` — checks both the `<http:request-config>` element and its nested `<http:request-connection>` child (XSD-correct placement). Also flags DB configs missing `pooling-profile`.
607
792
 
608
793
  **Example:**
609
794
 
610
795
  ```xml
611
- <!-- ✅ Good - HTTP with pooling -->
612
- <http:request-config name="API_Config" maxConnections="20" connectionIdleTimeout="30000"/>
796
+ <!-- ✅ Good - HTTP with pooling on request-connection (XSD-correct) -->
797
+ <http:request-config name="API_Config">
798
+ <http:request-connection>
799
+ <http:client-socket-properties>
800
+ <http:tcp-client-socket-properties connectionTimeout="30000"/>
801
+ </http:client-socket-properties>
802
+ </http:request-connection>
803
+ </http:request-config>
804
+ <!-- maxConnections on http:request-connection avoids SAXParseException -->
613
805
 
614
806
  <!-- ✅ Good - DB with pooling -->
615
807
  <db:config name="Database_Config">
@@ -629,12 +821,14 @@
629
821
 
630
822
  **Description:** Connectors should have reconnection strategies configured for resilience.
631
823
 
632
- **Checked Connectors:** HTTP Request, HTTP Listener, JMS, AMQP, SFTP, FTP, VM, Database
824
+ **Checked Connectors:** HTTP Request, HTTP Listener, JMS, AMQP, SFTP, FTP, VM, Database, Salesforce
825
+
826
+ > **Note (v1.21):** The rule now differentiates between listener and request configurations. Listeners are recommended to use `reconnect-forever`, while requests should use bounded reconnect with `count` and `frequency`.
633
827
 
634
828
  **Example:**
635
829
 
636
830
  ```xml
637
- <!-- ✅ Good -->
831
+ <!-- ✅ Good - bounded reconnect for requests -->
638
832
  <http:request-config name="API_Config">
639
833
  <http:request-connection>
640
834
  <reconnection>
@@ -642,10 +836,31 @@
642
836
  </reconnection>
643
837
  </http:request-connection>
644
838
  </http:request-config>
839
+
840
+ <!-- ✅ Good - reconnect-forever for listeners -->
841
+ <http:listener-config name="Listener_Config">
842
+ <http:listener-connection>
843
+ <reconnection>
844
+ <reconnect-forever frequency="5000"/>
845
+ </reconnection>
846
+ </http:listener-connection>
847
+ </http:listener-config>
645
848
  ```
646
849
 
647
850
  ---
648
851
 
852
+ ### RES-002: Listener Reconnect-Forever
853
+
854
+ | Property | Value |
855
+ | ------------ | ----------- |
856
+ | **Severity** | Warning |
857
+ | **Category** | Performance |
858
+ | **Fixable** | No |
859
+
860
+ **Description:** Listener connectors (HTTP Listener, JMS, AMQP, VM) should use `reconnect-forever` strategy rather than bounded reconnection. Listeners are critical entry points — if they stop reconnecting after N attempts, the application becomes unreachable.
861
+
862
+ ---
863
+
649
864
  ## Documentation Rules
650
865
 
651
866
  > **Best Practice**: Well-documented flows are easier to maintain. Use meaningful names that describe business purpose.
@@ -821,6 +1036,42 @@
821
1036
 
822
1037
  ---
823
1038
 
1039
+ ### CFG-001: Config Properties Ordering
1040
+
1041
+ | Property | Value |
1042
+ | ------------ | --------- |
1043
+ | **Severity** | Info |
1044
+ | **Category** | Standards |
1045
+ | **Fixable** | No |
1046
+
1047
+ **Description:** Configuration property elements (`secure-properties:config`, `configuration-properties`, HTTP configs) should follow a consistent ordering at the top of Mule configuration files. This improves readability and makes it easier to locate configurations.
1048
+
1049
+ ---
1050
+
1051
+ ### CFG-002: Missing Env Properties Declaration
1052
+
1053
+ | Property | Value |
1054
+ | ------------ | --------- |
1055
+ | **Severity** | Warning |
1056
+ | **Category** | Standards |
1057
+ | **Fixable** | No |
1058
+
1059
+ **Description:** Property placeholders referenced in XML files (`${property.name}`) should have corresponding entries in the project's YAML configuration files. Detects potential runtime failures from missing property definitions.
1060
+
1061
+ ---
1062
+
1063
+ ### STD-001: APIKit Route Variable Consistency
1064
+
1065
+ | Property | Value |
1066
+ | ------------ | --------- |
1067
+ | **Severity** | Info |
1068
+ | **Category** | Standards |
1069
+ | **Fixable** | No |
1070
+
1071
+ **Description:** APIKit route implementation flows should use consistent variable naming patterns. For example, if some routes set `httpStatus` and others set `http_status`, this rule flags the inconsistency.
1072
+
1073
+ ---
1074
+
824
1075
  ## Complexity Rules
825
1076
 
826
1077
  > **Best Practice**: Keep cyclomatic complexity below 10. Extract complex logic into sub-flows.
@@ -883,12 +1134,17 @@
883
1134
  - `src/main/mule`
884
1135
  - `src/main/resources`
885
1136
 
886
- **Recommended Directories:**
1137
+ **Recommended Directories** (configurable via `recommendedDirs` option):
887
1138
 
888
1139
  - `src/main/resources/dwl`
889
- - `src/main/resources/api`
890
1140
  - `src/test/munit`
891
1141
 
1142
+ > **Note:** `src/main/resources/api` was removed from the default recommended list in v1.20.0. Many Mule 4 projects reference their API specification from Anypoint Exchange and do not bundle it locally. To restore this check, configure the rule explicitly:
1143
+ >
1144
+ > ```json
1145
+ > "MULE-802": { "enabled": true, "options": { "recommendedDirs": ["src/main/resources/dwl", "src/main/resources/api", "src/test/munit"] } }
1146
+ > ```
1147
+
892
1148
  ---
893
1149
 
894
1150
  ### MULE-803: Global Config File
@@ -929,12 +1185,26 @@
929
1185
 
930
1186
  **Description:** Environment-specific YAML property files should exist for each environment.
931
1187
 
932
- **Expected Files:**
1188
+ **Expected Files** (default environments: `dev`, `qa`, `prod`):
933
1189
 
934
1190
  - `dev.yaml` or `config-dev.yaml`
935
1191
  - `qa.yaml` or `config-qa.yaml`
936
1192
  - `prod.yaml` or `config-prod.yaml`
937
1193
 
1194
+ Files can also live in `src/main/resources/config/` or `src/main/resources/properties/` subdirectories.
1195
+
1196
+ **Options:**
1197
+
1198
+ | Option | Default | Description |
1199
+ | -------------- | ----------------------- | ---------------------------------- |
1200
+ | `environments` | `["dev", "qa", "prod"]` | List of required environment names |
1201
+
1202
+ **Example configuration** to add `staging` or change defaults:
1203
+
1204
+ ```json
1205
+ "YAML-001": { "enabled": true, "options": { "environments": ["dev", "staging", "prod"] } }
1206
+ ```
1207
+
938
1208
  ---
939
1209
 
940
1210
  ### YAML-003: Property Naming Convention
@@ -1009,6 +1279,21 @@ db.password: "![encryptedValue]"
1009
1279
 
1010
1280
  **Description:** DataWeave files should use kebab-case naming (`my-transform.dwl`).
1011
1281
 
1282
+ > **Note on DataWeave module directories:** DataWeave module files **must** use camelCase because hyphens (`-`) are invalid in DataWeave module identifiers (importing `my-module` would be a compile error). Use the `exemptPaths` option to exclude module directories from kebab-case enforcement.
1283
+
1284
+ **Options:**
1285
+
1286
+ | Option | Default | Description |
1287
+ | ------------- | ------------ | ---------------------------------------------------------- |
1288
+ | `convention` | `kebab-case` | Naming convention: `kebab-case`, `camelCase`, or `any` |
1289
+ | `exemptPaths` | `[]` | Glob patterns for paths to skip (e.g. `["**/modules/**"]`) |
1290
+
1291
+ **Example configuration** to exempt a modules directory:
1292
+
1293
+ ```json
1294
+ "DW-002": { "enabled": true, "options": { "exemptPaths": ["**/modules/**", "**/lib/**"] } }
1295
+ ```
1296
+
1012
1297
  ---
1013
1298
 
1014
1299
  ### DW-003: DWL Modules
@@ -1056,6 +1341,18 @@ error.errorType.namespace ++ ":" ++ error.errorType.identifier
1056
1341
 
1057
1342
  ---
1058
1343
 
1344
+ ### DW-005: Duplicate Transform Logic
1345
+
1346
+ | Property | Value |
1347
+ | ------------ | --------- |
1348
+ | **Severity** | Warning |
1349
+ | **Category** | DataWeave |
1350
+ | **Fixable** | No |
1351
+
1352
+ **Description:** Detects duplicated DataWeave transform expressions within a single file. If the same `ee:set-payload` or `ee:set-variable` CDATA content appears multiple times, this suggests extracting it into a reusable `.dwl` module.
1353
+
1354
+ ---
1355
+
1059
1356
  ## API-Led Rules
1060
1357
 
1061
1358
  > **Best Practice**: Follow API-Led Connectivity architecture with clear layer separation:
@@ -1116,6 +1413,80 @@ error.errorType.namespace ++ ":" ++ error.errorType.identifier
1116
1413
 
1117
1414
  ---
1118
1415
 
1416
+ ### API-006: APIKit Main Flow Structure
1417
+
1418
+ | Property | Value |
1419
+ | ------------ | ------- |
1420
+ | **Severity** | Warning |
1421
+ | **Category** | API-Led |
1422
+ | **Fixable** | No |
1423
+
1424
+ **Description:** APIKit main flow (the flow containing the `apikit:router`) should follow the standard structure: HTTP listener followed by APIKit router, with an error handler referencing the APIKit error handler.
1425
+
1426
+ ---
1427
+
1428
+ ### API-007: APIKit Status Code Variable
1429
+
1430
+ | Property | Value |
1431
+ | ------------ | ------- |
1432
+ | **Severity** | Warning |
1433
+ | **Category** | API-Led |
1434
+ | **Fixable** | No |
1435
+
1436
+ **Description:** APIKit route implementation flows (e.g., `get:\resource:api-config`) should set an `httpStatus` variable to ensure correct HTTP response codes are returned.
1437
+
1438
+ ---
1439
+
1440
+ ### API-008: APIKit Console in Production
1441
+
1442
+ | Property | Value |
1443
+ | ------------ | ------- |
1444
+ | **Severity** | Warning |
1445
+ | **Category** | API-Led |
1446
+ | **Fixable** | No |
1447
+
1448
+ **Description:** The APIKit console endpoint (`apikit:console`) should be disabled or removed in production configurations. Exposing the console in production is a security risk.
1449
+
1450
+ ---
1451
+
1452
+ ## Connector Rules
1453
+
1454
+ ### SF-001: Salesforce Replay Channel Config
1455
+
1456
+ | Property | Value |
1457
+ | ------------ | --------- |
1458
+ | **Severity** | Warning |
1459
+ | **Category** | Connector |
1460
+ | **Fixable** | No |
1461
+
1462
+ **Description:** Salesforce Streaming and Platform Event subscriptions should configure a replay channel with proper `replayOption` and `resumeOffset` settings to avoid missing events after restarts.
1463
+
1464
+ ---
1465
+
1466
+ ### SF-002: Event Listener Null Guard
1467
+
1468
+ | Property | Value |
1469
+ | ------------ | --------- |
1470
+ | **Severity** | Warning |
1471
+ | **Category** | Connector |
1472
+ | **Fixable** | No |
1473
+
1474
+ **Description:** Event-driven listeners (Salesforce CDC, JMS, Anypoint MQ, etc.) should guard against null payloads. A null check or validation step should occur early in the flow to prevent `NullPointerException` in downstream processing.
1475
+
1476
+ ---
1477
+
1478
+ ### HTTP-004: Connection Idle Timeout
1479
+
1480
+ | Property | Value |
1481
+ | ------------ | ------- |
1482
+ | **Severity** | Warning |
1483
+ | **Category** | HTTP |
1484
+ | **Fixable** | No |
1485
+
1486
+ **Description:** HTTP request configurations should set `connectionIdleTimeout` to release idle connections and prevent resource exhaustion under load.
1487
+
1488
+ ---
1489
+
1119
1490
  ## Operations & Hygiene Rules
1120
1491
 
1121
1492
  ### HYG-002: Commented Code Detection
@@ -1142,14 +1513,45 @@ error.errorType.namespace ++ ":" ++ error.errorType.identifier
1142
1513
  | **Category** | Standards |
1143
1514
  | **Fixable** | No |
1144
1515
 
1145
- **Description:** Detects flows and sub-flows that are never referenced by `flow-ref` within the same file.
1516
+ **Description:** Detects flows and sub-flows that are never referenced by `flow-ref` across the entire project.
1146
1517
 
1147
1518
  **Check Logic:**
1148
1519
 
1149
- - **Sub-flows**: Always expected to be referenced; flagged if no `flow-ref` points to them.
1520
+ - **Cross-file detection**: The engine pre-scans all XML files to collect every `<flow-ref name="...">` target before running rules. A sub-flow or flow is only flagged if it is not referenced in _any_ file in the project.
1521
+ - **Sub-flows**: Always expected to be referenced; flagged if no `flow-ref` points to them anywhere in the project.
1150
1522
  - **Flows without triggers**: Flows that have no HTTP listener, scheduler, or VM listener and aren't referenced are flagged.
1151
1523
  - **Exclusions**: Flows matching common external patterns (`-main`, `-api`, `api-`, `-console`, `-error-handler`, `global`) are excluded.
1152
1524
 
1525
+ > **Note (v1.21):** The rule now also recognizes APIKit-generated flows (e.g., `get:\resource:api-config`) and flows with external triggers (Salesforce CDC, JMS, AMQP, VM, Anypoint MQ, Kafka, and 14+ connector patterns).
1526
+
1527
+ ---
1528
+
1529
+ ### HYG-004: Flow-Ref Target Exists
1530
+
1531
+ | Property | Value |
1532
+ | ------------ | --------- |
1533
+ | **Severity** | Error |
1534
+ | **Category** | Standards |
1535
+ | **Fixable** | No |
1536
+
1537
+ **Description:** Every `<flow-ref name="...">` must point to an existing flow or sub-flow in the project. This rule uses cross-file validation via the `allFlowNames` set populated during the engine's pre-scan phase.
1538
+
1539
+ **Why This Matters:** Broken flow references cause runtime errors. Catching them during static analysis prevents deployment failures.
1540
+
1541
+ ---
1542
+
1543
+ ### HYG-005: Unused Variable Detection
1544
+
1545
+ | Property | Value |
1546
+ | ------------ | --------- |
1547
+ | **Severity** | Warning |
1548
+ | **Category** | Standards |
1549
+ | **Fixable** | No |
1550
+
1551
+ **Description:** Detects `set-variable` values that are never referenced elsewhere in the project (via `vars.variableName`, `#[vars.variableName]`, or `variableName` in DataWeave expressions).
1552
+
1553
+ **Best Practice:** Remove unused variables to reduce clutter and improve maintainability.
1554
+
1153
1555
  ---
1154
1556
 
1155
1557
  ## Governance Rules
@@ -1228,11 +1630,11 @@ error.errorType.namespace ++ ":" ++ error.errorType.identifier
1228
1630
 
1229
1631
  ## Rule Priority Matrix
1230
1632
 
1231
- | Severity | Count | Rules |
1232
- | -------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1233
- | Error | 10 | MULE-001, 003, 004, 201, 202, SEC-002, SEC-006, LOG-004, DW-004, YAML-004, PROJ-001 |
1234
- | Warning | 25 | MULE-002, 005, 006, 007, 008, 009, 101, 102, 301, 303, 401, 402, 403, 502, 503, 604, 701, 801, 802, 803, 804, SEC-003, SEC-004, PERF-002, RES-001, OPS-002, OPS-003, HYG-001, HYG-003, API-004, PROJ-002 |
1235
- | Info | 21 | MULE-010, 501, 601, YAML-001, 003, DW-001, 002, 003, API-001, 002, 003, 005, EXP-001, 002, 003, ERR-001, LOG-001, OPS-001, DOC-001, HYG-002 |
1633
+ | Severity | Count | Rules |
1634
+ | -------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
1635
+ | Error | 14 | MULE-001, 003, 004, 201, 202, SEC-002, SEC-006, SEC-007, SEC-008, SEC-009, LOG-004, DW-004, YAML-004, ERR-004, HYG-004, PROJ-001 |
1636
+ | Warning | 37 | MULE-002, 005, 006, 007, 008, 009, 101, 102, 301, 303, 401, 402, 403, 502, 503, 604, 701, 801, 802, 803, 804, SEC-003, SEC-004, SEC-010, PERF-002, RES-001, RES-002, OPS-002, OPS-003, HYG-001, HYG-003, HYG-005, API-004, API-006, API-007, API-008, ERR-002, ERR-003, SF-001, SF-002, HTTP-004, CFG-002, DW-005, PROJ-002 |
1637
+ | Info | 27 | MULE-010, 501, 601, YAML-001, 003, DW-001, 002, 003, API-001, 002, 003, 005, EXP-001, 002, 003, ERR-001, LOG-001, OPS-001, DOC-001, HYG-002, CFG-001, STD-001 |
1236
1638
 
1237
1639
  ---
1238
1640