@code-pushup/core 0.7.0 → 0.8.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 (2) hide show
  1. package/index.js +166 -153
  2. package/package.json +1 -1
package/index.js CHANGED
@@ -9,7 +9,7 @@ import { spawn } from "child_process";
9
9
  // packages/utils/src/lib/report.ts
10
10
  import { join } from "path";
11
11
 
12
- // packages/models/src/lib/category-config.ts
12
+ // packages/models/src/lib/audit.ts
13
13
  import { z as z2 } from "zod";
14
14
 
15
15
  // packages/models/src/lib/implementation/schemas.ts
@@ -149,13 +149,107 @@ function hasWeightedRefsInCategories(categoryRefs) {
149
149
  return categoryRefs.reduce((acc, { weight }) => weight + acc, 0) !== 0;
150
150
  }
151
151
 
152
+ // packages/models/src/lib/audit.ts
153
+ var auditSchema = z2.object({
154
+ slug: slugSchema("ID (unique within plugin)")
155
+ }).merge(
156
+ metaSchema({
157
+ titleDescription: "Descriptive name",
158
+ descriptionDescription: "Description (markdown)",
159
+ docsUrlDescription: "Link to documentation (rationale)",
160
+ description: "List of scorable metrics for the given plugin"
161
+ })
162
+ );
163
+ var pluginAuditsSchema = z2.array(auditSchema, {
164
+ description: "List of audits maintained in a plugin"
165
+ }).refine(
166
+ (auditMetadata) => !getDuplicateSlugsInAudits(auditMetadata),
167
+ (auditMetadata) => ({
168
+ message: duplicateSlugsInAuditsErrorMsg(auditMetadata)
169
+ })
170
+ );
171
+ function duplicateSlugsInAuditsErrorMsg(audits) {
172
+ const duplicateRefs = getDuplicateSlugsInAudits(audits);
173
+ return `In plugin audits the slugs are not unique: ${errorItems(
174
+ duplicateRefs
175
+ )}`;
176
+ }
177
+ function getDuplicateSlugsInAudits(audits) {
178
+ return hasDuplicateStrings(audits.map(({ slug }) => slug));
179
+ }
180
+
181
+ // packages/models/src/lib/audit-issue.ts
182
+ import { z as z3 } from "zod";
183
+ var sourceFileLocationSchema = z3.object(
184
+ {
185
+ file: filePathSchema("Relative path to source file in Git repo"),
186
+ position: z3.object(
187
+ {
188
+ startLine: positiveIntSchema("Start line"),
189
+ startColumn: positiveIntSchema("Start column").optional(),
190
+ endLine: positiveIntSchema("End line").optional(),
191
+ endColumn: positiveIntSchema("End column").optional()
192
+ },
193
+ { description: "Location in file" }
194
+ ).optional()
195
+ },
196
+ { description: "Source file location" }
197
+ );
198
+ var issueSeveritySchema = z3.enum(["info", "warning", "error"], {
199
+ description: "Severity level"
200
+ });
201
+ var issueSchema = z3.object(
202
+ {
203
+ message: z3.string({ description: "Descriptive error message" }).max(512),
204
+ severity: issueSeveritySchema,
205
+ source: sourceFileLocationSchema.optional()
206
+ },
207
+ { description: "Issue information" }
208
+ );
209
+
210
+ // packages/models/src/lib/audit-output.ts
211
+ import { z as z4 } from "zod";
212
+ var auditOutputSchema = z4.object(
213
+ {
214
+ slug: slugSchema("Reference to audit"),
215
+ displayValue: z4.string({ description: "Formatted value (e.g. '0.9 s', '2.1 MB')" }).optional(),
216
+ value: positiveIntSchema("Raw numeric value"),
217
+ score: z4.number({
218
+ description: "Value between 0 and 1"
219
+ }).min(0).max(1),
220
+ details: z4.object(
221
+ {
222
+ issues: z4.array(issueSchema, { description: "List of findings" })
223
+ },
224
+ { description: "Detailed information" }
225
+ ).optional()
226
+ },
227
+ { description: "Audit information" }
228
+ );
229
+ var auditOutputsSchema = z4.array(auditOutputSchema, {
230
+ description: "List of JSON formatted audit output emitted by the runner process of a plugin"
231
+ }).refine(
232
+ (audits) => !getDuplicateSlugsInAudits2(audits),
233
+ (audits) => ({ message: duplicateSlugsInAuditsErrorMsg2(audits) })
234
+ );
235
+ function duplicateSlugsInAuditsErrorMsg2(audits) {
236
+ const duplicateRefs = getDuplicateSlugsInAudits2(audits);
237
+ return `In plugin audits the slugs are not unique: ${errorItems(
238
+ duplicateRefs
239
+ )}`;
240
+ }
241
+ function getDuplicateSlugsInAudits2(audits) {
242
+ return hasDuplicateStrings(audits.map(({ slug }) => slug));
243
+ }
244
+
152
245
  // packages/models/src/lib/category-config.ts
246
+ import { z as z5 } from "zod";
153
247
  var categoryRefSchema = weightedRefSchema(
154
248
  "Weighted references to audits and/or groups for the category",
155
249
  "Slug of an audit or group (depending on `type`)"
156
250
  ).merge(
157
- z2.object({
158
- type: z2.enum(["audit", "group"], {
251
+ z5.object({
252
+ type: z5.enum(["audit", "group"], {
159
253
  description: "Discriminant for reference kind, affects where `slug` is looked up"
160
254
  }),
161
255
  plugin: slugSchema(
@@ -176,8 +270,8 @@ var categoryConfigSchema = scorableSchema(
176
270
  description: "Meta info for category"
177
271
  })
178
272
  ).merge(
179
- z2.object({
180
- isBinary: z2.boolean({
273
+ z5.object({
274
+ isBinary: z5.boolean({
181
275
  description: 'Is this a binary category (i.e. only a perfect score considered a "pass")?'
182
276
  }).optional()
183
277
  })
@@ -193,7 +287,7 @@ function getDuplicateRefsInCategoryMetrics(metrics) {
193
287
  metrics.map(({ slug, type, plugin }) => `${type} :: ${plugin} / ${slug}`)
194
288
  );
195
289
  }
196
- var categoriesSchema = z2.array(categoryConfigSchema, {
290
+ var categoriesSchema = z5.array(categoryConfigSchema, {
197
291
  description: "Categorization of individual audits"
198
292
  }).min(1).refine(
199
293
  (categoryCfg) => !getDuplicateSlugCategories(categoryCfg),
@@ -215,68 +309,38 @@ function getDuplicateSlugCategories(categories) {
215
309
  import { z as z11 } from "zod";
216
310
 
217
311
  // packages/models/src/lib/persist-config.ts
218
- import { z as z3 } from "zod";
219
- var formatSchema = z3.enum(["json", "md"]);
220
- var persistConfigSchema = z3.object({
312
+ import { z as z6 } from "zod";
313
+ var formatSchema = z6.enum(["json", "md"]);
314
+ var persistConfigSchema = z6.object({
221
315
  outputDir: filePathSchema("Artifacts folder").optional(),
222
316
  filename: fileNameSchema(
223
317
  "Artifacts file name (without extension)"
224
318
  ).optional(),
225
- format: z3.array(formatSchema).optional()
319
+ format: z6.array(formatSchema).optional()
226
320
  });
227
321
 
228
322
  // packages/models/src/lib/plugin-config.ts
229
323
  import { z as z9 } from "zod";
230
324
 
231
- // packages/models/src/lib/plugin-config-audits.ts
232
- import { z as z4 } from "zod";
233
- var auditSchema = z4.object({
234
- slug: slugSchema("ID (unique within plugin)")
235
- }).merge(
236
- metaSchema({
237
- titleDescription: "Descriptive name",
238
- descriptionDescription: "Description (markdown)",
239
- docsUrlDescription: "Link to documentation (rationale)",
240
- description: "List of scorable metrics for the given plugin"
241
- })
242
- );
243
- var pluginAuditsSchema = z4.array(auditSchema, {
244
- description: "List of audits maintained in a plugin"
245
- }).refine(
246
- (auditMetadata) => !getDuplicateSlugsInAudits(auditMetadata),
247
- (auditMetadata) => ({
248
- message: duplicateSlugsInAuditsErrorMsg(auditMetadata)
249
- })
250
- );
251
- function duplicateSlugsInAuditsErrorMsg(audits) {
252
- const duplicateRefs = getDuplicateSlugsInAudits(audits);
253
- return `In plugin audits the slugs are not unique: ${errorItems(
254
- duplicateRefs
255
- )}`;
256
- }
257
- function getDuplicateSlugsInAudits(audits) {
258
- return hasDuplicateStrings(audits.map(({ slug }) => slug));
259
- }
260
-
261
- // packages/models/src/lib/plugin-config-groups.ts
262
- import { z as z5 } from "zod";
263
- var auditGroupRefSchema = weightedRefSchema(
264
- "Weighted references to audits",
265
- "Reference slug to an audit within this plugin (e.g. 'max-lines')"
325
+ // packages/models/src/lib/group.ts
326
+ import { z as z7 } from "zod";
327
+ var groupRefSchema = weightedRefSchema(
328
+ "Weighted reference to a group",
329
+ "Reference slug to a group within this plugin (e.g. 'max-lines')"
266
330
  );
267
- var auditGroupMetaSchema = metaSchema({
331
+ var groupMetaSchema = metaSchema({
268
332
  titleDescription: "Descriptive name for the group",
269
333
  descriptionDescription: "Description of the group (markdown)",
270
334
  docsUrlDescription: "Group documentation site",
271
335
  description: "Group metadata"
272
336
  });
273
- var auditGroupSchema = scorableSchema(
274
- 'An audit group aggregates a set of audits into a single score which can be referenced from a category. E.g. the group slug "performance" groups audits and can be referenced in a category',
275
- auditGroupRefSchema,
337
+ var groupSchema = scorableSchema(
338
+ 'A group aggregates a set of audits into a single score which can be referenced from a category. E.g. the group slug "performance" groups audits and can be referenced in a category',
339
+ groupRefSchema,
276
340
  getDuplicateRefsInGroups,
277
341
  duplicateRefsInGroupsErrorMsg
278
- ).merge(auditGroupMetaSchema);
279
- var auditGroupsSchema = z5.array(auditGroupSchema, {
342
+ ).merge(groupMetaSchema);
343
+ var groupsSchema = z7.array(groupSchema, {
280
344
  description: "List of groups"
281
345
  }).optional().refine(
282
346
  (groups) => !getDuplicateSlugsInGroups(groups),
@@ -284,16 +348,14 @@ var auditGroupsSchema = z5.array(auditGroupSchema, {
284
348
  message: duplicateSlugsInGroupsErrorMsg(groups)
285
349
  })
286
350
  );
287
- function duplicateRefsInGroupsErrorMsg(groupAudits) {
288
- const duplicateRefs = getDuplicateRefsInGroups(groupAudits);
289
- return `In plugin groups the audit refs are not unique: ${errorItems(
351
+ function duplicateRefsInGroupsErrorMsg(groups) {
352
+ const duplicateRefs = getDuplicateRefsInGroups(groups);
353
+ return `In plugin groups the following references are not unique: ${errorItems(
290
354
  duplicateRefs
291
355
  )}`;
292
356
  }
293
- function getDuplicateRefsInGroups(groupAudits) {
294
- return hasDuplicateStrings(
295
- groupAudits.map(({ slug: ref }) => ref).filter(exists)
296
- );
357
+ function getDuplicateRefsInGroups(groups) {
358
+ return hasDuplicateStrings(groups.map(({ slug: ref }) => ref).filter(exists));
297
359
  }
298
360
  function duplicateSlugsInGroupsErrorMsg(groups) {
299
361
  const duplicateRefs = getDuplicateSlugsInGroups(groups);
@@ -303,76 +365,8 @@ function getDuplicateSlugsInGroups(groups) {
303
365
  return Array.isArray(groups) ? hasDuplicateStrings(groups.map(({ slug }) => slug)) : false;
304
366
  }
305
367
 
306
- // packages/models/src/lib/plugin-config-runner.ts
368
+ // packages/models/src/lib/runner-config.ts
307
369
  import { z as z8 } from "zod";
308
-
309
- // packages/models/src/lib/plugin-process-output.ts
310
- import { z as z7 } from "zod";
311
-
312
- // packages/models/src/lib/plugin-process-output-audit-issue.ts
313
- import { z as z6 } from "zod";
314
- var sourceFileLocationSchema = z6.object(
315
- {
316
- file: filePathSchema("Relative path to source file in Git repo"),
317
- position: z6.object(
318
- {
319
- startLine: positiveIntSchema("Start line"),
320
- startColumn: positiveIntSchema("Start column").optional(),
321
- endLine: positiveIntSchema("End line").optional(),
322
- endColumn: positiveIntSchema("End column").optional()
323
- },
324
- { description: "Location in file" }
325
- ).optional()
326
- },
327
- { description: "Source file location" }
328
- );
329
- var issueSeveritySchema = z6.enum(["info", "warning", "error"], {
330
- description: "Severity level"
331
- });
332
- var issueSchema = z6.object(
333
- {
334
- message: z6.string({ description: "Descriptive error message" }).max(512),
335
- severity: issueSeveritySchema,
336
- source: sourceFileLocationSchema.optional()
337
- },
338
- { description: "Issue information" }
339
- );
340
-
341
- // packages/models/src/lib/plugin-process-output.ts
342
- var auditOutputSchema = z7.object(
343
- {
344
- slug: slugSchema("Reference to audit"),
345
- displayValue: z7.string({ description: "Formatted value (e.g. '0.9 s', '2.1 MB')" }).optional(),
346
- value: positiveIntSchema("Raw numeric value"),
347
- score: z7.number({
348
- description: "Value between 0 and 1"
349
- }).min(0).max(1),
350
- details: z7.object(
351
- {
352
- issues: z7.array(issueSchema, { description: "List of findings" })
353
- },
354
- { description: "Detailed information" }
355
- ).optional()
356
- },
357
- { description: "Audit information" }
358
- );
359
- var auditOutputsSchema = z7.array(auditOutputSchema, {
360
- description: "List of JSON formatted audit output emitted by the runner process of a plugin"
361
- }).refine(
362
- (audits) => !getDuplicateSlugsInAudits2(audits),
363
- (audits) => ({ message: duplicateSlugsInAuditsErrorMsg2(audits) })
364
- );
365
- function duplicateSlugsInAuditsErrorMsg2(audits) {
366
- const duplicateRefs = getDuplicateSlugsInAudits2(audits);
367
- return `In plugin audits the slugs are not unique: ${errorItems(
368
- duplicateRefs
369
- )}`;
370
- }
371
- function getDuplicateSlugsInAudits2(audits) {
372
- return hasDuplicateStrings(audits.map(({ slug }) => slug));
373
- }
374
-
375
- // packages/models/src/lib/plugin-config-runner.ts
376
370
  var outputTransformSchema = z8.function().args(z8.unknown()).returns(z8.union([auditOutputsSchema, z8.promise(auditOutputsSchema)]));
377
371
  var runnerConfigSchema = z8.object(
378
372
  {
@@ -409,7 +403,7 @@ var pluginMetaSchema = packageVersionSchema({
409
403
  var pluginDataSchema = z9.object({
410
404
  runner: z9.union([runnerConfigSchema, runnerFunctionSchema]),
411
405
  audits: pluginAuditsSchema,
412
- groups: auditGroupsSchema
406
+ groups: groupsSchema
413
407
  });
414
408
  var pluginConfigSchema = pluginMetaSchema.merge(pluginDataSchema).refine(
415
409
  (pluginCfg) => !getMissingRefsFromGroups(pluginCfg),
@@ -527,7 +521,7 @@ var pluginReportSchema = pluginMetaSchema.merge(
527
521
  ).merge(
528
522
  z12.object({
529
523
  audits: z12.array(auditReportSchema),
530
- groups: z12.array(auditGroupSchema).optional()
524
+ groups: z12.array(groupSchema).optional()
531
525
  })
532
526
  );
533
527
  var reportSchema = packageVersionSchema({
@@ -744,25 +738,28 @@ function calcDuration(start, stop) {
744
738
  return Math.floor(stop - start);
745
739
  }
746
740
  function countCategoryAudits(refs, plugins) {
747
- const groupLookup = plugins.reduce((lookup, plugin) => {
748
- if (!plugin.groups.length) {
749
- return lookup;
750
- }
751
- return {
752
- ...lookup,
753
- [plugin.slug]: {
754
- ...plugin.groups.reduce(
755
- (groupLookup2, group) => {
756
- return {
757
- ...groupLookup2,
758
- [group.slug]: group
759
- };
760
- },
761
- {}
762
- )
741
+ const groupLookup = plugins.reduce(
742
+ (lookup, plugin) => {
743
+ if (!plugin.groups.length) {
744
+ return lookup;
763
745
  }
764
- };
765
- }, {});
746
+ return {
747
+ ...lookup,
748
+ [plugin.slug]: {
749
+ ...plugin.groups.reduce(
750
+ (groupLookup2, group) => {
751
+ return {
752
+ ...groupLookup2,
753
+ [group.slug]: group
754
+ };
755
+ },
756
+ {}
757
+ )
758
+ }
759
+ };
760
+ },
761
+ {}
762
+ );
766
763
  return refs.reduce((acc, ref) => {
767
764
  if (ref.type === "group") {
768
765
  const groupRefs = groupLookup[ref.plugin]?.[ref.slug]?.refs;
@@ -1448,6 +1445,22 @@ var verboseUtils = (verbose) => ({
1448
1445
  exec: getExecVerbose(verbose)
1449
1446
  });
1450
1447
 
1448
+ // packages/utils/src/lib/group-by-status.ts
1449
+ function groupByStatus(results) {
1450
+ return results.reduce(
1451
+ (acc, result) => {
1452
+ if (result.status === "fulfilled") {
1453
+ return { ...acc, fulfilled: [...acc.fulfilled, result] };
1454
+ }
1455
+ if (result.status === "rejected") {
1456
+ return { ...acc, rejected: [...acc.rejected, result] };
1457
+ }
1458
+ return acc;
1459
+ },
1460
+ { fulfilled: [], rejected: [] }
1461
+ );
1462
+ }
1463
+
1451
1464
  // packages/core/src/lib/implementation/persist.ts
1452
1465
  var PersistDirError = class extends Error {
1453
1466
  constructor(outputDir) {
@@ -1598,14 +1611,14 @@ async function executePlugins(plugins, options) {
1598
1611
  const errorsCallback = ({ reason }) => console.error(reason);
1599
1612
  const results = await Promise.allSettled(pluginsResult);
1600
1613
  logMultipleResults(results, "Plugins", void 0, errorsCallback);
1601
- const failedResults = results.filter(isPromiseRejectedResult);
1602
- if (failedResults.length) {
1603
- const errorMessages = failedResults.map(({ reason }) => reason).join(", ");
1614
+ const { fulfilled, rejected } = groupByStatus(results);
1615
+ if (rejected.length) {
1616
+ const errorMessages = rejected.map(({ reason }) => reason).join(", ");
1604
1617
  throw new Error(
1605
- `Plugins failed: ${failedResults.length} errors: ${errorMessages}`
1618
+ `Plugins failed: ${rejected.length} errors: ${errorMessages}`
1606
1619
  );
1607
1620
  }
1608
- return results.filter(isPromiseFulfilledResult).map((result) => result.value);
1621
+ return fulfilled.map((result) => result.value);
1609
1622
  }
1610
1623
  function auditOutputsCorrelateWithPluginOutput(auditOutputs, pluginConfigAudits) {
1611
1624
  auditOutputs.forEach((auditOutput) => {
@@ -1620,7 +1633,7 @@ function auditOutputsCorrelateWithPluginOutput(auditOutputs, pluginConfigAudits)
1620
1633
 
1621
1634
  // packages/core/package.json
1622
1635
  var name = "@code-pushup/core";
1623
- var version = "0.7.0";
1636
+ var version = "0.8.1";
1624
1637
 
1625
1638
  // packages/core/src/lib/implementation/collect.ts
1626
1639
  async function collect(options) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@code-pushup/core",
3
- "version": "0.7.0",
3
+ "version": "0.8.1",
4
4
  "dependencies": {
5
5
  "@code-pushup/models": "*",
6
6
  "@code-pushup/utils": "*",