@sfdxy/mule-lint 1.4.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 +413 -0
- package/dist/bin/mule-lint.d.ts +3 -0
- package/dist/bin/mule-lint.d.ts.map +1 -0
- package/dist/bin/mule-lint.js +123 -0
- package/dist/bin/mule-lint.js.map +1 -0
- package/dist/src/core/ComplexityCalculator.d.ts +42 -0
- package/dist/src/core/ComplexityCalculator.d.ts.map +1 -0
- package/dist/src/core/ComplexityCalculator.js +123 -0
- package/dist/src/core/ComplexityCalculator.js.map +1 -0
- package/dist/src/core/FileScanner.d.ts +58 -0
- package/dist/src/core/FileScanner.d.ts.map +1 -0
- package/dist/src/core/FileScanner.js +161 -0
- package/dist/src/core/FileScanner.js.map +1 -0
- package/dist/src/core/XPathHelper.d.ts +81 -0
- package/dist/src/core/XPathHelper.d.ts.map +1 -0
- package/dist/src/core/XPathHelper.js +229 -0
- package/dist/src/core/XPathHelper.js.map +1 -0
- package/dist/src/core/XmlParser.d.ts +38 -0
- package/dist/src/core/XmlParser.d.ts.map +1 -0
- package/dist/src/core/XmlParser.js +131 -0
- package/dist/src/core/XmlParser.js.map +1 -0
- package/dist/src/core/YamlParser.d.ts +30 -0
- package/dist/src/core/YamlParser.d.ts.map +1 -0
- package/dist/src/core/YamlParser.js +120 -0
- package/dist/src/core/YamlParser.js.map +1 -0
- package/dist/src/core/index.d.ts +4 -0
- package/dist/src/core/index.d.ts.map +1 -0
- package/dist/src/core/index.js +21 -0
- package/dist/src/core/index.js.map +1 -0
- package/dist/src/engine/LintEngine.d.ts +60 -0
- package/dist/src/engine/LintEngine.d.ts.map +1 -0
- package/dist/src/engine/LintEngine.js +271 -0
- package/dist/src/engine/LintEngine.js.map +1 -0
- package/dist/src/engine/index.d.ts +2 -0
- package/dist/src/engine/index.d.ts.map +1 -0
- package/dist/src/engine/index.js +18 -0
- package/dist/src/engine/index.js.map +1 -0
- package/dist/src/formatters/JsonFormatter.d.ts +18 -0
- package/dist/src/formatters/JsonFormatter.d.ts.map +1 -0
- package/dist/src/formatters/JsonFormatter.js +45 -0
- package/dist/src/formatters/JsonFormatter.js.map +1 -0
- package/dist/src/formatters/SarifFormatter.d.ts +8 -0
- package/dist/src/formatters/SarifFormatter.d.ts.map +1 -0
- package/dist/src/formatters/SarifFormatter.js +115 -0
- package/dist/src/formatters/SarifFormatter.js.map +1 -0
- package/dist/src/formatters/TableFormatter.d.ts +10 -0
- package/dist/src/formatters/TableFormatter.d.ts.map +1 -0
- package/dist/src/formatters/TableFormatter.js +100 -0
- package/dist/src/formatters/TableFormatter.js.map +1 -0
- package/dist/src/formatters/index.d.ts +10 -0
- package/dist/src/formatters/index.d.ts.map +1 -0
- package/dist/src/formatters/index.js +42 -0
- package/dist/src/formatters/index.js.map +1 -0
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +28 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/rules/api-led/ApiLedRules.d.ts +42 -0
- package/dist/src/rules/api-led/ApiLedRules.d.ts.map +1 -0
- package/dist/src/rules/api-led/ApiLedRules.js +95 -0
- package/dist/src/rules/api-led/ApiLedRules.js.map +1 -0
- package/dist/src/rules/base/BaseRule.d.ts +89 -0
- package/dist/src/rules/base/BaseRule.d.ts.map +1 -0
- package/dist/src/rules/base/BaseRule.js +137 -0
- package/dist/src/rules/base/BaseRule.js.map +1 -0
- package/dist/src/rules/complexity/FlowComplexityRule.d.ts +18 -0
- package/dist/src/rules/complexity/FlowComplexityRule.d.ts.map +1 -0
- package/dist/src/rules/complexity/FlowComplexityRule.js +58 -0
- package/dist/src/rules/complexity/FlowComplexityRule.js.map +1 -0
- package/dist/src/rules/dataweave/DataWeaveRules.d.ts +45 -0
- package/dist/src/rules/dataweave/DataWeaveRules.d.ts.map +1 -0
- package/dist/src/rules/dataweave/DataWeaveRules.js +168 -0
- package/dist/src/rules/dataweave/DataWeaveRules.js.map +1 -0
- package/dist/src/rules/documentation/FlowDescriptionRule.d.ts +16 -0
- package/dist/src/rules/documentation/FlowDescriptionRule.d.ts.map +1 -0
- package/dist/src/rules/documentation/FlowDescriptionRule.js +33 -0
- package/dist/src/rules/documentation/FlowDescriptionRule.js.map +1 -0
- package/dist/src/rules/documentation/MissingDocNameRule.d.ts +17 -0
- package/dist/src/rules/documentation/MissingDocNameRule.d.ts.map +1 -0
- package/dist/src/rules/documentation/MissingDocNameRule.js +44 -0
- package/dist/src/rules/documentation/MissingDocNameRule.js.map +1 -0
- package/dist/src/rules/error-handling/CorrelationIdRule.d.ts +26 -0
- package/dist/src/rules/error-handling/CorrelationIdRule.d.ts.map +1 -0
- package/dist/src/rules/error-handling/CorrelationIdRule.js +86 -0
- package/dist/src/rules/error-handling/CorrelationIdRule.js.map +1 -0
- package/dist/src/rules/error-handling/GenericErrorRule.d.ts +22 -0
- package/dist/src/rules/error-handling/GenericErrorRule.d.ts.map +1 -0
- package/dist/src/rules/error-handling/GenericErrorRule.js +51 -0
- package/dist/src/rules/error-handling/GenericErrorRule.js.map +1 -0
- package/dist/src/rules/error-handling/GlobalErrorHandlerRule.d.ts +17 -0
- package/dist/src/rules/error-handling/GlobalErrorHandlerRule.d.ts.map +1 -0
- package/dist/src/rules/error-handling/GlobalErrorHandlerRule.js +77 -0
- package/dist/src/rules/error-handling/GlobalErrorHandlerRule.js.map +1 -0
- package/dist/src/rules/error-handling/HttpStatusRule.d.ts +21 -0
- package/dist/src/rules/error-handling/HttpStatusRule.d.ts.map +1 -0
- package/dist/src/rules/error-handling/HttpStatusRule.js +57 -0
- package/dist/src/rules/error-handling/HttpStatusRule.js.map +1 -0
- package/dist/src/rules/error-handling/MissingErrorHandlerRule.d.ts +17 -0
- package/dist/src/rules/error-handling/MissingErrorHandlerRule.d.ts.map +1 -0
- package/dist/src/rules/error-handling/MissingErrorHandlerRule.js +51 -0
- package/dist/src/rules/error-handling/MissingErrorHandlerRule.js.map +1 -0
- package/dist/src/rules/experimental/ExperimentalRules.d.ts +43 -0
- package/dist/src/rules/experimental/ExperimentalRules.d.ts.map +1 -0
- package/dist/src/rules/experimental/ExperimentalRules.js +92 -0
- package/dist/src/rules/experimental/ExperimentalRules.js.map +1 -0
- package/dist/src/rules/http/HttpContentTypeRule.d.ts +17 -0
- package/dist/src/rules/http/HttpContentTypeRule.d.ts.map +1 -0
- package/dist/src/rules/http/HttpContentTypeRule.js +50 -0
- package/dist/src/rules/http/HttpContentTypeRule.js.map +1 -0
- package/dist/src/rules/http/HttpTimeoutRule.d.ts +16 -0
- package/dist/src/rules/http/HttpTimeoutRule.d.ts.map +1 -0
- package/dist/src/rules/http/HttpTimeoutRule.js +33 -0
- package/dist/src/rules/http/HttpTimeoutRule.js.map +1 -0
- package/dist/src/rules/http/HttpUserAgentRule.d.ts +17 -0
- package/dist/src/rules/http/HttpUserAgentRule.d.ts.map +1 -0
- package/dist/src/rules/http/HttpUserAgentRule.js +48 -0
- package/dist/src/rules/http/HttpUserAgentRule.js.map +1 -0
- package/dist/src/rules/index.d.ts +45 -0
- package/dist/src/rules/index.d.ts.map +1 -0
- package/dist/src/rules/index.js +205 -0
- package/dist/src/rules/index.js.map +1 -0
- package/dist/src/rules/logging/LoggerCategoryRule.d.ts +21 -0
- package/dist/src/rules/logging/LoggerCategoryRule.d.ts.map +1 -0
- package/dist/src/rules/logging/LoggerCategoryRule.js +61 -0
- package/dist/src/rules/logging/LoggerCategoryRule.js.map +1 -0
- package/dist/src/rules/logging/LoggerInUntilSuccessfulRule.d.ts +16 -0
- package/dist/src/rules/logging/LoggerInUntilSuccessfulRule.d.ts.map +1 -0
- package/dist/src/rules/logging/LoggerInUntilSuccessfulRule.js +29 -0
- package/dist/src/rules/logging/LoggerInUntilSuccessfulRule.js.map +1 -0
- package/dist/src/rules/logging/LoggerPayloadRule.d.ts +17 -0
- package/dist/src/rules/logging/LoggerPayloadRule.d.ts.map +1 -0
- package/dist/src/rules/logging/LoggerPayloadRule.js +39 -0
- package/dist/src/rules/logging/LoggerPayloadRule.js.map +1 -0
- package/dist/src/rules/naming/FlowCasingRule.d.ts +18 -0
- package/dist/src/rules/naming/FlowCasingRule.d.ts.map +1 -0
- package/dist/src/rules/naming/FlowCasingRule.js +40 -0
- package/dist/src/rules/naming/FlowCasingRule.js.map +1 -0
- package/dist/src/rules/naming/FlowNamingRule.d.ts +17 -0
- package/dist/src/rules/naming/FlowNamingRule.d.ts.map +1 -0
- package/dist/src/rules/naming/FlowNamingRule.js +60 -0
- package/dist/src/rules/naming/FlowNamingRule.js.map +1 -0
- package/dist/src/rules/naming/VariableNamingRule.d.ts +18 -0
- package/dist/src/rules/naming/VariableNamingRule.d.ts.map +1 -0
- package/dist/src/rules/naming/VariableNamingRule.js +39 -0
- package/dist/src/rules/naming/VariableNamingRule.js.map +1 -0
- package/dist/src/rules/performance/AsyncErrorHandlerRule.d.ts +16 -0
- package/dist/src/rules/performance/AsyncErrorHandlerRule.d.ts.map +1 -0
- package/dist/src/rules/performance/AsyncErrorHandlerRule.js +34 -0
- package/dist/src/rules/performance/AsyncErrorHandlerRule.js.map +1 -0
- package/dist/src/rules/performance/LargeChoiceBlockRule.d.ts +16 -0
- package/dist/src/rules/performance/LargeChoiceBlockRule.d.ts.map +1 -0
- package/dist/src/rules/performance/LargeChoiceBlockRule.js +32 -0
- package/dist/src/rules/performance/LargeChoiceBlockRule.js.map +1 -0
- package/dist/src/rules/performance/ScatterGatherRoutesRule.d.ts +16 -0
- package/dist/src/rules/performance/ScatterGatherRoutesRule.d.ts.map +1 -0
- package/dist/src/rules/performance/ScatterGatherRoutesRule.js +32 -0
- package/dist/src/rules/performance/ScatterGatherRoutesRule.js.map +1 -0
- package/dist/src/rules/security/HardcodedCredentialsRule.d.ts +19 -0
- package/dist/src/rules/security/HardcodedCredentialsRule.d.ts.map +1 -0
- package/dist/src/rules/security/HardcodedCredentialsRule.js +66 -0
- package/dist/src/rules/security/HardcodedCredentialsRule.js.map +1 -0
- package/dist/src/rules/security/HardcodedHttpRule.d.ts +33 -0
- package/dist/src/rules/security/HardcodedHttpRule.d.ts.map +1 -0
- package/dist/src/rules/security/HardcodedHttpRule.js +108 -0
- package/dist/src/rules/security/HardcodedHttpRule.js.map +1 -0
- package/dist/src/rules/security/InsecureTlsRule.d.ts +16 -0
- package/dist/src/rules/security/InsecureTlsRule.d.ts.map +1 -0
- package/dist/src/rules/security/InsecureTlsRule.js +36 -0
- package/dist/src/rules/security/InsecureTlsRule.js.map +1 -0
- package/dist/src/rules/standards/ChoiceAntiPatternRule.d.ts +17 -0
- package/dist/src/rules/standards/ChoiceAntiPatternRule.d.ts.map +1 -0
- package/dist/src/rules/standards/ChoiceAntiPatternRule.js +43 -0
- package/dist/src/rules/standards/ChoiceAntiPatternRule.js.map +1 -0
- package/dist/src/rules/standards/DeprecatedComponentRule.d.ts +17 -0
- package/dist/src/rules/standards/DeprecatedComponentRule.d.ts.map +1 -0
- package/dist/src/rules/standards/DeprecatedComponentRule.js +37 -0
- package/dist/src/rules/standards/DeprecatedComponentRule.js.map +1 -0
- package/dist/src/rules/standards/DwlStandardsRule.d.ts +22 -0
- package/dist/src/rules/standards/DwlStandardsRule.d.ts.map +1 -0
- package/dist/src/rules/standards/DwlStandardsRule.js +90 -0
- package/dist/src/rules/standards/DwlStandardsRule.js.map +1 -0
- package/dist/src/rules/structure/StructureRules.d.ts +45 -0
- package/dist/src/rules/structure/StructureRules.d.ts.map +1 -0
- package/dist/src/rules/structure/StructureRules.js +163 -0
- package/dist/src/rules/structure/StructureRules.js.map +1 -0
- package/dist/src/rules/yaml/YamlRules.d.ts +46 -0
- package/dist/src/rules/yaml/YamlRules.d.ts.map +1 -0
- package/dist/src/rules/yaml/YamlRules.js +226 -0
- package/dist/src/rules/yaml/YamlRules.js.map +1 -0
- package/dist/src/types/Config.d.ts +50 -0
- package/dist/src/types/Config.d.ts.map +1 -0
- package/dist/src/types/Config.js +18 -0
- package/dist/src/types/Config.js.map +1 -0
- package/dist/src/types/Report.d.ts +47 -0
- package/dist/src/types/Report.d.ts.map +1 -0
- package/dist/src/types/Report.js +3 -0
- package/dist/src/types/Report.js.map +1 -0
- package/dist/src/types/Rule.d.ts +76 -0
- package/dist/src/types/Rule.d.ts.map +1 -0
- package/dist/src/types/Rule.js +3 -0
- package/dist/src/types/Rule.js.map +1 -0
- package/dist/src/types/index.d.ts +4 -0
- package/dist/src/types/index.d.ts.map +1 -0
- package/dist/src/types/index.js +21 -0
- package/dist/src/types/index.js.map +1 -0
- package/package.json +70 -0
package/README.md
ADDED
|
@@ -0,0 +1,413 @@
|
|
|
1
|
+
# Mule-Lint
|
|
2
|
+
|
|
3
|
+
<p align="center">
|
|
4
|
+
<strong>Enterprise-grade static analysis tool for MuleSoft applications</strong>
|
|
5
|
+
</p>
|
|
6
|
+
|
|
7
|
+
<p align="center">
|
|
8
|
+
<a href="#installation">Installation</a> •
|
|
9
|
+
<a href="#quick-start">Quick Start</a> •
|
|
10
|
+
<a href="#rules">Rules</a> •
|
|
11
|
+
<a href="#output-formats">Output</a> •
|
|
12
|
+
<a href="#configuration">Configuration</a> •
|
|
13
|
+
<a href="#extending">Extending</a>
|
|
14
|
+
</p>
|
|
15
|
+
|
|
16
|
+
---
|
|
17
|
+
|
|
18
|
+
## Overview
|
|
19
|
+
|
|
20
|
+
**Mule-Lint** is a TypeScript-based linting tool designed to enforce best practices and standards for MuleSoft applications. It provides:
|
|
21
|
+
|
|
22
|
+
- ✅ **10+ Built-in Rules** covering error handling, naming conventions, security, and logging
|
|
23
|
+
- ✅ **Multiple Output Formats** - Table (human), JSON (scripts), SARIF (AI agents/VS Code)
|
|
24
|
+
- ✅ **CI/CD Ready** - Exit codes and machine-readable output
|
|
25
|
+
- ✅ **TypeScript** - Fully typed for VS Code extension integration
|
|
26
|
+
- ✅ **Extensible** - Add custom rules for your organization
|
|
27
|
+
|
|
28
|
+
### Architecture
|
|
29
|
+
|
|
30
|
+
```mermaid
|
|
31
|
+
flowchart TB
|
|
32
|
+
subgraph CLI["CLI Layer"]
|
|
33
|
+
A[mule-lint command]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
subgraph Engine["LintEngine"]
|
|
37
|
+
B[FileScanner] --> C[XmlParser]
|
|
38
|
+
C --> D[Rule Executor]
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
subgraph Rules["Rules - Strategy Pattern"]
|
|
42
|
+
D --> E[MULE-001]
|
|
43
|
+
D --> F[MULE-002]
|
|
44
|
+
D --> G[...]
|
|
45
|
+
D --> H[MULE-010]
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
subgraph Output["Formatters"]
|
|
49
|
+
I[Table]
|
|
50
|
+
J[JSON]
|
|
51
|
+
K[SARIF]
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
A --> B
|
|
55
|
+
D --> I
|
|
56
|
+
D --> J
|
|
57
|
+
D --> K
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### Data Flow
|
|
61
|
+
|
|
62
|
+
```mermaid
|
|
63
|
+
flowchart LR
|
|
64
|
+
A["XML Files"] --> B["Parse DOM"]
|
|
65
|
+
B --> C["Execute Rules"]
|
|
66
|
+
C --> D["Collect Issues"]
|
|
67
|
+
D --> E["Format Output"]
|
|
68
|
+
E --> F["Table / JSON / SARIF"]
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
---
|
|
73
|
+
|
|
74
|
+
## Installation
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
# Global installation
|
|
78
|
+
npm install -g mule-lint
|
|
79
|
+
|
|
80
|
+
# Or as a dev dependency
|
|
81
|
+
npm install --save-dev mule-lint
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Quick Start
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Scan a directory
|
|
90
|
+
mule-lint ./src/main/mule
|
|
91
|
+
|
|
92
|
+
# Scan a single file
|
|
93
|
+
mule-lint ./src/main/mule/implementation.xml
|
|
94
|
+
|
|
95
|
+
# Output as JSON
|
|
96
|
+
mule-lint ./src/main/mule -f json
|
|
97
|
+
|
|
98
|
+
# Output as SARIF (for AI agents/VS Code)
|
|
99
|
+
mule-lint ./src/main/mule -f sarif > report.sarif
|
|
100
|
+
|
|
101
|
+
# Write to file
|
|
102
|
+
mule-lint ./src/main/mule -o report.txt
|
|
103
|
+
|
|
104
|
+
# Fail on warnings (for CI/CD)
|
|
105
|
+
mule-lint ./src/main/mule --fail-on-warning
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
### CLI Options
|
|
109
|
+
|
|
110
|
+
| Option | Description |
|
|
111
|
+
|--------|-------------|
|
|
112
|
+
| `-f, --format <type>` | Output format: `table`, `json`, `sarif` (default: `table`) |
|
|
113
|
+
| `-o, --output <file>` | Write output to file instead of stdout |
|
|
114
|
+
| `-c, --config <file>` | Path to configuration file |
|
|
115
|
+
| `-q, --quiet` | Show only errors (suppress warnings and info) |
|
|
116
|
+
| `-e, --experimental` | **Enable experimental rules (opt-in)** |
|
|
117
|
+
| `--fail-on-warning` | Exit with error code if warnings found |
|
|
118
|
+
| `-v, --verbose` | Show verbose output |
|
|
119
|
+
|
|
120
|
+
### Examples
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
# Basic scan
|
|
124
|
+
mule-lint .
|
|
125
|
+
|
|
126
|
+
# Scan with experimental rules
|
|
127
|
+
mule-lint . --experimental
|
|
128
|
+
|
|
129
|
+
# Output SARIF for VS Code
|
|
130
|
+
mule-lint src/main/mule -f sarif -o results.sarif
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
---
|
|
134
|
+
|
|
135
|
+
## Rules
|
|
136
|
+
|
|
137
|
+
### Core Rules (MVP)
|
|
138
|
+
|
|
139
|
+
| ID | Name | Severity | Category | Description |
|
|
140
|
+
|----|------|----------|----------|-------------|
|
|
141
|
+
| MULE-001 | Global Error Handler | Error | Error Handling | Project should have global error handler |
|
|
142
|
+
| MULE-002 | Flow Naming | Warning | Naming | Flows end with `-flow`, sub-flows with `-subflow` |
|
|
143
|
+
| MULE-003 | Missing Error Handler | Error | Error Handling | Flows should have error handlers |
|
|
144
|
+
| MULE-004 | Hardcoded URLs | Error | Security | Use property placeholders for URLs |
|
|
145
|
+
| MULE-005 | HTTP Status Check | Warning | Error Handling | Error handlers should set httpStatus |
|
|
146
|
+
| MULE-006 | Logger Category | Warning | Logging | Loggers should have category attribute |
|
|
147
|
+
| MULE-007 | Correlation ID | Warning | Error Handling | Error handlers should reference correlationId |
|
|
148
|
+
| MULE-008 | Choice Anti-Pattern | Warning | Standards | Avoid raise-error in otherwise |
|
|
149
|
+
| MULE-009 | Generic Error Type | Warning | Error Handling | Avoid catching type="ANY" |
|
|
150
|
+
| MULE-010 | DWL Standards | Info | Standards | Standard DataWeave files should exist |
|
|
151
|
+
|
|
152
|
+
### Extended Rules
|
|
153
|
+
|
|
154
|
+
| ID | Name | Severity | Category | Description |
|
|
155
|
+
|----|------|----------|----------|-------------|
|
|
156
|
+
| MULE-101 | Flow Casing | Warning | Naming | kebab-case for flows |
|
|
157
|
+
| MULE-102 | Variable Naming | Warning | Naming | camelCase for variables |
|
|
158
|
+
| MULE-201 | Hardcoded Credentials | Error | Security | Use `${secure::}` |
|
|
159
|
+
| MULE-202 | Insecure TLS | Error | Security | No insecure="true" |
|
|
160
|
+
| MULE-301 | Logger Payload | Warning | Logging | Don't log entire payload |
|
|
161
|
+
| MULE-303 | Logger in Retry | Warning | Logging | Avoid loggers in until-successful |
|
|
162
|
+
| MULE-401 | HTTP User-Agent | Warning | HTTP | Include User-Agent |
|
|
163
|
+
| MULE-402 | HTTP Content-Type | Warning | HTTP | POST/PUT needs Content-Type |
|
|
164
|
+
| MULE-403 | HTTP Timeout | Warning | HTTP | Set responseTimeout |
|
|
165
|
+
| MULE-501 | Scatter-Gather | Info | Performance | Limit parallel routes |
|
|
166
|
+
| MULE-502 | Async Error | Warning | Performance | Async needs error handling |
|
|
167
|
+
| MULE-503 | Large Choice | Warning | Performance | Max 7 when clauses |
|
|
168
|
+
| MULE-601 | Flow Description | Info | Documentation | Add doc:description |
|
|
169
|
+
| MULE-604 | Missing doc:name | Warning | Documentation | Key components need doc:name |
|
|
170
|
+
| MULE-701 | Deprecated | Warning | Standards | Detect deprecated elements |
|
|
171
|
+
| MULE-801 | Flow Complexity | Warning | Complexity | Cyclomatic complexity threshold |
|
|
172
|
+
| MULE-802 | Project Structure | Warning | Structure | Validate folder structure |
|
|
173
|
+
| MULE-803 | Global Config | Warning | Structure | global.xml should exist |
|
|
174
|
+
| MULE-804 | Monolithic XML | Warning | Structure | Split large XML files |
|
|
175
|
+
|
|
176
|
+
### DataWeave & API-Led Rules
|
|
177
|
+
|
|
178
|
+
| ID | Name | Severity | Category | Description |
|
|
179
|
+
|----|------|----------|----------|-------------|
|
|
180
|
+
| DW-001 | External DWL | Warning | DataWeave | Externalize complex transforms |
|
|
181
|
+
| DW-002 | DWL Naming | Info | DataWeave | kebab-case for .dwl files |
|
|
182
|
+
| DW-003 | DWL Modules | Info | DataWeave | Use common modules |
|
|
183
|
+
| API-001 | Experience Layer | Info | API-Led | Experience API patterns |
|
|
184
|
+
| API-002 | Process Layer | Info | API-Led | Process layer orchestration |
|
|
185
|
+
| API-003 | System Layer | Info | API-Led | System layer connections |
|
|
186
|
+
|
|
187
|
+
### Experimental Rules
|
|
188
|
+
|
|
189
|
+
| ID | Name | Severity | Category | Description |
|
|
190
|
+
|----|------|----------|----------|-------------|
|
|
191
|
+
| EXP-001 | Flow Ref Depth | Info | Experimental | Limit flow-ref chains |
|
|
192
|
+
| EXP-002 | Config Naming | Info | Experimental | Connector config naming |
|
|
193
|
+
| EXP-003 | MUnit Coverage | Info | Experimental | Check for MUnit tests |
|
|
194
|
+
| YAML-001 | Env Files | Warning | Standards | Environment YAML files |
|
|
195
|
+
| YAML-003 | Property Naming | Info | Standards | Property key format |
|
|
196
|
+
| YAML-004 | Plaintext Secrets | Error | Security | Encrypted secrets |
|
|
197
|
+
|
|
198
|
+
**Total: 41 rules** across 13 categories.
|
|
199
|
+
|
|
200
|
+
See [Rules Catalog](docs/rules-catalog.md) for detailed documentation.
|
|
201
|
+
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
---
|
|
205
|
+
|
|
206
|
+
## Output Formats
|
|
207
|
+
|
|
208
|
+
### Table (Default)
|
|
209
|
+
|
|
210
|
+
Human-readable colorized output:
|
|
211
|
+
|
|
212
|
+
```
|
|
213
|
+
Mule-Lint Report
|
|
214
|
+
Scanned 5 files in 123ms
|
|
215
|
+
|
|
216
|
+
src/main/mule/impl.xml
|
|
217
|
+
45:0 error Flow "getOrders" is missing an error handler (MULE-003)
|
|
218
|
+
67:0 warning Logger is missing 'category' attribute (MULE-006)
|
|
219
|
+
|
|
220
|
+
Summary:
|
|
221
|
+
Errors: 1
|
|
222
|
+
Warnings: 1
|
|
223
|
+
Infos: 0
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
### JSON
|
|
227
|
+
|
|
228
|
+
Machine-readable for scripting:
|
|
229
|
+
|
|
230
|
+
```json
|
|
231
|
+
[
|
|
232
|
+
{
|
|
233
|
+
"filePath": "/path/to/impl.xml",
|
|
234
|
+
"line": 45,
|
|
235
|
+
"message": "Flow \"getOrders\" is missing an error handler",
|
|
236
|
+
"ruleId": "MULE-003",
|
|
237
|
+
"severity": "error"
|
|
238
|
+
}
|
|
239
|
+
]
|
|
240
|
+
```
|
|
241
|
+
|
|
242
|
+
### SARIF (For AI Agents)
|
|
243
|
+
|
|
244
|
+
[SARIF 2.1.0](https://sarifweb.azurewebsites.net/) format for VS Code, GitHub, and AI agents:
|
|
245
|
+
|
|
246
|
+
```json
|
|
247
|
+
{
|
|
248
|
+
"$schema": "https://json.schemastore.org/sarif-2.1.0.json",
|
|
249
|
+
"version": "2.1.0",
|
|
250
|
+
"runs": [{
|
|
251
|
+
"tool": {
|
|
252
|
+
"driver": {
|
|
253
|
+
"name": "mule-lint",
|
|
254
|
+
"version": "1.0.0"
|
|
255
|
+
}
|
|
256
|
+
},
|
|
257
|
+
"results": [...]
|
|
258
|
+
}]
|
|
259
|
+
}
|
|
260
|
+
```
|
|
261
|
+
|
|
262
|
+
---
|
|
263
|
+
|
|
264
|
+
## Configuration
|
|
265
|
+
|
|
266
|
+
Create a `.mulelintrc.json` file in your project root:
|
|
267
|
+
|
|
268
|
+
```json
|
|
269
|
+
{
|
|
270
|
+
"rules": {
|
|
271
|
+
"MULE-001": { "enabled": true },
|
|
272
|
+
"MULE-002": {
|
|
273
|
+
"enabled": true,
|
|
274
|
+
"options": {
|
|
275
|
+
"flowSuffix": "-flow",
|
|
276
|
+
"subflowSuffix": "-subflow",
|
|
277
|
+
"excludePatterns": ["*-api-main"]
|
|
278
|
+
}
|
|
279
|
+
},
|
|
280
|
+
"MULE-006": {
|
|
281
|
+
"enabled": true,
|
|
282
|
+
"severity": "error",
|
|
283
|
+
"options": {
|
|
284
|
+
"requiredPrefix": "com.myorg"
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
},
|
|
288
|
+
"include": ["src/main/mule/**/*.xml"],
|
|
289
|
+
"exclude": ["**/test/**", "**/*.munit.xml"],
|
|
290
|
+
"failOnWarning": false
|
|
291
|
+
}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
---
|
|
295
|
+
|
|
296
|
+
## Using as a Library
|
|
297
|
+
|
|
298
|
+
Import directly into your TypeScript/JavaScript projects:
|
|
299
|
+
|
|
300
|
+
```typescript
|
|
301
|
+
import { LintEngine, ALL_RULES, formatSarif } from 'mule-lint';
|
|
302
|
+
|
|
303
|
+
// Create engine with all rules
|
|
304
|
+
const engine = new LintEngine({
|
|
305
|
+
rules: ALL_RULES,
|
|
306
|
+
config: {
|
|
307
|
+
include: ['src/main/mule/**/*.xml'],
|
|
308
|
+
},
|
|
309
|
+
});
|
|
310
|
+
|
|
311
|
+
// Scan a project
|
|
312
|
+
const report = await engine.scan('./my-mule-project');
|
|
313
|
+
console.log(formatSarif(report));
|
|
314
|
+
|
|
315
|
+
// Scan content directly (useful for VS Code extensions)
|
|
316
|
+
const issues = engine.scanContent(xmlContent, 'file.xml');
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
---
|
|
320
|
+
|
|
321
|
+
## Extending
|
|
322
|
+
|
|
323
|
+
### Adding Custom Rules
|
|
324
|
+
|
|
325
|
+
See [Extending Guide](docs/extending.md) for detailed instructions on creating custom rules.
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
import { BaseRule, ValidationContext, Issue } from 'mule-lint';
|
|
329
|
+
|
|
330
|
+
export class MyCustomRule extends BaseRule {
|
|
331
|
+
id = 'CUSTOM-001';
|
|
332
|
+
name = 'My Custom Rule';
|
|
333
|
+
description = 'Enforces my organization standards';
|
|
334
|
+
severity = 'warning' as const;
|
|
335
|
+
category = 'standards' as const;
|
|
336
|
+
|
|
337
|
+
validate(doc: Document, context: ValidationContext): Issue[] {
|
|
338
|
+
// Your validation logic using XPath
|
|
339
|
+
const flows = this.select('//mule:flow', doc);
|
|
340
|
+
// ...
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
```
|
|
344
|
+
|
|
345
|
+
---
|
|
346
|
+
|
|
347
|
+
## Project Inspiration
|
|
348
|
+
|
|
349
|
+
This project is inspired by and builds upon the ideas from:
|
|
350
|
+
|
|
351
|
+
- **[mule-lint/mule-lint](https://github.com/mule-lint/mule-lint)** - The original Groovy-based MuleSoft linting tool with DSL-based rule definitions
|
|
352
|
+
|
|
353
|
+
While the original project uses Groovy and a custom DSL, this TypeScript implementation was created to:
|
|
354
|
+
- Enable easier VS Code extension integration
|
|
355
|
+
- Provide better AI agent compatibility via SARIF output
|
|
356
|
+
- Leverage the modern npm ecosystem
|
|
357
|
+
- Offer simpler CI/CD integration
|
|
358
|
+
|
|
359
|
+
---
|
|
360
|
+
|
|
361
|
+
## Documentation
|
|
362
|
+
|
|
363
|
+
| Document | Description |
|
|
364
|
+
|----------|-------------|
|
|
365
|
+
| [Architecture](docs/architecture.md) | System design and data flow |
|
|
366
|
+
| [Rules Catalog](docs/rules-catalog.md) | Complete list of all rules |
|
|
367
|
+
| [Extending](docs/extending.md) | How to add custom rules |
|
|
368
|
+
| [Naming Conventions](docs/naming-conventions.md) | Code style guide |
|
|
369
|
+
|
|
370
|
+
---
|
|
371
|
+
|
|
372
|
+
## Development
|
|
373
|
+
|
|
374
|
+
```bash
|
|
375
|
+
# Install dependencies
|
|
376
|
+
npm install
|
|
377
|
+
|
|
378
|
+
# Build
|
|
379
|
+
npm run build
|
|
380
|
+
|
|
381
|
+
# Run tests
|
|
382
|
+
npm test
|
|
383
|
+
|
|
384
|
+
# Lint
|
|
385
|
+
npm run lint
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
---
|
|
389
|
+
|
|
390
|
+
## Credits
|
|
391
|
+
|
|
392
|
+
<table>
|
|
393
|
+
<tr>
|
|
394
|
+
<td align="center">
|
|
395
|
+
<strong>Built with AI Assistance</strong><br>
|
|
396
|
+
This project was developed with the assistance of:<br><br>
|
|
397
|
+
🚀 <strong>Antigravity</strong> (Google DeepMind)<br>
|
|
398
|
+
🤖 <strong>GitHub Copilot</strong>
|
|
399
|
+
</td>
|
|
400
|
+
</tr>
|
|
401
|
+
</table>
|
|
402
|
+
|
|
403
|
+
---
|
|
404
|
+
|
|
405
|
+
## Contributing
|
|
406
|
+
|
|
407
|
+
Contributions are welcome! Please read the [Contributing Guide](CONTRIBUTING.md) for details.
|
|
408
|
+
|
|
409
|
+
---
|
|
410
|
+
|
|
411
|
+
## License
|
|
412
|
+
|
|
413
|
+
MIT © 2024
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mule-lint.d.ts","sourceRoot":"","sources":["../../bin/mule-lint.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
4
|
+
if (k2 === undefined) k2 = k;
|
|
5
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
6
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
7
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
8
|
+
}
|
|
9
|
+
Object.defineProperty(o, k2, desc);
|
|
10
|
+
}) : (function(o, m, k, k2) {
|
|
11
|
+
if (k2 === undefined) k2 = k;
|
|
12
|
+
o[k2] = m[k];
|
|
13
|
+
}));
|
|
14
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
15
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
16
|
+
}) : function(o, v) {
|
|
17
|
+
o["default"] = v;
|
|
18
|
+
});
|
|
19
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
20
|
+
var ownKeys = function(o) {
|
|
21
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
22
|
+
var ar = [];
|
|
23
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
24
|
+
return ar;
|
|
25
|
+
};
|
|
26
|
+
return ownKeys(o);
|
|
27
|
+
};
|
|
28
|
+
return function (mod) {
|
|
29
|
+
if (mod && mod.__esModule) return mod;
|
|
30
|
+
var result = {};
|
|
31
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
32
|
+
__setModuleDefault(result, mod);
|
|
33
|
+
return result;
|
|
34
|
+
};
|
|
35
|
+
})();
|
|
36
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
37
|
+
const commander_1 = require("commander");
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const LintEngine_1 = require("../src/engine/LintEngine");
|
|
41
|
+
const rules_1 = require("../src/rules");
|
|
42
|
+
const formatters_1 = require("../src/formatters");
|
|
43
|
+
const program = new commander_1.Command();
|
|
44
|
+
program
|
|
45
|
+
.name('mule-lint')
|
|
46
|
+
.description('Static analysis tool for MuleSoft applications')
|
|
47
|
+
.version('1.0.0')
|
|
48
|
+
.argument('<path>', 'Path to scan (directory or file)')
|
|
49
|
+
.option('-f, --format <type>', 'Output format: table, json, sarif', 'table')
|
|
50
|
+
.option('-o, --output <file>', 'Write output to file instead of stdout')
|
|
51
|
+
.option('-c, --config <file>', 'Path to configuration file')
|
|
52
|
+
.option('-q, --quiet', 'Show only errors (suppress warnings and info)')
|
|
53
|
+
.option('--fail-on-warning', 'Exit with error code if warnings found')
|
|
54
|
+
.option('-e, --experimental', 'Enable experimental rules (opt-in)')
|
|
55
|
+
.option('-v, --verbose', 'Show verbose output')
|
|
56
|
+
.action(async (targetPath, options) => {
|
|
57
|
+
try {
|
|
58
|
+
await runLint(targetPath, options);
|
|
59
|
+
}
|
|
60
|
+
catch (error) {
|
|
61
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
62
|
+
console.error(`Error: ${message}`);
|
|
63
|
+
process.exit(2);
|
|
64
|
+
}
|
|
65
|
+
});
|
|
66
|
+
async function runLint(targetPath, options) {
|
|
67
|
+
const absolutePath = path.resolve(targetPath);
|
|
68
|
+
// Validate path exists
|
|
69
|
+
if (!fs.existsSync(absolutePath)) {
|
|
70
|
+
throw new Error(`Path does not exist: ${absolutePath}`);
|
|
71
|
+
}
|
|
72
|
+
// Load configuration if specified
|
|
73
|
+
let config = {};
|
|
74
|
+
if (options.config) {
|
|
75
|
+
const configPath = path.resolve(options.config);
|
|
76
|
+
if (!fs.existsSync(configPath)) {
|
|
77
|
+
throw new Error(`Config file not found: ${configPath}`);
|
|
78
|
+
}
|
|
79
|
+
const configContent = fs.readFileSync(configPath, 'utf-8');
|
|
80
|
+
config = JSON.parse(configContent);
|
|
81
|
+
}
|
|
82
|
+
// Filter rules based on keys (experimental is opt-in)
|
|
83
|
+
const effectiveRules = options.experimental
|
|
84
|
+
? rules_1.ALL_RULES
|
|
85
|
+
: rules_1.ALL_RULES.filter(rule => rule.category !== 'experimental');
|
|
86
|
+
if (options.verbose) {
|
|
87
|
+
console.log(`Loaded ${effectiveRules.length} rules (Experimental: ${options.experimental ? 'ON' : 'OFF'})`);
|
|
88
|
+
}
|
|
89
|
+
// Create engine
|
|
90
|
+
const engine = new LintEngine_1.LintEngine({
|
|
91
|
+
rules: effectiveRules,
|
|
92
|
+
config,
|
|
93
|
+
verbose: options.verbose,
|
|
94
|
+
});
|
|
95
|
+
// Run scan
|
|
96
|
+
const report = await engine.scan(absolutePath);
|
|
97
|
+
// Filter if quiet mode
|
|
98
|
+
if (options.quiet) {
|
|
99
|
+
for (const file of report.files) {
|
|
100
|
+
file.issues = file.issues.filter(issue => issue.severity === 'error');
|
|
101
|
+
}
|
|
102
|
+
report.summary.bySeverity.warning = 0;
|
|
103
|
+
report.summary.bySeverity.info = 0;
|
|
104
|
+
}
|
|
105
|
+
// Format output
|
|
106
|
+
const formatterType = options.format;
|
|
107
|
+
const output = (0, formatters_1.format)(report, formatterType);
|
|
108
|
+
// Write output
|
|
109
|
+
if (options.output) {
|
|
110
|
+
const outputPath = path.resolve(options.output);
|
|
111
|
+
fs.writeFileSync(outputPath, output, 'utf-8');
|
|
112
|
+
console.log(`Report written to: ${outputPath}`);
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
console.log(output);
|
|
116
|
+
}
|
|
117
|
+
// Exit code
|
|
118
|
+
const exitCode = (0, formatters_1.getExitCode)(report, options.failOnWarning);
|
|
119
|
+
process.exit(exitCode);
|
|
120
|
+
}
|
|
121
|
+
// Run the CLI
|
|
122
|
+
program.parse();
|
|
123
|
+
//# sourceMappingURL=mule-lint.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mule-lint.js","sourceRoot":"","sources":["../../bin/mule-lint.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Calculates cyclomatic complexity for Mule flows
|
|
3
|
+
*
|
|
4
|
+
* Complexity = 1 + (number of decision points)
|
|
5
|
+
*
|
|
6
|
+
* Decision points in Mule XML:
|
|
7
|
+
* - <choice> with N <when> clauses = N decision points
|
|
8
|
+
* - <until-successful> = 1 decision point
|
|
9
|
+
* - <foreach> = 1 decision point
|
|
10
|
+
* - <scatter-gather> = 1 decision point (parallel execution)
|
|
11
|
+
* - <try> = 1 decision point
|
|
12
|
+
*/
|
|
13
|
+
export declare class ComplexityCalculator {
|
|
14
|
+
/**
|
|
15
|
+
* Calculate cyclomatic complexity for a flow element
|
|
16
|
+
*/
|
|
17
|
+
static calculateFlowComplexity(flowNode: Node): ComplexityResult;
|
|
18
|
+
/**
|
|
19
|
+
* Get complexity rating
|
|
20
|
+
*/
|
|
21
|
+
static getRating(complexity: number): ComplexityRating;
|
|
22
|
+
/**
|
|
23
|
+
* Helper to select nodes using XPath with Mule namespace
|
|
24
|
+
*/
|
|
25
|
+
private static selectNodes;
|
|
26
|
+
/**
|
|
27
|
+
* Get the line number for a node
|
|
28
|
+
*/
|
|
29
|
+
static getNodeLine(node: Node): number;
|
|
30
|
+
}
|
|
31
|
+
export interface ComplexityResult {
|
|
32
|
+
complexity: number;
|
|
33
|
+
details: ComplexityDetail[];
|
|
34
|
+
rating: ComplexityRating;
|
|
35
|
+
}
|
|
36
|
+
export interface ComplexityDetail {
|
|
37
|
+
type: string;
|
|
38
|
+
count: number;
|
|
39
|
+
contribution: number;
|
|
40
|
+
}
|
|
41
|
+
export type ComplexityRating = 'low' | 'moderate' | 'high';
|
|
42
|
+
//# sourceMappingURL=ComplexityCalculator.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ComplexityCalculator.d.ts","sourceRoot":"","sources":["../../../src/core/ComplexityCalculator.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;GAWG;AACH,qBAAa,oBAAoB;IAC7B;;OAEG;IACH,MAAM,CAAC,uBAAuB,CAAC,QAAQ,EAAE,IAAI,GAAG,gBAAgB;IA6EhE;;OAEG;IACH,MAAM,CAAC,SAAS,CAAC,UAAU,EAAE,MAAM,GAAG,gBAAgB;IAMtD;;OAEG;IACH,OAAO,CAAC,MAAM,CAAC,WAAW;IAa1B;;OAEG;IACH,MAAM,CAAC,WAAW,CAAC,IAAI,EAAE,IAAI,GAAG,MAAM;CAGzC;AAED,MAAM,WAAW,gBAAgB;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,gBAAgB,EAAE,CAAC;IAC5B,MAAM,EAAE,gBAAgB,CAAC;CAC5B;AAED,MAAM,WAAW,gBAAgB;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,YAAY,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,MAAM,gBAAgB,GAAG,KAAK,GAAG,UAAU,GAAG,MAAM,CAAC"}
|