@vue-html-bridge/cli 0.1.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/LICENSE +21 -0
- package/README.md +81 -0
- package/dist/adapters.d.ts +29 -0
- package/dist/adapters.d.ts.map +1 -0
- package/dist/adapters.js +55 -0
- package/dist/adapters.js.map +1 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +54 -0
- package/dist/bin.js.map +1 -0
- package/dist/cli.d.ts +27 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +93 -0
- package/dist/cli.js.map +1 -0
- package/dist/diagnostics.d.ts +22 -0
- package/dist/diagnostics.d.ts.map +1 -0
- package/dist/diagnostics.js +71 -0
- package/dist/diagnostics.js.map +1 -0
- package/dist/enumerate.d.ts +18 -0
- package/dist/enumerate.d.ts.map +1 -0
- package/dist/enumerate.js +182 -0
- package/dist/enumerate.js.map +1 -0
- package/dist/exit-codes.d.ts +23 -0
- package/dist/exit-codes.d.ts.map +1 -0
- package/dist/exit-codes.js +38 -0
- package/dist/exit-codes.js.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/dist/line-index.d.ts +34 -0
- package/dist/line-index.d.ts.map +1 -0
- package/dist/line-index.js +82 -0
- package/dist/line-index.js.map +1 -0
- package/dist/options.d.ts +79 -0
- package/dist/options.d.ts.map +1 -0
- package/dist/options.js +465 -0
- package/dist/options.js.map +1 -0
- package/dist/output/ndjson.d.ts +80 -0
- package/dist/output/ndjson.d.ts.map +1 -0
- package/dist/output/ndjson.js +61 -0
- package/dist/output/ndjson.js.map +1 -0
- package/dist/output/text.d.ts +12 -0
- package/dist/output/text.d.ts.map +1 -0
- package/dist/output/text.js +76 -0
- package/dist/output/text.js.map +1 -0
- package/dist/runner.d.ts +38 -0
- package/dist/runner.d.ts.map +1 -0
- package/dist/runner.js +221 -0
- package/dist/runner.js.map +1 -0
- package/dist/settings-resolution.d.ts +27 -0
- package/dist/settings-resolution.d.ts.map +1 -0
- package/dist/settings-resolution.js +48 -0
- package/dist/settings-resolution.js.map +1 -0
- package/dist/types.d.ts +74 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/package.json +43 -0
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
function pluralize(count, noun) {
|
|
2
|
+
return `${count} ${noun}${count === 1 ? "" : "s"}`;
|
|
3
|
+
}
|
|
4
|
+
function evidenceSuffix(evidence) {
|
|
5
|
+
const parts = [];
|
|
6
|
+
if (evidence.variantCount > 1)
|
|
7
|
+
parts.push(`${evidence.variantCount} variants`);
|
|
8
|
+
if (evidence.truncated)
|
|
9
|
+
parts.push("truncated");
|
|
10
|
+
return parts.length > 0 ? ` (${parts.join(", ")})` : "";
|
|
11
|
+
}
|
|
12
|
+
/** cli.md §4.2 `--no-color`: ANSI codes for the severity token only, applied by the caller only when color is enabled. */
|
|
13
|
+
const SEVERITY_COLOR = {
|
|
14
|
+
error: "[31m", // red
|
|
15
|
+
warning: "[33m", // yellow
|
|
16
|
+
info: "[36m", // cyan
|
|
17
|
+
hint: "[90m", // gray
|
|
18
|
+
};
|
|
19
|
+
const ANSI_RESET = "[0m";
|
|
20
|
+
function colorize(text, code, color) {
|
|
21
|
+
return color ? `${code}${text}${ANSI_RESET}` : text;
|
|
22
|
+
}
|
|
23
|
+
function formatDiagnostic(path, diagnostic, color) {
|
|
24
|
+
const lines = [];
|
|
25
|
+
const severityToken = colorize(diagnostic.severity, SEVERITY_COLOR[diagnostic.severity], color);
|
|
26
|
+
lines.push(`${path}:${diagnostic.position.startLine}:${diagnostic.position.startColumn} ${severityToken} ${diagnostic.code}`);
|
|
27
|
+
const adapterSuffix = diagnostic.adapterId
|
|
28
|
+
? ` [${diagnostic.adapterId}]`
|
|
29
|
+
: "";
|
|
30
|
+
lines.push(` ${diagnostic.message}${evidenceSuffix(diagnostic.evidence)}${adapterSuffix}`);
|
|
31
|
+
for (const related of diagnostic.relatedInformation) {
|
|
32
|
+
lines.push(` related ${related.path}:${related.position.startLine}:${related.position.startColumn} ${related.message}`);
|
|
33
|
+
}
|
|
34
|
+
return lines.join("\n");
|
|
35
|
+
}
|
|
36
|
+
function formatRunError(error, color) {
|
|
37
|
+
const location = error.path ? `${error.path}: ` : "";
|
|
38
|
+
const adapterSuffix = error.adapterId ? ` [${error.adapterId}]` : "";
|
|
39
|
+
const prefix = colorize("error", SEVERITY_COLOR.error, color);
|
|
40
|
+
return `${prefix}: ${location}${error.message} (${error.code})${adapterSuffix}`;
|
|
41
|
+
}
|
|
42
|
+
function formatSummary(counts) {
|
|
43
|
+
const parts = [
|
|
44
|
+
pluralize(counts.errors, "error"),
|
|
45
|
+
pluralize(counts.warnings, "warning"),
|
|
46
|
+
pluralize(counts.infos, "info"),
|
|
47
|
+
pluralize(counts.hints, "hint"),
|
|
48
|
+
];
|
|
49
|
+
const runErrorSuffix = counts.runErrors > 0 ? `, ${pluralize(counts.runErrors, "run error")}` : "";
|
|
50
|
+
return `${pluralize(counts.filesAnalyzed, "file")} analyzed: ${parts.join(", ")}${runErrorSuffix}`;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* `writeStdout`/`writeStderr` are called with already-newline-terminated
|
|
54
|
+
* chunks; the caller owns the real stream (kept simple/testable, same
|
|
55
|
+
* pattern as output/ndjson.ts).
|
|
56
|
+
*/
|
|
57
|
+
export function createTextRenderer(writeStdout, writeStderr, options = {}) {
|
|
58
|
+
const color = options.color ?? false;
|
|
59
|
+
return {
|
|
60
|
+
start() {
|
|
61
|
+
// No start-of-stream marker in text mode.
|
|
62
|
+
},
|
|
63
|
+
file(path, diagnostics) {
|
|
64
|
+
for (const diagnostic of diagnostics) {
|
|
65
|
+
writeStdout(`${formatDiagnostic(path, diagnostic, color)}\n`);
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
runError(error) {
|
|
69
|
+
writeStderr(`${formatRunError(error, color)}\n`);
|
|
70
|
+
},
|
|
71
|
+
summary(counts) {
|
|
72
|
+
writeStdout(`${formatSummary(counts)}\n`);
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=text.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"text.js","sourceRoot":"","sources":["../../src/output/text.ts"],"names":[],"mappings":"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"}
|
package/dist/runner.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { AdapterModuleResolver } from "@vue-html-bridge/adapter-loader";
|
|
2
|
+
import { type ResolvedVueHtmlBridgeSettings } from "@vue-html-bridge/settings";
|
|
3
|
+
import type { AdapterLogger, HtmlValidatorAdapter } from "@vue-html-bridge/validator-api";
|
|
4
|
+
import { type FailOnThreshold } from "./exit-codes.js";
|
|
5
|
+
import type { OutputRenderer } from "./types.js";
|
|
6
|
+
export interface RunCliOptions {
|
|
7
|
+
/** Absolute. */
|
|
8
|
+
workspaceRoot: string;
|
|
9
|
+
/** Absolute. */
|
|
10
|
+
cwd: string;
|
|
11
|
+
positionalArgs: readonly string[];
|
|
12
|
+
settings: ResolvedVueHtmlBridgeSettings;
|
|
13
|
+
workspaceTrusted: boolean;
|
|
14
|
+
failOn: FailOnThreshold;
|
|
15
|
+
signal: AbortSignal;
|
|
16
|
+
renderer: OutputRenderer;
|
|
17
|
+
/** stderr-only notices (untrusted-mode banner, pre-analysis "no analyzable input") — always stderr regardless of `--format` (cli.md §2, §7.2 stdout validity). */
|
|
18
|
+
notice: (message: string) => void;
|
|
19
|
+
/** Injectable for tests (adapter-loader.md §6 item 8's shared contract fixture, adapter-testkit's fake adapter). */
|
|
20
|
+
moduleResolver?: AdapterModuleResolver;
|
|
21
|
+
builtins?: ReadonlyMap<string, HtmlValidatorAdapter<unknown>>;
|
|
22
|
+
logger?: AdapterLogger;
|
|
23
|
+
}
|
|
24
|
+
export type RunCliResult = {
|
|
25
|
+
interrupted: true;
|
|
26
|
+
} | {
|
|
27
|
+
interrupted: false;
|
|
28
|
+
exitCode: number;
|
|
29
|
+
};
|
|
30
|
+
export declare function runCli(options: RunCliOptions): Promise<RunCliResult>;
|
|
31
|
+
/**
|
|
32
|
+
* cli.md §6 step 3: `AnalyzeRequest.uri` is built from the resolved absolute
|
|
33
|
+
* real path with Node's `pathToFileURL` — its Windows drive-letter and
|
|
34
|
+
* percent-encoding rules *are* the contract, so this is a thin, exported
|
|
35
|
+
* wrapper (not a reimplementation) kept testable at the module boundary.
|
|
36
|
+
*/
|
|
37
|
+
export declare function toFileUri(absolutePath: string): string;
|
|
38
|
+
//# sourceMappingURL=runner.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.d.ts","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,iCAAiC,CAAC;AAM7E,OAAO,EAEL,KAAK,6BAA6B,EACnC,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EACV,aAAa,EACb,oBAAoB,EACrB,MAAM,gCAAgC,CAAC;AAQxC,OAAO,EAIL,KAAK,eAAe,EACrB,MAAM,iBAAiB,CAAC;AAEzB,OAAO,KAAK,EAEV,cAAc,EAGf,MAAM,YAAY,CAAC;AAKpB,MAAM,WAAW,aAAa;IAC5B,gBAAgB;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB;IAChB,GAAG,EAAE,MAAM,CAAC;IACZ,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;IAClC,QAAQ,EAAE,6BAA6B,CAAC;IACxC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,MAAM,EAAE,eAAe,CAAC;IACxB,MAAM,EAAE,WAAW,CAAC;IACpB,QAAQ,EAAE,cAAc,CAAC;IACzB,kKAAkK;IAClK,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,oHAAoH;IACpH,cAAc,CAAC,EAAE,qBAAqB,CAAC;IACvC,QAAQ,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC,CAAC;IAC9D,MAAM,CAAC,EAAE,aAAa,CAAC;CACxB;AAED,MAAM,MAAM,YAAY,GACtB;IAAE,WAAW,EAAE,IAAI,CAAA;CAAE,GAAG;IAAE,WAAW,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAAC;AAEnE,wBAAsB,MAAM,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO,CAAC,YAAY,CAAC,CA6L1E;AA0BD;;;;;GAKG;AACH,wBAAgB,SAAS,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,CAEtD"}
|
package/dist/runner.js
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
// The execution model (cli.md §6, §8): enumeration, adapter loading,
|
|
2
|
+
// analyzer lifecycle, and the run-outcome model. This module takes an
|
|
3
|
+
// already-resolved settings object and a trust decision; it knows nothing
|
|
4
|
+
// about flags (cli.md §11).
|
|
5
|
+
import { readFile } from "node:fs/promises";
|
|
6
|
+
import { relative, sep } from "node:path";
|
|
7
|
+
import { pathToFileURL } from "node:url";
|
|
8
|
+
import { createWorkspaceAnalyzer, } from "@vue-html-bridge/analyzer";
|
|
9
|
+
import { decomposeSettings, } from "@vue-html-bridge/settings";
|
|
10
|
+
import { loadAdaptersForRun } from "./adapters.js";
|
|
11
|
+
import { isSessionFailureDiagnostic, projectDiagnostic, sortCliDiagnostics, } from "./diagnostics.js";
|
|
12
|
+
import { enumerateFiles } from "./enumerate.js";
|
|
13
|
+
import { computeExitCode, EXIT_RUN_ERROR, severityMeetsThreshold, } from "./exit-codes.js";
|
|
14
|
+
import { createLineIndex } from "./line-index.js";
|
|
15
|
+
/** Bounded cleanup (cli.md §6 "Signals"): dispose never blocks exit indefinitely. */
|
|
16
|
+
const DISPOSE_TIMEOUT_MS = 3000;
|
|
17
|
+
export async function runCli(options) {
|
|
18
|
+
const decomposed = decomposeSettings(options.settings);
|
|
19
|
+
const enumerated = await enumerateFiles({
|
|
20
|
+
workspaceRoot: options.workspaceRoot,
|
|
21
|
+
cwd: options.cwd,
|
|
22
|
+
positionalArgs: options.positionalArgs,
|
|
23
|
+
include: decomposed.host.include,
|
|
24
|
+
exclude: decomposed.host.exclude,
|
|
25
|
+
});
|
|
26
|
+
if (enumerated.files.length === 0) {
|
|
27
|
+
// cli.md §8: "no analyzable input" is one of the reasons a run fails
|
|
28
|
+
// *before* analysis starts — stdout carries zero lines (§7.2); every
|
|
29
|
+
// message here is stderr-only, never routed through the renderer.
|
|
30
|
+
for (const error of enumerated.errors) {
|
|
31
|
+
options.notice(`${formatNoticeFromRunError(error)}\n`);
|
|
32
|
+
}
|
|
33
|
+
options.notice(`${enumerated.errors.length > 0
|
|
34
|
+
? "No files left to analyze after resolving the given arguments."
|
|
35
|
+
: "No files matched the given include/exclude patterns."}\n`);
|
|
36
|
+
return { interrupted: false, exitCode: EXIT_RUN_ERROR };
|
|
37
|
+
}
|
|
38
|
+
if (!options.workspaceTrusted) {
|
|
39
|
+
options.notice("--untrusted: ignoring workspace validator configuration and external adapters.\n");
|
|
40
|
+
}
|
|
41
|
+
const loadResult = await loadAdaptersForRun({
|
|
42
|
+
validators: decomposed.validators,
|
|
43
|
+
workspaceRoot: options.workspaceRoot,
|
|
44
|
+
workspaceTrusted: options.workspaceTrusted,
|
|
45
|
+
externalAdapters: decomposed.host.externalAdapters,
|
|
46
|
+
moduleResolver: options.moduleResolver,
|
|
47
|
+
builtins: options.builtins,
|
|
48
|
+
logger: options.logger,
|
|
49
|
+
});
|
|
50
|
+
const runLevelErrors = [];
|
|
51
|
+
const reportedKeys = new Set();
|
|
52
|
+
/** cli.md §8: run-level errors are reported once each, keyed per their kind. */
|
|
53
|
+
function reportRunError(error, dedupeKey) {
|
|
54
|
+
if (reportedKeys.has(dedupeKey))
|
|
55
|
+
return;
|
|
56
|
+
reportedKeys.add(dedupeKey);
|
|
57
|
+
runLevelErrors.push(error);
|
|
58
|
+
options.renderer.runError(error);
|
|
59
|
+
}
|
|
60
|
+
const analyzer = await createWorkspaceAnalyzer({
|
|
61
|
+
workspaceRoot: options.workspaceRoot,
|
|
62
|
+
adapters: loadResult.adapters,
|
|
63
|
+
generateOptions: decomposed.generateOptions,
|
|
64
|
+
maxConcurrency: decomposed.analyzer.maxConcurrency,
|
|
65
|
+
logger: options.logger,
|
|
66
|
+
});
|
|
67
|
+
const counts = {
|
|
68
|
+
filesAnalyzed: 0,
|
|
69
|
+
errors: 0,
|
|
70
|
+
warnings: 0,
|
|
71
|
+
infos: 0,
|
|
72
|
+
hints: 0,
|
|
73
|
+
runErrors: 0,
|
|
74
|
+
};
|
|
75
|
+
let hasThresholdDiagnostic = false;
|
|
76
|
+
try {
|
|
77
|
+
// A run that reaches here *is* reaching analysis — emit the stream's
|
|
78
|
+
// start marker (NDJSON's `meta`; a no-op for text) before anything else,
|
|
79
|
+
// then report the enumeration/adapter-load failures already known.
|
|
80
|
+
options.renderer.start();
|
|
81
|
+
for (const error of enumerated.errors) {
|
|
82
|
+
reportRunError(error, `enumerate:${error.message}`);
|
|
83
|
+
}
|
|
84
|
+
for (const failure of loadResult.failures) {
|
|
85
|
+
reportRunError({ code: `adapter-load/${failure.kind}`, message: failure.message }, `adapter-load:${failure.dedupeKey}`);
|
|
86
|
+
}
|
|
87
|
+
for (const absolutePath of enumerated.files) {
|
|
88
|
+
if (options.signal.aborted)
|
|
89
|
+
break;
|
|
90
|
+
const relPath = toWorkspaceRelativePosix(options.workspaceRoot, absolutePath);
|
|
91
|
+
let source;
|
|
92
|
+
try {
|
|
93
|
+
source = await readFile(absolutePath, "utf8");
|
|
94
|
+
}
|
|
95
|
+
catch (error) {
|
|
96
|
+
reportRunError({
|
|
97
|
+
code: "file-unreadable",
|
|
98
|
+
message: `Failed to read "${relPath}": ${errorMessage(error)}`,
|
|
99
|
+
path: relPath,
|
|
100
|
+
}, `file-read:${relPath}`);
|
|
101
|
+
continue;
|
|
102
|
+
}
|
|
103
|
+
let result;
|
|
104
|
+
try {
|
|
105
|
+
result = await analyzer.analyze({
|
|
106
|
+
uri: toFileUri(absolutePath),
|
|
107
|
+
filename: absolutePath,
|
|
108
|
+
source,
|
|
109
|
+
signal: options.signal,
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
catch (error) {
|
|
113
|
+
if (options.signal.aborted)
|
|
114
|
+
break; // cancellation is not a diagnostic
|
|
115
|
+
reportRunError({
|
|
116
|
+
code: "internal-error",
|
|
117
|
+
message: `Analysis failed for "${relPath}": ${errorMessage(error)}`,
|
|
118
|
+
path: relPath,
|
|
119
|
+
}, `internal:${relPath}`);
|
|
120
|
+
continue;
|
|
121
|
+
}
|
|
122
|
+
// A result that completed just as the signal fired is discarded, not
|
|
123
|
+
// rendered (cli.md §6: "cancellation is not a diagnostic").
|
|
124
|
+
if (options.signal.aborted)
|
|
125
|
+
break;
|
|
126
|
+
const index = createLineIndex(source);
|
|
127
|
+
const perFileDiagnostics = [];
|
|
128
|
+
for (const diagnostic of result.diagnostics) {
|
|
129
|
+
if (isSessionFailureDiagnostic(diagnostic)) {
|
|
130
|
+
// cli.md §8: the analyzer places this on every analyzed file; the
|
|
131
|
+
// CLI reports it once at run level and drops it from the file's
|
|
132
|
+
// own diagnostics list.
|
|
133
|
+
reportRunError({
|
|
134
|
+
code: diagnostic.code,
|
|
135
|
+
message: diagnostic.message,
|
|
136
|
+
...(diagnostic.adapterId !== undefined
|
|
137
|
+
? { adapterId: diagnostic.adapterId }
|
|
138
|
+
: {}),
|
|
139
|
+
}, `session:${diagnostic.adapterId ?? ""}:${diagnostic.code}`);
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
perFileDiagnostics.push(diagnostic);
|
|
143
|
+
}
|
|
144
|
+
const projected = sortCliDiagnostics(perFileDiagnostics.map((diagnostic) => projectDiagnostic(diagnostic, index, relPath)));
|
|
145
|
+
for (const diagnostic of projected) {
|
|
146
|
+
tallySeverity(counts, diagnostic.severity);
|
|
147
|
+
if (severityMeetsThreshold(diagnostic.severity, options.failOn)) {
|
|
148
|
+
hasThresholdDiagnostic = true;
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
counts.filesAnalyzed += 1;
|
|
152
|
+
options.renderer.file(relPath, projected);
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
finally {
|
|
156
|
+
await disposeBounded(analyzer);
|
|
157
|
+
}
|
|
158
|
+
if (options.signal.aborted) {
|
|
159
|
+
// cli.md §7.2: no `summary` line on interruption — the caller (bin.ts)
|
|
160
|
+
// knows which signal fired and picks 130/143.
|
|
161
|
+
return { interrupted: true };
|
|
162
|
+
}
|
|
163
|
+
counts.runErrors = runLevelErrors.length;
|
|
164
|
+
options.renderer.summary(counts);
|
|
165
|
+
return {
|
|
166
|
+
interrupted: false,
|
|
167
|
+
exitCode: computeExitCode({
|
|
168
|
+
hasRunLevelError: runLevelErrors.length > 0,
|
|
169
|
+
hasThresholdDiagnostic,
|
|
170
|
+
}),
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function tallySeverity(counts, severity) {
|
|
174
|
+
switch (severity) {
|
|
175
|
+
case "error":
|
|
176
|
+
counts.errors += 1;
|
|
177
|
+
break;
|
|
178
|
+
case "warning":
|
|
179
|
+
counts.warnings += 1;
|
|
180
|
+
break;
|
|
181
|
+
case "info":
|
|
182
|
+
counts.infos += 1;
|
|
183
|
+
break;
|
|
184
|
+
case "hint":
|
|
185
|
+
counts.hints += 1;
|
|
186
|
+
break;
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
function toWorkspaceRelativePosix(root, absolutePath) {
|
|
190
|
+
return relative(root, absolutePath).split(sep).join("/");
|
|
191
|
+
}
|
|
192
|
+
/**
|
|
193
|
+
* cli.md §6 step 3: `AnalyzeRequest.uri` is built from the resolved absolute
|
|
194
|
+
* real path with Node's `pathToFileURL` — its Windows drive-letter and
|
|
195
|
+
* percent-encoding rules *are* the contract, so this is a thin, exported
|
|
196
|
+
* wrapper (not a reimplementation) kept testable at the module boundary.
|
|
197
|
+
*/
|
|
198
|
+
export function toFileUri(absolutePath) {
|
|
199
|
+
return pathToFileURL(absolutePath).href;
|
|
200
|
+
}
|
|
201
|
+
function errorMessage(error) {
|
|
202
|
+
return error instanceof Error ? error.message : String(error);
|
|
203
|
+
}
|
|
204
|
+
function formatNoticeFromRunError(error) {
|
|
205
|
+
return `error: ${error.message} (${error.code})`;
|
|
206
|
+
}
|
|
207
|
+
async function disposeBounded(analyzer) {
|
|
208
|
+
let timer;
|
|
209
|
+
const timeout = new Promise((resolvePromise) => {
|
|
210
|
+
timer = setTimeout(resolvePromise, DISPOSE_TIMEOUT_MS);
|
|
211
|
+
timer.unref();
|
|
212
|
+
});
|
|
213
|
+
try {
|
|
214
|
+
await Promise.race([analyzer.dispose(), timeout]);
|
|
215
|
+
}
|
|
216
|
+
finally {
|
|
217
|
+
if (timer !== undefined)
|
|
218
|
+
clearTimeout(timer);
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../src/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { type ResolvedVueHtmlBridgeSettings, type SettingsIssue, type VueHtmlBridgeSettingsInput } from "@vue-html-bridge/settings";
|
|
2
|
+
import { type ValidatorFlagOp } from "./options.js";
|
|
3
|
+
export interface ResolveCliSettingsOptions {
|
|
4
|
+
/** Absolute. */
|
|
5
|
+
workspaceRoot: string;
|
|
6
|
+
/** Absolute; `--config`'s relative path is resolved against this (cli.md §4.1 resolves it "from the current working directory"). */
|
|
7
|
+
cwd: string;
|
|
8
|
+
/** Raw `--config` value, if given. */
|
|
9
|
+
configPath?: string;
|
|
10
|
+
/** The flags layer built by options.ts, minus the three validator flags. */
|
|
11
|
+
flagsInput: VueHtmlBridgeSettingsInput;
|
|
12
|
+
validatorOps: readonly ValidatorFlagOp[];
|
|
13
|
+
untrusted: boolean;
|
|
14
|
+
}
|
|
15
|
+
export type ResolveCliSettingsResult = {
|
|
16
|
+
kind: "ok";
|
|
17
|
+
settings: ResolvedVueHtmlBridgeSettings;
|
|
18
|
+
workspaceTrusted: boolean;
|
|
19
|
+
/** Warning-severity issues (settings.md §4), for the caller to print to stderr. */
|
|
20
|
+
warnings: readonly SettingsIssue[];
|
|
21
|
+
} | {
|
|
22
|
+
kind: "fatal";
|
|
23
|
+
/** Every issue (error-severity ones are why this run is fatal; warnings are included too, for a complete stderr report). */
|
|
24
|
+
issues: readonly SettingsIssue[];
|
|
25
|
+
};
|
|
26
|
+
export declare function resolveCliSettings(options: ResolveCliSettingsOptions): Promise<ResolveCliSettingsResult>;
|
|
27
|
+
//# sourceMappingURL=settings-resolution.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-resolution.d.ts","sourceRoot":"","sources":["../src/settings-resolution.ts"],"names":[],"mappings":"AASA,OAAO,EAKL,KAAK,6BAA6B,EAClC,KAAK,aAAa,EAClB,KAAK,0BAA0B,EAChC,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAyB,KAAK,eAAe,EAAE,MAAM,cAAc,CAAC;AAE3E,MAAM,WAAW,yBAAyB;IACxC,gBAAgB;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,oIAAoI;IACpI,GAAG,EAAE,MAAM,CAAC;IACZ,sCAAsC;IACtC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,4EAA4E;IAC5E,UAAU,EAAE,0BAA0B,CAAC;IACvC,YAAY,EAAE,SAAS,eAAe,EAAE,CAAC;IACzC,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,MAAM,wBAAwB,GAChC;IACE,IAAI,EAAE,IAAI,CAAC;IACX,QAAQ,EAAE,6BAA6B,CAAC;IACxC,gBAAgB,EAAE,OAAO,CAAC;IAC1B,mFAAmF;IACnF,QAAQ,EAAE,SAAS,aAAa,EAAE,CAAC;CACpC,GACD;IACE,IAAI,EAAE,OAAO,CAAC;IACd,4HAA4H;IAC5H,MAAM,EAAE,SAAS,aAAa,EAAE,CAAC;CAClC,CAAC;AAEN,wBAAsB,kBAAkB,CACtC,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,wBAAwB,CAAC,CA+CnC"}
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
// Settings sourcing (cli.md §4.1): loads the config-file layer (explicit
|
|
2
|
+
// `--config`, or discovered `.vue-html-bridge.json`/`package.json#vueHtmlBridge`),
|
|
3
|
+
// merges it with the flags layer through the shared `resolveSettings`, then
|
|
4
|
+
// applies the two CLI-specific, post-resolution steps that are *not* part of
|
|
5
|
+
// `resolveSettings` itself: the §4.3 validator-flag patches and the §5
|
|
6
|
+
// `--untrusted` trust forcing. `resolveSettings`'s own semantics are used
|
|
7
|
+
// unchanged — this module decides only what the CLI does with the result
|
|
8
|
+
// (fatal vs. warn, per §4.1).
|
|
9
|
+
import { isAbsolute, resolve } from "node:path";
|
|
10
|
+
import { createNodeFileSystem, loadSettingsFile, loadWorkspaceSettingsFile, resolveSettings, } from "@vue-html-bridge/settings";
|
|
11
|
+
import { applyValidatorFlagOps } from "./options.js";
|
|
12
|
+
export async function resolveCliSettings(options) {
|
|
13
|
+
const fileSystem = createNodeFileSystem();
|
|
14
|
+
const configLayerResult = options.configPath !== undefined
|
|
15
|
+
? await loadSettingsFile(isAbsolute(options.configPath)
|
|
16
|
+
? options.configPath
|
|
17
|
+
: resolve(options.cwd, options.configPath), fileSystem)
|
|
18
|
+
: await loadWorkspaceSettingsFile(options.workspaceRoot, fileSystem);
|
|
19
|
+
const { settings, issues } = resolveSettings([
|
|
20
|
+
configLayerResult.settings,
|
|
21
|
+
options.flagsInput,
|
|
22
|
+
]);
|
|
23
|
+
const allIssues = [...configLayerResult.issues, ...issues];
|
|
24
|
+
const hasFatalIssue = allIssues.some((issue) => issue.severity === "error");
|
|
25
|
+
if (hasFatalIssue) {
|
|
26
|
+
return { kind: "fatal", issues: allIssues };
|
|
27
|
+
}
|
|
28
|
+
const patchedValidators = applyValidatorFlagOps(settings.validators, options.validatorOps);
|
|
29
|
+
// §5: `--untrusted` forces externalAdapters to "disabled" regardless of
|
|
30
|
+
// what resolution produced — it "wins over any conflicting trust-related
|
|
31
|
+
// flag or setting" — and every other resolved field is left untouched
|
|
32
|
+
// (host-neutral settings apply the same either way, per §5).
|
|
33
|
+
const workspaceTrusted = !options.untrusted;
|
|
34
|
+
const externalAdapters = options.untrusted
|
|
35
|
+
? "disabled"
|
|
36
|
+
: settings.externalAdapters;
|
|
37
|
+
return {
|
|
38
|
+
kind: "ok",
|
|
39
|
+
settings: {
|
|
40
|
+
...settings,
|
|
41
|
+
validators: patchedValidators,
|
|
42
|
+
externalAdapters,
|
|
43
|
+
},
|
|
44
|
+
workspaceTrusted,
|
|
45
|
+
warnings: allIssues.filter((issue) => issue.severity === "warning"),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=settings-resolution.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"settings-resolution.js","sourceRoot":"","sources":["../src/settings-resolution.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,mFAAmF;AACnF,4EAA4E;AAC5E,6EAA6E;AAC7E,uEAAuE;AACvE,0EAA0E;AAC1E,yEAAyE;AACzE,8BAA8B;AAC9B,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAChD,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,yBAAyB,EACzB,eAAe,GAIhB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EAAE,qBAAqB,EAAwB,MAAM,cAAc,CAAC;AA6B3E,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,OAAkC;IAElC,MAAM,UAAU,GAAG,oBAAoB,EAAE,CAAC;IAE1C,MAAM,iBAAiB,GACrB,OAAO,CAAC,UAAU,KAAK,SAAS;QAC9B,CAAC,CAAC,MAAM,gBAAgB,CACpB,UAAU,CAAC,OAAO,CAAC,UAAU,CAAC;YAC5B,CAAC,CAAC,OAAO,CAAC,UAAU;YACpB,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,UAAU,CAAC,EAC5C,UAAU,CACX;QACH,CAAC,CAAC,MAAM,yBAAyB,CAAC,OAAO,CAAC,aAAa,EAAE,UAAU,CAAC,CAAC;IAEzE,MAAM,EAAE,QAAQ,EAAE,MAAM,EAAE,GAAG,eAAe,CAAC;QAC3C,iBAAiB,CAAC,QAAQ;QAC1B,OAAO,CAAC,UAAU;KACnB,CAAC,CAAC;IACH,MAAM,SAAS,GAAG,CAAC,GAAG,iBAAiB,CAAC,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC;IAC3D,MAAM,aAAa,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,OAAO,CAAC,CAAC;IAC5E,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;IAC9C,CAAC;IAED,MAAM,iBAAiB,GAAG,qBAAqB,CAC7C,QAAQ,CAAC,UAAU,EACnB,OAAO,CAAC,YAAY,CACrB,CAAC;IAEF,wEAAwE;IACxE,yEAAyE;IACzE,sEAAsE;IACtE,6DAA6D;IAC7D,MAAM,gBAAgB,GAAG,CAAC,OAAO,CAAC,SAAS,CAAC;IAC5C,MAAM,gBAAgB,GAAG,OAAO,CAAC,SAAS;QACxC,CAAC,CAAE,UAAoB;QACvB,CAAC,CAAC,QAAQ,CAAC,gBAAgB,CAAC;IAE9B,OAAO;QACL,IAAI,EAAE,IAAI;QACV,QAAQ,EAAE;YACR,GAAG,QAAQ;YACX,UAAU,EAAE,iBAAiB;YAC7B,gBAAgB;SACjB;QACD,gBAAgB;QAChB,QAAQ,EAAE,SAAS,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,QAAQ,KAAK,SAAS,CAAC;KACpE,CAAC;AACJ,CAAC"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
/** cli.md §7.2 `CliNdjsonDiagnostic`, and the shape `--format text` renders from. */
|
|
2
|
+
export interface CliDiagnosticRange {
|
|
3
|
+
start: number;
|
|
4
|
+
end: number;
|
|
5
|
+
}
|
|
6
|
+
export interface CliDiagnosticPosition {
|
|
7
|
+
startLine: number;
|
|
8
|
+
startColumn: number;
|
|
9
|
+
endLine: number;
|
|
10
|
+
endColumn: number;
|
|
11
|
+
}
|
|
12
|
+
export interface CliDiagnosticRelated {
|
|
13
|
+
/** Workspace-relative, "/"-separated. */
|
|
14
|
+
path: string;
|
|
15
|
+
range: CliDiagnosticRange;
|
|
16
|
+
position: CliDiagnosticPosition;
|
|
17
|
+
message: string;
|
|
18
|
+
}
|
|
19
|
+
export interface CliDiagnosticEvidence {
|
|
20
|
+
variantCount: number;
|
|
21
|
+
truncated: boolean;
|
|
22
|
+
}
|
|
23
|
+
export interface CliDiagnostic {
|
|
24
|
+
severity: "error" | "warning" | "info" | "hint";
|
|
25
|
+
code: string;
|
|
26
|
+
message: string;
|
|
27
|
+
origin: "core" | "validator" | "adapter";
|
|
28
|
+
adapterId?: string;
|
|
29
|
+
codeDescriptionHref?: string;
|
|
30
|
+
range: CliDiagnosticRange;
|
|
31
|
+
position: CliDiagnosticPosition;
|
|
32
|
+
relatedInformation: readonly CliDiagnosticRelated[];
|
|
33
|
+
evidence: CliDiagnosticEvidence;
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* cli.md §8: a problem with the run itself, distinct from a diagnostic.
|
|
37
|
+
* Reported once each (deduplicated by the caller), regardless of format.
|
|
38
|
+
*/
|
|
39
|
+
export interface RunLevelError {
|
|
40
|
+
/** e.g. "adapter/markuplint/configuration-error", "file-unreadable", "adapter-load/invalid-shape". */
|
|
41
|
+
code: string;
|
|
42
|
+
message: string;
|
|
43
|
+
adapterId?: string;
|
|
44
|
+
/** Workspace-relative, "/"-separated, when the error is file-scoped. */
|
|
45
|
+
path?: string;
|
|
46
|
+
}
|
|
47
|
+
export interface RunSummaryCounts {
|
|
48
|
+
filesAnalyzed: number;
|
|
49
|
+
errors: number;
|
|
50
|
+
warnings: number;
|
|
51
|
+
infos: number;
|
|
52
|
+
hints: number;
|
|
53
|
+
runErrors: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* The streaming contract both `output/text.ts` and `output/ndjson.ts`
|
|
57
|
+
* implement (cli.md §6 step 5, §7): `runner.ts` renders each file's result
|
|
58
|
+
* as it completes rather than buffering the whole run, and is otherwise
|
|
59
|
+
* agnostic to the chosen format. Each renderer owns where a given call ends
|
|
60
|
+
* up (stdout vs. stderr) — text sends `runError` to stderr (§7.1), NDJSON
|
|
61
|
+
* sends it to stdout as a `runError` record (§7.2) — so `runner.ts` never
|
|
62
|
+
* writes to a stream directly.
|
|
63
|
+
*/
|
|
64
|
+
export interface OutputRenderer {
|
|
65
|
+
/** Emitted once, only for a run that reaches analysis (NDJSON's `meta` line; a no-op for text). */
|
|
66
|
+
start(): void;
|
|
67
|
+
/** One call per file, in completion order, with diagnostics already sorted (diagnostics.ts). */
|
|
68
|
+
file(path: string, diagnostics: readonly CliDiagnostic[]): void;
|
|
69
|
+
/** One call per run-level error, as it occurs (already deduplicated by the caller). */
|
|
70
|
+
runError(error: RunLevelError): void;
|
|
71
|
+
/** Called once, at the very end, only when the run completed without interruption. */
|
|
72
|
+
summary(counts: RunSummaryCounts): void;
|
|
73
|
+
}
|
|
74
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAKA,qFAAqF;AACrF,MAAM,WAAW,kBAAkB;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,GAAG,EAAE,MAAM,CAAC;CACb;AAED,MAAM,WAAW,qBAAqB;IACpC,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,WAAW,oBAAoB;IACnC,yCAAyC;IACzC,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,qBAAqB,CAAC;IAChC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,GAAG,SAAS,GAAG,MAAM,GAAG,MAAM,CAAC;IAChD,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IACzC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,KAAK,EAAE,kBAAkB,CAAC;IAC1B,QAAQ,EAAE,qBAAqB,CAAC;IAChC,kBAAkB,EAAE,SAAS,oBAAoB,EAAE,CAAC;IACpD,QAAQ,EAAE,qBAAqB,CAAC;CACjC;AAED;;;GAGG;AACH,MAAM,WAAW,aAAa;IAC5B,sGAAsG;IACtG,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,wEAAwE;IACxE,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,cAAc;IAC7B,mGAAmG;IACnG,KAAK,IAAI,IAAI,CAAC;IACd,gGAAgG;IAChG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,SAAS,aAAa,EAAE,GAAG,IAAI,CAAC;IAChE,uFAAuF;IACvF,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,IAAI,CAAC;IACrC,sFAAsF;IACtF,OAAO,CAAC,MAAM,EAAE,gBAAgB,GAAG,IAAI,CAAC;CACzC"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
// Shared internal types used across runner.ts and the output/ renderers,
|
|
2
|
+
// factored out so the output modules never need to import runner.ts (cli.md
|
|
3
|
+
// §11: "output modules take fully converted positions and never see the
|
|
4
|
+
// analyzer types beyond SourceDiagnostic").
|
|
5
|
+
export {};
|
|
6
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,yEAAyE;AACzE,4EAA4E;AAC5E,wEAAwE;AACxE,4CAA4C"}
|
package/package.json
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vue-html-bridge/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"license": "MIT",
|
|
5
|
+
"description": "One-shot command-line client for vue-html-bridge analysis.",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"exports": {
|
|
8
|
+
".": {
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"import": "./dist/index.js"
|
|
11
|
+
},
|
|
12
|
+
"./package.json": "./package.json"
|
|
13
|
+
},
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"files": [
|
|
16
|
+
"dist"
|
|
17
|
+
],
|
|
18
|
+
"bin": {
|
|
19
|
+
"vue-html-bridge": "./dist/bin.js"
|
|
20
|
+
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"minimatch": "10.2.6",
|
|
23
|
+
"@vue-html-bridge/analyzer": "0.1.0",
|
|
24
|
+
"@vue-html-bridge/adapter-loader": "0.1.0",
|
|
25
|
+
"@vue-html-bridge/validator-api": "0.1.0",
|
|
26
|
+
"@vue-html-bridge/settings": "0.1.0",
|
|
27
|
+
"@vue-html-bridge/adapter-markuplint": "0.1.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/node": "26.2.0",
|
|
31
|
+
"vitest": "4.1.11",
|
|
32
|
+
"vscode-jsonrpc": "9.0.1",
|
|
33
|
+
"vscode-languageserver": "10.1.0",
|
|
34
|
+
"vscode-uri": "3.1.0",
|
|
35
|
+
"@vue-html-bridge/adapter-testkit": "0.1.0",
|
|
36
|
+
"@vue-html-bridge/language-server": "0.1.0"
|
|
37
|
+
},
|
|
38
|
+
"scripts": {
|
|
39
|
+
"build": "tsc -p tsconfig.build.json && chmod +x dist/bin.js",
|
|
40
|
+
"typecheck": "tsc -p tsconfig.json",
|
|
41
|
+
"test": "vitest run"
|
|
42
|
+
}
|
|
43
|
+
}
|