@descent-vtt/spec-graph 0.14.0 → 0.15.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 +56 -0
- package/README.md +50 -18
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +57 -15
- package/dist/cli.js.map +1 -1
- package/dist/diff.js.map +1 -1
- package/dist/directives.js.map +1 -1
- package/dist/extract.js.map +1 -1
- package/dist/glob.js.map +1 -1
- package/dist/graph.js.map +1 -1
- package/dist/report.d.ts +5 -1
- package/dist/report.js +15 -6
- package/dist/report.js.map +1 -1
- package/dist/select.js +4 -3
- package/dist/select.js.map +1 -1
- package/package.json +1 -1
package/dist/report.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Output formatting.\n *\n * Two audiences, one set of facts. In a terminal the report leads with the file\n * and line so an editor can jump there, indents the supporting evidence, and\n * ends with a concrete next action - because a finding a reader cannot act on\n * is a finding they will learn to scroll past. In CI it emits JSON with every\n * position intact, so a bot can annotate a diff.\n *\n * Colour is opt-out and auto-detected, and the glyphs degrade to ASCII when the\n * terminal cannot render them.\n */\n\nimport { createHash } from 'node:crypto';\n\nimport { fingerprintOf, type StaleEntry } from './baseline.js';\nimport type { SpecGraph } from './graph.js';\nimport type { ProjectRule } from './project-rules.js';\nimport { formatRef } from './source.js';\nimport { DEFAULT_SEVERITIES, RULE_DESCRIPTIONS, RULE_IDS } from './rules.js';\nimport { displayWidth } from './vendor/spec-core/text/index.js';\nimport type { AnalysisResult } from './runner.js';\nimport type {\n AnyRuleId,\n Diagnostic,\n Edge,\n RuleId,\n Severity,\n SourceRef,\n SpecNode,\n SuppressedRef,\n} from './types.js';\n\nexport interface ReporterOptions {\n readonly color?: boolean | undefined;\n readonly ascii?: boolean | undefined;\n readonly verbose?: boolean | undefined;\n /** Stop after this many findings. `0` means no limit. */\n readonly max?: number | undefined;\n /**\n * Rules whose severity `--strict` raised.\n *\n * A finding that only became an error because of a flag has to say so, or the\n * reader cannot tell what would happen without it.\n */\n readonly escalated?: ReadonlySet<AnyRuleId> | undefined;\n /**\n * What a baseline accounted for on this run.\n *\n * Reported as counts rather than as a list: the point of accepted debt is\n * that nobody has to read it every time. `stale` is the ratchet - debt the\n * run did not spend and which can be struck from the file - and `ratchet`\n * says whether this run was asked to fail over it.\n *\n * `entries` carries the stale ones themselves, for the structured formats. A\n * number is enough to know the file has slack and never enough to strike it,\n * and a bot that wants to open the pull request needs the rows.\n */\n readonly baseline?:\n | {\n readonly source: string;\n readonly suppressed: number;\n readonly stale: number;\n readonly ratchet?: boolean | undefined;\n readonly entries?: readonly StaleEntry[] | undefined;\n }\n | undefined;\n /**\n * The baseline's path as it is typed where the run was started, for the\n * command that re-records it; `baseline.source` when unset. The source reads\n * from the root, and typed in a directory below it, it names another file.\n * Beside the baseline rather than in it, because the JSON report writes the\n * baseline whole.\n */\n readonly recordAs?: string | undefined;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Environment detection */\n/* -------------------------------------------------------------------------- */\n\nexport interface ColorEnvironment {\n readonly isTTY?: boolean | undefined;\n readonly env?: Readonly<Record<string, string | undefined>> | undefined;\n /**\n * Host platform, defaulting to the real one.\n *\n * Injected for the same reason `env` is: without it half of\n * {@link shouldUseAscii} is unreachable from a test, and a rule about\n * Windows consoles that only Windows can exercise is a rule that breaks on\n * Windows and nowhere else.\n */\n readonly platform?: NodeJS.Platform | undefined;\n}\n\n/**\n * Honours `NO_COLOR`, `FORCE_COLOR` and `TERM=dumb` before falling back to TTY.\n *\n * `CI` is not read. It says who started the run and nothing of what the\n * stream draws: a pipeline's log that is a terminal draws colour, spec-brief\n * and spec-guard colour there, and one that does not sets `NO_COLOR`.\n */\nexport function shouldUseColor(environment: ColorEnvironment = {}): boolean {\n const env = environment.env ?? process.env;\n if (env['NO_COLOR'] !== undefined && env['NO_COLOR'] !== '') return false;\n // `FORCE_COLOR=0` is the conventional way to turn colour off, so it has to\n // win over an attached TTY rather than merely failing to force it on.\n if (env['FORCE_COLOR'] === '0') return false;\n if (env['FORCE_COLOR'] !== undefined && env['FORCE_COLOR'] !== '') return true;\n if (env['TERM'] === 'dumb') return false;\n return environment.isTTY === true;\n}\n\n/**\n * True when ASCII was asked for, or the terminal is unlikely to render\n * box-drawing and arrows.\n *\n * `SPEC_GRAPH_ASCII` asks, and `0`, `false` and a blank do not: each is how a\n * script writes \"off\", and every one of them used to turn ASCII on.\n */\nexport function shouldUseAscii(environment: ColorEnvironment = {}): boolean {\n const env = environment.env ?? process.env;\n const asked = (env['SPEC_GRAPH_ASCII'] ?? '').trim().toLowerCase();\n if (asked !== '' && asked !== '0' && asked !== 'false') return true;\n if ((environment.platform ?? process.platform) !== 'win32') return false;\n // Windows Terminal and modern shells set these; the legacy console does not.\n return env['WT_SESSION'] === undefined && env['TERM_PROGRAM'] === undefined;\n}\n\nconst EMPTY_RULES: ReadonlySet<RuleId> = new Set<RuleId>();\n\ntype Paint = (text: string) => string;\n\nexport interface Painter {\n readonly error: Paint;\n readonly warn: Paint;\n readonly info: Paint;\n readonly dim: Paint;\n readonly bold: Paint;\n readonly hint: Paint;\n readonly location: Paint;\n}\n\nexport function createPainter(color: boolean): Painter {\n const wrap = (open: string): Paint => (text) => (color ? `\\u001b[${open}m${text}\\u001b[0m` : text);\n return {\n error: wrap('31'),\n warn: wrap('33'),\n info: wrap('36'),\n dim: wrap('2'),\n bold: wrap('1'),\n hint: wrap('32'),\n location: wrap('4'),\n };\n}\n\ninterface Glyphs {\n readonly error: string;\n readonly warn: string;\n readonly info: string;\n readonly related: string;\n readonly hint: string;\n readonly separator: string;\n}\n\nfunction glyphs(ascii: boolean): Glyphs {\n return ascii\n ? { error: 'x', warn: '!', info: 'i', related: '|', hint: '>', separator: '-' }\n : { error: '\\u2716', warn: '\\u26a0', info: '\\u2139', related: '\\u21b3', hint: '\\u2192', separator: '\\u00b7' };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Human report */\n/* -------------------------------------------------------------------------- */\n\n/** Renders the full terminal report. */\nexport function formatReport(result: AnalysisResult, options: ReporterOptions = {}): string {\n const paint = createPainter(options.color ?? false);\n const marks = glyphs(options.ascii ?? false);\n const lines: string[] = [];\n const { summary } = result;\n\n lines.push(\n `${paint.bold('spec-graph')} ${paint.dim(\n [\n `${summary.documents} ${plural(summary.documents, 'document')}`,\n `${summary.items} ${plural(summary.items, 'item')}`,\n `${summary.edges} ${plural(summary.edges, 'relation')}`,\n `${summary.openObligations} open`,\n ].join(` ${marks.separator} `),\n )}`,\n );\n lines.push('');\n\n // Zero is falsy and never reaches the comparison, so `> 0` and `>= 0` are\n // the same test here.\n const limit = options.max && options.max > 0 ? options.max : result.diagnostics.length;\n const shown = result.diagnostics.slice(0, limit);\n\n const escalated = options.escalated ?? EMPTY_RULES;\n for (const diagnostic of shown) {\n lines.push(...formatDiagnostic(diagnostic, paint, marks, escalated));\n lines.push('');\n }\n\n if (result.diagnostics.length > shown.length) {\n lines.push(paint.dim(` ... and ${result.diagnostics.length - shown.length} more`));\n lines.push('');\n }\n\n if (options.verbose && result.problems.length > 0) {\n for (const problem of result.problems) {\n lines.push(`${paint.warn(marks.warn)} ${paint.location(formatRef(problem.at))} ${problem.message}`);\n }\n lines.push('');\n }\n\n const unread = options.verbose ? 0 : unreadFrontMatter(result);\n if (unread > 0) {\n lines.push(`${paint.warn(marks.warn)} ${unreadNotice(unread)}`, '');\n }\n\n // What the repository told spec-graph to stop looking at. Only under\n // --verbose, and never as a finding: these are not defects, they are the one\n // place a configuration can make the check quieter, and a single over-broad\n // glob looks exactly like a clean repository from the outside. See ADR-0008.\n if (options.verbose && result.corpus.suppressed.length > 0) {\n for (const [target, entry] of groupSuppressed(result.corpus.suppressed)) {\n const where = entry.by === 'family' ? 'ignored family' : 'ignored reference';\n const times = entry.count === 1 ? '' : ` (${entry.count} times)`;\n lines.push(`${paint.dim(marks.info)} ${paint.location(formatRef(entry.at))} ${paint.dim(`${where}: ${target}${times}`)}`);\n }\n lines.push('');\n }\n\n const tally: string[] = [];\n if (summary.errors > 0) tally.push(paint.error(`${summary.errors} ${plural(summary.errors, 'error')}`));\n if (summary.warnings > 0) tally.push(paint.warn(`${summary.warnings} ${plural(summary.warnings, 'warning')}`));\n if (summary.infos > 0) tally.push(paint.info(`${summary.infos} ${plural(summary.infos, 'note')}`));\n tally.push(paint.dim(`${summary.durationMs}ms`));\n const raised = result.diagnostics.filter((diagnostic) => escalated.has(diagnostic.rule)).length;\n if (raised > 0) {\n tally.push(paint.warn(`${raised} raised by --strict`));\n }\n const baseline = options.baseline;\n if (baseline !== undefined && baseline.suppressed > 0) {\n tally.push(paint.dim(`${baseline.suppressed} accepted by ${baseline.source}`));\n }\n lines.push(tally.join(` ${marks.separator} `));\n\n // Under `--ratchet` a paid entry is a failure rather than a note, so it is\n // painted and worded as one.\n const ratcheted = ratchetFailed(baseline);\n if (baseline !== undefined && baseline.stale > 0) {\n // A \"gone\" entry is not the ratchet working, and saying so matters more\n // than the count does: the usual way to produce one is to narrow an include\n // pattern, which loses sight of a defect rather than fixing it.\n //\n // The fallback is only ever filtered for gone entries, so filling it with\n // anything that is not one counts the same zero.\n const gone = (baseline.entries ?? []).filter((entry) => entry.reason === 'gone').length;\n const because =\n gone === 0\n ? `tighten it: spec-graph check --record-baseline ${options.recordAs ?? baseline.source}`\n : `${gone} of them ${gone === 1 ? 'names a document' : 'name documents'} this run did not see - check the include patterns before re-recording`;\n const text = `${baseline.stale} baseline ${plural(baseline.stale, 'entry', 'entries')} no longer ${\n baseline.stale === 1 ? 'occurs' : 'occur'\n } - ${because}`;\n lines.push(ratcheted ? `${paint.error(marks.error)} ${text}` : paint.dim(text));\n }\n\n // `ok` means no errors, so where it is true the sum below is the warnings\n // alone and `-` in place of `+` asks the same question.\n lines.push(\n ratcheted\n ? `${paint.error(marks.error)} ${\n result.ok ? 'the baseline is looser than the repository' : 'the specification graph is inconsistent'\n }`\n : result.ok\n ? `${paint.hint(marks.hint === '>' ? 'ok' : '\\u2714')} ${\n summary.errors + summary.warnings === 0\n ? 'the specification graph is consistent'\n : 'no errors - the specification graph holds'\n }`\n : `${paint.error(marks.error)} the specification graph is inconsistent`,\n );\n\n return lines.join('\\n');\n}\n\nfunction formatDiagnostic(\n diagnostic: Diagnostic,\n paint: Painter,\n marks: Glyphs,\n escalated: ReadonlySet<AnyRuleId>,\n): string[] {\n const mark = severityMark(diagnostic.severity, paint, marks);\n const label = escalated.has(diagnostic.rule)\n ? `${diagnostic.rule} ${paint.warn('(strict: warn -> error)')}`\n : diagnostic.rule;\n const lines: string[] = [\n `${mark} ${paint.location(formatRef(diagnostic.at))} ${paint.dim(label)}`,\n ` ${diagnostic.message}`,\n ];\n\n // Padded to the columns a terminal draws, not to UTF-16 units: `docs/決策.md`\n // is ten units and twelve columns, so `.padEnd` left the notes beside it two\n // columns out of line.\n const width = Math.max(0, ...diagnostic.related.map((entry) => displayWidth(formatRef(entry.at))));\n for (const entry of diagnostic.related) {\n const reference = formatRef(entry.at);\n const padded = `${reference}${' '.repeat(width - displayWidth(reference))}`;\n lines.push(` ${paint.dim(marks.related)} ${paint.dim(padded)} ${paint.dim(entry.note)}`);\n }\n\n lines.push(` ${paint.hint(marks.hint)} ${paint.hint(diagnostic.hint)}`);\n return lines;\n}\n\nfunction severityMark(severity: Exclude<Severity, 'off'>, paint: Painter, marks: Glyphs): string {\n switch (severity) {\n case 'error':\n return paint.error(marks.error);\n case 'warn':\n return paint.warn(marks.warn);\n case 'info':\n return paint.info(marks.info);\n }\n}\n\nfunction plural(count: number, word: string, plural?: string): string {\n if (count === 1) return word;\n return plural ?? `${word}s`;\n}\n\n/**\n * How many front-matter values the graph is built from went unread.\n *\n * Parse problems are listed only under `--verbose`, and most of them can wait\n * there. These cannot: `status: Superseded by ADR-3: see notes` is not read,\n * the document reads as unknown, and a failing check reports that the graph is\n * consistent. So a default run says how many there are, and where to look.\n */\nfunction unreadFrontMatter(result: AnalysisResult): number {\n return result.problems.filter((problem) => problem.unread === true).length;\n}\n\nfunction unreadNotice(count: number): string {\n return `${count} front-matter ${plural(count, 'value')} not read - see --verbose`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Markdown */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The same report as GitHub-flavoured Markdown.\n *\n * SARIF puts a finding on the line that caused it, which is where somebody\n * fixing one wants it. It says nothing to the person deciding whether to merge,\n * because a code-scanning alert is a list of lines and not a verdict. This is\n * the verdict: one table, the counts above it, and the baseline's slack\n * underneath, sized to be read without scrolling.\n *\n * Written for `$GITHUB_STEP_SUMMARY` and for a pull-request comment, but it is\n * named for what it is rather than for where it goes - the same text is what a\n * review tool, a chat message or a generated page wants.\n *\n * It carries no duration, which the JSON report does, so two runs over one\n * corpus produce identical bytes. That is what lets a test compare a run from\n * a subdirectory against a run from the root and assert they are the same\n * report rather than the same shape. See ADR-0015 and ADR-0018.\n */\nexport function formatMarkdown(result: AnalysisResult, options: ReporterOptions = {}): string {\n const { summary } = result;\n const escalated = options.escalated ?? EMPTY_RULES;\n const ratcheted = ratchetFailed(options.baseline);\n const lines: string[] = ['### spec-graph', ''];\n\n // `ok` means no errors, as in the terminal's verdict, so `-` in place of `+`\n // below asks the same question.\n const verdict =\n ratcheted && result.ok\n ? 'The baseline is looser than the repository.'\n : result.ok\n ? summary.errors + summary.warnings === 0\n ? 'The specification graph is consistent.'\n : 'No errors - the specification graph holds.'\n : 'The specification graph is inconsistent.';\n lines.push(verdict, '');\n\n lines.push('| | |', '| --- | ---: |');\n lines.push(`| Documents | ${summary.documents} |`);\n lines.push(`| Items | ${summary.items} |`);\n lines.push(`| Relations | ${summary.edges} |`);\n lines.push(`| Open obligations | ${summary.openObligations} |`);\n lines.push(`| Errors | ${summary.errors} |`);\n lines.push(`| Warnings | ${summary.warnings} |`);\n lines.push(`| Notes | ${summary.infos} |`);\n lines.push('');\n\n // Zero never reaches the comparison, as in the terminal report.\n const limit = options.max && options.max > 0 ? options.max : result.diagnostics.length;\n const shown = result.diagnostics.slice(0, limit);\n\n if (shown.length > 0) {\n lines.push('| | Rule | Where | Finding |', '| --- | --- | --- | --- |');\n for (const diagnostic of shown) {\n const rule = escalated.has(diagnostic.rule) ? `${diagnostic.rule} (strict)` : diagnostic.rule;\n // The hint in the same cell, under the message. A finding without its\n // next action is the half a reader cannot act on, and a fifth column\n // would push the message off the side of the page.\n const what = `${cell(diagnostic.message)}<br>${cell(diagnostic.hint)}`;\n lines.push(`| ${diagnostic.severity} | \\`${cell(rule)}\\` | \\`${cell(formatRef(diagnostic.at))}\\` | ${what} |`);\n }\n if (result.diagnostics.length > shown.length) {\n lines.push(`| | | | ... and ${result.diagnostics.length - shown.length} more |`);\n }\n lines.push('');\n }\n\n const baseline = options.baseline;\n if (baseline !== undefined) {\n const accepted = `${baseline.suppressed} ${plural(baseline.suppressed, 'finding')} accepted by \\`${cell(baseline.source)}\\``;\n if (baseline.stale === 0) {\n lines.push(accepted, '');\n } else {\n // The fallback is only filtered for gone entries, as in the terminal report.\n const gone = (baseline.entries ?? []).filter((entry) => entry.reason === 'gone').length;\n lines.push(\n `${accepted}, and ${baseline.stale} ${plural(baseline.stale, 'entry', 'entries')} no longer ${\n baseline.stale === 1 ? 'occurs' : 'occur'\n }${\n gone === 0\n ? ''\n : ` - ${gone} of them ${gone === 1 ? 'names a document' : 'name documents'} this run did not see`\n }.`,\n '',\n );\n // Listed rather than counted, because the point of a summary on a pull\n // request is that somebody can act on it without opening a terminal.\n lines.push('| Entry | Rule | Document | Why |', '| --- | --- | --- | --- |');\n for (const entry of baseline.entries ?? []) {\n const why = entry.reason === 'gone' ? 'not in this corpus - check the include patterns' : 'fixed';\n lines.push(`| ${entry.reason} | \\`${cell(entry.rule)}\\` | \\`${cell(entry.document)}\\` | ${why} |`);\n }\n lines.push('');\n }\n }\n\n const unread = options.verbose ? 0 : unreadFrontMatter(result);\n if (unread > 0) lines.push(`${unreadNotice(unread)}.`, '');\n\n if (options.verbose && result.problems.length > 0) {\n lines.push('<details><summary>Problems with the input</summary>', '');\n for (const problem of result.problems) {\n lines.push(`- \\`${cell(formatRef(problem.at))}\\` ${cell(problem.message)}`);\n }\n lines.push('', '</details>', '');\n }\n\n if (options.verbose && result.corpus.suppressed.length > 0) {\n lines.push('<details><summary>References this configuration silenced</summary>', '');\n for (const [target, entry] of groupSuppressed(result.corpus.suppressed)) {\n const where = entry.by === 'family' ? 'ignored family' : 'ignored reference';\n const times = entry.count === 1 ? '' : ` (${entry.count} times)`;\n lines.push(`- \\`${cell(target)}\\` - ${where}${times}, first at \\`${cell(formatRef(entry.at))}\\``);\n }\n lines.push('', '</details>', '');\n }\n\n // Every block above ends in exactly one blank line, so there is only ever one\n // trailing newline for this to strip, and `\\n$` would strip the same.\n return `${lines.join('\\n').replace(/\\n+$/, '')}\\n`;\n}\n\n/**\n * Makes one value safe to put in a table cell.\n *\n * A pipe would end the cell and a newline would end the row, and a diagnostic\n * message is written by whoever wrote the rule - including a project rule,\n * whose message is a template a repository controls.\n */\nfunction cell(value: string): string {\n return value.replace(/[|]/g, '|').replace(/\\s+/g, ' ').trim();\n}\n\n/* -------------------------------------------------------------------------- */\n/* JSON */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The machine-readable report.\n *\n * Deliberately flat and versioned: this is the contract a CI annotator or a\n * dashboard builds against, and it must be safe to add fields to it later.\n */\n/**\n * One row per silenced target, with the first place it was written.\n *\n * Grouped because a concept tag used forty times is one decision, and forty\n * lines of it would bury the one entry somebody needs to see. Insertion order\n * is document order, which is already deterministic.\n */\nfunction groupSuppressed(\n suppressed: readonly SuppressedRef[],\n): Map<string, { at: SourceRef; by: SuppressedRef['by']; count: number }> {\n const out = new Map<string, { at: SourceRef; by: SuppressedRef['by']; count: number }>();\n for (const entry of suppressed) {\n const seen = out.get(entry.target);\n if (seen === undefined) out.set(entry.target, { at: entry.at, by: entry.by, count: 1 });\n else seen.count += 1;\n }\n return out;\n}\n\n/**\n * True when a baseline was asked to ratchet and has slack left in it.\n *\n * Both reporters ask, because both have to agree with the exit code: a report\n * that prints \"ok\" above a failing build is worse than no report.\n */\nfunction ratchetFailed(baseline: ReporterOptions['baseline']): boolean {\n return baseline !== undefined && baseline.ratchet === true && baseline.stale > 0;\n}\n\n/* -------------------------------------------------------------------------- */\n/* SARIF */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The static-analysis interchange format, for the tools that already read it.\n *\n * The reason to emit it is not the format, it is what consumes the format:\n * GitHub code scanning turns a SARIF upload into annotations on the diff, and\n * an editor turns it into the problems pane, neither of which needs a line of\n * spec-graph-specific integration.\n *\n * One field earns the whole exercise. `partialFingerprints` is how a consumer\n * tracks a finding across commits without keying on a line number, and\n * spec-graph already has exactly that identifier for exactly that reason - the\n * `rule/document/subject` triple a baseline is keyed on (ADR-0012). The two\n * problems turned out to be the same problem, so the answer is the same answer.\n *\n * Deterministic and timestamp-free, like every other output here. Nothing about\n * a run that has the same findings should produce a different file.\n */\nexport function formatSarif(\n result: AnalysisResult,\n graph: SpecGraph,\n options: {\n version?: string | undefined;\n escalated?: ReadonlySet<AnyRuleId> | undefined;\n projectRules?: readonly ProjectRule[] | undefined;\n } = {},\n): string {\n const escalated = options.escalated ?? EMPTY_RULES;\n // A project rule describes itself by the selector it is, because that is the\n // only honest answer: its message is a template, and a template with `{0}` in\n // it is not a description of anything. See ADR-0016.\n const known: [AnyRuleId, string, Severity][] = [\n ...RULE_IDS.map((id): [AnyRuleId, string, Severity] => [id, RULE_DESCRIPTIONS[id], DEFAULT_SEVERITIES[id]]),\n ...(options.projectRules ?? []).map((rule): [AnyRuleId, string, Severity] => [\n rule.id,\n rule.sources.join(' | '),\n rule.severity,\n ]),\n ];\n const fired = known.filter(([id]) => result.diagnostics.some((diagnostic) => diagnostic.rule === id));\n return `${JSON.stringify(\n {\n $schema: 'https://json.schemastore.org/sarif-2.1.0.json',\n version: '2.1.0',\n runs: [\n {\n tool: {\n driver: {\n name: 'spec-graph',\n informationUri: 'https://github.com/DescentVTT/spec-graph',\n // JSON.stringify drops a key whose value is undefined, so always\n // spreading the pair writes the same file; the test is for the reader.\n ...(options.version === undefined ? {} : { version: options.version, semanticVersion: options.version }),\n // Only the rules that fired. A driver listing all of them\n // describes the tool; this file describes the run.\n rules: fired.map(([id, description, level]) => ({\n id,\n shortDescription: { text: description },\n defaultConfiguration: { level: sarifLevel(level) },\n })),\n },\n },\n results: result.diagnostics.map((diagnostic) => {\n const print = fingerprintOf(graph, diagnostic);\n return {\n ruleId: diagnostic.rule,\n level: sarifLevel(diagnostic.severity),\n message: { text: `${diagnostic.message}. ${diagnostic.hint}` },\n locations: [sarifLocation(diagnostic.at)],\n ...(diagnostic.related.length === 0\n ? {}\n : {\n relatedLocations: diagnostic.related.map((entry) => ({\n ...sarifLocation(entry.at),\n message: { text: entry.note },\n })),\n }),\n partialFingerprints: {\n specGraphIdentity: `${diagnostic.rule}/${print.document}/${print.subject}`,\n },\n properties: {\n nodes: diagnostic.nodes,\n target: diagnostic.target,\n // A finding that is only an error because of a flag says so\n // here too, so a reviewer reading an annotation is not misled.\n escalated: escalated.has(diagnostic.rule),\n },\n };\n }),\n },\n ],\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction sarifLevel(severity: Severity): string {\n switch (severity) {\n case 'error':\n return 'error';\n case 'warn':\n return 'warning';\n case 'info':\n return 'note';\n default:\n return 'none';\n }\n}\n\nfunction sarifLocation(at: SourceRef): {\n physicalLocation: {\n artifactLocation: { uri: string };\n region: { startLine: number; startColumn: number; endLine: number; endColumn: number };\n };\n} {\n return {\n physicalLocation: {\n // Already repository-relative and POSIX, which is what SARIF asks for.\n artifactLocation: { uri: at.file },\n region: {\n startLine: at.span.start.line,\n startColumn: at.span.start.column,\n endLine: at.span.end.line,\n endColumn: at.span.end.column,\n },\n },\n };\n}\n\n/* -------------------------------------------------------------------------- */\n/* GitLab Code Quality */\n/* -------------------------------------------------------------------------- */\n\ntype GitlabSeverity = 'critical' | 'major' | 'minor' | 'info';\n\n/**\n * GitLab's Code Quality report, which a merge request reads to show the\n * findings a change introduced and the ones it resolved - what SARIF is to\n * GitHub, so the family is not GitHub's alone.\n *\n * The format is GitLab's and carries no version of its own: a JSON array with\n * the five fields GitLab reads and nothing else.\n *\n * `fingerprint` is how GitLab matches a finding in the merge request to the\n * same finding on the target branch, so it holds what the finding is about and\n * nothing that moves when something else changes: the rule, the specification\n * and what within it, hashed - the identity a baseline counts by. Not the line,\n * so a paragraph moved above a finding does not make it new. Not the message,\n * which carries counts: ticking one of three boxes turned \"holds 3 open\n * obligations\" into \"holds 2\", and GitLab showed one finding resolved and one\n * introduced. Two findings that agree on all three - one broken link written\n * twice in a document - are told apart by their order, the second hashed with a\n * `2`: GitLab tells issues apart by fingerprint, and two that shared one would\n * be read as one.\n */\nexport function formatGitlab(\n result: AnalysisResult,\n options: { escalated?: ReadonlySet<AnyRuleId> | undefined } = {},\n): string {\n const escalated = options.escalated ?? EMPTY_RULES;\n const occurrences = new Map<string, number>();\n const issues = result.diagnostics.map((diagnostic) => {\n const { document, subject } = fingerprintOf(result.graph, diagnostic);\n const identity = [diagnostic.rule, document, subject];\n const key = JSON.stringify(identity);\n const occurrence = (occurrences.get(key) ?? 0) + 1;\n occurrences.set(key, occurrence);\n return {\n description: `${diagnostic.message}. ${diagnostic.hint}`,\n check_name: diagnostic.rule,\n fingerprint: createHash('sha256')\n .update(occurrence === 1 ? key : JSON.stringify([...identity, occurrence]))\n .digest('hex'),\n severity: gitlabSeverity(diagnostic.severity, escalated.has(diagnostic.rule)),\n location: { path: diagnostic.at.file, lines: { begin: diagnostic.at.span.start.line } },\n };\n });\n return `${JSON.stringify(issues, null, 2)}\\n`;\n}\n\n/**\n * spec-graph's three severities on GitLab's five. An error is critical: it\n * fails the build. One that is only an error because `--strict` raised it is\n * major, which is the one place the report can say so. A warning is minor,\n * and a note is information. `blocker` is left to tools that know more about\n * what cannot ship than a documentation linter does.\n */\nfunction gitlabSeverity(severity: Severity, escalated: boolean): GitlabSeverity {\n switch (severity) {\n case 'error':\n return escalated ? 'major' : 'critical';\n case 'warn':\n return 'minor';\n default:\n return 'info';\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* GitHub workflow commands */\n/* -------------------------------------------------------------------------- */\n\n/** A workflow command's message: `%`, and the line breaks that would end the command. */\nfunction escapeData(text: string): string {\n return text.replace(/%/g, '%25').replace(/\\r/g, '%0D').replace(/\\n/g, '%0A');\n}\n\n/** A workflow command's property: as a message, and the `:` and `,` that would end the property. */\nfunction escapeProperty(text: string): string {\n return escapeData(text).replace(/:/g, '%3A').replace(/,/g, '%2C');\n}\n\n/**\n * Findings as GitHub Actions workflow commands, one line each, which a job's\n * log turns into annotations on the pull request's diff with no upload step -\n * what SARIF does through code scanning, for a repository that has none.\n *\n * An error is `error`, a warning `warning` and a note `notice`, as spec-guard\n * writes them. The rule is the title, marked `(strict)` where only `--strict`\n * made it an error, as the Markdown report marks it; the message carries the\n * hint, since a finding without its next action is the half a reader cannot\n * act on. Nothing at all for a clean run.\n */\nexport function formatGithub(\n result: AnalysisResult,\n options: { escalated?: ReadonlySet<AnyRuleId> | undefined } = {},\n): string {\n const escalated = options.escalated ?? EMPTY_RULES;\n return result.diagnostics\n .map((diagnostic) => {\n const title = escalated.has(diagnostic.rule) ? `${diagnostic.rule} (strict)` : diagnostic.rule;\n const place = `file=${escapeProperty(diagnostic.at.file)},line=${diagnostic.at.span.start.line}`;\n return `::${githubLevel(diagnostic.severity)} ${place},title=${escapeProperty(title)}::${escapeData(\n `${diagnostic.message}. ${diagnostic.hint}`,\n )}\\n`;\n })\n .join('');\n}\n\nfunction githubLevel(severity: Severity): 'error' | 'warning' | 'notice' {\n switch (severity) {\n case 'error':\n return 'error';\n case 'warn':\n return 'warning';\n default:\n return 'notice';\n }\n}\n\nexport function formatJson(\n result: AnalysisResult,\n options: { escalated?: ReadonlySet<AnyRuleId>; baseline?: ReporterOptions['baseline'] } = {},\n): string {\n const escalated = options.escalated ?? EMPTY_RULES;\n return `${JSON.stringify(\n {\n version: 1,\n ok: result.ok && !ratchetFailed(options.baseline),\n strict: escalated.size > 0,\n // Always spreading would write `baseline: undefined`, which JSON.stringify\n // drops, so the test changes nothing but what the line says.\n ...(options.baseline === undefined ? {} : { baseline: options.baseline }),\n summary: result.summary,\n files: result.files,\n // The audit trail for what configuration silenced. Always present, unlike\n // the human report's --verbose gate: a machine reader that has to ask for\n // it twice will not ask. See ADR-0008.\n suppressed: result.corpus.suppressed.map((entry) => ({\n target: entry.target,\n from: entry.from,\n by: entry.by,\n file: entry.at.file,\n line: entry.at.span.start.line,\n })),\n diagnostics: result.diagnostics.map((diagnostic) => ({\n rule: diagnostic.rule,\n severity: diagnostic.severity,\n // True when this finding is only an error because of --strict.\n escalated: escalated.has(diagnostic.rule),\n message: diagnostic.message,\n hint: diagnostic.hint,\n nodes: diagnostic.nodes,\n target: diagnostic.target,\n file: diagnostic.at.file,\n line: diagnostic.at.span.start.line,\n column: diagnostic.at.span.start.column,\n endLine: diagnostic.at.span.end.line,\n endColumn: diagnostic.at.span.end.column,\n related: diagnostic.related.map((entry) => ({\n file: entry.at.file,\n line: entry.at.span.start.line,\n column: entry.at.span.start.column,\n note: entry.note,\n })),\n })),\n problems: result.problems.map((problem) => ({\n message: problem.message,\n file: problem.at.file,\n line: problem.at.span.start.line,\n })),\n },\n null,\n 2,\n )}\\n`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Graph export */\n/* -------------------------------------------------------------------------- */\n\nexport type GraphFormat = 'dot' | 'mermaid' | 'json';\n\nexport interface GraphExportOptions {\n /** Leave out `contains` edges and item nodes. */\n readonly documentsOnly?: boolean | undefined;\n /**\n * What made the export, for the JSON form. Passed in rather than looked up,\n * because reading the package's own version is I/O and this module has none.\n * Two exports from different versions differ wherever extraction changed, and\n * `diff` warns about that only if it can see it (ADR-0020).\n */\n readonly generator?: { readonly name: string; readonly version: string } | undefined;\n}\n\n/** Serialises the graph for Graphviz, Mermaid, or a downstream tool. */\nexport function formatGraph(graph: SpecGraph, format: GraphFormat, options: GraphExportOptions = {}): string {\n const skipItems = options.documentsOnly ?? false;\n const nodes = [...graph.nodes.values()].filter((node) => !skipItems || node.kind === 'document');\n const visible = new Set(nodes.map((node) => node.id));\n\n // Hiding items must not hide what they say. An obligation delegated from an\n // item to a document is lifted onto the item's owner, so the document-level\n // view still shows the handover rather than silently losing it.\n const lifted = skipItems\n ? dedupeEdges(\n graph.edges\n // Containment of an *item* is what hiding items makes redundant.\n // Containment of a specification by the register that holds it is\n // structure between documents, and is what this view exists to show.\n //\n // An item is contained by its own document, so its containment would\n // lift onto that document and fall to the reflexive filter below\n // anyway: dropping this filter changes no export, and it stays to\n // say which containment the view keeps.\n .filter((edge) => edge.kind !== 'contains' || visible.has(edge.to))\n .map((edge) => {\n const from = graph.owningDocument(edge.from)?.id ?? edge.from;\n const to = graph.owningDocument(edge.to)?.id ?? edge.to;\n // An edge that did not move, rebuilt, is the same edge: its own\n // `reflexive` already says whether `from` is `to`.\n return from === edge.from && to === edge.to ? edge : { ...edge, from, to, reflexive: from === to };\n })\n .filter((edge) => !edge.reflexive),\n )\n : graph.edges;\n\n const edges = lifted.filter((edge) => visible.has(edge.from) && visible.has(edge.to));\n\n switch (format) {\n case 'dot':\n return toDot(nodes, edges);\n case 'mermaid':\n return toMermaid(nodes, edges);\n case 'json':\n return `${JSON.stringify(\n {\n version: 1,\n // `generator: undefined` is dropped by JSON.stringify, so the test\n // decides nothing the file shows.\n ...(options.generator !== undefined && { generator: options.generator }),\n nodes: nodes.map(serialiseNode),\n edges: edges.map((edge) => ({\n kind: edge.kind,\n from: edge.from,\n to: edge.to,\n origin: edge.origin,\n declaredIn: edge.declaredIn,\n file: edge.declaredAt.file,\n line: edge.declaredAt.span.start.line,\n })),\n },\n null,\n 2,\n )}\\n`;\n }\n}\n\n/** Collapses duplicate relations produced by lifting item edges onto documents. */\nfunction dedupeEdges(edges: readonly Edge[]): Edge[] {\n const seen = new Set<string>();\n // Anything here that is not an edge between drawn nodes is dropped by the\n // filter formatGraph applies next, so seeding this array changes no export.\n const out: Edge[] = [];\n for (const edge of edges) {\n const key = `${edge.kind} ${edge.from} ${edge.to}`;\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(edge);\n }\n return out;\n}\n\nfunction serialiseNode(node: SpecNode): Record<string, unknown> {\n const base = {\n id: node.id,\n kind: node.kind,\n title: node.title,\n file: node.at.file,\n line: node.at.span.start.line,\n };\n return node.kind === 'document'\n ? { ...base, path: node.path, phase: node.phase, status: node.rawStatus, aliases: node.aliases }\n : {\n ...base,\n declared: node.declared,\n document: node.document,\n section: node.section,\n disposition: node.disposition,\n openness: node.openness,\n };\n}\n\n/** Phase colours, chosen to stay legible in both light and dark renderings. */\nconst PHASE_FILL: Readonly<Record<string, string>> = {\n draft: '#e8f0fe',\n active: '#e6f4ea',\n frozen: '#e8eaed',\n retired: '#fce8e6',\n record: '#f3e8fd',\n unknown: '#ffffff',\n};\n\nfunction toDot(nodes: readonly SpecNode[], edges: readonly Edge[]): string {\n const lines = ['digraph spec {', ' rankdir=LR;', ' node [shape=box, style=\"rounded,filled\", fontname=\"sans\"];'];\n for (const node of nodes) {\n // Every phase has a fill, `unknown` included, so the fallback is for a\n // phase added to the lattice before it is given a colour, and no graph\n // today reaches it.\n const fill = node.kind === 'document' ? (PHASE_FILL[node.phase] ?? '#ffffff') : '#fffbe6';\n const label = node.kind === 'document' ? `${node.id}\\\\n${escapeDot(node.title)}` : escapeDot(node.text);\n const shape = node.kind === 'document' ? 'box' : 'note';\n lines.push(` \"${escapeDot(node.id)}\" [label=\"${label}\", fillcolor=\"${fill}\", shape=${shape}];`);\n }\n for (const edge of edges) {\n const style = edge.kind === 'contains' ? ', style=dotted' : '';\n lines.push(` \"${escapeDot(edge.from)}\" -> \"${escapeDot(edge.to)}\" [label=\"${edge.kind}\"${style}];`);\n }\n lines.push('}');\n return `${lines.join('\\n')}\\n`;\n}\n\nfunction toMermaid(nodes: readonly SpecNode[], edges: readonly Edge[]): string {\n const lines = ['graph LR'];\n const alias = new Map<string, string>();\n nodes.forEach((node, position) => alias.set(node.id, `n${position}`));\n\n for (const node of nodes) {\n const key = alias.get(node.id) as string;\n const label = escapeMermaid(node.kind === 'document' ? node.id : node.text);\n lines.push(node.kind === 'document' ? ` ${key}[\"${label}\"]` : ` ${key}([\"${label}\"])`);\n if (node.kind === 'document' && node.phase !== 'unknown') lines.push(` class ${key} ${node.phase};`);\n }\n // formatGraph hands over only edges between the nodes being drawn, and every\n // one of those has an alias.\n for (const edge of edges) {\n lines.push(` ${alias.get(edge.from) as string} -->|${edge.kind}| ${alias.get(edge.to) as string}`);\n }\n for (const [phase, fill] of Object.entries(PHASE_FILL)) {\n if (phase === 'unknown') continue;\n lines.push(` classDef ${phase} fill:${fill},stroke:#5f6368;`);\n }\n return `${lines.join('\\n')}\\n`;\n}\n\nfunction escapeDot(value: string): string {\n return value.replace(/[\"\\\\]/g, '\\\\$&').replace(/\\n/g, '\\\\n');\n}\n\nfunction escapeMermaid(value: string): string {\n return value.replace(/[\"#]/g, ' ').replace(/\\s+/g, ' ').trim();\n}\n"]}
|
|
1
|
+
{"version":3,"file":"report.js","sourceRoot":"","sources":["../src/report.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Output formatting.\n *\n * Two audiences, one set of facts. In a terminal the report leads with the file\n * and line so an editor can jump there, indents the supporting evidence, and\n * ends with a concrete next action - because a finding a reader cannot act on\n * is a finding they will learn to scroll past. In CI it emits JSON with every\n * position intact, so a bot can annotate a diff.\n *\n * Colour is opt-out and auto-detected, and the glyphs degrade to ASCII when the\n * terminal cannot render them.\n */\n\nimport { createHash } from 'node:crypto';\n\nimport { fingerprintOf, type StaleEntry } from './baseline.js';\nimport type { SpecGraph } from './graph.js';\nimport type { ProjectRule } from './project-rules.js';\nimport { formatRef } from './source.js';\nimport { DEFAULT_SEVERITIES, RULE_DESCRIPTIONS, RULE_IDS } from './rules.js';\nimport { displayWidth } from './vendor/spec-core/text/index.js';\nimport type { AnalysisResult } from './runner.js';\nimport type {\n AnyRuleId,\n Diagnostic,\n Edge,\n RuleId,\n Severity,\n SourceRef,\n SpecNode,\n SuppressedRef,\n} from './types.js';\n\nexport interface ReporterOptions {\n readonly color?: boolean | undefined;\n readonly ascii?: boolean | undefined;\n readonly verbose?: boolean | undefined;\n /** Stop after this many findings. `0` means no limit. */\n readonly max?: number | undefined;\n /**\n * Rules whose severity `--strict` raised.\n *\n * A finding that only became an error because of a flag has to say so, or the\n * reader cannot tell what would happen without it.\n */\n readonly escalated?: ReadonlySet<AnyRuleId> | undefined;\n /**\n * What a baseline accounted for on this run.\n *\n * Reported as counts rather than as a list: the point of accepted debt is\n * that nobody has to read it every time. `stale` is the ratchet - debt the\n * run did not spend and which can be struck from the file - and `ratchet`\n * says whether this run was asked to fail over it.\n *\n * `entries` carries the stale ones themselves, for the structured formats. A\n * number is enough to know the file has slack and never enough to strike it,\n * and a bot that wants to open the pull request needs the rows.\n */\n readonly baseline?:\n | {\n readonly source: string;\n readonly suppressed: number;\n readonly stale: number;\n readonly ratchet?: boolean | undefined;\n readonly entries?: readonly StaleEntry[] | undefined;\n }\n | undefined;\n /**\n * The baseline's path as it is typed where the run was started, for the\n * command that re-records it; `baseline.source` when unset. The source reads\n * from the root, and typed in a directory below it, it names another file.\n * Beside the baseline rather than in it, because the JSON report writes the\n * baseline whole.\n */\n readonly recordAs?: string | undefined;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Environment detection */\n/* -------------------------------------------------------------------------- */\n\nexport interface ColorEnvironment {\n readonly isTTY?: boolean | undefined;\n readonly env?: Readonly<Record<string, string | undefined>> | undefined;\n /**\n * Host platform, defaulting to the real one.\n *\n * Injected for the same reason `env` is: without it half of\n * {@link shouldUseAscii} is unreachable from a test, and a rule about\n * Windows consoles that only Windows can exercise is a rule that breaks on\n * Windows and nowhere else.\n */\n readonly platform?: NodeJS.Platform | undefined;\n}\n\n/**\n * Honours `NO_COLOR`, `FORCE_COLOR` and `TERM=dumb` before falling back to\n * TTY, as the family reads them (spec-core's ADR-0005): `NO_COLOR` set to\n * anything first; then `FORCE_COLOR`, off for exactly `0` or exactly `false`\n * and on for anything else; then `TERM=dumb`. Either of the first two set to\n * nothing is as unset.\n *\n * `CI` is not read. It says who started the run and nothing of what the\n * stream draws: a pipeline's log that is a terminal draws colour, spec-brief\n * and spec-guard colour there, and one that does not sets `NO_COLOR`.\n */\nexport function shouldUseColor(environment: ColorEnvironment = {}): boolean {\n const env = environment.env ?? process.env;\n if (env['NO_COLOR'] !== undefined && env['NO_COLOR'] !== '') return false;\n // `0` and `false` are how the convention writes off, as Node and\n // supports-color read them, so each has to win over an attached TTY rather\n // than merely fail to force colour on: `false` used to force it. The two\n // spellings exactly; every other value that is not empty forces colour on.\n const forced = env['FORCE_COLOR'];\n if (forced === '0' || forced === 'false') return false;\n if (forced !== undefined && forced !== '') return true;\n if (env['TERM'] === 'dumb') return false;\n return environment.isTTY === true;\n}\n\n/**\n * True when ASCII was asked for, or the terminal is unlikely to render\n * box-drawing and arrows.\n *\n * `SPEC_GRAPH_ASCII` asks, and `0`, `false` and a blank do not: each is how a\n * script writes \"off\", and every one of them used to turn ASCII on.\n */\nexport function shouldUseAscii(environment: ColorEnvironment = {}): boolean {\n const env = environment.env ?? process.env;\n const asked = (env['SPEC_GRAPH_ASCII'] ?? '').trim().toLowerCase();\n if (asked !== '' && asked !== '0' && asked !== 'false') return true;\n if ((environment.platform ?? process.platform) !== 'win32') return false;\n // Windows Terminal and modern shells set these; the legacy console does not.\n // Set to nothing is as unset, as for every convention's variable: `WT_SESSION=`\n // is a script clearing it, and used to read as a terminal announcing itself.\n return (env['WT_SESSION'] ?? '') === '' && (env['TERM_PROGRAM'] ?? '') === '';\n}\n\nconst EMPTY_RULES: ReadonlySet<RuleId> = new Set<RuleId>();\n\ntype Paint = (text: string) => string;\n\nexport interface Painter {\n readonly error: Paint;\n readonly warn: Paint;\n readonly info: Paint;\n readonly dim: Paint;\n readonly bold: Paint;\n readonly hint: Paint;\n readonly location: Paint;\n}\n\nexport function createPainter(color: boolean): Painter {\n const wrap = (open: string): Paint => (text) => (color ? `\\u001b[${open}m${text}\\u001b[0m` : text);\n return {\n error: wrap('31'),\n warn: wrap('33'),\n info: wrap('36'),\n dim: wrap('2'),\n bold: wrap('1'),\n hint: wrap('32'),\n location: wrap('4'),\n };\n}\n\ninterface Glyphs {\n readonly error: string;\n readonly warn: string;\n readonly info: string;\n readonly related: string;\n readonly hint: string;\n readonly separator: string;\n}\n\nfunction glyphs(ascii: boolean): Glyphs {\n return ascii\n ? { error: 'x', warn: '!', info: 'i', related: '|', hint: '>', separator: '-' }\n : { error: '\\u2716', warn: '\\u26a0', info: '\\u2139', related: '\\u21b3', hint: '\\u2192', separator: '\\u00b7' };\n}\n\n/* -------------------------------------------------------------------------- */\n/* Human report */\n/* -------------------------------------------------------------------------- */\n\n/** Renders the full terminal report. */\nexport function formatReport(result: AnalysisResult, options: ReporterOptions = {}): string {\n const paint = createPainter(options.color ?? false);\n const marks = glyphs(options.ascii ?? false);\n const lines: string[] = [];\n const { summary } = result;\n\n lines.push(\n `${paint.bold('spec-graph')} ${paint.dim(\n [\n `${summary.documents} ${plural(summary.documents, 'document')}`,\n `${summary.items} ${plural(summary.items, 'item')}`,\n `${summary.edges} ${plural(summary.edges, 'relation')}`,\n `${summary.openObligations} open`,\n ].join(` ${marks.separator} `),\n )}`,\n );\n lines.push('');\n\n // Zero is falsy and never reaches the comparison, so `> 0` and `>= 0` are\n // the same test here.\n const limit = options.max && options.max > 0 ? options.max : result.diagnostics.length;\n const shown = result.diagnostics.slice(0, limit);\n\n const escalated = options.escalated ?? EMPTY_RULES;\n for (const diagnostic of shown) {\n lines.push(...formatDiagnostic(diagnostic, paint, marks, escalated));\n lines.push('');\n }\n\n if (result.diagnostics.length > shown.length) {\n lines.push(paint.dim(` ... and ${result.diagnostics.length - shown.length} more`));\n lines.push('');\n }\n\n if (options.verbose && result.problems.length > 0) {\n for (const problem of result.problems) {\n lines.push(`${paint.warn(marks.warn)} ${paint.location(formatRef(problem.at))} ${problem.message}`);\n }\n lines.push('');\n }\n\n const unread = options.verbose ? 0 : unreadFrontMatter(result);\n if (unread > 0) {\n lines.push(`${paint.warn(marks.warn)} ${unreadNotice(unread)}`, '');\n }\n\n // What the repository told spec-graph to stop looking at. Only under\n // --verbose, and never as a finding: these are not defects, they are the one\n // place a configuration can make the check quieter, and a single over-broad\n // glob looks exactly like a clean repository from the outside. See ADR-0008.\n if (options.verbose && result.corpus.suppressed.length > 0) {\n for (const [target, entry] of groupSuppressed(result.corpus.suppressed)) {\n const where = entry.by === 'family' ? 'ignored family' : 'ignored reference';\n const times = entry.count === 1 ? '' : ` (${entry.count} times)`;\n lines.push(`${paint.dim(marks.info)} ${paint.location(formatRef(entry.at))} ${paint.dim(`${where}: ${target}${times}`)}`);\n }\n lines.push('');\n }\n\n const tally: string[] = [];\n if (summary.errors > 0) tally.push(paint.error(`${summary.errors} ${plural(summary.errors, 'error')}`));\n if (summary.warnings > 0) tally.push(paint.warn(`${summary.warnings} ${plural(summary.warnings, 'warning')}`));\n if (summary.infos > 0) tally.push(paint.info(`${summary.infos} ${plural(summary.infos, 'note')}`));\n tally.push(paint.dim(`${summary.durationMs}ms`));\n const raised = result.diagnostics.filter((diagnostic) => escalated.has(diagnostic.rule)).length;\n if (raised > 0) {\n tally.push(paint.warn(`${raised} raised by --strict`));\n }\n const baseline = options.baseline;\n if (baseline !== undefined && baseline.suppressed > 0) {\n tally.push(paint.dim(`${baseline.suppressed} accepted by ${baseline.source}`));\n }\n lines.push(tally.join(` ${marks.separator} `));\n\n // Under `--ratchet` a paid entry is a failure rather than a note, so it is\n // painted and worded as one.\n const ratcheted = ratchetFailed(baseline);\n if (baseline !== undefined && baseline.stale > 0) {\n // A \"gone\" entry is not the ratchet working, and saying so matters more\n // than the count does: the usual way to produce one is to narrow an include\n // pattern, which loses sight of a defect rather than fixing it.\n //\n // The fallback is only ever filtered for gone entries, so filling it with\n // anything that is not one counts the same zero.\n const gone = (baseline.entries ?? []).filter((entry) => entry.reason === 'gone').length;\n const because =\n gone === 0\n ? `tighten it: spec-graph check --record-baseline ${options.recordAs ?? baseline.source}`\n : `${gone} of them ${gone === 1 ? 'names a document' : 'name documents'} this run did not see - check the include patterns before re-recording`;\n const text = `${baseline.stale} baseline ${plural(baseline.stale, 'entry', 'entries')} no longer ${\n baseline.stale === 1 ? 'occurs' : 'occur'\n } - ${because}`;\n lines.push(ratcheted ? `${paint.error(marks.error)} ${text}` : paint.dim(text));\n }\n\n // `ok` means no errors, so where it is true the sum below is the warnings\n // alone and `-` in place of `+` asks the same question.\n lines.push(\n ratcheted\n ? `${paint.error(marks.error)} ${\n result.ok ? 'the baseline is looser than the repository' : 'the specification graph is inconsistent'\n }`\n : result.ok\n ? `${paint.hint(marks.hint === '>' ? 'ok' : '\\u2714')} ${\n summary.errors + summary.warnings === 0\n ? 'the specification graph is consistent'\n : 'no errors - the specification graph holds'\n }`\n : `${paint.error(marks.error)} the specification graph is inconsistent`,\n );\n\n return lines.join('\\n');\n}\n\nfunction formatDiagnostic(\n diagnostic: Diagnostic,\n paint: Painter,\n marks: Glyphs,\n escalated: ReadonlySet<AnyRuleId>,\n): string[] {\n const mark = severityMark(diagnostic.severity, paint, marks);\n const label = escalated.has(diagnostic.rule)\n ? `${diagnostic.rule} ${paint.warn('(strict: warn -> error)')}`\n : diagnostic.rule;\n const lines: string[] = [\n `${mark} ${paint.location(formatRef(diagnostic.at))} ${paint.dim(label)}`,\n ` ${diagnostic.message}`,\n ];\n\n // Padded to the columns a terminal draws, not to UTF-16 units: `docs/決策.md`\n // is ten units and twelve columns, so `.padEnd` left the notes beside it two\n // columns out of line.\n const width = Math.max(0, ...diagnostic.related.map((entry) => displayWidth(formatRef(entry.at))));\n for (const entry of diagnostic.related) {\n const reference = formatRef(entry.at);\n const padded = `${reference}${' '.repeat(width - displayWidth(reference))}`;\n lines.push(` ${paint.dim(marks.related)} ${paint.dim(padded)} ${paint.dim(entry.note)}`);\n }\n\n lines.push(` ${paint.hint(marks.hint)} ${paint.hint(diagnostic.hint)}`);\n return lines;\n}\n\nfunction severityMark(severity: Exclude<Severity, 'off'>, paint: Painter, marks: Glyphs): string {\n switch (severity) {\n case 'error':\n return paint.error(marks.error);\n case 'warn':\n return paint.warn(marks.warn);\n case 'info':\n return paint.info(marks.info);\n }\n}\n\nfunction plural(count: number, word: string, plural?: string): string {\n if (count === 1) return word;\n return plural ?? `${word}s`;\n}\n\n/**\n * How many front-matter values the graph is built from went unread.\n *\n * Parse problems are listed only under `--verbose`, and most of them can wait\n * there. These cannot: `status: Superseded by ADR-3: see notes` is not read,\n * the document reads as unknown, and a failing check reports that the graph is\n * consistent. So a default run says how many there are, and where to look.\n */\nfunction unreadFrontMatter(result: AnalysisResult): number {\n return result.problems.filter((problem) => problem.unread === true).length;\n}\n\nfunction unreadNotice(count: number): string {\n return `${count} front-matter ${plural(count, 'value')} not read - see --verbose`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Markdown */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The same report as GitHub-flavoured Markdown.\n *\n * SARIF puts a finding on the line that caused it, which is where somebody\n * fixing one wants it. It says nothing to the person deciding whether to merge,\n * because a code-scanning alert is a list of lines and not a verdict. This is\n * the verdict: one table, the counts above it, and the baseline's slack\n * underneath, sized to be read without scrolling.\n *\n * Written for `$GITHUB_STEP_SUMMARY` and for a pull-request comment, but it is\n * named for what it is rather than for where it goes - the same text is what a\n * review tool, a chat message or a generated page wants.\n *\n * It carries no duration, which the JSON report does, so two runs over one\n * corpus produce identical bytes. That is what lets a test compare a run from\n * a subdirectory against a run from the root and assert they are the same\n * report rather than the same shape. See ADR-0015 and ADR-0018.\n */\nexport function formatMarkdown(result: AnalysisResult, options: ReporterOptions = {}): string {\n const { summary } = result;\n const escalated = options.escalated ?? EMPTY_RULES;\n const ratcheted = ratchetFailed(options.baseline);\n const lines: string[] = ['### spec-graph', ''];\n\n // `ok` means no errors, as in the terminal's verdict, so `-` in place of `+`\n // below asks the same question.\n const verdict =\n ratcheted && result.ok\n ? 'The baseline is looser than the repository.'\n : result.ok\n ? summary.errors + summary.warnings === 0\n ? 'The specification graph is consistent.'\n : 'No errors - the specification graph holds.'\n : 'The specification graph is inconsistent.';\n lines.push(verdict, '');\n\n lines.push('| | |', '| --- | ---: |');\n lines.push(`| Documents | ${summary.documents} |`);\n lines.push(`| Items | ${summary.items} |`);\n lines.push(`| Relations | ${summary.edges} |`);\n lines.push(`| Open obligations | ${summary.openObligations} |`);\n lines.push(`| Errors | ${summary.errors} |`);\n lines.push(`| Warnings | ${summary.warnings} |`);\n lines.push(`| Notes | ${summary.infos} |`);\n lines.push('');\n\n // Zero never reaches the comparison, as in the terminal report.\n const limit = options.max && options.max > 0 ? options.max : result.diagnostics.length;\n const shown = result.diagnostics.slice(0, limit);\n\n if (shown.length > 0) {\n lines.push('| | Rule | Where | Finding |', '| --- | --- | --- | --- |');\n for (const diagnostic of shown) {\n const rule = escalated.has(diagnostic.rule) ? `${diagnostic.rule} (strict)` : diagnostic.rule;\n // The hint in the same cell, under the message. A finding without its\n // next action is the half a reader cannot act on, and a fifth column\n // would push the message off the side of the page.\n const what = `${cell(diagnostic.message)}<br>${cell(diagnostic.hint)}`;\n lines.push(`| ${diagnostic.severity} | \\`${cell(rule)}\\` | \\`${cell(formatRef(diagnostic.at))}\\` | ${what} |`);\n }\n if (result.diagnostics.length > shown.length) {\n lines.push(`| | | | ... and ${result.diagnostics.length - shown.length} more |`);\n }\n lines.push('');\n }\n\n const baseline = options.baseline;\n if (baseline !== undefined) {\n const accepted = `${baseline.suppressed} ${plural(baseline.suppressed, 'finding')} accepted by \\`${cell(baseline.source)}\\``;\n if (baseline.stale === 0) {\n lines.push(accepted, '');\n } else {\n // The fallback is only filtered for gone entries, as in the terminal report.\n const gone = (baseline.entries ?? []).filter((entry) => entry.reason === 'gone').length;\n lines.push(\n `${accepted}, and ${baseline.stale} ${plural(baseline.stale, 'entry', 'entries')} no longer ${\n baseline.stale === 1 ? 'occurs' : 'occur'\n }${\n gone === 0\n ? ''\n : ` - ${gone} of them ${gone === 1 ? 'names a document' : 'name documents'} this run did not see`\n }.`,\n '',\n );\n // Listed rather than counted, because the point of a summary on a pull\n // request is that somebody can act on it without opening a terminal.\n lines.push('| Entry | Rule | Document | Why |', '| --- | --- | --- | --- |');\n for (const entry of baseline.entries ?? []) {\n const why = entry.reason === 'gone' ? 'not in this corpus - check the include patterns' : 'fixed';\n lines.push(`| ${entry.reason} | \\`${cell(entry.rule)}\\` | \\`${cell(entry.document)}\\` | ${why} |`);\n }\n lines.push('');\n }\n }\n\n const unread = options.verbose ? 0 : unreadFrontMatter(result);\n if (unread > 0) lines.push(`${unreadNotice(unread)}.`, '');\n\n if (options.verbose && result.problems.length > 0) {\n lines.push('<details><summary>Problems with the input</summary>', '');\n for (const problem of result.problems) {\n lines.push(`- \\`${cell(formatRef(problem.at))}\\` ${cell(problem.message)}`);\n }\n lines.push('', '</details>', '');\n }\n\n if (options.verbose && result.corpus.suppressed.length > 0) {\n lines.push('<details><summary>References this configuration silenced</summary>', '');\n for (const [target, entry] of groupSuppressed(result.corpus.suppressed)) {\n const where = entry.by === 'family' ? 'ignored family' : 'ignored reference';\n const times = entry.count === 1 ? '' : ` (${entry.count} times)`;\n lines.push(`- \\`${cell(target)}\\` - ${where}${times}, first at \\`${cell(formatRef(entry.at))}\\``);\n }\n lines.push('', '</details>', '');\n }\n\n // Every block above ends in exactly one blank line, so there is only ever one\n // trailing newline for this to strip, and `\\n$` would strip the same.\n return `${lines.join('\\n').replace(/\\n+$/, '')}\\n`;\n}\n\n/**\n * Makes one value safe to put in a table cell.\n *\n * A pipe would end the cell and a newline would end the row, and a diagnostic\n * message is written by whoever wrote the rule - including a project rule,\n * whose message is a template a repository controls.\n */\nfunction cell(value: string): string {\n return value.replace(/[|]/g, '|').replace(/\\s+/g, ' ').trim();\n}\n\n/* -------------------------------------------------------------------------- */\n/* JSON */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The machine-readable report.\n *\n * Deliberately flat and versioned: this is the contract a CI annotator or a\n * dashboard builds against, and it must be safe to add fields to it later.\n */\n/**\n * One row per silenced target, with the first place it was written.\n *\n * Grouped because a concept tag used forty times is one decision, and forty\n * lines of it would bury the one entry somebody needs to see. Insertion order\n * is document order, which is already deterministic.\n */\nfunction groupSuppressed(\n suppressed: readonly SuppressedRef[],\n): Map<string, { at: SourceRef; by: SuppressedRef['by']; count: number }> {\n const out = new Map<string, { at: SourceRef; by: SuppressedRef['by']; count: number }>();\n for (const entry of suppressed) {\n const seen = out.get(entry.target);\n if (seen === undefined) out.set(entry.target, { at: entry.at, by: entry.by, count: 1 });\n else seen.count += 1;\n }\n return out;\n}\n\n/**\n * True when a baseline was asked to ratchet and has slack left in it.\n *\n * Both reporters ask, because both have to agree with the exit code: a report\n * that prints \"ok\" above a failing build is worse than no report.\n */\nfunction ratchetFailed(baseline: ReporterOptions['baseline']): boolean {\n return baseline !== undefined && baseline.ratchet === true && baseline.stale > 0;\n}\n\n/* -------------------------------------------------------------------------- */\n/* SARIF */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The static-analysis interchange format, for the tools that already read it.\n *\n * The reason to emit it is not the format, it is what consumes the format:\n * GitHub code scanning turns a SARIF upload into annotations on the diff, and\n * an editor turns it into the problems pane, neither of which needs a line of\n * spec-graph-specific integration.\n *\n * One field earns the whole exercise. `partialFingerprints` is how a consumer\n * tracks a finding across commits without keying on a line number, and\n * spec-graph already has exactly that identifier for exactly that reason - the\n * `rule/document/subject` triple a baseline is keyed on (ADR-0012). The two\n * problems turned out to be the same problem, so the answer is the same answer.\n *\n * Deterministic and timestamp-free, like every other output here. Nothing about\n * a run that has the same findings should produce a different file.\n */\nexport function formatSarif(\n result: AnalysisResult,\n graph: SpecGraph,\n options: {\n version?: string | undefined;\n escalated?: ReadonlySet<AnyRuleId> | undefined;\n projectRules?: readonly ProjectRule[] | undefined;\n } = {},\n): string {\n const escalated = options.escalated ?? EMPTY_RULES;\n // A project rule describes itself by the selector it is, because that is the\n // only honest answer: its message is a template, and a template with `{0}` in\n // it is not a description of anything. See ADR-0016.\n const known: [AnyRuleId, string, Severity][] = [\n ...RULE_IDS.map((id): [AnyRuleId, string, Severity] => [id, RULE_DESCRIPTIONS[id], DEFAULT_SEVERITIES[id]]),\n ...(options.projectRules ?? []).map((rule): [AnyRuleId, string, Severity] => [\n rule.id,\n rule.sources.join(' | '),\n rule.severity,\n ]),\n ];\n const fired = known.filter(([id]) => result.diagnostics.some((diagnostic) => diagnostic.rule === id));\n return `${JSON.stringify(\n {\n $schema: 'https://json.schemastore.org/sarif-2.1.0.json',\n version: '2.1.0',\n runs: [\n {\n tool: {\n driver: {\n name: 'spec-graph',\n informationUri: 'https://github.com/DescentVTT/spec-graph',\n // JSON.stringify drops a key whose value is undefined, so always\n // spreading the pair writes the same file; the test is for the reader.\n ...(options.version === undefined ? {} : { version: options.version, semanticVersion: options.version }),\n // Only the rules that fired. A driver listing all of them\n // describes the tool; this file describes the run.\n rules: fired.map(([id, description, level]) => ({\n id,\n shortDescription: { text: description },\n defaultConfiguration: { level: sarifLevel(level) },\n })),\n },\n },\n results: result.diagnostics.map((diagnostic) => {\n const print = fingerprintOf(graph, diagnostic);\n return {\n ruleId: diagnostic.rule,\n level: sarifLevel(diagnostic.severity),\n message: { text: `${diagnostic.message}. ${diagnostic.hint}` },\n locations: [sarifLocation(diagnostic.at)],\n ...(diagnostic.related.length === 0\n ? {}\n : {\n relatedLocations: diagnostic.related.map((entry) => ({\n ...sarifLocation(entry.at),\n message: { text: entry.note },\n })),\n }),\n partialFingerprints: {\n specGraphIdentity: `${diagnostic.rule}/${print.document}/${print.subject}`,\n },\n properties: {\n nodes: diagnostic.nodes,\n target: diagnostic.target,\n // A finding that is only an error because of a flag says so\n // here too, so a reviewer reading an annotation is not misled.\n escalated: escalated.has(diagnostic.rule),\n },\n };\n }),\n },\n ],\n },\n null,\n 2,\n )}\\n`;\n}\n\nfunction sarifLevel(severity: Severity): string {\n switch (severity) {\n case 'error':\n return 'error';\n case 'warn':\n return 'warning';\n case 'info':\n return 'note';\n default:\n return 'none';\n }\n}\n\nfunction sarifLocation(at: SourceRef): {\n physicalLocation: {\n artifactLocation: { uri: string };\n region: { startLine: number; startColumn: number; endLine: number; endColumn: number };\n };\n} {\n return {\n physicalLocation: {\n // Already repository-relative and POSIX, which is what SARIF asks for.\n artifactLocation: { uri: at.file },\n region: {\n startLine: at.span.start.line,\n startColumn: at.span.start.column,\n endLine: at.span.end.line,\n endColumn: at.span.end.column,\n },\n },\n };\n}\n\n/* -------------------------------------------------------------------------- */\n/* GitLab Code Quality */\n/* -------------------------------------------------------------------------- */\n\ntype GitlabSeverity = 'critical' | 'major' | 'minor' | 'info';\n\n/**\n * GitLab's Code Quality report, which a merge request reads to show the\n * findings a change introduced and the ones it resolved - what SARIF is to\n * GitHub, so the family is not GitHub's alone.\n *\n * The format is GitLab's and carries no version of its own: a JSON array with\n * the five fields GitLab reads and nothing else.\n *\n * `fingerprint` is how GitLab matches a finding in the merge request to the\n * same finding on the target branch, so it holds what the finding is about and\n * nothing that moves when something else changes: the rule, the specification\n * and what within it, hashed - the identity a baseline counts by. Not the line,\n * so a paragraph moved above a finding does not make it new. Not the message,\n * which carries counts: ticking one of three boxes turned \"holds 3 open\n * obligations\" into \"holds 2\", and GitLab showed one finding resolved and one\n * introduced. Two findings that agree on all three - one broken link written\n * twice in a document - are told apart by their order, the second hashed with a\n * `2`: GitLab tells issues apart by fingerprint, and two that shared one would\n * be read as one.\n */\nexport function formatGitlab(\n result: AnalysisResult,\n options: { escalated?: ReadonlySet<AnyRuleId> | undefined } = {},\n): string {\n const escalated = options.escalated ?? EMPTY_RULES;\n const occurrences = new Map<string, number>();\n const issues = result.diagnostics.map((diagnostic) => {\n const { document, subject } = fingerprintOf(result.graph, diagnostic);\n const identity = [diagnostic.rule, document, subject];\n const key = JSON.stringify(identity);\n const occurrence = (occurrences.get(key) ?? 0) + 1;\n occurrences.set(key, occurrence);\n return {\n description: `${diagnostic.message}. ${diagnostic.hint}`,\n check_name: diagnostic.rule,\n fingerprint: createHash('sha256')\n .update(occurrence === 1 ? key : JSON.stringify([...identity, occurrence]))\n .digest('hex'),\n severity: gitlabSeverity(diagnostic.severity, escalated.has(diagnostic.rule)),\n location: { path: diagnostic.at.file, lines: { begin: diagnostic.at.span.start.line } },\n };\n });\n return `${JSON.stringify(issues, null, 2)}\\n`;\n}\n\n/**\n * spec-graph's three severities on GitLab's five. An error is critical: it\n * fails the build. One that is only an error because `--strict` raised it is\n * major, which is the one place the report can say so. A warning is minor,\n * and a note is information. `blocker` is left to tools that know more about\n * what cannot ship than a documentation linter does.\n */\nfunction gitlabSeverity(severity: Severity, escalated: boolean): GitlabSeverity {\n switch (severity) {\n case 'error':\n return escalated ? 'major' : 'critical';\n case 'warn':\n return 'minor';\n default:\n return 'info';\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* GitHub workflow commands */\n/* -------------------------------------------------------------------------- */\n\n/** A workflow command's message: `%`, and the line breaks that would end the command. */\nfunction escapeData(text: string): string {\n return text.replace(/%/g, '%25').replace(/\\r/g, '%0D').replace(/\\n/g, '%0A');\n}\n\n/** A workflow command's property: as a message, and the `:` and `,` that would end the property. */\nfunction escapeProperty(text: string): string {\n return escapeData(text).replace(/:/g, '%3A').replace(/,/g, '%2C');\n}\n\n/**\n * Findings as GitHub Actions workflow commands, one line each, which a job's\n * log turns into annotations on the pull request's diff with no upload step -\n * what SARIF does through code scanning, for a repository that has none.\n *\n * An error is `error`, a warning `warning` and a note `notice`, as spec-guard\n * writes them. The rule is the title, marked `(strict)` where only `--strict`\n * made it an error, as the Markdown report marks it; the message carries the\n * hint, since a finding without its next action is the half a reader cannot\n * act on. Nothing at all for a clean run.\n */\nexport function formatGithub(\n result: AnalysisResult,\n options: { escalated?: ReadonlySet<AnyRuleId> | undefined } = {},\n): string {\n const escalated = options.escalated ?? EMPTY_RULES;\n return result.diagnostics\n .map((diagnostic) => {\n const title = escalated.has(diagnostic.rule) ? `${diagnostic.rule} (strict)` : diagnostic.rule;\n const place = `file=${escapeProperty(diagnostic.at.file)},line=${diagnostic.at.span.start.line}`;\n return `::${githubLevel(diagnostic.severity)} ${place},title=${escapeProperty(title)}::${escapeData(\n `${diagnostic.message}. ${diagnostic.hint}`,\n )}\\n`;\n })\n .join('');\n}\n\nfunction githubLevel(severity: Severity): 'error' | 'warning' | 'notice' {\n switch (severity) {\n case 'error':\n return 'error';\n case 'warn':\n return 'warning';\n default:\n return 'notice';\n }\n}\n\nexport function formatJson(\n result: AnalysisResult,\n options: { escalated?: ReadonlySet<AnyRuleId>; baseline?: ReporterOptions['baseline'] } = {},\n): string {\n const escalated = options.escalated ?? EMPTY_RULES;\n return `${JSON.stringify(\n {\n version: 1,\n ok: result.ok && !ratchetFailed(options.baseline),\n strict: escalated.size > 0,\n // Always spreading would write `baseline: undefined`, which JSON.stringify\n // drops, so the test changes nothing but what the line says.\n ...(options.baseline === undefined ? {} : { baseline: options.baseline }),\n summary: result.summary,\n files: result.files,\n // The audit trail for what configuration silenced. Always present, unlike\n // the human report's --verbose gate: a machine reader that has to ask for\n // it twice will not ask. See ADR-0008.\n suppressed: result.corpus.suppressed.map((entry) => ({\n target: entry.target,\n from: entry.from,\n by: entry.by,\n file: entry.at.file,\n line: entry.at.span.start.line,\n })),\n diagnostics: result.diagnostics.map((diagnostic) => ({\n rule: diagnostic.rule,\n severity: diagnostic.severity,\n // True when this finding is only an error because of --strict.\n escalated: escalated.has(diagnostic.rule),\n message: diagnostic.message,\n hint: diagnostic.hint,\n nodes: diagnostic.nodes,\n target: diagnostic.target,\n file: diagnostic.at.file,\n line: diagnostic.at.span.start.line,\n column: diagnostic.at.span.start.column,\n endLine: diagnostic.at.span.end.line,\n endColumn: diagnostic.at.span.end.column,\n related: diagnostic.related.map((entry) => ({\n file: entry.at.file,\n line: entry.at.span.start.line,\n column: entry.at.span.start.column,\n note: entry.note,\n })),\n })),\n problems: result.problems.map((problem) => ({\n message: problem.message,\n file: problem.at.file,\n line: problem.at.span.start.line,\n })),\n },\n null,\n 2,\n )}\\n`;\n}\n\n/* -------------------------------------------------------------------------- */\n/* Graph export */\n/* -------------------------------------------------------------------------- */\n\nexport type GraphFormat = 'dot' | 'mermaid' | 'json';\n\nexport interface GraphExportOptions {\n /** Leave out `contains` edges and item nodes. */\n readonly documentsOnly?: boolean | undefined;\n /**\n * What made the export, for the JSON form. Passed in rather than looked up,\n * because reading the package's own version is I/O and this module has none.\n * Two exports from different versions differ wherever extraction changed, and\n * `diff` warns about that only if it can see it (ADR-0020).\n */\n readonly generator?: { readonly name: string; readonly version: string } | undefined;\n}\n\n/** Serialises the graph for Graphviz, Mermaid, or a downstream tool. */\nexport function formatGraph(graph: SpecGraph, format: GraphFormat, options: GraphExportOptions = {}): string {\n const skipItems = options.documentsOnly ?? false;\n const nodes = [...graph.nodes.values()].filter((node) => !skipItems || node.kind === 'document');\n const visible = new Set(nodes.map((node) => node.id));\n\n // Hiding items must not hide what they say. An obligation delegated from an\n // item to a document is lifted onto the item's owner, so the document-level\n // view still shows the handover rather than silently losing it.\n const lifted = skipItems\n ? dedupeEdges(\n graph.edges\n // Containment of an *item* is what hiding items makes redundant.\n // Containment of a specification by the register that holds it is\n // structure between documents, and is what this view exists to show.\n //\n // An item is contained by its own document, so its containment would\n // lift onto that document and fall to the reflexive filter below\n // anyway: dropping this filter changes no export, and it stays to\n // say which containment the view keeps.\n .filter((edge) => edge.kind !== 'contains' || visible.has(edge.to))\n .map((edge) => {\n const from = graph.owningDocument(edge.from)?.id ?? edge.from;\n const to = graph.owningDocument(edge.to)?.id ?? edge.to;\n // An edge that did not move, rebuilt, is the same edge: its own\n // `reflexive` already says whether `from` is `to`.\n return from === edge.from && to === edge.to ? edge : { ...edge, from, to, reflexive: from === to };\n })\n .filter((edge) => !edge.reflexive),\n )\n : graph.edges;\n\n const edges = lifted.filter((edge) => visible.has(edge.from) && visible.has(edge.to));\n\n switch (format) {\n case 'dot':\n return toDot(nodes, edges);\n case 'mermaid':\n return toMermaid(nodes, edges);\n case 'json':\n return `${JSON.stringify(\n {\n version: 1,\n // `generator: undefined` is dropped by JSON.stringify, so the test\n // decides nothing the file shows.\n ...(options.generator !== undefined && { generator: options.generator }),\n nodes: nodes.map(serialiseNode),\n edges: edges.map((edge) => ({\n kind: edge.kind,\n from: edge.from,\n to: edge.to,\n origin: edge.origin,\n declaredIn: edge.declaredIn,\n file: edge.declaredAt.file,\n line: edge.declaredAt.span.start.line,\n })),\n },\n null,\n 2,\n )}\\n`;\n }\n}\n\n/** Collapses duplicate relations produced by lifting item edges onto documents. */\nfunction dedupeEdges(edges: readonly Edge[]): Edge[] {\n const seen = new Set<string>();\n // Anything here that is not an edge between drawn nodes is dropped by the\n // filter formatGraph applies next, so seeding this array changes no export.\n const out: Edge[] = [];\n for (const edge of edges) {\n const key = `${edge.kind} ${edge.from} ${edge.to}`;\n if (seen.has(key)) continue;\n seen.add(key);\n out.push(edge);\n }\n return out;\n}\n\nfunction serialiseNode(node: SpecNode): Record<string, unknown> {\n const base = {\n id: node.id,\n kind: node.kind,\n title: node.title,\n file: node.at.file,\n line: node.at.span.start.line,\n };\n return node.kind === 'document'\n ? { ...base, path: node.path, phase: node.phase, status: node.rawStatus, aliases: node.aliases }\n : {\n ...base,\n declared: node.declared,\n document: node.document,\n section: node.section,\n disposition: node.disposition,\n openness: node.openness,\n };\n}\n\n/** Phase colours, chosen to stay legible in both light and dark renderings. */\nconst PHASE_FILL: Readonly<Record<string, string>> = {\n draft: '#e8f0fe',\n active: '#e6f4ea',\n frozen: '#e8eaed',\n retired: '#fce8e6',\n record: '#f3e8fd',\n unknown: '#ffffff',\n};\n\nfunction toDot(nodes: readonly SpecNode[], edges: readonly Edge[]): string {\n const lines = ['digraph spec {', ' rankdir=LR;', ' node [shape=box, style=\"rounded,filled\", fontname=\"sans\"];'];\n for (const node of nodes) {\n // Every phase has a fill, `unknown` included, so the fallback is for a\n // phase added to the lattice before it is given a colour, and no graph\n // today reaches it.\n const fill = node.kind === 'document' ? (PHASE_FILL[node.phase] ?? '#ffffff') : '#fffbe6';\n const label = node.kind === 'document' ? `${node.id}\\\\n${escapeDot(node.title)}` : escapeDot(node.text);\n const shape = node.kind === 'document' ? 'box' : 'note';\n lines.push(` \"${escapeDot(node.id)}\" [label=\"${label}\", fillcolor=\"${fill}\", shape=${shape}];`);\n }\n for (const edge of edges) {\n const style = edge.kind === 'contains' ? ', style=dotted' : '';\n lines.push(` \"${escapeDot(edge.from)}\" -> \"${escapeDot(edge.to)}\" [label=\"${edge.kind}\"${style}];`);\n }\n lines.push('}');\n return `${lines.join('\\n')}\\n`;\n}\n\nfunction toMermaid(nodes: readonly SpecNode[], edges: readonly Edge[]): string {\n const lines = ['graph LR'];\n const alias = new Map<string, string>();\n nodes.forEach((node, position) => alias.set(node.id, `n${position}`));\n\n for (const node of nodes) {\n const key = alias.get(node.id) as string;\n const label = escapeMermaid(node.kind === 'document' ? node.id : node.text);\n lines.push(node.kind === 'document' ? ` ${key}[\"${label}\"]` : ` ${key}([\"${label}\"])`);\n if (node.kind === 'document' && node.phase !== 'unknown') lines.push(` class ${key} ${node.phase};`);\n }\n // formatGraph hands over only edges between the nodes being drawn, and every\n // one of those has an alias.\n for (const edge of edges) {\n lines.push(` ${alias.get(edge.from) as string} -->|${edge.kind}| ${alias.get(edge.to) as string}`);\n }\n for (const [phase, fill] of Object.entries(PHASE_FILL)) {\n if (phase === 'unknown') continue;\n lines.push(` classDef ${phase} fill:${fill},stroke:#5f6368;`);\n }\n return `${lines.join('\\n')}\\n`;\n}\n\nfunction escapeDot(value: string): string {\n return value.replace(/[\"\\\\]/g, '\\\\$&').replace(/\\n/g, '\\\\n');\n}\n\nfunction escapeMermaid(value: string): string {\n return value.replace(/[\"#]/g, ' ').replace(/\\s+/g, ' ').trim();\n}\n"]}
|
package/dist/select.js
CHANGED
|
@@ -162,9 +162,10 @@ class Parser {
|
|
|
162
162
|
return out;
|
|
163
163
|
}
|
|
164
164
|
// The anchor decides nothing, since a starred class matches the empty
|
|
165
|
-
// string where the search starts; it says where the value begins.
|
|
166
|
-
|
|
167
|
-
|
|
165
|
+
// string where the search starts; it says where the value begins. For the
|
|
166
|
+
// same reason the search never misses, and there is nothing to fall back
|
|
167
|
+
// from.
|
|
168
|
+
const value = /^[^\]\s]*/.exec(this.source.slice(this.position))[0];
|
|
168
169
|
this.position += value.length;
|
|
169
170
|
return value;
|
|
170
171
|
}
|
package/dist/select.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"select.js","sourceRoot":"","sources":["../src/select.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The selector language.\n *\n * Rules and users ask the graph the same kinds of question, so they use the same\n * machinery. Every built-in diagnostic is a path query plus a message; anything\n * a rule can find, `spec-graph query` can find too, which means a team can\n * express a convention spec-graph never anticipated without writing a plugin.\n *\n * ```text\n * item[openness=open] -delegates-to-> document[phase=retired]\n * document[phase=active] -assumes,depends-on-> document[phase=retired]\n * document =supersedes=> document[phase=active]\n * item[state=obviated] <-assumes- *\n * *[path^=docs/adr] -blocked-by-> item[openness=open]\n * ```\n *\n * A query evaluates to **paths**, not endpoints. A rule that has the whole path\n * can say \"ADR-0004 line 31 delegates this to ADR-0002, which was retired in\n * March\" instead of naming two documents and leaving the reader to reconstruct\n * the relationship.\n */\n\nimport { receptivityOf } from './lifecycle.js';\nimport type { SpecGraph } from './graph.js';\nimport { EDGE_KINDS, type Edge, type EdgeKind, type NodeKind, type SpecNode } from './types.js';\nimport { compileRegex, RegexError, type RegexMatcher } from './vendor/spec-core/pattern/index.js';\n\n/* -------------------------------------------------------------------------- */\n/* Shapes */\n/* -------------------------------------------------------------------------- */\n\nexport type Operator = '=' | '!=' | '^=' | '$=' | '*=' | '~=' | 'exists';\n\nexport interface Predicate {\n readonly key: string;\n readonly operator: Operator;\n readonly value: string;\n}\n\nexport interface NodeMatcher {\n /** `null` matches both documents and items. */\n readonly kind: NodeKind | null;\n readonly predicates: readonly Predicate[];\n}\n\nexport interface StepSpec {\n readonly direction: 'out' | 'in';\n /** `null` matches any edge kind. */\n readonly kinds: readonly EdgeKind[] | null;\n /** Follow the relation transitively, taking the shortest path to each node. */\n readonly transitive: boolean;\n readonly node: NodeMatcher;\n}\n\nexport interface QuerySpec {\n readonly start: NodeMatcher;\n readonly steps: readonly StepSpec[];\n}\n\n/**\n * One path through the graph.\n *\n * `nodes` holds the start and the node each step matched; `edges` is the whole\n * path in order. A transitive step contributes one node and every edge it\n * walked, so the nodes it passed through are named only by those edges.\n */\nexport interface Match {\n readonly nodes: readonly SpecNode[];\n readonly edges: readonly Edge[];\n}\n\nexport class QueryError extends Error {\n /** Offset into the query string where the problem starts. */\n readonly offset: number;\n\n constructor(message: string, offset: number) {\n super(message);\n this.name = 'QueryError';\n this.offset = offset;\n }\n}\n\n/** Guards against a pathological query fanning out over a huge corpus. */\nexport const DEFAULT_MATCH_LIMIT = 10_000;\n\n/* -------------------------------------------------------------------------- */\n/* Parsing */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The words that name a node type, and `null` for the ones that name any.\n *\n * A map, because a selector is typed by a person and an object answers to\n * more names than it was given: `constructor` was a node type no node has, so\n * `constructor[status=draft]` matched nothing where `construct[status=draft]`\n * was refused.\n */\nconst NODE_KINDS: ReadonlyMap<string, NodeKind | null> = new Map<string, NodeKind | null>([\n ['document', 'document'],\n ['documents', 'document'],\n ['doc', 'document'],\n ['docs', 'document'],\n ['item', 'item'],\n ['items', 'item'],\n ['node', null],\n ['nodes', null],\n ['any', null],\n ['*', null],\n]);\n\n/** Compiles a selector string into a {@link QuerySpec}. */\nexport function parseQuery(source: string): QuerySpec {\n const parser = new Parser(source);\n const start = parser.parseNodeMatcher();\n const steps: StepSpec[] = [];\n parser.skipSpace();\n while (!parser.atEnd()) {\n steps.push(parser.parseStep());\n parser.skipSpace();\n }\n return { start, steps };\n}\n\nclass Parser {\n private readonly source: string;\n private position = 0;\n\n constructor(source: string) {\n this.source = source;\n }\n\n atEnd(): boolean {\n return this.position >= this.source.length;\n }\n\n skipSpace(): void {\n // The bound decides nothing: past the end the character is `undefined`,\n // which `test` reads as the word \"undefined\" and rejects. It is kept so the\n // loop does not lean on that.\n while (this.position < this.source.length && /\\s/.test(this.source[this.position] as string)) this.position += 1;\n }\n\n parseNodeMatcher(): NodeMatcher {\n this.skipSpace();\n let kind: NodeKind | null = null;\n const word = /^[A-Za-z]+|^\\*/.exec(this.source.slice(this.position));\n if (word) {\n const text = (word[0] as string).toLowerCase();\n if (!NODE_KINDS.has(text)) {\n throw new QueryError(\n `unknown node type \"${word[0]}\", expected one of: document, item, * (any)`,\n this.position,\n );\n }\n kind = NODE_KINDS.get(text) as NodeKind | null;\n this.position += (word[0] as string).length;\n } else if (this.source[this.position] !== '[') {\n throw new QueryError('expected a node type (document, item or *) or a [predicate]', this.position);\n }\n\n const predicates: Predicate[] = [];\n while (this.source[this.position] === '[') predicates.push(this.parsePredicate());\n return { kind, predicates };\n }\n\n private parsePredicate(): Predicate {\n this.position += 1;\n const keyMatch = /^[A-Za-z_][A-Za-z0-9_.:-]*/.exec(this.source.slice(this.position));\n if (!keyMatch) throw new QueryError('expected an attribute name after \"[\"', this.position);\n const key = (keyMatch[0] as string).toLowerCase();\n this.position += (keyMatch[0] as string).length;\n\n if (this.source[this.position] === ']') {\n this.position += 1;\n return { key, operator: 'exists', value: '' };\n }\n\n const operatorMatch = /^(!=|\\^=|\\$=|\\*=|~=|=)/.exec(this.source.slice(this.position));\n if (!operatorMatch) {\n throw new QueryError(\n `expected an operator (=, !=, ^=, $=, *=, ~=) or \"]\" after \"${key}\"`,\n this.position,\n );\n }\n const operator = operatorMatch[0] as Operator;\n this.position += operator.length;\n\n const valueStart = this.position;\n const value = this.parseValue();\n if (this.source[this.position] !== ']') throw new QueryError('expected \"]\" to close the predicate', this.position);\n this.position += 1;\n // A pattern is checked here rather than where it runs, because here is the\n // only place that knows where in the selector it was written. It used to be\n // compiled on first use and an unparseable one silently matched nothing,\n // which is the same silence a misspelled relation would have produced if\n // this grammar tolerated one. See ADR-0017.\n if (operator === '~=') {\n try {\n pattern(value);\n } catch (error) {\n if (!(error instanceof RegexError)) throw error;\n throw new QueryError(error.message, valueStart + error.offset + (quoted(this.source[valueStart]) ? 1 : 0));\n }\n }\n return { key, operator, value };\n }\n\n private parseValue(): string {\n const quote = this.source[this.position];\n if (quote === '\"' || quote === \"'\") {\n this.position += 1;\n let out = '';\n while (this.position < this.source.length && this.source[this.position] !== quote) {\n if (this.source[this.position] === '\\\\') this.position += 1;\n // `?? ''` meets only a backslash at the very end, and the value it\n // builds then is thrown away with the unterminated quote below.\n out += this.source[this.position] ?? '';\n this.position += 1;\n }\n if (this.source[this.position] !== quote) throw new QueryError('unterminated quoted value', this.position);\n this.position += 1;\n return out;\n }\n // The anchor decides nothing, since a starred class matches the empty\n // string where the search starts; it says where the value begins.\n const match = /^[^\\]\\s]*/.exec(this.source.slice(this.position));\n const value = (match?.[0] ?? '') as string;\n this.position += value.length;\n return value;\n }\n\n parseStep(): StepSpec {\n const rest = this.source.slice(this.position);\n // The forward form is lazy because its terminator is two characters (`->`),\n // which cannot be confused with the hyphen inside `delegates-to`. The\n // backward terminator is a single `-`, so it must be greedy and backtrack:\n // matching lazily would read `<-delegates-to-` as the relation `delegates`.\n const forward = /^(-|=)([A-Za-z,*-]*?)(->|=>)/.exec(rest);\n const backward = /^(<-|<=)([A-Za-z,*-]*)(-|=)(?=\\s|$|[A-Za-z*[])/.exec(rest);\n\n // Both are anchored where the step starts and open with different\n // characters, so at most one of them matches.\n if (forward) {\n const transitive = (forward[1] as string) === '=';\n const closing = forward[3] as string;\n if ((closing === '=>') !== transitive) {\n throw new QueryError('mismatched arrow: use -kind-> for one hop or =kind=> for transitive', this.position);\n }\n const kinds = this.parseKinds(forward[2] as string, this.position + 1);\n this.position += (forward[0] as string).length;\n return { direction: 'out', kinds, transitive, node: this.parseNodeMatcher() };\n }\n\n if (backward) {\n const transitive = (backward[1] as string) === '<=';\n const closing = backward[3] as string;\n if ((closing === '=') !== transitive) {\n throw new QueryError('mismatched arrow: use <-kind- for one hop or <=kind= for transitive', this.position);\n }\n const kinds = this.parseKinds(backward[2] as string, this.position + 2);\n this.position += (backward[0] as string).length;\n return { direction: 'in', kinds, transitive, node: this.parseNodeMatcher() };\n }\n\n throw new QueryError(\n 'expected a relation step such as -delegates-to->, <-assumes- or =supersedes=>',\n this.position,\n );\n }\n\n /**\n * Reads the relation list between a step's arrows.\n *\n * Nothing is trimmed, because the step patterns admit no whitespace inside\n * an arrow. An empty list is not a special case either: it splits into one\n * empty name, which is skipped, and no names at all means any relation.\n */\n private parseKinds(raw: string, offset: number): readonly EdgeKind[] | null {\n if (raw === '*') return null;\n const kinds: EdgeKind[] = [];\n for (const part of raw.split(',')) {\n const name = part.toLowerCase();\n if (name.length === 0) continue;\n if (!(EDGE_KINDS as readonly string[]).includes(name)) {\n throw new QueryError(`unknown relation \"${name}\", expected one of: ${EDGE_KINDS.join(', ')}`, offset);\n }\n kinds.push(name as EdgeKind);\n }\n // `null` rather than an empty list, which the graph would read the same\n // way: the spec says \"any relation\" in the form its type documents.\n return kinds.length > 0 ? kinds : null;\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Attributes */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Every attribute key a node can answer to, excluding the open `fm.` namespace.\n *\n * Selectors do not validate their keys - an unknown one simply matches nothing,\n * which is the forgiving reading a query typed at a prompt wants. A message\n * template is the opposite case: `{1.phse}` would render as an empty string in\n * a diagnostic somebody has to act on, silently and forever. So the list is\n * published here, next to the switch it mirrors, for the one caller that needs\n * to be strict. See ADR-0016.\n */\nexport const SELECTOR_KEYS: readonly string[] = Object.freeze([\n 'alias',\n 'body',\n 'conflicted',\n 'disposition',\n 'document',\n 'evidence',\n 'file',\n 'id',\n 'kind',\n 'line',\n 'openness',\n 'path',\n 'phase',\n 'receptivity',\n 'section',\n 'state',\n 'status',\n 'text',\n 'title',\n]);\n\n/**\n * The values a predicate key sees on a node.\n *\n * Multi-valued keys (`alias`, `section`) match when *any* value matches, which\n * is what makes `[section=Open Questions]` read the way people expect.\n */\nexport function attributesOf(node: SpecNode, key: string, graph?: SpecGraph): string[] {\n switch (key) {\n case 'id':\n return [node.id];\n case 'kind':\n return [node.kind];\n case 'title':\n return [node.title];\n case 'file':\n return [node.at.file];\n case 'line':\n return [String(node.at.span.start.line)];\n case 'document':\n return [node.kind === 'item' ? node.document : node.id];\n }\n\n if (node.kind === 'document') {\n switch (key) {\n case 'path':\n return [node.path];\n case 'phase':\n return [node.phase];\n case 'status':\n return node.rawStatus === null ? [] : [node.rawStatus];\n case 'receptivity':\n return [receptivityOf(node.phase)];\n case 'alias':\n return [...node.aliases];\n }\n if (key.startsWith('fm.')) {\n // Its own keys only: every object answers to `constructor`, and no\n // document's front matter said so.\n const name = key.slice(3);\n if (!Object.hasOwn(node.frontMatter, name)) return [];\n const value = node.frontMatter[name] as string | readonly string[];\n return typeof value === 'string' ? [value] : [...value];\n }\n return [];\n }\n\n // An item inherits its document's lifecycle. Without this, the two rules that\n // matter most could not be written as queries at all, because the question\n // they ask - \"is the document holding this obligation still open?\" - is about\n // the owner, not the item.\n if (key === 'phase' || key === 'receptivity' || key === 'status' || key === 'path' || key === 'alias') {\n const owner = graph?.owningDocument(node.id);\n if (owner) return attributesOf(owner, key, graph);\n return key === 'path' ? [node.at.file] : [];\n }\n\n switch (key) {\n case 'state':\n case 'disposition':\n return [node.disposition];\n case 'openness':\n return [node.openness];\n case 'section':\n return [...node.section];\n case 'text':\n return [node.text];\n case 'body':\n return [node.body];\n case 'evidence':\n return [node.evidence.source];\n case 'conflicted':\n return [node.conflicts.length > 0 ? 'true' : 'false'];\n default:\n return [];\n }\n}\n\nfunction testPredicate(node: SpecNode, predicate: Predicate, graph?: SpecGraph): boolean {\n const values = attributesOf(node, predicate.key, graph);\n const needle = predicate.value.toLowerCase();\n\n if (predicate.operator === 'exists') return values.some((value) => value.length > 0);\n if (predicate.operator === '!=') return !values.some((value) => value.toLowerCase() === needle);\n\n return values.some((raw) => {\n const value = raw.toLowerCase();\n switch (predicate.operator) {\n case '=':\n return value === needle;\n case '^=':\n return value.startsWith(needle);\n case '$=':\n return value.endsWith(needle);\n case '*=':\n return value.includes(needle);\n case '~=':\n return pattern(predicate.value).test(raw);\n default:\n // Unreachable: `exists` and `!=` returned above, and the type knows\n // no other operator. Narrowing does not reach into this callback.\n return false;\n }\n });\n}\n\nconst patterns = new Map<string, RegexMatcher>();\n\n/**\n * Compiles a `~=` pattern, once per distinct pattern.\n *\n * Cached because a rule runs its predicate against every node in the corpus,\n * and because compiling is the expensive half now that matching is linear.\n * The cache changes the cost and nothing else: a pattern compiled twice\n * matches what it matched once.\n */\nexport function pattern(source: string): RegexMatcher {\n const cached = patterns.get(source);\n if (cached) return cached;\n const compiled = compileRegex(source);\n patterns.set(source, compiled);\n return compiled;\n}\n\nfunction quoted(char: string | undefined): boolean {\n return char === '\"' || char === \"'\";\n}\n\n/** True when a node satisfies a matcher. */\nexport function matches(node: SpecNode, matcher: NodeMatcher, graph?: SpecGraph): boolean {\n if (matcher.kind !== null && node.kind !== matcher.kind) return false;\n return matcher.predicates.every((predicate) => testPredicate(node, predicate, graph));\n}\n\n/* -------------------------------------------------------------------------- */\n/* Execution */\n/* -------------------------------------------------------------------------- */\n\nexport interface ExecuteOptions {\n /**\n * Cap on the paths produced by each traversal step.\n *\n * It bounds *expansion*, not the initial selection: a query with no steps\n * returns every matching node. That asymmetry is deliberate. The limit exists\n * so a query across a dense graph cannot fan out unboundedly, and the rules\n * run through this engine - truncating the set of nodes a rule starts from\n * would silently drop findings, whereas truncating a runaway expansion only\n * ever drops paths that were already beyond reading.\n */\n readonly limit?: number | undefined;\n /**\n * Whether a step may stay inside one document.\n *\n * Off by default for reflexive edges: a document that links to itself is a\n * formatting quirk, not a relationship, and letting those through turns every\n * table of contents into a finding.\n */\n readonly allowReflexive?: boolean | undefined;\n}\n\n/** Runs a compiled query and returns every matching path. */\nexport function execute(graph: SpecGraph, spec: QuerySpec, options: ExecuteOptions = {}): Match[] {\n const limit = options.limit ?? DEFAULT_MATCH_LIMIT;\n const allowReflexive = options.allowReflexive ?? false;\n\n let frontier: Match[] = [];\n for (const node of graph.nodes.values()) {\n if (matches(node, spec.start, graph)) frontier.push({ nodes: [node], edges: [] });\n }\n\n for (const step of spec.steps) {\n const next: Match[] = [];\n const seen = new Set<string>();\n\n for (const match of frontier) {\n const tail = match.nodes[match.nodes.length - 1] as SpecNode;\n for (const { node, path } of expand(graph, tail, step, allowReflexive)) {\n if (!matches(node, step.node, graph)) continue;\n const key = `${match.nodes.map((n) => n.id).join('>')}>${node.id}`;\n if (seen.has(key)) continue;\n seen.add(key);\n next.push({ nodes: [...match.nodes, node], edges: [...match.edges, ...path] });\n if (next.length >= limit) break;\n }\n if (next.length >= limit) break;\n }\n\n frontier = next;\n // An empty frontier stays empty through every later step; this only stops\n // walking them.\n if (frontier.length === 0) break;\n }\n\n return frontier;\n}\n\ninterface Expansion {\n readonly node: SpecNode;\n readonly path: readonly Edge[];\n}\n\n// `buildGraph` drops every edge that names an unknown node, so the `if (node)`\n// guards below never skip anything in a graph it built. They stand for a\n// `SpecGraph` built some other way.\nfunction expand(graph: SpecGraph, from: SpecNode, step: StepSpec, allowReflexive: boolean): Expansion[] {\n const kinds = step.kinds ?? [];\n const out: Expansion[] = [];\n\n if (!step.transitive) {\n const edges = step.direction === 'out' ? graph.out(from.id, kinds) : graph.in(from.id, kinds);\n for (const edge of edges) {\n if (!allowReflexive && edge.reflexive) continue;\n const targetId = step.direction === 'out' ? edge.to : edge.from;\n const node = graph.node(targetId);\n if (node) out.push({ node, path: [edge] });\n }\n return out;\n }\n\n // Transitive steps take the shortest path to each reachable node, which keeps\n // the result deterministic and the reported evidence minimal.\n const reached =\n step.direction === 'out'\n ? graph.reach(from.id, kinds)\n : reachIncoming(graph, from.id, kinds);\n\n for (const [id, path] of reached) {\n if (!allowReflexive && path.every((edge) => edge.reflexive)) continue;\n const node = graph.node(id);\n if (node) out.push({ node, path });\n }\n return out;\n}\n\nfunction reachIncoming(graph: SpecGraph, id: string, kinds: readonly EdgeKind[]): Map<string, readonly Edge[]> {\n const paths = new Map<string, readonly Edge[]>();\n const pathTo = new Map<string, readonly Edge[]>([[id, []]]);\n const queue: string[] = [id];\n\n while (queue.length > 0) {\n const current = queue.shift() as string;\n const prefix = pathTo.get(current) as readonly Edge[];\n for (const edge of graph.in(current, kinds)) {\n if (pathTo.has(edge.from) && edge.from !== id) continue;\n const path = [...prefix, edge];\n if (edge.from === id) {\n if (!paths.has(id)) paths.set(id, path);\n continue;\n }\n pathTo.set(edge.from, path);\n paths.set(edge.from, path);\n queue.push(edge.from);\n }\n }\n return paths;\n}\n\n/** Parses and runs a selector in one call. */\nexport function query(graph: SpecGraph, selector: string, options?: ExecuteOptions): Match[] {\n return execute(graph, parseQuery(selector), options);\n}\n\n/**\n * Renders a match the way the selector reads, for `spec-graph query`.\n *\n * Every edge is written in the direction it was walked - `A -kind-> B`\n * forwards, `A <-kind- B` backwards - and names the node it arrives at, so a\n * transitive step shows each document it passed through. Reading the nodes off\n * `match.nodes` instead printed the end of a transitive path in its middle, and\n * a backward step as a relation pointing the other way.\n */\nexport function renderMatch(match: Match): string {\n let at = (match.nodes[0] as SpecNode).id;\n const parts: string[] = [at];\n for (const edge of match.edges) {\n const forwards = edge.from === at;\n at = forwards ? edge.to : edge.from;\n parts.push(forwards ? `-${edge.kind}->` : `<-${edge.kind}-`, at);\n }\n return parts.join(' ');\n}\n"]}
|
|
1
|
+
{"version":3,"file":"select.js","sourceRoot":"","sources":["../src/select.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The selector language.\n *\n * Rules and users ask the graph the same kinds of question, so they use the same\n * machinery. Every built-in diagnostic is a path query plus a message; anything\n * a rule can find, `spec-graph query` can find too, which means a team can\n * express a convention spec-graph never anticipated without writing a plugin.\n *\n * ```text\n * item[openness=open] -delegates-to-> document[phase=retired]\n * document[phase=active] -assumes,depends-on-> document[phase=retired]\n * document =supersedes=> document[phase=active]\n * item[state=obviated] <-assumes- *\n * *[path^=docs/adr] -blocked-by-> item[openness=open]\n * ```\n *\n * A query evaluates to **paths**, not endpoints. A rule that has the whole path\n * can say \"ADR-0004 line 31 delegates this to ADR-0002, which was retired in\n * March\" instead of naming two documents and leaving the reader to reconstruct\n * the relationship.\n */\n\nimport { receptivityOf } from './lifecycle.js';\nimport type { SpecGraph } from './graph.js';\nimport { EDGE_KINDS, type Edge, type EdgeKind, type NodeKind, type SpecNode } from './types.js';\nimport { compileRegex, RegexError, type RegexMatcher } from './vendor/spec-core/pattern/index.js';\n\n/* -------------------------------------------------------------------------- */\n/* Shapes */\n/* -------------------------------------------------------------------------- */\n\nexport type Operator = '=' | '!=' | '^=' | '$=' | '*=' | '~=' | 'exists';\n\nexport interface Predicate {\n readonly key: string;\n readonly operator: Operator;\n readonly value: string;\n}\n\nexport interface NodeMatcher {\n /** `null` matches both documents and items. */\n readonly kind: NodeKind | null;\n readonly predicates: readonly Predicate[];\n}\n\nexport interface StepSpec {\n readonly direction: 'out' | 'in';\n /** `null` matches any edge kind. */\n readonly kinds: readonly EdgeKind[] | null;\n /** Follow the relation transitively, taking the shortest path to each node. */\n readonly transitive: boolean;\n readonly node: NodeMatcher;\n}\n\nexport interface QuerySpec {\n readonly start: NodeMatcher;\n readonly steps: readonly StepSpec[];\n}\n\n/**\n * One path through the graph.\n *\n * `nodes` holds the start and the node each step matched; `edges` is the whole\n * path in order. A transitive step contributes one node and every edge it\n * walked, so the nodes it passed through are named only by those edges.\n */\nexport interface Match {\n readonly nodes: readonly SpecNode[];\n readonly edges: readonly Edge[];\n}\n\nexport class QueryError extends Error {\n /** Offset into the query string where the problem starts. */\n readonly offset: number;\n\n constructor(message: string, offset: number) {\n super(message);\n this.name = 'QueryError';\n this.offset = offset;\n }\n}\n\n/** Guards against a pathological query fanning out over a huge corpus. */\nexport const DEFAULT_MATCH_LIMIT = 10_000;\n\n/* -------------------------------------------------------------------------- */\n/* Parsing */\n/* -------------------------------------------------------------------------- */\n\n/**\n * The words that name a node type, and `null` for the ones that name any.\n *\n * A map, because a selector is typed by a person and an object answers to\n * more names than it was given: `constructor` was a node type no node has, so\n * `constructor[status=draft]` matched nothing where `construct[status=draft]`\n * was refused.\n */\nconst NODE_KINDS: ReadonlyMap<string, NodeKind | null> = new Map<string, NodeKind | null>([\n ['document', 'document'],\n ['documents', 'document'],\n ['doc', 'document'],\n ['docs', 'document'],\n ['item', 'item'],\n ['items', 'item'],\n ['node', null],\n ['nodes', null],\n ['any', null],\n ['*', null],\n]);\n\n/** Compiles a selector string into a {@link QuerySpec}. */\nexport function parseQuery(source: string): QuerySpec {\n const parser = new Parser(source);\n const start = parser.parseNodeMatcher();\n const steps: StepSpec[] = [];\n parser.skipSpace();\n while (!parser.atEnd()) {\n steps.push(parser.parseStep());\n parser.skipSpace();\n }\n return { start, steps };\n}\n\nclass Parser {\n private readonly source: string;\n private position = 0;\n\n constructor(source: string) {\n this.source = source;\n }\n\n atEnd(): boolean {\n return this.position >= this.source.length;\n }\n\n skipSpace(): void {\n // The bound decides nothing: past the end the character is `undefined`,\n // which `test` reads as the word \"undefined\" and rejects. It is kept so the\n // loop does not lean on that.\n while (this.position < this.source.length && /\\s/.test(this.source[this.position] as string)) this.position += 1;\n }\n\n parseNodeMatcher(): NodeMatcher {\n this.skipSpace();\n let kind: NodeKind | null = null;\n const word = /^[A-Za-z]+|^\\*/.exec(this.source.slice(this.position));\n if (word) {\n const text = (word[0] as string).toLowerCase();\n if (!NODE_KINDS.has(text)) {\n throw new QueryError(\n `unknown node type \"${word[0]}\", expected one of: document, item, * (any)`,\n this.position,\n );\n }\n kind = NODE_KINDS.get(text) as NodeKind | null;\n this.position += (word[0] as string).length;\n } else if (this.source[this.position] !== '[') {\n throw new QueryError('expected a node type (document, item or *) or a [predicate]', this.position);\n }\n\n const predicates: Predicate[] = [];\n while (this.source[this.position] === '[') predicates.push(this.parsePredicate());\n return { kind, predicates };\n }\n\n private parsePredicate(): Predicate {\n this.position += 1;\n const keyMatch = /^[A-Za-z_][A-Za-z0-9_.:-]*/.exec(this.source.slice(this.position));\n if (!keyMatch) throw new QueryError('expected an attribute name after \"[\"', this.position);\n const key = (keyMatch[0] as string).toLowerCase();\n this.position += (keyMatch[0] as string).length;\n\n if (this.source[this.position] === ']') {\n this.position += 1;\n return { key, operator: 'exists', value: '' };\n }\n\n const operatorMatch = /^(!=|\\^=|\\$=|\\*=|~=|=)/.exec(this.source.slice(this.position));\n if (!operatorMatch) {\n throw new QueryError(\n `expected an operator (=, !=, ^=, $=, *=, ~=) or \"]\" after \"${key}\"`,\n this.position,\n );\n }\n const operator = operatorMatch[0] as Operator;\n this.position += operator.length;\n\n const valueStart = this.position;\n const value = this.parseValue();\n if (this.source[this.position] !== ']') throw new QueryError('expected \"]\" to close the predicate', this.position);\n this.position += 1;\n // A pattern is checked here rather than where it runs, because here is the\n // only place that knows where in the selector it was written. It used to be\n // compiled on first use and an unparseable one silently matched nothing,\n // which is the same silence a misspelled relation would have produced if\n // this grammar tolerated one. See ADR-0017.\n if (operator === '~=') {\n try {\n pattern(value);\n } catch (error) {\n if (!(error instanceof RegexError)) throw error;\n throw new QueryError(error.message, valueStart + error.offset + (quoted(this.source[valueStart]) ? 1 : 0));\n }\n }\n return { key, operator, value };\n }\n\n private parseValue(): string {\n const quote = this.source[this.position];\n if (quote === '\"' || quote === \"'\") {\n this.position += 1;\n let out = '';\n while (this.position < this.source.length && this.source[this.position] !== quote) {\n if (this.source[this.position] === '\\\\') this.position += 1;\n // `?? ''` meets only a backslash at the very end, and the value it\n // builds then is thrown away with the unterminated quote below.\n out += this.source[this.position] ?? '';\n this.position += 1;\n }\n if (this.source[this.position] !== quote) throw new QueryError('unterminated quoted value', this.position);\n this.position += 1;\n return out;\n }\n // The anchor decides nothing, since a starred class matches the empty\n // string where the search starts; it says where the value begins. For the\n // same reason the search never misses, and there is nothing to fall back\n // from.\n const value = /^[^\\]\\s]*/.exec(this.source.slice(this.position))![0];\n this.position += value.length;\n return value;\n }\n\n parseStep(): StepSpec {\n const rest = this.source.slice(this.position);\n // The forward form is lazy because its terminator is two characters (`->`),\n // which cannot be confused with the hyphen inside `delegates-to`. The\n // backward terminator is a single `-`, so it must be greedy and backtrack:\n // matching lazily would read `<-delegates-to-` as the relation `delegates`.\n const forward = /^(-|=)([A-Za-z,*-]*?)(->|=>)/.exec(rest);\n const backward = /^(<-|<=)([A-Za-z,*-]*)(-|=)(?=\\s|$|[A-Za-z*[])/.exec(rest);\n\n // Both are anchored where the step starts and open with different\n // characters, so at most one of them matches.\n if (forward) {\n const transitive = (forward[1] as string) === '=';\n const closing = forward[3] as string;\n if ((closing === '=>') !== transitive) {\n throw new QueryError('mismatched arrow: use -kind-> for one hop or =kind=> for transitive', this.position);\n }\n const kinds = this.parseKinds(forward[2] as string, this.position + 1);\n this.position += (forward[0] as string).length;\n return { direction: 'out', kinds, transitive, node: this.parseNodeMatcher() };\n }\n\n if (backward) {\n const transitive = (backward[1] as string) === '<=';\n const closing = backward[3] as string;\n if ((closing === '=') !== transitive) {\n throw new QueryError('mismatched arrow: use <-kind- for one hop or <=kind= for transitive', this.position);\n }\n const kinds = this.parseKinds(backward[2] as string, this.position + 2);\n this.position += (backward[0] as string).length;\n return { direction: 'in', kinds, transitive, node: this.parseNodeMatcher() };\n }\n\n throw new QueryError(\n 'expected a relation step such as -delegates-to->, <-assumes- or =supersedes=>',\n this.position,\n );\n }\n\n /**\n * Reads the relation list between a step's arrows.\n *\n * Nothing is trimmed, because the step patterns admit no whitespace inside\n * an arrow. An empty list is not a special case either: it splits into one\n * empty name, which is skipped, and no names at all means any relation.\n */\n private parseKinds(raw: string, offset: number): readonly EdgeKind[] | null {\n if (raw === '*') return null;\n const kinds: EdgeKind[] = [];\n for (const part of raw.split(',')) {\n const name = part.toLowerCase();\n if (name.length === 0) continue;\n if (!(EDGE_KINDS as readonly string[]).includes(name)) {\n throw new QueryError(`unknown relation \"${name}\", expected one of: ${EDGE_KINDS.join(', ')}`, offset);\n }\n kinds.push(name as EdgeKind);\n }\n // `null` rather than an empty list, which the graph would read the same\n // way: the spec says \"any relation\" in the form its type documents.\n return kinds.length > 0 ? kinds : null;\n }\n}\n\n/* -------------------------------------------------------------------------- */\n/* Attributes */\n/* -------------------------------------------------------------------------- */\n\n/**\n * Every attribute key a node can answer to, excluding the open `fm.` namespace.\n *\n * Selectors do not validate their keys - an unknown one simply matches nothing,\n * which is the forgiving reading a query typed at a prompt wants. A message\n * template is the opposite case: `{1.phse}` would render as an empty string in\n * a diagnostic somebody has to act on, silently and forever. So the list is\n * published here, next to the switch it mirrors, for the one caller that needs\n * to be strict. See ADR-0016.\n */\nexport const SELECTOR_KEYS: readonly string[] = Object.freeze([\n 'alias',\n 'body',\n 'conflicted',\n 'disposition',\n 'document',\n 'evidence',\n 'file',\n 'id',\n 'kind',\n 'line',\n 'openness',\n 'path',\n 'phase',\n 'receptivity',\n 'section',\n 'state',\n 'status',\n 'text',\n 'title',\n]);\n\n/**\n * The values a predicate key sees on a node.\n *\n * Multi-valued keys (`alias`, `section`) match when *any* value matches, which\n * is what makes `[section=Open Questions]` read the way people expect.\n */\nexport function attributesOf(node: SpecNode, key: string, graph?: SpecGraph): string[] {\n switch (key) {\n case 'id':\n return [node.id];\n case 'kind':\n return [node.kind];\n case 'title':\n return [node.title];\n case 'file':\n return [node.at.file];\n case 'line':\n return [String(node.at.span.start.line)];\n case 'document':\n return [node.kind === 'item' ? node.document : node.id];\n }\n\n if (node.kind === 'document') {\n switch (key) {\n case 'path':\n return [node.path];\n case 'phase':\n return [node.phase];\n case 'status':\n return node.rawStatus === null ? [] : [node.rawStatus];\n case 'receptivity':\n return [receptivityOf(node.phase)];\n case 'alias':\n return [...node.aliases];\n }\n if (key.startsWith('fm.')) {\n // Its own keys only: every object answers to `constructor`, and no\n // document's front matter said so.\n const name = key.slice(3);\n if (!Object.hasOwn(node.frontMatter, name)) return [];\n const value = node.frontMatter[name] as string | readonly string[];\n return typeof value === 'string' ? [value] : [...value];\n }\n return [];\n }\n\n // An item inherits its document's lifecycle. Without this, the two rules that\n // matter most could not be written as queries at all, because the question\n // they ask - \"is the document holding this obligation still open?\" - is about\n // the owner, not the item.\n if (key === 'phase' || key === 'receptivity' || key === 'status' || key === 'path' || key === 'alias') {\n const owner = graph?.owningDocument(node.id);\n if (owner) return attributesOf(owner, key, graph);\n return key === 'path' ? [node.at.file] : [];\n }\n\n switch (key) {\n case 'state':\n case 'disposition':\n return [node.disposition];\n case 'openness':\n return [node.openness];\n case 'section':\n return [...node.section];\n case 'text':\n return [node.text];\n case 'body':\n return [node.body];\n case 'evidence':\n return [node.evidence.source];\n case 'conflicted':\n return [node.conflicts.length > 0 ? 'true' : 'false'];\n default:\n return [];\n }\n}\n\nfunction testPredicate(node: SpecNode, predicate: Predicate, graph?: SpecGraph): boolean {\n const values = attributesOf(node, predicate.key, graph);\n const needle = predicate.value.toLowerCase();\n\n if (predicate.operator === 'exists') return values.some((value) => value.length > 0);\n if (predicate.operator === '!=') return !values.some((value) => value.toLowerCase() === needle);\n\n return values.some((raw) => {\n const value = raw.toLowerCase();\n switch (predicate.operator) {\n case '=':\n return value === needle;\n case '^=':\n return value.startsWith(needle);\n case '$=':\n return value.endsWith(needle);\n case '*=':\n return value.includes(needle);\n case '~=':\n return pattern(predicate.value).test(raw);\n default:\n // Unreachable: `exists` and `!=` returned above, and the type knows\n // no other operator. Narrowing does not reach into this callback.\n return false;\n }\n });\n}\n\nconst patterns = new Map<string, RegexMatcher>();\n\n/**\n * Compiles a `~=` pattern, once per distinct pattern.\n *\n * Cached because a rule runs its predicate against every node in the corpus,\n * and because compiling is the expensive half now that matching is linear.\n * The cache changes the cost and nothing else: a pattern compiled twice\n * matches what it matched once.\n */\nexport function pattern(source: string): RegexMatcher {\n const cached = patterns.get(source);\n if (cached) return cached;\n const compiled = compileRegex(source);\n patterns.set(source, compiled);\n return compiled;\n}\n\nfunction quoted(char: string | undefined): boolean {\n return char === '\"' || char === \"'\";\n}\n\n/** True when a node satisfies a matcher. */\nexport function matches(node: SpecNode, matcher: NodeMatcher, graph?: SpecGraph): boolean {\n if (matcher.kind !== null && node.kind !== matcher.kind) return false;\n return matcher.predicates.every((predicate) => testPredicate(node, predicate, graph));\n}\n\n/* -------------------------------------------------------------------------- */\n/* Execution */\n/* -------------------------------------------------------------------------- */\n\nexport interface ExecuteOptions {\n /**\n * Cap on the paths produced by each traversal step.\n *\n * It bounds *expansion*, not the initial selection: a query with no steps\n * returns every matching node. That asymmetry is deliberate. The limit exists\n * so a query across a dense graph cannot fan out unboundedly, and the rules\n * run through this engine - truncating the set of nodes a rule starts from\n * would silently drop findings, whereas truncating a runaway expansion only\n * ever drops paths that were already beyond reading.\n */\n readonly limit?: number | undefined;\n /**\n * Whether a step may stay inside one document.\n *\n * Off by default for reflexive edges: a document that links to itself is a\n * formatting quirk, not a relationship, and letting those through turns every\n * table of contents into a finding.\n */\n readonly allowReflexive?: boolean | undefined;\n}\n\n/** Runs a compiled query and returns every matching path. */\nexport function execute(graph: SpecGraph, spec: QuerySpec, options: ExecuteOptions = {}): Match[] {\n const limit = options.limit ?? DEFAULT_MATCH_LIMIT;\n const allowReflexive = options.allowReflexive ?? false;\n\n let frontier: Match[] = [];\n for (const node of graph.nodes.values()) {\n if (matches(node, spec.start, graph)) frontier.push({ nodes: [node], edges: [] });\n }\n\n for (const step of spec.steps) {\n const next: Match[] = [];\n const seen = new Set<string>();\n\n for (const match of frontier) {\n const tail = match.nodes[match.nodes.length - 1]!;\n for (const { node, path } of expand(graph, tail, step, allowReflexive)) {\n if (!matches(node, step.node, graph)) continue;\n const key = `${match.nodes.map((n) => n.id).join('>')}>${node.id}`;\n if (seen.has(key)) continue;\n seen.add(key);\n next.push({ nodes: [...match.nodes, node], edges: [...match.edges, ...path] });\n if (next.length >= limit) break;\n }\n if (next.length >= limit) break;\n }\n\n frontier = next;\n // An empty frontier stays empty through every later step; this only stops\n // walking them.\n if (frontier.length === 0) break;\n }\n\n return frontier;\n}\n\ninterface Expansion {\n readonly node: SpecNode;\n readonly path: readonly Edge[];\n}\n\n// `buildGraph` drops every edge that names an unknown node, so the `if (node)`\n// guards below never skip anything in a graph it built. They stand for a\n// `SpecGraph` built some other way.\nfunction expand(graph: SpecGraph, from: SpecNode, step: StepSpec, allowReflexive: boolean): Expansion[] {\n const kinds = step.kinds ?? [];\n const out: Expansion[] = [];\n\n if (!step.transitive) {\n const edges = step.direction === 'out' ? graph.out(from.id, kinds) : graph.in(from.id, kinds);\n for (const edge of edges) {\n if (!allowReflexive && edge.reflexive) continue;\n const targetId = step.direction === 'out' ? edge.to : edge.from;\n const node = graph.node(targetId);\n if (node) out.push({ node, path: [edge] });\n }\n return out;\n }\n\n // Transitive steps take the shortest path to each reachable node, which keeps\n // the result deterministic and the reported evidence minimal.\n const reached =\n step.direction === 'out'\n ? graph.reach(from.id, kinds)\n : reachIncoming(graph, from.id, kinds);\n\n for (const [id, path] of reached) {\n if (!allowReflexive && path.every((edge) => edge.reflexive)) continue;\n const node = graph.node(id);\n if (node) out.push({ node, path });\n }\n return out;\n}\n\nfunction reachIncoming(graph: SpecGraph, id: string, kinds: readonly EdgeKind[]): Map<string, readonly Edge[]> {\n const paths = new Map<string, readonly Edge[]>();\n const pathTo = new Map<string, readonly Edge[]>([[id, []]]);\n const queue: string[] = [id];\n\n while (queue.length > 0) {\n const current = queue.shift() as string;\n const prefix = pathTo.get(current) as readonly Edge[];\n for (const edge of graph.in(current, kinds)) {\n if (pathTo.has(edge.from) && edge.from !== id) continue;\n const path = [...prefix, edge];\n if (edge.from === id) {\n if (!paths.has(id)) paths.set(id, path);\n continue;\n }\n pathTo.set(edge.from, path);\n paths.set(edge.from, path);\n queue.push(edge.from);\n }\n }\n return paths;\n}\n\n/** Parses and runs a selector in one call. */\nexport function query(graph: SpecGraph, selector: string, options?: ExecuteOptions): Match[] {\n return execute(graph, parseQuery(selector), options);\n}\n\n/**\n * Renders a match the way the selector reads, for `spec-graph query`.\n *\n * Every edge is written in the direction it was walked - `A -kind-> B`\n * forwards, `A <-kind- B` backwards - and names the node it arrives at, so a\n * transitive step shows each document it passed through. Reading the nodes off\n * `match.nodes` instead printed the end of a transitive path in its middle, and\n * a backward step as a relation pointing the other way.\n */\nexport function renderMatch(match: Match): string {\n let at = (match.nodes[0] as SpecNode).id;\n const parts: string[] = [at];\n for (const edge of match.edges) {\n const forwards = edge.from === at;\n at = forwards ? edge.to : edge.from;\n parts.push(forwards ? `-${edge.kind}->` : `<-${edge.kind}-`, at);\n }\n return parts.join(' ');\n}\n"]}
|
package/package.json
CHANGED