@timiagama/ecr 0.0.1 → 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.
Files changed (138) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +16 -0
  3. package/README.md +411 -7
  4. package/dist/bin.d.ts +20 -0
  5. package/dist/bin.d.ts.map +1 -0
  6. package/dist/bin.js +26 -0
  7. package/dist/bin.js.map +1 -0
  8. package/dist/cli/corpus-loader.d.ts +198 -0
  9. package/dist/cli/corpus-loader.d.ts.map +1 -0
  10. package/dist/cli/corpus-loader.js +351 -0
  11. package/dist/cli/corpus-loader.js.map +1 -0
  12. package/dist/cli/corpus-statistics.d.ts +113 -0
  13. package/dist/cli/corpus-statistics.d.ts.map +1 -0
  14. package/dist/cli/corpus-statistics.js +119 -0
  15. package/dist/cli/corpus-statistics.js.map +1 -0
  16. package/dist/cli/diagnostic-reporter.d.ts +103 -0
  17. package/dist/cli/diagnostic-reporter.d.ts.map +1 -0
  18. package/dist/cli/diagnostic-reporter.js +254 -0
  19. package/dist/cli/diagnostic-reporter.js.map +1 -0
  20. package/dist/cli/project-ignore.d.ts +113 -0
  21. package/dist/cli/project-ignore.d.ts.map +1 -0
  22. package/dist/cli/project-ignore.js +199 -0
  23. package/dist/cli/project-ignore.js.map +1 -0
  24. package/dist/cli/safe-text.d.ts +25 -0
  25. package/dist/cli/safe-text.d.ts.map +1 -0
  26. package/dist/cli/safe-text.js +34 -0
  27. package/dist/cli/safe-text.js.map +1 -0
  28. package/dist/cli/supervisor.d.ts +108 -0
  29. package/dist/cli/supervisor.d.ts.map +1 -0
  30. package/dist/cli/supervisor.js +139 -0
  31. package/dist/cli/supervisor.js.map +1 -0
  32. package/dist/cli.d.ts +247 -0
  33. package/dist/cli.d.ts.map +1 -0
  34. package/dist/cli.js +591 -0
  35. package/dist/cli.js.map +1 -0
  36. package/dist/corpus-validator.d.ts +183 -0
  37. package/dist/corpus-validator.d.ts.map +1 -0
  38. package/dist/corpus-validator.js +479 -0
  39. package/dist/corpus-validator.js.map +1 -0
  40. package/dist/document-identity-rule.d.ts +198 -0
  41. package/dist/document-identity-rule.d.ts.map +1 -0
  42. package/dist/document-identity-rule.js +244 -0
  43. package/dist/document-identity-rule.js.map +1 -0
  44. package/dist/ecr.d.ts +103 -0
  45. package/dist/ecr.d.ts.map +1 -0
  46. package/dist/ecr.js +216 -0
  47. package/dist/ecr.js.map +1 -0
  48. package/dist/glob-pattern.d.ts +94 -0
  49. package/dist/glob-pattern.d.ts.map +1 -0
  50. package/dist/glob-pattern.js +188 -0
  51. package/dist/glob-pattern.js.map +1 -0
  52. package/dist/heading-source-form.d.ts +77 -0
  53. package/dist/heading-source-form.d.ts.map +1 -0
  54. package/dist/heading-source-form.js +129 -0
  55. package/dist/heading-source-form.js.map +1 -0
  56. package/dist/identifier-grammar.d.ts +212 -0
  57. package/dist/identifier-grammar.d.ts.map +1 -0
  58. package/dist/identifier-grammar.js +273 -0
  59. package/dist/identifier-grammar.js.map +1 -0
  60. package/dist/index.d.ts +19 -0
  61. package/dist/index.d.ts.map +1 -0
  62. package/dist/index.js +11 -0
  63. package/dist/index.js.map +1 -0
  64. package/dist/inline-reference-rule.d.ts +557 -0
  65. package/dist/inline-reference-rule.d.ts.map +1 -0
  66. package/dist/inline-reference-rule.js +802 -0
  67. package/dist/inline-reference-rule.js.map +1 -0
  68. package/dist/meta-documents.d.ts +91 -0
  69. package/dist/meta-documents.d.ts.map +1 -0
  70. package/dist/meta-documents.js +133 -0
  71. package/dist/meta-documents.js.map +1 -0
  72. package/dist/per-document-visitor.d.ts +510 -0
  73. package/dist/per-document-visitor.d.ts.map +1 -0
  74. package/dist/per-document-visitor.js +1032 -0
  75. package/dist/per-document-visitor.js.map +1 -0
  76. package/dist/references-section-rule.d.ts +482 -0
  77. package/dist/references-section-rule.d.ts.map +1 -0
  78. package/dist/references-section-rule.js +777 -0
  79. package/dist/references-section-rule.js.map +1 -0
  80. package/dist/section-hierarchy-rule.d.ts +299 -0
  81. package/dist/section-hierarchy-rule.d.ts.map +1 -0
  82. package/dist/section-hierarchy-rule.js +482 -0
  83. package/dist/section-hierarchy-rule.js.map +1 -0
  84. package/dist/source-alignment.d.ts +41 -0
  85. package/dist/source-alignment.d.ts.map +1 -0
  86. package/dist/source-alignment.js +166 -0
  87. package/dist/source-alignment.js.map +1 -0
  88. package/dist/source-lines.d.ts +69 -0
  89. package/dist/source-lines.d.ts.map +1 -0
  90. package/dist/source-lines.js +104 -0
  91. package/dist/source-lines.js.map +1 -0
  92. package/dist/spec-version.d.ts +19 -0
  93. package/dist/spec-version.d.ts.map +1 -0
  94. package/dist/spec-version.js +19 -0
  95. package/dist/spec-version.js.map +1 -0
  96. package/dist/types.d.ts +219 -0
  97. package/dist/types.d.ts.map +1 -0
  98. package/dist/types.js +11 -0
  99. package/dist/types.js.map +1 -0
  100. package/examples/docs/0. Orientation/0.0 - System Overview.md +34 -0
  101. package/examples/docs/0. Orientation/0.0.1 - Glossary.md +21 -0
  102. package/examples/docs/0. Orientation/0.0.2 - Quality Gates.md +22 -0
  103. package/examples/docs/3. Ingestion/3.1 - Ingestion - Validation Rules.md +33 -0
  104. package/examples/docs/4. Payments/4.10 - Settlement.md +22 -0
  105. package/examples/docs/4. Payments/4.2 - Payment Processing Contract.md +33 -0
  106. package/examples/docs/8. Orchestration/8.1 - Workflow Orchestration Contract.md +38 -0
  107. package/examples/docs/8. Orchestration/8.1.3 - Retry Policy.md +17 -0
  108. package/examples/docs/8. Orchestration/8.10 - Dead Letter Queue.md +20 -0
  109. package/examples/docs/README.md +7 -0
  110. package/package.json +65 -7
  111. package/protocol/navigation-protocol.md +223 -0
  112. package/spec/v2/1 - ECR - Structural Specification.md +1467 -0
  113. package/spec/v2/2 - ECR - User Guide.md +845 -0
  114. package/spec/v2/3 - Design Rationale - The Section Separator.md +243 -0
  115. package/src/bin.ts +30 -0
  116. package/src/cli/corpus-loader.ts +482 -0
  117. package/src/cli/corpus-statistics.ts +196 -0
  118. package/src/cli/diagnostic-reporter.ts +344 -0
  119. package/src/cli/project-ignore.ts +238 -0
  120. package/src/cli/safe-text.ts +39 -0
  121. package/src/cli/supervisor.ts +204 -0
  122. package/src/cli.ts +836 -0
  123. package/src/corpus-validator.ts +642 -0
  124. package/src/document-identity-rule.ts +422 -0
  125. package/src/ecr.ts +298 -0
  126. package/src/glob-pattern.ts +242 -0
  127. package/src/heading-source-form.ts +173 -0
  128. package/src/identifier-grammar.ts +380 -0
  129. package/src/index.ts +78 -0
  130. package/src/inline-reference-rule.ts +1235 -0
  131. package/src/meta-documents.ts +159 -0
  132. package/src/per-document-visitor.ts +1528 -0
  133. package/src/references-section-rule.ts +1182 -0
  134. package/src/section-hierarchy-rule.ts +705 -0
  135. package/src/source-alignment.ts +209 -0
  136. package/src/source-lines.ts +123 -0
  137. package/src/spec-version.ts +19 -0
  138. package/src/types.ts +267 -0
@@ -0,0 +1,113 @@
1
+ /**
2
+ * Corpus Statistics
3
+ *
4
+ * Counts the structure ECR makes explicit, so that a reader can measure their
5
+ * own corpus rather than take anyone's figures on trust. Every number here is
6
+ * derived from validated artefacts, not from a regular expression over the
7
+ * source, so the same corpus always yields the same counts.
8
+ */
9
+ import type { CorpusResult } from '../types.js';
10
+ /**
11
+ * Counts of References-section entries by their declared direction.
12
+ */
13
+ export interface DirectionCounts {
14
+ /** Entries declaring the cited document as an authority. */
15
+ readonly authority: number;
16
+ /** Entries declaring the cited document as a constraint. */
17
+ readonly constraint: number;
18
+ /** Entries declaring the cited document as a contract. */
19
+ readonly contract: number;
20
+ /** Entries declaring the cited document as a dependency. */
21
+ readonly dependency: number;
22
+ }
23
+ /**
24
+ * A measured summary of an ECR corpus.
25
+ */
26
+ export interface CorpusStatisticsReport {
27
+ /** Documents validated, excluding meta-documents. */
28
+ readonly documents: number;
29
+ /** Documents that carry at least one References entry. */
30
+ readonly documentsWithReferences: number;
31
+ /** Sections extracted across the corpus, excluding the root H1 of each document. */
32
+ readonly sections: number;
33
+ /** Unique DocIDs found in the corpus. */
34
+ readonly docIds: number;
35
+ /** Unique SectionIDs found in the corpus. */
36
+ readonly sectionIds: number;
37
+ /** References-section entries, the document-level edges. */
38
+ readonly referenceEntries: number;
39
+ /** References-section entries broken down by direction. */
40
+ readonly referencesByDirection: DirectionCounts;
41
+ /** Inline `see`/`per` references. */
42
+ readonly inlineReferences: number;
43
+ /** Inline references naming a precise section rather than a whole document. */
44
+ readonly sectionPreciseInlineReferences: number;
45
+ /** Every edge in the corpus: References entries plus inline references. */
46
+ readonly totalEdges: number;
47
+ /**
48
+ * Whether every input document was parsed successfully. This does not imply
49
+ * ECR conformance or complete extraction.
50
+ *
51
+ * A document that was parsed but has no recoverable DocID contributes
52
+ * nothing to any count, and one with structural errors contributes whatever
53
+ * did pass validation; both leave this `true`, because both were parsed.
54
+ * Only a document the parser could not read at all makes it `false`, and
55
+ * {@link unparsable} names those documents.
56
+ */
57
+ readonly complete: boolean;
58
+ /**
59
+ * Documents the parser could not read at all, which contribute nothing.
60
+ * A document with ordinary validation errors is not listed here: it still
61
+ * contributes whatever passed validation.
62
+ */
63
+ readonly unparsable: readonly string[];
64
+ }
65
+ /**
66
+ * Derives a statistical summary from a corpus validation result.
67
+ *
68
+ * Only documents that produced extracted artefacts contribute, which means
69
+ * every document with a valid H1 DocID. A document with other structural
70
+ * errors still counts, and contributes whatever was extracted from it: a
71
+ * heading or References entry that could not be read at all adds nothing,
72
+ * while one reported for something other than its structure -- a heading
73
+ * whose source form breaks the navigation guarantee, say -- is extracted and
74
+ * counted like any other. A document with no recoverable DocID contributes
75
+ * nothing at all.
76
+ */
77
+ export declare class CorpusStatistics {
78
+ /** The validation result to summarise. */
79
+ private readonly corpusResult;
80
+ /**
81
+ * Creates a summariser for one validation result.
82
+ *
83
+ * @param corpusResult - The result produced by validating the corpus
84
+ */
85
+ constructor(corpusResult: CorpusResult);
86
+ /**
87
+ * Computes the summary.
88
+ *
89
+ * @returns Counts describing the corpus's explicit structure
90
+ */
91
+ summarise(): CorpusStatisticsReport;
92
+ /**
93
+ * Gathers the extracted artefacts of every document that produced them.
94
+ *
95
+ * @returns Extracted documents, in corpus order
96
+ */
97
+ private collectExtractedDocuments;
98
+ /**
99
+ * Names the documents the parser could not read, so that a reader knows
100
+ * what these counts leave out rather than taking them for the whole corpus.
101
+ *
102
+ * @returns Their URIs, in corpus order
103
+ */
104
+ private collectUnparsableDocuments;
105
+ /**
106
+ * Counts the entries of a corpus index map.
107
+ *
108
+ * @param index - A DocID or SectionID index, absent when indexing did not succeed
109
+ * @returns The number of entries, or 0 when the index is absent
110
+ */
111
+ private countIndexEntries;
112
+ }
113
+ //# sourceMappingURL=corpus-statistics.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corpus-statistics.d.ts","sourceRoot":"","sources":["../../src/cli/corpus-statistics.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAyC,MAAM,aAAa,CAAC;AAEvF;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,4DAA4D;IAC5D,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,0DAA0D;IAC1D,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED;;GAEG;AACH,MAAM,WAAW,sBAAsB;IACrC,qDAAqD;IACrD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,0DAA0D;IAC1D,QAAQ,CAAC,uBAAuB,EAAE,MAAM,CAAC;IACzC,oFAAoF;IACpF,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,4DAA4D;IAC5D,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,2DAA2D;IAC3D,QAAQ,CAAC,qBAAqB,EAAE,eAAe,CAAC;IAChD,qCAAqC;IACrC,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,+EAA+E;IAC/E,QAAQ,CAAC,8BAA8B,EAAE,MAAM,CAAC;IAChD,2EAA2E;IAC3E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B;;;;;;;;;OASG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;IAC3B;;;;OAIG;IACH,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAED;;;;;;;;;;;GAWG;AACH,qBAAa,gBAAgB;IAC3B,0CAA0C;IAC1C,OAAO,CAAC,QAAQ,CAAC,YAAY,CAAe;IAE5C;;;;OAIG;gBACgB,YAAY,EAAE,YAAY;IAI7C;;;;OAIG;IACI,SAAS,IAAI,sBAAsB;IAsD1C;;;;OAIG;IACH,OAAO,CAAC,yBAAyB;IAYjC;;;;;OAKG;IACH,OAAO,CAAC,0BAA0B;IAUlC;;;;;OAKG;IACH,OAAO,CAAC,iBAAiB;CAG1B"}
@@ -0,0 +1,119 @@
1
+ /**
2
+ * Corpus Statistics
3
+ *
4
+ * Counts the structure ECR makes explicit, so that a reader can measure their
5
+ * own corpus rather than take anyone's figures on trust. Every number here is
6
+ * derived from validated artefacts, not from a regular expression over the
7
+ * source, so the same corpus always yields the same counts.
8
+ */
9
+ import { UNPARSABLE_DOCUMENT_RULE_ID } from '../per-document-visitor.js';
10
+ /**
11
+ * Derives a statistical summary from a corpus validation result.
12
+ *
13
+ * Only documents that produced extracted artefacts contribute, which means
14
+ * every document with a valid H1 DocID. A document with other structural
15
+ * errors still counts, and contributes whatever was extracted from it: a
16
+ * heading or References entry that could not be read at all adds nothing,
17
+ * while one reported for something other than its structure -- a heading
18
+ * whose source form breaks the navigation guarantee, say -- is extracted and
19
+ * counted like any other. A document with no recoverable DocID contributes
20
+ * nothing at all.
21
+ */
22
+ export class CorpusStatistics {
23
+ /** The validation result to summarise. */
24
+ corpusResult;
25
+ /**
26
+ * Creates a summariser for one validation result.
27
+ *
28
+ * @param corpusResult - The result produced by validating the corpus
29
+ */
30
+ constructor(corpusResult) {
31
+ this.corpusResult = corpusResult;
32
+ }
33
+ /**
34
+ * Computes the summary.
35
+ *
36
+ * @returns Counts describing the corpus's explicit structure
37
+ */
38
+ summarise() {
39
+ const extractedDocuments = this.collectExtractedDocuments();
40
+ const unparsable = this.collectUnparsableDocuments();
41
+ let documentsWithReferences = 0;
42
+ let sections = 0;
43
+ let referenceEntries = 0;
44
+ let inlineReferences = 0;
45
+ let sectionPreciseInlineReferences = 0;
46
+ const referencesByDirection = {
47
+ authority: 0,
48
+ constraint: 0,
49
+ contract: 0,
50
+ dependency: 0,
51
+ };
52
+ for (const document of extractedDocuments) {
53
+ if (document.references.length > 0) {
54
+ documentsWithReferences += 1;
55
+ }
56
+ // The root H1 is a node but not a section, so it is not counted here.
57
+ sections += Math.max(document.sections.length - 1, 0);
58
+ referenceEntries += document.references.length;
59
+ inlineReferences += document.inlineReferences.length;
60
+ for (const reference of document.references) {
61
+ referencesByDirection[reference.direction] += 1;
62
+ }
63
+ for (const inlineReference of document.inlineReferences) {
64
+ if (inlineReference.toId.includes('#')) {
65
+ sectionPreciseInlineReferences += 1;
66
+ }
67
+ }
68
+ }
69
+ return {
70
+ documents: extractedDocuments.length,
71
+ documentsWithReferences,
72
+ sections,
73
+ docIds: this.countIndexEntries(this.corpusResult.index?.docIds),
74
+ sectionIds: this.countIndexEntries(this.corpusResult.index?.sectionIds),
75
+ referenceEntries,
76
+ referencesByDirection: { ...referencesByDirection },
77
+ inlineReferences,
78
+ sectionPreciseInlineReferences,
79
+ totalEdges: referenceEntries + inlineReferences,
80
+ complete: unparsable.length === 0,
81
+ unparsable,
82
+ };
83
+ }
84
+ /**
85
+ * Gathers the extracted artefacts of every document that produced them.
86
+ *
87
+ * @returns Extracted documents, in corpus order
88
+ */
89
+ collectExtractedDocuments() {
90
+ const extracted = [];
91
+ for (const entry of this.corpusResult.documents) {
92
+ if (entry.result.extracted !== undefined) {
93
+ extracted.push(entry.result.extracted);
94
+ }
95
+ }
96
+ return extracted;
97
+ }
98
+ /**
99
+ * Names the documents the parser could not read, so that a reader knows
100
+ * what these counts leave out rather than taking them for the whole corpus.
101
+ *
102
+ * @returns Their URIs, in corpus order
103
+ */
104
+ collectUnparsableDocuments() {
105
+ return this.corpusResult.documents
106
+ .filter((entry) => entry.result.diagnostics.some((diagnostic) => diagnostic.ruleId === UNPARSABLE_DOCUMENT_RULE_ID))
107
+ .map((entry) => entry.uri);
108
+ }
109
+ /**
110
+ * Counts the entries of a corpus index map.
111
+ *
112
+ * @param index - A DocID or SectionID index, absent when indexing did not succeed
113
+ * @returns The number of entries, or 0 when the index is absent
114
+ */
115
+ countIndexEntries(index) {
116
+ return index === undefined ? 0 : Object.keys(index).length;
117
+ }
118
+ }
119
+ //# sourceMappingURL=corpus-statistics.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"corpus-statistics.js","sourceRoot":"","sources":["../../src/cli/corpus-statistics.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Diagnostic Reporting
3
+ *
4
+ * Renders validation results for a terminal or for a machine. The pretty form
5
+ * groups diagnostics by document and prints a `path:line:column` prefix so an
6
+ * editor can jump to them; the JSON form is the same data unformatted, for CI
7
+ * and for tooling built on top of the CLI.
8
+ */
9
+ import type { CorpusResult } from '../types.js';
10
+ import type { CorpusStatisticsReport } from './corpus-statistics.js';
11
+ /**
12
+ * Output formats the CLI can produce.
13
+ */
14
+ export type ReportFormat = 'pretty' | 'json';
15
+ /**
16
+ * Counts of diagnostics by severity.
17
+ */
18
+ export interface SeverityTotals {
19
+ /** Diagnostics that make the corpus non-conforming. */
20
+ readonly errors: number;
21
+ /** Diagnostics that warrant attention but do not fail validation. */
22
+ readonly warnings: number;
23
+ /** Informational diagnostics. */
24
+ readonly infos: number;
25
+ }
26
+ /**
27
+ * Formats corpus validation results and statistics for output.
28
+ */
29
+ export declare class DiagnosticReporter {
30
+ /** The format to render in. */
31
+ private readonly format;
32
+ /**
33
+ * Creates a reporter.
34
+ *
35
+ * @param format - The output format to produce
36
+ */
37
+ constructor(format: ReportFormat);
38
+ /**
39
+ * Renders a corpus validation result.
40
+ *
41
+ * @param corpusResult - The result to render
42
+ * @param excludedPaths - Paths skipped as meta-documents or by ignore pattern
43
+ * @param notFollowedPaths - Links beneath the corpus root that were not followed
44
+ * @returns The text to write to standard output
45
+ */
46
+ reportValidation(corpusResult: CorpusResult, excludedPaths: readonly string[], notFollowedPaths: readonly string[]): string;
47
+ /**
48
+ * Renders a statistics report.
49
+ *
50
+ * @param statistics - The measured summary to render
51
+ * @param notFollowedPaths - Links beneath the corpus root that were not followed, and so not measured
52
+ * @returns The text to write to standard output
53
+ */
54
+ reportStatistics(statistics: CorpusStatisticsReport, notFollowedPaths: readonly string[]): string;
55
+ /**
56
+ * Counts the documents the parser could not read.
57
+ *
58
+ * @param corpusResult - The result being reported
59
+ * @returns How many documents produced an unparsable-document diagnostic
60
+ */
61
+ private static countUnparsable;
62
+ /**
63
+ * Lists the links a walk did not follow, by name: unlike an exclusion,
64
+ * nobody asked for them to be skipped.
65
+ *
66
+ * @param notFollowedPaths - Links beneath the corpus root that were not followed
67
+ * @returns Lines to print; none when there are no such links
68
+ */
69
+ static listNotFollowed(notFollowedPaths: readonly string[]): readonly string[];
70
+ /**
71
+ * Renders the human-readable form of a validation result.
72
+ *
73
+ * @param corpusResult - The result being rendered
74
+ * @param located - Diagnostics paired with their document paths
75
+ * @param totals - Severity counts across the corpus
76
+ * @param excludedPaths - Paths skipped during discovery
77
+ * @param notFollowedPaths - Links beneath the corpus root that were not followed
78
+ * @returns The text to write to standard output
79
+ */
80
+ private renderPretty;
81
+ /**
82
+ * Flattens per-document and corpus-wide diagnostics into one ordered list,
83
+ * grouped by document.
84
+ *
85
+ * A corpus-wide diagnostic still names the document it concerns — a
86
+ * duplicate DocID, an unresolved reference or a stale References title each
87
+ * belong to a specific file — so it is listed under that document, after the
88
+ * document's own diagnostics. Only a corpus-wide diagnostic whose URI matches
89
+ * no validated document falls back to the `(corpus)` label.
90
+ *
91
+ * @param corpusResult - The result to read
92
+ * @returns Diagnostics paired with the path they belong to, in document order
93
+ */
94
+ private collectDiagnostics;
95
+ /**
96
+ * Counts diagnostics by severity.
97
+ *
98
+ * @param located - The diagnostics to count
99
+ * @returns Totals per severity
100
+ */
101
+ private countSeverities;
102
+ }
103
+ //# sourceMappingURL=diagnostic-reporter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostic-reporter.d.ts","sourceRoot":"","sources":["../../src/cli/diagnostic-reporter.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAIH,OAAO,KAAK,EAAE,YAAY,EAAkC,MAAM,aAAa,CAAC;AAChF,OAAO,KAAK,EAAE,sBAAsB,EAAmB,MAAM,wBAAwB,CAAC;AAEtF;;GAEG;AACH,MAAM,MAAM,YAAY,GAAG,QAAQ,GAAG,MAAM,CAAC;AAY7C;;GAEG;AACH,MAAM,WAAW,cAAc;IAC7B,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,qEAAqE;IACrE,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,iCAAiC;IACjC,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;CACxB;AAKD;;GAEG;AACH,qBAAa,kBAAkB;IAC7B,+BAA+B;IAC/B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;IAEtC;;;;OAIG;gBACgB,MAAM,EAAE,YAAY;IAIvC;;;;;;;OAOG;IACI,gBAAgB,CACrB,YAAY,EAAE,YAAY,EAC1B,aAAa,EAAE,SAAS,MAAM,EAAE,EAChC,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAClC,MAAM;IAiCT;;;;;;OAMG;IACI,gBAAgB,CACrB,UAAU,EAAE,sBAAsB,EAClC,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAClC,MAAM;IAkDT;;;;;OAKG;IACH,OAAO,CAAC,MAAM,CAAC,eAAe;IAQ9B;;;;;;OAMG;WACW,eAAe,CAAC,gBAAgB,EAAE,SAAS,MAAM,EAAE,GAAG,SAAS,MAAM,EAAE;IAWrF;;;;;;;;;OASG;IACH,OAAO,CAAC,YAAY;IAuEpB;;;;;;;;;;;;OAYG;IACH,OAAO,CAAC,kBAAkB;IA2B1B;;;;;OAKG;IACH,OAAO,CAAC,eAAe;CAmBxB"}
@@ -0,0 +1,254 @@
1
+ /**
2
+ * Diagnostic Reporting
3
+ *
4
+ * Renders validation results for a terminal or for a machine. The pretty form
5
+ * groups diagnostics by document and prints a `path:line:column` prefix so an
6
+ * editor can jump to them; the JSON form is the same data unformatted, for CI
7
+ * and for tooling built on top of the CLI.
8
+ */
9
+ import { showControlCharacters } from './safe-text.js';
10
+ import { UNPARSABLE_DOCUMENT_RULE_ID } from '../per-document-visitor.js';
11
+ /** Label used for a diagnostic whose URI matches no validated document. */
12
+ const CORPUS_SCOPE_LABEL = '(corpus)';
13
+ /**
14
+ * Formats corpus validation results and statistics for output.
15
+ */
16
+ export class DiagnosticReporter {
17
+ /** The format to render in. */
18
+ format;
19
+ /**
20
+ * Creates a reporter.
21
+ *
22
+ * @param format - The output format to produce
23
+ */
24
+ constructor(format) {
25
+ this.format = format;
26
+ }
27
+ /**
28
+ * Renders a corpus validation result.
29
+ *
30
+ * @param corpusResult - The result to render
31
+ * @param excludedPaths - Paths skipped as meta-documents or by ignore pattern
32
+ * @param notFollowedPaths - Links beneath the corpus root that were not followed
33
+ * @returns The text to write to standard output
34
+ */
35
+ reportValidation(corpusResult, excludedPaths, notFollowedPaths) {
36
+ const located = this.collectDiagnostics(corpusResult);
37
+ const totals = this.countSeverities(located);
38
+ if (this.format === 'json') {
39
+ return JSON.stringify({
40
+ documents: corpusResult.documents.length,
41
+ excluded: excludedPaths,
42
+ notFollowed: notFollowedPaths,
43
+ totals,
44
+ diagnostics: located.map((entry) => ({
45
+ path: entry.path,
46
+ ruleId: entry.diagnostic.ruleId,
47
+ severity: entry.diagnostic.severity,
48
+ message: entry.diagnostic.message,
49
+ ...(entry.diagnostic.range !== undefined
50
+ ? {
51
+ // Positions are zero-based internally; editors are one-based.
52
+ line: entry.diagnostic.range.start.line + 1,
53
+ column: entry.diagnostic.range.start.character + 1,
54
+ }
55
+ : {}),
56
+ })),
57
+ }, null, 2);
58
+ }
59
+ return this.renderPretty(corpusResult, located, totals, excludedPaths, notFollowedPaths);
60
+ }
61
+ /**
62
+ * Renders a statistics report.
63
+ *
64
+ * @param statistics - The measured summary to render
65
+ * @param notFollowedPaths - Links beneath the corpus root that were not followed, and so not measured
66
+ * @returns The text to write to standard output
67
+ */
68
+ reportStatistics(statistics, notFollowedPaths) {
69
+ if (this.format === 'json') {
70
+ return JSON.stringify({ ...statistics, notFollowed: notFollowedPaths }, null, 2);
71
+ }
72
+ const direction = statistics.referencesByDirection;
73
+ const links = DiagnosticReporter.listNotFollowed(notFollowedPaths);
74
+ // A document the parser could not read contributes nothing to any of
75
+ // these numbers, so saying which ones, and that the numbers are therefore
76
+ // partial, is the difference between a measurement and a misreading.
77
+ const unparsable = statistics.unparsable.length === 0
78
+ ? []
79
+ : [
80
+ ` ${String(statistics.unparsable.length)} document(s) could not be parsed, ` +
81
+ 'so they are not counted above:',
82
+ ...statistics.unparsable.map((path) => ` ${path}`),
83
+ ' These statistics describe the rest of the corpus.',
84
+ '',
85
+ ];
86
+ const lines = [
87
+ '',
88
+ ' Corpus structure',
89
+ ' ────────────────',
90
+ ` documents ${String(statistics.documents)}`,
91
+ ` with a References section ${String(statistics.documentsWithReferences)}`,
92
+ ` sections ${String(statistics.sections)}`,
93
+ '',
94
+ ` unique DocIDs ${String(statistics.docIds)}`,
95
+ ` unique SectionIDs ${String(statistics.sectionIds)}`,
96
+ '',
97
+ ` References entries ${String(statistics.referenceEntries)}`,
98
+ ` authority ${String(direction.authority)}`,
99
+ ` constraint ${String(direction.constraint)}`,
100
+ ` contract ${String(direction.contract)}`,
101
+ ` dependency ${String(direction.dependency)}`,
102
+ '',
103
+ ` inline see/per references ${String(statistics.inlineReferences)}`,
104
+ ` section-precise ${String(statistics.sectionPreciseInlineReferences)}`,
105
+ '',
106
+ ` total edges ${String(statistics.totalEdges)}`,
107
+ '',
108
+ ...unparsable,
109
+ ...links,
110
+ ...(links.length > 0 ? [''] : []),
111
+ ];
112
+ return showControlCharacters(lines.join('\n'));
113
+ }
114
+ /**
115
+ * Counts the documents the parser could not read.
116
+ *
117
+ * @param corpusResult - The result being reported
118
+ * @returns How many documents produced an unparsable-document diagnostic
119
+ */
120
+ static countUnparsable(corpusResult) {
121
+ return corpusResult.documents.filter((entry) => entry.result.diagnostics.some((diagnostic) => diagnostic.ruleId === UNPARSABLE_DOCUMENT_RULE_ID)).length;
122
+ }
123
+ /**
124
+ * Lists the links a walk did not follow, by name: unlike an exclusion,
125
+ * nobody asked for them to be skipped.
126
+ *
127
+ * @param notFollowedPaths - Links beneath the corpus root that were not followed
128
+ * @returns Lines to print; none when there are no such links
129
+ */
130
+ static listNotFollowed(notFollowedPaths) {
131
+ if (notFollowedPaths.length === 0) {
132
+ return [];
133
+ }
134
+ return [
135
+ ` ${String(notFollowedPaths.length)} link(s) not followed:`,
136
+ ...notFollowedPaths.map((path) => ` ${path}`),
137
+ ];
138
+ }
139
+ /**
140
+ * Renders the human-readable form of a validation result.
141
+ *
142
+ * @param corpusResult - The result being rendered
143
+ * @param located - Diagnostics paired with their document paths
144
+ * @param totals - Severity counts across the corpus
145
+ * @param excludedPaths - Paths skipped during discovery
146
+ * @param notFollowedPaths - Links beneath the corpus root that were not followed
147
+ * @returns The text to write to standard output
148
+ */
149
+ renderPretty(corpusResult, located, totals, excludedPaths, notFollowedPaths) {
150
+ const lines = [''];
151
+ let currentPath = undefined;
152
+ for (const entry of located) {
153
+ if (entry.path !== currentPath) {
154
+ lines.push(` ${entry.path}`);
155
+ currentPath = entry.path;
156
+ }
157
+ const position = entry.diagnostic.range !== undefined
158
+ ? `${String(entry.diagnostic.range.start.line + 1)}:` +
159
+ String(entry.diagnostic.range.start.character + 1)
160
+ : '-';
161
+ lines.push(` ${position.padEnd(8)} ${entry.diagnostic.severity.padEnd(7)} ` +
162
+ `${entry.diagnostic.ruleId.padEnd(10)} ${entry.diagnostic.message}`);
163
+ }
164
+ if (located.length > 0) {
165
+ lines.push('');
166
+ }
167
+ const documentCount = String(corpusResult.documents.length);
168
+ // "checked" covers every document the command attempted, which is not the
169
+ // same as every document having been validated: one the parser could not
170
+ // read was attempted and counted, but nothing in it was validated. Those
171
+ // are then stated outright, and their errors are in the total already.
172
+ const unparsableCount = DiagnosticReporter.countUnparsable(corpusResult);
173
+ const unparsableNote = unparsableCount > 0
174
+ ? ` ${String(unparsableCount)} document(s) could not be parsed.`
175
+ : '';
176
+ if (totals.errors === 0 && totals.warnings > 0) {
177
+ lines.push(` ${documentCount} document(s) checked, no errors, ` +
178
+ `${String(totals.warnings)} warning(s).${unparsableNote}`);
179
+ }
180
+ else if (totals.errors === 0) {
181
+ lines.push(` ${documentCount} document(s) checked, no errors.${unparsableNote}`);
182
+ }
183
+ else {
184
+ lines.push(` ${documentCount} document(s) checked: ` +
185
+ `${String(totals.errors)} error(s), ${String(totals.warnings)} warning(s).${unparsableNote}`);
186
+ }
187
+ if (excludedPaths.length > 0) {
188
+ lines.push(` ${String(excludedPaths.length)} path(s) excluded.`);
189
+ }
190
+ lines.push(...DiagnosticReporter.listNotFollowed(notFollowedPaths));
191
+ lines.push('');
192
+ // Every line here can carry text quoted from a document or a path from
193
+ // the disk, so the whole report is made safe to print in one place.
194
+ return showControlCharacters(lines.join('\n'));
195
+ }
196
+ /**
197
+ * Flattens per-document and corpus-wide diagnostics into one ordered list,
198
+ * grouped by document.
199
+ *
200
+ * A corpus-wide diagnostic still names the document it concerns — a
201
+ * duplicate DocID, an unresolved reference or a stale References title each
202
+ * belong to a specific file — so it is listed under that document, after the
203
+ * document's own diagnostics. Only a corpus-wide diagnostic whose URI matches
204
+ * no validated document falls back to the `(corpus)` label.
205
+ *
206
+ * @param corpusResult - The result to read
207
+ * @returns Diagnostics paired with the path they belong to, in document order
208
+ */
209
+ collectDiagnostics(corpusResult) {
210
+ const located = [];
211
+ const documentUris = new Set(corpusResult.documents.map((entry) => entry.uri));
212
+ for (const entry of corpusResult.documents) {
213
+ for (const diagnostic of entry.result.diagnostics) {
214
+ located.push({ path: entry.uri, diagnostic });
215
+ }
216
+ for (const diagnostic of corpusResult.diagnostics) {
217
+ if (diagnostic.uri === entry.uri) {
218
+ located.push({ path: entry.uri, diagnostic });
219
+ }
220
+ }
221
+ }
222
+ for (const diagnostic of corpusResult.diagnostics) {
223
+ if (!documentUris.has(diagnostic.uri)) {
224
+ located.push({ path: CORPUS_SCOPE_LABEL, diagnostic });
225
+ }
226
+ }
227
+ return located;
228
+ }
229
+ /**
230
+ * Counts diagnostics by severity.
231
+ *
232
+ * @param located - The diagnostics to count
233
+ * @returns Totals per severity
234
+ */
235
+ countSeverities(located) {
236
+ let errors = 0;
237
+ let warnings = 0;
238
+ let infos = 0;
239
+ for (const entry of located) {
240
+ const severity = entry.diagnostic.severity;
241
+ if (severity === 'error') {
242
+ errors += 1;
243
+ }
244
+ else if (severity === 'warning') {
245
+ warnings += 1;
246
+ }
247
+ else {
248
+ infos += 1;
249
+ }
250
+ }
251
+ return { errors, warnings, infos };
252
+ }
253
+ }
254
+ //# sourceMappingURL=diagnostic-reporter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"diagnostic-reporter.js","sourceRoot":"","sources":["../../src/cli/diagnostic-reporter.ts"],"names":[],"mappings":"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"}