nuxt-layerscope 0.1.1 → 0.1.3
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/CHANGELOG.md +15 -0
- package/dist/analyze-DVzyPH7N.mjs +2 -0
- package/dist/{analyze-C78UDFtY.mjs → analyze-QaYmBXyK.mjs} +32 -6
- package/dist/api.d.mts +7 -2
- package/dist/api.mjs +4 -4
- package/dist/bin.mjs +22 -14
- package/dist/eslint.mjs +3 -3
- package/dist/{file-analysis-D9TGP_Nb.mjs → file-analysis-Bh7qcWUK.mjs} +3 -3
- package/dist/index.mjs +3 -3
- package/dist/{layer-factory-xZmIAPrA.mjs → layer-factory-DFh7nkFH.mjs} +15 -1
- package/dist/{report-DtAi0vPb.mjs → report-CKhXT50W.mjs} +1 -1
- package/dist/{report-BNW0GCl9.mjs → report-DShTCB59.mjs} +26 -12
- package/dist/{unused-Cgg4-LKM.mjs → unused-BtsPSfxb.mjs} +1 -1
- package/dist/{version-D6whhsHH.mjs → version-DFWOUgi5.mjs} +1 -1
- package/package.json +1 -1
- package/dist/analyze-Du9Dkd8L.mjs +0 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.3
|
|
4
|
+
|
|
5
|
+
- Notes and the `--verbose` line are printed after the report, in every command, so they are the
|
|
6
|
+
last thing on screen. `note:` is highlighted in a terminal.
|
|
7
|
+
- `layerscope check` lists files with errors after files with only warnings, so the errors stay
|
|
8
|
+
next to the summary in a long report.
|
|
9
|
+
- The text report colors severities, rule names and the summary in a terminal. `NO_COLOR` and
|
|
10
|
+
`FORCE_COLOR` are honoured.
|
|
11
|
+
|
|
12
|
+
## 0.1.2
|
|
13
|
+
|
|
14
|
+
- A note appears when `nuxt.config` is newer than the registry, because changes to its
|
|
15
|
+
`layerscope` key only apply after `nuxi prepare`, `dev` or `build`.
|
|
16
|
+
- Layer errors caused by the `layerscope` key of `nuxt.config` name it as their source.
|
|
17
|
+
|
|
3
18
|
## 0.1.1
|
|
4
19
|
|
|
5
20
|
- Names inside type syntax are no longer reported as unresolved references: labeled tuple members
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { c as realPath, d as effectiveConfig,
|
|
1
|
+
import { c as realPath, d as effectiveConfig, f as labelConfigError, g as ruleSeverity, h as isRuleName, s as readJson, v as LayerscopeError } from "./layer-factory-DFh7nkFH.mjs";
|
|
2
2
|
import { r as pascalCase, t as compareStrings } from "./strings-CrOjNZmB.mjs";
|
|
3
3
|
import { t as globComponents } from "./component-files-DgOXNE6l.mjs";
|
|
4
|
-
import { c as createOwnerLookup, d as createAnalysisEnv, f as readRegistry, h as boundaryFindings, m as loadSymbolTable, n as analyzeFile, p as tableFromRegistry, r as collectFiles, u as resolveLayers, v as loadConfig } from "./file-analysis-
|
|
4
|
+
import { c as createOwnerLookup, d as createAnalysisEnv, f as readRegistry, h as boundaryFindings, m as loadSymbolTable, n as analyzeFile, p as tableFromRegistry, r as collectFiles, u as resolveLayers, v as loadConfig } from "./file-analysis-Bh7qcWUK.mjs";
|
|
5
5
|
import { basename, extname, join, relative, resolve } from "pathe";
|
|
6
|
-
import { existsSync, writeFileSync } from "node:fs";
|
|
6
|
+
import { existsSync, statSync, writeFileSync } from "node:fs";
|
|
7
7
|
import { escapePath, glob } from "tinyglobby";
|
|
8
8
|
import { spawnSync } from "node:child_process";
|
|
9
9
|
//#region src/baseline/index.ts
|
|
@@ -149,6 +149,24 @@ function runRules(input) {
|
|
|
149
149
|
};
|
|
150
150
|
}
|
|
151
151
|
//#endregion
|
|
152
|
+
//#region src/analyze/config-freshness.ts
|
|
153
|
+
const NUXT_CONFIG_FILES = [
|
|
154
|
+
"nuxt.config.ts",
|
|
155
|
+
"nuxt.config.mts",
|
|
156
|
+
"nuxt.config.js",
|
|
157
|
+
"nuxt.config.mjs"
|
|
158
|
+
];
|
|
159
|
+
/**
|
|
160
|
+
* The registry holds the `layerscope` key of `nuxt.config` as it was at the last `nuxi prepare`,
|
|
161
|
+
* `dev` or `build`, so an edit made since then does not apply yet.
|
|
162
|
+
*/
|
|
163
|
+
function staleConfigNote(rootDir, registryFile) {
|
|
164
|
+
const config = NUXT_CONFIG_FILES.map((name) => join(rootDir, name)).find((file) => existsSync(file));
|
|
165
|
+
if (config === void 0 || !existsSync(registryFile)) return null;
|
|
166
|
+
if (statSync(config).mtimeMs <= statSync(registryFile).mtimeMs) return null;
|
|
167
|
+
return "nuxt.config is newer than the layerscope registry, so changes to its \"layerscope\" key do not apply yet. Run \"nuxi prepare\" again, or pass --prepare.";
|
|
168
|
+
}
|
|
169
|
+
//#endregion
|
|
152
170
|
//#region src/analyze/freshness.ts
|
|
153
171
|
const RERUN_HINT = "Run \"nuxi prepare\" again, or pass --prepare.";
|
|
154
172
|
const COMPONENT_SUFFIX = /(?:\.(?:client|server))?(?:\.global|\.island)*$/u;
|
|
@@ -266,13 +284,21 @@ function recordedConfig(buildDir, registry) {
|
|
|
266
284
|
async function loadEnvironment(options) {
|
|
267
285
|
const { rootDir, buildDir } = options;
|
|
268
286
|
const { registry, table, ...symbols } = loadSymbols(buildDir, options.source);
|
|
269
|
-
const
|
|
270
|
-
const
|
|
287
|
+
const recorded = recordedConfig(buildDir, registry);
|
|
288
|
+
const config = effectiveConfig(options.config, recorded);
|
|
289
|
+
const { layers, ownerOf, notes } = await loadLayers(rootDir, config, registry?.layers).catch((error) => {
|
|
290
|
+
throw labelConfigError(error, recorded);
|
|
291
|
+
});
|
|
292
|
+
const stale = registry === null ? null : staleConfigNote(rootDir, symbols.sourceFile);
|
|
271
293
|
await (registry === null ? assertFresh(table, layers) : assertRegistryFresh(table, registry));
|
|
272
294
|
return {
|
|
273
295
|
...symbols,
|
|
274
296
|
config,
|
|
275
|
-
notes: [
|
|
297
|
+
notes: [
|
|
298
|
+
...symbols.notes,
|
|
299
|
+
...notes,
|
|
300
|
+
...stale === null ? [] : [stale]
|
|
301
|
+
],
|
|
276
302
|
registry,
|
|
277
303
|
layers,
|
|
278
304
|
env: createAnalysisEnv(table, ownerOf, buildDir, config)
|
package/dist/api.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { a as Context, c as Layer, d as Reference, f as ReferenceKind, g as SourceOption, h as Severity, i as BaselineResult, l as LayerRule, m as RuleName, n as AnalyzeResult, o as Edge, p as ResolutionSource, r as BaselineEntry, s as Finding, t as defineConfig, u as LayerscopeConfig } from "./define-DNRGLVG_.mjs";
|
|
2
2
|
import { t as ProjectConfig } from "./effective-Dqg4EwH_.mjs";
|
|
3
|
+
import { styleText } from "node:util";
|
|
3
4
|
//#region src/analyze/index.d.ts
|
|
4
5
|
interface AnalyzeOptions {
|
|
5
6
|
/** Defaults to `process.cwd()`. */
|
|
@@ -114,11 +115,15 @@ interface Registry {
|
|
|
114
115
|
config?: ProjectConfig;
|
|
115
116
|
}
|
|
116
117
|
//#endregion
|
|
118
|
+
//#region src/utils/style.d.ts
|
|
119
|
+
/** Wraps text in terminal styles, e.g. `paint('red', 'error')`. */
|
|
120
|
+
type Paint = (format: Parameters<typeof styleText>[0], text: string) => string;
|
|
121
|
+
//#endregion
|
|
117
122
|
//#region src/report/index.d.ts
|
|
118
123
|
export declare const OUTPUT_FORMATS: readonly ['text', 'github', 'json'];
|
|
119
124
|
type OutputFormat = (typeof OUTPUT_FORMATS)[number];
|
|
120
|
-
/** Paths in the output are relative to `cwd`. */
|
|
121
|
-
export declare function formatResult(result: AnalyzeResult, format: OutputFormat, cwd?: string): string;
|
|
125
|
+
/** Paths in the output are relative to `cwd`. Only the text format uses `paint`. */
|
|
126
|
+
export declare function formatResult(result: AnalyzeResult, format: OutputFormat, cwd?: string, paint?: Paint): string;
|
|
122
127
|
//#endregion
|
|
123
128
|
//#region src/report/json.d.ts
|
|
124
129
|
/** Bumped on breaking changes to the JSON report shape. */
|
package/dist/api.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { l as REGISTRY_FILE, u as REGISTRY_VERSION, v as LayerscopeError } from "./layer-factory-DFh7nkFH.mjs";
|
|
2
2
|
import { t as defineConfig } from "./define-l62B9fVk.mjs";
|
|
3
|
-
import { i as createBaseline, n as BASELINE_FILE, r as BASELINE_VERSION, t as analyze } from "./analyze-
|
|
4
|
-
import { i as JSON_REPORT_VERSION, n as formatResult, t as OUTPUT_FORMATS } from "./report-
|
|
5
|
-
import { r as buildGraph, t as findUnused } from "./unused-
|
|
3
|
+
import { i as createBaseline, n as BASELINE_FILE, r as BASELINE_VERSION, t as analyze } from "./analyze-QaYmBXyK.mjs";
|
|
4
|
+
import { i as JSON_REPORT_VERSION, n as formatResult, t as OUTPUT_FORMATS } from "./report-DShTCB59.mjs";
|
|
5
|
+
import { r as buildGraph, t as findUnused } from "./unused-BtsPSfxb.mjs";
|
|
6
6
|
export { BASELINE_FILE, BASELINE_VERSION, JSON_REPORT_VERSION, LayerscopeError, OUTPUT_FORMATS, REGISTRY_FILE, REGISTRY_VERSION, analyze, buildGraph, createBaseline, defineConfig, findUnused, formatResult };
|
package/dist/bin.mjs
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import {
|
|
2
|
+
import { v as LayerscopeError } from "./layer-factory-DFh7nkFH.mjs";
|
|
3
3
|
import { i as plural, r as pascalCase } from "./strings-CrOjNZmB.mjs";
|
|
4
|
-
import { a as writeBaseline, i as createBaseline, n as BASELINE_FILE, t as analyze } from "./analyze-
|
|
5
|
-
import { n as formatResult, r as isOutputFormat, t as OUTPUT_FORMATS } from "./report-
|
|
6
|
-
import { i as edgeStatus, n as GRAPH_LEVELS, r as buildGraph, t as findUnused } from "./unused-
|
|
4
|
+
import { a as writeBaseline, i as createBaseline, n as BASELINE_FILE, t as analyze } from "./analyze-QaYmBXyK.mjs";
|
|
5
|
+
import { a as paintFor, n as formatResult, r as isOutputFormat, t as OUTPUT_FORMATS } from "./report-DShTCB59.mjs";
|
|
6
|
+
import { i as edgeStatus, n as GRAPH_LEVELS, r as buildGraph, t as findUnused } from "./unused-BtsPSfxb.mjs";
|
|
7
7
|
import { relative, resolve } from "pathe";
|
|
8
8
|
import { cac } from "cac";
|
|
9
9
|
//#region src/commands/shared.ts
|
|
@@ -20,14 +20,19 @@ function toSource(value) {
|
|
|
20
20
|
if (source === void 0) throw new LayerscopeError(`Unknown source "${value}". Use ${SOURCE_OPTIONS.join(", ")}.`);
|
|
21
21
|
return source;
|
|
22
22
|
}
|
|
23
|
-
/**
|
|
23
|
+
/**
|
|
24
|
+
* Diagnostics go to stderr, so stdout stays machine-readable in every format. Call it after the
|
|
25
|
+
* report is written: notes at the end are the ones a reader still sees when the report scrolled.
|
|
26
|
+
*/
|
|
24
27
|
function writeNotes(result, verbose) {
|
|
25
|
-
const
|
|
28
|
+
const paint = paintFor(process.stderr);
|
|
29
|
+
const lines = result.notes.map((note) => `${paint(["yellow", "bold"], "layerscope: note:")} ${note}`);
|
|
26
30
|
if (verbose) {
|
|
27
31
|
const kind = result.source === "registry" ? "the registry" : "the generated .d.ts files";
|
|
28
|
-
|
|
32
|
+
const source = relative(process.cwd(), result.sourceFile);
|
|
33
|
+
lines.unshift(paint("dim", `layerscope: symbols from ${kind} (${source})`));
|
|
29
34
|
}
|
|
30
|
-
if (lines.length > 0) process.stderr.write(`${lines.join("\n")}\n`);
|
|
35
|
+
if (lines.length > 0) process.stderr.write(`${process.stdout.isTTY ? "\n" : ""}${lines.join("\n")}\n`);
|
|
31
36
|
}
|
|
32
37
|
//#endregion
|
|
33
38
|
//#region src/commands/check.ts
|
|
@@ -38,11 +43,11 @@ async function updateBaseline(rootDir, flags) {
|
|
|
38
43
|
prepare: flags.prepare,
|
|
39
44
|
source: toSource(flags.source)
|
|
40
45
|
});
|
|
41
|
-
writeNotes(result, flags.verbose === true);
|
|
42
46
|
const file = resolve(rootDir, flags.baseline);
|
|
43
47
|
writeBaseline(file, createBaseline(result.findings, rootDir));
|
|
44
48
|
const count = plural(result.findings.length, "finding");
|
|
45
49
|
process.stdout.write(`✔ Wrote ${count} to ${relative(process.cwd(), file)}\n`);
|
|
50
|
+
writeNotes(result, flags.verbose === true);
|
|
46
51
|
return 0;
|
|
47
52
|
}
|
|
48
53
|
async function check(root, flags) {
|
|
@@ -57,8 +62,8 @@ async function check(root, flags) {
|
|
|
57
62
|
source: toSource(flags.source),
|
|
58
63
|
baseline: flags.baseline
|
|
59
64
|
});
|
|
65
|
+
process.stdout.write(formatResult(result, format, process.cwd(), paintFor(process.stdout)));
|
|
60
66
|
writeNotes(result, flags.verbose === true);
|
|
61
|
-
process.stdout.write(formatResult(result, format));
|
|
62
67
|
return result.findings.some((finding) => finding.severity === "error") ? 1 : 0;
|
|
63
68
|
}
|
|
64
69
|
function registerCheck(cli) {
|
|
@@ -162,8 +167,8 @@ async function graph(root, flags) {
|
|
|
162
167
|
prepare: flags.prepare,
|
|
163
168
|
source: toSource(flags.source)
|
|
164
169
|
});
|
|
165
|
-
writeNotes(result, flags.verbose === true);
|
|
166
170
|
process.stdout.write(formatGraph(buildGraph(result, result.config, level), format));
|
|
171
|
+
writeNotes(result, flags.verbose === true);
|
|
167
172
|
return 0;
|
|
168
173
|
}
|
|
169
174
|
function registerGraph(cli) {
|
|
@@ -216,8 +221,8 @@ async function unused(root, flags) {
|
|
|
216
221
|
prepare: flags.prepare,
|
|
217
222
|
source: toSource(flags.source)
|
|
218
223
|
});
|
|
219
|
-
writeNotes(result, flags.verbose === true);
|
|
220
224
|
process.stdout.write(formatUnused(findUnused(result), format));
|
|
225
|
+
writeNotes(result, flags.verbose === true);
|
|
221
226
|
return 0;
|
|
222
227
|
}
|
|
223
228
|
function registerUnused(cli) {
|
|
@@ -331,10 +336,13 @@ async function why(symbol, root, flags) {
|
|
|
331
336
|
prepare: flags.prepare,
|
|
332
337
|
source: toSource(flags.source)
|
|
333
338
|
});
|
|
334
|
-
writeNotes(result, flags.verbose === true);
|
|
335
339
|
const targets = findUses(result, symbol, result.config);
|
|
336
|
-
if (targets.length === 0)
|
|
340
|
+
if (targets.length === 0) {
|
|
341
|
+
writeNotes(result, flags.verbose === true);
|
|
342
|
+
throw new LayerscopeError(`No uses of "${symbol}" found.`);
|
|
343
|
+
}
|
|
337
344
|
process.stdout.write(formatWhy(symbol, targets, format));
|
|
345
|
+
writeNotes(result, flags.verbose === true);
|
|
338
346
|
return 0;
|
|
339
347
|
}
|
|
340
348
|
function registerWhy(cli) {
|
package/dist/eslint.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { d as effectiveConfig, l as REGISTRY_FILE } from "./layer-factory-
|
|
2
|
-
import { t as packageVersion } from "./version-
|
|
3
|
-
import { _ as findConfigFile, a as lineColumn, c as createOwnerLookup, d as createAnalysisEnv, f as readRegistry, h as boundaryFindings, i as isCheckedFile, l as nameLayers, o as offsetAt, p as tableFromRegistry, s as scanFile, t as FileAnalysis, y as loadConfigSync } from "./file-analysis-
|
|
1
|
+
import { d as effectiveConfig, l as REGISTRY_FILE } from "./layer-factory-DFh7nkFH.mjs";
|
|
2
|
+
import { t as packageVersion } from "./version-DFWOUgi5.mjs";
|
|
3
|
+
import { _ as findConfigFile, a as lineColumn, c as createOwnerLookup, d as createAnalysisEnv, f as readRegistry, h as boundaryFindings, i as isCheckedFile, l as nameLayers, o as offsetAt, p as tableFromRegistry, s as scanFile, t as FileAnalysis, y as loadConfigSync } from "./file-analysis-Bh7qcWUK.mjs";
|
|
4
4
|
import { dirname, join, relative, resolve } from "pathe";
|
|
5
5
|
import { existsSync, readFileSync, statSync } from "node:fs";
|
|
6
6
|
//#region src/eslint/lint-file.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as isClonedFrom, c as realPath, g as
|
|
1
|
+
import { _ as LayerConfigError, a as isClonedFrom, c as realPath, g as ruleSeverity, i as layerFromPath, l as REGISTRY_FILE, m as validateConfig, n as deriveDirectories, o as isFile, r as layerFromNuxt, s as readJson, t as ROOT_LAYER_NAME, v as LayerscopeError } from "./layer-factory-DFh7nkFH.mjs";
|
|
2
2
|
import { n as escapeRegExp, r as pascalCase, t as compareStrings } from "./strings-CrOjNZmB.mjs";
|
|
3
3
|
import { dirname, isAbsolute, join, relative, resolve } from "pathe";
|
|
4
4
|
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
@@ -408,10 +408,10 @@ function validateLayers(layers, config) {
|
|
|
408
408
|
for (const [name, rule] of Object.entries(config.layers ?? {})) {
|
|
409
409
|
if (!names.has(name)) {
|
|
410
410
|
const known = [...names].toSorted().join(", ");
|
|
411
|
-
throw new
|
|
411
|
+
throw new LayerConfigError(`Unknown layer "${name}" in config. Known layers: ${known}`);
|
|
412
412
|
}
|
|
413
413
|
const unknown = rule.allow?.find((allowed) => !names.has(allowed));
|
|
414
|
-
if (unknown !== void 0) throw new
|
|
414
|
+
if (unknown !== void 0) throw new LayerConfigError(`layers.${name}.allow: unknown layer "${unknown}"`);
|
|
415
415
|
}
|
|
416
416
|
}
|
|
417
417
|
//#endregion
|
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { l as REGISTRY_FILE, p as pickProjectConfig, r as layerFromNuxt } from "./layer-factory-DFh7nkFH.mjs";
|
|
2
2
|
import { t as summarize } from "./summary-DiUYKMPe.mjs";
|
|
3
3
|
import { i as plural, t as compareStrings } from "./strings-CrOjNZmB.mjs";
|
|
4
|
-
import { t as packageVersion } from "./version-
|
|
4
|
+
import { t as packageVersion } from "./version-DFWOUgi5.mjs";
|
|
5
5
|
import { t as globComponents } from "./component-files-DgOXNE6l.mjs";
|
|
6
6
|
import { t as defineConfig } from "./define-l62B9fVk.mjs";
|
|
7
7
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
@@ -106,7 +106,7 @@ function renderError(message) {
|
|
|
106
106
|
//#region src/devtools/index.ts
|
|
107
107
|
const DEVTOOLS_ROUTE = "/__layerscope";
|
|
108
108
|
async function renderReport(nuxt, format) {
|
|
109
|
-
const [{ analyze }, { formatResult }] = await Promise.all([import("./analyze-
|
|
109
|
+
const [{ analyze }, { formatResult }] = await Promise.all([import("./analyze-DVzyPH7N.mjs"), import("./report-CKhXT50W.mjs")]);
|
|
110
110
|
const { rootDir, app } = nuxt.options;
|
|
111
111
|
const result = await analyze({ rootDir });
|
|
112
112
|
if (format === "json") return formatResult(result, "json", rootDir);
|
|
@@ -9,6 +9,15 @@ var LayerscopeError = class extends Error {
|
|
|
9
9
|
}
|
|
10
10
|
};
|
|
11
11
|
//#endregion
|
|
12
|
+
//#region src/layer-config-error.ts
|
|
13
|
+
/** A layer name in the config that matches no layer. */
|
|
14
|
+
var LayerConfigError = class extends LayerscopeError {
|
|
15
|
+
constructor(..._args) {
|
|
16
|
+
super(..._args);
|
|
17
|
+
this.name = "LayerConfigError";
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
//#endregion
|
|
12
21
|
//#region src/config/rules.ts
|
|
13
22
|
const DEFAULT_SEVERITY = {
|
|
14
23
|
"layer-boundary": "error",
|
|
@@ -70,6 +79,11 @@ function effectiveConfig(fileConfig, recorded) {
|
|
|
70
79
|
...recorded
|
|
71
80
|
};
|
|
72
81
|
}
|
|
82
|
+
/** Names the `nuxt.config` key in a layer error, when the settings that caused it came from there. */
|
|
83
|
+
function labelConfigError(error, recorded) {
|
|
84
|
+
if (error instanceof LayerConfigError && recorded !== void 0 && hasProjectConfig(recorded)) return new LayerscopeError(`${NUXT_CONFIG_LABEL}: ${error.message}`);
|
|
85
|
+
return error;
|
|
86
|
+
}
|
|
73
87
|
//#endregion
|
|
74
88
|
//#region src/registry/schema.ts
|
|
75
89
|
/** Bumped on breaking changes to `registry.json`; readers fall back to the `.d.ts` files. */
|
|
@@ -165,4 +179,4 @@ function layerFromPath(name, root) {
|
|
|
165
179
|
};
|
|
166
180
|
}
|
|
167
181
|
//#endregion
|
|
168
|
-
export { isClonedFrom as a, realPath as c, effectiveConfig as d,
|
|
182
|
+
export { LayerConfigError as _, isClonedFrom as a, realPath as c, effectiveConfig as d, labelConfigError as f, ruleSeverity as g, isRuleName as h, layerFromPath as i, REGISTRY_FILE as l, validateConfig as m, deriveDirectories as n, isFile as o, pickProjectConfig as p, layerFromNuxt as r, readJson as s, ROOT_LAYER_NAME as t, REGISTRY_VERSION as u, LayerscopeError as v };
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as formatResult, r as isOutputFormat, t as OUTPUT_FORMATS } from "./report-
|
|
1
|
+
import { n as formatResult, r as isOutputFormat, t as OUTPUT_FORMATS } from "./report-DShTCB59.mjs";
|
|
2
2
|
export { OUTPUT_FORMATS, formatResult, isOutputFormat };
|
|
@@ -1,6 +1,15 @@
|
|
|
1
1
|
import { t as summarize } from "./summary-DiUYKMPe.mjs";
|
|
2
2
|
import { i as plural } from "./strings-CrOjNZmB.mjs";
|
|
3
3
|
import { relative } from "pathe";
|
|
4
|
+
import { styleText } from "node:util";
|
|
5
|
+
//#region src/utils/style.ts
|
|
6
|
+
/** No styles: what the report functions use unless the CLI passes a painter for its terminal. */
|
|
7
|
+
const plain = (_format, text) => text;
|
|
8
|
+
/** Styles only when `stream` is a terminal; `NO_COLOR` and `FORCE_COLOR` are honoured. */
|
|
9
|
+
function paintFor(stream) {
|
|
10
|
+
return (format, text) => styleText(format, text, { stream });
|
|
11
|
+
}
|
|
12
|
+
//#endregion
|
|
4
13
|
//#region src/report/baseline.ts
|
|
5
14
|
/** `layer-boundary useCart → web (×2)` */
|
|
6
15
|
function describeEntry(entry) {
|
|
@@ -87,8 +96,8 @@ function formatJson(result, cwd) {
|
|
|
87
96
|
//#endregion
|
|
88
97
|
//#region src/report/text.ts
|
|
89
98
|
const DETAIL_INDENT = " ".repeat(17);
|
|
90
|
-
function formatFinding(finding, cwd) {
|
|
91
|
-
return [` ${`${finding.line}:${finding.column}`.padEnd(8)}${finding.severity.
|
|
99
|
+
function formatFinding(finding, cwd, paint) {
|
|
100
|
+
return [` ${paint("dim", `${finding.line}:${finding.column}`.padEnd(8))}${paint(finding.severity === "error" ? "red" : "yellow", finding.severity) + " ".repeat(7 - finding.severity.length)}${finding.message} ${paint("dim", finding.rule)}`, ...findingDetails(finding, cwd).map((detail) => `${DETAIL_INDENT}${paint("dim", detail)}`)].join("\n");
|
|
92
101
|
}
|
|
93
102
|
function formatRemovable(baseline, cwd) {
|
|
94
103
|
if (baseline.removable.length === 0) return null;
|
|
@@ -96,17 +105,22 @@ function formatRemovable(baseline, cwd) {
|
|
|
96
105
|
const count = baseline.removable.length;
|
|
97
106
|
return [`${relative(cwd, baseline.file)}: ${plural(count, "fixed entry", "fixed entries")}. ${UPDATE_HINT} ${count === 1 ? "it" : "them"}.`, ...entries].join("\n");
|
|
98
107
|
}
|
|
99
|
-
function formatFooter(result) {
|
|
108
|
+
function formatFooter(result, paint) {
|
|
100
109
|
const suppressed = result.baseline?.suppressed.length ?? 0;
|
|
101
110
|
const baselined = suppressed > 0 ? `, ${suppressed} more in the baseline` : "";
|
|
102
|
-
if (result.findings.length === 0) return `✔ No problems in ${plural(result.files.length, "file")} across ${plural(result.layers.length, "layer")}${baselined}`;
|
|
111
|
+
if (result.findings.length === 0) return `${paint(["green", "bold"], `✔ No problems in ${plural(result.files.length, "file")} across ${plural(result.layers.length, "layer")}`)}${baselined}`;
|
|
103
112
|
const { errors, warnings } = summarize(result.findings);
|
|
104
|
-
|
|
113
|
+
const counts = `✖ ${plural(result.findings.length, "problem")} (${plural(errors, "error")}, ${plural(warnings, "warning")})`;
|
|
114
|
+
return `${paint(["bold", errors > 0 ? "red" : "yellow"], counts)}${baselined}`;
|
|
115
|
+
}
|
|
116
|
+
function hasError(findings) {
|
|
117
|
+
return findings.some((finding) => finding.severity === "error");
|
|
105
118
|
}
|
|
106
|
-
|
|
107
|
-
|
|
119
|
+
/** Files with errors come last, next to the summary, where they are least likely to scroll away. */
|
|
120
|
+
function formatText(result, cwd, paint = plain) {
|
|
121
|
+
const sections = [...Map.groupBy(result.findings, (finding) => relative(cwd, finding.file))].toSorted(([, a], [, b]) => Number(hasError(a)) - Number(hasError(b))).map(([file, findings]) => [paint("underline", file), ...findings.map((finding) => formatFinding(finding, cwd, paint))].join("\n"));
|
|
108
122
|
const removable = result.baseline === void 0 ? null : formatRemovable(result.baseline, cwd);
|
|
109
|
-
return `${[...removable === null ? sections : [...sections, removable], formatFooter(result)].join("\n\n")}\n`;
|
|
123
|
+
return `${[...removable === null ? sections : [...sections, removable], formatFooter(result, paint)].join("\n\n")}\n`;
|
|
110
124
|
}
|
|
111
125
|
//#endregion
|
|
112
126
|
//#region src/report/index.ts
|
|
@@ -123,9 +137,9 @@ const formatters = {
|
|
|
123
137
|
function isOutputFormat(value) {
|
|
124
138
|
return Object.hasOwn(formatters, value);
|
|
125
139
|
}
|
|
126
|
-
/** Paths in the output are relative to `cwd`. */
|
|
127
|
-
function formatResult(result, format, cwd = process.cwd()) {
|
|
128
|
-
return formatters[format](result, cwd);
|
|
140
|
+
/** Paths in the output are relative to `cwd`. Only the text format uses `paint`. */
|
|
141
|
+
function formatResult(result, format, cwd = process.cwd(), paint = plain) {
|
|
142
|
+
return formatters[format](result, cwd, paint);
|
|
129
143
|
}
|
|
130
144
|
//#endregion
|
|
131
|
-
export { JSON_REPORT_VERSION as i, formatResult as n, isOutputFormat as r, OUTPUT_FORMATS as t };
|
|
145
|
+
export { paintFor as a, JSON_REPORT_VERSION as i, formatResult as n, isOutputFormat as r, OUTPUT_FORMATS as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as compareStrings } from "./strings-CrOjNZmB.mjs";
|
|
2
|
-
import { c as createOwnerLookup, g as isAllowed } from "./file-analysis-
|
|
2
|
+
import { c as createOwnerLookup, g as isAllowed } from "./file-analysis-Bh7qcWUK.mjs";
|
|
3
3
|
import { relative } from "pathe";
|
|
4
4
|
//#region src/rules/edge-status.ts
|
|
5
5
|
/** How the layer rules see one edge. */
|
package/package.json
CHANGED