patram 0.6.2 → 0.8.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.d.ts +40 -0
- package/lib/build-graph.d.ts +11 -0
- package/lib/build-graph.types.d.ts +24 -0
- package/lib/claim-helpers.d.ts +20 -0
- package/lib/cli-help-metadata.js +48 -9
- package/lib/command-output.js +1 -0
- package/lib/document-node-identity.d.ts +47 -0
- package/lib/inspect-reverse-references.js +184 -0
- package/lib/layout-incoming-references.js +105 -0
- package/lib/layout-incoming-summary-lines.js +21 -0
- package/lib/list-source-files.d.ts +29 -0
- package/lib/load-patram-config.d.ts +384 -0
- package/lib/load-patram-config.types.d.ts +45 -0
- package/lib/load-project-graph.d.ts +35 -0
- package/lib/output-view.types.d.ts +88 -0
- package/lib/output-view.types.ts +19 -2
- package/lib/overlay-graph.d.ts +43 -0
- package/lib/overlay-graph.js +191 -0
- package/lib/parse-claims.d.ts +40 -0
- package/lib/parse-claims.types.d.ts +31 -0
- package/lib/parse-cli-arguments-helpers.js +11 -4
- package/lib/parse-cli-arguments.types.ts +8 -2
- package/lib/parse-jsdoc-blocks.d.ts +15 -0
- package/lib/parse-jsdoc-claims.d.ts +9 -0
- package/lib/parse-jsdoc-prose.d.ts +28 -0
- package/lib/parse-markdown-claims.d.ts +14 -0
- package/lib/parse-markdown-directives.d.ts +34 -0
- package/lib/parse-where-clause.d.ts +75 -0
- package/lib/parse-where-clause.js +157 -37
- package/lib/parse-where-clause.types.d.ts +63 -0
- package/lib/parse-yaml-claims.d.ts +38 -0
- package/lib/patram-cli.js +66 -1
- package/lib/patram-config.d.ts +106 -0
- package/lib/patram-config.types.d.ts +14 -0
- package/lib/patram.d.ts +73 -0
- package/lib/patram.js +3 -0
- package/lib/query-graph.d.ts +68 -0
- package/lib/query-graph.js +27 -24
- package/lib/query-inspection.d.ts +86 -0
- package/lib/render-cli-help.js +1 -1
- package/lib/render-json-output.js +91 -62
- package/lib/render-output-view.js +58 -3
- package/lib/render-plain-output.js +46 -3
- package/lib/render-rich-output.js +50 -5
- package/lib/resolve-patram-graph-config.d.ts +9 -0
- package/lib/reverse-reference-test-helpers.js +76 -0
- package/lib/show-document.js +44 -6
- package/lib/source-file-defaults.d.ts +5 -0
- package/lib/tagged-fenced-block-error.d.ts +10 -0
- package/lib/tagged-fenced-block-markdown.d.ts +47 -0
- package/lib/tagged-fenced-block-metadata.d.ts +26 -0
- package/lib/tagged-fenced-block-parser.d.ts +61 -0
- package/lib/tagged-fenced-blocks.d.ts +39 -0
- package/lib/tagged-fenced-blocks.types.d.ts +32 -0
- package/package.json +13 -2
package/lib/patram.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
export {
|
|
2
|
+
extractTaggedFencedBlocks,
|
|
3
|
+
loadTaggedFencedBlocks,
|
|
4
|
+
selectTaggedBlock,
|
|
5
|
+
selectTaggedBlocks,
|
|
6
|
+
} from './tagged-fenced-blocks.js';
|
|
7
|
+
|
|
8
|
+
export { parseWhereClause } from './parse-where-clause.js';
|
|
9
|
+
export { getQuerySemanticDiagnostics } from './query-inspection.js';
|
|
10
|
+
export { loadProjectGraph } from './load-project-graph.js';
|
|
11
|
+
export { overlayGraph } from './overlay-graph.js';
|
|
12
|
+
export { queryGraph } from './query-graph.js';
|
|
13
|
+
|
|
14
|
+
export type PatramGraphNode = import('./build-graph.types.ts').GraphNode;
|
|
15
|
+
export type PatramGraphEdge = import('./build-graph.types.ts').GraphEdge;
|
|
16
|
+
export type PatramBuildGraphResult =
|
|
17
|
+
import('./build-graph.types.ts').BuildGraphResult;
|
|
18
|
+
export type PatramDiagnostic =
|
|
19
|
+
import('./load-patram-config.types.ts').PatramDiagnostic;
|
|
20
|
+
export type PatramRepoConfig =
|
|
21
|
+
import('./load-patram-config.types.ts').PatramRepoConfig;
|
|
22
|
+
export type PatramParsedFieldName =
|
|
23
|
+
import('./parse-where-clause.types.ts').ParsedFieldName;
|
|
24
|
+
export type PatramParsedFieldTerm =
|
|
25
|
+
import('./parse-where-clause.types.ts').ParsedFieldTerm;
|
|
26
|
+
export type PatramParsedFieldSetTerm =
|
|
27
|
+
import('./parse-where-clause.types.ts').ParsedFieldSetTerm;
|
|
28
|
+
export type PatramParsedTraversalTerm =
|
|
29
|
+
import('./parse-where-clause.types.ts').ParsedTraversalTerm;
|
|
30
|
+
export type PatramParsedRelationTerm =
|
|
31
|
+
import('./parse-where-clause.types.ts').ParsedRelationTerm;
|
|
32
|
+
export type PatramParsedRelationTargetTerm =
|
|
33
|
+
import('./parse-where-clause.types.ts').ParsedRelationTargetTerm;
|
|
34
|
+
export type PatramParsedAggregateComparison =
|
|
35
|
+
import('./parse-where-clause.types.ts').ParsedAggregateComparison;
|
|
36
|
+
export type PatramParsedAggregateName =
|
|
37
|
+
import('./parse-where-clause.types.ts').ParsedAggregateName;
|
|
38
|
+
export type PatramParsedAggregateTerm =
|
|
39
|
+
import('./parse-where-clause.types.ts').ParsedAggregateTerm;
|
|
40
|
+
export type PatramParsedTermExpression =
|
|
41
|
+
import('./parse-where-clause.types.ts').ParsedTermExpression;
|
|
42
|
+
export type PatramParsedNotExpression =
|
|
43
|
+
import('./parse-where-clause.types.ts').ParsedNotExpression;
|
|
44
|
+
export type PatramParsedBooleanExpression =
|
|
45
|
+
import('./parse-where-clause.types.ts').ParsedBooleanExpression;
|
|
46
|
+
export type PatramParsedTerm =
|
|
47
|
+
import('./parse-where-clause.types.ts').ParsedTerm;
|
|
48
|
+
export type PatramParsedExpression =
|
|
49
|
+
import('./parse-where-clause.types.ts').ParsedExpression;
|
|
50
|
+
export type PatramParseWhereClauseResult =
|
|
51
|
+
import('./parse-where-clause.types.ts').ParseWhereClauseResult;
|
|
52
|
+
export type PatramQuerySource =
|
|
53
|
+
| {
|
|
54
|
+
kind: 'ad_hoc';
|
|
55
|
+
}
|
|
56
|
+
| {
|
|
57
|
+
kind: 'stored_query';
|
|
58
|
+
name: string;
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
export interface PatramProjectGraphResult {
|
|
62
|
+
claims: import('./parse-claims.types.ts').PatramClaim[];
|
|
63
|
+
config: import('./load-patram-config.types.ts').PatramRepoConfig;
|
|
64
|
+
diagnostics: PatramDiagnostic[];
|
|
65
|
+
graph: PatramBuildGraphResult;
|
|
66
|
+
source_file_paths: string[];
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
export interface PatramQueryResult {
|
|
70
|
+
diagnostics: PatramDiagnostic[];
|
|
71
|
+
nodes: PatramGraphNode[];
|
|
72
|
+
total_count: number;
|
|
73
|
+
}
|
package/lib/patram.js
CHANGED
|
@@ -5,5 +5,8 @@ export {
|
|
|
5
5
|
selectTaggedBlocks,
|
|
6
6
|
} from './tagged-fenced-blocks.js';
|
|
7
7
|
|
|
8
|
+
export { parseWhereClause } from './parse-where-clause.js';
|
|
9
|
+
export { getQuerySemanticDiagnostics } from './query-inspection.js';
|
|
8
10
|
export { loadProjectGraph } from './load-project-graph.js';
|
|
11
|
+
export { overlayGraph } from './overlay-graph.js';
|
|
9
12
|
export { queryGraph } from './query-graph.js';
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {{
|
|
3
|
+
* incoming: Map<string, Map<string, Set<string>>>,
|
|
4
|
+
* outgoing: Map<string, Map<string, Set<string>>>,
|
|
5
|
+
* }} RelationIndexes
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {{
|
|
9
|
+
* bindings?: Record<string, string>,
|
|
10
|
+
* limit?: number,
|
|
11
|
+
* offset?: number,
|
|
12
|
+
* }} QueryGraphOptions
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* @typedef {{
|
|
16
|
+
* nodes: BuildGraphResult['nodes'],
|
|
17
|
+
* relation_indexes: RelationIndexes,
|
|
18
|
+
* }} EvaluationContext
|
|
19
|
+
*/
|
|
20
|
+
/**
|
|
21
|
+
* Filter graph nodes with the query language.
|
|
22
|
+
*
|
|
23
|
+
* @param {BuildGraphResult} graph
|
|
24
|
+
* @param {string} where_clause
|
|
25
|
+
* @param {PatramRepoConfig | QueryGraphOptions=} repo_config_or_query_options
|
|
26
|
+
* @param {QueryGraphOptions=} query_options
|
|
27
|
+
* @returns {{ diagnostics: PatramDiagnostic[], nodes: GraphNode[], total_count: number }}
|
|
28
|
+
*/
|
|
29
|
+
export function queryGraph(graph: BuildGraphResult, where_clause: string, repo_config_or_query_options?: (PatramRepoConfig | QueryGraphOptions) | undefined, query_options?: QueryGraphOptions | undefined): {
|
|
30
|
+
diagnostics: PatramDiagnostic[];
|
|
31
|
+
nodes: GraphNode[];
|
|
32
|
+
total_count: number;
|
|
33
|
+
};
|
|
34
|
+
/**
|
|
35
|
+
* Query graph filtering.
|
|
36
|
+
*
|
|
37
|
+
* Applies the v0 where-clause language to graph nodes and keeps pagination
|
|
38
|
+
* separate from matching.
|
|
39
|
+
*
|
|
40
|
+
* Kind: graph
|
|
41
|
+
* Status: active
|
|
42
|
+
* Uses Term: ../docs/reference/terms/graph.md
|
|
43
|
+
* Uses Term: ../docs/reference/terms/query.md
|
|
44
|
+
* Tracked in: ../docs/plans/v0/source-anchor-dogfooding.md
|
|
45
|
+
* Decided by: ../docs/decisions/query-language.md
|
|
46
|
+
* Implements: ../docs/tasks/v0/query-command.md
|
|
47
|
+
* @patram
|
|
48
|
+
* @see {@link ./load-project-graph.js}
|
|
49
|
+
* @see {@link ../docs/decisions/query-language.md}
|
|
50
|
+
*/
|
|
51
|
+
export const DEFAULT_QUERY_LIMIT: 25;
|
|
52
|
+
export type RelationIndexes = {
|
|
53
|
+
incoming: Map<string, Map<string, Set<string>>>;
|
|
54
|
+
outgoing: Map<string, Map<string, Set<string>>>;
|
|
55
|
+
};
|
|
56
|
+
export type QueryGraphOptions = {
|
|
57
|
+
bindings?: Record<string, string>;
|
|
58
|
+
limit?: number;
|
|
59
|
+
offset?: number;
|
|
60
|
+
};
|
|
61
|
+
export type EvaluationContext = {
|
|
62
|
+
nodes: BuildGraphResult["nodes"];
|
|
63
|
+
relation_indexes: RelationIndexes;
|
|
64
|
+
};
|
|
65
|
+
import type { BuildGraphResult } from './build-graph.types.ts';
|
|
66
|
+
import type { PatramRepoConfig } from './load-patram-config.types.ts';
|
|
67
|
+
import type { PatramDiagnostic } from './load-patram-config.types.ts';
|
|
68
|
+
import type { GraphNode } from './build-graph.types.ts';
|
package/lib/query-graph.js
CHANGED
|
@@ -43,6 +43,14 @@ export const DEFAULT_QUERY_LIMIT = 25;
|
|
|
43
43
|
* }} RelationIndexes
|
|
44
44
|
*/
|
|
45
45
|
|
|
46
|
+
/**
|
|
47
|
+
* @typedef {{
|
|
48
|
+
* bindings?: Record<string, string>,
|
|
49
|
+
* limit?: number,
|
|
50
|
+
* offset?: number,
|
|
51
|
+
* }} QueryGraphOptions
|
|
52
|
+
*/
|
|
53
|
+
|
|
46
54
|
/**
|
|
47
55
|
* @typedef {{
|
|
48
56
|
* nodes: BuildGraphResult['nodes'],
|
|
@@ -55,17 +63,21 @@ export const DEFAULT_QUERY_LIMIT = 25;
|
|
|
55
63
|
*
|
|
56
64
|
* @param {BuildGraphResult} graph
|
|
57
65
|
* @param {string} where_clause
|
|
58
|
-
* @param {PatramRepoConfig |
|
|
59
|
-
* @param {
|
|
66
|
+
* @param {PatramRepoConfig | QueryGraphOptions=} repo_config_or_query_options
|
|
67
|
+
* @param {QueryGraphOptions=} query_options
|
|
60
68
|
* @returns {{ diagnostics: PatramDiagnostic[], nodes: GraphNode[], total_count: number }}
|
|
61
69
|
*/
|
|
62
70
|
export function queryGraph(
|
|
63
71
|
graph,
|
|
64
72
|
where_clause,
|
|
65
|
-
|
|
66
|
-
|
|
73
|
+
repo_config_or_query_options = {},
|
|
74
|
+
query_options = {},
|
|
67
75
|
) {
|
|
68
|
-
const
|
|
76
|
+
const { query_options: resolved_query_options, repo_config } =
|
|
77
|
+
resolveQueryGraphOptions(repo_config_or_query_options, query_options);
|
|
78
|
+
const parse_result = parseWhereClause(where_clause, {
|
|
79
|
+
bindings: resolved_query_options.bindings,
|
|
80
|
+
});
|
|
69
81
|
|
|
70
82
|
if (!parse_result.success) {
|
|
71
83
|
return {
|
|
@@ -75,9 +87,6 @@ export function queryGraph(
|
|
|
75
87
|
};
|
|
76
88
|
}
|
|
77
89
|
|
|
78
|
-
const { pagination_options: resolved_pagination_options, repo_config } =
|
|
79
|
-
resolveQueryGraphOptions(repo_config_or_pagination, pagination_options);
|
|
80
|
-
|
|
81
90
|
if (repo_config) {
|
|
82
91
|
const diagnostics = getQuerySemanticDiagnostics(
|
|
83
92
|
repo_config,
|
|
@@ -102,10 +111,7 @@ export function queryGraph(
|
|
|
102
111
|
const matching_nodes = graph_nodes.filter((graph_node) =>
|
|
103
112
|
matchesExpression(graph_node, parse_result.expression, evaluation_context),
|
|
104
113
|
);
|
|
105
|
-
const paginated_nodes = paginateNodes(
|
|
106
|
-
matching_nodes,
|
|
107
|
-
resolved_pagination_options,
|
|
108
|
-
);
|
|
114
|
+
const paginated_nodes = paginateNodes(matching_nodes, resolved_query_options);
|
|
109
115
|
|
|
110
116
|
return {
|
|
111
117
|
diagnostics: [],
|
|
@@ -501,29 +507,26 @@ function getScalarFieldValue(field_value) {
|
|
|
501
507
|
}
|
|
502
508
|
|
|
503
509
|
/**
|
|
504
|
-
* @param {PatramRepoConfig |
|
|
505
|
-
* @param {
|
|
506
|
-
* @returns {{
|
|
510
|
+
* @param {PatramRepoConfig | QueryGraphOptions} repo_config_or_query_options
|
|
511
|
+
* @param {QueryGraphOptions} query_options
|
|
512
|
+
* @returns {{ query_options: QueryGraphOptions, repo_config: PatramRepoConfig | null }}
|
|
507
513
|
*/
|
|
508
|
-
function resolveQueryGraphOptions(
|
|
509
|
-
|
|
510
|
-
pagination_options,
|
|
511
|
-
) {
|
|
512
|
-
if (isRepoConfig(repo_config_or_pagination)) {
|
|
514
|
+
function resolveQueryGraphOptions(repo_config_or_query_options, query_options) {
|
|
515
|
+
if (isRepoConfig(repo_config_or_query_options)) {
|
|
513
516
|
return {
|
|
514
|
-
|
|
515
|
-
repo_config:
|
|
517
|
+
query_options,
|
|
518
|
+
repo_config: repo_config_or_query_options,
|
|
516
519
|
};
|
|
517
520
|
}
|
|
518
521
|
|
|
519
522
|
return {
|
|
520
|
-
|
|
523
|
+
query_options: repo_config_or_query_options,
|
|
521
524
|
repo_config: null,
|
|
522
525
|
};
|
|
523
526
|
}
|
|
524
527
|
|
|
525
528
|
/**
|
|
526
|
-
* @param {PatramRepoConfig |
|
|
529
|
+
* @param {PatramRepoConfig | QueryGraphOptions} value
|
|
527
530
|
* @returns {value is PatramRepoConfig}
|
|
528
531
|
*/
|
|
529
532
|
function isRepoConfig(value) {
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {{ kind: 'ad_hoc' } | { kind: 'stored_query', name: string }} QuerySource
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* @typedef {import('./parse-where-clause.types.ts').ParsedFieldTerm | import('./parse-where-clause.types.ts').ParsedFieldSetTerm} FieldDiagnosticTerm
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* @typedef {{ query_source: QuerySource, where_clause: string }} ResolvedWhereClause
|
|
9
|
+
*/
|
|
10
|
+
/**
|
|
11
|
+
* @typedef {{ inspection_mode: 'explain' | 'lint', limit: number | null, offset: number }} QueryInspectionOptions
|
|
12
|
+
*/
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {{
|
|
15
|
+
* execution?: {
|
|
16
|
+
* limit: number | null,
|
|
17
|
+
* offset: number,
|
|
18
|
+
* },
|
|
19
|
+
* expression?: ParsedExpression,
|
|
20
|
+
* inspection_mode: 'explain' | 'lint',
|
|
21
|
+
* query_source: QuerySource,
|
|
22
|
+
* where_clause: string,
|
|
23
|
+
* }} QueryInspectionSuccess
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Inspect one resolved query without executing it.
|
|
27
|
+
*
|
|
28
|
+
* @param {PatramRepoConfig} repo_config
|
|
29
|
+
* @param {ResolvedWhereClause} resolved_where_clause
|
|
30
|
+
* @param {QueryInspectionOptions} inspection_options
|
|
31
|
+
* @returns {{ success: true, value: QueryInspectionSuccess } | { diagnostics: PatramDiagnostic[], success: false }}
|
|
32
|
+
*/
|
|
33
|
+
export function inspectQuery(repo_config: PatramRepoConfig, resolved_where_clause: ResolvedWhereClause, inspection_options: QueryInspectionOptions): {
|
|
34
|
+
success: true;
|
|
35
|
+
value: QueryInspectionSuccess;
|
|
36
|
+
} | {
|
|
37
|
+
diagnostics: PatramDiagnostic[];
|
|
38
|
+
success: false;
|
|
39
|
+
};
|
|
40
|
+
/**
|
|
41
|
+
* Render a successful query inspection in one output mode.
|
|
42
|
+
*
|
|
43
|
+
* @param {QueryInspectionSuccess} query_inspection
|
|
44
|
+
* @param {ResolvedOutputMode} output_mode
|
|
45
|
+
* @returns {string}
|
|
46
|
+
*/
|
|
47
|
+
export function renderQueryInspection(query_inspection: QueryInspectionSuccess, output_mode: ResolvedOutputMode): string;
|
|
48
|
+
/**
|
|
49
|
+
* Collect schema-aware diagnostics for one parsed where clause.
|
|
50
|
+
*
|
|
51
|
+
* @param {PatramRepoConfig} repo_config
|
|
52
|
+
* @param {QuerySource} query_source
|
|
53
|
+
* @param {ParsedExpression} expression
|
|
54
|
+
* @returns {PatramDiagnostic[]}
|
|
55
|
+
*/
|
|
56
|
+
export function getQuerySemanticDiagnostics(repo_config: PatramRepoConfig, query_source: QuerySource, expression: ParsedExpression): PatramDiagnostic[];
|
|
57
|
+
export type QuerySource = {
|
|
58
|
+
kind: "ad_hoc";
|
|
59
|
+
} | {
|
|
60
|
+
kind: "stored_query";
|
|
61
|
+
name: string;
|
|
62
|
+
};
|
|
63
|
+
export type FieldDiagnosticTerm = import("./parse-where-clause.types.ts").ParsedFieldTerm | import("./parse-where-clause.types.ts").ParsedFieldSetTerm;
|
|
64
|
+
export type ResolvedWhereClause = {
|
|
65
|
+
query_source: QuerySource;
|
|
66
|
+
where_clause: string;
|
|
67
|
+
};
|
|
68
|
+
export type QueryInspectionOptions = {
|
|
69
|
+
inspection_mode: "explain" | "lint";
|
|
70
|
+
limit: number | null;
|
|
71
|
+
offset: number;
|
|
72
|
+
};
|
|
73
|
+
export type QueryInspectionSuccess = {
|
|
74
|
+
execution?: {
|
|
75
|
+
limit: number | null;
|
|
76
|
+
offset: number;
|
|
77
|
+
};
|
|
78
|
+
expression?: ParsedExpression;
|
|
79
|
+
inspection_mode: "explain" | "lint";
|
|
80
|
+
query_source: QuerySource;
|
|
81
|
+
where_clause: string;
|
|
82
|
+
};
|
|
83
|
+
import type { PatramRepoConfig } from './load-patram-config.types.ts';
|
|
84
|
+
import type { PatramDiagnostic } from './load-patram-config.types.ts';
|
|
85
|
+
import type { ResolvedOutputMode } from './output-view.types.ts';
|
|
86
|
+
import type { ParsedExpression } from './parse-where-clause.types.ts';
|
package/lib/render-cli-help.js
CHANGED
|
@@ -308,7 +308,7 @@ function renderInvalidCommandOptionError(command_name, invalid_token) {
|
|
|
308
308
|
}
|
|
309
309
|
|
|
310
310
|
/**
|
|
311
|
-
* @param {'query' | 'show'} command_name
|
|
311
|
+
* @param {'query' | 'refs' | 'show'} command_name
|
|
312
312
|
* @param {string} argument_label
|
|
313
313
|
* @returns {string}
|
|
314
314
|
*/
|
|
@@ -10,54 +10,113 @@
|
|
|
10
10
|
*/
|
|
11
11
|
export function renderJsonOutput(output_view) {
|
|
12
12
|
if (output_view.command === 'query') {
|
|
13
|
-
return
|
|
14
|
-
{
|
|
15
|
-
results: output_view.items.map(formatJsonQueryItem),
|
|
16
|
-
summary: {
|
|
17
|
-
shown_count: output_view.summary.count,
|
|
18
|
-
total_count: output_view.summary.total_count,
|
|
19
|
-
offset: output_view.summary.offset,
|
|
20
|
-
limit: output_view.summary.limit,
|
|
21
|
-
},
|
|
22
|
-
hints: output_view.hints,
|
|
23
|
-
},
|
|
24
|
-
null,
|
|
25
|
-
2,
|
|
26
|
-
)}\n`;
|
|
13
|
+
return renderJsonQueryOutput(output_view);
|
|
27
14
|
}
|
|
28
15
|
|
|
29
16
|
if (output_view.command === 'queries') {
|
|
30
|
-
return
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
2,
|
|
36
|
-
)}\n`;
|
|
17
|
+
return renderJsonQueriesOutput(output_view.items);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if (output_view.command === 'refs') {
|
|
21
|
+
return renderJsonRefsOutput(output_view);
|
|
37
22
|
}
|
|
38
23
|
|
|
39
24
|
if (output_view.command === 'show') {
|
|
40
|
-
return
|
|
41
|
-
{
|
|
42
|
-
document: output_view.document
|
|
43
|
-
? formatJsonShowDocument(output_view.document)
|
|
44
|
-
: undefined,
|
|
45
|
-
source: output_view.source,
|
|
46
|
-
resolved_links: output_view.items.map(formatJsonResolvedLink),
|
|
47
|
-
},
|
|
48
|
-
null,
|
|
49
|
-
2,
|
|
50
|
-
)}\n`;
|
|
25
|
+
return renderJsonShowOutput(output_view);
|
|
51
26
|
}
|
|
52
27
|
|
|
53
28
|
throw new Error('Unsupported output view command.');
|
|
54
29
|
}
|
|
55
30
|
|
|
31
|
+
/**
|
|
32
|
+
* @param {Extract<OutputView, { command: 'query' }>} output_view
|
|
33
|
+
* @returns {string}
|
|
34
|
+
*/
|
|
35
|
+
function renderJsonQueryOutput(output_view) {
|
|
36
|
+
return `${JSON.stringify(
|
|
37
|
+
{
|
|
38
|
+
results: output_view.items.map(formatJsonQueryItem),
|
|
39
|
+
summary: {
|
|
40
|
+
shown_count: output_view.summary.count,
|
|
41
|
+
total_count: output_view.summary.total_count,
|
|
42
|
+
offset: output_view.summary.offset,
|
|
43
|
+
limit: output_view.summary.limit,
|
|
44
|
+
},
|
|
45
|
+
hints: output_view.hints,
|
|
46
|
+
},
|
|
47
|
+
null,
|
|
48
|
+
2,
|
|
49
|
+
)}\n`;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* @param {OutputStoredQueryItem[]} output_items
|
|
54
|
+
* @returns {string}
|
|
55
|
+
*/
|
|
56
|
+
function renderJsonQueriesOutput(output_items) {
|
|
57
|
+
return `${JSON.stringify(
|
|
58
|
+
{
|
|
59
|
+
queries: output_items.map(formatJsonStoredQuery),
|
|
60
|
+
},
|
|
61
|
+
null,
|
|
62
|
+
2,
|
|
63
|
+
)}\n`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* @param {Extract<OutputView, { command: 'refs' }>} output_view
|
|
68
|
+
* @returns {string}
|
|
69
|
+
*/
|
|
70
|
+
function renderJsonRefsOutput(output_view) {
|
|
71
|
+
return `${JSON.stringify(
|
|
72
|
+
{
|
|
73
|
+
node: formatJsonNodeItem(output_view.node),
|
|
74
|
+
incoming: Object.fromEntries(
|
|
75
|
+
Object.entries(output_view.incoming).map(
|
|
76
|
+
([relation_name, output_items]) => [
|
|
77
|
+
relation_name,
|
|
78
|
+
output_items.map(formatJsonNodeItem),
|
|
79
|
+
],
|
|
80
|
+
),
|
|
81
|
+
),
|
|
82
|
+
},
|
|
83
|
+
null,
|
|
84
|
+
2,
|
|
85
|
+
)}\n`;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* @param {Extract<OutputView, { command: 'show' }>} output_view
|
|
90
|
+
* @returns {string}
|
|
91
|
+
*/
|
|
92
|
+
function renderJsonShowOutput(output_view) {
|
|
93
|
+
return `${JSON.stringify(
|
|
94
|
+
{
|
|
95
|
+
document: output_view.document
|
|
96
|
+
? formatJsonNodeItem(output_view.document)
|
|
97
|
+
: undefined,
|
|
98
|
+
incoming_summary: output_view.incoming_summary,
|
|
99
|
+
source: output_view.source,
|
|
100
|
+
resolved_links: output_view.items.map(formatJsonResolvedLink),
|
|
101
|
+
},
|
|
102
|
+
null,
|
|
103
|
+
2,
|
|
104
|
+
)}\n`;
|
|
105
|
+
}
|
|
106
|
+
|
|
56
107
|
/**
|
|
57
108
|
* @param {OutputNodeItem} output_item
|
|
58
109
|
* @returns {{ '$class': string, '$id': string, '$path'?: string, derived?: Record<string, boolean | number | string | null>, derived_summary?: string, fields: Record<string, string | string[]>, title: string }}
|
|
59
110
|
*/
|
|
60
111
|
function formatJsonQueryItem(output_item) {
|
|
112
|
+
return formatJsonNodeItem(output_item);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
/**
|
|
116
|
+
* @param {OutputNodeItem} output_item
|
|
117
|
+
* @returns {{ '$class': string, '$id': string, '$path'?: string, derived?: Record<string, boolean | number | string | null>, derived_summary?: string, fields: Record<string, string | string[]>, title: string }}
|
|
118
|
+
*/
|
|
119
|
+
function formatJsonNodeItem(output_item) {
|
|
61
120
|
/** @type {{ '$class': string, '$id': string, '$path'?: string, derived?: Record<string, boolean | number | string | null>, derived_summary?: string, fields: Record<string, string | string[]>, title: string }} */
|
|
62
121
|
const query_item = {
|
|
63
122
|
$class: output_item.node_kind,
|
|
@@ -128,33 +187,3 @@ function formatJsonResolvedLink(output_item) {
|
|
|
128
187
|
|
|
129
188
|
return resolved_link;
|
|
130
189
|
}
|
|
131
|
-
|
|
132
|
-
/**
|
|
133
|
-
* @param {OutputNodeItem} output_item
|
|
134
|
-
* @returns {{ '$class': string, '$id': string, '$path'?: string, derived?: Record<string, boolean | number | string | null>, derived_summary?: string, fields: Record<string, string | string[]>, title: string }}
|
|
135
|
-
*/
|
|
136
|
-
function formatJsonShowDocument(output_item) {
|
|
137
|
-
/** @type {{ '$class': string, '$id': string, '$path'?: string, derived?: Record<string, boolean | number | string | null>, derived_summary?: string, fields: Record<string, string | string[]>, title: string }} */
|
|
138
|
-
const document_summary = {
|
|
139
|
-
$class: output_item.node_kind,
|
|
140
|
-
$id: output_item.id,
|
|
141
|
-
fields: output_item.fields,
|
|
142
|
-
title: output_item.title,
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
if (output_item.path) {
|
|
146
|
-
document_summary.$path = output_item.path;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
if (output_item.derived_summary) {
|
|
150
|
-
document_summary.derived_summary = output_item.derived_summary.name;
|
|
151
|
-
document_summary.derived = Object.fromEntries(
|
|
152
|
-
output_item.derived_summary.fields.map((field) => [
|
|
153
|
-
field.name,
|
|
154
|
-
field.value,
|
|
155
|
-
]),
|
|
156
|
-
);
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
return document_summary;
|
|
160
|
-
}
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @import { DerivedSummaryEvaluator } from './derived-summary.js';
|
|
4
4
|
* @import { PatramRepoConfig } from './load-patram-config.types.ts';
|
|
5
5
|
* @import { ParsedCliArguments } from './parse-cli-arguments.types.ts';
|
|
6
|
-
* @import { OutputDerivedSummary, OutputMetadataField, OutputNodeItem, OutputResolvedLinkItem, OutputResolvedLinkTarget, OutputStoredQueryItem, OutputView, ResolvedOutputMode, ShowOutputView } from './output-view.types.ts';
|
|
6
|
+
* @import { OutputDerivedSummary, OutputMetadataField, OutputNodeItem, OutputResolvedLinkItem, OutputResolvedLinkTarget, OutputStoredQueryItem, OutputView, RefsOutputView, ResolvedOutputMode, ShowOutputView } from './output-view.types.ts';
|
|
7
7
|
*/
|
|
8
8
|
/* eslint-disable max-lines */
|
|
9
9
|
|
|
@@ -55,7 +55,7 @@ export function createOutputView(command_name, command_items, command_options) {
|
|
|
55
55
|
/**
|
|
56
56
|
* Create a shared output view for the show command.
|
|
57
57
|
*
|
|
58
|
-
* @param {{ path: string, rendered_source: string, resolved_links: Array<{ label: string, reference: number, target: { kind?: string, path: string, status?: string, title: string } }>, source: string }} show_output
|
|
58
|
+
* @param {{ incoming_summary: Record<string, number>, path: string, rendered_source: string, resolved_links: Array<{ label: string, reference: number, target: { kind?: string, path: string, status?: string, title: string } }>, source: string }} show_output
|
|
59
59
|
* @param {{ derived_summary_evaluator?: DerivedSummaryEvaluator, document_node_ids?: BuildGraphResult['document_node_ids'], graph_nodes?: BuildGraphResult['nodes'], repo_config?: PatramRepoConfig }=} command_options
|
|
60
60
|
* @returns {ShowOutputView}
|
|
61
61
|
*/
|
|
@@ -78,6 +78,7 @@ export function createShowOutputView(show_output, command_options = {}) {
|
|
|
78
78
|
)
|
|
79
79
|
: undefined,
|
|
80
80
|
hints: [],
|
|
81
|
+
incoming_summary: show_output.incoming_summary,
|
|
81
82
|
items: show_output.resolved_links.map((resolved_link) =>
|
|
82
83
|
createResolvedLinkOutputItem(resolved_link, command_options),
|
|
83
84
|
),
|
|
@@ -91,6 +92,46 @@ export function createShowOutputView(show_output, command_options = {}) {
|
|
|
91
92
|
};
|
|
92
93
|
}
|
|
93
94
|
|
|
95
|
+
/**
|
|
96
|
+
* Create a shared output view for the refs command.
|
|
97
|
+
*
|
|
98
|
+
* @param {{ incoming: Record<string, GraphNode[]>, node: GraphNode }} refs_output
|
|
99
|
+
* @param {{ derived_summary_evaluator?: DerivedSummaryEvaluator, repo_config?: PatramRepoConfig }=} command_options
|
|
100
|
+
* @returns {RefsOutputView}
|
|
101
|
+
*/
|
|
102
|
+
export function createRefsOutputView(refs_output, command_options = {}) {
|
|
103
|
+
/** @type {Record<string, OutputNodeItem[]>} */
|
|
104
|
+
const incoming = {};
|
|
105
|
+
|
|
106
|
+
for (const relation_name of Object.keys(refs_output.incoming)) {
|
|
107
|
+
incoming[relation_name] = refs_output.incoming[relation_name].map(
|
|
108
|
+
(graph_node) =>
|
|
109
|
+
createOutputNodeItem(
|
|
110
|
+
graph_node,
|
|
111
|
+
command_options.derived_summary_evaluator?.evaluate(graph_node) ??
|
|
112
|
+
null,
|
|
113
|
+
command_options.repo_config?.fields ?? {},
|
|
114
|
+
),
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return {
|
|
119
|
+
command: 'refs',
|
|
120
|
+
hints: [],
|
|
121
|
+
incoming,
|
|
122
|
+
node: createOutputNodeItem(
|
|
123
|
+
refs_output.node,
|
|
124
|
+
command_options.derived_summary_evaluator?.evaluate(refs_output.node) ??
|
|
125
|
+
null,
|
|
126
|
+
command_options.repo_config?.fields ?? {},
|
|
127
|
+
),
|
|
128
|
+
summary: {
|
|
129
|
+
count: countIncomingReferenceItems(incoming),
|
|
130
|
+
kind: 'incoming_reference_list',
|
|
131
|
+
},
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
|
|
94
135
|
/**
|
|
95
136
|
* Render one shared output view through the resolved renderer.
|
|
96
137
|
*
|
|
@@ -130,7 +171,7 @@ function createQueryOutputView(graph_nodes, command_options = {}) {
|
|
|
130
171
|
command: 'query',
|
|
131
172
|
hints:
|
|
132
173
|
command_options.hints ??
|
|
133
|
-
(total_count === 0 ? [
|
|
174
|
+
(total_count === 0 ? ["Try: patram query --where '$class=task'"] : []),
|
|
134
175
|
items: graph_nodes.map((graph_node) =>
|
|
135
176
|
createOutputNodeItem(
|
|
136
177
|
graph_node,
|
|
@@ -168,6 +209,20 @@ function createStoredQueriesOutputView(stored_queries) {
|
|
|
168
209
|
};
|
|
169
210
|
}
|
|
170
211
|
|
|
212
|
+
/**
|
|
213
|
+
* @param {Record<string, OutputNodeItem[]>} incoming
|
|
214
|
+
* @returns {number}
|
|
215
|
+
*/
|
|
216
|
+
function countIncomingReferenceItems(incoming) {
|
|
217
|
+
let count = 0;
|
|
218
|
+
|
|
219
|
+
for (const output_items of Object.values(incoming)) {
|
|
220
|
+
count += output_items.length;
|
|
221
|
+
}
|
|
222
|
+
|
|
223
|
+
return count;
|
|
224
|
+
}
|
|
225
|
+
|
|
171
226
|
/**
|
|
172
227
|
* @param {GraphNode} graph_node
|
|
173
228
|
* @param {OutputDerivedSummary | null} derived_summary
|