patram 0.2.0 → 0.4.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/lib/build-graph-identity.js +86 -99
- package/lib/build-graph.js +536 -31
- package/lib/build-graph.types.ts +6 -2
- package/lib/check-directive-metadata.js +534 -0
- package/lib/check-directive-value.js +291 -0
- package/lib/check-graph.js +23 -5
- package/lib/cli-help-metadata.js +56 -16
- package/lib/command-output.js +16 -1
- package/lib/derived-summary.js +10 -8
- package/lib/directive-diagnostics.js +38 -0
- package/lib/directive-type-rules.js +133 -0
- package/lib/discover-fields.js +435 -0
- package/lib/discover-fields.types.ts +52 -0
- package/lib/document-node-identity.js +317 -0
- package/lib/format-node-header.js +9 -7
- package/lib/format-output-metadata.js +15 -23
- package/lib/layout-stored-queries.js +124 -85
- package/lib/load-patram-config.js +433 -96
- package/lib/load-patram-config.types.ts +98 -3
- package/lib/load-project-graph.js +4 -1
- package/lib/output-view.types.ts +14 -6
- package/lib/parse-cli-arguments.types.ts +1 -1
- package/lib/parse-where-clause.js +344 -107
- package/lib/parse-where-clause.types.ts +25 -8
- package/lib/patram-cli.js +68 -4
- package/lib/patram-config.js +31 -31
- package/lib/patram-config.types.ts +10 -4
- package/lib/query-graph.js +269 -40
- package/lib/query-inspection.js +440 -60
- package/lib/render-field-discovery.js +184 -0
- package/lib/render-json-output.js +21 -22
- package/lib/render-output-view.js +301 -34
- package/lib/render-plain-output.js +1 -1
- package/lib/render-rich-output.js +1 -1
- package/lib/render-rich-source.js +245 -14
- package/lib/resolve-patram-graph-config.js +15 -9
- package/lib/show-document.js +66 -9
- package/package.json +5 -5
|
@@ -1,53 +1,24 @@
|
|
|
1
|
+
/** @import * as $k$$l$document$j$node$j$identity$k$js from './document-node-identity.js'; */
|
|
1
2
|
/**
|
|
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);
|
|
9
|
+
import { normalizeRepoRelativePath } from './document-node-identity.js';
|
|
22
10
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
source_path,
|
|
30
|
-
mapping_definition.node.kind,
|
|
31
|
-
);
|
|
32
|
-
const entity_key = getStringClaimValue(claim);
|
|
33
|
-
const existing_entity_key = document_entity_keys.get(entity_map_key);
|
|
34
|
-
|
|
35
|
-
if (existing_entity_key && existing_entity_key !== entity_key) {
|
|
36
|
-
throw new Error(
|
|
37
|
-
`Document "${source_path}" defines multiple ${mapping_definition.node.kind} 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.
|
|
49
20
|
*
|
|
50
|
-
* @param {{ field: string, key?: 'path' | 'value',
|
|
21
|
+
* @param {{ field: string, key?: 'path' | 'value', class: string }} node_mapping
|
|
51
22
|
* @param {PatramClaim} claim
|
|
52
23
|
* @param {Map<string, string>} document_entity_keys
|
|
53
24
|
* @returns {string}
|
|
@@ -55,7 +26,7 @@ export function collectDocumentEntityKeys(mappings, claims) {
|
|
|
55
26
|
export function resolveNodeKey(node_mapping, claim, document_entity_keys) {
|
|
56
27
|
const source_key = normalizeRepoRelativePath(claim.origin.path);
|
|
57
28
|
|
|
58
|
-
if (node_mapping.
|
|
29
|
+
if (node_mapping.class === 'document') {
|
|
59
30
|
return source_key;
|
|
60
31
|
}
|
|
61
32
|
|
|
@@ -65,7 +36,7 @@ export function resolveNodeKey(node_mapping, claim, document_entity_keys) {
|
|
|
65
36
|
|
|
66
37
|
return (
|
|
67
38
|
document_entity_keys.get(
|
|
68
|
-
getDocumentEntityMapKey(source_key, node_mapping.
|
|
39
|
+
getDocumentEntityMapKey(source_key, node_mapping.class),
|
|
69
40
|
) ?? source_key
|
|
70
41
|
);
|
|
71
42
|
}
|
|
@@ -73,123 +44,95 @@ export function resolveNodeKey(node_mapping, claim, document_entity_keys) {
|
|
|
73
44
|
/**
|
|
74
45
|
* Resolve one edge target key and canonical path.
|
|
75
46
|
*
|
|
76
|
-
* @param {string}
|
|
47
|
+
* @param {string} target_class
|
|
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, import('./document-node-identity.js').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') {
|
|
91
|
-
return resolveValueTargetReference(
|
|
64
|
+
return resolveValueTargetReference(target_class, claim);
|
|
92
65
|
}
|
|
93
66
|
|
|
94
67
|
return resolvePathTargetReference(
|
|
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
|
|
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
|
|
109
|
-
if (!source_path
|
|
82
|
+
export function setCanonicalPath(graph_node, source_path) {
|
|
83
|
+
if (!source_path) {
|
|
110
84
|
return;
|
|
111
85
|
}
|
|
112
86
|
|
|
113
|
-
if (!graph_node
|
|
87
|
+
if (!graph_node.$path) {
|
|
88
|
+
graph_node.$path = source_path;
|
|
114
89
|
graph_node.path = source_path;
|
|
115
90
|
return;
|
|
116
91
|
}
|
|
117
92
|
|
|
118
|
-
if (graph_node
|
|
93
|
+
if (graph_node.$path !== source_path) {
|
|
119
94
|
throw new Error(
|
|
120
95
|
`Node "${graph_node.id}" maps to multiple canonical paths.`,
|
|
121
96
|
);
|
|
122
97
|
}
|
|
123
98
|
}
|
|
124
99
|
|
|
125
|
-
/**
|
|
126
|
-
* Normalize one repo-relative source path.
|
|
127
|
-
*
|
|
128
|
-
* @param {string} source_path
|
|
129
|
-
* @returns {string}
|
|
130
|
-
*/
|
|
131
|
-
export function normalizeRepoRelativePath(source_path) {
|
|
132
|
-
return posix.normalize(source_path.replaceAll('\\', '/'));
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
/**
|
|
136
|
-
* @param {Record<string, MappingDefinition>} mappings
|
|
137
|
-
* @param {PatramClaim} claim
|
|
138
|
-
* @returns {MappingDefinition | null}
|
|
139
|
-
*/
|
|
140
|
-
function resolveMappingDefinition(mappings, claim) {
|
|
141
|
-
if (claim.type === 'directive') {
|
|
142
|
-
return resolveDirectiveMapping(mappings, claim);
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return mappings[claim.type] ?? null;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
/**
|
|
149
|
-
* @param {Record<string, MappingDefinition>} mappings
|
|
150
|
-
* @param {PatramClaim} claim
|
|
151
|
-
* @returns {MappingDefinition | null}
|
|
152
|
-
*/
|
|
153
|
-
function resolveDirectiveMapping(mappings, claim) {
|
|
154
|
-
if (!claim.parser || !claim.name) {
|
|
155
|
-
return null;
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
return mappings[`${claim.parser}.directive.${claim.name}`] ?? null;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
100
|
/**
|
|
162
101
|
* @param {string} target_kind
|
|
163
102
|
* @param {PatramClaim} claim
|
|
164
|
-
* @returns {{ key: string, path?: string }}
|
|
103
|
+
* @returns {{ class_name: string, key: string, path?: string }}
|
|
165
104
|
*/
|
|
166
105
|
function resolveValueTargetReference(target_kind, claim) {
|
|
167
106
|
const target_key = getStringClaimValue(claim);
|
|
168
107
|
|
|
169
108
|
if (target_kind === 'document') {
|
|
170
109
|
return {
|
|
110
|
+
class_name: 'document',
|
|
171
111
|
key: target_key,
|
|
172
112
|
path: target_key,
|
|
173
113
|
};
|
|
174
114
|
}
|
|
175
115
|
|
|
176
116
|
return {
|
|
117
|
+
class_name: target_kind,
|
|
177
118
|
key: target_key,
|
|
178
119
|
path: normalizeRepoRelativePath(claim.origin.path),
|
|
179
120
|
};
|
|
180
121
|
}
|
|
181
122
|
|
|
182
123
|
/**
|
|
183
|
-
* @param {string}
|
|
124
|
+
* @param {string} target_class
|
|
184
125
|
* @param {PatramClaim} claim
|
|
185
126
|
* @param {Map<string, string>} document_entity_keys
|
|
127
|
+
* @param {Map<string, import('./document-node-identity.js').DocumentNodeReference>} document_node_references
|
|
186
128
|
* @param {Set<string>} document_paths
|
|
187
|
-
* @returns {{ key: string, path?: string }}
|
|
129
|
+
* @returns {{ class_name: string, key: string, path?: string }}
|
|
188
130
|
*/
|
|
189
131
|
function resolvePathTargetReference(
|
|
190
|
-
|
|
132
|
+
target_class,
|
|
191
133
|
claim,
|
|
192
134
|
document_entity_keys,
|
|
135
|
+
document_node_references,
|
|
193
136
|
document_paths,
|
|
194
137
|
) {
|
|
195
138
|
const raw_target = getPathTargetValue(claim);
|
|
@@ -199,19 +142,52 @@ function resolvePathTargetReference(
|
|
|
199
142
|
document_paths,
|
|
200
143
|
);
|
|
201
144
|
|
|
202
|
-
if (
|
|
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)) {
|
|
203
155
|
return {
|
|
204
|
-
|
|
156
|
+
class_name: document_node_reference.class_name,
|
|
157
|
+
key: document_node_reference.key,
|
|
205
158
|
path: target_path,
|
|
206
159
|
};
|
|
207
160
|
}
|
|
208
161
|
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
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, import('./document-node-identity.js').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
|
+
}
|
|
212
187
|
|
|
213
188
|
return {
|
|
214
|
-
|
|
189
|
+
class_name: document_node_reference.class_name,
|
|
190
|
+
key: document_node_reference.key,
|
|
215
191
|
path: target_path,
|
|
216
192
|
};
|
|
217
193
|
}
|
|
@@ -262,9 +238,20 @@ function getStringClaimValue(claim) {
|
|
|
262
238
|
|
|
263
239
|
/**
|
|
264
240
|
* @param {string} document_path
|
|
265
|
-
* @param {string}
|
|
241
|
+
* @param {string} class_name
|
|
266
242
|
* @returns {string}
|
|
267
243
|
*/
|
|
268
|
-
function getDocumentEntityMapKey(document_path,
|
|
269
|
-
return `${
|
|
244
|
+
function getDocumentEntityMapKey(document_path, class_name) {
|
|
245
|
+
return `${class_name}:${document_path}`;
|
|
246
|
+
}
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* @param {import('./document-node-identity.js').DocumentNodeReference | undefined} document_node_reference
|
|
250
|
+
* @returns {document_node_reference is $k$$l$document$j$node$j$identity$k$js.DocumentNodeReference}
|
|
251
|
+
*/
|
|
252
|
+
function documentNodeReferenceIsPromoted(document_node_reference) {
|
|
253
|
+
return (
|
|
254
|
+
document_node_reference !== undefined &&
|
|
255
|
+
document_node_reference.class_name !== 'document'
|
|
256
|
+
);
|
|
270
257
|
}
|