@code-pushup/eslint-plugin 0.39.0 → 0.42.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (3) hide show
  1. package/bin.js +434 -90
  2. package/index.js +436 -90
  3. package/package.json +5 -5
package/bin.js CHANGED
@@ -2,8 +2,292 @@
2
2
  import { writeFile as writeFile2 } from "node:fs/promises";
3
3
  import { dirname, join as join3 } from "node:path";
4
4
 
5
- // packages/models/src/lib/audit.ts
6
- import { z as z2 } from "zod";
5
+ // packages/utils/src/lib/text-formats/constants.ts
6
+ var NEW_LINE = "\n";
7
+ var TAB = " ";
8
+
9
+ // packages/utils/src/lib/text-formats/html/details.ts
10
+ function details(title, content, cfg = { open: false }) {
11
+ return `<details${cfg.open ? " open" : ""}>${NEW_LINE}<summary>${title}</summary>${NEW_LINE}${// ⚠️ The blank line is needed to ensure Markdown in content is rendered correctly.
12
+ NEW_LINE}${content}${NEW_LINE}${// @TODO in the future we could consider adding it only if the content ends with a code block
13
+ // ⚠️ The blank line ensure Markdown in content is rendered correctly.
14
+ NEW_LINE}</details>${// ⚠️ The blank line is needed to ensure Markdown after details is rendered correctly.
15
+ NEW_LINE}`;
16
+ }
17
+
18
+ // packages/utils/src/lib/text-formats/html/font-style.ts
19
+ var boldElement = "b";
20
+ function bold(text) {
21
+ return `<${boldElement}>${text}</${boldElement}>`;
22
+ }
23
+ var italicElement = "i";
24
+ function italic(text) {
25
+ return `<${italicElement}>${text}</${italicElement}>`;
26
+ }
27
+ var codeElement = "code";
28
+ function code(text) {
29
+ return `<${codeElement}>${text}</${codeElement}>`;
30
+ }
31
+
32
+ // packages/utils/src/lib/text-formats/html/link.ts
33
+ function link(href, text) {
34
+ return `<a href="${href}">${text || href}"</a>`;
35
+ }
36
+
37
+ // packages/utils/src/lib/transform.ts
38
+ function toArray(val) {
39
+ return Array.isArray(val) ? val : [val];
40
+ }
41
+ function objectToEntries(obj) {
42
+ return Object.entries(obj);
43
+ }
44
+ function countOccurrences(values) {
45
+ return values.reduce(
46
+ (acc, value) => ({ ...acc, [value]: (acc[value] ?? 0) + 1 }),
47
+ {}
48
+ );
49
+ }
50
+ function distinct(array) {
51
+ return [...new Set(array)];
52
+ }
53
+ function capitalize(text) {
54
+ return `${text.charAt(0).toLocaleUpperCase()}${text.slice(
55
+ 1
56
+ )}`;
57
+ }
58
+
59
+ // packages/utils/src/lib/table.ts
60
+ function rowToStringArray({ rows, columns = [] }) {
61
+ if (Array.isArray(rows.at(0)) && typeof columns.at(0) === "object") {
62
+ throw new TypeError(
63
+ "Column can`t be object when rows are primitive values"
64
+ );
65
+ }
66
+ return rows.map((row) => {
67
+ if (Array.isArray(row)) {
68
+ return row.map(String);
69
+ }
70
+ const objectRow = row;
71
+ if (columns.length === 0 || typeof columns.at(0) === "string") {
72
+ return Object.values(objectRow).map(String);
73
+ }
74
+ return columns.map(
75
+ ({ key }) => String(objectRow[key])
76
+ );
77
+ });
78
+ }
79
+ function columnsToStringArray({ rows, columns = [] }) {
80
+ const firstRow = rows.at(0);
81
+ const primitiveRows = Array.isArray(firstRow);
82
+ if (typeof columns.at(0) === "string" && !primitiveRows) {
83
+ throw new Error("invalid union type. Caught by model parsing.");
84
+ }
85
+ if (columns.length === 0) {
86
+ if (Array.isArray(firstRow)) {
87
+ return firstRow.map((_, idx) => String(idx));
88
+ }
89
+ return Object.keys(firstRow);
90
+ }
91
+ if (typeof columns.at(0) === "string") {
92
+ return columns.map(String);
93
+ }
94
+ const cols = columns;
95
+ return cols.map(({ label, key }) => label ?? capitalize(key));
96
+ }
97
+ function getColumnAlignmentForKeyAndIndex(targetKey, targetIdx, columns = []) {
98
+ const column = columns.at(targetIdx) ?? columns.find((col) => col.key === targetKey);
99
+ if (typeof column === "string") {
100
+ return column;
101
+ } else if (typeof column === "object") {
102
+ return column.align ?? "center";
103
+ } else {
104
+ return "center";
105
+ }
106
+ }
107
+ function getColumnAlignmentForIndex(targetIdx, columns = []) {
108
+ const column = columns.at(targetIdx);
109
+ if (column == null) {
110
+ return "center";
111
+ } else if (typeof column === "string") {
112
+ return column;
113
+ } else if (typeof column === "object") {
114
+ return column.align ?? "center";
115
+ } else {
116
+ return "center";
117
+ }
118
+ }
119
+ function getColumnAlignments({
120
+ rows,
121
+ columns = []
122
+ }) {
123
+ if (rows.at(0) == null) {
124
+ throw new Error("first row can`t be undefined.");
125
+ }
126
+ if (Array.isArray(rows.at(0))) {
127
+ const firstPrimitiveRow = rows.at(0);
128
+ return Array.from({ length: firstPrimitiveRow.length }).map(
129
+ (_, idx) => getColumnAlignmentForIndex(idx, columns)
130
+ );
131
+ }
132
+ const firstObject = rows.at(0);
133
+ return Object.keys(firstObject).map(
134
+ (key, idx) => getColumnAlignmentForKeyAndIndex(key, idx, columns)
135
+ );
136
+ }
137
+
138
+ // packages/utils/src/lib/text-formats/html/table.ts
139
+ function wrap(elem, content) {
140
+ return `<${elem}>${content}</${elem}>${NEW_LINE}`;
141
+ }
142
+ function wrapRow(content) {
143
+ const elem = "tr";
144
+ return `<${elem}>${NEW_LINE}${content}</${elem}>${NEW_LINE}`;
145
+ }
146
+ function table(tableData) {
147
+ if (tableData.rows.length === 0) {
148
+ throw new Error("Data can't be empty");
149
+ }
150
+ const tableHeaderCols = columnsToStringArray(tableData).map((s) => wrap("th", s)).join("");
151
+ const tableHeaderRow = wrapRow(tableHeaderCols);
152
+ const tableBody = rowToStringArray(tableData).map((arr) => {
153
+ const columns = arr.map((s) => wrap("td", s)).join("");
154
+ return wrapRow(columns);
155
+ }).join("");
156
+ return wrap("table", `${NEW_LINE}${tableHeaderRow}${tableBody}`);
157
+ }
158
+
159
+ // packages/utils/src/lib/text-formats/md/font-style.ts
160
+ var boldWrap = "**";
161
+ function bold2(text) {
162
+ return `${boldWrap}${text}${boldWrap}`;
163
+ }
164
+ var italicWrap = "_";
165
+ function italic2(text) {
166
+ return `${italicWrap}${text}${italicWrap}`;
167
+ }
168
+ var strikeThroughWrap = "~";
169
+ function strikeThrough(text) {
170
+ return `${strikeThroughWrap}${text}${strikeThroughWrap}`;
171
+ }
172
+ var codeWrap = "`";
173
+ function code2(text) {
174
+ return `${codeWrap}${text}${codeWrap}`;
175
+ }
176
+
177
+ // packages/utils/src/lib/text-formats/md/headline.ts
178
+ function headline(text, hierarchy = 1) {
179
+ return `${"#".repeat(hierarchy)} ${text}${NEW_LINE}`;
180
+ }
181
+ function h(text, hierarchy = 1) {
182
+ return headline(text, hierarchy);
183
+ }
184
+ function h1(text) {
185
+ return headline(text, 1);
186
+ }
187
+ function h2(text) {
188
+ return headline(text, 2);
189
+ }
190
+ function h3(text) {
191
+ return headline(text, 3);
192
+ }
193
+ function h4(text) {
194
+ return headline(text, 4);
195
+ }
196
+ function h5(text) {
197
+ return headline(text, 5);
198
+ }
199
+ function h6(text) {
200
+ return headline(text, 6);
201
+ }
202
+
203
+ // packages/utils/src/lib/text-formats/md/image.ts
204
+ function image(src, alt) {
205
+ return `![${alt}](${src})`;
206
+ }
207
+
208
+ // packages/utils/src/lib/text-formats/md/link.ts
209
+ function link2(href, text) {
210
+ return `[${text || href}](${href})`;
211
+ }
212
+
213
+ // packages/utils/src/lib/text-formats/md/list.ts
214
+ function li(text, order = "unordered") {
215
+ const style = order === "unordered" ? "-" : "- [ ]";
216
+ return `${style} ${text}`;
217
+ }
218
+ function indentation(text, level = 1) {
219
+ return `${TAB.repeat(level)}${text}`;
220
+ }
221
+
222
+ // packages/utils/src/lib/text-formats/md/paragraphs.ts
223
+ function paragraphs(...sections) {
224
+ return sections.filter(Boolean).join(`${NEW_LINE}${NEW_LINE}`);
225
+ }
226
+
227
+ // packages/utils/src/lib/text-formats/md/section.ts
228
+ function section(...contents) {
229
+ return `${lines(...contents)}${NEW_LINE}`;
230
+ }
231
+ function lines(...contents) {
232
+ return `${contents.filter(Boolean).join(NEW_LINE)}`;
233
+ }
234
+
235
+ // packages/utils/src/lib/text-formats/md/table.ts
236
+ var alignString = /* @__PURE__ */ new Map([
237
+ ["left", ":--"],
238
+ ["center", ":--:"],
239
+ ["right", "--:"]
240
+ ]);
241
+ function tableRow(rows) {
242
+ return `|${rows.join("|")}|`;
243
+ }
244
+ function table2(data) {
245
+ if (data.rows.length === 0) {
246
+ throw new Error("Data can't be empty");
247
+ }
248
+ const alignmentRow = getColumnAlignments(data).map(
249
+ (s) => alignString.get(s) ?? String(alignString.get("center"))
250
+ );
251
+ return section(
252
+ `${lines(
253
+ tableRow(columnsToStringArray(data)),
254
+ tableRow(alignmentRow),
255
+ ...rowToStringArray(data).map(tableRow)
256
+ )}`
257
+ );
258
+ }
259
+
260
+ // packages/utils/src/lib/text-formats/index.ts
261
+ var md = {
262
+ bold: bold2,
263
+ italic: italic2,
264
+ strikeThrough,
265
+ code: code2,
266
+ link: link2,
267
+ image,
268
+ headline,
269
+ h,
270
+ h1,
271
+ h2,
272
+ h3,
273
+ h4,
274
+ h5,
275
+ h6,
276
+ indentation,
277
+ lines,
278
+ li,
279
+ section,
280
+ paragraphs,
281
+ table: table2
282
+ };
283
+ var html = {
284
+ bold,
285
+ italic,
286
+ code,
287
+ link,
288
+ details,
289
+ table
290
+ };
7
291
 
8
292
  // packages/models/src/lib/implementation/schemas.ts
9
293
  import { MATERIAL_ICONS } from "vscode-material-icons";
@@ -70,6 +354,7 @@ function missingRefsForCategoriesErrorMsg(categories, plugins) {
70
354
  }
71
355
 
72
356
  // packages/models/src/lib/implementation/schemas.ts
357
+ var primitiveValueSchema = z.union([z.string(), z.number()]);
73
358
  function executionMetaSchema(options = {
74
359
  descriptionDate: "Execution start date and time",
75
360
  descriptionDuration: "Execution duration in ms"
@@ -161,6 +446,7 @@ function hasNonZeroWeightedRef(refs) {
161
446
  }
162
447
 
163
448
  // packages/models/src/lib/audit.ts
449
+ import { z as z2 } from "zod";
164
450
  var auditSchema = z2.object({
165
451
  slug: slugSchema.describe("ID (unique within plugin)")
166
452
  }).merge(
@@ -190,7 +476,7 @@ function getDuplicateSlugsInAudits(audits) {
190
476
  }
191
477
 
192
478
  // packages/models/src/lib/audit-output.ts
193
- import { z as z4 } from "zod";
479
+ import { z as z5 } from "zod";
194
480
 
195
481
  // packages/models/src/lib/issue.ts
196
482
  import { z as z3 } from "zod";
@@ -221,16 +507,61 @@ var issueSchema = z3.object(
221
507
  { description: "Issue information" }
222
508
  );
223
509
 
510
+ // packages/models/src/lib/table.ts
511
+ import { z as z4 } from "zod";
512
+ var tableAlignmentSchema = z4.enum(["left", "center", "right"], {
513
+ description: "Cell alignment"
514
+ });
515
+ var tableColumnObjectSchema = z4.object({
516
+ key: z4.string(),
517
+ label: z4.string().optional(),
518
+ align: tableAlignmentSchema.optional()
519
+ });
520
+ var tableRowObjectSchema = z4.record(primitiveValueSchema, {
521
+ description: "Object row"
522
+ });
523
+ var tableRowPrimitiveSchema = z4.array(primitiveValueSchema, {
524
+ description: "Primitive row"
525
+ });
526
+ var tableSharedSchema = z4.object({
527
+ title: z4.string().optional().describe("Display title for table")
528
+ });
529
+ var tablePrimitiveSchema = tableSharedSchema.merge(
530
+ z4.object(
531
+ {
532
+ columns: z4.array(tableAlignmentSchema).optional(),
533
+ rows: z4.array(tableRowPrimitiveSchema)
534
+ },
535
+ { description: "Table with primitive rows and optional alignment columns" }
536
+ )
537
+ );
538
+ var tableObjectSchema = tableSharedSchema.merge(
539
+ z4.object(
540
+ {
541
+ columns: z4.union([
542
+ z4.array(tableAlignmentSchema),
543
+ z4.array(tableColumnObjectSchema)
544
+ ]).optional(),
545
+ rows: z4.array(tableRowObjectSchema)
546
+ },
547
+ {
548
+ description: "Table with object rows and optional alignment or object columns"
549
+ }
550
+ )
551
+ );
552
+ var tableSchema = (description = "Table information") => z4.union([tablePrimitiveSchema, tableObjectSchema], { description });
553
+
224
554
  // packages/models/src/lib/audit-output.ts
225
555
  var auditValueSchema = nonnegativeIntSchema.describe("Raw numeric value");
226
- var auditDisplayValueSchema = z4.string({ description: "Formatted value (e.g. '0.9 s', '2.1 MB')" }).optional();
227
- var auditDetailsSchema = z4.object(
556
+ var auditDisplayValueSchema = z5.string({ description: "Formatted value (e.g. '0.9 s', '2.1 MB')" }).optional();
557
+ var auditDetailsSchema = z5.object(
228
558
  {
229
- issues: z4.array(issueSchema, { description: "List of findings" })
559
+ issues: z5.array(issueSchema, { description: "List of findings" }).optional(),
560
+ table: tableSchema("Table of related findings").optional()
230
561
  },
231
562
  { description: "Detailed information" }
232
563
  );
233
- var auditOutputSchema = z4.object(
564
+ var auditOutputSchema = z5.object(
234
565
  {
235
566
  slug: slugSchema.describe("Reference to audit"),
236
567
  displayValue: auditDisplayValueSchema,
@@ -240,7 +571,7 @@ var auditOutputSchema = z4.object(
240
571
  },
241
572
  { description: "Audit information" }
242
573
  );
243
- var auditOutputsSchema = z4.array(auditOutputSchema, {
574
+ var auditOutputsSchema = z5.array(auditOutputSchema, {
244
575
  description: "List of JSON formatted audit output emitted by the runner process of a plugin"
245
576
  }).refine(
246
577
  (audits) => !getDuplicateSlugsInAudits2(audits),
@@ -257,13 +588,13 @@ function getDuplicateSlugsInAudits2(audits) {
257
588
  }
258
589
 
259
590
  // packages/models/src/lib/category-config.ts
260
- import { z as z5 } from "zod";
591
+ import { z as z6 } from "zod";
261
592
  var categoryRefSchema = weightedRefSchema(
262
593
  "Weighted references to audits and/or groups for the category",
263
594
  "Slug of an audit or group (depending on `type`)"
264
595
  ).merge(
265
- z5.object({
266
- type: z5.enum(["audit", "group"], {
596
+ z6.object({
597
+ type: z6.enum(["audit", "group"], {
267
598
  description: "Discriminant for reference kind, affects where `slug` is looked up"
268
599
  }),
269
600
  plugin: slugSchema.describe(
@@ -284,8 +615,8 @@ var categoryConfigSchema = scorableSchema(
284
615
  description: "Meta info for category"
285
616
  })
286
617
  ).merge(
287
- z5.object({
288
- isBinary: z5.boolean({
618
+ z6.object({
619
+ isBinary: z6.boolean({
289
620
  description: 'Is this a binary category (i.e. only a perfect score considered a "pass")?'
290
621
  }).optional()
291
622
  })
@@ -301,7 +632,7 @@ function getDuplicateRefsInCategoryMetrics(metrics) {
301
632
  metrics.map(({ slug, type, plugin }) => `${type} :: ${plugin} / ${slug}`)
302
633
  );
303
634
  }
304
- var categoriesSchema = z5.array(categoryConfigSchema, {
635
+ var categoriesSchema = z6.array(categoryConfigSchema, {
305
636
  description: "Categorization of individual audits"
306
637
  }).refine(
307
638
  (categoryCfg) => !getDuplicateSlugCategories(categoryCfg),
@@ -320,18 +651,18 @@ function getDuplicateSlugCategories(categories) {
320
651
  }
321
652
 
322
653
  // packages/models/src/lib/commit.ts
323
- import { z as z6 } from "zod";
324
- var commitSchema = z6.object(
654
+ import { z as z7 } from "zod";
655
+ var commitSchema = z7.object(
325
656
  {
326
- hash: z6.string({ description: "Commit SHA (full)" }).regex(
657
+ hash: z7.string({ description: "Commit SHA (full)" }).regex(
327
658
  /^[\da-f]{40}$/,
328
659
  "Commit SHA should be a 40-character hexadecimal string"
329
660
  ),
330
- message: z6.string({ description: "Commit message" }),
331
- date: z6.coerce.date({
661
+ message: z7.string({ description: "Commit message" }),
662
+ date: z7.coerce.date({
332
663
  description: "Date and time when commit was authored"
333
664
  }),
334
- author: z6.string({
665
+ author: z7.string({
335
666
  description: "Commit author name"
336
667
  }).trim()
337
668
  },
@@ -339,22 +670,22 @@ var commitSchema = z6.object(
339
670
  );
340
671
 
341
672
  // packages/models/src/lib/core-config.ts
342
- import { z as z12 } from "zod";
673
+ import { z as z13 } from "zod";
343
674
 
344
675
  // packages/models/src/lib/persist-config.ts
345
- import { z as z7 } from "zod";
346
- var formatSchema = z7.enum(["json", "md"]);
347
- var persistConfigSchema = z7.object({
676
+ import { z as z8 } from "zod";
677
+ var formatSchema = z8.enum(["json", "md"]);
678
+ var persistConfigSchema = z8.object({
348
679
  outputDir: filePathSchema.describe("Artifacts folder").optional(),
349
680
  filename: fileNameSchema.describe("Artifacts file name (without extension)").optional(),
350
- format: z7.array(formatSchema).optional()
681
+ format: z8.array(formatSchema).optional()
351
682
  });
352
683
 
353
684
  // packages/models/src/lib/plugin-config.ts
354
- import { z as z10 } from "zod";
685
+ import { z as z11 } from "zod";
355
686
 
356
687
  // packages/models/src/lib/group.ts
357
- import { z as z8 } from "zod";
688
+ import { z as z9 } from "zod";
358
689
  var groupRefSchema = weightedRefSchema(
359
690
  "Weighted reference to a group",
360
691
  "Reference slug to a group within this plugin (e.g. 'max-lines')"
@@ -371,7 +702,7 @@ var groupSchema = scorableSchema(
371
702
  getDuplicateRefsInGroups,
372
703
  duplicateRefsInGroupsErrorMsg
373
704
  ).merge(groupMetaSchema);
374
- var groupsSchema = z8.array(groupSchema, {
705
+ var groupsSchema = z9.array(groupSchema, {
375
706
  description: "List of groups"
376
707
  }).optional().refine(
377
708
  (groups) => !getDuplicateSlugsInGroups(groups),
@@ -399,14 +730,14 @@ function getDuplicateSlugsInGroups(groups) {
399
730
  }
400
731
 
401
732
  // packages/models/src/lib/runner-config.ts
402
- import { z as z9 } from "zod";
403
- var outputTransformSchema = z9.function().args(z9.unknown()).returns(z9.union([auditOutputsSchema, z9.promise(auditOutputsSchema)]));
404
- var runnerConfigSchema = z9.object(
733
+ import { z as z10 } from "zod";
734
+ var outputTransformSchema = z10.function().args(z10.unknown()).returns(z10.union([auditOutputsSchema, z10.promise(auditOutputsSchema)]));
735
+ var runnerConfigSchema = z10.object(
405
736
  {
406
- command: z9.string({
737
+ command: z10.string({
407
738
  description: "Shell command to execute"
408
739
  }),
409
- args: z9.array(z9.string({ description: "Command arguments" })).optional(),
740
+ args: z10.array(z10.string({ description: "Command arguments" })).optional(),
410
741
  outputFile: filePathSchema.describe("Output path"),
411
742
  outputTransform: outputTransformSchema.optional()
412
743
  },
@@ -414,8 +745,8 @@ var runnerConfigSchema = z9.object(
414
745
  description: "How to execute runner"
415
746
  }
416
747
  );
417
- var onProgressSchema = z9.function().args(z9.unknown()).returns(z9.void());
418
- var runnerFunctionSchema = z9.function().args(onProgressSchema.optional()).returns(z9.union([auditOutputsSchema, z9.promise(auditOutputsSchema)]));
748
+ var onProgressSchema = z10.function().args(z10.unknown()).returns(z10.void());
749
+ var runnerFunctionSchema = z10.function().args(onProgressSchema.optional()).returns(z10.union([auditOutputsSchema, z10.promise(auditOutputsSchema)]));
419
750
 
420
751
  // packages/models/src/lib/plugin-config.ts
421
752
  var pluginMetaSchema = packageVersionSchema().merge(
@@ -426,13 +757,13 @@ var pluginMetaSchema = packageVersionSchema().merge(
426
757
  description: "Plugin metadata"
427
758
  })
428
759
  ).merge(
429
- z10.object({
760
+ z11.object({
430
761
  slug: slugSchema.describe("Unique plugin slug within core config"),
431
762
  icon: materialIconSchema
432
763
  })
433
764
  );
434
- var pluginDataSchema = z10.object({
435
- runner: z10.union([runnerConfigSchema, runnerFunctionSchema]),
765
+ var pluginDataSchema = z11.object({
766
+ runner: z11.union([runnerConfigSchema, runnerFunctionSchema]),
436
767
  audits: pluginAuditsSchema,
437
768
  groups: groupsSchema
438
769
  });
@@ -458,22 +789,22 @@ function getMissingRefsFromGroups(pluginCfg) {
458
789
  }
459
790
 
460
791
  // packages/models/src/lib/upload-config.ts
461
- import { z as z11 } from "zod";
462
- var uploadConfigSchema = z11.object({
792
+ import { z as z12 } from "zod";
793
+ var uploadConfigSchema = z12.object({
463
794
  server: urlSchema.describe("URL of deployed portal API"),
464
- apiKey: z11.string({
795
+ apiKey: z12.string({
465
796
  description: "API key with write access to portal (use `process.env` for security)"
466
797
  }),
467
798
  organization: slugSchema.describe(
468
799
  "Organization slug from Code PushUp portal"
469
800
  ),
470
801
  project: slugSchema.describe("Project slug from Code PushUp portal"),
471
- timeout: z11.number({ description: "Request timeout in minutes (default is 5)" }).positive().int().optional()
802
+ timeout: z12.number({ description: "Request timeout in minutes (default is 5)" }).positive().int().optional()
472
803
  });
473
804
 
474
805
  // packages/models/src/lib/core-config.ts
475
- var unrefinedCoreConfigSchema = z12.object({
476
- plugins: z12.array(pluginConfigSchema, {
806
+ var unrefinedCoreConfigSchema = z13.object({
807
+ plugins: z13.array(pluginConfigSchema, {
477
808
  description: "List of plugins to be used (official, community-provided, or custom)"
478
809
  }).min(1),
479
810
  /** portal configuration for persisting results */
@@ -496,7 +827,7 @@ function refineCoreConfig(schema) {
496
827
  }
497
828
 
498
829
  // packages/models/src/lib/report.ts
499
- import { z as z13 } from "zod";
830
+ import { z as z14 } from "zod";
500
831
  var auditReportSchema = auditSchema.merge(auditOutputSchema);
501
832
  var pluginReportSchema = pluginMetaSchema.merge(
502
833
  executionMetaSchema({
@@ -504,9 +835,9 @@ var pluginReportSchema = pluginMetaSchema.merge(
504
835
  descriptionDuration: "Duration of the plugin run in ms"
505
836
  })
506
837
  ).merge(
507
- z13.object({
508
- audits: z13.array(auditReportSchema).min(1),
509
- groups: z13.array(groupSchema).optional()
838
+ z14.object({
839
+ audits: z14.array(auditReportSchema).min(1),
840
+ groups: z14.array(groupSchema).optional()
510
841
  })
511
842
  ).refine(
512
843
  (pluginReport) => !getMissingRefsFromGroups2(pluginReport.audits, pluginReport.groups ?? []),
@@ -540,10 +871,10 @@ var reportSchema = packageVersionSchema({
540
871
  descriptionDuration: "Duration of the collect run in ms"
541
872
  })
542
873
  ).merge(
543
- z13.object(
874
+ z14.object(
544
875
  {
545
- categories: z13.array(categoryConfigSchema),
546
- plugins: z13.array(pluginReportSchema).min(1),
876
+ categories: z14.array(categoryConfigSchema),
877
+ plugins: z14.array(pluginReportSchema).min(1),
547
878
  commit: commitSchema.describe("Git commit for which report was collected").nullable()
548
879
  },
549
880
  { description: "Collect output data" }
@@ -559,40 +890,40 @@ var reportSchema = packageVersionSchema({
559
890
  );
560
891
 
561
892
  // packages/models/src/lib/reports-diff.ts
562
- import { z as z14 } from "zod";
893
+ import { z as z15 } from "zod";
563
894
  function makeComparisonSchema(schema) {
564
895
  const sharedDescription = schema.description || "Result";
565
- return z14.object({
896
+ return z15.object({
566
897
  before: schema.describe(`${sharedDescription} (source commit)`),
567
898
  after: schema.describe(`${sharedDescription} (target commit)`)
568
899
  });
569
900
  }
570
901
  function makeArraysComparisonSchema(diffSchema, resultSchema, description) {
571
- return z14.object(
902
+ return z15.object(
572
903
  {
573
- changed: z14.array(diffSchema),
574
- unchanged: z14.array(resultSchema),
575
- added: z14.array(resultSchema),
576
- removed: z14.array(resultSchema)
904
+ changed: z15.array(diffSchema),
905
+ unchanged: z15.array(resultSchema),
906
+ added: z15.array(resultSchema),
907
+ removed: z15.array(resultSchema)
577
908
  },
578
909
  { description }
579
910
  );
580
911
  }
581
- var scorableMetaSchema = z14.object({
912
+ var scorableMetaSchema = z15.object({
582
913
  slug: slugSchema,
583
914
  title: titleSchema,
584
915
  docsUrl: docsUrlSchema
585
916
  });
586
917
  var scorableWithPluginMetaSchema = scorableMetaSchema.merge(
587
- z14.object({
918
+ z15.object({
588
919
  plugin: pluginMetaSchema.pick({ slug: true, title: true, docsUrl: true }).describe("Plugin which defines it")
589
920
  })
590
921
  );
591
922
  var scorableDiffSchema = scorableMetaSchema.merge(
592
- z14.object({
923
+ z15.object({
593
924
  scores: makeComparisonSchema(scoreSchema).merge(
594
- z14.object({
595
- diff: z14.number().min(-1).max(1).describe("Score change (`scores.after - scores.before`)")
925
+ z15.object({
926
+ diff: z15.number().min(-1).max(1).describe("Score change (`scores.after - scores.before`)")
596
927
  })
597
928
  ).describe("Score comparison")
598
929
  })
@@ -603,10 +934,10 @@ var scorableWithPluginDiffSchema = scorableDiffSchema.merge(
603
934
  var categoryDiffSchema = scorableDiffSchema;
604
935
  var groupDiffSchema = scorableWithPluginDiffSchema;
605
936
  var auditDiffSchema = scorableWithPluginDiffSchema.merge(
606
- z14.object({
937
+ z15.object({
607
938
  values: makeComparisonSchema(auditValueSchema).merge(
608
- z14.object({
609
- diff: z14.number().int().describe("Value change (`values.after - values.before`)")
939
+ z15.object({
940
+ diff: z15.number().int().describe("Value change (`values.after - values.before`)")
610
941
  })
611
942
  ).describe("Audit `value` comparison"),
612
943
  displayValues: makeComparisonSchema(auditDisplayValueSchema).describe(
@@ -615,15 +946,15 @@ var auditDiffSchema = scorableWithPluginDiffSchema.merge(
615
946
  })
616
947
  );
617
948
  var categoryResultSchema = scorableMetaSchema.merge(
618
- z14.object({ score: scoreSchema })
949
+ z15.object({ score: scoreSchema })
619
950
  );
620
951
  var groupResultSchema = scorableWithPluginMetaSchema.merge(
621
- z14.object({ score: scoreSchema })
952
+ z15.object({ score: scoreSchema })
622
953
  );
623
954
  var auditResultSchema = scorableWithPluginMetaSchema.merge(
624
955
  auditOutputSchema.pick({ score: true, value: true, displayValue: true })
625
956
  );
626
- var reportsDiffSchema = z14.object({
957
+ var reportsDiffSchema = z15.object({
627
958
  commits: makeComparisonSchema(commitSchema).nullable().describe("Commits identifying compared reports"),
628
959
  categories: makeArraysComparisonSchema(
629
960
  categoryDiffSchema,
@@ -748,6 +1079,7 @@ function pluginWorkDir(slug) {
748
1079
  }
749
1080
 
750
1081
  // packages/utils/src/lib/reports/utils.ts
1082
+ var { image: image2, bold: boldMd } = md;
751
1083
  function calcDuration(start, stop) {
752
1084
  return Math.round((stop ?? performance.now()) - start);
753
1085
  }
@@ -791,13 +1123,13 @@ function executeProcess(cfg) {
791
1123
  process2.on("error", (err) => {
792
1124
  stderr += err.toString();
793
1125
  });
794
- process2.on("close", (code) => {
1126
+ process2.on("close", (code3) => {
795
1127
  const timings = { date, duration: calcDuration(start) };
796
- if (code === 0 || ignoreExitCode) {
1128
+ if (code3 === 0 || ignoreExitCode) {
797
1129
  onComplete?.();
798
- resolve({ code, stdout, stderr, ...timings });
1130
+ resolve({ code: code3, stdout, stderr, ...timings });
799
1131
  } else {
800
- const errorMsg = new ProcessError({ code, stdout, stderr, ...timings });
1132
+ const errorMsg = new ProcessError({ code: code3, stdout, stderr, ...timings });
801
1133
  onError?.(errorMsg);
802
1134
  reject(errorMsg);
803
1135
  }
@@ -805,30 +1137,42 @@ function executeProcess(cfg) {
805
1137
  });
806
1138
  }
807
1139
 
808
- // packages/utils/src/lib/git.ts
1140
+ // packages/utils/src/lib/git/git.ts
809
1141
  import { simpleGit } from "simple-git";
810
1142
 
811
- // packages/utils/src/lib/transform.ts
812
- function toArray(val) {
813
- return Array.isArray(val) ? val : [val];
814
- }
815
- function objectToEntries(obj) {
816
- return Object.entries(obj);
817
- }
818
- function countOccurrences(values) {
819
- return values.reduce(
820
- (acc, value) => ({ ...acc, [value]: (acc[value] ?? 0) + 1 }),
821
- {}
822
- );
823
- }
824
- function distinct(array) {
825
- return [...new Set(array)];
826
- }
1143
+ // packages/utils/src/lib/git/git.commits-and-tags.ts
1144
+ import { simpleGit as simpleGit2 } from "simple-git";
1145
+
1146
+ // packages/utils/src/lib/semver.ts
1147
+ import { rcompare, valid } from "semver";
827
1148
 
828
1149
  // packages/utils/src/lib/progress.ts
829
1150
  import chalk3 from "chalk";
830
1151
  import { MultiProgressBars } from "multi-progress-bars";
831
1152
 
1153
+ // packages/utils/src/lib/reports/formatting.ts
1154
+ var { headline: headline2, lines: lines2, link: link3, section: section2, table: table3 } = md;
1155
+
1156
+ // packages/utils/src/lib/reports/generate-md-report-categoy-section.ts
1157
+ var { link: link4, section: section3, h2: h22, lines: lines3, li: li2, bold: boldMd2, h3: h32, indentation: indentation2 } = md;
1158
+
1159
+ // packages/utils/src/lib/reports/generate-md-report.ts
1160
+ var { h1: h12, h2: h23, h3: h33, lines: lines4, link: link5, section: section4, code: codeMd } = md;
1161
+ var { bold: boldHtml, details: details2 } = html;
1162
+
1163
+ // packages/utils/src/lib/reports/generate-md-reports-diff.ts
1164
+ var {
1165
+ h1: h13,
1166
+ h2: h24,
1167
+ lines: lines5,
1168
+ link: link6,
1169
+ bold: boldMd3,
1170
+ italic: italicMd,
1171
+ table: table4,
1172
+ section: section5
1173
+ } = md;
1174
+ var { details: details3 } = html;
1175
+
832
1176
  // packages/utils/src/lib/reports/log-stdout-summary.ts
833
1177
  import chalk4 from "chalk";
834
1178