patram 0.11.0 → 0.12.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 (110) hide show
  1. package/bin/patram.js +4 -4
  2. package/lib/cli/commands/fields.js +0 -4
  3. package/lib/cli/commands/queries.js +10 -20
  4. package/lib/cli/commands/query.js +1 -8
  5. package/lib/cli/commands/refs.js +3 -10
  6. package/lib/cli/commands/show.js +1 -8
  7. package/lib/cli/help-metadata.js +71 -106
  8. package/lib/cli/main.js +10 -10
  9. package/lib/cli/parse-arguments-helpers.js +165 -59
  10. package/lib/cli/parse-arguments.js +4 -4
  11. package/lib/cli/render-help.js +2 -2
  12. package/lib/config/defaults.js +33 -25
  13. package/lib/config/load-patram-config.d.ts +8 -33
  14. package/lib/config/load-patram-config.js +9 -33
  15. package/lib/config/load-patram-config.types.d.ts +3 -40
  16. package/lib/config/manage-stored-queries-helpers.d.ts +4 -4
  17. package/lib/config/manage-stored-queries-helpers.js +91 -33
  18. package/lib/config/manage-stored-queries.d.ts +4 -4
  19. package/lib/config/manage-stored-queries.js +11 -5
  20. package/lib/config/patram-config.d.ts +34 -34
  21. package/lib/config/patram-config.js +3 -3
  22. package/lib/config/patram-config.types.d.ts +5 -11
  23. package/lib/config/resolve-patram-graph-config.d.ts +5 -1
  24. package/lib/config/resolve-patram-graph-config.js +3 -119
  25. package/lib/config/schema.d.ts +158 -269
  26. package/lib/config/schema.js +72 -210
  27. package/lib/config/validate-patram-config-value.js +6 -31
  28. package/lib/config/validation.d.ts +2 -12
  29. package/lib/config/validation.js +125 -483
  30. package/lib/find-close-match.d.ts +4 -1
  31. package/lib/graph/build-graph-identity.d.ts +1 -32
  32. package/lib/graph/build-graph-identity.js +5 -269
  33. package/lib/graph/build-graph.d.ts +13 -4
  34. package/lib/graph/build-graph.js +347 -488
  35. package/lib/graph/build-graph.types.d.ts +8 -9
  36. package/lib/graph/check-directive-metadata-helpers.d.ts +30 -0
  37. package/lib/graph/check-directive-metadata-helpers.js +126 -0
  38. package/lib/graph/check-directive-metadata.d.ts +8 -9
  39. package/lib/graph/check-directive-metadata.js +70 -561
  40. package/lib/graph/check-directive-path-target.d.ts +6 -13
  41. package/lib/graph/check-directive-path-target.js +26 -57
  42. package/lib/graph/check-directive-value.d.ts +1 -5
  43. package/lib/graph/check-directive-value.js +40 -180
  44. package/lib/graph/check-graph.d.ts +5 -5
  45. package/lib/graph/check-graph.js +8 -6
  46. package/lib/graph/document-node-identity.d.ts +23 -7
  47. package/lib/graph/document-node-identity.js +417 -160
  48. package/lib/graph/graph-node.d.ts +42 -0
  49. package/lib/graph/graph-node.js +83 -0
  50. package/lib/graph/inspect-reverse-references.js +16 -11
  51. package/lib/graph/load-project-graph.d.ts +7 -7
  52. package/lib/graph/load-project-graph.js +7 -7
  53. package/lib/graph/parse-where-clause.types.d.ts +3 -2
  54. package/lib/graph/query/cypher-reader.d.ts +59 -0
  55. package/lib/graph/query/cypher-reader.js +151 -0
  56. package/lib/graph/query/cypher-support.d.ts +79 -0
  57. package/lib/graph/query/cypher-support.js +213 -0
  58. package/lib/graph/query/cypher-tokenize.d.ts +13 -0
  59. package/lib/graph/query/cypher-tokenize.js +225 -0
  60. package/lib/graph/query/cypher.types.d.ts +43 -0
  61. package/lib/graph/query/execute.d.ts +7 -7
  62. package/lib/graph/query/execute.js +71 -33
  63. package/lib/graph/query/inspect.js +58 -24
  64. package/lib/graph/query/parse-cypher-patterns.d.ts +27 -0
  65. package/lib/graph/query/parse-cypher-patterns.js +382 -0
  66. package/lib/graph/query/parse-cypher.d.ts +7 -0
  67. package/lib/graph/query/parse-cypher.js +580 -0
  68. package/lib/graph/query/parse-query.d.ts +13 -0
  69. package/lib/graph/query/parse-query.js +97 -0
  70. package/lib/graph/query/resolve.js +77 -23
  71. package/lib/output/command-output.js +12 -5
  72. package/lib/output/compact-layout.js +221 -0
  73. package/lib/output/format-output-item-block.js +31 -1
  74. package/lib/output/format-output-metadata.js +16 -29
  75. package/lib/output/format-stored-query-block.js +95 -0
  76. package/lib/output/layout-incoming-references.js +101 -19
  77. package/lib/output/layout-stored-queries.js +23 -330
  78. package/lib/output/list-queries.js +1 -1
  79. package/lib/output/render-field-discovery.js +11 -2
  80. package/lib/output/render-output-view.js +9 -5
  81. package/lib/output/renderers/json.js +5 -26
  82. package/lib/output/renderers/plain.js +155 -35
  83. package/lib/output/renderers/rich.js +250 -36
  84. package/lib/output/resolved-link-layout.js +43 -0
  85. package/lib/output/rich-source/render.js +193 -35
  86. package/lib/output/show-document.js +25 -18
  87. package/lib/output/view-model/index.js +124 -103
  88. package/lib/parse/jsdoc/parse-jsdoc-blocks.js +1 -1
  89. package/lib/parse/jsdoc/parse-jsdoc-claims.js +12 -6
  90. package/lib/parse/markdown/parse-markdown-claims.js +99 -62
  91. package/lib/parse/markdown/parse-markdown-directives.d.ts +10 -6
  92. package/lib/parse/markdown/parse-markdown-directives.js +104 -18
  93. package/lib/parse/markdown/parse-markdown-prose.d.ts +27 -0
  94. package/lib/parse/markdown/parse-markdown-prose.js +243 -0
  95. package/lib/parse/parse-claims.d.ts +2 -6
  96. package/lib/parse/parse-claims.js +11 -53
  97. package/lib/parse/tagged-fenced/tagged-fenced-blocks.d.ts +4 -4
  98. package/lib/parse/tagged-fenced/tagged-fenced-blocks.js +4 -4
  99. package/lib/parse/yaml/parse-yaml-claims.js +4 -4
  100. package/lib/patram.d.ts +3 -5
  101. package/lib/patram.js +1 -1
  102. package/lib/scan/discover-fields.js +194 -55
  103. package/lib/scan/list-source-files.d.ts +4 -4
  104. package/lib/scan/list-source-files.js +4 -4
  105. package/package.json +1 -1
  106. package/lib/directive-validation-test-helpers.js +0 -87
  107. package/lib/graph/query/parse.d.ts +0 -75
  108. package/lib/graph/query/parse.js +0 -1064
  109. package/lib/output/derived-summary.js +0 -280
  110. package/lib/output/format-derived-summary-row.js +0 -9
@@ -1,280 +0,0 @@
1
- /**
2
- * @import { BuildGraphResult, GraphNode } from '../graph/build-graph.types.ts';
3
- * @import { OutputDerivedSummary } from './output-view.types.ts';
4
- * @import { DerivedSummaryConfig, DerivedSummaryFieldConfig, DerivedSummaryScalar, PatramRepoConfig } from '../config/load-patram-config.types.ts';
5
- */
6
-
7
- import { queryGraph } from '../graph/query/execute.js';
8
-
9
- /**
10
- * Derived summary evaluation.
11
- *
12
- * Evaluates repo-configured output-only metadata for graph nodes without
13
- * mutating graph state.
14
- *
15
- * Kind: output
16
- * Status: active
17
- * Tracked in: ../../docs/plans/v0/declarative-derived-summaries.md
18
- * Decided by: ../../docs/decisions/declarative-derived-summary-config.md
19
- * Decided by: ../../docs/decisions/declarative-derived-summary-side-effects.md
20
- * @patram
21
- * @see {@link ../config/load-patram-config.js}
22
- * @see {@link ./render-output-view.js}
23
- */
24
-
25
- /**
26
- * @typedef {{
27
- * evaluate: (graph_node: GraphNode) => OutputDerivedSummary | null,
28
- * }} DerivedSummaryEvaluator
29
- */
30
-
31
- /**
32
- * @param {PatramRepoConfig} repo_config
33
- * @param {BuildGraphResult} graph
34
- * @returns {DerivedSummaryEvaluator}
35
- */
36
- export function createDerivedSummaryEvaluator(repo_config, graph) {
37
- const summary_by_class = createSummaryByClass(repo_config.derived_summaries);
38
- /** @type {Map<string, Set<string>>} */
39
- const matching_node_id_cache = new Map();
40
-
41
- return {
42
- evaluate(graph_node) {
43
- const configured_summary = summary_by_class.get(
44
- graph_node.$class ?? 'document',
45
- );
46
-
47
- if (!configured_summary) {
48
- return null;
49
- }
50
-
51
- return {
52
- fields: configured_summary.definition.fields.map(
53
- (field_definition) => ({
54
- name: field_definition.name,
55
- value: evaluateFieldValue(
56
- field_definition,
57
- configured_summary.definition,
58
- graph,
59
- graph_node,
60
- matching_node_id_cache,
61
- ),
62
- }),
63
- ),
64
- name: configured_summary.name,
65
- };
66
- },
67
- };
68
- }
69
-
70
- /**
71
- * @param {DerivedSummaryFieldConfig} field_definition
72
- * @param {DerivedSummaryConfig} summary_definition
73
- * @param {BuildGraphResult} graph
74
- * @param {GraphNode} graph_node
75
- * @param {Map<string, Set<string>>} matching_node_id_cache
76
- * @returns {DerivedSummaryScalar}
77
- */
78
- function evaluateFieldValue(
79
- field_definition,
80
- summary_definition,
81
- graph,
82
- graph_node,
83
- matching_node_id_cache,
84
- ) {
85
- if ('count' in field_definition) {
86
- return countMatchingTraversalNodes(
87
- graph,
88
- graph_node,
89
- field_definition.count.traversal,
90
- field_definition.count.where,
91
- matching_node_id_cache,
92
- );
93
- }
94
-
95
- return selectFieldValue(
96
- graph,
97
- graph_node,
98
- summary_definition,
99
- field_definition,
100
- matching_node_id_cache,
101
- );
102
- }
103
-
104
- /**
105
- * @param {BuildGraphResult} graph
106
- * @param {GraphNode} graph_node
107
- * @param {string} traversal_text
108
- * @param {string} where_clause
109
- * @param {Map<string, Set<string>>} matching_node_id_cache
110
- * @returns {number}
111
- */
112
- function countMatchingTraversalNodes(
113
- graph,
114
- graph_node,
115
- traversal_text,
116
- where_clause,
117
- matching_node_id_cache,
118
- ) {
119
- const target_node_ids = getTraversedNodeIds(
120
- graph,
121
- graph_node.id,
122
- traversal_text,
123
- );
124
-
125
- if (target_node_ids.size === 0) {
126
- return 0;
127
- }
128
-
129
- const matching_node_ids = getMatchingNodeIds(
130
- graph,
131
- where_clause,
132
- matching_node_id_cache,
133
- );
134
- let matching_count = 0;
135
-
136
- for (const target_node_id of target_node_ids) {
137
- if (matching_node_ids.has(target_node_id)) {
138
- matching_count += 1;
139
- }
140
- }
141
-
142
- return matching_count;
143
- }
144
-
145
- /**
146
- * @param {BuildGraphResult} graph
147
- * @param {GraphNode} graph_node
148
- * @param {DerivedSummaryConfig} summary_definition
149
- * @param {Extract<DerivedSummaryFieldConfig, { select: unknown }>} field_definition
150
- * @param {Map<string, Set<string>>} matching_node_id_cache
151
- * @returns {DerivedSummaryScalar}
152
- */
153
- function selectFieldValue(
154
- graph,
155
- graph_node,
156
- summary_definition,
157
- field_definition,
158
- matching_node_id_cache,
159
- ) {
160
- for (const select_case of field_definition.select) {
161
- const matching_node_ids = getMatchingNodeIds(
162
- graph,
163
- select_case.when,
164
- matching_node_id_cache,
165
- );
166
-
167
- if (matching_node_ids.has(graph_node.id)) {
168
- return select_case.value;
169
- }
170
- }
171
-
172
- return field_definition.default;
173
- }
174
-
175
- /**
176
- * @param {BuildGraphResult} graph
177
- * @param {string} where_clause
178
- * @param {Map<string, Set<string>>} matching_node_id_cache
179
- * @returns {Set<string>}
180
- */
181
- function getMatchingNodeIds(graph, where_clause, matching_node_id_cache) {
182
- const cached_node_ids = matching_node_id_cache.get(where_clause);
183
-
184
- if (cached_node_ids) {
185
- return cached_node_ids;
186
- }
187
-
188
- const query_result = queryGraph(graph, where_clause);
189
-
190
- if (query_result.diagnostics.length > 0) {
191
- throw new Error(
192
- `Expected derived summary query "${where_clause}" to be valid.`,
193
- );
194
- }
195
-
196
- const matching_node_ids = new Set(
197
- query_result.nodes.map((matching_node) => matching_node.id),
198
- );
199
-
200
- matching_node_id_cache.set(where_clause, matching_node_ids);
201
-
202
- return matching_node_ids;
203
- }
204
-
205
- /**
206
- * @param {BuildGraphResult} graph
207
- * @param {string} node_id
208
- * @param {string} traversal_text
209
- * @returns {Set<string>}
210
- */
211
- function getTraversedNodeIds(graph, node_id, traversal_text) {
212
- const traversal = parseTraversal(traversal_text);
213
- /** @type {Set<string>} */
214
- const target_node_ids = new Set();
215
-
216
- for (const graph_edge of graph.edges) {
217
- if (graph_edge.relation !== traversal.relation_name) {
218
- continue;
219
- }
220
-
221
- if (traversal.direction === 'in' && graph_edge.to === node_id) {
222
- target_node_ids.add(graph_edge.from);
223
- }
224
-
225
- if (traversal.direction === 'out' && graph_edge.from === node_id) {
226
- target_node_ids.add(graph_edge.to);
227
- }
228
- }
229
-
230
- return target_node_ids;
231
- }
232
-
233
- /**
234
- * @param {string} traversal_text
235
- * @returns {{ direction: 'in' | 'out', relation_name: string }}
236
- */
237
- function parseTraversal(traversal_text) {
238
- const traversal_match =
239
- /^(?<direction>in|out):(?<relation_name>[a-zA-Z0-9_]+)$/du.exec(
240
- traversal_text,
241
- );
242
-
243
- if (
244
- !traversal_match?.groups?.direction ||
245
- !traversal_match.groups.relation_name
246
- ) {
247
- throw new Error(`Invalid derived summary traversal "${traversal_text}".`);
248
- }
249
-
250
- return {
251
- direction: /** @type {'in' | 'out'} */ (traversal_match.groups.direction),
252
- relation_name: traversal_match.groups.relation_name,
253
- };
254
- }
255
-
256
- /**
257
- * @param {PatramRepoConfig['derived_summaries']} derived_summaries
258
- * @returns {Map<string, { definition: DerivedSummaryConfig, name: string }>}
259
- */
260
- function createSummaryByClass(derived_summaries) {
261
- /** @type {Map<string, { definition: DerivedSummaryConfig, name: string }>} */
262
- const summary_by_class = new Map();
263
-
264
- if (!derived_summaries) {
265
- return summary_by_class;
266
- }
267
-
268
- for (const [summary_name, summary_definition] of Object.entries(
269
- derived_summaries,
270
- )) {
271
- for (const class_name of summary_definition.classes) {
272
- summary_by_class.set(class_name, {
273
- definition: summary_definition,
274
- name: summary_name,
275
- });
276
- }
277
- }
278
-
279
- return summary_by_class;
280
- }
@@ -1,9 +0,0 @@
1
- /**
2
- * @param {import('./output-view.types.ts').OutputDerivedSummary} derived_summary
3
- * @returns {string}
4
- */
5
- export function formatDerivedSummaryRow(derived_summary) {
6
- return derived_summary.fields
7
- .map((field) => `${field.name}: ${String(field.value)}`)
8
- .join(' ');
9
- }