@jasonbelmonti/markdown-engine 3.6.0 → 3.8.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/CHANGELOG.md +19 -0
- package/README.md +40 -11
- package/dist/cli/declarative-validation.d.ts +3 -9
- package/dist/cli/declarative-validation.d.ts.map +1 -1
- package/dist/cli/declarative-validation.js +6 -16
- package/dist/cli/declarative-validation.js.map +1 -1
- package/dist/cli/run.d.ts.map +1 -1
- package/dist/cli/run.js +2 -0
- package/dist/cli/run.js.map +1 -1
- package/dist/cli/validate-args.d.ts +3 -1
- package/dist/cli/validate-args.d.ts.map +1 -1
- package/dist/cli/validate-args.js +45 -92
- package/dist/cli/validate-args.js.map +1 -1
- package/dist/cli/validation-output.d.ts +16 -0
- package/dist/cli/validation-output.d.ts.map +1 -0
- package/dist/cli/validation-output.js +26 -0
- package/dist/cli/validation-output.js.map +1 -0
- package/dist/cli/validation-report.d.ts +8 -0
- package/dist/cli/validation-report.d.ts.map +1 -0
- package/dist/cli/validation-report.js +24 -0
- package/dist/cli/validation-report.js.map +1 -0
- package/dist/cli/validation-summary.d.ts +47 -0
- package/dist/cli/validation-summary.d.ts.map +1 -0
- package/dist/cli/validation-summary.js +55 -0
- package/dist/cli/validation-summary.js.map +1 -0
- package/dist/declarative-validation/assertions/evaluator.d.ts.map +1 -1
- package/dist/declarative-validation/assertions/evaluator.js +3 -0
- package/dist/declarative-validation/assertions/evaluator.js.map +1 -1
- package/dist/declarative-validation/assertions/table-rows-complete.d.ts +4 -0
- package/dist/declarative-validation/assertions/table-rows-complete.d.ts.map +1 -0
- package/dist/declarative-validation/assertions/table-rows-complete.js +40 -0
- package/dist/declarative-validation/assertions/table-rows-complete.js.map +1 -0
- package/dist/declarative-validation/compiler/assertion-builders.d.ts.map +1 -1
- package/dist/declarative-validation/compiler/assertion-builders.js +2 -0
- package/dist/declarative-validation/compiler/assertion-builders.js.map +1 -1
- package/dist/declarative-validation/compiler/assertions.d.ts.map +1 -1
- package/dist/declarative-validation/compiler/assertions.js +1 -0
- package/dist/declarative-validation/compiler/assertions.js.map +1 -1
- package/dist/declarative-validation/compiler/compatibility.d.ts.map +1 -1
- package/dist/declarative-validation/compiler/compatibility.js +1 -0
- package/dist/declarative-validation/compiler/compatibility.js.map +1 -1
- package/dist/declarative-validation/compiler/plan.d.ts +2 -0
- package/dist/declarative-validation/compiler/plan.d.ts.map +1 -1
- package/dist/declarative-validation/compiler/table-rows-complete.d.ts +3 -0
- package/dist/declarative-validation/compiler/table-rows-complete.d.ts.map +1 -0
- package/dist/declarative-validation/compiler/table-rows-complete.js +17 -0
- package/dist/declarative-validation/compiler/table-rows-complete.js.map +1 -0
- package/dist/declarative-validation/profile/assertion-schema.d.ts.map +1 -1
- package/dist/declarative-validation/profile/assertion-schema.js +14 -0
- package/dist/declarative-validation/profile/assertion-schema.js.map +1 -1
- package/dist/declarative-validation/profile/index.d.ts +1 -0
- package/dist/declarative-validation/profile/index.d.ts.map +1 -1
- package/dist/internal/package-version.d.ts +1 -1
- package/dist/internal/package-version.js +1 -1
- package/dist-bundled/markdown-engine-cli.mjs +266 -149
- package/docs/contracts/declarative-validation.md +123 -7
- package/fixtures/declarative-validation/examples/table-rows-complete/README.md +65 -0
- package/fixtures/declarative-validation/examples/table-rows-complete/blockquote.md +3 -0
- package/fixtures/declarative-validation/examples/table-rows-complete/complete.md +3 -0
- package/fixtures/declarative-validation/examples/table-rows-complete/consumer-missing.md +50 -0
- package/fixtures/declarative-validation/examples/table-rows-complete/consumer-repaired.md +50 -0
- package/fixtures/declarative-validation/examples/table-rows-complete/excess.md +3 -0
- package/fixtures/declarative-validation/examples/table-rows-complete/explicit-empty.md +3 -0
- package/fixtures/declarative-validation/examples/table-rows-complete/header-only.md +2 -0
- package/fixtures/declarative-validation/examples/table-rows-complete/legacy.yaml +10 -0
- package/fixtures/declarative-validation/examples/table-rows-complete/missing.md +3 -0
- package/fixtures/declarative-validation/examples/table-rows-complete/multiple.md +5 -0
- package/fixtures/declarative-validation/examples/table-rows-complete/oracle.json +85 -0
- package/fixtures/declarative-validation/examples/table-rows-complete/profile.yaml +11 -0
- package/fixtures/declarative-validation/examples/table-rows-complete/shape.yaml +8 -0
- package/fixtures/declarative-validation/examples/table-rows-complete/syntax.md +3 -0
- package/package.json +2 -2
- package/scripts/install-markdown-engine-cli.sh +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,25 @@
|
|
|
4
4
|
|
|
5
5
|
No unreleased changes.
|
|
6
6
|
|
|
7
|
+
## 3.8.0 - 2026-09-27
|
|
8
|
+
|
|
9
|
+
### Added
|
|
10
|
+
|
|
11
|
+
- Added opt-in validation CLI `--output summary --report-file <new-file>`:
|
|
12
|
+
bounded JSON diagnostics and verdict/identity metadata on stdout, with the
|
|
13
|
+
complete existing JSON result retained in an exclusive report file and
|
|
14
|
+
identified by its byte digest. Default full output is unchanged; report
|
|
15
|
+
publication errors exit 2 without printing a successful validation result.
|
|
16
|
+
|
|
17
|
+
## 3.7.0 - 2026-09-26
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
|
|
21
|
+
- Added the opt-in V2 `tableRowsComplete` assertion to require each selected
|
|
22
|
+
table body row to match the header cell count, with located diagnostics for
|
|
23
|
+
missing and excess cells. Explicit empty cells remain a separate nonblank
|
|
24
|
+
content concern, and existing profiles retain their behavior by default.
|
|
25
|
+
|
|
7
26
|
## 3.6.0 - 2026-09-13
|
|
8
27
|
|
|
9
28
|
### Added
|
package/README.md
CHANGED
|
@@ -6,14 +6,13 @@ profile and runtime work.
|
|
|
6
6
|
Package release state:
|
|
7
7
|
|
|
8
8
|
- package name: `@jasonbelmonti/markdown-engine`
|
|
9
|
-
- package metadata version: `3.
|
|
9
|
+
- package metadata version: `3.8.0`
|
|
10
10
|
- published npm versions before this release: `0.1.0`, `1.0.0`, `2.0.0`,
|
|
11
|
-
`3.0.0`, `3.1.0`, `3.1.1`, `3.2.0`, `3.3.0`, `3.4.0`, `3.5.0`
|
|
12
|
-
- npm release target: `3.
|
|
11
|
+
`3.0.0`, `3.1.0`, `3.1.1`, `3.2.0`, `3.3.0`, `3.4.0`, `3.5.0`, `3.6.0`
|
|
12
|
+
- npm release target: `3.8.0` on `latest`
|
|
13
13
|
- website: <https://jasonbelmonti.github.io/markdown-engine/>
|
|
14
|
-
- release focus: opt-in
|
|
15
|
-
|
|
16
|
-
rich IR contract
|
|
14
|
+
- release focus: opt-in compact validation output with complete retained reports,
|
|
15
|
+
preserving default full output and the `documentVersion: "1.0.0"` rich IR contract
|
|
17
16
|
- maintainer documentation map: [docs/README.md](docs/README.md)
|
|
18
17
|
- design reference:
|
|
19
18
|
[Markdown Engine 1.0 Rich IR design](docs/design/markdown-engine-1.0-rich-ir-operational-design-spec.md)
|
|
@@ -30,7 +29,9 @@ Package release state:
|
|
|
30
29
|
|
|
31
30
|
Out of scope for this package: profile compiler behavior, runtime lenses, MCP
|
|
32
31
|
transport, agent adapters, semantic or LLM evaluation, arbitrary rule plugins,
|
|
33
|
-
network services,
|
|
32
|
+
network services, persistent workflow state, and raw parser AST as a public contract.
|
|
33
|
+
The CLI can write an explicitly requested validation report; the engine API remains
|
|
34
|
+
free of filesystem writes.
|
|
34
35
|
|
|
35
36
|
## Public API
|
|
36
37
|
|
|
@@ -85,7 +86,7 @@ console.log(validationResult.valid);
|
|
|
85
86
|
console.log(serialize(validationResult, { pretty: true }));
|
|
86
87
|
```
|
|
87
88
|
|
|
88
|
-
Package 3.
|
|
89
|
+
Package 3.8 retains the serialized document contract at
|
|
89
90
|
`documentVersion: "1.0.0"` and makes that rich IR path the default for
|
|
90
91
|
`normalize(parsed)`. Callers may still pass
|
|
91
92
|
`normalize(parsed, { documentVersion: "1.0.0" })` explicitly. That path adds
|
|
@@ -158,6 +159,34 @@ Successful validation exits with code `0`; validation or normalization error
|
|
|
158
159
|
diagnostics exit with code `1`. Validation JSON includes `profile`,
|
|
159
160
|
`ruleResults`, `diagnostics`, and `evidence`.
|
|
160
161
|
|
|
162
|
+
For a compact machine-readable response, retain the complete result separately:
|
|
163
|
+
|
|
164
|
+
```sh
|
|
165
|
+
mkdir -p reports
|
|
166
|
+
markdown-engine validate \
|
|
167
|
+
--file node_modules/@jasonbelmonti/markdown-engine/fixtures/declarative-validation/examples/operational-spec/pass.md \
|
|
168
|
+
--profile node_modules/@jasonbelmonti/markdown-engine/fixtures/declarative-validation/examples/operational-spec/profile.yaml \
|
|
169
|
+
--output summary --report-file reports/validation-001.json
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
`--output full` is the default and preserves the existing JSON byte layout.
|
|
173
|
+
`--output summary` requires `--report-file` and returns the verdict, stage,
|
|
174
|
+
exit code, runtime/profile identities, diagnostic counts, and at most ten
|
|
175
|
+
located diagnostics (errors first). Omitted diagnostics and shortened fields
|
|
176
|
+
are explicitly counted. The report contains the complete default JSON,
|
|
177
|
+
including evidence; stdout identifies its absolute path, byte count and
|
|
178
|
+
SHA-256 digest. Profile-stage failures retain their own JSON shape in the
|
|
179
|
+
report and do not invent document/profile evidence identities.
|
|
180
|
+
|
|
181
|
+
Choose a new report filename per invocation; its parent directory must exist.
|
|
182
|
+
Reports are published without overwriting existing files, including either
|
|
183
|
+
input. A report-write failure exits `2`, prints an error to stderr and emits
|
|
184
|
+
no validation JSON to stdout. `--report-file` can also accompany full output.
|
|
185
|
+
Usage and input-read failures keep their existing stderr behavior and do not
|
|
186
|
+
create a report. Summary output is presentation only; it does not change any
|
|
187
|
+
validation result or establish semantic acceptance. See the
|
|
188
|
+
[compact output contract](docs/contracts/declarative-validation.md#compact-validation-output).
|
|
189
|
+
|
|
161
190
|
Declarative validation compatibility is syntax-versioned. Existing v1 profiles
|
|
162
191
|
remain on the v1 result and evidence shape by keeping:
|
|
163
192
|
|
|
@@ -289,13 +318,13 @@ By default, the installer places the CLI under
|
|
|
289
318
|
and writes the wrapper to
|
|
290
319
|
`${MARKDOWN_ENGINE_BIN_DIR:-$HOME/.local/bin}/markdown-engine`. The installer
|
|
291
320
|
uses a local bundled artifact only when it matches the pinned artifact hash.
|
|
292
|
-
Otherwise it downloads `@jasonbelmonti/markdown-engine@3.
|
|
321
|
+
Otherwise it downloads `@jasonbelmonti/markdown-engine@3.8.0` with `npm pack
|
|
293
322
|
--ignore-scripts` and extracts only
|
|
294
323
|
`package/dist-bundled/markdown-engine-cli.mjs` from the tarball. It verifies the
|
|
295
324
|
pinned artifact hash before installing:
|
|
296
325
|
|
|
297
326
|
```text
|
|
298
|
-
|
|
327
|
+
cecfb88ab9cb9a3030c13e41b5e56ac30b44436fb1da7bb890bea5f9bd215fce
|
|
299
328
|
```
|
|
300
329
|
|
|
301
330
|
The installed wrapper is:
|
|
@@ -304,7 +333,7 @@ The installed wrapper is:
|
|
|
304
333
|
"${MARKDOWN_ENGINE_BIN_DIR:-$HOME/.local/bin}/markdown-engine" validate --file <file.md> --profile <profile.yaml> --format json
|
|
305
334
|
```
|
|
306
335
|
|
|
307
|
-
Package 3.
|
|
336
|
+
Package 3.8 keeps the 2.0 API normalization default: callers that invoke
|
|
308
337
|
`normalize(parsed)` receive the rich IR `1.0.0` document shape. Consumers that
|
|
309
338
|
still need the legacy `0.0.0` shape should consume the rich IR fields
|
|
310
339
|
(`target`, `sections`, `textSpans`, `tables`, `lists`, and `links`) or pin
|
|
@@ -1,18 +1,12 @@
|
|
|
1
1
|
import type { DeclarativeOutputFormat } from "../declarative-validation/profile/index.js";
|
|
2
|
+
import { type ValidationOutputOptions, type ValidationOutputResult } from "./validation-output.js";
|
|
2
3
|
/** @internal Declarative validation CLI behavior is not part of the package API. */
|
|
3
|
-
export interface DeclarativeValidationCliAdapterOptions {
|
|
4
|
+
export interface DeclarativeValidationCliAdapterOptions extends ValidationOutputOptions {
|
|
4
5
|
cwd: string;
|
|
5
6
|
filePath: string;
|
|
6
7
|
profilePath: string;
|
|
7
8
|
format: DeclarativeOutputFormat;
|
|
8
9
|
}
|
|
9
|
-
export type DeclarativeValidationCliAdapterResult =
|
|
10
|
-
kind: "output";
|
|
11
|
-
exitCode: 0 | 1;
|
|
12
|
-
output: string;
|
|
13
|
-
} | {
|
|
14
|
-
kind: "fileError";
|
|
15
|
-
message: string;
|
|
16
|
-
};
|
|
10
|
+
export type DeclarativeValidationCliAdapterResult = ValidationOutputResult;
|
|
17
11
|
export declare function runDeclarativeValidationCli(input: DeclarativeValidationCliAdapterOptions): Promise<DeclarativeValidationCliAdapterResult>;
|
|
18
12
|
//# sourceMappingURL=declarative-validation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"declarative-validation.d.ts","sourceRoot":"","sources":["../../src/cli/declarative-validation.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,uBAAuB,EAExB,MAAM,4CAA4C,CAAC;
|
|
1
|
+
{"version":3,"file":"declarative-validation.d.ts","sourceRoot":"","sources":["../../src/cli/declarative-validation.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EACV,uBAAuB,EAExB,MAAM,4CAA4C,CAAC;AASpD,OAAO,EAA0B,KAAK,uBAAuB,EAAE,KAAK,sBAAsB,EAAE,MAAM,wBAAwB,CAAC;AAE3H,oFAAoF;AACpF,MAAM,WAAW,sCAAuC,SAAQ,uBAAuB;IACrF,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,uBAAuB,CAAC;CACjC;AAED,MAAM,MAAM,qCAAqC,GAAG,sBAAsB,CAAC;AAE3E,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,sCAAsC,GAC5C,OAAO,CAAC,qCAAqC,CAAC,CA8EhD"}
|
|
@@ -3,9 +3,9 @@ import { compileValidationProfile } from "../declarative-validation/compiler/ind
|
|
|
3
3
|
import { parseValidationProfileInput } from "../declarative-validation/profile/index.js";
|
|
4
4
|
import { createDeclarativeValidationResult } from "../declarative-validation/results/index.js";
|
|
5
5
|
import { cloneDiagnostics, hasErrorDiagnostic } from "../diagnostics/index.js";
|
|
6
|
-
import { normalizeStableJsonValue } from "../internal/stable-json.js";
|
|
7
6
|
import { readCliFile } from "./files.js";
|
|
8
7
|
import { normalizeMarkdown } from "./normalize-markdown.js";
|
|
8
|
+
import { outputValidationResult } from "./validation-output.js";
|
|
9
9
|
export async function runDeclarativeValidationCli(input) {
|
|
10
10
|
const profileText = await readValidationFile(input.profilePath, input.cwd);
|
|
11
11
|
if (profileText.kind === "fileError") {
|
|
@@ -16,11 +16,11 @@ export async function runDeclarativeValidationCli(input) {
|
|
|
16
16
|
});
|
|
17
17
|
if (profileResult.profile === undefined ||
|
|
18
18
|
hasErrorDiagnostic(profileResult.diagnostics)) {
|
|
19
|
-
return
|
|
19
|
+
return outputValidationResult(profileStageResult(profileResult.diagnostics), 1, input);
|
|
20
20
|
}
|
|
21
21
|
const compileDiagnostics = compileProfileForCli(profileResult.profile);
|
|
22
22
|
if (hasErrorDiagnostic(compileDiagnostics)) {
|
|
23
|
-
return
|
|
23
|
+
return outputValidationResult(profileStageResult([...profileResult.diagnostics, ...compileDiagnostics]), 1, input);
|
|
24
24
|
}
|
|
25
25
|
const markdown = await readValidationFile(input.filePath, input.cwd);
|
|
26
26
|
if (markdown.kind === "fileError") {
|
|
@@ -36,14 +36,14 @@ export async function runDeclarativeValidationCli(input) {
|
|
|
36
36
|
...normalizeResult.diagnostics,
|
|
37
37
|
];
|
|
38
38
|
if (hasErrorDiagnostic(normalizeResult.diagnostics)) {
|
|
39
|
-
return
|
|
39
|
+
return outputValidationResult(documentDiagnosticsResult(normalizeResult.document, profileResult.profile, markdown.content, [
|
|
40
40
|
...documentDiagnostics,
|
|
41
41
|
...documentVersionDiagnostics(profileResult.profile, normalizeResult.document.version),
|
|
42
|
-
]), 1);
|
|
42
|
+
]), 1, input);
|
|
43
43
|
}
|
|
44
44
|
const validationResult = validateWithProfile(normalizeResult.document, profileResult.profile, { includeEvidence: true, sourceText: markdown.content });
|
|
45
45
|
const result = mergeDocumentDiagnostics(validationResult, documentDiagnostics);
|
|
46
|
-
return
|
|
46
|
+
return outputValidationResult(result, hasErrorDiagnostic(result.diagnostics) ? 1 : 0, input);
|
|
47
47
|
}
|
|
48
48
|
function compileProfileForCli(profile) {
|
|
49
49
|
return compileValidationProfile(profile).diagnostics;
|
|
@@ -99,16 +99,6 @@ function mergeDocumentDiagnostics(validationResult, documentDiagnostics) {
|
|
|
99
99
|
: {}),
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
|
-
function outputResult(result, exitCode) {
|
|
103
|
-
return {
|
|
104
|
-
kind: "output",
|
|
105
|
-
exitCode,
|
|
106
|
-
output: serializeDeclarativeValidationCliJsonResult(result),
|
|
107
|
-
};
|
|
108
|
-
}
|
|
109
|
-
function serializeDeclarativeValidationCliJsonResult(result) {
|
|
110
|
-
return JSON.stringify(normalizeStableJsonValue(result), null, 2) ?? "null";
|
|
111
|
-
}
|
|
112
102
|
async function readValidationFile(path, cwd) {
|
|
113
103
|
try {
|
|
114
104
|
return {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"declarative-validation.js","sourceRoot":"","sources":["../../src/cli/declarative-validation.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,MAAM,kCAAkC,CAAC;AAGvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,6CAA6C,CAAC;AACvF,OAAO,EAAE,2BAA2B,EAAE,MAAM,4CAA4C,CAAC;AAKzF,OAAO,EAAE,iCAAiC,EAAE,MAAM,4CAA4C,CAAC;
|
|
1
|
+
{"version":3,"file":"declarative-validation.js","sourceRoot":"","sources":["../../src/cli/declarative-validation.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/run.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC;CACtC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,wBAAsB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"run.d.ts","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,UAAU;IACzB,KAAK,CAAC,KAAK,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAAC;CACtC;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,EAAE,UAAU,CAAC;CACpB;AAED,wBAAsB,MAAM,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,MAAM,CAAC,CAqDhE"}
|
package/dist/cli/run.js
CHANGED
|
@@ -20,6 +20,8 @@ export async function runCli(input) {
|
|
|
20
20
|
filePath: argsResult.filePath,
|
|
21
21
|
format: argsResult.format,
|
|
22
22
|
profilePath: argsResult.profilePath,
|
|
23
|
+
output: argsResult.output,
|
|
24
|
+
...(argsResult.reportFile !== undefined ? { reportFile: argsResult.reportFile } : {}),
|
|
23
25
|
});
|
|
24
26
|
if (validationResult.kind === "fileError") {
|
|
25
27
|
input.stderr.write(`${validationResult.message}\n`);
|
package/dist/cli/run.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,EAAE,mCAAmC,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAa5D,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,KAAkB;IAC7C,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE5C,IAAI,UAAU,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC/B,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACrC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAChC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,OAAO,OAAO,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;QACnE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACnC,MAAM,gBAAgB,GAAG,MAAM,2BAA2B,CAAC;YACzD,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,QAAQ,EAAE,UAAU,CAAC,QAAQ;YAC7B,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,WAAW,EAAE,UAAU,CAAC,WAAW;
|
|
1
|
+
{"version":3,"file":"run.js","sourceRoot":"","sources":["../../src/cli/run.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,EAAE,2BAA2B,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,EAAE,mCAAmC,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAa5D,MAAM,CAAC,KAAK,UAAU,MAAM,CAAC,KAAkB;IAC7C,MAAM,UAAU,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAE5C,IAAI,UAAU,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QAC/B,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACrC,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;QAChC,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,UAAU,CAAC,OAAO,OAAO,UAAU,CAAC,KAAK,EAAE,CAAC,CAAC;QACnE,OAAO,CAAC,CAAC;IACX,CAAC;IAED,IAAI,UAAU,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACnC,MAAM,gBAAgB,GAAG,MAAM,2BAA2B,CAAC;YACzD,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,QAAQ,EAAE,UAAU,CAAC,QAAQ;YAC7B,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,WAAW,EAAE,UAAU,CAAC,WAAW;YACnC,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,GAAG,CAAC,UAAU,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,UAAU,EAAE,UAAU,CAAC,UAAU,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACtF,CAAC,CAAC;QAEH,IAAI,gBAAgB,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YAC1C,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAAC,OAAO,IAAI,CAAC,CAAC;YACpD,OAAO,CAAC,CAAC;QACX,CAAC;QAED,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,gBAAgB,CAAC,MAAM,IAAI,CAAC,CAAC;QACnD,OAAO,gBAAgB,CAAC,QAAQ,CAAC;IACnC,CAAC;IAED,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,gBAAgB,CAAC,UAAU,CAAC,UAAU,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC;QAC1E,MAAM,eAAe,GAAG,iBAAiB,CAAC;YACxC,eAAe,EAAE,UAAU,CAAC,eAAe;YAC3C,QAAQ;YACR,IAAI,EAAE,UAAU,CAAC,UAAU;SAC5B,CAAC,CAAC;QAEH,KAAK,CAAC,MAAM,CAAC,KAAK,CAChB,GAAG,SAAS,CAAC,eAAe,EAAE;YAC5B,iBAAiB,EAAE,mCAAmC,CACpD,UAAU,CAAC,eAAe,CAC3B;YACD,MAAM,EAAE,IAAI;SACb,CAAC,IAAI,CACP,CAAC;QACF,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAC/C,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC;AAED,SAAS,YAAY,CAAC,KAAc;IAClC,OAAO,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAChE,CAAC"}
|
|
@@ -4,6 +4,8 @@ export interface ValidateCliArgs {
|
|
|
4
4
|
filePath: string;
|
|
5
5
|
format: DeclarativeOutputFormat;
|
|
6
6
|
profilePath: string;
|
|
7
|
+
output: "full" | "summary";
|
|
8
|
+
reportFile?: string;
|
|
7
9
|
}
|
|
8
10
|
export type ValidateCliArgsResult = ValidateCliArgs | {
|
|
9
11
|
kind: "help";
|
|
@@ -13,6 +15,6 @@ export type ValidateCliArgsResult = ValidateCliArgs | {
|
|
|
13
15
|
message: string;
|
|
14
16
|
usage: string;
|
|
15
17
|
};
|
|
16
|
-
export declare const validateCliUsage = "Usage: markdown-engine validate --file <markdown-file> --profile <profile-file> [--format json]\n\nRuns declarative validation for one Markdown file and one validation profile.\n\nOptions:\n --file <markdown-file> Markdown file to validate.\n --profile <profile-file> Declarative validation profile to apply.\n --format json Output JSON. This is the default and only supported format.\n -h, --help Show this help message.\n\nExit status:\n 0 Validation completed with no error diagnostics.\n 1 Profile/config/compile or validation diagnostics failed.\n 2 Usage, unsupported format, unknown args, or file read error.\n";
|
|
18
|
+
export declare const validateCliUsage = "Usage: markdown-engine validate --file <markdown-file> --profile <profile-file> [--format json] [--output full|summary] [--report-file <new-file>]\n\nRuns declarative validation for one Markdown file and one validation profile.\n\nOptions:\n --file <markdown-file> Markdown file to validate.\n --profile <profile-file> Declarative validation profile to apply.\n --format json Output JSON. This is the default and only supported format.\n --output full|summary Full JSON (default) or a compact validation summary.\n --report-file <new-file> Save full JSON; required for summary. Never overwrites.\n -h, --help Show this help message.\n\nSummary includes at most 10 top-level diagnostics, errors first, with explicit\nomission/truncation counts. The report's parent directory must already exist.\n\nExit status:\n 0 Validation completed with no error diagnostics.\n 1 Profile/config/compile or validation diagnostics failed.\n 2 Usage, unsupported format, unknown args, or file read/write error.\n";
|
|
17
19
|
export declare function parseValidateCliArgs(args: string[]): ValidateCliArgsResult;
|
|
18
20
|
//# sourceMappingURL=validate-args.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-args.d.ts","sourceRoot":"","sources":["../../src/cli/validate-args.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4CAA4C,CAAC;
|
|
1
|
+
{"version":3,"file":"validate-args.d.ts","sourceRoot":"","sources":["../../src/cli/validate-args.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,4CAA4C,CAAC;AAE1F,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,UAAU,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,uBAAuB,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,qBAAqB,GAC7B,eAAe,GACf;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC/B;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CAAC;AAEtD,eAAO,MAAM,gBAAgB,0oCAmB5B,CAAC;AAEF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,qBAAqB,CAoD1E"}
|
|
@@ -1,10 +1,4 @@
|
|
|
1
|
-
const
|
|
2
|
-
const fileAssignmentPrefix = `${fileFlag}=`;
|
|
3
|
-
const profileFlag = "--profile";
|
|
4
|
-
const profileAssignmentPrefix = `${profileFlag}=`;
|
|
5
|
-
const formatFlag = "--format";
|
|
6
|
-
const formatAssignmentPrefix = `${formatFlag}=`;
|
|
7
|
-
export const validateCliUsage = `Usage: markdown-engine validate --file <markdown-file> --profile <profile-file> [--format json]
|
|
1
|
+
export const validateCliUsage = `Usage: markdown-engine validate --file <markdown-file> --profile <profile-file> [--format json] [--output full|summary] [--report-file <new-file>]
|
|
8
2
|
|
|
9
3
|
Runs declarative validation for one Markdown file and one validation profile.
|
|
10
4
|
|
|
@@ -12,119 +6,78 @@ Options:
|
|
|
12
6
|
--file <markdown-file> Markdown file to validate.
|
|
13
7
|
--profile <profile-file> Declarative validation profile to apply.
|
|
14
8
|
--format json Output JSON. This is the default and only supported format.
|
|
9
|
+
--output full|summary Full JSON (default) or a compact validation summary.
|
|
10
|
+
--report-file <new-file> Save full JSON; required for summary. Never overwrites.
|
|
15
11
|
-h, --help Show this help message.
|
|
16
12
|
|
|
13
|
+
Summary includes at most 10 top-level diagnostics, errors first, with explicit
|
|
14
|
+
omission/truncation counts. The report's parent directory must already exist.
|
|
15
|
+
|
|
17
16
|
Exit status:
|
|
18
17
|
0 Validation completed with no error diagnostics.
|
|
19
18
|
1 Profile/config/compile or validation diagnostics failed.
|
|
20
|
-
2 Usage, unsupported format, unknown args, or file read error.
|
|
19
|
+
2 Usage, unsupported format, unknown args, or file read/write error.
|
|
21
20
|
`;
|
|
22
21
|
export function parseValidateCliArgs(args) {
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
|
|
22
|
+
const values = {
|
|
23
|
+
"--file": [], "--profile": [], "--format": [], "--output": [], "--report-file": [],
|
|
24
|
+
};
|
|
26
25
|
for (let index = 0; index < args.length; index += 1) {
|
|
27
26
|
const arg = args[index];
|
|
28
27
|
if (arg === "-h" || arg === "--help") {
|
|
29
28
|
return { kind: "help", usage: validateCliUsage };
|
|
30
29
|
}
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
continue;
|
|
30
|
+
const equals = arg.indexOf("=");
|
|
31
|
+
const flag = equals === -1 ? arg : arg.slice(0, equals);
|
|
32
|
+
if (!Object.hasOwn(values, flag))
|
|
33
|
+
return validateError(`Unknown argument: ${arg}`);
|
|
34
|
+
const entries = values[flag];
|
|
35
|
+
if (flag !== "--file" && flag !== "--profile" && entries.length > 0) {
|
|
36
|
+
return validateError(`Expected at most one ${flag} selector.`);
|
|
39
37
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
38
|
+
const value = equals === -1 ? args[index + 1] : arg.slice(equals + 1);
|
|
39
|
+
if (value === undefined || (equals === -1 && value.startsWith("-"))) {
|
|
40
|
+
return validateError(`Missing value for ${flag}.`);
|
|
43
41
|
}
|
|
44
|
-
if (
|
|
45
|
-
|
|
46
|
-
if (value.kind === "error") {
|
|
47
|
-
return validateError(value.message);
|
|
48
|
-
}
|
|
49
|
-
profilePaths.push(value.value);
|
|
50
|
-
index += 1;
|
|
51
|
-
continue;
|
|
42
|
+
if (flag === "--format" && value !== "json") {
|
|
43
|
+
return validateError(`Unsupported validation output format: ${value}.`);
|
|
52
44
|
}
|
|
53
|
-
if (
|
|
54
|
-
|
|
55
|
-
continue;
|
|
45
|
+
if (flag === "--output" && value !== "full" && value !== "summary") {
|
|
46
|
+
return validateError(`Unsupported validation output mode: ${value}.`);
|
|
56
47
|
}
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
return validateError("Expected at most one --format selector.");
|
|
60
|
-
}
|
|
61
|
-
const value = readRequiredFlagValue(arg, args, index);
|
|
62
|
-
if (value.kind === "error") {
|
|
63
|
-
return validateError(value.message);
|
|
64
|
-
}
|
|
65
|
-
const parsedFormat = parseDeclarativeOutputFormat(value.value);
|
|
66
|
-
if (parsedFormat.kind === "error") {
|
|
67
|
-
return validateError(parsedFormat.message);
|
|
68
|
-
}
|
|
69
|
-
format = parsedFormat.format;
|
|
48
|
+
entries.push(value);
|
|
49
|
+
if (equals === -1)
|
|
70
50
|
index += 1;
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
if (arg?.startsWith(formatAssignmentPrefix) === true) {
|
|
74
|
-
if (format !== undefined) {
|
|
75
|
-
return validateError("Expected at most one --format selector.");
|
|
76
|
-
}
|
|
77
|
-
const parsedFormat = parseDeclarativeOutputFormat(arg.slice(formatAssignmentPrefix.length));
|
|
78
|
-
if (parsedFormat.kind === "error") {
|
|
79
|
-
return validateError(parsedFormat.message);
|
|
80
|
-
}
|
|
81
|
-
format = parsedFormat.format;
|
|
82
|
-
continue;
|
|
83
|
-
}
|
|
84
|
-
return validateError(`Unknown argument: ${arg ?? ""}`);
|
|
85
51
|
}
|
|
86
|
-
|
|
52
|
+
const files = values["--file"];
|
|
53
|
+
const profiles = values["--profile"];
|
|
54
|
+
if (files.length === 0)
|
|
87
55
|
return validateError("Expected exactly one --file target.");
|
|
88
|
-
|
|
89
|
-
if (filePaths.length > 1) {
|
|
56
|
+
if (files.length > 1)
|
|
90
57
|
return validateError("Expected one Markdown file target, received multiple.");
|
|
91
|
-
|
|
92
|
-
if (profilePaths.length === 0) {
|
|
58
|
+
if (profiles.length === 0)
|
|
93
59
|
return validateError("Expected exactly one --profile target.");
|
|
94
|
-
|
|
95
|
-
if (profilePaths.length > 1) {
|
|
60
|
+
if (profiles.length > 1)
|
|
96
61
|
return validateError("Expected one profile file target, received multiple.");
|
|
97
|
-
|
|
98
|
-
const
|
|
99
|
-
|
|
100
|
-
if (filePath === undefined || filePath.trim() === "") {
|
|
62
|
+
const filePath = files[0];
|
|
63
|
+
const profilePath = profiles[0];
|
|
64
|
+
if (filePath.trim() === "")
|
|
101
65
|
return validateError("File path cannot be empty.");
|
|
102
|
-
|
|
103
|
-
if (profilePath === undefined || profilePath.trim() === "") {
|
|
66
|
+
if (profilePath.trim() === "")
|
|
104
67
|
return validateError("Profile path cannot be empty.");
|
|
68
|
+
const output = (values["--output"][0] ?? "full");
|
|
69
|
+
const reportFile = values["--report-file"][0];
|
|
70
|
+
if (reportFile !== undefined && reportFile.trim() === "") {
|
|
71
|
+
return validateError("Report file path cannot be empty.");
|
|
72
|
+
}
|
|
73
|
+
if (output === "summary" && reportFile === undefined) {
|
|
74
|
+
return validateError("--output summary requires --report-file to retain the full result.");
|
|
105
75
|
}
|
|
106
76
|
return {
|
|
107
|
-
kind: "validate",
|
|
108
|
-
|
|
109
|
-
format: format ?? "json",
|
|
110
|
-
profilePath,
|
|
77
|
+
kind: "validate", filePath, profilePath, format: "json", output,
|
|
78
|
+
...(reportFile !== undefined ? { reportFile } : {}),
|
|
111
79
|
};
|
|
112
80
|
}
|
|
113
|
-
function readRequiredFlagValue(arg, args, index) {
|
|
114
|
-
const value = args[index + 1];
|
|
115
|
-
if (value === undefined || value.startsWith("-")) {
|
|
116
|
-
return { kind: "error", message: `Missing value for ${arg}.` };
|
|
117
|
-
}
|
|
118
|
-
return { kind: "ok", value };
|
|
119
|
-
}
|
|
120
|
-
function parseDeclarativeOutputFormat(value) {
|
|
121
|
-
return value === "json"
|
|
122
|
-
? { kind: "ok", format: value }
|
|
123
|
-
: {
|
|
124
|
-
kind: "error",
|
|
125
|
-
message: `Unsupported validation output format: ${value}.`,
|
|
126
|
-
};
|
|
127
|
-
}
|
|
128
81
|
function validateError(message) {
|
|
129
82
|
return { kind: "error", message, usage: validateCliUsage };
|
|
130
83
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"validate-args.js","sourceRoot":"","sources":["../../src/cli/validate-args.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"validate-args.js","sourceRoot":"","sources":["../../src/cli/validate-args.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DeclarativeValidationCliJsonResult } from "../declarative-validation/results/index.js";
|
|
2
|
+
export interface ValidationOutputOptions {
|
|
3
|
+
cwd: string;
|
|
4
|
+
output?: "full" | "summary";
|
|
5
|
+
reportFile?: string;
|
|
6
|
+
}
|
|
7
|
+
export type ValidationOutputResult = {
|
|
8
|
+
kind: "output";
|
|
9
|
+
exitCode: 0 | 1;
|
|
10
|
+
output: string;
|
|
11
|
+
} | {
|
|
12
|
+
kind: "fileError";
|
|
13
|
+
message: string;
|
|
14
|
+
};
|
|
15
|
+
export declare function outputValidationResult(result: DeclarativeValidationCliJsonResult, exitCode: 0 | 1, options: ValidationOutputOptions): Promise<ValidationOutputResult>;
|
|
16
|
+
//# sourceMappingURL=validation-output.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation-output.d.ts","sourceRoot":"","sources":["../../src/cli/validation-output.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kCAAkC,EAAE,MAAM,4CAA4C,CAAC;AAKrG,MAAM,WAAW,uBAAuB;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,MAAM,MAAM,sBAAsB,GAC9B;IAAE,IAAI,EAAE,QAAQ,CAAC;IAAC,QAAQ,EAAE,CAAC,GAAG,CAAC,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACnD;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,CAAC;AAE3C,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,kCAAkC,EAC1C,QAAQ,EAAE,CAAC,GAAG,CAAC,EACf,OAAO,EAAE,uBAAuB,GAC/B,OAAO,CAAC,sBAAsB,CAAC,CAmBjC"}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { normalizeStableJsonValue } from "../internal/stable-json.js";
|
|
2
|
+
import { saveValidationReport } from "./validation-report.js";
|
|
3
|
+
import { createValidationSummary } from "./validation-summary.js";
|
|
4
|
+
export async function outputValidationResult(result, exitCode, options) {
|
|
5
|
+
const output = JSON.stringify(normalizeStableJsonValue(result), null, 2) ?? "null";
|
|
6
|
+
try {
|
|
7
|
+
const report = options.reportFile === undefined ? undefined
|
|
8
|
+
: await saveValidationReport(options.cwd, options.reportFile, `${output}\n`);
|
|
9
|
+
if (options.output === "summary") {
|
|
10
|
+
if (report === undefined)
|
|
11
|
+
throw new Error("--output summary requires --report-file.");
|
|
12
|
+
return {
|
|
13
|
+
kind: "output", exitCode,
|
|
14
|
+
output: JSON.stringify(normalizeStableJsonValue(createValidationSummary(result, exitCode, report))),
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
return { kind: "output", exitCode, output };
|
|
18
|
+
}
|
|
19
|
+
catch (error) {
|
|
20
|
+
return {
|
|
21
|
+
kind: "fileError",
|
|
22
|
+
message: `Unable to save validation report "${options.reportFile ?? ""}": ${error instanceof Error ? error.message : String(error)}`,
|
|
23
|
+
};
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=validation-output.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation-output.js","sourceRoot":"","sources":["../../src/cli/validation-output.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AACtE,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAC;AAC9D,OAAO,EAAE,uBAAuB,EAAE,MAAM,yBAAyB,CAAC;AAYlE,MAAM,CAAC,KAAK,UAAU,sBAAsB,CAC1C,MAA0C,EAC1C,QAAe,EACf,OAAgC;IAEhC,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC,wBAAwB,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC;IACnF,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,OAAO,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,SAAS;YACzD,CAAC,CAAC,MAAM,oBAAoB,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,UAAU,EAAE,GAAG,MAAM,IAAI,CAAC,CAAC;QAC/E,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;YACjC,IAAI,MAAM,KAAK,SAAS;gBAAE,MAAM,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC;YACtF,OAAO;gBACL,IAAI,EAAE,QAAQ,EAAE,QAAQ;gBACxB,MAAM,EAAE,IAAI,CAAC,SAAS,CAAC,wBAAwB,CAAC,uBAAuB,CAAC,MAAM,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;aACpG,CAAC;QACJ,CAAC;QACD,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO;YACL,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,qCAAqC,OAAO,CAAC,UAAU,IAAI,EAAE,MAAM,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE;SACrI,CAAC;IACJ,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export interface ValidationReportReference {
|
|
2
|
+
path: string;
|
|
3
|
+
sha256: string;
|
|
4
|
+
bytes: number;
|
|
5
|
+
}
|
|
6
|
+
/** Publish complete report bytes without replacing any existing destination. */
|
|
7
|
+
export declare function saveValidationReport(cwd: string, reportFile: string, content: string): Promise<ValidationReportReference>;
|
|
8
|
+
//# sourceMappingURL=validation-report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation-report.d.ts","sourceRoot":"","sources":["../../src/cli/validation-report.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,yBAAyB;IACxC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;CACf;AAED,gFAAgF;AAChF,wBAAsB,oBAAoB,CACxC,GAAG,EAAE,MAAM,EACX,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,yBAAyB,CAAC,CAiBpC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
import { link, mkdtemp, rm, writeFile } from "node:fs/promises";
|
|
3
|
+
import { dirname, join, resolve } from "node:path";
|
|
4
|
+
/** Publish complete report bytes without replacing any existing destination. */
|
|
5
|
+
export async function saveValidationReport(cwd, reportFile, content) {
|
|
6
|
+
const path = resolve(cwd, reportFile);
|
|
7
|
+
const temporaryDirectory = await mkdtemp(join(dirname(path), ".markdown-engine-report-"));
|
|
8
|
+
try {
|
|
9
|
+
const temporaryFile = join(temporaryDirectory, "report.json");
|
|
10
|
+
await writeFile(temporaryFile, content, { encoding: "utf8", mode: 0o600, flag: "wx" });
|
|
11
|
+
// A same-directory hard link publishes atomically and refuses existing paths,
|
|
12
|
+
// including symlinks/hard links to the Markdown or profile inputs.
|
|
13
|
+
await link(temporaryFile, path);
|
|
14
|
+
}
|
|
15
|
+
finally {
|
|
16
|
+
await rm(temporaryDirectory, { recursive: true, force: true });
|
|
17
|
+
}
|
|
18
|
+
return {
|
|
19
|
+
path,
|
|
20
|
+
sha256: createHash("sha256").update(content, "utf8").digest("hex"),
|
|
21
|
+
bytes: Buffer.byteLength(content, "utf8"),
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=validation-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validation-report.js","sourceRoot":"","sources":["../../src/cli/validation-report.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAQnD,gFAAgF;AAChF,MAAM,CAAC,KAAK,UAAU,oBAAoB,CACxC,GAAW,EACX,UAAkB,EAClB,OAAe;IAEf,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;IACtC,MAAM,kBAAkB,GAAG,MAAM,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,0BAA0B,CAAC,CAAC,CAAC;IAC1F,IAAI,CAAC;QACH,MAAM,aAAa,GAAG,IAAI,CAAC,kBAAkB,EAAE,aAAa,CAAC,CAAC;QAC9D,MAAM,SAAS,CAAC,aAAa,EAAE,OAAO,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QACvF,8EAA8E;QAC9E,mEAAmE;QACnE,MAAM,IAAI,CAAC,aAAa,EAAE,IAAI,CAAC,CAAC;IAClC,CAAC;YAAS,CAAC;QACT,MAAM,EAAE,CAAC,kBAAkB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;IACjE,CAAC;IACD,OAAO;QACL,IAAI;QACJ,MAAM,EAAE,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC;QAClE,KAAK,EAAE,MAAM,CAAC,UAAU,CAAC,OAAO,EAAE,MAAM,CAAC;KAC1C,CAAC;AACJ,CAAC"}
|