@sfdxy/mule-lint 1.19.0 → 1.20.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +65 -56
- package/dist/package.json +1 -1
- package/dist/src/engine/LintEngine.d.ts +10 -0
- package/dist/src/engine/LintEngine.d.ts.map +1 -1
- package/dist/src/engine/LintEngine.js +68 -4
- package/dist/src/engine/LintEngine.js.map +1 -1
- package/dist/src/rules/dataweave/DataWeaveRules.d.ts +6 -0
- package/dist/src/rules/dataweave/DataWeaveRules.d.ts.map +1 -1
- package/dist/src/rules/dataweave/DataWeaveRules.js +16 -0
- package/dist/src/rules/dataweave/DataWeaveRules.js.map +1 -1
- package/dist/src/rules/error-handling/CorrelationIdRule.d.ts +22 -1
- package/dist/src/rules/error-handling/CorrelationIdRule.d.ts.map +1 -1
- package/dist/src/rules/error-handling/CorrelationIdRule.js +107 -6
- package/dist/src/rules/error-handling/CorrelationIdRule.js.map +1 -1
- package/dist/src/rules/error-handling/GlobalErrorHandlerRule.d.ts +14 -2
- package/dist/src/rules/error-handling/GlobalErrorHandlerRule.d.ts.map +1 -1
- package/dist/src/rules/error-handling/GlobalErrorHandlerRule.js +40 -18
- package/dist/src/rules/error-handling/GlobalErrorHandlerRule.js.map +1 -1
- package/dist/src/rules/error-handling/HttpStatusRule.d.ts +5 -0
- package/dist/src/rules/error-handling/HttpStatusRule.d.ts.map +1 -1
- package/dist/src/rules/error-handling/HttpStatusRule.js +15 -0
- package/dist/src/rules/error-handling/HttpStatusRule.js.map +1 -1
- package/dist/src/rules/http/HttpContentTypeRule.d.ts +28 -1
- package/dist/src/rules/http/HttpContentTypeRule.d.ts.map +1 -1
- package/dist/src/rules/http/HttpContentTypeRule.js +68 -7
- package/dist/src/rules/http/HttpContentTypeRule.js.map +1 -1
- package/dist/src/rules/operations/UnusedFlowRule.d.ts +6 -1
- package/dist/src/rules/operations/UnusedFlowRule.d.ts.map +1 -1
- package/dist/src/rules/operations/UnusedFlowRule.js +23 -9
- package/dist/src/rules/operations/UnusedFlowRule.js.map +1 -1
- package/dist/src/rules/performance/ConnectionPoolingRule.d.ts +5 -0
- package/dist/src/rules/performance/ConnectionPoolingRule.d.ts.map +1 -1
- package/dist/src/rules/performance/ConnectionPoolingRule.js +18 -5
- package/dist/src/rules/performance/ConnectionPoolingRule.js.map +1 -1
- package/dist/src/rules/performance/ReconnectionStrategyRule.d.ts +7 -0
- package/dist/src/rules/performance/ReconnectionStrategyRule.d.ts.map +1 -1
- package/dist/src/rules/performance/ReconnectionStrategyRule.js +15 -2
- package/dist/src/rules/performance/ReconnectionStrategyRule.js.map +1 -1
- package/dist/src/rules/structure/StructureRules.d.ts +8 -1
- package/dist/src/rules/structure/StructureRules.d.ts.map +1 -1
- package/dist/src/rules/structure/StructureRules.js +11 -7
- package/dist/src/rules/structure/StructureRules.js.map +1 -1
- package/dist/src/types/Rule.d.ts +22 -0
- package/dist/src/types/Rule.d.ts.map +1 -1
- package/docs/best-practices/rules-catalog.md +107 -13
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConnectionPoolingRule.d.ts","sourceRoot":"","sources":["../../../../src/rules/performance/ConnectionPoolingRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C
|
|
1
|
+
{"version":3,"file":"ConnectionPoolingRule.d.ts","sourceRoot":"","sources":["../../../../src/rules/performance/ConnectionPoolingRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;;;;;;;;;GAUG;AACH,qBAAa,qBAAsB,SAAQ,QAAQ;IACjD,EAAE,SAAc;IAChB,IAAI,SAAwB;IAC5B,WAAW,SAA0D;IACrE,QAAQ,EAAG,SAAS,CAAU;IAC9B,QAAQ,EAAG,aAAa,CAAU;IAElC,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,KAAK,EAAE;CA2E9D"}
|
|
@@ -7,6 +7,11 @@ const BaseRule_1 = require("../base/BaseRule");
|
|
|
7
7
|
*
|
|
8
8
|
* DB and HTTP connectors should configure connection pools
|
|
9
9
|
* for optimal performance and resource management.
|
|
10
|
+
*
|
|
11
|
+
* Per the Mule HTTP connector XSD, `maxConnections` and `connectionIdleTimeout`
|
|
12
|
+
* are valid on BOTH `<http:request-config>` (older style) and on the nested
|
|
13
|
+
* `<http:request-connection>` child element (current XSD-correct placement).
|
|
14
|
+
* The rule must accept either location to avoid false positives.
|
|
10
15
|
*/
|
|
11
16
|
class ConnectionPoolingRule extends BaseRule_1.BaseRule {
|
|
12
17
|
id = 'PERF-002';
|
|
@@ -21,13 +26,21 @@ class ConnectionPoolingRule extends BaseRule_1.BaseRule {
|
|
|
21
26
|
for (const config of httpConfigs) {
|
|
22
27
|
const element = config;
|
|
23
28
|
const name = element.getAttribute('name') ?? 'unnamed';
|
|
24
|
-
// Check for connection pooling attributes
|
|
25
|
-
const
|
|
26
|
-
|
|
27
|
-
|
|
29
|
+
// Check for connection pooling attributes on the request-config element itself
|
|
30
|
+
const hasPoolingOnConfig = element.hasAttribute('maxConnections') || element.hasAttribute('connectionIdleTimeout');
|
|
31
|
+
// Also check the nested http:request-connection child element (XSD-correct placement).
|
|
32
|
+
// Per the Mule HTTP connector XSD, maxConnections and connectionIdleTimeout belong on
|
|
33
|
+
// http:request-connection, not http:request-config. Both placements must be accepted.
|
|
34
|
+
const connectionChild = this.selectFirst('.//*[local-name()="request-connection"]', config);
|
|
35
|
+
const hasPoolingOnConnection = connectionChild !== null &&
|
|
36
|
+
(connectionChild.hasAttribute('maxConnections') ||
|
|
37
|
+
connectionChild.hasAttribute('connectionIdleTimeout'));
|
|
38
|
+
// Also accept a pooling-profile child (db-style config)
|
|
39
|
+
const hasPoolingProfile = this.select('.//*[local-name()="pooling-profile"]', config).length > 0;
|
|
40
|
+
const hasPooling = hasPoolingOnConfig || hasPoolingOnConnection || hasPoolingProfile;
|
|
28
41
|
if (!hasPooling) {
|
|
29
42
|
issues.push(this.createIssue(config, `HTTP request config "${name}" has no connection pooling configured`, {
|
|
30
|
-
suggestion: 'Add maxConnections and connectionIdleTimeout for optimal connection management',
|
|
43
|
+
suggestion: 'Add maxConnections and connectionIdleTimeout on <http:request-connection> for optimal connection management',
|
|
31
44
|
}));
|
|
32
45
|
}
|
|
33
46
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConnectionPoolingRule.js","sourceRoot":"","sources":["../../../../src/rules/performance/ConnectionPoolingRule.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAE5C
|
|
1
|
+
{"version":3,"file":"ConnectionPoolingRule.js","sourceRoot":"","sources":["../../../../src/rules/performance/ConnectionPoolingRule.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAE5C;;;;;;;;;;GAUG;AACH,MAAa,qBAAsB,SAAQ,mBAAQ;IACjD,EAAE,GAAG,UAAU,CAAC;IAChB,IAAI,GAAG,oBAAoB,CAAC;IAC5B,WAAW,GAAG,sDAAsD,CAAC;IACrE,QAAQ,GAAG,SAAkB,CAAC;IAC9B,QAAQ,GAAG,aAAsB,CAAC;IAElC,QAAQ,CAAC,GAAa,EAAE,QAA2B;QACjD,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,oCAAoC;QACpC,MAAM,WAAW,GAAG,IAAI,CAAC,MAAM,CAC7B,mGAAmG,EACnG,GAAG,CACJ,CAAC;QAEF,KAAK,MAAM,MAAM,IAAI,WAAW,EAAE,CAAC;YACjC,MAAM,OAAO,GAAG,MAAiB,CAAC;YAClC,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC;YAEvD,+EAA+E;YAC/E,MAAM,kBAAkB,GACtB,OAAO,CAAC,YAAY,CAAC,gBAAgB,CAAC,IAAI,OAAO,CAAC,YAAY,CAAC,uBAAuB,CAAC,CAAC;YAE1F,uFAAuF;YACvF,sFAAsF;YACtF,sFAAsF;YACtF,MAAM,eAAe,GAAG,IAAI,CAAC,WAAW,CAAC,yCAAyC,EAAE,MAAM,CAAC,CAAC;YAC5F,MAAM,sBAAsB,GAC1B,eAAe,KAAK,IAAI;gBACxB,CAAE,eAA2B,CAAC,YAAY,CAAC,gBAAgB,CAAC;oBACzD,eAA2B,CAAC,YAAY,CAAC,uBAAuB,CAAC,CAAC,CAAC;YAExE,wDAAwD;YACxD,MAAM,iBAAiB,GACrB,IAAI,CAAC,MAAM,CAAC,sCAAsC,EAAE,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAEzE,MAAM,UAAU,GAAG,kBAAkB,IAAI,sBAAsB,IAAI,iBAAiB,CAAC;YAErF,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,CACT,IAAI,CAAC,WAAW,CACd,MAAM,EACN,wBAAwB,IAAI,wCAAwC,EACpE;oBACE,UAAU,EACR,6GAA6G;iBAChH,CACF,CACF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,gCAAgC;QAChC,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAC3B,yFAAyF,EACzF,GAAG,CACJ,CAAC;QAEF,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;YAC/B,MAAM,OAAO,GAAG,MAAiB,CAAC;YAClC,MAAM,IAAI,GAAG,OAAO,CAAC,YAAY,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC;YAEvD,4BAA4B;YAC5B,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,CAAC,sCAAsC,EAAE,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YAE1F,IAAI,CAAC,UAAU,EAAE,CAAC;gBAChB,MAAM,CAAC,IAAI,CACT,IAAI,CAAC,WAAW,CACd,MAAM,EACN,oBAAoB,IAAI,wCAAwC,EAChE;oBACE,UAAU,EACR,iFAAiF;iBACpF,CACF,CACF,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAlFD,sDAkFC"}
|
|
@@ -4,6 +4,13 @@ import { BaseRule } from '../base/BaseRule';
|
|
|
4
4
|
* RES-001: Reconnection Strategy
|
|
5
5
|
*
|
|
6
6
|
* Connectors should have reconnection strategies configured for resilience.
|
|
7
|
+
*
|
|
8
|
+
* Per the Mule HTTP connector XSD, `<reconnection>` is a child element of
|
|
9
|
+
* `<http:request-connection>`, NOT a direct child of `<http:request-config>`.
|
|
10
|
+
* Placing `<reconnection>` directly under `<http:request-config>` causes a
|
|
11
|
+
* SAXParseException at build time. The rule uses a descendant search (`.//*`)
|
|
12
|
+
* to correctly resolve reconnection elements at any depth, including the valid
|
|
13
|
+
* `http:request-config > http:request-connection > reconnection` nesting.
|
|
7
14
|
*/
|
|
8
15
|
export declare class ReconnectionStrategyRule extends BaseRule {
|
|
9
16
|
id: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReconnectionStrategyRule.d.ts","sourceRoot":"","sources":["../../../../src/rules/performance/ReconnectionStrategyRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C
|
|
1
|
+
{"version":3,"file":"ReconnectionStrategyRule.d.ts","sourceRoot":"","sources":["../../../../src/rules/performance/ReconnectionStrategyRule.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;;;;;;;;;;GAWG;AACH,qBAAa,wBAAyB,SAAQ,QAAQ;IACpD,EAAE,SAAa;IACf,IAAI,SAA2B;IAC/B,WAAW,SAA+D;IAC1E,QAAQ,EAAG,SAAS,CAAU;IAC9B,QAAQ,EAAG,aAAa,CAAU;IAElC,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,QAAQ,EAAE,iBAAiB,GAAG,KAAK,EAAE;CAkE9D"}
|
|
@@ -6,6 +6,13 @@ const BaseRule_1 = require("../base/BaseRule");
|
|
|
6
6
|
* RES-001: Reconnection Strategy
|
|
7
7
|
*
|
|
8
8
|
* Connectors should have reconnection strategies configured for resilience.
|
|
9
|
+
*
|
|
10
|
+
* Per the Mule HTTP connector XSD, `<reconnection>` is a child element of
|
|
11
|
+
* `<http:request-connection>`, NOT a direct child of `<http:request-config>`.
|
|
12
|
+
* Placing `<reconnection>` directly under `<http:request-config>` causes a
|
|
13
|
+
* SAXParseException at build time. The rule uses a descendant search (`.//*`)
|
|
14
|
+
* to correctly resolve reconnection elements at any depth, including the valid
|
|
15
|
+
* `http:request-config > http:request-connection > reconnection` nesting.
|
|
9
16
|
*/
|
|
10
17
|
class ReconnectionStrategyRule extends BaseRule_1.BaseRule {
|
|
11
18
|
id = 'RES-001';
|
|
@@ -29,14 +36,20 @@ class ReconnectionStrategyRule extends BaseRule_1.BaseRule {
|
|
|
29
36
|
for (const connector of connectorConfigs) {
|
|
30
37
|
const configs = this.select(`//*[local-name()="${connector.pattern}"]`, doc);
|
|
31
38
|
for (const config of configs) {
|
|
32
|
-
//
|
|
39
|
+
// Use descendant search (.//*) so that reconnection elements nested anywhere
|
|
40
|
+
// inside the config element are detected. This handles the XSD-correct pattern:
|
|
41
|
+
// <http:request-config>
|
|
42
|
+
// <http:request-connection>
|
|
43
|
+
// <reconnection>...</reconnection> ← correct per HTTP connector XSD
|
|
44
|
+
// </http:request-connection>
|
|
45
|
+
// </http:request-config>
|
|
33
46
|
const hasReconnection = this.exists('.//*[local-name()="reconnection"]', config) ||
|
|
34
47
|
this.exists('.//*[local-name()="reconnect"]', config) ||
|
|
35
48
|
this.exists('.//*[local-name()="reconnect-forever"]', config);
|
|
36
49
|
if (!hasReconnection) {
|
|
37
50
|
const name = this.getNameAttribute(config) ?? connector.name;
|
|
38
51
|
issues.push(this.createIssue(config, `${connector.name} config "${name}" has no reconnection strategy`, {
|
|
39
|
-
suggestion: 'Add <reconnection>
|
|
52
|
+
suggestion: 'Add <reconnection><reconnect count="3" frequency="2000"/></reconnection> inside <http:request-connection> for HTTP connectors',
|
|
40
53
|
}));
|
|
41
54
|
}
|
|
42
55
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ReconnectionStrategyRule.js","sourceRoot":"","sources":["../../../../src/rules/performance/ReconnectionStrategyRule.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAE5C
|
|
1
|
+
{"version":3,"file":"ReconnectionStrategyRule.js","sourceRoot":"","sources":["../../../../src/rules/performance/ReconnectionStrategyRule.ts"],"names":[],"mappings":";;;AACA,+CAA4C;AAE5C;;;;;;;;;;;GAWG;AACH,MAAa,wBAAyB,SAAQ,mBAAQ;IACpD,EAAE,GAAG,SAAS,CAAC;IACf,IAAI,GAAG,uBAAuB,CAAC;IAC/B,WAAW,GAAG,2DAA2D,CAAC;IAC1E,QAAQ,GAAG,SAAkB,CAAC;IAC9B,QAAQ,GAAG,aAAsB,CAAC;IAElC,QAAQ,CAAC,GAAa,EAAE,QAA2B;QACjD,MAAM,MAAM,GAAY,EAAE,CAAC;QAE3B,8EAA8E;QAC9E,qFAAqF;QACrF,MAAM,gBAAgB,GAAG;YACvB,EAAE,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,cAAc,EAAE;YACnD,EAAE,OAAO,EAAE,iBAAiB,EAAE,IAAI,EAAE,eAAe,EAAE;YACrD,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE;YACtC,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE;YACxC,EAAE,OAAO,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE;YACxC,EAAE,OAAO,EAAE,YAAY,EAAE,IAAI,EAAE,KAAK,EAAE;YACtC,EAAE,OAAO,EAAE,WAAW,EAAE,IAAI,EAAE,IAAI,EAAE;SACrC,CAAC;QAEF,KAAK,MAAM,SAAS,IAAI,gBAAgB,EAAE,CAAC;YACzC,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,qBAAqB,SAAS,CAAC,OAAO,IAAI,EAAE,GAAG,CAAC,CAAC;YAE7E,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;gBAC7B,6EAA6E;gBAC7E,gFAAgF;gBAChF,0BAA0B;gBAC1B,gCAAgC;gBAChC,4EAA4E;gBAC5E,iCAAiC;gBACjC,2BAA2B;gBAC3B,MAAM,eAAe,GACnB,IAAI,CAAC,MAAM,CAAC,mCAAmC,EAAE,MAAM,CAAC;oBACxD,IAAI,CAAC,MAAM,CAAC,gCAAgC,EAAE,MAAM,CAAC;oBACrD,IAAI,CAAC,MAAM,CAAC,wCAAwC,EAAE,MAAM,CAAC,CAAC;gBAEhE,IAAI,CAAC,eAAe,EAAE,CAAC;oBACrB,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,SAAS,CAAC,IAAI,CAAC;oBAC7D,MAAM,CAAC,IAAI,CACT,IAAI,CAAC,WAAW,CACd,MAAM,EACN,GAAG,SAAS,CAAC,IAAI,YAAY,IAAI,gCAAgC,EACjE;wBACE,UAAU,EACR,+HAA+H;qBAClI,CACF,CACF,CAAC;gBACJ,CAAC;YACH,CAAC;QACH,CAAC;QAED,yDAAyD;QACzD,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,2DAA2D,EAAE,GAAG,CAAC,CAAC;QAChG,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;YAC/B,MAAM,eAAe,GACnB,IAAI,CAAC,MAAM,CAAC,mCAAmC,EAAE,MAAM,CAAC;gBACxD,IAAI,CAAC,MAAM,CAAC,gCAAgC,EAAE,MAAM,CAAC,CAAC;YAExD,IAAI,CAAC,eAAe,EAAE,CAAC;gBACrB,MAAM,IAAI,GAAG,IAAI,CAAC,gBAAgB,CAAC,MAAM,CAAC,IAAI,UAAU,CAAC;gBACzD,MAAM,CAAC,IAAI,CACT,IAAI,CAAC,WAAW,CAAC,MAAM,EAAE,oBAAoB,IAAI,gCAAgC,EAAE;oBACjF,UAAU,EAAE,kDAAkD;iBAC/D,CAAC,CACH,CAAC;YACJ,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AAzED,4DAyEC"}
|
|
@@ -4,6 +4,12 @@ import { BaseRule } from '../base/BaseRule';
|
|
|
4
4
|
* MULE-802: Project Structure Validation
|
|
5
5
|
*
|
|
6
6
|
* Validates standard MuleSoft project folder structure.
|
|
7
|
+
*
|
|
8
|
+
* The recommended directories list is configurable via the rule's `recommendedDirs`
|
|
9
|
+
* option. The default list intentionally excludes `src/main/resources/api` because
|
|
10
|
+
* many modern Mule 4 projects reference their API specification from Anypoint Exchange
|
|
11
|
+
* rather than bundling it locally — requiring that directory would produce false
|
|
12
|
+
* positives on valid projects.
|
|
7
13
|
*/
|
|
8
14
|
export declare class ProjectStructureRule extends BaseRule {
|
|
9
15
|
id: string;
|
|
@@ -12,7 +18,8 @@ export declare class ProjectStructureRule extends BaseRule {
|
|
|
12
18
|
severity: "warning";
|
|
13
19
|
category: "structure";
|
|
14
20
|
private readonly REQUIRED_DIRS;
|
|
15
|
-
|
|
21
|
+
/** Default recommended dirs (api/ excluded — see class JSDoc) */
|
|
22
|
+
private readonly DEFAULT_RECOMMENDED_DIRS;
|
|
16
23
|
validate(_doc: Document, context: ValidationContext): Issue[];
|
|
17
24
|
}
|
|
18
25
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StructureRules.d.ts","sourceRoot":"","sources":["../../../../src/rules/structure/StructureRules.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C
|
|
1
|
+
{"version":3,"file":"StructureRules.d.ts","sourceRoot":"","sources":["../../../../src/rules/structure/StructureRules.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,iBAAiB,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAE5C;;;;;;;;;;GAUG;AACH,qBAAa,oBAAqB,SAAQ,QAAQ;IAChD,EAAE,SAAc;IAChB,IAAI,SAAuB;IAC3B,WAAW,SAAyD;IACpE,QAAQ,EAAG,SAAS,CAAU;IAC9B,QAAQ,EAAG,WAAW,CAAU;IAEhC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAA2C;IAEzE,iEAAiE;IACjE,OAAO,CAAC,QAAQ,CAAC,wBAAwB,CAAgD;IAEzF,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,GAAG,KAAK,EAAE;CAwC9D;AAED;;;;GAIG;AACH,qBAAa,gBAAiB,SAAQ,QAAQ;IAC5C,EAAE,SAAc;IAChB,IAAI,SAAwB;IAC5B,WAAW,SAA+D;IAC1E,QAAQ,EAAG,SAAS,CAAU;IAC9B,QAAQ,EAAG,WAAW,CAAU;IAEhC,QAAQ,CAAC,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,GAAG,KAAK,EAAE;IAuB7D,OAAO,CAAC,gBAAgB;CAQzB;AAED;;;;GAIG;AACH,qBAAa,iBAAkB,SAAQ,QAAQ;IAC7C,EAAE,SAAc;IAChB,IAAI,SAAyB;IAC7B,WAAW,SAAwD;IACnE,QAAQ,EAAG,SAAS,CAAU;IAC9B,QAAQ,EAAG,WAAW,CAAU;IAEhC,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,GAAG,KAAK,EAAE;CAqB7D"}
|
|
@@ -41,6 +41,12 @@ const BaseRule_1 = require("../base/BaseRule");
|
|
|
41
41
|
* MULE-802: Project Structure Validation
|
|
42
42
|
*
|
|
43
43
|
* Validates standard MuleSoft project folder structure.
|
|
44
|
+
*
|
|
45
|
+
* The recommended directories list is configurable via the rule's `recommendedDirs`
|
|
46
|
+
* option. The default list intentionally excludes `src/main/resources/api` because
|
|
47
|
+
* many modern Mule 4 projects reference their API specification from Anypoint Exchange
|
|
48
|
+
* rather than bundling it locally — requiring that directory would produce false
|
|
49
|
+
* positives on valid projects.
|
|
44
50
|
*/
|
|
45
51
|
class ProjectStructureRule extends BaseRule_1.BaseRule {
|
|
46
52
|
id = 'MULE-802';
|
|
@@ -49,11 +55,8 @@ class ProjectStructureRule extends BaseRule_1.BaseRule {
|
|
|
49
55
|
severity = 'warning';
|
|
50
56
|
category = 'structure';
|
|
51
57
|
REQUIRED_DIRS = ['src/main/mule', 'src/main/resources'];
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
'src/main/resources/api',
|
|
55
|
-
'src/test/munit',
|
|
56
|
-
];
|
|
58
|
+
/** Default recommended dirs (api/ excluded — see class JSDoc) */
|
|
59
|
+
DEFAULT_RECOMMENDED_DIRS = ['src/main/resources/dwl', 'src/test/munit'];
|
|
57
60
|
validate(_doc, context) {
|
|
58
61
|
const issues = [];
|
|
59
62
|
const projectRoot = context.projectRoot;
|
|
@@ -70,8 +73,9 @@ class ProjectStructureRule extends BaseRule_1.BaseRule {
|
|
|
70
73
|
});
|
|
71
74
|
}
|
|
72
75
|
}
|
|
73
|
-
// Check recommended directories
|
|
74
|
-
|
|
76
|
+
// Check recommended directories (configurable)
|
|
77
|
+
const recommendedDirs = this.getOption(context, 'recommendedDirs', this.DEFAULT_RECOMMENDED_DIRS);
|
|
78
|
+
for (const dir of recommendedDirs) {
|
|
75
79
|
const fullPath = path.join(projectRoot, dir);
|
|
76
80
|
if (!fs.existsSync(fullPath)) {
|
|
77
81
|
issues.push({
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"StructureRules.js","sourceRoot":"","sources":["../../../../src/rules/structure/StructureRules.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAE7B,+CAA4C;AAE5C
|
|
1
|
+
{"version":3,"file":"StructureRules.js","sourceRoot":"","sources":["../../../../src/rules/structure/StructureRules.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,uCAAyB;AACzB,2CAA6B;AAE7B,+CAA4C;AAE5C;;;;;;;;;;GAUG;AACH,MAAa,oBAAqB,SAAQ,mBAAQ;IAChD,EAAE,GAAG,UAAU,CAAC;IAChB,IAAI,GAAG,mBAAmB,CAAC;IAC3B,WAAW,GAAG,qDAAqD,CAAC;IACpE,QAAQ,GAAG,SAAkB,CAAC;IAC9B,QAAQ,GAAG,WAAoB,CAAC;IAEf,aAAa,GAAG,CAAC,eAAe,EAAE,oBAAoB,CAAC,CAAC;IAEzE,iEAAiE;IAChD,wBAAwB,GAAG,CAAC,wBAAwB,EAAE,gBAAgB,CAAC,CAAC;IAEzF,QAAQ,CAAC,IAAc,EAAE,OAA0B;QACjD,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QAExC,6BAA6B;QAC7B,KAAK,MAAM,GAAG,IAAI,IAAI,CAAC,aAAa,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;YAC7C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,+BAA+B,GAAG,EAAE;oBAC7C,MAAM,EAAE,IAAI,CAAC,EAAE;oBACf,QAAQ,EAAE,OAAO;oBACjB,UAAU,EAAE,8BAA8B,GAAG,EAAE;iBAChD,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,+CAA+C;QAC/C,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CACpC,OAAO,EACP,iBAAiB,EACjB,IAAI,CAAC,wBAAwB,CAC9B,CAAC;QAEF,KAAK,MAAM,GAAG,IAAI,eAAe,EAAE,CAAC;YAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC;YAC7C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;gBAC7B,MAAM,CAAC,IAAI,CAAC;oBACV,IAAI,EAAE,CAAC;oBACP,OAAO,EAAE,kCAAkC,GAAG,EAAE;oBAChD,MAAM,EAAE,IAAI,CAAC,EAAE;oBACf,QAAQ,EAAE,MAAM;oBAChB,UAAU,EAAE,sBAAsB,GAAG,EAAE;iBACxC,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AApDD,oDAoDC;AAED;;;;GAIG;AACH,MAAa,gBAAiB,SAAQ,mBAAQ;IAC5C,EAAE,GAAG,UAAU,CAAC;IAChB,IAAI,GAAG,oBAAoB,CAAC;IAC5B,WAAW,GAAG,2DAA2D,CAAC;IAC1E,QAAQ,GAAG,SAAkB,CAAC;IAC9B,QAAQ,GAAG,WAAoB,CAAC;IAEhC,QAAQ,CAAC,IAAc,EAAE,OAA0B;QACjD,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QAEhE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,OAAO,MAAM,CAAC;QAChB,CAAC;QAED,MAAM,eAAe,GAAG,IAAI,CAAC,gBAAgB,CAAC,OAAO,CAAC,CAAC;QAEvD,IAAI,CAAC,eAAe,EAAE,CAAC;YACrB,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,CAAC;gBACP,OAAO,EAAE,uCAAuC;gBAChD,MAAM,EAAE,IAAI,CAAC,EAAE;gBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,UAAU,EAAE,2DAA2D;aACxE,CAAC,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;IAEO,gBAAgB,CAAC,GAAW;QAClC,IAAI,CAAC;YACH,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;YAClC,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QACrF,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,KAAK,CAAC;QACf,CAAC;IACH,CAAC;CACF;AAtCD,4CAsCC;AAED;;;;GAIG;AACH,MAAa,iBAAkB,SAAQ,mBAAQ;IAC7C,EAAE,GAAG,UAAU,CAAC;IAChB,IAAI,GAAG,qBAAqB,CAAC;IAC7B,WAAW,GAAG,oDAAoD,CAAC;IACnE,QAAQ,GAAG,SAAkB,CAAC;IAC9B,QAAQ,GAAG,WAAoB,CAAC;IAEhC,QAAQ,CAAC,GAAa,EAAE,OAA0B;QAChD,MAAM,MAAM,GAAY,EAAE,CAAC;QAC3B,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,UAAU,EAAE,EAAE,CAAC,CAAC;QAEzD,oDAAoD;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,aAAa,EAAE,GAAG,CAAC,CAAC;QAC9C,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,iBAAiB,EAAE,GAAG,CAAC,CAAC;QACrD,MAAM,UAAU,GAAG,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,MAAM,CAAC;QAElD,IAAI,UAAU,GAAG,QAAQ,EAAE,CAAC;YAC1B,MAAM,CAAC,IAAI,CAAC;gBACV,IAAI,EAAE,CAAC;gBACP,OAAO,EAAE,YAAY,UAAU,uCAAuC;gBACtE,MAAM,EAAE,IAAI,CAAC,EAAE;gBACf,QAAQ,EAAE,IAAI,CAAC,QAAQ;gBACvB,UAAU,EAAE,qDAAqD;aAClE,CAAC,CAAC;QACL,CAAC;QAED,OAAO,MAAM,CAAC;IAChB,CAAC;CACF;AA5BD,8CA4BC"}
|
package/dist/src/types/Rule.d.ts
CHANGED
|
@@ -43,6 +43,16 @@ export interface RuleConfig {
|
|
|
43
43
|
/** Rule-specific options */
|
|
44
44
|
options?: Record<string, unknown>;
|
|
45
45
|
}
|
|
46
|
+
/**
|
|
47
|
+
* Project-level context derived from a pre-scan of all files.
|
|
48
|
+
* Populated by LintEngine before per-file rule execution.
|
|
49
|
+
*/
|
|
50
|
+
export interface ProjectContext {
|
|
51
|
+
/** True if any file in the project contains an http:listener element */
|
|
52
|
+
hasHttpListener: boolean;
|
|
53
|
+
/** True if any file contains an apikit:router or apikit:console element */
|
|
54
|
+
hasApikitRouter: boolean;
|
|
55
|
+
}
|
|
46
56
|
/**
|
|
47
57
|
* Context passed to each rule during validation
|
|
48
58
|
*/
|
|
@@ -55,6 +65,18 @@ export interface ValidationContext {
|
|
|
55
65
|
projectRoot: string;
|
|
56
66
|
/** Configuration for this specific rule */
|
|
57
67
|
config: RuleConfig;
|
|
68
|
+
/**
|
|
69
|
+
* Set of all flow/sub-flow names referenced via <flow-ref> across all
|
|
70
|
+
* project files. Populated during the LintEngine pre-scan phase.
|
|
71
|
+
* When undefined (e.g. standalone file scan), intra-file refs only.
|
|
72
|
+
*/
|
|
73
|
+
allFlowRefs?: Set<string>;
|
|
74
|
+
/**
|
|
75
|
+
* Project-level feature flags derived from a pre-scan of all files.
|
|
76
|
+
* Rules that only apply to HTTP-exposed projects (e.g. MULE-005) should
|
|
77
|
+
* check these flags before reporting issues.
|
|
78
|
+
*/
|
|
79
|
+
projectContext?: ProjectContext;
|
|
58
80
|
}
|
|
59
81
|
/**
|
|
60
82
|
* Interface that all lint rules must implement
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Rule.d.ts","sourceRoot":"","sources":["../../../src/types/Rule.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpD;;GAEG;AACH,MAAM,MAAM,YAAY,GACpB,gBAAgB,GAChB,QAAQ,GACR,UAAU,GACV,SAAS,GACT,MAAM,GACN,aAAa,GACb,eAAe,GACf,WAAW,GACX,YAAY,GACZ,WAAW,GACX,WAAW,GACX,SAAS,GACT,YAAY,GACZ,YAAY,GACZ,cAAc,CAAC;AAEnB;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,KAAK,GAAG,eAAe,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,kCAAkC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,4BAA4B;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,MAAM,EAAE,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"Rule.d.ts","sourceRoot":"","sources":["../../../src/types/Rule.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,MAAM,CAAC;AAEpD;;GAEG;AACH,MAAM,MAAM,YAAY,GACpB,gBAAgB,GAChB,QAAQ,GACR,UAAU,GACV,SAAS,GACT,MAAM,GACN,aAAa,GACb,eAAe,GACf,WAAW,GACX,YAAY,GACZ,WAAW,GACX,WAAW,GACX,SAAS,GACT,YAAY,GACZ,YAAY,GACZ,cAAc,CAAC;AAEnB;;;;;GAKG;AACH,MAAM,MAAM,SAAS,GAAG,YAAY,GAAG,KAAK,GAAG,eAAe,CAAC;AAE/D;;GAEG;AACH,MAAM,WAAW,KAAK;IACpB,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8CAA8C;IAC9C,OAAO,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,MAAM,EAAE,MAAM,CAAC;IACf,4BAA4B;IAC5B,QAAQ,EAAE,QAAQ,CAAC;IACnB,+CAA+C;IAC/C,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,yDAAyD;IACzD,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,kCAAkC;IAClC,OAAO,EAAE,OAAO,CAAC;IACjB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,4BAA4B;IAC5B,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACnC;AAED;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,wEAAwE;IACxE,eAAe,EAAE,OAAO,CAAC;IACzB,2EAA2E;IAC3E,eAAe,EAAE,OAAO,CAAC;CAC1B;AAED;;GAEG;AACH,MAAM,WAAW,iBAAiB;IAChC,gDAAgD;IAChD,QAAQ,EAAE,MAAM,CAAC;IACjB,wCAAwC;IACxC,YAAY,EAAE,MAAM,CAAC;IACrB,wCAAwC;IACxC,WAAW,EAAE,MAAM,CAAC;IACpB,2CAA2C;IAC3C,MAAM,EAAE,UAAU,CAAC;IACnB;;;;OAIG;IACH,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC1B;;;;OAIG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;CACjC;AAED;;GAEG;AACH,MAAM,WAAW,IAAI;IACnB,2CAA2C;IAC3C,EAAE,EAAE,MAAM,CAAC;IACX,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAC;IACpB,6BAA6B;IAC7B,QAAQ,EAAE,QAAQ,CAAC;IACnB,uCAAuC;IACvC,QAAQ,EAAE,YAAY,CAAC;IACvB,gEAAgE;IAChE,SAAS,CAAC,EAAE,SAAS,CAAC;IACtB,oCAAoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;;OAKG;IACH,QAAQ,CAAC,GAAG,EAAE,QAAQ,EAAE,OAAO,EAAE,iBAAiB,GAAG,KAAK,EAAE,CAAC;CAC9D"}
|
|
@@ -75,16 +75,24 @@
|
|
|
75
75
|
|
|
76
76
|
| Property | Value |
|
|
77
77
|
| ------------ | -------------- |
|
|
78
|
-
| **Severity** |
|
|
78
|
+
| **Severity** | Warning |
|
|
79
79
|
| **Category** | Error Handling |
|
|
80
80
|
| **Fixable** | No |
|
|
81
81
|
|
|
82
|
-
**Description:** Every Mule project should have a global error handler file
|
|
82
|
+
**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
83
|
|
|
84
84
|
**Check Logic:**
|
|
85
85
|
|
|
86
|
-
1.
|
|
87
|
-
2.
|
|
86
|
+
1. If the expected file exists (`src/main/mule/global-error-handler.xml`), the rule passes.
|
|
87
|
+
2. Otherwise, checks each flow file for a named `<error-handler name="...">` or `<error-handler ref="...">` element.
|
|
88
|
+
3. If neither is found in a flow file (a file containing `<flow>` or `<sub-flow>` elements), a warning is reported.
|
|
89
|
+
4. Pure configuration files (no flows) are skipped to reduce noise.
|
|
90
|
+
|
|
91
|
+
**Options:**
|
|
92
|
+
|
|
93
|
+
| Option | Default | Description |
|
|
94
|
+
| ---------- | ---------------------------------------- | ------------------------------ |
|
|
95
|
+
| `filePath` | `src/main/mule/global-error-handler.xml` | Relative path to expected file |
|
|
88
96
|
|
|
89
97
|
**Why This Matters:** A global error handler ensures consistent error responses across all flows and reduces code duplication.
|
|
90
98
|
|
|
@@ -118,6 +126,14 @@
|
|
|
118
126
|
|
|
119
127
|
**Description:** Error handlers should set an `httpStatus` variable for proper API responses.
|
|
120
128
|
|
|
129
|
+
**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.
|
|
130
|
+
|
|
131
|
+
**Options:**
|
|
132
|
+
|
|
133
|
+
| Option | Default | Description |
|
|
134
|
+
| -------------- | ------------ | --------------------------- |
|
|
135
|
+
| `variableName` | `httpStatus` | Name of the variable to set |
|
|
136
|
+
|
|
121
137
|
**Best Practice:** Always set httpStatus in error handlers to return appropriate HTTP codes (400, 404, 500, etc.).
|
|
122
138
|
|
|
123
139
|
---
|
|
@@ -132,6 +148,24 @@
|
|
|
132
148
|
|
|
133
149
|
**Description:** Error handlers should reference `correlationId` for traceability across distributed systems.
|
|
134
150
|
|
|
151
|
+
**Check Logic:**
|
|
152
|
+
|
|
153
|
+
1. Checks inline XML text and attributes for correlation ID patterns (`correlationId`, `correlation_id`, `x-correlation-id`, `x-request-id`, etc.)
|
|
154
|
+
2. For `ee:set-payload` elements with a `resource="..."` attribute, reads the referenced `.dwl` file from `src/main/resources/<resourcePath>` and checks its content.
|
|
155
|
+
3. If a resource file is referenced but cannot be read (e.g. not yet generated), downgrades to `info` severity to avoid false positives.
|
|
156
|
+
|
|
157
|
+
**Example (inline):**
|
|
158
|
+
|
|
159
|
+
```xml
|
|
160
|
+
<on-error-continue>
|
|
161
|
+
<ee:transform>
|
|
162
|
+
<ee:set-payload resource="classpath:dwl/error-response.dwl"/>
|
|
163
|
+
</ee:transform>
|
|
164
|
+
</on-error-continue>
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
The DWL file at `src/main/resources/dwl/error-response.dwl` will be checked for `correlationId` usage.
|
|
168
|
+
|
|
135
169
|
---
|
|
136
170
|
|
|
137
171
|
### MULE-009: Generic Error Type
|
|
@@ -197,7 +231,7 @@
|
|
|
197
231
|
| **Category** | Naming |
|
|
198
232
|
| **Fixable** | Yes |
|
|
199
233
|
|
|
200
|
-
**Description:** Flows must end with `-flow` suffix, sub-flows with `-subflow`.
|
|
234
|
+
**Description:** Flows must end with `-flow` suffix, sub-flows with `-subflow`. Both flow and sub-flow naming are enforced by this rule.
|
|
201
235
|
|
|
202
236
|
**Examples:**
|
|
203
237
|
|
|
@@ -211,6 +245,14 @@
|
|
|
211
245
|
<sub-flow name="validateInput">
|
|
212
246
|
```
|
|
213
247
|
|
|
248
|
+
**Options:**
|
|
249
|
+
|
|
250
|
+
| Option | Default | Description |
|
|
251
|
+
| ----------------- | -------------------------------------------------- | ----------------------------------------- |
|
|
252
|
+
| `flowSuffix` | `-flow` | Required suffix for `<flow>` elements |
|
|
253
|
+
| `subflowSuffix` | `-subflow` | Required suffix for `<sub-flow>` elements |
|
|
254
|
+
| `excludePatterns` | `['*-api-main', '*-main', 'get:*', 'post:*', ...]` | Glob patterns to skip |
|
|
255
|
+
|
|
214
256
|
---
|
|
215
257
|
|
|
216
258
|
### MULE-101: Flow Name Casing
|
|
@@ -535,6 +577,16 @@
|
|
|
535
577
|
|
|
536
578
|
**Description:** POST/PUT HTTP requests should include a `Content-Type` header.
|
|
537
579
|
|
|
580
|
+
**Detection Patterns:**
|
|
581
|
+
|
|
582
|
+
| Pattern | Description |
|
|
583
|
+
| ------------------------- | ------------------------------------------------------------------------------------------------- |
|
|
584
|
+
| A — Static header | `<http:header headerName="Content-Type" value="..."/>` inside `<http:headers>` |
|
|
585
|
+
| B — CDATA DataWeave block | `<http:headers><![CDATA[#[output application/java --- {"Content-Type": "..."}]]]></http:headers>` |
|
|
586
|
+
| C — Inline DW expression | `<http:headers value='#[{"Content-Type": "..."}]'/>` |
|
|
587
|
+
|
|
588
|
+
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.
|
|
589
|
+
|
|
538
590
|
---
|
|
539
591
|
|
|
540
592
|
### MULE-403: HTTP Request Timeout
|
|
@@ -603,13 +655,20 @@
|
|
|
603
655
|
|
|
604
656
|
**Description:** DB and HTTP connectors should configure connection pools for optimal performance and resource management.
|
|
605
657
|
|
|
606
|
-
**Check Logic:** Flags HTTP request
|
|
658
|
+
**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
659
|
|
|
608
660
|
**Example:**
|
|
609
661
|
|
|
610
662
|
```xml
|
|
611
|
-
<!-- ✅ Good - HTTP with pooling -->
|
|
612
|
-
<http:request-config name="API_Config"
|
|
663
|
+
<!-- ✅ Good - HTTP with pooling on request-connection (XSD-correct) -->
|
|
664
|
+
<http:request-config name="API_Config">
|
|
665
|
+
<http:request-connection>
|
|
666
|
+
<http:client-socket-properties>
|
|
667
|
+
<http:tcp-client-socket-properties connectionTimeout="30000"/>
|
|
668
|
+
</http:client-socket-properties>
|
|
669
|
+
</http:request-connection>
|
|
670
|
+
</http:request-config>
|
|
671
|
+
<!-- maxConnections on http:request-connection avoids SAXParseException -->
|
|
613
672
|
|
|
614
673
|
<!-- ✅ Good - DB with pooling -->
|
|
615
674
|
<db:config name="Database_Config">
|
|
@@ -883,12 +942,17 @@
|
|
|
883
942
|
- `src/main/mule`
|
|
884
943
|
- `src/main/resources`
|
|
885
944
|
|
|
886
|
-
**Recommended Directories
|
|
945
|
+
**Recommended Directories** (configurable via `recommendedDirs` option):
|
|
887
946
|
|
|
888
947
|
- `src/main/resources/dwl`
|
|
889
|
-
- `src/main/resources/api`
|
|
890
948
|
- `src/test/munit`
|
|
891
949
|
|
|
950
|
+
> **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:
|
|
951
|
+
>
|
|
952
|
+
> ```json
|
|
953
|
+
> "MULE-802": { "enabled": true, "options": { "recommendedDirs": ["src/main/resources/dwl", "src/main/resources/api", "src/test/munit"] } }
|
|
954
|
+
> ```
|
|
955
|
+
|
|
892
956
|
---
|
|
893
957
|
|
|
894
958
|
### MULE-803: Global Config File
|
|
@@ -929,12 +993,26 @@
|
|
|
929
993
|
|
|
930
994
|
**Description:** Environment-specific YAML property files should exist for each environment.
|
|
931
995
|
|
|
932
|
-
**Expected Files
|
|
996
|
+
**Expected Files** (default environments: `dev`, `qa`, `prod`):
|
|
933
997
|
|
|
934
998
|
- `dev.yaml` or `config-dev.yaml`
|
|
935
999
|
- `qa.yaml` or `config-qa.yaml`
|
|
936
1000
|
- `prod.yaml` or `config-prod.yaml`
|
|
937
1001
|
|
|
1002
|
+
Files can also live in `src/main/resources/config/` or `src/main/resources/properties/` subdirectories.
|
|
1003
|
+
|
|
1004
|
+
**Options:**
|
|
1005
|
+
|
|
1006
|
+
| Option | Default | Description |
|
|
1007
|
+
| -------------- | ----------------------- | ---------------------------------- |
|
|
1008
|
+
| `environments` | `["dev", "qa", "prod"]` | List of required environment names |
|
|
1009
|
+
|
|
1010
|
+
**Example configuration** to add `staging` or change defaults:
|
|
1011
|
+
|
|
1012
|
+
```json
|
|
1013
|
+
"YAML-001": { "enabled": true, "options": { "environments": ["dev", "staging", "prod"] } }
|
|
1014
|
+
```
|
|
1015
|
+
|
|
938
1016
|
---
|
|
939
1017
|
|
|
940
1018
|
### YAML-003: Property Naming Convention
|
|
@@ -1009,6 +1087,21 @@ db.password: "![encryptedValue]"
|
|
|
1009
1087
|
|
|
1010
1088
|
**Description:** DataWeave files should use kebab-case naming (`my-transform.dwl`).
|
|
1011
1089
|
|
|
1090
|
+
> **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.
|
|
1091
|
+
|
|
1092
|
+
**Options:**
|
|
1093
|
+
|
|
1094
|
+
| Option | Default | Description |
|
|
1095
|
+
| ------------- | ------------ | ---------------------------------------------------------- |
|
|
1096
|
+
| `convention` | `kebab-case` | Naming convention: `kebab-case`, `camelCase`, or `any` |
|
|
1097
|
+
| `exemptPaths` | `[]` | Glob patterns for paths to skip (e.g. `["**/modules/**"]`) |
|
|
1098
|
+
|
|
1099
|
+
**Example configuration** to exempt a modules directory:
|
|
1100
|
+
|
|
1101
|
+
```json
|
|
1102
|
+
"DW-002": { "enabled": true, "options": { "exemptPaths": ["**/modules/**", "**/lib/**"] } }
|
|
1103
|
+
```
|
|
1104
|
+
|
|
1012
1105
|
---
|
|
1013
1106
|
|
|
1014
1107
|
### DW-003: DWL Modules
|
|
@@ -1142,11 +1235,12 @@ error.errorType.namespace ++ ":" ++ error.errorType.identifier
|
|
|
1142
1235
|
| **Category** | Standards |
|
|
1143
1236
|
| **Fixable** | No |
|
|
1144
1237
|
|
|
1145
|
-
**Description:** Detects flows and sub-flows that are never referenced by `flow-ref`
|
|
1238
|
+
**Description:** Detects flows and sub-flows that are never referenced by `flow-ref` across the entire project.
|
|
1146
1239
|
|
|
1147
1240
|
**Check Logic:**
|
|
1148
1241
|
|
|
1149
|
-
- **
|
|
1242
|
+
- **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.
|
|
1243
|
+
- **Sub-flows**: Always expected to be referenced; flagged if no `flow-ref` points to them anywhere in the project.
|
|
1150
1244
|
- **Flows without triggers**: Flows that have no HTTP listener, scheduler, or VM listener and aren't referenced are flagged.
|
|
1151
1245
|
- **Exclusions**: Flows matching common external patterns (`-main`, `-api`, `api-`, `-console`, `-error-handler`, `global`) are excluded.
|
|
1152
1246
|
|