patram 0.3.0 → 0.5.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.
@@ -1,48 +1,19 @@
1
1
  /**
2
+ * @import { DocumentNodeReference } from './document-node-identity.js';
2
3
  * @import { GraphNode } from './build-graph.types.ts';
3
4
  * @import { PatramClaim } from './parse-claims.types.ts';
4
- * @import { MappingDefinition } from './patram-config.types.ts';
5
5
  */
6
6
 
7
7
  import { posix } from 'node:path';
8
8
 
9
- /**
10
- * Collect semantic entity keys defined by canonical documents.
11
- *
12
- * @param {Record<string, MappingDefinition>} mappings
13
- * @param {PatramClaim[]} claims
14
- * @returns {Map<string, string>}
15
- */
16
- export function collectDocumentEntityKeys(mappings, claims) {
17
- /** @type {Map<string, string>} */
18
- const document_entity_keys = new Map();
19
-
20
- for (const claim of claims) {
21
- const mapping_definition = resolveMappingDefinition(mappings, claim);
22
-
23
- if (mapping_definition?.node?.key !== 'value') {
24
- continue;
25
- }
26
-
27
- const source_path = normalizeRepoRelativePath(claim.origin.path);
28
- const entity_map_key = getDocumentEntityMapKey(
29
- source_path,
30
- mapping_definition.node.class,
31
- );
32
- const entity_key = getStringClaimValue(claim);
33
- const existing_entity_key = document_entity_keys.get(entity_map_key);
9
+ import { normalizeRepoRelativePath } from './document-node-identity.js';
34
10
 
35
- if (existing_entity_key && existing_entity_key !== entity_key) {
36
- throw new Error(
37
- `Document "${source_path}" defines multiple ${mapping_definition.node.class} ids.`,
38
- );
39
- }
40
-
41
- document_entity_keys.set(entity_map_key, entity_key);
42
- }
43
-
44
- return document_entity_keys;
45
- }
11
+ export {
12
+ collectDocumentEntityKeys,
13
+ collectDocumentNodeReferences,
14
+ normalizeRepoRelativePath,
15
+ resolveDocumentNodeId,
16
+ } from './document-node-identity.js';
46
17
 
47
18
  /**
48
19
  * Resolve the node key for one mapped claim.
@@ -77,14 +48,16 @@ export function resolveNodeKey(node_mapping, claim, document_entity_keys) {
77
48
  * @param {'path' | 'value'} target_type
78
49
  * @param {PatramClaim} claim
79
50
  * @param {Map<string, string>} document_entity_keys
51
+ * @param {Map<string, DocumentNodeReference>} document_node_references
80
52
  * @param {Set<string>} document_paths
81
- * @returns {{ key: string, path?: string }}
53
+ * @returns {{ class_name: string, key: string, path?: string }}
82
54
  */
83
55
  export function resolveTargetReference(
84
56
  target_class,
85
57
  target_type,
86
58
  claim,
87
59
  document_entity_keys,
60
+ document_node_references,
88
61
  document_paths,
89
62
  ) {
90
63
  if (target_type === 'value') {
@@ -95,18 +68,19 @@ export function resolveTargetReference(
95
68
  target_class,
96
69
  claim,
97
70
  document_entity_keys,
71
+ document_node_references,
98
72
  document_paths,
99
73
  );
100
74
  }
101
75
 
102
76
  /**
103
- * Attach one canonical path to a non-document graph node.
77
+ * Attach one canonical path to a graph node.
104
78
  *
105
79
  * @param {GraphNode} graph_node
106
80
  * @param {string | undefined} source_path
107
81
  */
108
- export function setNonDocumentPath(graph_node, source_path) {
109
- if (!source_path || graph_node.$class === 'document') {
82
+ export function setCanonicalPath(graph_node, source_path) {
83
+ if (!source_path) {
110
84
  return;
111
85
  }
112
86
 
@@ -123,58 +97,24 @@ export function setNonDocumentPath(graph_node, source_path) {
123
97
  }
124
98
  }
125
99
 
126
- /**
127
- * Normalize one repo-relative source path.
128
- *
129
- * @param {string} source_path
130
- * @returns {string}
131
- */
132
- export function normalizeRepoRelativePath(source_path) {
133
- return posix.normalize(source_path.replaceAll('\\', '/'));
134
- }
135
-
136
- /**
137
- * @param {Record<string, MappingDefinition>} mappings
138
- * @param {PatramClaim} claim
139
- * @returns {MappingDefinition | null}
140
- */
141
- function resolveMappingDefinition(mappings, claim) {
142
- if (claim.type === 'directive') {
143
- return resolveDirectiveMapping(mappings, claim);
144
- }
145
-
146
- return mappings[claim.type] ?? null;
147
- }
148
-
149
- /**
150
- * @param {Record<string, MappingDefinition>} mappings
151
- * @param {PatramClaim} claim
152
- * @returns {MappingDefinition | null}
153
- */
154
- function resolveDirectiveMapping(mappings, claim) {
155
- if (!claim.parser || !claim.name) {
156
- return null;
157
- }
158
-
159
- return mappings[`${claim.parser}.directive.${claim.name}`] ?? null;
160
- }
161
-
162
100
  /**
163
101
  * @param {string} target_kind
164
102
  * @param {PatramClaim} claim
165
- * @returns {{ key: string, path?: string }}
103
+ * @returns {{ class_name: string, key: string, path?: string }}
166
104
  */
167
105
  function resolveValueTargetReference(target_kind, claim) {
168
106
  const target_key = getStringClaimValue(claim);
169
107
 
170
108
  if (target_kind === 'document') {
171
109
  return {
110
+ class_name: 'document',
172
111
  key: target_key,
173
112
  path: target_key,
174
113
  };
175
114
  }
176
115
 
177
116
  return {
117
+ class_name: target_kind,
178
118
  key: target_key,
179
119
  path: normalizeRepoRelativePath(claim.origin.path),
180
120
  };
@@ -184,13 +124,15 @@ function resolveValueTargetReference(target_kind, claim) {
184
124
  * @param {string} target_class
185
125
  * @param {PatramClaim} claim
186
126
  * @param {Map<string, string>} document_entity_keys
127
+ * @param {Map<string, DocumentNodeReference>} document_node_references
187
128
  * @param {Set<string>} document_paths
188
- * @returns {{ key: string, path?: string }}
129
+ * @returns {{ class_name: string, key: string, path?: string }}
189
130
  */
190
131
  function resolvePathTargetReference(
191
132
  target_class,
192
133
  claim,
193
134
  document_entity_keys,
135
+ document_node_references,
194
136
  document_paths,
195
137
  ) {
196
138
  const raw_target = getPathTargetValue(claim);
@@ -201,18 +143,51 @@ function resolvePathTargetReference(
201
143
  );
202
144
 
203
145
  if (target_class === 'document') {
146
+ return resolveDocumentTargetReference(
147
+ target_path,
148
+ document_node_references,
149
+ );
150
+ }
151
+
152
+ const document_node_reference = document_node_references.get(target_path);
153
+
154
+ if (documentNodeReferenceIsPromoted(document_node_reference)) {
204
155
  return {
205
- key: target_path,
156
+ class_name: document_node_reference.class_name,
157
+ key: document_node_reference.key,
206
158
  path: target_path,
207
159
  };
208
160
  }
209
161
 
210
- const semantic_target_key = document_entity_keys.get(
211
- getDocumentEntityMapKey(target_path, target_class),
212
- );
162
+ return {
163
+ class_name: target_class,
164
+ key:
165
+ document_entity_keys.get(
166
+ getDocumentEntityMapKey(target_path, target_class),
167
+ ) ?? target_path,
168
+ path: target_path,
169
+ };
170
+ }
171
+
172
+ /**
173
+ * @param {string} target_path
174
+ * @param {Map<string, DocumentNodeReference>} document_node_references
175
+ * @returns {{ class_name: string, key: string, path?: string }}
176
+ */
177
+ function resolveDocumentTargetReference(target_path, document_node_references) {
178
+ const document_node_reference = document_node_references.get(target_path);
179
+
180
+ if (!document_node_reference) {
181
+ return {
182
+ class_name: 'document',
183
+ key: target_path,
184
+ path: target_path,
185
+ };
186
+ }
213
187
 
214
188
  return {
215
- key: semantic_target_key ?? target_path,
189
+ class_name: document_node_reference.class_name,
190
+ key: document_node_reference.key,
216
191
  path: target_path,
217
192
  };
218
193
  }
@@ -269,3 +244,14 @@ function getStringClaimValue(claim) {
269
244
  function getDocumentEntityMapKey(document_path, class_name) {
270
245
  return `${class_name}:${document_path}`;
271
246
  }
247
+
248
+ /**
249
+ * @param {DocumentNodeReference | undefined} document_node_reference
250
+ * @returns {document_node_reference is DocumentNodeReference}
251
+ */
252
+ function documentNodeReferenceIsPromoted(document_node_reference) {
253
+ return (
254
+ document_node_reference !== undefined &&
255
+ document_node_reference.class_name !== 'document'
256
+ );
257
+ }
@@ -10,10 +10,11 @@ import { posix } from 'node:path';
10
10
 
11
11
  import {
12
12
  collectDocumentEntityKeys,
13
+ collectDocumentNodeReferences,
13
14
  normalizeRepoRelativePath,
14
15
  resolveNodeKey,
15
16
  resolveTargetReference,
16
- setNonDocumentPath,
17
+ setCanonicalPath,
17
18
  } from './build-graph-identity.js';
18
19
 
19
20
  /**
@@ -52,6 +53,10 @@ const EXPLICIT_TITLE_PRIORITY = 2;
52
53
  export function buildGraph(patram_config, claims) {
53
54
  /** @type {Map<string, GraphNode>} */
54
55
  const graph_nodes = new Map();
56
+ const document_node_references = collectDocumentNodeReferences(
57
+ patram_config.mappings,
58
+ claims,
59
+ );
55
60
  const document_entity_keys = collectDocumentEntityKeys(
56
61
  patram_config.mappings,
57
62
  claims,
@@ -63,12 +68,13 @@ export function buildGraph(patram_config, claims) {
63
68
  /** @type {Map<string, number>} */
64
69
  const title_priorities = new Map();
65
70
 
66
- createDocumentNodes(graph_nodes, claims);
71
+ createDocumentNodes(graph_nodes, document_node_references);
67
72
  applyNodeMappings(
68
73
  graph_nodes,
69
74
  patram_config,
70
75
  claims,
71
76
  document_entity_keys,
77
+ document_node_references,
72
78
  title_priorities,
73
79
  );
74
80
  const graph_edges = createGraphEdges(
@@ -76,16 +82,26 @@ export function buildGraph(patram_config, claims) {
76
82
  patram_config.mappings,
77
83
  claims,
78
84
  document_entity_keys,
85
+ document_node_references,
79
86
  document_paths,
80
87
  );
81
88
  applyFallbackTitles(graph_nodes, title_priorities);
82
89
 
83
- return {
90
+ const graph_result = {
84
91
  edges: graph_edges,
85
92
  nodes: Object.fromEntries(
86
93
  [...graph_nodes.entries()].sort(compareNodeEntries),
87
94
  ),
88
95
  };
96
+
97
+ attachDocumentNodeAliases(graph_result.nodes, document_node_references);
98
+ Object.defineProperty(
99
+ graph_result,
100
+ 'document_node_ids',
101
+ createDocumentNodeIdsProperty(document_node_references),
102
+ );
103
+
104
+ return graph_result;
89
105
  }
90
106
 
91
107
  /**
@@ -116,15 +132,17 @@ function resolveDirectiveMapping(mappings, claim) {
116
132
 
117
133
  /**
118
134
  * @param {Map<string, GraphNode>} graph_nodes
119
- * @param {PatramClaim[]} claims
135
+ * @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
120
136
  */
121
- function createDocumentNodes(graph_nodes, claims) {
122
- for (const claim of claims) {
123
- upsertNode(
137
+ function createDocumentNodes(graph_nodes, document_node_references) {
138
+ for (const document_node_reference of document_node_references.values()) {
139
+ const graph_node = upsertNode(
124
140
  graph_nodes,
125
- 'document',
126
- normalizeRepoRelativePath(claim.origin.path),
141
+ document_node_reference.class_name,
142
+ document_node_reference.key,
127
143
  );
144
+
145
+ setCanonicalPath(graph_node, document_node_reference.path);
128
146
  }
129
147
  }
130
148
 
@@ -133,6 +151,7 @@ function createDocumentNodes(graph_nodes, claims) {
133
151
  * @param {PatramConfig} patram_config
134
152
  * @param {PatramClaim[]} claims
135
153
  * @param {Map<string, string>} document_entity_keys
154
+ * @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
136
155
  * @param {Map<string, number>} title_priorities
137
156
  */
138
157
  function applyNodeMappings(
@@ -140,6 +159,7 @@ function applyNodeMappings(
140
159
  patram_config,
141
160
  claims,
142
161
  document_entity_keys,
162
+ document_node_references,
143
163
  title_priorities,
144
164
  ) {
145
165
  for (const claim of claims) {
@@ -158,6 +178,7 @@ function applyNodeMappings(
158
178
  mapping_definition.node,
159
179
  claim,
160
180
  document_entity_keys,
181
+ document_node_references,
161
182
  title_priorities,
162
183
  );
163
184
  }
@@ -168,6 +189,7 @@ function applyNodeMappings(
168
189
  * @param {Record<string, MappingDefinition>} mappings
169
190
  * @param {PatramClaim[]} claims
170
191
  * @param {Map<string, string>} document_entity_keys
192
+ * @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
171
193
  * @param {Set<string>} document_paths
172
194
  * @returns {GraphEdge[]}
173
195
  */
@@ -176,6 +198,7 @@ function createGraphEdges(
176
198
  mappings,
177
199
  claims,
178
200
  document_entity_keys,
201
+ document_node_references,
179
202
  document_paths,
180
203
  ) {
181
204
  /** @type {GraphEdge[]} */
@@ -189,25 +212,26 @@ function createGraphEdges(
189
212
  continue;
190
213
  }
191
214
 
192
- const source_document_node = upsertNode(
215
+ const source_document_node = getDocumentGraphNode(
193
216
  graph_nodes,
194
- 'document',
195
- normalizeRepoRelativePath(claim.origin.path),
217
+ document_node_references,
218
+ claim,
196
219
  );
197
220
  const target_reference = resolveTargetReference(
198
221
  mapping_definition.emit.target_class,
199
222
  mapping_definition.emit.target,
200
223
  claim,
201
224
  document_entity_keys,
225
+ document_node_references,
202
226
  document_paths,
203
227
  );
204
228
  const target_node = upsertNode(
205
229
  graph_nodes,
206
- mapping_definition.emit.target_class,
230
+ target_reference.class_name,
207
231
  target_reference.key,
208
232
  );
209
233
 
210
- setNonDocumentPath(target_node, target_reference.path);
234
+ setCanonicalPath(target_node, target_reference.path);
211
235
 
212
236
  edge_number += 1;
213
237
  graph_edges.push({
@@ -228,6 +252,7 @@ function createGraphEdges(
228
252
  * @param {{ field: string, key?: 'path' | 'value', class: string }} node_mapping
229
253
  * @param {PatramClaim} claim
230
254
  * @param {Map<string, string>} document_entity_keys
255
+ * @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
231
256
  * @param {Map<string, number>} title_priorities
232
257
  */
233
258
  function applyNodeMapping(
@@ -236,14 +261,25 @@ function applyNodeMapping(
236
261
  node_mapping,
237
262
  claim,
238
263
  document_entity_keys,
264
+ document_node_references,
239
265
  title_priorities,
240
266
  ) {
241
267
  const source_key = normalizeRepoRelativePath(claim.origin.path);
242
- const node_key = resolveNodeKey(node_mapping, claim, document_entity_keys);
243
- const graph_node = upsertNode(graph_nodes, node_mapping.class, node_key);
244
- const field_value = getNodeFieldValue(claim);
268
+ const graph_node = resolveGraphNode(
269
+ graph_nodes,
270
+ node_mapping,
271
+ claim,
272
+ document_entity_keys,
273
+ document_node_references,
274
+ );
275
+ const field_value = resolveNodeFieldValue(
276
+ graph_node,
277
+ node_mapping,
278
+ claim,
279
+ source_key,
280
+ );
245
281
 
246
- setNonDocumentPath(graph_node, source_key);
282
+ setCanonicalPath(graph_node, source_key);
247
283
  validateNodeFieldMapping(
248
284
  patram_config,
249
285
  node_mapping.class,
@@ -408,6 +444,122 @@ function getNodeFieldValue(claim) {
408
444
  throw new Error(`Claim "${claim.id}" does not carry a string value.`);
409
445
  }
410
446
 
447
+ /**
448
+ * @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
449
+ * @returns {{ configurable: false, enumerable: false, value: Record<string, string>, writable: false }}
450
+ */
451
+ function createDocumentNodeIdsProperty(document_node_references) {
452
+ return {
453
+ configurable: false,
454
+ enumerable: false,
455
+ value: Object.fromEntries(
456
+ [...document_node_references.entries()].map(
457
+ ([document_path, document_node_reference]) => [
458
+ document_path,
459
+ document_node_reference.id,
460
+ ],
461
+ ),
462
+ ),
463
+ writable: false,
464
+ };
465
+ }
466
+
467
+ /**
468
+ * @param {Map<string, GraphNode>} graph_nodes
469
+ * @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
470
+ * @param {PatramClaim} claim
471
+ * @returns {GraphNode}
472
+ */
473
+ function getDocumentGraphNode(graph_nodes, document_node_references, claim) {
474
+ const document_path = normalizeRepoRelativePath(claim.origin.path);
475
+ const document_node_reference = document_node_references.get(document_path);
476
+
477
+ if (!document_node_reference) {
478
+ throw new Error(`Missing document node reference for "${document_path}".`);
479
+ }
480
+
481
+ const graph_node = upsertNode(
482
+ graph_nodes,
483
+ document_node_reference.class_name,
484
+ document_node_reference.key,
485
+ );
486
+
487
+ setCanonicalPath(graph_node, document_node_reference.path);
488
+
489
+ return graph_node;
490
+ }
491
+
492
+ /**
493
+ * @param {Map<string, GraphNode>} graph_nodes
494
+ * @param {{ field: string, key?: 'path' | 'value', class: string }} node_mapping
495
+ * @param {PatramClaim} claim
496
+ * @param {Map<string, string>} document_entity_keys
497
+ * @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
498
+ * @returns {GraphNode}
499
+ */
500
+ function resolveGraphNode(
501
+ graph_nodes,
502
+ node_mapping,
503
+ claim,
504
+ document_entity_keys,
505
+ document_node_references,
506
+ ) {
507
+ if (node_mapping.class === 'document') {
508
+ return getDocumentGraphNode(graph_nodes, document_node_references, claim);
509
+ }
510
+
511
+ const node_key = resolveNodeKey(node_mapping, claim, document_entity_keys);
512
+
513
+ return upsertNode(graph_nodes, node_mapping.class, node_key);
514
+ }
515
+
516
+ /**
517
+ * @param {GraphNode} graph_node
518
+ * @param {{ field: string, key?: 'path' | 'value', class: string }} node_mapping
519
+ * @param {PatramClaim} claim
520
+ * @param {string} source_path
521
+ * @returns {string}
522
+ */
523
+ function resolveNodeFieldValue(graph_node, node_mapping, claim, source_path) {
524
+ if (node_mapping.field === '$id') {
525
+ return graph_node.id;
526
+ }
527
+
528
+ if (node_mapping.field === '$class') {
529
+ return graph_node.$class ?? graph_node.kind ?? node_mapping.class;
530
+ }
531
+
532
+ if (node_mapping.field === '$path') {
533
+ return source_path;
534
+ }
535
+
536
+ return getNodeFieldValue(claim);
537
+ }
538
+
539
+ /**
540
+ * @param {Record<string, GraphNode>} graph_nodes
541
+ * @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
542
+ */
543
+ function attachDocumentNodeAliases(graph_nodes, document_node_references) {
544
+ for (const [
545
+ document_path,
546
+ document_node_reference,
547
+ ] of document_node_references) {
548
+ const document_node_id = `doc:${document_path}`;
549
+
550
+ if (document_node_id === document_node_reference.id) {
551
+ continue;
552
+ }
553
+
554
+ Object.defineProperty(graph_nodes, document_node_id, {
555
+ configurable: false,
556
+ enumerable: false,
557
+ value: graph_nodes[document_node_reference.id],
558
+ writable: false,
559
+ });
560
+ }
561
+ }
562
+
411
563
  /**
412
564
  * @param {Map<string, GraphNode>} graph_nodes
413
565
  * @param {Map<string, number>} title_priorities
@@ -619,7 +771,7 @@ function getFieldDefinition(patram_config, field_name) {
619
771
  * @returns {{ fields?: Record<string, { presence: 'required' | 'optional' | 'forbidden' }>, unknown_fields?: 'ignore' | 'error' } | undefined}
620
772
  */
621
773
  function getClassSchema(patram_config, class_name) {
622
- return patram_config.class_schemas?.[class_name];
774
+ return patram_config.classes[class_name]?.schema;
623
775
  }
624
776
 
625
777
  /**
@@ -21,6 +21,7 @@ export interface GraphEdge {
21
21
  }
22
22
 
23
23
  export interface BuildGraphResult {
24
+ document_node_ids?: Record<string, string>;
24
25
  edges: GraphEdge[];
25
26
  nodes: Record<string, GraphNode>;
26
27
  }
@@ -8,7 +8,9 @@
8
8
 
9
9
  import {
10
10
  collectDocumentEntityKeys,
11
+ collectDocumentNodeReferences,
11
12
  normalizeRepoRelativePath,
13
+ resolveDocumentNodeId,
12
14
  } from './build-graph-identity.js';
13
15
  import { checkDirectiveValue } from './check-directive-value.js';
14
16
  import {
@@ -45,7 +47,7 @@ export function checkDirectiveMetadata(
45
47
  if (
46
48
  claims.length === 0 ||
47
49
  (repo_config.fields === undefined &&
48
- repo_config.class_schemas === undefined)
50
+ !hasConfiguredClassSchemas(repo_config))
49
51
  ) {
50
52
  return [];
51
53
  }
@@ -55,6 +57,10 @@ export function checkDirectiveMetadata(
55
57
  graph_config.mappings,
56
58
  claims,
57
59
  );
60
+ const document_node_references = collectDocumentNodeReferences(
61
+ graph_config.mappings,
62
+ claims,
63
+ );
58
64
  const document_paths = new Set(
59
65
  existing_file_paths.map((file_path) =>
60
66
  normalizeRepoRelativePath(file_path),
@@ -79,6 +85,7 @@ export function checkDirectiveMetadata(
79
85
  document_path,
80
86
  document_claims,
81
87
  document_entity_keys,
88
+ document_node_references,
82
89
  document_paths,
83
90
  );
84
91
  }
@@ -121,6 +128,7 @@ function groupDirectiveClaimsByDocument(claims) {
121
128
  * @param {string} document_path
122
129
  * @param {PatramClaim[]} document_claims
123
130
  * @param {Map<string, string>} document_entity_keys
131
+ * @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
124
132
  * @param {Set<string>} document_paths
125
133
  */
126
134
  function collectDocumentDiagnostics(
@@ -131,10 +139,11 @@ function collectDocumentDiagnostics(
131
139
  document_path,
132
140
  document_claims,
133
141
  document_entity_keys,
142
+ document_node_references,
134
143
  document_paths,
135
144
  ) {
136
145
  const document_kind = resolveDocumentKind(graph, document_path);
137
- const schema_definition = repo_config.class_schemas?.[document_kind];
146
+ const schema_definition = repo_config.classes?.[document_kind]?.schema;
138
147
  /** @type {Map<string, number>} */
139
148
  const directive_counts = new Map();
140
149
 
@@ -152,6 +161,7 @@ function collectDocumentDiagnostics(
152
161
  schema_definition,
153
162
  directive_counts,
154
163
  document_entity_keys,
164
+ document_node_references,
155
165
  document_paths,
156
166
  ),
157
167
  );
@@ -176,6 +186,7 @@ function collectDocumentDiagnostics(
176
186
  * @param {MetadataSchemaConfig | undefined} schema_definition
177
187
  * @param {Map<string, number>} directive_counts
178
188
  * @param {Map<string, string>} document_entity_keys
189
+ * @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
179
190
  * @param {Set<string>} document_paths
180
191
  * @returns {PatramDiagnostic[]}
181
192
  */
@@ -187,6 +198,7 @@ function collectClaimDiagnostics(
187
198
  schema_definition,
188
199
  directive_counts,
189
200
  document_entity_keys,
201
+ document_node_references,
190
202
  document_paths,
191
203
  ) {
192
204
  if (!claim.name) {
@@ -222,11 +234,26 @@ function collectClaimDiagnostics(
222
234
  repo_config,
223
235
  schema_definition?.fields[claim.name],
224
236
  document_entity_keys,
237
+ document_node_references,
225
238
  document_paths,
226
239
  ),
227
240
  ];
228
241
  }
229
242
 
243
+ /**
244
+ * @param {PatramRepoConfig} repo_config
245
+ * @returns {boolean}
246
+ */
247
+ function hasConfiguredClassSchemas(repo_config) {
248
+ for (const class_definition of Object.values(repo_config.classes ?? {})) {
249
+ if (class_definition.schema) {
250
+ return true;
251
+ }
252
+ }
253
+
254
+ return false;
255
+ }
256
+
230
257
  /**
231
258
  * @param {PatramRepoConfig} repo_config
232
259
  * @param {string} document_path
@@ -392,9 +419,14 @@ function getDirectiveFieldDefinition(repo_config, validation_field_name) {
392
419
  * @returns {string}
393
420
  */
394
421
  function resolveDocumentKind(graph, document_path) {
422
+ const document_node_id = resolveDocumentNodeId(
423
+ graph.document_node_ids,
424
+ document_path,
425
+ );
426
+
395
427
  return (
396
- graph.nodes[`doc:${document_path}`]?.$class ??
397
- graph.nodes[`doc:${document_path}`]?.kind ??
428
+ graph.nodes[document_node_id]?.$class ??
429
+ graph.nodes[document_node_id]?.kind ??
398
430
  'document'
399
431
  );
400
432
  }