@sfdxy/mule-lint 1.5.0 → 1.5.2

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.
@@ -111,6 +111,11 @@ async function runLint(targetPath, options) {
111
111
  fs.writeFileSync(outputPath, output, 'utf-8');
112
112
  console.log(`Report written to: ${outputPath}`);
113
113
  }
114
+ else if (formatterType === 'html') {
115
+ const outputPath = path.resolve('report.html');
116
+ fs.writeFileSync(outputPath, output, 'utf-8');
117
+ console.log(`Report written to: ${outputPath}`);
118
+ }
114
119
  else {
115
120
  console.log(output);
116
121
  }
@@ -1 +1 @@
1
- {"version":3,"file":"mule-lint.js","sourceRoot":"","sources":["../../bin/mule-lint.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"mule-lint.js","sourceRoot":"","sources":["../../bin/mule-lint.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAEA,yCAAoC;AACpC,uCAAyB;AACzB,2CAA6B;AAC7B,yDAAsD;AACtD,wCAAyC;AACzC,kDAAwD;AAGxD,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACF,IAAI,CAAC,WAAW,CAAC;KACjB,WAAW,CAAC,gDAAgD,CAAC;KAC7D,OAAO,CAAC,OAAO,CAAC;KAChB,QAAQ,CAAC,QAAQ,EAAE,kCAAkC,CAAC;KACtD,MAAM,CAAC,qBAAqB,EAAE,mCAAmC,EAAE,OAAO,CAAC;KAC3E,MAAM,CAAC,qBAAqB,EAAE,wCAAwC,CAAC;KACvE,MAAM,CAAC,qBAAqB,EAAE,4BAA4B,CAAC;KAC3D,MAAM,CAAC,aAAa,EAAE,+CAA+C,CAAC;KACtE,MAAM,CAAC,mBAAmB,EAAE,wCAAwC,CAAC;KACrE,MAAM,CAAC,oBAAoB,EAAE,oCAAoC,CAAC;KAClE,MAAM,CAAC,eAAe,EAAE,qBAAqB,CAAC;KAC9C,MAAM,CAAC,KAAK,EAAE,UAAkB,EAAE,OAAO,EAAE,EAAE;IAC1C,IAAI,CAAC;QACD,MAAM,OAAO,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACvE,OAAO,CAAC,KAAK,CAAC,UAAU,OAAO,EAAE,CAAC,CAAC;QACnC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;AACL,CAAC,CAAC,CAAC;AAYP,KAAK,UAAU,OAAO,CAAC,UAAkB,EAAE,OAAmB;IAC1D,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IAE9C,uBAAuB;IACvB,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,wBAAwB,YAAY,EAAE,CAAC,CAAC;IAC5D,CAAC;IAED,kCAAkC;IAClC,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACjB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAChD,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,0BAA0B,UAAU,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,MAAM,aAAa,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAC;QAC3D,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC;IACvC,CAAC;IAED,sDAAsD;IACtD,MAAM,cAAc,GAAG,OAAO,CAAC,YAAY;QACvC,CAAC,CAAC,iBAAS;QACX,CAAC,CAAC,iBAAS,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,QAAQ,KAAK,cAAc,CAAC,CAAC;IAEjE,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QAClB,OAAO,CAAC,GAAG,CAAC,UAAU,cAAc,CAAC,MAAM,yBAAyB,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,KAAK,GAAG,CAAC,CAAC;IAChH,CAAC;IAED,gBAAgB;IAChB,MAAM,MAAM,GAAG,IAAI,uBAAU,CAAC;QAC1B,KAAK,EAAE,cAAc;QACrB,MAAM;QACN,OAAO,EAAE,OAAO,CAAC,OAAO;KAC3B,CAAC,CAAC;IAEH,WAAW;IACX,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC;IAE/C,uBAAuB;IACvB,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAChB,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;YAC9B,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;QAC1E,CAAC;QACD,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,OAAO,GAAG,CAAC,CAAC;QACtC,MAAM,CAAC,OAAO,CAAC,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC;IACvC,CAAC;IAED,gBAAgB;IAChB,MAAM,aAAa,GAAG,OAAO,CAAC,MAAuB,CAAC;IACtD,MAAM,MAAM,GAAG,IAAA,mBAAM,EAAC,MAAM,EAAE,aAAa,CAAC,CAAC;IAE7C,eAAe;IACf,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACjB,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAChD,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,sBAAsB,UAAU,EAAE,CAAC,CAAC;IACpD,CAAC;SAAM,IAAI,aAAa,KAAK,MAAM,EAAE,CAAC;QAClC,MAAM,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAC/C,EAAE,CAAC,aAAa,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9C,OAAO,CAAC,GAAG,CAAC,sBAAsB,UAAU,EAAE,CAAC,CAAC;IACpD,CAAC;SAAM,CAAC;QACJ,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACxB,CAAC;IAED,YAAY;IACZ,MAAM,QAAQ,GAAG,IAAA,wBAAW,EAAC,MAAM,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAC5D,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC3B,CAAC;AAED,cAAc;AACd,OAAO,CAAC,KAAK,EAAE,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"HtmlFormatter.d.ts","sourceRoot":"","sources":["../../../src/formatters/HtmlFormatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CA4UrD"}
1
+ {"version":3,"file":"HtmlFormatter.d.ts","sourceRoot":"","sources":["../../../src/formatters/HtmlFormatter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAG7C;;GAEG;AACH,wBAAgB,UAAU,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAkXrD"}
@@ -12,7 +12,31 @@ function formatHtml(report) {
12
12
  const totalWarnings = report.summary.bySeverity.warning;
13
13
  const totalInfos = report.summary.bySeverity.info;
14
14
  const totalIssues = totalErrors + totalWarnings + totalInfos;
15
- const score = Math.max(0, 100 - (totalErrors * 5) - (totalWarnings * 1));
15
+ // Collect all issues into a flat list for the table
16
+ const allIssues = [];
17
+ for (const file of report.files) {
18
+ if (!file.parsed) {
19
+ allIssues.push({
20
+ severity: 'error',
21
+ file: file.relativePath,
22
+ line: 1,
23
+ column: 1,
24
+ message: file.parseError || 'Failed to parse XML file',
25
+ ruleId: 'PARSE-ERROR'
26
+ });
27
+ continue;
28
+ }
29
+ for (const issue of file.issues) {
30
+ allIssues.push({
31
+ severity: issue.severity,
32
+ file: file.relativePath,
33
+ line: issue.line,
34
+ column: issue.column || 0,
35
+ message: issue.message,
36
+ ruleId: issue.ruleId
37
+ });
38
+ }
39
+ }
16
40
  return `<!DOCTYPE html>
17
41
  <html lang="en">
18
42
  <head>
@@ -46,7 +70,7 @@ function formatHtml(report) {
46
70
 
47
71
  /* Layout */
48
72
  .container {
49
- max-width: 1200px;
73
+ width: 95%; /* Full width as requested */
50
74
  margin: 0 auto;
51
75
  padding: 20px;
52
76
  }
@@ -72,7 +96,7 @@ function formatHtml(report) {
72
96
  /* Dashboard Grid */
73
97
  .dashboard {
74
98
  display: grid;
75
- grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));
99
+ grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
76
100
  gap: 20px;
77
101
  margin-bottom: 30px;
78
102
  }
@@ -94,37 +118,16 @@ function formatHtml(report) {
94
118
  .number { font-size: 3rem; font-weight: 700; line-height: 1; margin-bottom: 0.5rem; }
95
119
  .label { color: var(--text-secondary); font-size: 0.9rem; text-transform: uppercase; letter-spacing: 0.05em; font-weight: 600; }
96
120
 
97
- .score-ring {
98
- width: 100px;
99
- height: 100px;
100
- border-radius: 50%;
101
- display: flex;
102
- align-items: center;
103
- justify-content: center;
104
- font-size: 2.5rem;
105
- font-weight: bold;
106
- color: var(--primary);
107
- border: 8px solid var(--background);
108
- position: relative;
109
- background: conic-gradient(var(--primary) calc(var(--score) * 1%), var(--border) 0);
110
- }
111
- .score-inner {
112
- width: 80px;
113
- height: 80px;
114
- background: var(--surface);
115
- border-radius: 50%;
116
- display: flex;
117
- align-items: center;
118
- justify-content: center;
119
- position: absolute;
120
- }
121
-
122
121
  /* Filters */
123
122
  .controls {
124
123
  display: flex;
125
124
  gap: 15px;
126
125
  margin-bottom: 20px;
127
- flex-wrap: wrap;
126
+ align-items: center;
127
+ background: var(--surface);
128
+ padding: 15px;
129
+ border-radius: 8px;
130
+ box-shadow: var(--shadow);
128
131
  }
129
132
  .search-box {
130
133
  flex: 1;
@@ -132,12 +135,15 @@ function formatHtml(report) {
132
135
  border: 1px solid var(--border);
133
136
  border-radius: 6px;
134
137
  font-size: 1rem;
135
- min-width: 200px;
138
+ }
139
+ .filter-group {
140
+ display: flex;
141
+ gap: 10px;
136
142
  }
137
143
  .filter-btn {
138
144
  padding: 8px 16px;
139
145
  border: 1px solid var(--border);
140
- background: var(--surface);
146
+ background: var(--background);
141
147
  border-radius: 6px;
142
148
  cursor: pointer;
143
149
  font-weight: 500;
@@ -151,52 +157,54 @@ function formatHtml(report) {
151
157
  color: white;
152
158
  border-color: var(--primary);
153
159
  }
154
- .filter-btn:hover:not(.active) { background: #f0f0f0; }
160
+ .filter-btn:hover:not(.active) { background: #e0e0e0; }
155
161
 
156
- /* File List */
157
- .file-section {
162
+ /* Issues Table */
163
+ .table-container {
158
164
  background: var(--surface);
159
165
  border-radius: 8px;
160
166
  box-shadow: var(--shadow);
161
- margin-bottom: 20px;
162
- overflow: hidden;
167
+ overflow-x: auto;
163
168
  }
164
- .file-header {
165
- padding: 15px 20px;
166
- background: #fafafa;
167
- border-bottom: 1px solid var(--border);
168
- display: flex;
169
- justify-content: space-between;
170
- align-items: center;
171
- cursor: pointer;
172
- user-select: none;
173
- }
174
- .file-header:hover { background: #f0f0f0; }
175
- .file-path { font-weight: 600; font-family: 'SFMono-Regular', Consolas, 'Liberation Mono', Menlo, monospace; color: var(--text-primary); }
176
- .badge-group { display: flex; gap: 8px; }
177
- .badge { padding: 4px 8px; border-radius: 12px; font-size: 0.75rem; font-weight: 600; color: white; min-width: 20px; text-align: center; }
178
- .badge.error { background: var(--error); }
179
- .badge.warning { background: var(--warning); }
180
- .badge.info { background: var(--info); }
181
-
182
- /* Issues Table */
183
- .issues-table {
169
+ table {
184
170
  width: 100%;
185
171
  border-collapse: collapse;
186
- display: table; /* Default visible */
187
172
  }
188
- .issues-table.collapsed { display: none; }
189
173
 
190
174
  th, td {
191
175
  text-align: left;
192
176
  padding: 12px 20px;
193
177
  border-bottom: 1px solid var(--border);
194
178
  }
195
- th { background: #f9f9f9; color: var(--text-secondary); font-weight: 600; font-size: 0.85rem; text-transform: uppercase; }
179
+ th {
180
+ background: #f9f9f9;
181
+ color: var(--text-secondary);
182
+ font-weight: 600;
183
+ font-size: 0.85rem;
184
+ text-transform: uppercase;
185
+ position: sticky;
186
+ top: 0;
187
+ }
188
+ tr:hover { background-color: #f5f9ff; }
196
189
  tr:last-child td { border-bottom: none; }
197
190
 
198
- .severity-cell { font-weight: 700; text-transform: uppercase; font-size: 0.8rem; }
191
+ .severity-badge {
192
+ font-weight: 700;
193
+ text-transform: uppercase;
194
+ font-size: 0.75rem;
195
+ padding: 4px 8px;
196
+ border-radius: 4px;
197
+ display: inline-block;
198
+ min-width: 60px;
199
+ text-align: center;
200
+ }
201
+ .bg-error { background-color: #ffebee; color: var(--error); }
202
+ .bg-warning { background-color: #fff3e0; color: var(--warning); }
203
+ .bg-info { background-color: #e3f2fd; color: var(--info); }
204
+
205
+ .file-link { font-family: monospace; font-weight: 600; color: var(--text-primary); }
199
206
  .location { font-family: monospace; color: var(--text-secondary); }
207
+
200
208
  .rule-pill {
201
209
  display: inline-block;
202
210
  background: #eef2f5;
@@ -207,10 +215,6 @@ function formatHtml(report) {
207
215
  font-family: monospace;
208
216
  border: 1px solid #dce1e6;
209
217
  }
210
-
211
- .color-error { color: var(--error); }
212
- .color-warning { color: var(--warning); }
213
- .color-info { color: var(--info); }
214
218
 
215
219
  .empty-state {
216
220
  text-align: center;
@@ -221,8 +225,8 @@ function formatHtml(report) {
221
225
 
222
226
  /* Responsive */
223
227
  @media (max-width: 768px) {
224
- .file-header { flex-direction: column; align-items: flex-start; gap: 10px; }
225
- .badge-group { align-self: flex-start; }
228
+ .controls { flex-direction: column; align-items: stretch; }
229
+ .filter-group { justify-content: space-between; }
226
230
  }
227
231
  </style>
228
232
  </head>
@@ -245,12 +249,6 @@ function formatHtml(report) {
245
249
  <div class="container">
246
250
  <!-- Dashboard -->
247
251
  <div class="dashboard">
248
- <div class="card">
249
- <div class="score-ring" style="--score: ${score}">
250
- <div class="score-inner">${score}</div>
251
- </div>
252
- <span class="label" style="margin-top: 10px;">Health Score</span>
253
- </div>
254
252
  <div class="card">
255
253
  <span class="number" style="color: var(--error)">${totalErrors}</span>
256
254
  <span class="label">Errors</span>
@@ -260,140 +258,121 @@ function formatHtml(report) {
260
258
  <span class="label">Warnings</span>
261
259
  </div>
262
260
  <div class="card">
263
- <span class="number" style="color: default">${report.files.length}</span>
261
+ <span class="number" style="color: var(--info)">${totalInfos}</span>
262
+ <span class="label">Infos</span>
263
+ </div>
264
+ <div class="card">
265
+ <span class="number">${report.files.length}</span>
264
266
  <span class="label">Files Scanned</span>
265
267
  </div>
266
268
  </div>
267
269
 
268
270
  <!-- Controls -->
269
271
  <div class="controls">
270
- <input type="text" id="searchInput" class="search-box" placeholder="Search files, rules, or messages..." onkeyup="filterIssues()">
271
-
272
- <button class="filter-btn active" onclick="toggleFilter('all', this)" id="btn-all">All</button>
273
- <button class="filter-btn" onclick="toggleFilter('error', this)" id="btn-error">Errors <span class="badge error">${totalErrors}</span></button>
274
- <button class="filter-btn" onclick="toggleFilter('warning', this)" id="btn-warning">Warnings <span class="badge warning">${totalWarnings}</span></button>
272
+ <input type="text" id="searchInput" class="search-box" placeholder="Search by file, message, or rule..." onkeyup="filterTable()">
273
+ <div class="filter-group">
274
+ <button class="filter-btn active" onclick="toggleFilter('all', this)" id="btn-all">All</button>
275
+ <button class="filter-btn" onclick="toggleFilter('error', this)" id="btn-error">Errors</button>
276
+ <button class="filter-btn" onclick="toggleFilter('warning', this)" id="btn-warning">Warnings</button>
277
+ <button class="filter-btn" onclick="toggleFilter('info', this)" id="btn-info">Infos</button>
278
+ </div>
275
279
  </div>
276
280
 
277
- <!-- File List -->
278
- <div id="report-content">
279
- ${renderFiles(report)}
280
- </div>
281
-
282
- ${totalIssues === 0 && report.summary.parseErrors === 0 ? `
283
- <div class="empty-state">
284
- <div class="empty-icon">🎉</div>
285
- <h2>No issues found!</h2>
286
- <p>Your MuleSoft code looks clean and compliant.</p>
281
+ <!-- Main Table -->
282
+ <div class="table-container">
283
+ <table id="issuesTable">
284
+ <thead>
285
+ <tr>
286
+ <th width="100">Severity</th>
287
+ <th width="150">Rule</th>
288
+ <th width="300">File</th>
289
+ <th width="100">Location</th>
290
+ <th>Message</th>
291
+ </tr>
292
+ </thead>
293
+ <tbody>
294
+ ${allIssues.map(issue => renderIssueRow(issue)).join('')}
295
+ </tbody>
296
+ </table>
297
+
298
+ ${totalIssues === 0 && report.summary.parseErrors === 0 ? `
299
+ <div class="empty-state">
300
+ <div class="empty-icon">🎉</div>
301
+ <h2>No issues found!</h2>
302
+ <p>Your MuleSoft code looks clean and compliant.</p>
303
+ </div>
304
+ ` : ''}
305
+
306
+ <div id="noResults" class="empty-state" style="display: none;">
307
+ <h2>No matching issues found</h2>
308
+ <p>Try adjusting your search filters.</p>
309
+ </div>
287
310
  </div>
288
- ` : ''}
289
-
290
311
  </div>
291
312
 
292
313
  <script>
293
- let currentFilter = 'all';
314
+ let currentSeverity = 'all';
294
315
 
295
- function toggleFilter(filter, btn) {
296
- currentFilter = filter;
316
+ function toggleFilter(severity, btn) {
317
+ currentSeverity = severity;
297
318
 
298
319
  // Update buttons
299
320
  document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
300
321
  btn.classList.add('active');
301
322
 
302
- filterIssues();
323
+ filterTable();
303
324
  }
304
325
 
305
- function filterIssues() {
306
- const search = document.getElementById('searchInput').value.toLowerCase();
307
- const fileSections = document.querySelectorAll('.file-section');
308
-
309
- fileSections.forEach(section => {
310
- const text = section.innerText.toLowerCase();
311
- const matchesSearch = text.includes(search);
312
-
313
- // For filtering by severity, we check if the section has relevant issues
314
- // This is a simplified approach: we either show or hide the whole file if it matches
315
- // Ideally we filter rows, but file-level hiding is often better for overview
326
+ function filterTable() {
327
+ const input = document.getElementById('searchInput');
328
+ const filter = input.value.toLowerCase();
329
+ const table = document.getElementById('issuesTable');
330
+ const tr = table.getElementsByTagName('tr');
331
+ let visibleCount = 0;
332
+
333
+ for (let i = 1; i < tr.length; i++) {
334
+ const row = tr[i];
335
+ const severity = row.getAttribute('data-severity');
336
+ const text = row.innerText.toLowerCase();
316
337
 
317
- let matchesFilter = true;
318
- if (currentFilter !== 'all') {
319
- matchesFilter = section.dataset.has.includes(currentFilter);
320
- }
338
+ const severityMatch = currentSeverity === 'all' || severity === currentSeverity;
339
+ const textMatch = text.includes(filter);
321
340
 
322
- if (matchesSearch && matchesFilter) {
323
- section.style.display = 'block';
341
+ if (severityMatch && textMatch) {
342
+ row.style.display = '';
343
+ visibleCount++;
324
344
  } else {
325
- section.style.display = 'none';
345
+ row.style.display = 'none';
326
346
  }
327
- });
328
- }
329
-
330
- function toggleFile(header) {
331
- const table = header.nextElementSibling;
332
- table.classList.toggle('collapsed');
347
+ }
348
+
349
+ // Show/hide no results message
350
+ const noResults = document.getElementById('noResults');
351
+ const emptyState = document.querySelector('.empty-state:not(#noResults)');
352
+
353
+ if (emptyState) return; // Don't interfere if main empty state is shown
354
+
355
+ if (visibleCount === 0 && tr.length > 1) {
356
+ noResults.style.display = 'block';
357
+ table.style.display = 'none';
358
+ } else {
359
+ noResults.style.display = 'none';
360
+ table.style.display = '';
361
+ }
333
362
  }
334
363
  </script>
335
364
  </body>
336
365
  </html>`;
337
366
  }
338
- function renderFiles(report) {
339
- return report.files
340
- .filter(f => f.issues.length > 0 || !f.parsed)
341
- .map(file => {
342
- const errorCount = file.issues.filter(i => i.severity === 'error').length + (file.parsed ? 0 : 1);
343
- const warningCount = file.issues.filter(i => i.severity === 'warning').length;
344
- const infoCount = file.issues.filter(i => i.severity === 'info').length;
345
- const hasTypes = [];
346
- if (errorCount > 0)
347
- hasTypes.push('error');
348
- if (warningCount > 0)
349
- hasTypes.push('warning');
350
- if (infoCount > 0)
351
- hasTypes.push('info');
352
- return `<div class="file-section" data-has="${hasTypes.join(' ')}">
353
- <div class="file-header" onclick="toggleFile(this)">
354
- <span class="file-path">${file.relativePath}</span>
355
- <div class="badge-group">
356
- ${!file.parsed ? '<span class="badge error">PARSE</span>' : ''}
357
- ${errorCount > 0 ? `<span class="badge error">${errorCount}</span>` : ''}
358
- ${warningCount > 0 ? `<span class="badge warning">${warningCount}</span>` : ''}
359
- </div>
360
- </div>
361
- <table class="issues-table">
362
- <thead>
363
- <tr>
364
- <th width="80">Severity</th>
365
- <th width="100">Location</th>
366
- <th>Message</th>
367
- <th width="120">Rule</th>
368
- </tr>
369
- </thead>
370
- <tbody>
371
- ${!file.parsed ? renderParseError(file) : ''}
372
- ${file.issues.map(issue => renderIssue(issue)).join('')}
373
- </tbody>
374
- </table>
375
- </div>`;
376
- }).join('');
377
- }
378
- function renderParseError(file) {
379
- return `<tr>
380
- <td class="severity-cell color-error">ERROR</td>
381
- <td class="location">1:1</td>
382
- <td>
383
- <div><strong>Failed to parse XML file</strong></div>
384
- <div style="font-size: 0.9em; margin-top: 4px; color: var(--text-secondary);">
385
- ${file.parseError || 'Unknown error'}
386
- </div>
387
- </td>
388
- <td><span class="rule-pill">PARSE-ERROR</span></td>
389
- </tr>`;
390
- }
391
- function renderIssue(issue) {
392
- return `<tr>
393
- <td class="severity-cell color-${issue.severity}">${issue.severity}</td>
394
- <td class="location">${issue.line}:${issue.column || 0}</td>
395
- <td>${escapeHtml(issue.message)}</td>
367
+ function renderIssueRow(issue) {
368
+ const badgeClass = issue.severity === 'error' ? 'bg-error' :
369
+ issue.severity === 'warning' ? 'bg-warning' : 'bg-info';
370
+ return `<tr data-severity="${issue.severity}">
371
+ <td><span class="severity-badge ${badgeClass}">${issue.severity}</span></td>
396
372
  <td><span class="rule-pill">${issue.ruleId}</span></td>
373
+ <td class="file-link" title="${issue.file}">${issue.file}</td>
374
+ <td class="location">${issue.line}:${issue.column}</td>
375
+ <td>${escapeHtml(issue.message)}</td>
397
376
  </tr>`;
398
377
  }
399
378
  function escapeHtml(unsafe) {
@@ -1 +1 @@
1
- {"version":3,"file":"HtmlFormatter.js","sourceRoot":"","sources":["../../../src/formatters/HtmlFormatter.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"HtmlFormatter.js","sourceRoot":"","sources":["../../../src/formatters/HtmlFormatter.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sfdxy/mule-lint",
3
- "version": "1.5.0",
3
+ "version": "1.5.2",
4
4
  "description": "Static analysis tool for MuleSoft applications - supports humans, AI agents, and CI/CD pipelines",
5
5
  "author": "Avinava",
6
6
  "license": "MIT",