patram 0.10.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 (117) hide show
  1. package/bin/patram.js +4 -4
  2. package/lib/cli/arguments.types.d.ts +1 -0
  3. package/lib/cli/commands/check.js +27 -15
  4. package/lib/cli/commands/fields.js +0 -4
  5. package/lib/cli/commands/queries.js +179 -1
  6. package/lib/cli/commands/query.js +1 -8
  7. package/lib/cli/commands/refs.js +3 -10
  8. package/lib/cli/commands/show.js +1 -8
  9. package/lib/cli/help-metadata.js +106 -111
  10. package/lib/cli/main.js +10 -10
  11. package/lib/cli/parse-arguments-helpers.js +416 -66
  12. package/lib/cli/parse-arguments.js +4 -4
  13. package/lib/cli/render-help.js +10 -4
  14. package/lib/config/defaults.js +33 -25
  15. package/lib/config/load-patram-config.d.ts +19 -33
  16. package/lib/config/load-patram-config.js +18 -121
  17. package/lib/config/load-patram-config.types.d.ts +3 -40
  18. package/lib/config/manage-stored-queries-helpers.d.ts +69 -0
  19. package/lib/config/manage-stored-queries-helpers.js +320 -0
  20. package/lib/config/manage-stored-queries-jsonc.d.ts +31 -0
  21. package/lib/config/manage-stored-queries-jsonc.js +95 -0
  22. package/lib/config/manage-stored-queries.d.ts +77 -0
  23. package/lib/config/manage-stored-queries.js +300 -0
  24. package/lib/config/patram-config.d.ts +34 -34
  25. package/lib/config/patram-config.js +3 -3
  26. package/lib/config/patram-config.types.d.ts +5 -11
  27. package/lib/config/resolve-patram-graph-config.d.ts +5 -1
  28. package/lib/config/resolve-patram-graph-config.js +3 -119
  29. package/lib/config/schema.d.ts +158 -269
  30. package/lib/config/schema.js +72 -210
  31. package/lib/config/validate-patram-config-value.d.ts +13 -0
  32. package/lib/config/validate-patram-config-value.js +94 -0
  33. package/lib/config/validation.d.ts +2 -12
  34. package/lib/config/validation.js +125 -483
  35. package/lib/find-close-match.d.ts +4 -1
  36. package/lib/graph/build-graph-identity.d.ts +1 -32
  37. package/lib/graph/build-graph-identity.js +5 -269
  38. package/lib/graph/build-graph.d.ts +13 -4
  39. package/lib/graph/build-graph.js +347 -488
  40. package/lib/graph/build-graph.types.d.ts +8 -9
  41. package/lib/graph/check-directive-metadata-helpers.d.ts +30 -0
  42. package/lib/graph/check-directive-metadata-helpers.js +126 -0
  43. package/lib/graph/check-directive-metadata.d.ts +8 -9
  44. package/lib/graph/check-directive-metadata.js +70 -561
  45. package/lib/graph/check-directive-path-target.d.ts +6 -13
  46. package/lib/graph/check-directive-path-target.js +26 -57
  47. package/lib/graph/check-directive-value.d.ts +1 -5
  48. package/lib/graph/check-directive-value.js +40 -180
  49. package/lib/graph/check-graph.d.ts +5 -5
  50. package/lib/graph/check-graph.js +8 -6
  51. package/lib/graph/document-node-identity.d.ts +23 -7
  52. package/lib/graph/document-node-identity.js +417 -160
  53. package/lib/graph/graph-node.d.ts +42 -0
  54. package/lib/graph/graph-node.js +83 -0
  55. package/lib/graph/inspect-reverse-references.js +16 -11
  56. package/lib/graph/load-project-graph.d.ts +7 -7
  57. package/lib/graph/load-project-graph.js +7 -7
  58. package/lib/graph/parse-where-clause.types.d.ts +3 -2
  59. package/lib/graph/query/cypher-reader.d.ts +59 -0
  60. package/lib/graph/query/cypher-reader.js +151 -0
  61. package/lib/graph/query/cypher-support.d.ts +79 -0
  62. package/lib/graph/query/cypher-support.js +213 -0
  63. package/lib/graph/query/cypher-tokenize.d.ts +13 -0
  64. package/lib/graph/query/cypher-tokenize.js +225 -0
  65. package/lib/graph/query/cypher.types.d.ts +43 -0
  66. package/lib/graph/query/execute.d.ts +7 -7
  67. package/lib/graph/query/execute.js +71 -33
  68. package/lib/graph/query/inspect.js +58 -24
  69. package/lib/graph/query/parse-cypher-patterns.d.ts +27 -0
  70. package/lib/graph/query/parse-cypher-patterns.js +382 -0
  71. package/lib/graph/query/parse-cypher.d.ts +7 -0
  72. package/lib/graph/query/parse-cypher.js +580 -0
  73. package/lib/graph/query/parse-query.d.ts +13 -0
  74. package/lib/graph/query/parse-query.js +97 -0
  75. package/lib/graph/query/resolve.d.ts +6 -0
  76. package/lib/graph/query/resolve.js +81 -24
  77. package/lib/output/command-output.js +12 -5
  78. package/lib/output/compact-layout.js +221 -0
  79. package/lib/output/format-output-item-block.js +31 -1
  80. package/lib/output/format-output-metadata.js +16 -29
  81. package/lib/output/format-stored-query-block.js +95 -0
  82. package/lib/output/layout-incoming-references.js +101 -19
  83. package/lib/output/layout-stored-queries.js +23 -330
  84. package/lib/output/list-queries.js +1 -1
  85. package/lib/output/render-field-discovery.js +11 -2
  86. package/lib/output/render-output-view.js +9 -5
  87. package/lib/output/renderers/json.js +5 -26
  88. package/lib/output/renderers/plain.js +155 -35
  89. package/lib/output/renderers/rich.js +250 -36
  90. package/lib/output/resolve-check-target.js +120 -11
  91. package/lib/output/resolved-link-layout.js +43 -0
  92. package/lib/output/rich-source/render.js +193 -35
  93. package/lib/output/show-document.js +25 -18
  94. package/lib/output/view-model/index.js +124 -103
  95. package/lib/parse/jsdoc/parse-jsdoc-blocks.js +1 -1
  96. package/lib/parse/jsdoc/parse-jsdoc-claims.js +12 -6
  97. package/lib/parse/markdown/parse-markdown-claims.js +99 -62
  98. package/lib/parse/markdown/parse-markdown-directives.d.ts +10 -6
  99. package/lib/parse/markdown/parse-markdown-directives.js +104 -18
  100. package/lib/parse/markdown/parse-markdown-prose.d.ts +27 -0
  101. package/lib/parse/markdown/parse-markdown-prose.js +243 -0
  102. package/lib/parse/parse-claims.d.ts +2 -6
  103. package/lib/parse/parse-claims.js +11 -53
  104. package/lib/parse/tagged-fenced/tagged-fenced-blocks.d.ts +4 -4
  105. package/lib/parse/tagged-fenced/tagged-fenced-blocks.js +4 -4
  106. package/lib/parse/yaml/parse-yaml-claims.js +4 -4
  107. package/lib/patram.d.ts +9 -3
  108. package/lib/patram.js +1 -1
  109. package/lib/scan/discover-fields.js +194 -55
  110. package/lib/scan/list-source-files.d.ts +4 -4
  111. package/lib/scan/list-source-files.js +4 -4
  112. package/package.json +2 -1
  113. package/lib/directive-validation-test-helpers.js +0 -87
  114. package/lib/graph/query/parse.d.ts +0 -75
  115. package/lib/graph/query/parse.js +0 -1064
  116. package/lib/output/derived-summary.js +0 -280
  117. 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
- }