@code-pushup/utils 0.1.1 → 0.3.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/index.js +96 -66
- package/package.json +1 -1
- package/src/index.d.ts +6 -6
- package/src/lib/file-system.d.ts +3 -2
- package/src/lib/formatting.d.ts +3 -0
package/index.js
CHANGED
|
@@ -11,6 +11,11 @@ import { z as z2 } from "zod";
|
|
|
11
11
|
import { z } from "zod";
|
|
12
12
|
import { MATERIAL_ICONS } from "@code-pushup/portal-client";
|
|
13
13
|
|
|
14
|
+
// packages/models/src/lib/implementation/limits.ts
|
|
15
|
+
var MAX_SLUG_LENGTH = 128;
|
|
16
|
+
var MAX_TITLE_LENGTH = 256;
|
|
17
|
+
var MAX_DESCRIPTION_LENGTH = 65536;
|
|
18
|
+
|
|
14
19
|
// packages/models/src/lib/implementation/utils.ts
|
|
15
20
|
var slugRegex = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
|
|
16
21
|
var filenameRegex = /^(?!.*[ \\/:*?"<>|]).+$/;
|
|
@@ -46,12 +51,12 @@ function executionMetaSchema(options = {
|
|
|
46
51
|
function slugSchema(description = "Unique ID (human-readable, URL-safe)") {
|
|
47
52
|
return z.string({ description }).regex(slugRegex, {
|
|
48
53
|
message: "The slug has to follow the pattern [0-9a-z] followed by multiple optional groups of -[0-9a-z]. e.g. my-slug"
|
|
49
|
-
}).max(
|
|
50
|
-
message:
|
|
54
|
+
}).max(MAX_SLUG_LENGTH, {
|
|
55
|
+
message: `slug can be max ${MAX_SLUG_LENGTH} characters long`
|
|
51
56
|
});
|
|
52
57
|
}
|
|
53
58
|
function descriptionSchema(description = "Description (markdown)") {
|
|
54
|
-
return z.string({ description }).max(
|
|
59
|
+
return z.string({ description }).max(MAX_DESCRIPTION_LENGTH).optional();
|
|
55
60
|
}
|
|
56
61
|
function docsUrlSchema(description = "Documentation site") {
|
|
57
62
|
return urlSchema(description).optional().or(z.string().max(0));
|
|
@@ -60,7 +65,7 @@ function urlSchema(description) {
|
|
|
60
65
|
return z.string({ description }).url();
|
|
61
66
|
}
|
|
62
67
|
function titleSchema(description = "Descriptive name") {
|
|
63
|
-
return z.string({ description }).max(
|
|
68
|
+
return z.string({ description }).max(MAX_TITLE_LENGTH);
|
|
64
69
|
}
|
|
65
70
|
function metaSchema(options) {
|
|
66
71
|
const {
|
|
@@ -566,6 +571,19 @@ function formatDuration(duration) {
|
|
|
566
571
|
}
|
|
567
572
|
return `${(duration / 1e3).toFixed(2)} s`;
|
|
568
573
|
}
|
|
574
|
+
function truncateText(text, maxChars) {
|
|
575
|
+
if (text.length <= maxChars) {
|
|
576
|
+
return text;
|
|
577
|
+
}
|
|
578
|
+
const ellipsis = "...";
|
|
579
|
+
return text.slice(0, maxChars - ellipsis.length) + ellipsis;
|
|
580
|
+
}
|
|
581
|
+
function truncateTitle(text) {
|
|
582
|
+
return truncateText(text, MAX_TITLE_LENGTH);
|
|
583
|
+
}
|
|
584
|
+
function truncateDescription(text) {
|
|
585
|
+
return truncateText(text, MAX_DESCRIPTION_LENGTH);
|
|
586
|
+
}
|
|
569
587
|
|
|
570
588
|
// packages/utils/src/lib/guards.ts
|
|
571
589
|
function isPromiseFulfilledResult(result) {
|
|
@@ -606,6 +624,22 @@ function logPromiseResults(results, logMessage, callback) {
|
|
|
606
624
|
}
|
|
607
625
|
|
|
608
626
|
// packages/utils/src/lib/file-system.ts
|
|
627
|
+
async function readTextFile(path) {
|
|
628
|
+
const buffer = await readFile(path);
|
|
629
|
+
return buffer.toString();
|
|
630
|
+
}
|
|
631
|
+
async function readJsonFile(path) {
|
|
632
|
+
const text = await readTextFile(path);
|
|
633
|
+
return JSON.parse(text);
|
|
634
|
+
}
|
|
635
|
+
async function fileExists(path) {
|
|
636
|
+
try {
|
|
637
|
+
const stats = await stat(path);
|
|
638
|
+
return stats.isFile();
|
|
639
|
+
} catch {
|
|
640
|
+
return false;
|
|
641
|
+
}
|
|
642
|
+
}
|
|
609
643
|
function toUnixPath(path, options) {
|
|
610
644
|
const unixPath = path.replace(/\\/g, "/");
|
|
611
645
|
if (options?.toRelative) {
|
|
@@ -624,14 +658,6 @@ async function ensureDirectoryExists(baseDir) {
|
|
|
624
658
|
}
|
|
625
659
|
}
|
|
626
660
|
}
|
|
627
|
-
async function readTextFile(path) {
|
|
628
|
-
const buffer = await readFile(path);
|
|
629
|
-
return buffer.toString();
|
|
630
|
-
}
|
|
631
|
-
async function readJsonFile(path) {
|
|
632
|
-
const text = await readTextFile(path);
|
|
633
|
-
return JSON.parse(text);
|
|
634
|
-
}
|
|
635
661
|
function logMultipleFileResults(fileResults, messagePrefix) {
|
|
636
662
|
const succeededCallback = (result) => {
|
|
637
663
|
const [fileName, size] = result.value;
|
|
@@ -968,60 +994,6 @@ async function getLatestCommit() {
|
|
|
968
994
|
return log?.latest;
|
|
969
995
|
}
|
|
970
996
|
|
|
971
|
-
// packages/utils/src/lib/progress.ts
|
|
972
|
-
import chalk2 from "chalk";
|
|
973
|
-
import { MultiProgressBars } from "multi-progress-bars";
|
|
974
|
-
var barStyles = {
|
|
975
|
-
active: (s) => chalk2.green(s),
|
|
976
|
-
done: (s) => chalk2.gray(s),
|
|
977
|
-
idle: (s) => chalk2.gray(s)
|
|
978
|
-
};
|
|
979
|
-
var messageStyles = {
|
|
980
|
-
active: (s) => chalk2.black(s),
|
|
981
|
-
done: (s) => chalk2.green(chalk2.bold(s)),
|
|
982
|
-
idle: (s) => chalk2.gray(s)
|
|
983
|
-
};
|
|
984
|
-
var mpb;
|
|
985
|
-
function getSingletonProgressBars(options) {
|
|
986
|
-
if (!mpb) {
|
|
987
|
-
mpb = new MultiProgressBars({
|
|
988
|
-
initMessage: "",
|
|
989
|
-
border: true,
|
|
990
|
-
...options
|
|
991
|
-
});
|
|
992
|
-
}
|
|
993
|
-
return mpb;
|
|
994
|
-
}
|
|
995
|
-
function getProgressBar(taskName) {
|
|
996
|
-
const tasks = getSingletonProgressBars();
|
|
997
|
-
tasks.addTask(taskName, {
|
|
998
|
-
type: "percentage",
|
|
999
|
-
percentage: 0,
|
|
1000
|
-
message: "",
|
|
1001
|
-
barTransformFn: barStyles.idle
|
|
1002
|
-
});
|
|
1003
|
-
return {
|
|
1004
|
-
incrementInSteps: (numPlugins) => {
|
|
1005
|
-
tasks.incrementTask(taskName, {
|
|
1006
|
-
percentage: 1 / numPlugins,
|
|
1007
|
-
barTransformFn: barStyles.active
|
|
1008
|
-
});
|
|
1009
|
-
},
|
|
1010
|
-
updateTitle: (title) => {
|
|
1011
|
-
tasks.updateTask(taskName, {
|
|
1012
|
-
message: title,
|
|
1013
|
-
barTransformFn: barStyles.active
|
|
1014
|
-
});
|
|
1015
|
-
},
|
|
1016
|
-
endProgress: (message = "") => {
|
|
1017
|
-
tasks.done(taskName, {
|
|
1018
|
-
message: messageStyles.done(message),
|
|
1019
|
-
barTransformFn: barStyles.done
|
|
1020
|
-
});
|
|
1021
|
-
}
|
|
1022
|
-
};
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
997
|
// packages/utils/src/lib/md/details.ts
|
|
1026
998
|
function details(title, content, cfg = { open: false }) {
|
|
1027
999
|
return `<details${cfg.open ? " open" : ""}>
|
|
@@ -1099,6 +1071,60 @@ function li(text, order = "unordered") {
|
|
|
1099
1071
|
return `${style2} ${text}`;
|
|
1100
1072
|
}
|
|
1101
1073
|
|
|
1074
|
+
// packages/utils/src/lib/progress.ts
|
|
1075
|
+
import chalk2 from "chalk";
|
|
1076
|
+
import { MultiProgressBars } from "multi-progress-bars";
|
|
1077
|
+
var barStyles = {
|
|
1078
|
+
active: (s) => chalk2.green(s),
|
|
1079
|
+
done: (s) => chalk2.gray(s),
|
|
1080
|
+
idle: (s) => chalk2.gray(s)
|
|
1081
|
+
};
|
|
1082
|
+
var messageStyles = {
|
|
1083
|
+
active: (s) => chalk2.black(s),
|
|
1084
|
+
done: (s) => chalk2.green(chalk2.bold(s)),
|
|
1085
|
+
idle: (s) => chalk2.gray(s)
|
|
1086
|
+
};
|
|
1087
|
+
var mpb;
|
|
1088
|
+
function getSingletonProgressBars(options) {
|
|
1089
|
+
if (!mpb) {
|
|
1090
|
+
mpb = new MultiProgressBars({
|
|
1091
|
+
initMessage: "",
|
|
1092
|
+
border: true,
|
|
1093
|
+
...options
|
|
1094
|
+
});
|
|
1095
|
+
}
|
|
1096
|
+
return mpb;
|
|
1097
|
+
}
|
|
1098
|
+
function getProgressBar(taskName) {
|
|
1099
|
+
const tasks = getSingletonProgressBars();
|
|
1100
|
+
tasks.addTask(taskName, {
|
|
1101
|
+
type: "percentage",
|
|
1102
|
+
percentage: 0,
|
|
1103
|
+
message: "",
|
|
1104
|
+
barTransformFn: barStyles.idle
|
|
1105
|
+
});
|
|
1106
|
+
return {
|
|
1107
|
+
incrementInSteps: (numPlugins) => {
|
|
1108
|
+
tasks.incrementTask(taskName, {
|
|
1109
|
+
percentage: 1 / numPlugins,
|
|
1110
|
+
barTransformFn: barStyles.active
|
|
1111
|
+
});
|
|
1112
|
+
},
|
|
1113
|
+
updateTitle: (title) => {
|
|
1114
|
+
tasks.updateTask(taskName, {
|
|
1115
|
+
message: title,
|
|
1116
|
+
barTransformFn: barStyles.active
|
|
1117
|
+
});
|
|
1118
|
+
},
|
|
1119
|
+
endProgress: (message = "") => {
|
|
1120
|
+
tasks.done(taskName, {
|
|
1121
|
+
message: messageStyles.done(message),
|
|
1122
|
+
barTransformFn: barStyles.done
|
|
1123
|
+
});
|
|
1124
|
+
}
|
|
1125
|
+
};
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1102
1128
|
// packages/utils/src/lib/report-to-md.ts
|
|
1103
1129
|
function reportToMd(report, commitData) {
|
|
1104
1130
|
let md = reportToHeaderSection() + NEW_LINE;
|
|
@@ -1509,6 +1535,7 @@ export {
|
|
|
1509
1535
|
ensureDirectoryExists,
|
|
1510
1536
|
executeProcess,
|
|
1511
1537
|
factorOf,
|
|
1538
|
+
fileExists,
|
|
1512
1539
|
findLineNumberInText,
|
|
1513
1540
|
formatBytes,
|
|
1514
1541
|
formatDuration,
|
|
@@ -1535,5 +1562,8 @@ export {
|
|
|
1535
1562
|
slugify,
|
|
1536
1563
|
toArray,
|
|
1537
1564
|
toUnixPath,
|
|
1565
|
+
truncateDescription,
|
|
1566
|
+
truncateText,
|
|
1567
|
+
truncateTitle,
|
|
1538
1568
|
verboseUtils
|
|
1539
1569
|
};
|
package/package.json
CHANGED
package/src/index.d.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
export { CliArgsObject, ProcessConfig, ProcessError, ProcessObserver, ProcessResult, executeProcess, objectToCliArgs, } from './lib/execute-process';
|
|
2
|
+
export { FileResult, MultipleFileResults, crawlFileSystem, ensureDirectoryExists, fileExists, findLineNumberInText, importEsmModule, logMultipleFileResults, pluginWorkDir, readJsonFile, readTextFile, toUnixPath, } from './lib/file-system';
|
|
3
|
+
export { formatBytes, formatDuration, pluralize, pluralizeToken, slugify, truncateDescription, truncateText, truncateTitle, } from './lib/formatting';
|
|
2
4
|
export { getLatestCommit, git } from './lib/git';
|
|
5
|
+
export { isPromiseFulfilledResult, isPromiseRejectedResult, } from './lib/guards';
|
|
6
|
+
export { logMultipleResults } from './lib/log-results';
|
|
7
|
+
export { NEW_LINE } from './lib/md';
|
|
3
8
|
export { ProgressBar, getProgressBar } from './lib/progress';
|
|
4
9
|
export { CODE_PUSHUP_DOMAIN, FOOTER_PREFIX, README_LINK, calcDuration, compareIssueSeverity, loadReport, } from './lib/report';
|
|
5
10
|
export { reportToMd } from './lib/report-to-md';
|
|
6
11
|
export { reportToStdout } from './lib/report-to-stdout';
|
|
7
12
|
export { ScoredReport, scoreReport } from './lib/scoring';
|
|
8
|
-
export {
|
|
13
|
+
export { countOccurrences, distinct, factorOf, objectToEntries, objectToKeys, toArray, } from './lib/transformation';
|
|
9
14
|
export { verboseUtils } from './lib/verbose-utils';
|
|
10
|
-
export { toArray, objectToKeys, objectToEntries, countOccurrences, distinct, factorOf, } from './lib/transformation';
|
|
11
|
-
export { slugify, pluralize, pluralizeToken, formatBytes, formatDuration, } from './lib/formatting';
|
|
12
|
-
export { NEW_LINE } from './lib/md';
|
|
13
|
-
export { logMultipleResults } from './lib/log-results';
|
|
14
|
-
export { isPromiseFulfilledResult, isPromiseRejectedResult, } from './lib/guards';
|
package/src/lib/file-system.d.ts
CHANGED
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
import { type Options } from 'bundle-require';
|
|
2
|
+
export declare function readTextFile(path: string): Promise<string>;
|
|
3
|
+
export declare function readJsonFile<T = unknown>(path: string): Promise<T>;
|
|
4
|
+
export declare function fileExists(path: string): Promise<boolean>;
|
|
2
5
|
export declare function toUnixPath(path: string, options?: {
|
|
3
6
|
toRelative?: boolean;
|
|
4
7
|
}): string;
|
|
5
8
|
export declare function ensureDirectoryExists(baseDir: string): Promise<void>;
|
|
6
|
-
export declare function readTextFile(path: string): Promise<string>;
|
|
7
|
-
export declare function readJsonFile<T = unknown>(path: string): Promise<T>;
|
|
8
9
|
export type FileResult = readonly [string] | readonly [string, number];
|
|
9
10
|
export type MultipleFileResults = PromiseSettledResult<FileResult>[];
|
|
10
11
|
export declare function logMultipleFileResults(fileResults: MultipleFileResults, messagePrefix: string): void;
|
package/src/lib/formatting.d.ts
CHANGED
|
@@ -3,3 +3,6 @@ export declare function pluralize(text: string): string;
|
|
|
3
3
|
export declare function formatBytes(bytes: number, decimals?: number): string;
|
|
4
4
|
export declare function pluralizeToken(token: string, times?: number): string;
|
|
5
5
|
export declare function formatDuration(duration: number): string;
|
|
6
|
+
export declare function truncateText(text: string, maxChars: number): string;
|
|
7
|
+
export declare function truncateTitle(text: string): string;
|
|
8
|
+
export declare function truncateDescription(text: string): string;
|