@mnaoumov/obsidian-dev-toolkit 2.1.0 → 3.0.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 +5 -1
- package/bin/archive-demo-vault.mjs +8 -0
- package/bin/generate-coverage-badge.mjs +8 -0
- package/bundlers/esbuild-impl/feature-options/package.json +6 -0
- package/bundlers/obsidian-cli-reload/package.json +6 -0
- package/bundlers/obsidian-plugin-build/package.json +6 -0
- package/bundlers/obsidian-plugin-features/package.json +6 -0
- package/bundlers/obsidian-plugin-transforms/package.json +6 -0
- package/bundlers/obsidian-plugin-webpack-loader/package.json +6 -0
- package/bundlers/obsidian-plugins-folder-deployment/package.json +6 -0
- package/bundlers/parcel/package.json +6 -0
- package/bundlers/rollup/package.json +6 -0
- package/bundlers/rollup-compatible/package.json +6 -0
- package/bundlers/rollup-compatible-features/package.json +6 -0
- package/bundlers/vite/package.json +6 -0
- package/bundlers/webpack/package.json +6 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.cjs +3 -188
- package/dist/lib/cjs/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.d.cts +2 -18
- package/dist/lib/cjs/bundlers/esbuild-impl/feature-options.cjs +173 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/feature-options.d.cts +60 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/index.cjs +4 -1
- package/dist/lib/cjs/bundlers/esbuild-impl/index.d.cts +1 -0
- package/dist/lib/cjs/bundlers/esbuild-impl/obsidian-plugin-builder.cjs +30 -82
- package/dist/lib/cjs/bundlers/esbuild-impl/obsidian-plugin-builder.d.cts +7 -24
- package/dist/lib/cjs/bundlers/index.cjs +39 -3
- package/dist/lib/cjs/bundlers/index.d.cts +12 -0
- package/dist/lib/cjs/bundlers/obsidian-cli-reload.cjs +182 -0
- package/dist/lib/cjs/bundlers/obsidian-cli-reload.d.cts +37 -0
- package/dist/lib/cjs/bundlers/obsidian-plugin-build.cjs +278 -0
- package/dist/lib/cjs/bundlers/obsidian-plugin-build.d.cts +217 -0
- package/dist/lib/cjs/bundlers/obsidian-plugin-features.cjs +242 -0
- package/dist/lib/cjs/bundlers/obsidian-plugin-features.d.cts +186 -0
- package/dist/lib/cjs/bundlers/obsidian-plugin-transforms.cjs +306 -0
- package/dist/lib/cjs/bundlers/obsidian-plugin-transforms.d.cts +231 -0
- package/dist/lib/cjs/bundlers/obsidian-plugin-webpack-loader.cjs +182 -0
- package/dist/lib/cjs/bundlers/obsidian-plugin-webpack-loader.d.cts +47 -0
- package/dist/lib/cjs/bundlers/obsidian-plugins-folder-deployment.cjs +320 -0
- package/dist/lib/cjs/bundlers/obsidian-plugins-folder-deployment.d.cts +44 -0
- package/dist/lib/cjs/bundlers/parcel.cjs +462 -0
- package/dist/lib/cjs/bundlers/parcel.d.cts +128 -0
- package/dist/lib/cjs/bundlers/rollup-compatible-features.cjs +181 -0
- package/dist/lib/cjs/bundlers/rollup-compatible-features.d.cts +128 -0
- package/dist/lib/cjs/bundlers/rollup-compatible.cjs +138 -0
- package/dist/lib/cjs/bundlers/rollup-compatible.d.cts +84 -0
- package/dist/lib/cjs/bundlers/rollup.cjs +218 -0
- package/dist/lib/cjs/bundlers/rollup.d.cts +99 -0
- package/dist/lib/cjs/bundlers/vite.cjs +229 -0
- package/dist/lib/cjs/bundlers/vite.d.cts +105 -0
- package/dist/lib/cjs/bundlers/webpack.cjs +354 -0
- package/dist/lib/cjs/bundlers/webpack.d.cts +133 -0
- package/dist/lib/cjs/demo-vault-cli.cjs +131 -0
- package/dist/lib/cjs/demo-vault-cli.d.cts +15 -0
- package/dist/lib/cjs/index.cjs +4 -1
- package/dist/lib/cjs/index.d.cts +1 -0
- package/dist/lib/cjs/test-runners/coverage-badge-cli.cjs +160 -0
- package/dist/lib/cjs/test-runners/coverage-badge-cli.d.cts +25 -0
- package/dist/lib/cjs/test-runners/coverage-badge.cjs +279 -0
- package/dist/lib/cjs/test-runners/coverage-badge.d.cts +143 -0
- package/dist/lib/cjs/test-runners/e2e-runner-support.cjs +170 -0
- package/dist/lib/cjs/test-runners/e2e-runner-support.d.cts +36 -0
- package/dist/lib/cjs/test-runners/index.cjs +18 -3
- package/dist/lib/cjs/test-runners/index.d.cts +5 -0
- package/dist/lib/cjs/test-runners/obsidian-test-runner.cjs +147 -0
- package/dist/lib/cjs/test-runners/obsidian-test-runner.d.cts +42 -0
- package/dist/lib/cjs/test-runners/wdio-obsidian.cjs +205 -0
- package/dist/lib/cjs/test-runners/wdio-obsidian.d.cts +199 -0
- package/dist/lib/esm/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.d.mts +2 -18
- package/dist/lib/esm/bundlers/esbuild-impl/copy-to-obsidian-plugins-folder-plugin.mjs +3 -192
- package/dist/lib/esm/bundlers/esbuild-impl/feature-options.d.mts +60 -0
- package/dist/lib/esm/bundlers/esbuild-impl/feature-options.mjs +82 -0
- package/dist/lib/esm/bundlers/esbuild-impl/index.d.mts +1 -0
- package/dist/lib/esm/bundlers/esbuild-impl/index.mjs +3 -1
- package/dist/lib/esm/bundlers/esbuild-impl/obsidian-plugin-builder.d.mts +7 -24
- package/dist/lib/esm/bundlers/esbuild-impl/obsidian-plugin-builder.mjs +41 -87
- package/dist/lib/esm/bundlers/index.d.mts +12 -0
- package/dist/lib/esm/bundlers/index.mjs +26 -2
- package/dist/lib/esm/bundlers/obsidian-cli-reload.d.mts +37 -0
- package/dist/lib/esm/bundlers/obsidian-cli-reload.mjs +83 -0
- package/dist/lib/esm/bundlers/obsidian-plugin-build.d.mts +217 -0
- package/dist/lib/esm/bundlers/obsidian-plugin-build.mjs +166 -0
- package/dist/lib/esm/bundlers/obsidian-plugin-features.d.mts +186 -0
- package/dist/lib/esm/bundlers/obsidian-plugin-features.mjs +126 -0
- package/dist/lib/esm/bundlers/obsidian-plugin-transforms.d.mts +231 -0
- package/dist/lib/esm/bundlers/obsidian-plugin-transforms.mjs +194 -0
- package/dist/lib/esm/bundlers/obsidian-plugin-webpack-loader.d.mts +47 -0
- package/dist/lib/esm/bundlers/obsidian-plugin-webpack-loader.mjs +89 -0
- package/dist/lib/esm/bundlers/obsidian-plugins-folder-deployment.d.mts +44 -0
- package/dist/lib/esm/bundlers/obsidian-plugins-folder-deployment.mjs +228 -0
- package/dist/lib/esm/bundlers/parcel.d.mts +128 -0
- package/dist/lib/esm/bundlers/parcel.mjs +361 -0
- package/dist/lib/esm/bundlers/rollup-compatible-features.d.mts +128 -0
- package/dist/lib/esm/bundlers/rollup-compatible-features.mjs +93 -0
- package/dist/lib/esm/bundlers/rollup-compatible.d.mts +84 -0
- package/dist/lib/esm/bundlers/rollup-compatible.mjs +43 -0
- package/dist/lib/esm/bundlers/rollup.d.mts +99 -0
- package/dist/lib/esm/bundlers/rollup.mjs +130 -0
- package/dist/lib/esm/bundlers/vite.d.mts +105 -0
- package/dist/lib/esm/bundlers/vite.mjs +144 -0
- package/dist/lib/esm/bundlers/webpack.d.mts +133 -0
- package/dist/lib/esm/bundlers/webpack.mjs +259 -0
- package/dist/lib/esm/demo-vault-cli.d.mts +15 -0
- package/dist/lib/esm/demo-vault-cli.mjs +23 -0
- package/dist/lib/esm/index.d.mts +1 -0
- package/dist/lib/esm/index.mjs +3 -1
- package/dist/lib/esm/test-runners/coverage-badge-cli.d.mts +25 -0
- package/dist/lib/esm/test-runners/coverage-badge-cli.mjs +51 -0
- package/dist/lib/esm/test-runners/coverage-badge.d.mts +143 -0
- package/dist/lib/esm/test-runners/coverage-badge.mjs +181 -0
- package/dist/lib/esm/test-runners/e2e-runner-support.d.mts +36 -0
- package/dist/lib/esm/test-runners/e2e-runner-support.mjs +61 -0
- package/dist/lib/esm/test-runners/index.d.mts +5 -0
- package/dist/lib/esm/test-runners/index.mjs +12 -2
- package/dist/lib/esm/test-runners/obsidian-test-runner.d.mts +42 -0
- package/dist/lib/esm/test-runners/obsidian-test-runner.mjs +52 -0
- package/dist/lib/esm/test-runners/wdio-obsidian.d.mts +199 -0
- package/dist/lib/esm/test-runners/wdio-obsidian.mjs +110 -0
- package/package.json +102 -4
- package/test-runners/coverage-badge/package.json +6 -0
- package/test-runners/coverage-badge-cli/package.json +6 -0
- package/test-runners/e2e-runner-support/package.json +6 -0
- package/test-runners/obsidian-test-runner/package.json +6 -0
- package/test-runners/wdio-obsidian/package.json +6 -0
- package/tsconfig/preact.json +7 -0
- package/tsconfig/react.json +7 -0
- package/tsconfig/solid.json +7 -0
- package/tsconfig/svelte.json +7 -0
- package/tsconfig/vue.json +7 -0
- package/types/styles.d.ts +32 -0
- package/types/wasm.d.ts +11 -0
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
/*
|
|
2
|
+
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
3
|
+
if you want to view the source, please visit the github repository of this plugin
|
|
4
|
+
*/
|
|
5
|
+
(function () {
|
|
6
|
+
function ensureBrowserProcess() {
|
|
7
|
+
const browserProcess = {
|
|
8
|
+
browser: true,
|
|
9
|
+
cwd() {
|
|
10
|
+
return "/";
|
|
11
|
+
},
|
|
12
|
+
env: {},
|
|
13
|
+
platform: "android"
|
|
14
|
+
};
|
|
15
|
+
const existingProcess = globalThis.process;
|
|
16
|
+
if (!existingProcess) {
|
|
17
|
+
globalThis.process = browserProcess;
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (existingProcess.versions?.node) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const existingProcessRecord = existingProcess;
|
|
24
|
+
for (const [key, value] of Object.entries(browserProcess)) {
|
|
25
|
+
existingProcessRecord[key] ??= value;
|
|
26
|
+
}
|
|
27
|
+
existingProcessRecord["browser"] = true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
ensureBrowserProcess();
|
|
31
|
+
})();
|
|
32
|
+
(function patchObsidianRequire() {
|
|
33
|
+
const originalRequire = require;
|
|
34
|
+
if (!originalRequire || originalRequire.__isPatched) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
require = Object.assign(
|
|
39
|
+
(id) => requirePatched(id),
|
|
40
|
+
originalRequire,
|
|
41
|
+
{
|
|
42
|
+
__isPatched: true
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
function extractDefault(module) {
|
|
47
|
+
return module && module.__esModule && 'default' in module ? module.default : module;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const OBSIDIAN_BUILT_IN_MODULE_NAMES = new Set([
|
|
51
|
+
'@codemirror/autocomplete',
|
|
52
|
+
'@codemirror/collab',
|
|
53
|
+
'@codemirror/commands',
|
|
54
|
+
'@codemirror/language',
|
|
55
|
+
'@codemirror/lint',
|
|
56
|
+
'@codemirror/search',
|
|
57
|
+
'@codemirror/state',
|
|
58
|
+
'@codemirror/text',
|
|
59
|
+
'@codemirror/view',
|
|
60
|
+
'@lezer/common',
|
|
61
|
+
'@lezer/highlight',
|
|
62
|
+
'@lezer/lr',
|
|
63
|
+
'obsidian']
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES = new Set([
|
|
67
|
+
'@codemirror/closebrackets',
|
|
68
|
+
'@codemirror/comment',
|
|
69
|
+
'@codemirror/fold',
|
|
70
|
+
'@codemirror/gutter',
|
|
71
|
+
'@codemirror/highlight',
|
|
72
|
+
'@codemirror/history',
|
|
73
|
+
'@codemirror/matchbrackets',
|
|
74
|
+
'@codemirror/panel',
|
|
75
|
+
'@codemirror/rangeset',
|
|
76
|
+
'@codemirror/rectangular-selection',
|
|
77
|
+
'@codemirror/stream-parser',
|
|
78
|
+
'@codemirror/tooltip']
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
function requirePatched(id) {
|
|
82
|
+
if (OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id) || DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id)) {
|
|
83
|
+
return originalRequire?.(id);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated, obsidianmd/no-global-this -- Need access to app. Actively use globalThis.
|
|
87
|
+
if (globalThis.app.isMobile) {
|
|
88
|
+
if (id === 'process' || id === 'node:process') {
|
|
89
|
+
// eslint-disable-next-line no-console -- Valid usage.
|
|
90
|
+
console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Fake process object is returned instead.`);
|
|
91
|
+
|
|
92
|
+
return process;
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
const module = originalRequire?.(id);
|
|
96
|
+
if (module) {
|
|
97
|
+
return extractDefault(module);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// eslint-disable-next-line no-console -- Valid usage.
|
|
102
|
+
console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Empty object is returned instead.`);
|
|
103
|
+
return {};
|
|
104
|
+
}
|
|
105
|
+
})();
|
|
106
|
+
|
|
107
|
+
"use strict";
|
|
108
|
+
var __defProp = Object.defineProperty;
|
|
109
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
110
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
111
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
112
|
+
var __export = (target, all) => {
|
|
113
|
+
for (var name in all)
|
|
114
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
115
|
+
};
|
|
116
|
+
var __copyProps = (to, from, except, desc) => {
|
|
117
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
118
|
+
for (let key of __getOwnPropNames(from))
|
|
119
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
120
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
121
|
+
}
|
|
122
|
+
return to;
|
|
123
|
+
};
|
|
124
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
125
|
+
var coverage_badge_exports = {};
|
|
126
|
+
__export(coverage_badge_exports, {
|
|
127
|
+
generateCoverageBadge: () => generateCoverageBadge,
|
|
128
|
+
getCoverageBadgeColor: () => getCoverageBadgeColor,
|
|
129
|
+
getCoveragePercent: () => getCoveragePercent,
|
|
130
|
+
parseLcovTotals: () => parseLcovTotals,
|
|
131
|
+
renderCoverageBadgeSvg: () => renderCoverageBadgeSvg
|
|
132
|
+
});
|
|
133
|
+
module.exports = __toCommonJS(coverage_badge_exports);
|
|
134
|
+
var import_root = require('@mnaoumov/typescript-dev-toolkit/root');
|
|
135
|
+
var import_promises = require('node:fs/promises');
|
|
136
|
+
var import_node_path = require('node:path');
|
|
137
|
+
const DEFAULT_LABEL = "coverage";
|
|
138
|
+
const DEFAULT_LCOV_PATH = "coverage/lcov.info";
|
|
139
|
+
const DEFAULT_OUTPUT_PATH = "coverage/coverage-badge.svg";
|
|
140
|
+
const FULL_PERCENT = 100;
|
|
141
|
+
const PERCENT_PRECISION = 10;
|
|
142
|
+
const GREEN_MIN_PERCENT = 90;
|
|
143
|
+
const YELLOW_GREEN_MIN_PERCENT = 80;
|
|
144
|
+
const YELLOW_MIN_PERCENT = 70;
|
|
145
|
+
const ORANGE_MIN_PERCENT = 60;
|
|
146
|
+
const RED = "#e05d44";
|
|
147
|
+
const BADGE_COLOR_THRESHOLDS = [
|
|
148
|
+
{ color: "#4c1", minPercent: FULL_PERCENT },
|
|
149
|
+
{ color: "#97ca00", minPercent: GREEN_MIN_PERCENT },
|
|
150
|
+
{ color: "#a4a61d", minPercent: YELLOW_GREEN_MIN_PERCENT },
|
|
151
|
+
{ color: "#dfb317", minPercent: YELLOW_MIN_PERCENT },
|
|
152
|
+
{ color: "#fe7d37", minPercent: ORANGE_MIN_PERCENT },
|
|
153
|
+
{ color: RED, minPercent: 0 }
|
|
154
|
+
];
|
|
155
|
+
const BADGE_HEIGHT = 20;
|
|
156
|
+
const TEXT_PADDING = 12;
|
|
157
|
+
const HALF = 0.5;
|
|
158
|
+
const TEXT_BASELINE = 14;
|
|
159
|
+
const TEXT_SHADOW_BASELINE = 15;
|
|
160
|
+
const NARROW_CHARACTER_WIDTH = 3.9;
|
|
161
|
+
const DEFAULT_CHARACTER_WIDTH = 7;
|
|
162
|
+
const WIDE_CHARACTER_WIDTH = 9.5;
|
|
163
|
+
const PERCENT_SIGN_WIDTH = 11.9;
|
|
164
|
+
const NARROW_CHARACTERS = /* @__PURE__ */ new Set([" ", "-", ",", ";", ":", "!", ".", "'", "(", ")", "/", "f", "I", "i", "j", "l", "r", "t"]);
|
|
165
|
+
const WIDE_CHARACTERS = /* @__PURE__ */ new Set(["M", "m", "W", "w"]);
|
|
166
|
+
async function generateCoverageBadge(options = {}) {
|
|
167
|
+
const {
|
|
168
|
+
label = DEFAULT_LABEL,
|
|
169
|
+
lcovPath = DEFAULT_LCOV_PATH,
|
|
170
|
+
metric = "lines",
|
|
171
|
+
outputPath = DEFAULT_OUTPUT_PATH
|
|
172
|
+
} = options;
|
|
173
|
+
const resolvedLcovPath = (0, import_root.resolvePathFromRootSafe)({ path: lcovPath });
|
|
174
|
+
let lcov;
|
|
175
|
+
try {
|
|
176
|
+
lcov = await (0, import_promises.readFile)(resolvedLcovPath, "utf-8");
|
|
177
|
+
} catch (error) {
|
|
178
|
+
throw new Error(`Could not read the lcov report '${resolvedLcovPath}'. Run the tests with coverage first.`, { cause: error });
|
|
179
|
+
}
|
|
180
|
+
const percent = getCoveragePercent(parseLcovTotals(lcov), metric);
|
|
181
|
+
const resolvedOutputPath = (0, import_root.resolvePathFromRootSafe)({ path: outputPath });
|
|
182
|
+
await (0, import_promises.mkdir)((0, import_node_path.dirname)(resolvedOutputPath), { recursive: true });
|
|
183
|
+
await (0, import_promises.writeFile)(resolvedOutputPath, renderCoverageBadgeSvg({ label, percent }));
|
|
184
|
+
return { outputPath: resolvedOutputPath, percent };
|
|
185
|
+
}
|
|
186
|
+
function getCoverageBadgeColor(percent) {
|
|
187
|
+
const threshold = BADGE_COLOR_THRESHOLDS.find((candidate) => percent >= candidate.minPercent);
|
|
188
|
+
return threshold?.color ?? RED;
|
|
189
|
+
}
|
|
190
|
+
function getCoveragePercent(totals, metric) {
|
|
191
|
+
const percents = {
|
|
192
|
+
branches: toPercent(totals.branches),
|
|
193
|
+
functions: toPercent(totals.functions),
|
|
194
|
+
lines: toPercent(totals.lines)
|
|
195
|
+
};
|
|
196
|
+
const percent = metric === "lowest" ? Math.min(percents.branches, percents.functions, percents.lines) : percents[metric];
|
|
197
|
+
return Math.floor(percent * PERCENT_PRECISION) / PERCENT_PRECISION;
|
|
198
|
+
}
|
|
199
|
+
function parseLcovTotals(lcov) {
|
|
200
|
+
const sums = /* @__PURE__ */ new Map();
|
|
201
|
+
for (const line of lcov.split(/\r?\n/u)) {
|
|
202
|
+
const match = /^(?<key>BRF|BRH|FNF|FNH|LF|LH):(?<value>\d+)$/u.exec(line.trim());
|
|
203
|
+
if (!match?.groups) {
|
|
204
|
+
continue;
|
|
205
|
+
}
|
|
206
|
+
const { key = "", value = "" } = match.groups;
|
|
207
|
+
sums.set(key, (sums.get(key) ?? 0) + Number(value));
|
|
208
|
+
}
|
|
209
|
+
function count(coveredKey, totalKey) {
|
|
210
|
+
return { covered: sums.get(coveredKey) ?? 0, total: sums.get(totalKey) ?? 0 };
|
|
211
|
+
}
|
|
212
|
+
return {
|
|
213
|
+
branches: count("BRH", "BRF"),
|
|
214
|
+
functions: count("FNH", "FNF"),
|
|
215
|
+
lines: count("LH", "LF")
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
function renderCoverageBadgeSvg(params) {
|
|
219
|
+
const { label, percent } = params;
|
|
220
|
+
const value = `${String(percent)}%`;
|
|
221
|
+
const labelTextWidth = measureText(label);
|
|
222
|
+
const valueTextWidth = measureText(value);
|
|
223
|
+
const labelWidth = labelTextWidth + TEXT_PADDING;
|
|
224
|
+
const valueWidth = valueTextWidth + TEXT_PADDING;
|
|
225
|
+
const width = labelWidth + valueWidth;
|
|
226
|
+
const labelCenter = labelWidth * HALF;
|
|
227
|
+
const valueCenter = labelWidth + valueWidth * HALF;
|
|
228
|
+
const color = getCoverageBadgeColor(percent);
|
|
229
|
+
const title = escapeXml(`${label}: ${value}`);
|
|
230
|
+
const escapedLabel = escapeXml(label);
|
|
231
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${String(width)}" height="${String(BADGE_HEIGHT)}" role="img" aria-label="${title}">
|
|
232
|
+
<title>${title}</title>
|
|
233
|
+
<linearGradient id="s" x2="0" y2="100%"><stop offset="0" stop-color="#bbb" stop-opacity=".1"/><stop offset="1" stop-opacity=".1"/></linearGradient>
|
|
234
|
+
<clipPath id="r"><rect width="${String(width)}" height="${String(BADGE_HEIGHT)}" rx="3" fill="#fff"/></clipPath>
|
|
235
|
+
<g clip-path="url(#r)">
|
|
236
|
+
<rect width="${String(labelWidth)}" height="${String(BADGE_HEIGHT)}" fill="#555"/>
|
|
237
|
+
<rect x="${String(labelWidth)}" width="${String(valueWidth)}" height="${String(BADGE_HEIGHT)}" fill="${color}"/>
|
|
238
|
+
<rect width="${String(width)}" height="${String(BADGE_HEIGHT)}" fill="url(#s)"/>
|
|
239
|
+
</g>
|
|
240
|
+
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" font-size="11" text-rendering="geometricPrecision">
|
|
241
|
+
<text x="${String(labelCenter)}" y="${String(TEXT_SHADOW_BASELINE)}" fill="#010101" fill-opacity=".3" textLength="${String(labelTextWidth)}">${escapedLabel}</text>
|
|
242
|
+
<text x="${String(labelCenter)}" y="${String(TEXT_BASELINE)}" textLength="${String(labelTextWidth)}">${escapedLabel}</text>
|
|
243
|
+
<text x="${String(valueCenter)}" y="${String(TEXT_SHADOW_BASELINE)}" fill="#010101" fill-opacity=".3" textLength="${String(valueTextWidth)}">${value}</text>
|
|
244
|
+
<text x="${String(valueCenter)}" y="${String(TEXT_BASELINE)}" textLength="${String(valueTextWidth)}">${value}</text>
|
|
245
|
+
</g>
|
|
246
|
+
</svg>
|
|
247
|
+
`;
|
|
248
|
+
}
|
|
249
|
+
function escapeXml(text) {
|
|
250
|
+
return text.replaceAll("&", "&").replaceAll("<", "<").replaceAll(">", ">").replaceAll('"', """);
|
|
251
|
+
}
|
|
252
|
+
function measureCharacter(character) {
|
|
253
|
+
if (character === "%") {
|
|
254
|
+
return PERCENT_SIGN_WIDTH;
|
|
255
|
+
}
|
|
256
|
+
if (NARROW_CHARACTERS.has(character)) {
|
|
257
|
+
return NARROW_CHARACTER_WIDTH;
|
|
258
|
+
}
|
|
259
|
+
return WIDE_CHARACTERS.has(character) ? WIDE_CHARACTER_WIDTH : DEFAULT_CHARACTER_WIDTH;
|
|
260
|
+
}
|
|
261
|
+
function measureText(text) {
|
|
262
|
+
let width = 0;
|
|
263
|
+
for (const character of text) {
|
|
264
|
+
width += measureCharacter(character);
|
|
265
|
+
}
|
|
266
|
+
return Math.round(width);
|
|
267
|
+
}
|
|
268
|
+
function toPercent(count) {
|
|
269
|
+
return count.total === 0 ? FULL_PERCENT : count.covered / count.total * FULL_PERCENT;
|
|
270
|
+
}
|
|
271
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
272
|
+
0 && (module.exports = {
|
|
273
|
+
generateCoverageBadge,
|
|
274
|
+
getCoverageBadgeColor,
|
|
275
|
+
getCoveragePercent,
|
|
276
|
+
parseLcovTotals,
|
|
277
|
+
renderCoverageBadgeSvg
|
|
278
|
+
});
|
|
279
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy90ZXN0LXJ1bm5lcnMvY292ZXJhZ2UtYmFkZ2UudHMiXSwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAZmlsZVxuICpcbiAqIFJlbmRlcnMgYSBjb3ZlcmFnZSBiYWRnZSBmcm9tIHRoZSBgY292ZXJhZ2UvbGNvdi5pbmZvYCByZXBvcnQgYHRlc3RDb3ZlcmFnZWAgd3JpdGVzLCBhcyBhIHNlbGYtY29udGFpbmVkIFNWRyBpblxuICogdGhlIHNoaWVsZHMuaW8gZmxhdCBzdHlsZSwgc28gYSBSRUFETUUgY2FuIHNob3cgdGhlIG1lYXN1cmVkIGNvdmVyYWdlIHdpdGggbm8gZXh0ZXJuYWwgc2VydmljZS4gVGhlXG4gKiBgb2JzaWRpYW4tcGx1Z2luLWNpLnltbGAgcmV1c2FibGUgd29ya2Zsb3cgcHVibGlzaGVzIGl0IHRvIGEgYGJhZGdlc2AgYnJhbmNoOyBzZWUgdGhlIENJIGFuZCByZWxlYXNlIGd1aWRlLlxuICovXG5cbmltcG9ydCB7IHJlc29sdmVQYXRoRnJvbVJvb3RTYWZlIH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtZGV2LXRvb2xraXQvcm9vdCc7XG5pbXBvcnQge1xuICBta2RpcixcbiAgcmVhZEZpbGUsXG4gIHdyaXRlRmlsZVxufSBmcm9tICdub2RlOmZzL3Byb21pc2VzJztcbmltcG9ydCB7IGRpcm5hbWUgfSBmcm9tICdub2RlOnBhdGgnO1xuXG4vKipcbiAqIFdoaWNoIGNvdmVyYWdlIGZpZ3VyZSB0aGUgYmFkZ2Ugc2hvd3MuXG4gKlxuICogLSBgbGluZXNgOiB0aGUgc2hhcmUgb2YgbGluZXMgY292ZXJlZCwgdGhlIGZpZ3VyZSBtb3N0IGNvdmVyYWdlIHNlcnZpY2VzIHNob3cuXG4gKiAtIGBmdW5jdGlvbnNgOiB0aGUgc2hhcmUgb2YgZnVuY3Rpb25zIGNvdmVyZWQuXG4gKiAtIGBicmFuY2hlc2A6IHRoZSBzaGFyZSBvZiBicmFuY2hlcyBjb3ZlcmVkLlxuICogLSBgbG93ZXN0YDogdGhlIGxvd2VzdCBvZiB0aGUgdGhyZWUsIHNvIHRoZSBiYWRnZSBuZXZlciBzaG93cyBhIGZpZ3VyZSBvbmUgb2YgdGhlIG90aGVycyBmYWxscyBiZWxvdy5cbiAqL1xuZXhwb3J0IHR5cGUgQ292ZXJhZ2VCYWRnZU1ldHJpYyA9ICdicmFuY2hlcycgfCAnZnVuY3Rpb25zJyB8ICdsaW5lcycgfCAnbG93ZXN0JztcblxuLyoqXG4gKiBBIGNvdmVyZWQgYW5kIGEgdG90YWwgY291bnQgb2Ygb25lIGtpbmQgb2YgY292ZXJhZ2UgaXRlbS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb3ZlcmFnZUNvdW50IHtcbiAgLyoqXG4gICAqIEhvdyBtYW55IGl0ZW1zIGFyZSBjb3ZlcmVkLlxuICAgKi9cbiAgcmVhZG9ubHkgY292ZXJlZDogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBIb3cgbWFueSBpdGVtcyB0aGVyZSBhcmUuXG4gICAqL1xuICByZWFkb25seSB0b3RhbDogbnVtYmVyO1xufVxuXG4vKipcbiAqIFRoZSBjb3ZlcmFnZSB0b3RhbHMgb2YgYSB3aG9sZSBsY292IHJlcG9ydC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDb3ZlcmFnZVRvdGFscyB7XG4gIC8qKlxuICAgKiBUaGUgYnJhbmNoZXMgKGBCUkZgIC8gYEJSSGApLlxuICAgKi9cbiAgcmVhZG9ubHkgYnJhbmNoZXM6IENvdmVyYWdlQ291bnQ7XG5cbiAgLyoqXG4gICAqIFRoZSBmdW5jdGlvbnMgKGBGTkZgIC8gYEZOSGApLlxuICAgKi9cbiAgcmVhZG9ubHkgZnVuY3Rpb25zOiBDb3ZlcmFnZUNvdW50O1xuXG4gIC8qKlxuICAgKiBUaGUgbGluZXMgKGBMRmAgLyBgTEhgKS5cbiAgICovXG4gIHJlYWRvbmx5IGxpbmVzOiBDb3ZlcmFnZUNvdW50O1xufVxuXG4vKipcbiAqIE9wdGlvbnMgZm9yIHtAbGluayBnZW5lcmF0ZUNvdmVyYWdlQmFkZ2V9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdlbmVyYXRlQ292ZXJhZ2VCYWRnZU9wdGlvbnMge1xuICAvKipcbiAgICogVGhlIHRleHQgb24gdGhlIGxlZnQgaGFsZiBvZiB0aGUgYmFkZ2UuXG4gICAqXG4gICAqIEBkZWZhdWx0IGAnY292ZXJhZ2UnYFxuICAgKi9cbiAgcmVhZG9ubHkgbGFiZWw/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBsY292IHJlcG9ydCB0byByZWFkLCByZWxhdGl2ZSB0byB0aGUgcHJvamVjdCByb290LlxuICAgKlxuICAgKiBAZGVmYXVsdCBgJ2NvdmVyYWdlL2xjb3YuaW5mbydgXG4gICAqL1xuICByZWFkb25seSBsY292UGF0aD86IHN0cmluZztcblxuICAvKipcbiAgICogV2hpY2ggY292ZXJhZ2UgZmlndXJlIHRoZSBiYWRnZSBzaG93cy5cbiAgICpcbiAgICogQGRlZmF1bHQgYCdsaW5lcydgXG4gICAqL1xuICByZWFkb25seSBtZXRyaWM/OiBDb3ZlcmFnZUJhZGdlTWV0cmljO1xuXG4gIC8qKlxuICAgKiBXaGVyZSB0byB3cml0ZSB0aGUgU1ZHLCByZWxhdGl2ZSB0byB0aGUgcHJvamVjdCByb290LiBUaGUgZGVmYXVsdCBzaXRzIGJlc2lkZSB0aGUgcmVwb3J0LCBpbiBhIGZvbGRlciBhXG4gICAqIHByb2plY3QgaWdub3Jlcywgc28gYSBsb2NhbCBjb3ZlcmFnZSBydW4gbmV2ZXIgbGVhdmVzIGEgY2hhbmdlZCBmaWxlIGJlaGluZC5cbiAgICpcbiAgICogQGRlZmF1bHQgYCdjb3ZlcmFnZS9jb3ZlcmFnZS1iYWRnZS5zdmcnYFxuICAgKi9cbiAgcmVhZG9ubHkgb3V0cHV0UGF0aD86IHN0cmluZztcbn1cblxuLyoqXG4gKiBUaGUgcmVzdWx0IG9mIHtAbGluayBnZW5lcmF0ZUNvdmVyYWdlQmFkZ2V9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEdlbmVyYXRlQ292ZXJhZ2VCYWRnZVJlc3VsdCB7XG4gIC8qKlxuICAgKiBUaGUgYWJzb2x1dGUgcGF0aCBvZiB0aGUgU1ZHIHdyaXR0ZW4uXG4gICAqL1xuICByZWFkb25seSBvdXRwdXRQYXRoOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBjb3ZlcmFnZSBmaWd1cmUgdGhlIGJhZGdlIHNob3dzLCBpbiBwZXJjZW50cywgcm91bmRlZCBkb3duIHRvIG9uZSBkZWNpbWFsLlxuICAgKi9cbiAgcmVhZG9ubHkgcGVyY2VudDogbnVtYmVyO1xufVxuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayByZW5kZXJDb3ZlcmFnZUJhZGdlU3ZnfS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZW5kZXJDb3ZlcmFnZUJhZGdlU3ZnUGFyYW1zIHtcbiAgLyoqXG4gICAqIFRoZSB0ZXh0IG9uIHRoZSBsZWZ0IGhhbGYgb2YgdGhlIGJhZGdlLlxuICAgKi9cbiAgcmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIGNvdmVyYWdlIGZpZ3VyZSwgaW4gcGVyY2VudHMuXG4gICAqL1xuICByZWFkb25seSBwZXJjZW50OiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBCYWRnZUNvbG9yVGhyZXNob2xkIHtcbiAgcmVhZG9ubHkgY29sb3I6IHN0cmluZztcbiAgcmVhZG9ubHkgbWluUGVyY2VudDogbnVtYmVyO1xufVxuXG5jb25zdCBERUZBVUxUX0xBQkVMID0gJ2NvdmVyYWdlJztcbmNvbnN0IERFRkFVTFRfTENPVl9QQVRIID0gJ2NvdmVyYWdlL2xjb3YuaW5mbyc7XG5jb25zdCBERUZBVUxUX09VVFBVVF9QQVRIID0gJ2NvdmVyYWdlL2NvdmVyYWdlLWJhZGdlLnN2Zyc7XG5jb25zdCBGVUxMX1BFUkNFTlQgPSAxMDA7XG5jb25zdCBQRVJDRU5UX1BSRUNJU0lPTiA9IDEwO1xuXG5jb25zdCBHUkVFTl9NSU5fUEVSQ0VOVCA9IDkwO1xuY29uc3QgWUVMTE9XX0dSRUVOX01JTl9QRVJDRU5UID0gODA7XG5jb25zdCBZRUxMT1dfTUlOX1BFUkNFTlQgPSA3MDtcbmNvbnN0IE9SQU5HRV9NSU5fUEVSQ0VOVCA9IDYwO1xuY29uc3QgUkVEID0gJyNlMDVkNDQnO1xuXG4vLyBUaGUgc2hpZWxkcy5pbyBjb2xvciBzY2FsZSwgZnJvbSB0aGUgdG9wIGRvd247IHRoZSBsYXN0IGVudHJ5IGNhdGNoZXMgZXZlcnl0aGluZyBiZWxvdyBpdC5cbmNvbnN0IEJBREdFX0NPTE9SX1RIUkVTSE9MRFM6IHJlYWRvbmx5IEJhZGdlQ29sb3JUaHJlc2hvbGRbXSA9IFtcbiAgeyBjb2xvcjogJyM0YzEnLCBtaW5QZXJjZW50OiBGVUxMX1BFUkNFTlQgfSxcbiAgeyBjb2xvcjogJyM5N2NhMDAnLCBtaW5QZXJjZW50OiBHUkVFTl9NSU5fUEVSQ0VOVCB9LFxuICB7IGNvbG9yOiAnI2E0YTYxZCcsIG1pblBlcmNlbnQ6IFlFTExPV19HUkVFTl9NSU5fUEVSQ0VOVCB9LFxuICB7IGNvbG9yOiAnI2RmYjMxNycsIG1pblBlcmNlbnQ6IFlFTExPV19NSU5fUEVSQ0VOVCB9LFxuICB7IGNvbG9yOiAnI2ZlN2QzNycsIG1pblBlcmNlbnQ6IE9SQU5HRV9NSU5fUEVSQ0VOVCB9LFxuICB7IGNvbG9yOiBSRUQsIG1pblBlcmNlbnQ6IDAgfVxuXTtcblxuY29uc3QgQkFER0VfSEVJR0hUID0gMjA7XG4vLyBUaGUgcGFkZGluZyBvbiBib3RoIHNpZGVzIG9mIGEgdGV4dCB0b2dldGhlci5cbmNvbnN0IFRFWFRfUEFERElORyA9IDEyO1xuY29uc3QgSEFMRiA9IDAuNTtcbmNvbnN0IFRFWFRfQkFTRUxJTkUgPSAxNDtcbmNvbnN0IFRFWFRfU0hBRE9XX0JBU0VMSU5FID0gMTU7XG5cbi8vIEFwcHJveGltYXRlIGFkdmFuY2Ugd2lkdGhzIG9mIDExcHggVmVyZGFuYSwgdGhlIGZhY2Ugc2hpZWxkcy5pbyBtZWFzdXJlcyB3aXRoLiBUaGUgcmVuZGVyZWQgdGV4dCBpcyBzdHJldGNoZWQgdG9cbi8vIHRoZSBjb21wdXRlZCB3aWR0aCB0aHJvdWdoIGB0ZXh0TGVuZ3RoYCwgc28gYW4gZXN0aW1hdGUgYSBwaXhlbCBvZmYgbW92ZXMgdGhlIHBhZGRpbmcsIG5ldmVyIGNsaXBzIHRoZSB0ZXh0LlxuY29uc3QgTkFSUk9XX0NIQVJBQ1RFUl9XSURUSCA9IDMuOTtcbmNvbnN0IERFRkFVTFRfQ0hBUkFDVEVSX1dJRFRIID0gNztcbmNvbnN0IFdJREVfQ0hBUkFDVEVSX1dJRFRIID0gOS41O1xuY29uc3QgUEVSQ0VOVF9TSUdOX1dJRFRIID0gMTEuOTtcbmNvbnN0IE5BUlJPV19DSEFSQUNURVJTID0gbmV3IFNldChbJyAnLCAnLScsICcsJywgJzsnLCAnOicsICchJywgJy4nLCAnXFwnJywgJygnLCAnKScsICcvJywgJ2YnLCAnSScsICdpJywgJ2onLCAnbCcsICdyJywgJ3QnXSk7XG5jb25zdCBXSURFX0NIQVJBQ1RFUlMgPSBuZXcgU2V0KFsnTScsICdtJywgJ1cnLCAndyddKTtcblxuLyoqXG4gKiBSZWFkcyB0aGUgbGNvdiByZXBvcnQsIHJlbmRlcnMgdGhlIGJhZGdlIGFuZCB3cml0ZXMgaXQuXG4gKlxuICogQHBhcmFtIG9wdGlvbnMgLSBUaGUge0BsaW5rIEdlbmVyYXRlQ292ZXJhZ2VCYWRnZU9wdGlvbnN9LlxuICogQHJldHVybnMgQSB7QGxpbmsgUHJvbWlzZX0gdGhhdCByZXNvbHZlcyB0byB0aGUge0BsaW5rIEdlbmVyYXRlQ292ZXJhZ2VCYWRnZVJlc3VsdH0uXG4gKiBAdGhyb3dzIFdoZW4gdGhlIGxjb3YgcmVwb3J0IGNhbm5vdCBiZSByZWFkOyBydW4gdGhlIHRlc3RzIHdpdGggY292ZXJhZ2UgZmlyc3QuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZW5lcmF0ZUNvdmVyYWdlQmFkZ2Uob3B0aW9uczogR2VuZXJhdGVDb3ZlcmFnZUJhZGdlT3B0aW9ucyA9IHt9KTogUHJvbWlzZTxHZW5lcmF0ZUNvdmVyYWdlQmFkZ2VSZXN1bHQ+IHtcbiAgY29uc3Qge1xuICAgIGxhYmVsID0gREVGQVVMVF9MQUJFTCxcbiAgICBsY292UGF0aCA9IERFRkFVTFRfTENPVl9QQVRILFxuICAgIG1ldHJpYyA9ICdsaW5lcycsXG4gICAgb3V0cHV0UGF0aCA9IERFRkFVTFRfT1VUUFVUX1BBVEhcbiAgfSA9IG9wdGlvbnM7XG5cbiAgY29uc3QgcmVzb2x2ZWRMY292UGF0aCA9IHJlc29sdmVQYXRoRnJvbVJvb3RTYWZlKHsgcGF0aDogbGNvdlBhdGggfSk7XG4gIGxldCBsY292OiBzdHJpbmc7XG4gIHRyeSB7XG4gICAgbGNvdiA9IGF3YWl0IHJlYWRGaWxlKHJlc29sdmVkTGNvdlBhdGgsICd1dGYtOCcpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHRocm93IG5ldyBFcnJvcihgQ291bGQgbm90IHJlYWQgdGhlIGxjb3YgcmVwb3J0ICcke3Jlc29sdmVkTGNvdlBhdGh9Jy4gUnVuIHRoZSB0ZXN0cyB3aXRoIGNvdmVyYWdlIGZpcnN0LmAsIHsgY2F1c2U6IGVycm9yIH0pO1xuICB9XG5cbiAgY29uc3QgcGVyY2VudCA9IGdldENvdmVyYWdlUGVyY2VudChwYXJzZUxjb3ZUb3RhbHMobGNvdiksIG1ldHJpYyk7XG4gIGNvbnN0IHJlc29sdmVkT3V0cHV0UGF0aCA9IHJlc29sdmVQYXRoRnJvbVJvb3RTYWZlKHsgcGF0aDogb3V0cHV0UGF0aCB9KTtcbiAgYXdhaXQgbWtkaXIoZGlybmFtZShyZXNvbHZlZE91dHB1dFBhdGgpLCB7IHJlY3Vyc2l2ZTogdHJ1ZSB9KTtcbiAgYXdhaXQgd3JpdGVGaWxlKHJlc29sdmVkT3V0cHV0UGF0aCwgcmVuZGVyQ292ZXJhZ2VCYWRnZVN2Zyh7IGxhYmVsLCBwZXJjZW50IH0pKTtcbiAgcmV0dXJuIHsgb3V0cHV0UGF0aDogcmVzb2x2ZWRPdXRwdXRQYXRoLCBwZXJjZW50IH07XG59XG5cbi8qKlxuICogUGlja3MgdGhlIGJhZGdlIGNvbG9yIG9mIGEgY292ZXJhZ2UgZmlndXJlLCBvbiB0aGUgc2hpZWxkcy5pbyBzY2FsZS5cbiAqXG4gKiBAcGFyYW0gcGVyY2VudCAtIFRoZSBjb3ZlcmFnZSBmaWd1cmUsIGluIHBlcmNlbnRzLlxuICogQHJldHVybnMgVGhlIGNvbG9yLCBhcyBhIENTUyBoZXggY29sb3IuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb3ZlcmFnZUJhZGdlQ29sb3IocGVyY2VudDogbnVtYmVyKTogc3RyaW5nIHtcbiAgY29uc3QgdGhyZXNob2xkID0gQkFER0VfQ09MT1JfVEhSRVNIT0xEUy5maW5kKChjYW5kaWRhdGUpID0+IHBlcmNlbnQgPj0gY2FuZGlkYXRlLm1pblBlcmNlbnQpO1xuICByZXR1cm4gdGhyZXNob2xkPy5jb2xvciA/PyBSRUQ7XG59XG5cbi8qKlxuICogQ29tcHV0ZXMgdGhlIGZpZ3VyZSBhIGJhZGdlIHNob3dzLlxuICpcbiAqIEEga2luZCB3aXRoIG5vdGhpbmcgdG8gY292ZXIgY291bnRzIGFzIGZ1bGx5IGNvdmVyZWQsIGFzIHZpdGVzdCdzIG93biBzdW1tYXJ5IHJlcG9ydHMgaXQuIFRoZSBmaWd1cmUgaXMgcm91bmRlZFxuICogRE9XTiB0byBvbmUgZGVjaW1hbCwgc28gYSBwcm9qZWN0IGF0IDk5Ljk2JSBuZXZlciBzaG93cyAxMDAlLlxuICpcbiAqIEBwYXJhbSB0b3RhbHMgLSBUaGUge0BsaW5rIENvdmVyYWdlVG90YWxzfS5cbiAqIEBwYXJhbSBtZXRyaWMgLSBUaGUge0BsaW5rIENvdmVyYWdlQmFkZ2VNZXRyaWN9LlxuICogQHJldHVybnMgVGhlIGNvdmVyYWdlIGZpZ3VyZSwgaW4gcGVyY2VudHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRDb3ZlcmFnZVBlcmNlbnQodG90YWxzOiBDb3ZlcmFnZVRvdGFscywgbWV0cmljOiBDb3ZlcmFnZUJhZGdlTWV0cmljKTogbnVtYmVyIHtcbiAgY29uc3QgcGVyY2VudHMgPSB7XG4gICAgYnJhbmNoZXM6IHRvUGVyY2VudCh0b3RhbHMuYnJhbmNoZXMpLFxuICAgIGZ1bmN0aW9uczogdG9QZXJjZW50KHRvdGFscy5mdW5jdGlvbnMpLFxuICAgIGxpbmVzOiB0b1BlcmNlbnQodG90YWxzLmxpbmVzKVxuICB9O1xuICBjb25zdCBwZXJjZW50ID0gbWV0cmljID09PSAnbG93ZXN0JyA/IE1hdGgubWluKHBlcmNlbnRzLmJyYW5jaGVzLCBwZXJjZW50cy5mdW5jdGlvbnMsIHBlcmNlbnRzLmxpbmVzKSA6IHBlcmNlbnRzW21ldHJpY107XG4gIHJldHVybiBNYXRoLmZsb29yKHBlcmNlbnQgKiBQRVJDRU5UX1BSRUNJU0lPTikgLyBQRVJDRU5UX1BSRUNJU0lPTjtcbn1cblxuLyoqXG4gKiBTdW1zIHRoZSBwZXItZmlsZSBjb3VudHMgb2YgYW4gbGNvdiByZXBvcnQuXG4gKlxuICogQHBhcmFtIGxjb3YgLSBUaGUgdGV4dCBvZiB0aGUgcmVwb3J0LlxuICogQHJldHVybnMgVGhlIHtAbGluayBDb3ZlcmFnZVRvdGFsc30uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUxjb3ZUb3RhbHMobGNvdjogc3RyaW5nKTogQ292ZXJhZ2VUb3RhbHMge1xuICBjb25zdCBzdW1zID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgZm9yIChjb25zdCBsaW5lIG9mIGxjb3Yuc3BsaXQoL1xccj9cXG4vdSkpIHtcbiAgICBjb25zdCBtYXRjaCA9IC9eKD88a2V5PkJSRnxCUkh8Rk5GfEZOSHxMRnxMSCk6KD88dmFsdWU+XFxkKykkL3UuZXhlYyhsaW5lLnRyaW0oKSk7XG4gICAgaWYgKCFtYXRjaD8uZ3JvdXBzKSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgY29uc3QgeyBrZXkgPSAnJywgdmFsdWUgPSAnJyB9ID0gbWF0Y2guZ3JvdXBzO1xuICAgIHN1bXMuc2V0KGtleSwgKHN1bXMuZ2V0KGtleSkgPz8gMCkgKyBOdW1iZXIodmFsdWUpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNvdW50KGNvdmVyZWRLZXk6IHN0cmluZywgdG90YWxLZXk6IHN0cmluZyk6IENvdmVyYWdlQ291bnQge1xuICAgIHJldHVybiB7IGNvdmVyZWQ6IHN1bXMuZ2V0KGNvdmVyZWRLZXkpID8/IDAsIHRvdGFsOiBzdW1zLmdldCh0b3RhbEtleSkgPz8gMCB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBicmFuY2hlczogY291bnQoJ0JSSCcsICdCUkYnKSxcbiAgICBmdW5jdGlvbnM6IGNvdW50KCdGTkgnLCAnRk5GJyksXG4gICAgbGluZXM6IGNvdW50KCdMSCcsICdMRicpXG4gIH07XG59XG5cbi8qKlxuICogUmVuZGVycyBhIGNvdmVyYWdlIGJhZGdlIGluIHRoZSBzaGllbGRzLmlvIGZsYXQgc3R5bGUuXG4gKlxuICogQHBhcmFtIHBhcmFtcyAtIFRoZSB7QGxpbmsgUmVuZGVyQ292ZXJhZ2VCYWRnZVN2Z1BhcmFtc30uXG4gKiBAcmV0dXJucyBUaGUgU1ZHIHRleHQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZW5kZXJDb3ZlcmFnZUJhZGdlU3ZnKHBhcmFtczogUmVuZGVyQ292ZXJhZ2VCYWRnZVN2Z1BhcmFtcyk6IHN0cmluZyB7XG4gIGNvbnN0IHsgbGFiZWwsIHBlcmNlbnQgfSA9IHBhcmFtcztcbiAgY29uc3QgdmFsdWUgPSBgJHtTdHJpbmcocGVyY2VudCl9JWA7XG4gIGNvbnN0IGxhYmVsVGV4dFdpZHRoID0gbWVhc3VyZVRleHQobGFiZWwpO1xuICBjb25zdCB2YWx1ZVRleHRXaWR0aCA9IG1lYXN1cmVUZXh0KHZhbHVlKTtcbiAgY29uc3QgbGFiZWxXaWR0aCA9IGxhYmVsVGV4dFdpZHRoICsgVEVYVF9QQURESU5HO1xuICBjb25zdCB2YWx1ZVdpZHRoID0gdmFsdWVUZXh0V2lkdGggKyBURVhUX1BBRERJTkc7XG4gIGNvbnN0IHdpZHRoID0gbGFiZWxXaWR0aCArIHZhbHVlV2lkdGg7XG4gIGNvbnN0IGxhYmVsQ2VudGVyID0gbGFiZWxXaWR0aCAqIEhBTEY7XG4gIGNvbnN0IHZhbHVlQ2VudGVyID0gbGFiZWxXaWR0aCArIHZhbHVlV2lkdGggKiBIQUxGO1xuICBjb25zdCBjb2xvciA9IGdldENvdmVyYWdlQmFkZ2VDb2xvcihwZXJjZW50KTtcbiAgY29uc3QgdGl0bGUgPSBlc2NhcGVYbWwoYCR7bGFiZWx9OiAke3ZhbHVlfWApO1xuICBjb25zdCBlc2NhcGVkTGFiZWwgPSBlc2NhcGVYbWwobGFiZWwpO1xuXG4gIHJldHVybiBgPHN2ZyB4bWxucz1cImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIgd2lkdGg9XCIke1N0cmluZyh3aWR0aCl9XCIgaGVpZ2h0PVwiJHtTdHJpbmcoQkFER0VfSEVJR0hUKX1cIiByb2xlPVwiaW1nXCIgYXJpYS1sYWJlbD1cIiR7dGl0bGV9XCI+XG4gIDx0aXRsZT4ke3RpdGxlfTwvdGl0bGU+XG4gIDxsaW5lYXJHcmFkaWVudCBpZD1cInNcIiB4Mj1cIjBcIiB5Mj1cIjEwMCVcIj48c3RvcCBvZmZzZXQ9XCIwXCIgc3RvcC1jb2xvcj1cIiNiYmJcIiBzdG9wLW9wYWNpdHk9XCIuMVwiLz48c3RvcCBvZmZzZXQ9XCIxXCIgc3RvcC1vcGFjaXR5PVwiLjFcIi8+PC9saW5lYXJHcmFkaWVudD5cbiAgPGNsaXBQYXRoIGlkPVwiclwiPjxyZWN0IHdpZHRoPVwiJHtTdHJpbmcod2lkdGgpfVwiIGhlaWdodD1cIiR7U3RyaW5nKEJBREdFX0hFSUdIVCl9XCIgcng9XCIzXCIgZmlsbD1cIiNmZmZcIi8+PC9jbGlwUGF0aD5cbiAgPGcgY2xpcC1wYXRoPVwidXJsKCNyKVwiPlxuICAgIDxyZWN0IHdpZHRoPVwiJHtTdHJpbmcobGFiZWxXaWR0aCl9XCIgaGVpZ2h0PVwiJHtTdHJpbmcoQkFER0VfSEVJR0hUKX1cIiBmaWxsPVwiIzU1NVwiLz5cbiAgICA8cmVjdCB4PVwiJHtTdHJpbmcobGFiZWxXaWR0aCl9XCIgd2lkdGg9XCIke1N0cmluZyh2YWx1ZVdpZHRoKX1cIiBoZWlnaHQ9XCIke1N0cmluZyhCQURHRV9IRUlHSFQpfVwiIGZpbGw9XCIke2NvbG9yfVwiLz5cbiAgICA8cmVjdCB3aWR0aD1cIiR7U3RyaW5nKHdpZHRoKX1cIiBoZWlnaHQ9XCIke1N0cmluZyhCQURHRV9IRUlHSFQpfVwiIGZpbGw9XCJ1cmwoI3MpXCIvPlxuICA8L2c+XG4gIDxnIGZpbGw9XCIjZmZmXCIgdGV4dC1hbmNob3I9XCJtaWRkbGVcIiBmb250LWZhbWlseT1cIlZlcmRhbmEsR2VuZXZhLERlamFWdSBTYW5zLHNhbnMtc2VyaWZcIiBmb250LXNpemU9XCIxMVwiIHRleHQtcmVuZGVyaW5nPVwiZ2VvbWV0cmljUHJlY2lzaW9uXCI+XG4gICAgPHRleHQgeD1cIiR7U3RyaW5nKGxhYmVsQ2VudGVyKX1cIiB5PVwiJHtTdHJpbmcoVEVYVF9TSEFET1dfQkFTRUxJTkUpfVwiIGZpbGw9XCIjMDEwMTAxXCIgZmlsbC1vcGFjaXR5PVwiLjNcIiB0ZXh0TGVuZ3RoPVwiJHtTdHJpbmcobGFiZWxUZXh0V2lkdGgpfVwiPiR7ZXNjYXBlZExhYmVsfTwvdGV4dD5cbiAgICA8dGV4dCB4PVwiJHtTdHJpbmcobGFiZWxDZW50ZXIpfVwiIHk9XCIke1N0cmluZyhURVhUX0JBU0VMSU5FKX1cIiB0ZXh0TGVuZ3RoPVwiJHtTdHJpbmcobGFiZWxUZXh0V2lkdGgpfVwiPiR7ZXNjYXBlZExhYmVsfTwvdGV4dD5cbiAgICA8dGV4dCB4PVwiJHtTdHJpbmcodmFsdWVDZW50ZXIpfVwiIHk9XCIke1N0cmluZyhURVhUX1NIQURPV19CQVNFTElORSl9XCIgZmlsbD1cIiMwMTAxMDFcIiBmaWxsLW9wYWNpdHk9XCIuM1wiIHRleHRMZW5ndGg9XCIke1N0cmluZyh2YWx1ZVRleHRXaWR0aCl9XCI+JHt2YWx1ZX08L3RleHQ+XG4gICAgPHRleHQgeD1cIiR7U3RyaW5nKHZhbHVlQ2VudGVyKX1cIiB5PVwiJHtTdHJpbmcoVEVYVF9CQVNFTElORSl9XCIgdGV4dExlbmd0aD1cIiR7U3RyaW5nKHZhbHVlVGV4dFdpZHRoKX1cIj4ke3ZhbHVlfTwvdGV4dD5cbiAgPC9nPlxuPC9zdmc+XG5gO1xufVxuXG5mdW5jdGlvbiBlc2NhcGVYbWwodGV4dDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIHRleHQucmVwbGFjZUFsbCgnJicsICcmYW1wOycpLnJlcGxhY2VBbGwoJzwnLCAnJmx0OycpLnJlcGxhY2VBbGwoJz4nLCAnJmd0OycpLnJlcGxhY2VBbGwoJ1wiJywgJyZxdW90OycpO1xufVxuXG5mdW5jdGlvbiBtZWFzdXJlQ2hhcmFjdGVyKGNoYXJhY3Rlcjogc3RyaW5nKTogbnVtYmVyIHtcbiAgaWYgKGNoYXJhY3RlciA9PT0gJyUnKSB7XG4gICAgcmV0dXJuIFBFUkNFTlRfU0lHTl9XSURUSDtcbiAgfVxuICBpZiAoTkFSUk9XX0NIQVJBQ1RFUlMuaGFzKGNoYXJhY3RlcikpIHtcbiAgICByZXR1cm4gTkFSUk9XX0NIQVJBQ1RFUl9XSURUSDtcbiAgfVxuICByZXR1cm4gV0lERV9DSEFSQUNURVJTLmhhcyhjaGFyYWN0ZXIpID8gV0lERV9DSEFSQUNURVJfV0lEVEggOiBERUZBVUxUX0NIQVJBQ1RFUl9XSURUSDtcbn1cblxuZnVuY3Rpb24gbWVhc3VyZVRleHQodGV4dDogc3RyaW5nKTogbnVtYmVyIHtcbiAgbGV0IHdpZHRoID0gMDtcbiAgZm9yIChjb25zdCBjaGFyYWN0ZXIgb2YgdGV4dCkge1xuICAgIHdpZHRoICs9IG1lYXN1cmVDaGFyYWN0ZXIoY2hhcmFjdGVyKTtcbiAgfVxuICByZXR1cm4gTWF0aC5yb3VuZCh3aWR0aCk7XG59XG5cbmZ1bmN0aW9uIHRvUGVyY2VudChjb3VudDogQ292ZXJhZ2VDb3VudCk6IG51bWJlciB7XG4gIHJldHVybiBjb3VudC50b3RhbCA9PT0gMCA/IEZVTExfUEVSQ0VOVCA6IGNvdW50LmNvdmVyZWQgLyBjb3VudC50b3RhbCAqIEZVTExfUEVSQ0VOVDtcbn1cbiJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQVFBLGtCQUF3QztBQUN4QyxzQkFJTztBQUNQLHVCQUF3QjtBQW9IeEIsTUFBTSxnQkFBZ0I7QUFDdEIsTUFBTSxvQkFBb0I7QUFDMUIsTUFBTSxzQkFBc0I7QUFDNUIsTUFBTSxlQUFlO0FBQ3JCLE1BQU0sb0JBQW9CO0FBRTFCLE1BQU0sb0JBQW9CO0FB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
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/// <reference path="../library-references.d.cts" />
|
|
2
|
+
/**
|
|
3
|
+
* @file
|
|
4
|
+
*
|
|
5
|
+
* Renders a coverage badge from the `coverage/lcov.info` report `testCoverage` writes, as a self-contained SVG in
|
|
6
|
+
* the shields.io flat style, so a README can show the measured coverage with no external service. The
|
|
7
|
+
* `obsidian-plugin-ci.yml` reusable workflow publishes it to a `badges` branch; see the CI and release guide.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Which coverage figure the badge shows.
|
|
11
|
+
*
|
|
12
|
+
* - `lines`: the share of lines covered, the figure most coverage services show.
|
|
13
|
+
* - `functions`: the share of functions covered.
|
|
14
|
+
* - `branches`: the share of branches covered.
|
|
15
|
+
* - `lowest`: the lowest of the three, so the badge never shows a figure one of the others falls below.
|
|
16
|
+
*/
|
|
17
|
+
export type CoverageBadgeMetric = 'branches' | 'functions' | 'lines' | 'lowest';
|
|
18
|
+
/**
|
|
19
|
+
* A covered and a total count of one kind of coverage item.
|
|
20
|
+
*/
|
|
21
|
+
export interface CoverageCount {
|
|
22
|
+
/**
|
|
23
|
+
* How many items are covered.
|
|
24
|
+
*/
|
|
25
|
+
readonly covered: number;
|
|
26
|
+
/**
|
|
27
|
+
* How many items there are.
|
|
28
|
+
*/
|
|
29
|
+
readonly total: number;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* The coverage totals of a whole lcov report.
|
|
33
|
+
*/
|
|
34
|
+
export interface CoverageTotals {
|
|
35
|
+
/**
|
|
36
|
+
* The branches (`BRF` / `BRH`).
|
|
37
|
+
*/
|
|
38
|
+
readonly branches: CoverageCount;
|
|
39
|
+
/**
|
|
40
|
+
* The functions (`FNF` / `FNH`).
|
|
41
|
+
*/
|
|
42
|
+
readonly functions: CoverageCount;
|
|
43
|
+
/**
|
|
44
|
+
* The lines (`LF` / `LH`).
|
|
45
|
+
*/
|
|
46
|
+
readonly lines: CoverageCount;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Options for {@link generateCoverageBadge}.
|
|
50
|
+
*/
|
|
51
|
+
export interface GenerateCoverageBadgeOptions {
|
|
52
|
+
/**
|
|
53
|
+
* The text on the left half of the badge.
|
|
54
|
+
*
|
|
55
|
+
* @default `'coverage'`
|
|
56
|
+
*/
|
|
57
|
+
readonly label?: string;
|
|
58
|
+
/**
|
|
59
|
+
* The lcov report to read, relative to the project root.
|
|
60
|
+
*
|
|
61
|
+
* @default `'coverage/lcov.info'`
|
|
62
|
+
*/
|
|
63
|
+
readonly lcovPath?: string;
|
|
64
|
+
/**
|
|
65
|
+
* Which coverage figure the badge shows.
|
|
66
|
+
*
|
|
67
|
+
* @default `'lines'`
|
|
68
|
+
*/
|
|
69
|
+
readonly metric?: CoverageBadgeMetric;
|
|
70
|
+
/**
|
|
71
|
+
* Where to write the SVG, relative to the project root. The default sits beside the report, in a folder a
|
|
72
|
+
* project ignores, so a local coverage run never leaves a changed file behind.
|
|
73
|
+
*
|
|
74
|
+
* @default `'coverage/coverage-badge.svg'`
|
|
75
|
+
*/
|
|
76
|
+
readonly outputPath?: string;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* The result of {@link generateCoverageBadge}.
|
|
80
|
+
*/
|
|
81
|
+
export interface GenerateCoverageBadgeResult {
|
|
82
|
+
/**
|
|
83
|
+
* The absolute path of the SVG written.
|
|
84
|
+
*/
|
|
85
|
+
readonly outputPath: string;
|
|
86
|
+
/**
|
|
87
|
+
* The coverage figure the badge shows, in percents, rounded down to one decimal.
|
|
88
|
+
*/
|
|
89
|
+
readonly percent: number;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Parameters for {@link renderCoverageBadgeSvg}.
|
|
93
|
+
*/
|
|
94
|
+
export interface RenderCoverageBadgeSvgParams {
|
|
95
|
+
/**
|
|
96
|
+
* The text on the left half of the badge.
|
|
97
|
+
*/
|
|
98
|
+
readonly label: string;
|
|
99
|
+
/**
|
|
100
|
+
* The coverage figure, in percents.
|
|
101
|
+
*/
|
|
102
|
+
readonly percent: number;
|
|
103
|
+
}
|
|
104
|
+
/**
|
|
105
|
+
* Reads the lcov report, renders the badge and writes it.
|
|
106
|
+
*
|
|
107
|
+
* @param options - The {@link GenerateCoverageBadgeOptions}.
|
|
108
|
+
* @returns A {@link Promise} that resolves to the {@link GenerateCoverageBadgeResult}.
|
|
109
|
+
* @throws When the lcov report cannot be read; run the tests with coverage first.
|
|
110
|
+
*/
|
|
111
|
+
export declare function generateCoverageBadge(options?: GenerateCoverageBadgeOptions): Promise<GenerateCoverageBadgeResult>;
|
|
112
|
+
/**
|
|
113
|
+
* Picks the badge color of a coverage figure, on the shields.io scale.
|
|
114
|
+
*
|
|
115
|
+
* @param percent - The coverage figure, in percents.
|
|
116
|
+
* @returns The color, as a CSS hex color.
|
|
117
|
+
*/
|
|
118
|
+
export declare function getCoverageBadgeColor(percent: number): string;
|
|
119
|
+
/**
|
|
120
|
+
* Computes the figure a badge shows.
|
|
121
|
+
*
|
|
122
|
+
* A kind with nothing to cover counts as fully covered, as vitest's own summary reports it. The figure is rounded
|
|
123
|
+
* DOWN to one decimal, so a project at 99.96% never shows 100%.
|
|
124
|
+
*
|
|
125
|
+
* @param totals - The {@link CoverageTotals}.
|
|
126
|
+
* @param metric - The {@link CoverageBadgeMetric}.
|
|
127
|
+
* @returns The coverage figure, in percents.
|
|
128
|
+
*/
|
|
129
|
+
export declare function getCoveragePercent(totals: CoverageTotals, metric: CoverageBadgeMetric): number;
|
|
130
|
+
/**
|
|
131
|
+
* Sums the per-file counts of an lcov report.
|
|
132
|
+
*
|
|
133
|
+
* @param lcov - The text of the report.
|
|
134
|
+
* @returns The {@link CoverageTotals}.
|
|
135
|
+
*/
|
|
136
|
+
export declare function parseLcovTotals(lcov: string): CoverageTotals;
|
|
137
|
+
/**
|
|
138
|
+
* Renders a coverage badge in the shields.io flat style.
|
|
139
|
+
*
|
|
140
|
+
* @param params - The {@link RenderCoverageBadgeSvgParams}.
|
|
141
|
+
* @returns The SVG text.
|
|
142
|
+
*/
|
|
143
|
+
export declare function renderCoverageBadgeSvg(params: RenderCoverageBadgeSvgParams): string;
|
|
@@ -0,0 +1,170 @@
|
|
|
1
|
+
/*
|
|
2
|
+
THIS IS A GENERATED/BUNDLED FILE BY ESBUILD
|
|
3
|
+
if you want to view the source, please visit the github repository of this plugin
|
|
4
|
+
*/
|
|
5
|
+
(function () {
|
|
6
|
+
function ensureBrowserProcess() {
|
|
7
|
+
const browserProcess = {
|
|
8
|
+
browser: true,
|
|
9
|
+
cwd() {
|
|
10
|
+
return "/";
|
|
11
|
+
},
|
|
12
|
+
env: {},
|
|
13
|
+
platform: "android"
|
|
14
|
+
};
|
|
15
|
+
const existingProcess = globalThis.process;
|
|
16
|
+
if (!existingProcess) {
|
|
17
|
+
globalThis.process = browserProcess;
|
|
18
|
+
return;
|
|
19
|
+
}
|
|
20
|
+
if (existingProcess.versions?.node) {
|
|
21
|
+
return;
|
|
22
|
+
}
|
|
23
|
+
const existingProcessRecord = existingProcess;
|
|
24
|
+
for (const [key, value] of Object.entries(browserProcess)) {
|
|
25
|
+
existingProcessRecord[key] ??= value;
|
|
26
|
+
}
|
|
27
|
+
existingProcessRecord["browser"] = true;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
ensureBrowserProcess();
|
|
31
|
+
})();
|
|
32
|
+
(function patchObsidianRequire() {
|
|
33
|
+
const originalRequire = require;
|
|
34
|
+
if (!originalRequire || originalRequire.__isPatched) {
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
require = Object.assign(
|
|
39
|
+
(id) => requirePatched(id),
|
|
40
|
+
originalRequire,
|
|
41
|
+
{
|
|
42
|
+
__isPatched: true
|
|
43
|
+
}
|
|
44
|
+
);
|
|
45
|
+
|
|
46
|
+
function extractDefault(module) {
|
|
47
|
+
return module && module.__esModule && 'default' in module ? module.default : module;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const OBSIDIAN_BUILT_IN_MODULE_NAMES = new Set([
|
|
51
|
+
'@codemirror/autocomplete',
|
|
52
|
+
'@codemirror/collab',
|
|
53
|
+
'@codemirror/commands',
|
|
54
|
+
'@codemirror/language',
|
|
55
|
+
'@codemirror/lint',
|
|
56
|
+
'@codemirror/search',
|
|
57
|
+
'@codemirror/state',
|
|
58
|
+
'@codemirror/text',
|
|
59
|
+
'@codemirror/view',
|
|
60
|
+
'@lezer/common',
|
|
61
|
+
'@lezer/highlight',
|
|
62
|
+
'@lezer/lr',
|
|
63
|
+
'obsidian']
|
|
64
|
+
);
|
|
65
|
+
|
|
66
|
+
const DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES = new Set([
|
|
67
|
+
'@codemirror/closebrackets',
|
|
68
|
+
'@codemirror/comment',
|
|
69
|
+
'@codemirror/fold',
|
|
70
|
+
'@codemirror/gutter',
|
|
71
|
+
'@codemirror/highlight',
|
|
72
|
+
'@codemirror/history',
|
|
73
|
+
'@codemirror/matchbrackets',
|
|
74
|
+
'@codemirror/panel',
|
|
75
|
+
'@codemirror/rangeset',
|
|
76
|
+
'@codemirror/rectangular-selection',
|
|
77
|
+
'@codemirror/stream-parser',
|
|
78
|
+
'@codemirror/tooltip']
|
|
79
|
+
);
|
|
80
|
+
|
|
81
|
+
function requirePatched(id) {
|
|
82
|
+
if (OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id) || DEPRECATED_OBSIDIAN_BUILT_IN_MODULE_NAMES.has(id)) {
|
|
83
|
+
return originalRequire?.(id);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
// eslint-disable-next-line @typescript-eslint/no-deprecated, obsidianmd/no-global-this -- Need access to app. Actively use globalThis.
|
|
87
|
+
if (globalThis.app.isMobile) {
|
|
88
|
+
if (id === 'process' || id === 'node:process') {
|
|
89
|
+
// eslint-disable-next-line no-console -- Valid usage.
|
|
90
|
+
console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Fake process object is returned instead.`);
|
|
91
|
+
|
|
92
|
+
return process;
|
|
93
|
+
}
|
|
94
|
+
} else {
|
|
95
|
+
const module = originalRequire?.(id);
|
|
96
|
+
if (module) {
|
|
97
|
+
return extractDefault(module);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// eslint-disable-next-line no-console -- Valid usage.
|
|
102
|
+
console.debug(`The most likely you can safely ignore this error. Module not found: ${id}. Empty object is returned instead.`);
|
|
103
|
+
return {};
|
|
104
|
+
}
|
|
105
|
+
})();
|
|
106
|
+
|
|
107
|
+
"use strict";
|
|
108
|
+
var __create = Object.create;
|
|
109
|
+
var __defProp = Object.defineProperty;
|
|
110
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
111
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
112
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
113
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
114
|
+
var __export = (target, all) => {
|
|
115
|
+
for (var name in all)
|
|
116
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
117
|
+
};
|
|
118
|
+
var __copyProps = (to, from, except, desc) => {
|
|
119
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
120
|
+
for (let key of __getOwnPropNames(from))
|
|
121
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
122
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
123
|
+
}
|
|
124
|
+
return to;
|
|
125
|
+
};
|
|
126
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
127
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
128
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
129
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
130
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
131
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
132
|
+
mod
|
|
133
|
+
));
|
|
134
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
135
|
+
var e2e_runner_support_exports = {};
|
|
136
|
+
__export(e2e_runner_support_exports, {
|
|
137
|
+
DEFAULT_END_TO_END_SPECS: () => DEFAULT_END_TO_END_SPECS,
|
|
138
|
+
assertProjectPackagesInstalled: () => assertProjectPackagesInstalled
|
|
139
|
+
});
|
|
140
|
+
module.exports = __toCommonJS(e2e_runner_support_exports);
|
|
141
|
+
var import_root = require('@mnaoumov/typescript-dev-toolkit/root');
|
|
142
|
+
var import_path = require('@mnaoumov/typescript-lib/path');
|
|
143
|
+
var import_node_module = require('node:module');
|
|
144
|
+
var import_node_process = __toESM(((module) => module && module.__esModule && 'default' in module ? module.default : module)(require('node:process')), 1);
|
|
145
|
+
const DEFAULT_END_TO_END_SPECS = "./e2e/**/*.spec.ts";
|
|
146
|
+
function assertProjectPackagesInstalled(params) {
|
|
147
|
+
const projectFolder = params.projectFolder ?? (0, import_root.getRootFolder)() ?? import_node_process.default.cwd();
|
|
148
|
+
const require2 = (0, import_node_module.createRequire)((0, import_path.join)(projectFolder, "package.json"));
|
|
149
|
+
const missingPackageNames = params.packageNames.filter((packageName) => !isPackageInstalled(require2, packageName));
|
|
150
|
+
if (missingPackageNames.length === 0) {
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
throw new Error(
|
|
154
|
+
`${params.requester} needs ${missingPackageNames.map((packageName) => `\`${packageName}\``).join(", ")}, which the project does not have. Install with: npm install --save-dev ${missingPackageNames.join(" ")}`
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
function isPackageInstalled(require2, packageName) {
|
|
158
|
+
try {
|
|
159
|
+
require2.resolve(`${packageName}/package.json`);
|
|
160
|
+
return true;
|
|
161
|
+
} catch (error) {
|
|
162
|
+
return error.code === "ERR_PACKAGE_PATH_NOT_EXPORTED";
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
166
|
+
0 && (module.exports = {
|
|
167
|
+
DEFAULT_END_TO_END_SPECS,
|
|
168
|
+
assertProjectPackagesInstalled
|
|
169
|
+
});
|
|
170
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy90ZXN0LXJ1bm5lcnMvZTJlLXJ1bm5lci1zdXBwb3J0LnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGZpbGVcbiAqXG4gKiBXaGF0IHRoZSBlbmQtdG8tZW5kIHJ1bm5lcnMgc2hhcmU6IHdoZXJlIHRoZSBzcGVjcyBsaXZlLCBhbmQgdGhlIGNoZWNrIHRoYXQgdGhlIHBhY2thZ2VzIGEgcnVubmVyIGRyaXZlcyBhcmVcbiAqIGluc3RhbGxlZCBpbiB0aGUgcHJvamVjdCwgc28gYSBtaXNzaW5nIG9uZSBpcyByZXBvcnRlZCB3aXRoIHRoZSBgbnBtIGluc3RhbGxgIGxpbmUgdGhhdCBmaXhlcyBpdCBpbnN0ZWFkIG9mIGFzIGFcbiAqIHNoZWxsJ3MgYGNvbW1hbmQgbm90IGZvdW5kYC5cbiAqL1xuXG5pbXBvcnQgeyBnZXRSb290Rm9sZGVyIH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtZGV2LXRvb2xraXQvcm9vdCc7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSAnQG1uYW91bW92L3R5cGVzY3JpcHQtbGliL3BhdGgnO1xuaW1wb3J0IHsgY3JlYXRlUmVxdWlyZSB9IGZyb20gJ25vZGU6bW9kdWxlJztcbmltcG9ydCBwcm9jZXNzIGZyb20gJ25vZGU6cHJvY2Vzcyc7XG5cbi8qKlxuICogVGhlIHNwZWMgZmlsZXMgdGhlIGVuZC10by1lbmQgcnVubmVycyBydW4gYnkgZGVmYXVsdC5cbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfRU5EX1RPX0VORF9TUEVDUyA9ICcuL2UyZS8qKi8qLnNwZWMudHMnO1xuXG4vKipcbiAqIFBhcmFtZXRlcnMgZm9yIHtAbGluayBhc3NlcnRQcm9qZWN0UGFja2FnZXNJbnN0YWxsZWR9LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEFzc2VydFByb2plY3RQYWNrYWdlc0luc3RhbGxlZFBhcmFtcyB7XG4gIC8qKlxuICAgKiBUaGUgcGFja2FnZXMgdGhlIHJ1bm5lciBuZWVkcy5cbiAgICovXG4gIHJlYWRvbmx5IHBhY2thZ2VOYW1lczogcmVhZG9ubHkgc3RyaW5nW107XG5cbiAgLyoqXG4gICAqIFRoZSBmb2xkZXIgd2hvc2UgYG5vZGVfbW9kdWxlc2AgdGhlIHBhY2thZ2VzIGFyZSByZXNvbHZlZCBmcm9tLiBEZWZhdWx0cyB0byB0aGUgcHJvamVjdCByb290LlxuICAgKi9cbiAgcmVhZG9ubHkgcHJvamVjdEZvbGRlcj86IHN0cmluZztcblxuICAvKipcbiAgICogV2hhdCBuZWVkcyB0aGUgcGFja2FnZXMsIGFzIHRoZSBlcnJvciBtZXNzYWdlIG5hbWVzIGl0LCBlLmcuIGB0ZXN0RW5kVG9FbmRXaXRoV2Rpb09ic2lkaWFuKClgLlxuICAgKi9cbiAgcmVhZG9ubHkgcmVxdWVzdGVyOiBzdHJpbmc7XG59XG5cbi8qKlxuICogVGhyb3dzIHdoZW4gYW55IG9mIHRoZSBwYWNrYWdlcyBpcyBub3QgaW5zdGFsbGVkIGluIHRoZSBwcm9qZWN0LCBuYW1pbmcgdGhlIGBucG0gaW5zdGFsbGAgbGluZS5cbiAqXG4gKiBAcGFyYW0gcGFyYW1zIC0gVGhlIHtAbGluayBBc3NlcnRQcm9qZWN0UGFja2FnZXNJbnN0YWxsZWRQYXJhbXN9LlxuICogQHRocm93cyBXaGVuIGEgcGFja2FnZSBpcyBtaXNzaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXNzZXJ0UHJvamVjdFBhY2thZ2VzSW5zdGFsbGVkKHBhcmFtczogQXNzZXJ0UHJvamVjdFBhY2thZ2VzSW5zdGFsbGVkUGFyYW1zKTogdm9pZCB7XG4gIGNvbnN0IHByb2plY3RGb2xkZXIgPSBwYXJhbXMucHJvamVjdEZvbGRlciA/PyBnZXRSb290Rm9sZGVyKCkgPz8gcHJvY2Vzcy5jd2QoKTtcbiAgY29uc3QgcmVxdWlyZSA9IGNyZWF0ZVJlcXVpcmUoam9pbihwcm9qZWN0Rm9sZGVyLCAncGFja2FnZS5qc29uJykpO1xuICBjb25zdCBtaXNzaW5nUGFja2FnZU5hbWVzID0gcGFyYW1zLnBhY2thZ2VOYW1lcy5maWx0ZXIoKHBhY2thZ2VOYW1lKSA9PiAhaXNQYWNrYWdlSW5zdGFsbGVkKHJlcXVpcmUsIHBhY2thZ2VOYW1lKSk7XG4gIGlmIChtaXNzaW5nUGFja2FnZU5hbWVzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRocm93IG5ldyBFcnJvcihcbiAgICBgJHtwYXJhbXMucmVxdWVzdGVyfSBuZWVkcyAke21pc3NpbmdQYWNrYWdlTmFtZXMubWFwKChwYWNrYWdlTmFtZSkgPT4gYFxcYCR7cGFja2FnZU5hbWV9XFxgYCkuam9pbignLCAnKX0sIHdoaWNoIHRoZSBwcm9qZWN0IGRvZXMgbm90IGhhdmUuIGBcbiAgICAgICsgYEluc3RhbGwgd2l0aDogbnBtIGluc3RhbGwgLS1zYXZlLWRldiAke21pc3NpbmdQYWNrYWdlTmFtZXMuam9pbignICcpfWBcbiAgKTtcbn1cblxuZnVuY3Rpb24gaXNQYWNrYWdlSW5zdGFsbGVkKHJlcXVpcmU6IE5vZGVKUy5SZXF1aXJlLCBwYWNrYWdlTmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHRyeSB7XG4gICAgcmVxdWlyZS5yZXNvbHZlKGAke3BhY2thZ2VOYW1lfS9wYWNrYWdlLmpzb25gKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAvLyBBIHBhY2thZ2Ugd2hvc2UgYGV4cG9ydHNgIG1hcCBkb2VzIG5vdCBsaXN0IGAuL3BhY2thZ2UuanNvbmAgaXMgaW5zdGFsbGVkIGFsbCB0aGUgc2FtZS5cbiAgICByZXR1cm4gKGVycm9yIGFzIE5vZGVKUy5FcnJub0V4Y2VwdGlvbikuY29kZSA9PT0gJ0VSUl9QQUNLQUdFX1BBVEhfTk9UX0VYUE9SVEVEJztcbiAgfVxufVxuIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQVFBLGtCQUE4QjtBQUM5QixrQkFBcUI7QUFDckIseUJBQThCO0FBQzlCLDBCQUFvQjtBQUtiLE1BQU0sMkJBQTJCO0FBNEJqQyxTQUFTLCtCQUErQixRQUFvRDtBQUNqRyxRQUFNLGdCQUFnQixPQUFPLHFCQUFpQiwyQkFBYyxLQUFLLG9CQUFBQSxRQUFRLElBQUk7QUFDN0UsUUFBTUMsZUFBVSxzQ0FBYyxrQkFBSyxlQUFlLGNBQWMsQ0FBQztBQUNqRSxRQUFNLHNCQUFzQixPQUFPLGFBQWEsT0FBTyxDQUFDLGdCQUFnQixDQUFDLG1CQUFtQkEsVUFBUyxXQUFXLENBQUM7QUFDakgsTUFBSSxvQkFBb0IsV0FBVyxHQUFHO0FBQ3BDO0FBQUEsRUFDRjtBQUVBLFFBQU0sSUFBSTtBQUFBLElBQ1IsR0FBRyxPQUFPLFNBQVMsVUFBVSxvQkFBb0IsSUFBSSxDQUFDLGdCQUFnQixLQUFLLFdBQVcsSUFBSSxFQUFFLEtBQUssSUFBSSxDQUFDLDJFQUMxRCxvQkFBb0IsS0FBSyxHQUFHLENBQUM7QUFBQSxFQUMzRTtBQUNGO0FBRUEsU0FBUyxtQkFBbUJBLFVBQXlCLGFBQThCO0FBQ2pGLE1BQUk7QUFDRixJQUFBQSxTQUFRLFFBQVEsR0FBRyxXQUFXLGVBQWU7QUFDN0MsV0FBTztBQUFBLEVBQ1QsU0FBUyxPQUFPO0FBRWQsV0FBUSxNQUFnQyxTQUFTO0FBQUEsRUFDbkQ7QUFDRjsiLCJuYW1lcyI6WyJwcm9jZXNzIiwicmVxdWlyZSJdfQ==
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/// <reference path="../library-references.d.cts" />
|
|
2
|
+
/**
|
|
3
|
+
* @file
|
|
4
|
+
*
|
|
5
|
+
* What the end-to-end runners share: where the specs live, and the check that the packages a runner drives are
|
|
6
|
+
* installed in the project, so a missing one is reported with the `npm install` line that fixes it instead of as a
|
|
7
|
+
* shell's `command not found`.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* The spec files the end-to-end runners run by default.
|
|
11
|
+
*/
|
|
12
|
+
export declare const DEFAULT_END_TO_END_SPECS = "./e2e/**/*.spec.ts";
|
|
13
|
+
/**
|
|
14
|
+
* Parameters for {@link assertProjectPackagesInstalled}.
|
|
15
|
+
*/
|
|
16
|
+
export interface AssertProjectPackagesInstalledParams {
|
|
17
|
+
/**
|
|
18
|
+
* The packages the runner needs.
|
|
19
|
+
*/
|
|
20
|
+
readonly packageNames: readonly string[];
|
|
21
|
+
/**
|
|
22
|
+
* The folder whose `node_modules` the packages are resolved from. Defaults to the project root.
|
|
23
|
+
*/
|
|
24
|
+
readonly projectFolder?: string;
|
|
25
|
+
/**
|
|
26
|
+
* What needs the packages, as the error message names it, e.g. `testEndToEndWithWdioObsidian()`.
|
|
27
|
+
*/
|
|
28
|
+
readonly requester: string;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Throws when any of the packages is not installed in the project, naming the `npm install` line.
|
|
32
|
+
*
|
|
33
|
+
* @param params - The {@link AssertProjectPackagesInstalledParams}.
|
|
34
|
+
* @throws When a package is missing.
|
|
35
|
+
*/
|
|
36
|
+
export declare function assertProjectPackagesInstalled(params: AssertProjectPackagesInstalledParams): void;
|