patram 0.7.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/bin/patram.js +2 -2
  2. package/lib/{parse-cli-color-options.js → cli/color-options.js} +2 -2
  3. package/lib/cli/command-helpers.js +35 -0
  4. package/lib/cli/commands/check.js +73 -0
  5. package/lib/cli/commands/fields.js +57 -0
  6. package/lib/cli/commands/queries.js +41 -0
  7. package/lib/cli/commands/query.js +239 -0
  8. package/lib/cli/commands/refs.js +72 -0
  9. package/lib/cli/commands/show.js +58 -0
  10. package/lib/{cli-help-metadata.js → cli/help-metadata.js} +54 -15
  11. package/lib/cli/main.js +76 -0
  12. package/lib/{parse-cli-arguments-helpers.js → cli/parse-arguments-helpers.js} +18 -11
  13. package/lib/{parse-cli-arguments.js → cli/parse-arguments.js} +12 -12
  14. package/lib/{parse-cli-query-pagination.js → cli/query-pagination.js} +2 -2
  15. package/lib/{render-cli-help.js → cli/render-help.js} +4 -4
  16. package/lib/{resolve-output-mode.js → cli/resolve-output-mode.js} +2 -2
  17. package/lib/cli/test-helpers.js +30 -0
  18. package/lib/config/defaults.d.ts +10 -0
  19. package/lib/config/defaults.js +80 -0
  20. package/lib/config/load-patram-config.d.ts +76 -0
  21. package/lib/config/load-patram-config.js +315 -0
  22. package/lib/config/load-patram-config.types.d.ts +45 -0
  23. package/lib/{patram-config.d.ts → config/patram-config.d.ts} +31 -31
  24. package/lib/{patram-config.js → config/patram-config.js} +3 -3
  25. package/lib/{patram-config.types.d.ts → config/patram-config.types.d.ts} +1 -1
  26. package/lib/{resolve-patram-graph-config.d.ts → config/resolve-patram-graph-config.d.ts} +2 -2
  27. package/lib/{resolve-patram-graph-config.js → config/resolve-patram-graph-config.js} +3 -3
  28. package/lib/{load-patram-config.d.ts → config/schema.d.ts} +147 -191
  29. package/lib/config/schema.js +324 -0
  30. package/lib/{source-file-defaults.d.ts → config/source-file-defaults.d.ts} +0 -1
  31. package/lib/{source-file-defaults.js → config/source-file-defaults.js} +1 -1
  32. package/lib/config/validation.d.ts +27 -0
  33. package/lib/config/validation.js +615 -0
  34. package/lib/directive-validation-test-helpers.js +1 -1
  35. package/lib/{build-graph-identity.d.ts → graph/build-graph-identity.d.ts} +2 -2
  36. package/lib/{build-graph-identity.js → graph/build-graph-identity.js} +1 -1
  37. package/lib/{build-graph.d.ts → graph/build-graph.d.ts} +3 -3
  38. package/lib/{build-graph.js → graph/build-graph.js} +17 -13
  39. package/lib/{build-graph.types.d.ts → graph/build-graph.types.d.ts} +1 -1
  40. package/lib/graph/check-directive-metadata.d.ts +23 -0
  41. package/lib/{check-directive-metadata.js → graph/check-directive-metadata.js} +7 -7
  42. package/lib/graph/check-directive-path-target.d.ts +32 -0
  43. package/lib/{check-directive-path-target.js → graph/check-directive-path-target.js} +4 -4
  44. package/lib/graph/check-directive-value.d.ts +19 -0
  45. package/lib/{check-directive-value.js → graph/check-directive-value.js} +3 -3
  46. package/lib/graph/check-graph.d.ts +29 -0
  47. package/lib/{check-graph.js → graph/check-graph.js} +6 -6
  48. package/lib/graph/directive-diagnostics.d.ts +20 -0
  49. package/lib/{directive-diagnostics.js → graph/directive-diagnostics.js} +2 -2
  50. package/lib/graph/directive-type-rules.d.ts +18 -0
  51. package/lib/{directive-type-rules.js → graph/directive-type-rules.js} +3 -3
  52. package/lib/{document-node-identity.d.ts → graph/document-node-identity.d.ts} +2 -2
  53. package/lib/{document-node-identity.js → graph/document-node-identity.js} +2 -2
  54. package/lib/graph/inspect-reverse-references.d.ts +22 -0
  55. package/lib/graph/inspect-reverse-references.js +184 -0
  56. package/lib/{load-project-graph.d.ts → graph/load-project-graph.d.ts} +10 -10
  57. package/lib/{load-project-graph.js → graph/load-project-graph.js} +12 -12
  58. package/lib/{parse-where-clause.types.d.ts → graph/parse-where-clause.types.d.ts} +1 -1
  59. package/lib/{query-graph.d.ts → graph/query/execute.d.ts} +11 -11
  60. package/lib/{query-graph.js → graph/query/execute.js} +12 -12
  61. package/lib/{query-inspection.d.ts → graph/query/inspect.d.ts} +10 -8
  62. package/lib/{query-inspection.js → graph/query/inspect.js} +16 -17
  63. package/lib/{parse-where-clause.d.ts → graph/query/parse.d.ts} +6 -6
  64. package/lib/{parse-where-clause.js → graph/query/parse.js} +2 -2
  65. package/lib/graph/query/resolve.d.ts +30 -0
  66. package/lib/{resolve-where-clause.js → graph/query/resolve.js} +1 -1
  67. package/lib/graph/reverse-reference-test-helpers.d.ts +55 -0
  68. package/lib/graph/reverse-reference-test-helpers.js +76 -0
  69. package/lib/{command-output.js → output/command-output.js} +6 -5
  70. package/lib/{derived-summary.js → output/derived-summary.js} +7 -7
  71. package/lib/output/layout-incoming-references.js +105 -0
  72. package/lib/output/layout-incoming-summary-lines.js +16 -0
  73. package/lib/{layout-stored-queries.js → output/layout-stored-queries.js} +9 -9
  74. package/lib/{list-queries.js → output/list-queries.js} +1 -1
  75. package/lib/{render-check-output.js → output/render-check-output.js} +1 -1
  76. package/lib/{render-field-discovery.js → output/render-field-discovery.js} +3 -3
  77. package/lib/output/render-output-view.js +56 -0
  78. package/lib/{render-json-output.js → output/renderers/json.js} +92 -63
  79. package/lib/{render-plain-output.js → output/renderers/plain.js} +62 -7
  80. package/lib/{render-rich-output.js → output/renderers/rich.js} +69 -8
  81. package/lib/{resolve-check-target.js → output/resolve-check-target.js} +1 -1
  82. package/lib/{render-rich-source.js → output/rich-source/render.js} +6 -6
  83. package/lib/{show-document.js → output/show-document.js} +54 -16
  84. package/lib/{render-output-view.js → output/view-model/index.js} +56 -47
  85. package/lib/{write-paged-output.js → output/write-paged-output.js} +9 -5
  86. package/lib/{claim-helpers.d.ts → parse/claim-helpers.d.ts} +2 -2
  87. package/lib/{parse-jsdoc-claims.d.ts → parse/jsdoc/parse-jsdoc-claims.d.ts} +2 -2
  88. package/lib/{parse-jsdoc-claims.js → parse/jsdoc/parse-jsdoc-claims.js} +9 -9
  89. package/lib/{parse-jsdoc-prose.d.ts → parse/jsdoc/parse-jsdoc-prose.d.ts} +1 -1
  90. package/lib/{parse-jsdoc-prose.js → parse/jsdoc/parse-jsdoc-prose.js} +1 -1
  91. package/lib/{parse-markdown-claims.d.ts → parse/markdown/parse-markdown-claims.d.ts} +3 -3
  92. package/lib/{parse-markdown-claims.js → parse/markdown/parse-markdown-claims.js} +8 -8
  93. package/lib/{parse-markdown-directives.d.ts → parse/markdown/parse-markdown-directives.d.ts} +2 -2
  94. package/lib/{parse-markdown-directives.js → parse/markdown/parse-markdown-directives.js} +3 -3
  95. package/lib/{parse-claims.d.ts → parse/parse-claims.d.ts} +4 -13
  96. package/lib/{parse-claims.js → parse/parse-claims.js} +18 -26
  97. package/lib/{parse-claims.types.d.ts → parse/parse-claims.types.d.ts} +1 -1
  98. package/lib/{tagged-fenced-block-error.d.ts → parse/tagged-fenced/tagged-fenced-block-error.d.ts} +2 -2
  99. package/lib/{tagged-fenced-block-parser.d.ts → parse/tagged-fenced/tagged-fenced-block-parser.d.ts} +3 -3
  100. package/lib/{tagged-fenced-blocks.d.ts → parse/tagged-fenced/tagged-fenced-blocks.d.ts} +7 -7
  101. package/lib/{tagged-fenced-blocks.js → parse/tagged-fenced/tagged-fenced-blocks.js} +3 -3
  102. package/lib/{parse-yaml-claims.d.ts → parse/yaml/parse-yaml-claims.d.ts} +4 -4
  103. package/lib/{parse-yaml-claims.js → parse/yaml/parse-yaml-claims.js} +22 -13
  104. package/lib/patram.d.ts +29 -28
  105. package/lib/patram.js +5 -6
  106. package/lib/{discover-fields.js → scan/discover-fields.js} +9 -8
  107. package/lib/scan/list-repo-files.d.ts +16 -0
  108. package/lib/{list-source-files.js → scan/list-repo-files.js} +2 -35
  109. package/lib/{list-source-files.d.ts → scan/list-source-files.d.ts} +4 -11
  110. package/lib/scan/list-source-files.js +45 -0
  111. package/package.json +8 -7
  112. package/lib/build-graph.types.ts +0 -27
  113. package/lib/discover-fields.types.ts +0 -52
  114. package/lib/load-patram-config.js +0 -1215
  115. package/lib/load-patram-config.types.d.ts +0 -45
  116. package/lib/load-patram-config.types.ts +0 -56
  117. package/lib/output-view.types.d.ts +0 -80
  118. package/lib/output-view.types.ts +0 -96
  119. package/lib/overlay-graph.d.ts +0 -43
  120. package/lib/overlay-graph.js +0 -191
  121. package/lib/parse-claims.types.ts +0 -41
  122. package/lib/parse-cli-arguments.types.ts +0 -69
  123. package/lib/parse-where-clause.types.ts +0 -87
  124. package/lib/patram-cli.js +0 -528
  125. package/lib/patram-config.types.ts +0 -22
  126. package/lib/tagged-fenced-blocks.types.ts +0 -38
  127. /package/lib/{format-derived-summary-row.js → output/format-derived-summary-row.js} +0 -0
  128. /package/lib/{format-node-header.js → output/format-node-header.js} +0 -0
  129. /package/lib/{format-output-item-block.js → output/format-output-item-block.js} +0 -0
  130. /package/lib/{format-output-metadata.js → output/format-output-metadata.js} +0 -0
  131. /package/lib/{claim-helpers.js → parse/claim-helpers.js} +0 -0
  132. /package/lib/{parse-jsdoc-blocks.d.ts → parse/jsdoc/parse-jsdoc-blocks.d.ts} +0 -0
  133. /package/lib/{parse-jsdoc-blocks.js → parse/jsdoc/parse-jsdoc-blocks.js} +0 -0
  134. /package/lib/{tagged-fenced-block-error.js → parse/tagged-fenced/tagged-fenced-block-error.js} +0 -0
  135. /package/lib/{tagged-fenced-block-markdown.d.ts → parse/tagged-fenced/tagged-fenced-block-markdown.d.ts} +0 -0
  136. /package/lib/{tagged-fenced-block-markdown.js → parse/tagged-fenced/tagged-fenced-block-markdown.js} +0 -0
  137. /package/lib/{tagged-fenced-block-metadata.d.ts → parse/tagged-fenced/tagged-fenced-block-metadata.d.ts} +0 -0
  138. /package/lib/{tagged-fenced-block-metadata.js → parse/tagged-fenced/tagged-fenced-block-metadata.js} +0 -0
  139. /package/lib/{tagged-fenced-block-parser.js → parse/tagged-fenced/tagged-fenced-block-parser.js} +0 -0
  140. /package/lib/{tagged-fenced-blocks.types.d.ts → parse/tagged-fenced/tagged-fenced-blocks.types.d.ts} +0 -0
@@ -1,9 +1,9 @@
1
1
  /* eslint-disable max-lines */
2
2
  /**
3
3
  * @import { BuildGraphResult, GraphEdge, GraphNode } from './build-graph.types.ts';
4
- * @import { PatramClaim } from './parse-claims.types.ts';
5
- * @import { MetadataFieldConfig } from './load-patram-config.types.ts';
6
- * @import { MappingDefinition, PatramConfig } from './patram-config.types.ts';
4
+ * @import { PatramClaim } from '../parse/parse-claims.types.ts';
5
+ * @import { MetadataFieldConfig } from '../config/load-patram-config.types.ts';
6
+ * @import { MappingDefinition, PatramConfig } from '../config/patram-config.types.ts';
7
7
  */
8
8
 
9
9
  import { posix } from 'node:path';
@@ -25,17 +25,17 @@ import {
25
25
  *
26
26
  * Kind: graph
27
27
  * Status: active
28
- * Uses Term: ../docs/reference/terms/claim.md
29
- * Uses Term: ../docs/reference/terms/document.md
30
- * Uses Term: ../docs/reference/terms/graph.md
31
- * Uses Term: ../docs/reference/terms/mapping.md
32
- * Uses Term: ../docs/reference/terms/relation.md
33
- * Tracked in: ../docs/plans/v0/source-anchor-dogfooding.md
34
- * Decided by: ../docs/decisions/graph-materialization.md
35
- * Implements: ../docs/tasks/v0/materialize-graph.md
28
+ * Uses Term: ../../docs/reference/terms/claim.md
29
+ * Uses Term: ../../docs/reference/terms/document.md
30
+ * Uses Term: ../../docs/reference/terms/graph.md
31
+ * Uses Term: ../../docs/reference/terms/mapping.md
32
+ * Uses Term: ../../docs/reference/terms/relation.md
33
+ * Tracked in: ../../docs/plans/v0/source-anchor-dogfooding.md
34
+ * Decided by: ../../docs/decisions/graph-materialization.md
35
+ * Implements: ../../docs/tasks/v0/materialize-graph.md
36
36
  * @patram
37
37
  * @see {@link ./load-project-graph.js}
38
- * @see {@link ../docs/decisions/graph-materialization.md}
38
+ * @see {@link ../../docs/decisions/graph-materialization.md}
39
39
  */
40
40
 
41
41
  const STRUCTURAL_FIELD_NAMES = new Set(['$class', '$id', '$path']);
@@ -712,8 +712,12 @@ function setSingleValueField(graph_node, field_name, field_value) {
712
712
  }
713
713
 
714
714
  if (current_value !== field_value) {
715
+ const current_value_text = Array.isArray(current_value)
716
+ ? current_value.join(', ')
717
+ : current_value;
718
+
715
719
  throw new Error(
716
- `Node "${graph_node.id}" has conflicting values for field "${field_name}": "${current_value}" and "${field_value}".`,
720
+ `Node "${graph_node.id}" has conflicting values for field "${field_name}": "${current_value_text}" and "${field_value}".`,
717
721
  );
718
722
  }
719
723
  }
@@ -1,4 +1,4 @@
1
- import type { ClaimOrigin } from './parse-claims.types.ts';
1
+ import type { ClaimOrigin } from '../parse/parse-claims.types.d.ts';
2
2
  export interface GraphNode {
3
3
  $class?: string;
4
4
  $id?: string;
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Directive and placement validation.
3
+ *
4
+ * Kind: graph
5
+ * Status: active
6
+ * Tracked in: ../../docs/plans/v0/directive-type-validation.md
7
+ * Decided by: ../../docs/decisions/directive-type-validation.md
8
+ * @see {@link ../../docs/decisions/directive-type-validation.md}
9
+ * @patram
10
+ * @see {@link ./check-graph.js}
11
+ */
12
+ /**
13
+ * @param {BuildGraphResult} graph
14
+ * @param {PatramRepoConfig} repo_config
15
+ * @param {PatramClaim[]} claims
16
+ * @param {string[]} existing_file_paths
17
+ * @returns {PatramDiagnostic[]}
18
+ */
19
+ export function checkDirectiveMetadata(graph: BuildGraphResult, repo_config: PatramRepoConfig, claims: PatramClaim[], existing_file_paths: string[]): PatramDiagnostic[];
20
+ import type { BuildGraphResult } from './build-graph.types.d.ts';
21
+ import type { PatramRepoConfig } from '../config/load-patram-config.types.d.ts';
22
+ import type { PatramClaim } from '../parse/parse-claims.types.d.ts';
23
+ import type { PatramDiagnostic } from '../config/load-patram-config.types.d.ts';
@@ -1,9 +1,9 @@
1
1
  /* eslint-disable max-lines */
2
2
  /**
3
3
  * @import { BuildGraphResult } from './build-graph.types.ts';
4
- * @import { ClassFieldRuleConfig, MetadataFieldConfig, MetadataSchemaConfig, PatramDiagnostic, PatramRepoConfig } from './load-patram-config.types.ts';
5
- * @import { PatramClaim } from './parse-claims.types.ts';
6
- * @import { MappingDefinition } from './patram-config.types.ts';
4
+ * @import { ClassFieldRuleConfig, MetadataFieldConfig, MetadataSchemaConfig, PatramDiagnostic, PatramRepoConfig } from '../config/load-patram-config.types.ts';
5
+ * @import { PatramClaim } from '../parse/parse-claims.types.ts';
6
+ * @import { MappingDefinition } from '../config/patram-config.types.ts';
7
7
  */
8
8
 
9
9
  import {
@@ -18,18 +18,18 @@ import {
18
18
  createOriginDiagnostic,
19
19
  } from './directive-diagnostics.js';
20
20
  import { formatQuotedList } from './directive-type-rules.js';
21
- import { resolvePatramGraphConfig } from './resolve-patram-graph-config.js';
21
+ import { resolvePatramGraphConfig } from '../config/resolve-patram-graph-config.js';
22
22
 
23
23
  /**
24
24
  * Directive and placement validation.
25
25
  *
26
26
  * Kind: graph
27
27
  * Status: active
28
- * Tracked in: ../docs/plans/v0/directive-type-validation.md
29
- * Decided by: ../docs/decisions/directive-type-validation.md
28
+ * Tracked in: ../../docs/plans/v0/directive-type-validation.md
29
+ * Decided by: ../../docs/decisions/directive-type-validation.md
30
+ * @see {@link ../../docs/decisions/directive-type-validation.md}
30
31
  * @patram
31
32
  * @see {@link ./check-graph.js}
32
- * @see {@link ../docs/decisions/directive-type-validation.md}
33
33
  */
34
34
 
35
35
  /**
@@ -0,0 +1,32 @@
1
+ /**
2
+ * @param {PatramClaim} claim
3
+ * @param {string} directive_name
4
+ * @param {MappingDefinition | null} mapping_definition
5
+ * @param {Exclude<DirectiveTypeConfig, { type: 'enum' }> | undefined} type_definition
6
+ * @param {Map<string, string>} document_entity_keys
7
+ * @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
8
+ * @param {Set<string>} document_paths
9
+ * @returns {PatramDiagnostic[]}
10
+ */
11
+ export function createPathExistenceDiagnostics(claim: PatramClaim, directive_name: string, mapping_definition: MappingDefinition | null, type_definition: Exclude<DirectiveTypeConfig, {
12
+ type: "enum";
13
+ }> | undefined, document_entity_keys: Map<string, string>, document_node_references: Map<string, import("./document-node-identity.js").DocumentNodeReference>, document_paths: Set<string>): PatramDiagnostic[];
14
+ /**
15
+ * @param {PatramClaim} claim
16
+ * @param {string} directive_name
17
+ * @param {Record<string, MappingDefinition>} mappings
18
+ * @param {PatramRepoConfig} repo_config
19
+ * @param {Exclude<DirectiveTypeConfig, { type: 'enum' }>} type_definition
20
+ * @param {Map<string, string>} document_entity_keys
21
+ * @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
22
+ * @param {Set<string>} document_paths
23
+ * @returns {PatramDiagnostic[]}
24
+ */
25
+ export function createPathClassDiagnostics(claim: PatramClaim, directive_name: string, mappings: Record<string, MappingDefinition>, repo_config: PatramRepoConfig, type_definition: Exclude<DirectiveTypeConfig, {
26
+ type: "enum";
27
+ }>, document_entity_keys: Map<string, string>, document_node_references: Map<string, import("./document-node-identity.js").DocumentNodeReference>, document_paths: Set<string>): PatramDiagnostic[];
28
+ import type { PatramClaim } from '../parse/parse-claims.types.d.ts';
29
+ import type { MappingDefinition } from '../config/patram-config.types.d.ts';
30
+ import type { DirectiveTypeConfig } from '../config/load-patram-config.types.d.ts';
31
+ import type { PatramDiagnostic } from '../config/load-patram-config.types.d.ts';
32
+ import type { PatramRepoConfig } from '../config/load-patram-config.types.d.ts';
@@ -1,10 +1,10 @@
1
1
  /**
2
- * @import { DirectiveTypeConfig, PatramDiagnostic, PatramRepoConfig } from './load-patram-config.types.ts';
3
- * @import { PatramClaim } from './parse-claims.types.ts';
4
- * @import { MappingDefinition } from './patram-config.types.ts';
2
+ * @import { DirectiveTypeConfig, PatramDiagnostic, PatramRepoConfig } from '../config/load-patram-config.types.ts';
3
+ * @import { PatramClaim } from '../parse/parse-claims.types.ts';
4
+ * @import { MappingDefinition } from '../config/patram-config.types.ts';
5
5
  */
6
6
 
7
- import { isPathLikeTarget } from './claim-helpers.js';
7
+ import { isPathLikeTarget } from '../parse/claim-helpers.js';
8
8
  import { resolveTargetReference } from './build-graph-identity.js';
9
9
  import { createOriginDiagnostic } from './directive-diagnostics.js';
10
10
 
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Check one directive claim value against typed validation rules.
3
+ *
4
+ * @param {PatramClaim} claim
5
+ * @param {string} directive_name
6
+ * @param {Record<string, MappingDefinition>} mappings
7
+ * @param {PatramRepoConfig} repo_config
8
+ * @param {MetadataDirectiveRuleConfig | undefined} _directive_rule
9
+ * @param {Map<string, string>} document_entity_keys
10
+ * @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
11
+ * @param {Set<string>} document_paths
12
+ * @returns {PatramDiagnostic[]}
13
+ */
14
+ export function checkDirectiveValue(claim: PatramClaim, directive_name: string, mappings: Record<string, MappingDefinition>, repo_config: PatramRepoConfig, _directive_rule: MetadataDirectiveRuleConfig | undefined, document_entity_keys: Map<string, string>, document_node_references: Map<string, import("./document-node-identity.js").DocumentNodeReference>, document_paths: Set<string>): PatramDiagnostic[];
15
+ import type { PatramClaim } from '../parse/parse-claims.types.d.ts';
16
+ import type { MappingDefinition } from '../config/patram-config.types.d.ts';
17
+ import type { PatramRepoConfig } from '../config/load-patram-config.types.d.ts';
18
+ import type { MetadataDirectiveRuleConfig } from '../config/load-patram-config.types.d.ts';
19
+ import type { PatramDiagnostic } from '../config/load-patram-config.types.d.ts';
@@ -1,7 +1,7 @@
1
1
  /**
2
- * @import { DirectiveTypeConfig, MetadataDirectiveRuleConfig, PatramDiagnostic, PatramRepoConfig } from './load-patram-config.types.ts';
3
- * @import { PatramClaim } from './parse-claims.types.ts';
4
- * @import { MappingDefinition } from './patram-config.types.ts';
2
+ * @import { DirectiveTypeConfig, MetadataDirectiveRuleConfig, PatramDiagnostic, PatramRepoConfig } from '../config/load-patram-config.types.ts';
3
+ * @import { PatramClaim } from '../parse/parse-claims.types.ts';
4
+ * @import { MappingDefinition } from '../config/patram-config.types.ts';
5
5
  */
6
6
 
7
7
  import {
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Graph validation.
3
+ *
4
+ * Reports broken document links and missing edge nodes after graph
5
+ * materialization.
6
+ *
7
+ * Kind: graph
8
+ * Status: active
9
+ * Tracked in: ../../docs/plans/v0/source-anchor-dogfooding.md
10
+ * Decided by: ../../docs/decisions/check-link-target-existence.md
11
+ * Implements: ../../docs/tasks/v0/check-command.md
12
+ * @see {@link ../../docs/decisions/check-link-target-existence.md}
13
+ * @patram
14
+ * @see {@link ./build-graph.js}
15
+ */
16
+ /**
17
+ * Check a materialized graph for broken document links and missing edge nodes.
18
+ *
19
+ * @param {BuildGraphResult} graph
20
+ * @param {string[]} existing_file_paths
21
+ * @param {PatramRepoConfig} [repo_config]
22
+ * @param {PatramClaim[]} [claims]
23
+ * @returns {PatramDiagnostic[]}
24
+ */
25
+ export function checkGraph(graph: BuildGraphResult, existing_file_paths: string[], repo_config?: PatramRepoConfig, claims?: PatramClaim[]): PatramDiagnostic[];
26
+ import type { BuildGraphResult } from './build-graph.types.d.ts';
27
+ import type { PatramRepoConfig } from '../config/load-patram-config.types.d.ts';
28
+ import type { PatramClaim } from '../parse/parse-claims.types.d.ts';
29
+ import type { PatramDiagnostic } from '../config/load-patram-config.types.d.ts';
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * @import { BuildGraphResult, GraphEdge, GraphNode } from './build-graph.types.ts';
3
- * @import { PatramDiagnostic, PatramRepoConfig } from './load-patram-config.types.ts';
4
- * @import { PatramClaim } from './parse-claims.types.ts';
3
+ * @import { PatramDiagnostic, PatramRepoConfig } from '../config/load-patram-config.types.ts';
4
+ * @import { PatramClaim } from '../parse/parse-claims.types.ts';
5
5
  */
6
6
 
7
7
  import { checkDirectiveMetadata } from './check-directive-metadata.js';
@@ -14,12 +14,12 @@ import { checkDirectiveMetadata } from './check-directive-metadata.js';
14
14
  *
15
15
  * Kind: graph
16
16
  * Status: active
17
- * Tracked in: ../docs/plans/v0/source-anchor-dogfooding.md
18
- * Decided by: ../docs/decisions/check-link-target-existence.md
19
- * Implements: ../docs/tasks/v0/check-command.md
17
+ * Tracked in: ../../docs/plans/v0/source-anchor-dogfooding.md
18
+ * Decided by: ../../docs/decisions/check-link-target-existence.md
19
+ * Implements: ../../docs/tasks/v0/check-command.md
20
+ * @see {@link ../../docs/decisions/check-link-target-existence.md}
20
21
  * @patram
21
22
  * @see {@link ./build-graph.js}
22
- * @see {@link ../docs/decisions/check-link-target-existence.md}
23
23
  */
24
24
 
25
25
  /**
@@ -0,0 +1,20 @@
1
+ /**
2
+ * @import { PatramDiagnostic } from '../config/load-patram-config.types.d.ts';
3
+ * @import { PatramClaim } from '../parse/parse-claims.types.d.ts';
4
+ */
5
+ /**
6
+ * @param {PatramClaim} claim
7
+ * @param {string} code
8
+ * @param {string} message
9
+ * @returns {PatramDiagnostic}
10
+ */
11
+ export function createOriginDiagnostic(claim: PatramClaim, code: string, message: string): PatramDiagnostic;
12
+ /**
13
+ * @param {string} document_path
14
+ * @param {string} code
15
+ * @param {string} message
16
+ * @returns {PatramDiagnostic}
17
+ */
18
+ export function createDocumentDiagnostic(document_path: string, code: string, message: string): PatramDiagnostic;
19
+ import type { PatramClaim } from '../parse/parse-claims.types.d.ts';
20
+ import type { PatramDiagnostic } from '../config/load-patram-config.types.d.ts';
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @import { PatramDiagnostic } from './load-patram-config.types.ts';
3
- * @import { PatramClaim } from './parse-claims.types.ts';
2
+ * @import { PatramDiagnostic } from '../config/load-patram-config.types.ts';
3
+ * @import { PatramClaim } from '../parse/parse-claims.types.ts';
4
4
  */
5
5
 
6
6
  /**
@@ -0,0 +1,18 @@
1
+ /**
2
+ * @param {MetadataFieldConfig} type_definition
3
+ * @param {string} directive_value
4
+ * @returns {boolean}
5
+ */
6
+ export function isDirectiveValueValid(type_definition: MetadataFieldConfig, directive_value: string): boolean;
7
+ /**
8
+ * @param {string} directive_name
9
+ * @param {Exclude<MetadataFieldConfig['type'], 'enum'>} type_name
10
+ * @returns {string}
11
+ */
12
+ export function getInvalidTypeMessage(directive_name: string, type_name: Exclude<MetadataFieldConfig["type"], "enum">): string;
13
+ /**
14
+ * @param {string[]} values
15
+ * @returns {string}
16
+ */
17
+ export function formatQuotedList(values: string[]): string;
18
+ import type { MetadataFieldConfig } from '../config/load-patram-config.types.d.ts';
@@ -1,8 +1,8 @@
1
1
  /**
2
- * @import { MetadataFieldConfig } from './load-patram-config.types.ts';
2
+ * @import { MetadataFieldConfig } from '../config/load-patram-config.types.ts';
3
3
  */
4
4
 
5
- import { isPathLikeTarget } from './claim-helpers.js';
5
+ import { isPathLikeTarget } from '../parse/claim-helpers.js';
6
6
 
7
7
  /**
8
8
  * @param {MetadataFieldConfig} type_definition
@@ -52,7 +52,7 @@ export function getInvalidTypeMessage(directive_name, type_name) {
52
52
  case 'date_time':
53
53
  return `Directive "${directive_name}" must use YYYY-MM-DD HH:MM.`;
54
54
  default:
55
- throw new Error(`Unsupported directive type "${type_name}".`);
55
+ throw new Error('Unsupported directive type.');
56
56
  }
57
57
  }
58
58
 
@@ -43,5 +43,5 @@ export type DocumentNodeReference = {
43
43
  key: string;
44
44
  path: string;
45
45
  };
46
- import type { MappingDefinition } from './patram-config.types.ts';
47
- import type { PatramClaim } from './parse-claims.types.ts';
46
+ import type { MappingDefinition } from '../config/patram-config.types.d.ts';
47
+ import type { PatramClaim } from '../parse/parse-claims.types.d.ts';
@@ -1,6 +1,6 @@
1
1
  /**
2
- * @import { PatramClaim } from './parse-claims.types.ts';
3
- * @import { MappingDefinition } from './patram-config.types.ts';
2
+ * @import { PatramClaim } from '../parse/parse-claims.types.ts';
3
+ * @import { MappingDefinition } from '../config/patram-config.types.ts';
4
4
  */
5
5
 
6
6
  import { posix } from 'node:path';
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Inspect incoming graph edges for one canonical target file.
3
+ *
4
+ * @param {BuildGraphResult} graph
5
+ * @param {string} target_file_path
6
+ * @param {PatramRepoConfig | undefined} repo_config
7
+ * @param {string | undefined} where_clause
8
+ * @returns {{
9
+ * diagnostics: PatramDiagnostic[],
10
+ * incoming: Record<string, GraphNode[]>,
11
+ * node: GraphNode,
12
+ * }}
13
+ */
14
+ export function inspectReverseReferences(graph: BuildGraphResult, target_file_path: string, repo_config: PatramRepoConfig | undefined, where_clause: string | undefined): {
15
+ diagnostics: PatramDiagnostic[];
16
+ incoming: Record<string, GraphNode[]>;
17
+ node: GraphNode;
18
+ };
19
+ import type { BuildGraphResult } from './build-graph.types.d.ts';
20
+ import type { PatramRepoConfig } from '../config/load-patram-config.types.d.ts';
21
+ import type { PatramDiagnostic } from '../config/load-patram-config.types.d.ts';
22
+ import type { GraphNode } from './build-graph.types.d.ts';
@@ -0,0 +1,184 @@
1
+ /**
2
+ * @import { BuildGraphResult, GraphNode } from './build-graph.types.ts';
3
+ * @import { PatramDiagnostic, PatramRepoConfig } from '../config/load-patram-config.types.ts';
4
+ */
5
+
6
+ import {
7
+ normalizeRepoRelativePath,
8
+ resolveDocumentNodeId,
9
+ } from './document-node-identity.js';
10
+ import { queryGraph } from './query/execute.js';
11
+
12
+ /**
13
+ * Inspect incoming graph edges for one canonical target file.
14
+ *
15
+ * @param {BuildGraphResult} graph
16
+ * @param {string} target_file_path
17
+ * @param {PatramRepoConfig | undefined} repo_config
18
+ * @param {string | undefined} where_clause
19
+ * @returns {{
20
+ * diagnostics: PatramDiagnostic[],
21
+ * incoming: Record<string, GraphNode[]>,
22
+ * node: GraphNode,
23
+ * }}
24
+ */
25
+ export function inspectReverseReferences(
26
+ graph,
27
+ target_file_path,
28
+ repo_config,
29
+ where_clause,
30
+ ) {
31
+ const normalized_target_path = normalizeRepoRelativePath(target_file_path);
32
+ const target_node_id = resolveDocumentNodeId(
33
+ graph.document_node_ids,
34
+ normalized_target_path,
35
+ );
36
+ const target_node =
37
+ graph.nodes[target_node_id] ??
38
+ createFallbackTargetNode(target_node_id, normalized_target_path);
39
+ const allowed_source_node_ids = where_clause
40
+ ? resolveAllowedSourceNodeIds(graph, where_clause, repo_config)
41
+ : null;
42
+
43
+ if (allowed_source_node_ids && 'diagnostics' in allowed_source_node_ids) {
44
+ return {
45
+ diagnostics: allowed_source_node_ids.diagnostics,
46
+ incoming: {},
47
+ node: target_node,
48
+ };
49
+ }
50
+
51
+ return {
52
+ diagnostics: [],
53
+ incoming: collectIncomingGroups(
54
+ graph,
55
+ target_node.id,
56
+ allowed_source_node_ids,
57
+ ),
58
+ node: target_node,
59
+ };
60
+ }
61
+
62
+ /**
63
+ * @param {BuildGraphResult} graph
64
+ * @param {string} target_node_id
65
+ * @param {Set<string> | null} allowed_source_node_ids
66
+ * @returns {Record<string, GraphNode[]>}
67
+ */
68
+ function collectIncomingGroups(graph, target_node_id, allowed_source_node_ids) {
69
+ /** @type {Map<string, Map<string, GraphNode>>} */
70
+ const grouped_incoming = new Map();
71
+
72
+ for (const graph_edge of graph.edges) {
73
+ if (graph_edge.to !== target_node_id) {
74
+ continue;
75
+ }
76
+
77
+ if (
78
+ allowed_source_node_ids &&
79
+ !allowed_source_node_ids.has(graph_edge.from)
80
+ ) {
81
+ continue;
82
+ }
83
+
84
+ const source_node = graph.nodes[graph_edge.from];
85
+
86
+ if (!source_node) {
87
+ continue;
88
+ }
89
+
90
+ let relation_sources = grouped_incoming.get(graph_edge.relation);
91
+
92
+ if (!relation_sources) {
93
+ relation_sources = new Map();
94
+ grouped_incoming.set(graph_edge.relation, relation_sources);
95
+ }
96
+
97
+ relation_sources.set(source_node.id, source_node);
98
+ }
99
+
100
+ return formatIncomingGroups(grouped_incoming);
101
+ }
102
+
103
+ /**
104
+ * @param {BuildGraphResult} graph
105
+ * @param {string} where_clause
106
+ * @param {PatramRepoConfig | undefined} repo_config
107
+ * @returns {{ diagnostics: PatramDiagnostic[] } | Set<string>}
108
+ */
109
+ function resolveAllowedSourceNodeIds(graph, where_clause, repo_config) {
110
+ const query_result = queryGraph(
111
+ graph,
112
+ where_clause,
113
+ repo_config ?? {
114
+ fields: {},
115
+ include: [],
116
+ queries: {},
117
+ },
118
+ );
119
+
120
+ if (query_result.diagnostics.length > 0) {
121
+ return {
122
+ diagnostics: query_result.diagnostics,
123
+ };
124
+ }
125
+
126
+ return new Set(query_result.nodes.map((graph_node) => graph_node.id));
127
+ }
128
+
129
+ /**
130
+ * @param {Map<string, Map<string, GraphNode>>} grouped_incoming
131
+ * @returns {Record<string, GraphNode[]>}
132
+ */
133
+ function formatIncomingGroups(grouped_incoming) {
134
+ /** @type {Record<string, GraphNode[]>} */
135
+ const incoming = {};
136
+
137
+ for (const relation_name of [...grouped_incoming.keys()].sort(
138
+ compareStrings,
139
+ )) {
140
+ const relation_sources = /** @type {Map<string, GraphNode>} */ (
141
+ grouped_incoming.get(relation_name)
142
+ );
143
+
144
+ incoming[relation_name] = [...relation_sources.values()].sort(
145
+ compareGraphNodes,
146
+ );
147
+ }
148
+
149
+ return incoming;
150
+ }
151
+
152
+ /**
153
+ * @param {string} node_id
154
+ * @param {string} target_path
155
+ * @returns {GraphNode}
156
+ */
157
+ function createFallbackTargetNode(node_id, target_path) {
158
+ return {
159
+ $class: 'document',
160
+ $id: node_id,
161
+ $path: target_path,
162
+ id: node_id,
163
+ path: target_path,
164
+ title: target_path,
165
+ };
166
+ }
167
+
168
+ /**
169
+ * @param {GraphNode} left_node
170
+ * @param {GraphNode} right_node
171
+ * @returns {number}
172
+ */
173
+ function compareGraphNodes(left_node, right_node) {
174
+ return compareStrings(left_node.id, right_node.id);
175
+ }
176
+
177
+ /**
178
+ * @param {string} left_value
179
+ * @param {string} right_value
180
+ * @returns {number}
181
+ */
182
+ function compareStrings(left_value, right_value) {
183
+ return left_value.localeCompare(right_value, 'en');
184
+ }
@@ -6,13 +6,13 @@
6
6
  *
7
7
  * Kind: graph
8
8
  * Status: active
9
- * Uses Term: ../docs/reference/terms/claim.md
10
- * Uses Term: ../docs/reference/terms/graph.md
11
- * Uses Term: ../docs/reference/terms/mapping.md
12
- * Tracked in: ../docs/plans/v0/source-anchor-dogfooding.md
13
- * Decided by: ../docs/decisions/dogfood-query-graph-v0.md
9
+ * Uses Term: ../../docs/reference/terms/claim.md
10
+ * Uses Term: ../../docs/reference/terms/graph.md
11
+ * Uses Term: ../../docs/reference/terms/mapping.md
12
+ * Tracked in: ../../docs/plans/v0/source-anchor-dogfooding.md
13
+ * Decided by: ../../docs/decisions/dogfood-query-graph-v0.md
14
14
  * @patram
15
- * @see {@link ./parse-claims.js}
15
+ * @see {@link ../parse/parse-claims.js}
16
16
  * @see {@link ./build-graph.js}
17
17
  */
18
18
  /**
@@ -29,7 +29,7 @@ export function loadProjectGraph(project_directory: string): Promise<{
29
29
  graph: BuildGraphResult;
30
30
  source_file_paths: string[];
31
31
  }>;
32
- import type { PatramClaim } from './parse-claims.types.ts';
33
- import type { PatramRepoConfig } from './load-patram-config.types.ts';
34
- import type { PatramDiagnostic } from './load-patram-config.types.ts';
35
- import type { BuildGraphResult } from './build-graph.types.ts';
32
+ import type { PatramClaim } from '../parse/parse-claims.types.d.ts';
33
+ import type { PatramRepoConfig } from '../config/load-patram-config.types.d.ts';
34
+ import type { PatramDiagnostic } from '../config/load-patram-config.types.d.ts';
35
+ import type { BuildGraphResult } from './build-graph.types.d.ts';
@@ -1,17 +1,17 @@
1
1
  /**
2
2
  * @import { BuildGraphResult } from './build-graph.types.ts';
3
- * @import { PatramClaim } from './parse-claims.types.ts';
4
- * @import { PatramDiagnostic, PatramRepoConfig } from './load-patram-config.types.ts';
3
+ * @import { PatramClaim } from '../parse/parse-claims.types.ts';
4
+ * @import { PatramDiagnostic, PatramRepoConfig } from '../config/load-patram-config.types.ts';
5
5
  */
6
6
 
7
7
  import { readFile } from 'node:fs/promises';
8
8
  import { resolve } from 'node:path';
9
9
 
10
10
  import { buildGraph } from './build-graph.js';
11
- import { listSourceFiles } from './list-source-files.js';
12
- import { loadPatramConfig } from './load-patram-config.js';
13
- import { createParseOptions, parseSourceFile } from './parse-claims.js';
14
- import { resolvePatramGraphConfig } from './resolve-patram-graph-config.js';
11
+ import { loadPatramConfig } from '../config/load-patram-config.js';
12
+ import { createParseOptions, parseSourceFile } from '../parse/parse-claims.js';
13
+ import { listSourceFiles } from '../scan/list-source-files.js';
14
+ import { resolvePatramGraphConfig } from '../config/resolve-patram-graph-config.js';
15
15
 
16
16
  /**
17
17
  * Project graph loading pipeline.
@@ -21,13 +21,13 @@ import { resolvePatramGraphConfig } from './resolve-patram-graph-config.js';
21
21
  *
22
22
  * Kind: graph
23
23
  * Status: active
24
- * Uses Term: ../docs/reference/terms/claim.md
25
- * Uses Term: ../docs/reference/terms/graph.md
26
- * Uses Term: ../docs/reference/terms/mapping.md
27
- * Tracked in: ../docs/plans/v0/source-anchor-dogfooding.md
28
- * Decided by: ../docs/decisions/dogfood-query-graph-v0.md
24
+ * Uses Term: ../../docs/reference/terms/claim.md
25
+ * Uses Term: ../../docs/reference/terms/graph.md
26
+ * Uses Term: ../../docs/reference/terms/mapping.md
27
+ * Tracked in: ../../docs/plans/v0/source-anchor-dogfooding.md
28
+ * Decided by: ../../docs/decisions/dogfood-query-graph-v0.md
29
29
  * @patram
30
- * @see {@link ./parse-claims.js}
30
+ * @see {@link ../parse/parse-claims.js}
31
31
  * @see {@link ./build-graph.js}
32
32
  */
33
33
 
@@ -1,4 +1,4 @@
1
- import type { PatramDiagnostic } from './load-patram-config.types.ts';
1
+ import type { PatramDiagnostic } from '../config/load-patram-config.types.d.ts';
2
2
  export type ParsedFieldName = string;
3
3
  export interface ParsedFieldTerm {
4
4
  column: number;