patram 0.7.0 → 0.9.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/bin/patram.js +2 -2
- package/lib/{parse-cli-color-options.js → cli/color-options.js} +2 -2
- package/lib/cli/command-helpers.js +35 -0
- package/lib/cli/commands/check.js +73 -0
- package/lib/cli/commands/fields.js +57 -0
- package/lib/cli/commands/queries.js +41 -0
- package/lib/cli/commands/query.js +239 -0
- package/lib/cli/commands/refs.js +72 -0
- package/lib/cli/commands/show.js +58 -0
- package/lib/{cli-help-metadata.js → cli/help-metadata.js} +54 -15
- package/lib/cli/main.js +76 -0
- package/lib/{parse-cli-arguments-helpers.js → cli/parse-arguments-helpers.js} +18 -11
- package/lib/{parse-cli-arguments.js → cli/parse-arguments.js} +12 -12
- package/lib/{parse-cli-query-pagination.js → cli/query-pagination.js} +2 -2
- package/lib/{render-cli-help.js → cli/render-help.js} +4 -4
- package/lib/{resolve-output-mode.js → cli/resolve-output-mode.js} +2 -2
- package/lib/cli/test-helpers.js +30 -0
- package/lib/config/defaults.d.ts +10 -0
- package/lib/config/defaults.js +80 -0
- package/lib/config/load-patram-config.d.ts +76 -0
- package/lib/config/load-patram-config.js +315 -0
- package/lib/config/load-patram-config.types.d.ts +45 -0
- package/lib/{patram-config.d.ts → config/patram-config.d.ts} +31 -31
- package/lib/{patram-config.js → config/patram-config.js} +3 -3
- package/lib/{patram-config.types.d.ts → config/patram-config.types.d.ts} +1 -1
- package/lib/{resolve-patram-graph-config.d.ts → config/resolve-patram-graph-config.d.ts} +2 -2
- package/lib/{resolve-patram-graph-config.js → config/resolve-patram-graph-config.js} +3 -3
- package/lib/{load-patram-config.d.ts → config/schema.d.ts} +147 -191
- package/lib/config/schema.js +324 -0
- package/lib/{source-file-defaults.d.ts → config/source-file-defaults.d.ts} +0 -1
- package/lib/{source-file-defaults.js → config/source-file-defaults.js} +1 -1
- package/lib/config/validation.d.ts +27 -0
- package/lib/config/validation.js +615 -0
- package/lib/directive-validation-test-helpers.js +1 -1
- package/lib/{build-graph-identity.d.ts → graph/build-graph-identity.d.ts} +2 -2
- package/lib/{build-graph-identity.js → graph/build-graph-identity.js} +1 -1
- package/lib/{build-graph.d.ts → graph/build-graph.d.ts} +3 -3
- package/lib/{build-graph.js → graph/build-graph.js} +17 -13
- package/lib/{build-graph.types.d.ts → graph/build-graph.types.d.ts} +1 -1
- package/lib/graph/check-directive-metadata.d.ts +23 -0
- package/lib/{check-directive-metadata.js → graph/check-directive-metadata.js} +7 -7
- package/lib/graph/check-directive-path-target.d.ts +32 -0
- package/lib/{check-directive-path-target.js → graph/check-directive-path-target.js} +4 -4
- package/lib/graph/check-directive-value.d.ts +19 -0
- package/lib/{check-directive-value.js → graph/check-directive-value.js} +3 -3
- package/lib/graph/check-graph.d.ts +29 -0
- package/lib/{check-graph.js → graph/check-graph.js} +6 -6
- package/lib/graph/directive-diagnostics.d.ts +20 -0
- package/lib/{directive-diagnostics.js → graph/directive-diagnostics.js} +2 -2
- package/lib/graph/directive-type-rules.d.ts +18 -0
- package/lib/{directive-type-rules.js → graph/directive-type-rules.js} +3 -3
- package/lib/{document-node-identity.d.ts → graph/document-node-identity.d.ts} +2 -2
- package/lib/{document-node-identity.js → graph/document-node-identity.js} +2 -2
- package/lib/graph/inspect-reverse-references.d.ts +22 -0
- package/lib/graph/inspect-reverse-references.js +184 -0
- package/lib/{load-project-graph.d.ts → graph/load-project-graph.d.ts} +10 -10
- package/lib/{load-project-graph.js → graph/load-project-graph.js} +12 -12
- package/lib/{parse-where-clause.types.d.ts → graph/parse-where-clause.types.d.ts} +1 -1
- package/lib/{query-graph.d.ts → graph/query/execute.d.ts} +11 -11
- package/lib/{query-graph.js → graph/query/execute.js} +12 -12
- package/lib/{query-inspection.d.ts → graph/query/inspect.d.ts} +10 -8
- package/lib/{query-inspection.js → graph/query/inspect.js} +16 -17
- package/lib/{parse-where-clause.d.ts → graph/query/parse.d.ts} +6 -6
- package/lib/{parse-where-clause.js → graph/query/parse.js} +2 -2
- package/lib/graph/query/resolve.d.ts +30 -0
- package/lib/{resolve-where-clause.js → graph/query/resolve.js} +1 -1
- package/lib/graph/reverse-reference-test-helpers.d.ts +55 -0
- package/lib/graph/reverse-reference-test-helpers.js +76 -0
- package/lib/{command-output.js → output/command-output.js} +6 -5
- package/lib/{derived-summary.js → output/derived-summary.js} +7 -7
- package/lib/output/layout-incoming-references.js +105 -0
- package/lib/output/layout-incoming-summary-lines.js +16 -0
- package/lib/{layout-stored-queries.js → output/layout-stored-queries.js} +9 -9
- package/lib/{list-queries.js → output/list-queries.js} +1 -1
- package/lib/{render-check-output.js → output/render-check-output.js} +1 -1
- package/lib/{render-field-discovery.js → output/render-field-discovery.js} +3 -3
- package/lib/output/render-output-view.js +56 -0
- package/lib/{render-json-output.js → output/renderers/json.js} +92 -63
- package/lib/{render-plain-output.js → output/renderers/plain.js} +62 -7
- package/lib/{render-rich-output.js → output/renderers/rich.js} +69 -8
- package/lib/{resolve-check-target.js → output/resolve-check-target.js} +1 -1
- package/lib/{render-rich-source.js → output/rich-source/render.js} +6 -6
- package/lib/{show-document.js → output/show-document.js} +54 -16
- package/lib/{render-output-view.js → output/view-model/index.js} +56 -47
- package/lib/{write-paged-output.js → output/write-paged-output.js} +9 -5
- package/lib/{claim-helpers.d.ts → parse/claim-helpers.d.ts} +2 -2
- package/lib/{parse-jsdoc-claims.d.ts → parse/jsdoc/parse-jsdoc-claims.d.ts} +2 -2
- package/lib/{parse-jsdoc-claims.js → parse/jsdoc/parse-jsdoc-claims.js} +9 -9
- package/lib/{parse-jsdoc-prose.d.ts → parse/jsdoc/parse-jsdoc-prose.d.ts} +1 -1
- package/lib/{parse-jsdoc-prose.js → parse/jsdoc/parse-jsdoc-prose.js} +1 -1
- package/lib/{parse-markdown-claims.d.ts → parse/markdown/parse-markdown-claims.d.ts} +3 -3
- package/lib/{parse-markdown-claims.js → parse/markdown/parse-markdown-claims.js} +8 -8
- package/lib/{parse-markdown-directives.d.ts → parse/markdown/parse-markdown-directives.d.ts} +2 -2
- package/lib/{parse-markdown-directives.js → parse/markdown/parse-markdown-directives.js} +3 -3
- package/lib/{parse-claims.d.ts → parse/parse-claims.d.ts} +4 -13
- package/lib/{parse-claims.js → parse/parse-claims.js} +18 -26
- package/lib/{parse-claims.types.d.ts → parse/parse-claims.types.d.ts} +1 -1
- package/lib/{tagged-fenced-block-error.d.ts → parse/tagged-fenced/tagged-fenced-block-error.d.ts} +2 -2
- package/lib/{tagged-fenced-block-parser.d.ts → parse/tagged-fenced/tagged-fenced-block-parser.d.ts} +3 -3
- package/lib/{tagged-fenced-blocks.d.ts → parse/tagged-fenced/tagged-fenced-blocks.d.ts} +7 -7
- package/lib/{tagged-fenced-blocks.js → parse/tagged-fenced/tagged-fenced-blocks.js} +3 -3
- package/lib/{parse-yaml-claims.d.ts → parse/yaml/parse-yaml-claims.d.ts} +4 -4
- package/lib/{parse-yaml-claims.js → parse/yaml/parse-yaml-claims.js} +22 -13
- package/lib/patram.d.ts +29 -28
- package/lib/patram.js +5 -6
- package/lib/{discover-fields.js → scan/discover-fields.js} +9 -8
- package/lib/scan/list-repo-files.d.ts +16 -0
- package/lib/{list-source-files.js → scan/list-repo-files.js} +2 -35
- package/lib/{list-source-files.d.ts → scan/list-source-files.d.ts} +4 -11
- package/lib/scan/list-source-files.js +45 -0
- package/package.json +8 -7
- package/lib/build-graph.types.ts +0 -27
- package/lib/discover-fields.types.ts +0 -52
- package/lib/load-patram-config.js +0 -1215
- package/lib/load-patram-config.types.d.ts +0 -45
- package/lib/load-patram-config.types.ts +0 -56
- package/lib/output-view.types.d.ts +0 -80
- package/lib/output-view.types.ts +0 -96
- package/lib/overlay-graph.d.ts +0 -43
- package/lib/overlay-graph.js +0 -191
- package/lib/parse-claims.types.ts +0 -41
- package/lib/parse-cli-arguments.types.ts +0 -69
- package/lib/parse-where-clause.types.ts +0 -87
- package/lib/patram-cli.js +0 -528
- package/lib/patram-config.types.ts +0 -22
- package/lib/tagged-fenced-blocks.types.ts +0 -38
- /package/lib/{format-derived-summary-row.js → output/format-derived-summary-row.js} +0 -0
- /package/lib/{format-node-header.js → output/format-node-header.js} +0 -0
- /package/lib/{format-output-item-block.js → output/format-output-item-block.js} +0 -0
- /package/lib/{format-output-metadata.js → output/format-output-metadata.js} +0 -0
- /package/lib/{claim-helpers.js → parse/claim-helpers.js} +0 -0
- /package/lib/{parse-jsdoc-blocks.d.ts → parse/jsdoc/parse-jsdoc-blocks.d.ts} +0 -0
- /package/lib/{parse-jsdoc-blocks.js → parse/jsdoc/parse-jsdoc-blocks.js} +0 -0
- /package/lib/{tagged-fenced-block-error.js → parse/tagged-fenced/tagged-fenced-block-error.js} +0 -0
- /package/lib/{tagged-fenced-block-markdown.d.ts → parse/tagged-fenced/tagged-fenced-block-markdown.d.ts} +0 -0
- /package/lib/{tagged-fenced-block-markdown.js → parse/tagged-fenced/tagged-fenced-block-markdown.js} +0 -0
- /package/lib/{tagged-fenced-block-metadata.d.ts → parse/tagged-fenced/tagged-fenced-block-metadata.d.ts} +0 -0
- /package/lib/{tagged-fenced-block-metadata.js → parse/tagged-fenced/tagged-fenced-block-metadata.js} +0 -0
- /package/lib/{tagged-fenced-block-parser.js → parse/tagged-fenced/tagged-fenced-block-parser.js} +0 -0
- /package/lib/{tagged-fenced-blocks.types.d.ts → parse/tagged-fenced/tagged-fenced-blocks.types.d.ts} +0 -0
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @import { OutputStoredQueryItem } from './output-view.types.ts';
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
|
-
import { parseWhereClause } from '
|
|
6
|
+
import { parseWhereClause } from '../graph/query/parse.js';
|
|
7
7
|
|
|
8
8
|
const MAX_STORED_QUERY_WIDTH = 100;
|
|
9
9
|
const MIN_TERM_COLUMN_WIDTH = 20;
|
|
@@ -96,7 +96,7 @@ function createStoredQueryPhrases(where_clause) {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
/**
|
|
99
|
-
* @param {import('
|
|
99
|
+
* @param {import('../graph/parse-where-clause.types.ts').ParsedExpression} expression
|
|
100
100
|
* @returns {StoredQuerySegment[][]}
|
|
101
101
|
*/
|
|
102
102
|
function createExpressionPhrases(expression) {
|
|
@@ -114,7 +114,7 @@ function createExpressionPhrases(expression) {
|
|
|
114
114
|
}
|
|
115
115
|
|
|
116
116
|
/**
|
|
117
|
-
* @param {import('
|
|
117
|
+
* @param {import('../graph/parse-where-clause.types.ts').ParsedExpression} expression
|
|
118
118
|
* @param {'and' | 'or'} operator
|
|
119
119
|
* @param {boolean} should_prefix_operator
|
|
120
120
|
* @returns {StoredQuerySegment[]}
|
|
@@ -139,7 +139,7 @@ function createExpressionPhrase(expression, operator, should_prefix_operator) {
|
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
/**
|
|
142
|
-
* @param {import('
|
|
142
|
+
* @param {import('../graph/parse-where-clause.types.ts').ParsedExpression} expression
|
|
143
143
|
* @param {number} parent_precedence
|
|
144
144
|
* @returns {StoredQuerySegment[]}
|
|
145
145
|
*/
|
|
@@ -159,7 +159,7 @@ function createExpressionSegments(expression, parent_precedence) {
|
|
|
159
159
|
}
|
|
160
160
|
|
|
161
161
|
/**
|
|
162
|
-
* @param {import('
|
|
162
|
+
* @param {import('../graph/parse-where-clause.types.ts').ParsedExpression} expression
|
|
163
163
|
* @returns {StoredQuerySegment[]}
|
|
164
164
|
*/
|
|
165
165
|
function createRawExpressionSegments(expression) {
|
|
@@ -202,7 +202,7 @@ function createRawExpressionSegments(expression) {
|
|
|
202
202
|
}
|
|
203
203
|
|
|
204
204
|
/**
|
|
205
|
-
* @param {import('
|
|
205
|
+
* @param {import('../graph/parse-where-clause.types.ts').ParsedExpression} expression
|
|
206
206
|
* @returns {number}
|
|
207
207
|
*/
|
|
208
208
|
function getExpressionPrecedence(expression) {
|
|
@@ -230,7 +230,7 @@ function getBooleanExpressionPrecedence(operator) {
|
|
|
230
230
|
}
|
|
231
231
|
|
|
232
232
|
/**
|
|
233
|
-
* @param {import('
|
|
233
|
+
* @param {import('../graph/parse-where-clause.types.ts').ParsedTerm} term
|
|
234
234
|
* @returns {StoredQuerySegment[]}
|
|
235
235
|
*/
|
|
236
236
|
function createTermSegments(term) {
|
|
@@ -265,7 +265,7 @@ function createTermSegments(term) {
|
|
|
265
265
|
}
|
|
266
266
|
|
|
267
267
|
/**
|
|
268
|
-
* @param {import('
|
|
268
|
+
* @param {import('../graph/parse-where-clause.types.ts').ParsedFieldSetTerm} term
|
|
269
269
|
* @returns {StoredQuerySegment[]}
|
|
270
270
|
*/
|
|
271
271
|
function createFieldSetSegments(term) {
|
|
@@ -281,7 +281,7 @@ function createFieldSetSegments(term) {
|
|
|
281
281
|
}
|
|
282
282
|
|
|
283
283
|
/**
|
|
284
|
-
* @param {import('
|
|
284
|
+
* @param {import('../graph/parse-where-clause.types.ts').ParsedAggregateTerm} term
|
|
285
285
|
* @returns {StoredQuerySegment[]}
|
|
286
286
|
*/
|
|
287
287
|
function createAggregateSegments(term) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @import { ResolvedOutputMode } from './output-view.types.ts';
|
|
3
|
-
* @import { FieldDiscoveryResult, FieldDiscoverySuggestion } from '
|
|
3
|
+
* @import { FieldDiscoveryResult, FieldDiscoverySuggestion } from '../scan/discover-fields.types.ts';
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { Ansis } from 'ansis';
|
|
@@ -135,7 +135,7 @@ function formatTextFieldSuggestion(field_suggestion, render_options) {
|
|
|
135
135
|
|
|
136
136
|
/**
|
|
137
137
|
* @param {string} section_title
|
|
138
|
-
* @param {import('
|
|
138
|
+
* @param {import('../scan/discover-fields.types.ts').FieldDiscoveryEvidenceReference[]} evidence_references
|
|
139
139
|
* @param {{ header: (value: string) => string, label: (value: string) => string }} render_options
|
|
140
140
|
* @returns {string[]}
|
|
141
141
|
*/
|
|
@@ -168,7 +168,7 @@ function formatTextEvidenceSection(
|
|
|
168
168
|
}
|
|
169
169
|
|
|
170
170
|
/**
|
|
171
|
-
* @param {import('
|
|
171
|
+
* @param {import('../scan/discover-fields.types.ts').FieldDiscoveryEvidenceReference} evidence_reference
|
|
172
172
|
* @returns {string}
|
|
173
173
|
*/
|
|
174
174
|
function formatEvidenceReference(evidence_reference) {
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import { ParsedCliArguments } from '../cli/arguments.types.ts';
|
|
3
|
+
* @import { ResolvedOutputMode, OutputView } from './output-view.types.ts';
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { renderJsonOutput } from './renderers/json.js';
|
|
7
|
+
import { renderPlainOutput } from './renderers/plain.js';
|
|
8
|
+
import { renderRichOutput } from './renderers/rich.js';
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Shared command output views.
|
|
12
|
+
*
|
|
13
|
+
* Normalizes `query`, `queries`, and `show` results into renderer-specific
|
|
14
|
+
* output models.
|
|
15
|
+
*
|
|
16
|
+
* Kind: output
|
|
17
|
+
* Status: active
|
|
18
|
+
* Tracked in: ../../docs/plans/v0/source-anchor-dogfooding.md
|
|
19
|
+
* Decided by: ../../docs/decisions/cli-output-architecture.md
|
|
20
|
+
* @patram
|
|
21
|
+
* @see {@link ./show-document.js}
|
|
22
|
+
* @see {@link ../../docs/decisions/cli-output-architecture.md}
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
createOutputView,
|
|
27
|
+
createRefsOutputView,
|
|
28
|
+
createShowOutputView,
|
|
29
|
+
} from './view-model/index.js';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* Render one shared output view through the resolved renderer.
|
|
33
|
+
*
|
|
34
|
+
* @param {OutputView} output_view
|
|
35
|
+
* @param {ResolvedOutputMode} output_mode
|
|
36
|
+
* @param {ParsedCliArguments} parsed_arguments
|
|
37
|
+
* @returns {Promise<string>}
|
|
38
|
+
*/
|
|
39
|
+
export async function renderOutputView(
|
|
40
|
+
output_view,
|
|
41
|
+
output_mode,
|
|
42
|
+
parsed_arguments,
|
|
43
|
+
) {
|
|
44
|
+
if (output_mode.renderer_name === 'json') {
|
|
45
|
+
return renderJsonOutput(output_view);
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
if (output_mode.renderer_name === 'plain') {
|
|
49
|
+
return renderPlainOutput(output_view);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
return renderRichOutput(output_view, {
|
|
53
|
+
color_enabled: output_mode.color_enabled,
|
|
54
|
+
color_mode: parsed_arguments.color_mode,
|
|
55
|
+
});
|
|
56
|
+
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @import { OutputNodeItem, OutputResolvedLinkItem, OutputStoredQueryItem, OutputView } from '
|
|
2
|
+
* @import { OutputNodeItem, OutputResolvedLinkItem, OutputStoredQueryItem, OutputView } from '../output-view.types.ts';
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -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
|
-
}
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @import { OutputNodeItem, OutputResolvedLinkItem, OutputStoredQueryItem, OutputView, QueryOutputView, ShowOutputView } from '
|
|
2
|
+
* @import { OutputNodeItem, OutputResolvedLinkItem, OutputStoredQueryItem, OutputView, QueryOutputView, RefsOutputView, ShowOutputView } from '../output-view.types.ts';
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
formatOutputNodeMetadataRows,
|
|
7
7
|
formatResolvedLinkMetadataRows,
|
|
8
|
-
} from '
|
|
9
|
-
import { formatNodeHeader } from '
|
|
10
|
-
import { formatOutputItemBlock } from '
|
|
11
|
-
import {
|
|
8
|
+
} from '../format-output-metadata.js';
|
|
9
|
+
import { formatNodeHeader } from '../format-node-header.js';
|
|
10
|
+
import { formatOutputItemBlock } from '../format-output-item-block.js';
|
|
11
|
+
import { layoutIncomingReferenceLines } from '../layout-incoming-references.js';
|
|
12
|
+
import { layoutIncomingSummaryLines } from '../layout-incoming-summary-lines.js';
|
|
13
|
+
import { layoutStoredQueries } from '../layout-stored-queries.js';
|
|
12
14
|
|
|
13
15
|
/**
|
|
14
16
|
* Render the canonical plain output for one output view.
|
|
@@ -25,6 +27,10 @@ export function renderPlainOutput(output_view) {
|
|
|
25
27
|
return renderPlainStoredQueries(output_view.items);
|
|
26
28
|
}
|
|
27
29
|
|
|
30
|
+
if (output_view.command === 'refs') {
|
|
31
|
+
return renderPlainRefsOutput(output_view);
|
|
32
|
+
}
|
|
33
|
+
|
|
28
34
|
if (output_view.command === 'show') {
|
|
29
35
|
return renderPlainShowOutput(output_view);
|
|
30
36
|
}
|
|
@@ -85,8 +91,13 @@ function renderPlainShowOutput(output_view) {
|
|
|
85
91
|
const document_summary = output_view.document
|
|
86
92
|
? formatPlainNodeItem(output_view.document)
|
|
87
93
|
: '';
|
|
94
|
+
const incoming_summary = renderPlainIncomingSummary(output_view);
|
|
88
95
|
|
|
89
|
-
if (
|
|
96
|
+
if (
|
|
97
|
+
document_summary.length === 0 &&
|
|
98
|
+
output_view.items.length === 0 &&
|
|
99
|
+
incoming_summary.length === 0
|
|
100
|
+
) {
|
|
90
101
|
return `${rendered_source}\n`;
|
|
91
102
|
}
|
|
92
103
|
|
|
@@ -99,7 +110,28 @@ function renderPlainShowOutput(output_view) {
|
|
|
99
110
|
|
|
100
111
|
summary_items.push(...output_view.items.map(formatPlainResolvedLinkItem));
|
|
101
112
|
|
|
102
|
-
|
|
113
|
+
const summary_blocks = summary_items.filter((summary_item) => summary_item);
|
|
114
|
+
|
|
115
|
+
if (incoming_summary.length > 0) {
|
|
116
|
+
summary_blocks.push(incoming_summary);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return `${rendered_source}\n\n----------------\n${summary_blocks.join('\n\n')}\n`;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* @param {RefsOutputView} output_view
|
|
124
|
+
* @returns {string}
|
|
125
|
+
*/
|
|
126
|
+
function renderPlainRefsOutput(output_view) {
|
|
127
|
+
const node_summary = formatPlainNodeItem(output_view.node);
|
|
128
|
+
const output_lines = layoutIncomingReferenceLines(output_view.incoming);
|
|
129
|
+
|
|
130
|
+
if (output_lines.length === 0) {
|
|
131
|
+
return `${node_summary}\n\nNo incoming references.\n`;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
return `${node_summary}\n\n${output_lines.join('\n')}\n`;
|
|
103
135
|
}
|
|
104
136
|
|
|
105
137
|
/**
|
|
@@ -135,6 +167,29 @@ function formatPlainResolvedLinkItem(output_item) {
|
|
|
135
167
|
});
|
|
136
168
|
}
|
|
137
169
|
|
|
170
|
+
/**
|
|
171
|
+
* @param {ShowOutputView} output_view
|
|
172
|
+
* @returns {string}
|
|
173
|
+
*/
|
|
174
|
+
function renderPlainIncomingSummary(output_view) {
|
|
175
|
+
if (!hasIncomingSummary(output_view.incoming_summary)) {
|
|
176
|
+
return '';
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const output_lines = layoutIncomingSummaryLines(output_view.incoming_summary);
|
|
180
|
+
output_lines.push('', `Hint: patram refs ${output_view.path}`);
|
|
181
|
+
|
|
182
|
+
return output_lines.join('\n');
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* @param {Record<string, number>} incoming_summary
|
|
187
|
+
* @returns {boolean}
|
|
188
|
+
*/
|
|
189
|
+
function hasIncomingSummary(incoming_summary) {
|
|
190
|
+
return Object.keys(incoming_summary).length > 0;
|
|
191
|
+
}
|
|
192
|
+
|
|
138
193
|
/**
|
|
139
194
|
* @param {string} value
|
|
140
195
|
* @returns {string}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @import { CliColorMode } from '
|
|
3
|
-
* @import { OutputNodeItem, OutputResolvedLinkItem, OutputStoredQueryItem, OutputView, QueryOutputView, ShowOutputView } from '
|
|
2
|
+
* @import { CliColorMode } from '../../cli/arguments.types.ts';
|
|
3
|
+
* @import { OutputNodeItem, OutputResolvedLinkItem, OutputStoredQueryItem, OutputView, QueryOutputView, RefsOutputView, ShowOutputView } from '../output-view.types.ts';
|
|
4
4
|
*/
|
|
5
5
|
|
|
6
6
|
import { Ansis } from 'ansis';
|
|
@@ -8,11 +8,13 @@ import { Ansis } from 'ansis';
|
|
|
8
8
|
import {
|
|
9
9
|
formatOutputNodeMetadataRows,
|
|
10
10
|
formatResolvedLinkMetadataRows,
|
|
11
|
-
} from '
|
|
12
|
-
import { formatNodeHeader } from '
|
|
13
|
-
import { formatOutputItemBlock } from '
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
11
|
+
} from '../format-output-metadata.js';
|
|
12
|
+
import { formatNodeHeader } from '../format-node-header.js';
|
|
13
|
+
import { formatOutputItemBlock } from '../format-output-item-block.js';
|
|
14
|
+
import { layoutIncomingReferenceLines } from '../layout-incoming-references.js';
|
|
15
|
+
import { layoutIncomingSummaryLines } from '../layout-incoming-summary-lines.js';
|
|
16
|
+
import { layoutStoredQueries } from '../layout-stored-queries.js';
|
|
17
|
+
import { renderRichSource } from '../rich-source/render.js';
|
|
16
18
|
|
|
17
19
|
const FULL_WIDTH_DIVIDER = ` ${'─'.repeat(78)} `;
|
|
18
20
|
|
|
@@ -34,6 +36,9 @@ export async function renderRichOutput(output_view, render_options) {
|
|
|
34
36
|
return renderRichStoredQueries(output_view.items, ansi);
|
|
35
37
|
}
|
|
36
38
|
|
|
39
|
+
if (output_view.command === 'refs') {
|
|
40
|
+
return renderRichRefsOutput(output_view, ansi);
|
|
41
|
+
}
|
|
37
42
|
if (output_view.command === 'show') {
|
|
38
43
|
return renderRichShowOutput(output_view, render_options, ansi);
|
|
39
44
|
}
|
|
@@ -105,8 +110,13 @@ async function renderRichShowOutput(output_view, render_options, ansi) {
|
|
|
105
110
|
const document_summary = output_view.document
|
|
106
111
|
? formatRichNodeItem(output_view.document, ansi)
|
|
107
112
|
: '';
|
|
113
|
+
const incoming_summary = renderRichIncomingSummary(output_view, ansi);
|
|
108
114
|
|
|
109
|
-
if (
|
|
115
|
+
if (
|
|
116
|
+
document_summary.length === 0 &&
|
|
117
|
+
output_view.items.length === 0 &&
|
|
118
|
+
incoming_summary.length === 0
|
|
119
|
+
) {
|
|
110
120
|
return `${rendered_source}\n`;
|
|
111
121
|
}
|
|
112
122
|
|
|
@@ -121,9 +131,34 @@ async function renderRichShowOutput(output_view, render_options, ansi) {
|
|
|
121
131
|
...output_view.items.map((item) => formatRichResolvedLinkItem(item, ansi)),
|
|
122
132
|
);
|
|
123
133
|
|
|
134
|
+
if (incoming_summary.length > 0) {
|
|
135
|
+
summary_items.push(incoming_summary);
|
|
136
|
+
}
|
|
137
|
+
|
|
124
138
|
return `${rendered_source}\n\n${ansi.gray(FULL_WIDTH_DIVIDER)}\n\n${summary_items.join('\n\n')}\n`;
|
|
125
139
|
}
|
|
126
140
|
|
|
141
|
+
/**
|
|
142
|
+
* @param {RefsOutputView} output_view
|
|
143
|
+
* @param {Ansis} ansi
|
|
144
|
+
* @returns {string}
|
|
145
|
+
*/
|
|
146
|
+
function renderRichRefsOutput(output_view, ansi) {
|
|
147
|
+
const node_summary = formatRichNodeItem(output_view.node, ansi);
|
|
148
|
+
const output_lines = layoutIncomingReferenceLines(output_view.incoming, {
|
|
149
|
+
format_node_header(output_item) {
|
|
150
|
+
return ansi.green(formatNodeHeader(output_item));
|
|
151
|
+
},
|
|
152
|
+
format_relation_header(relation_name, relation_count) {
|
|
153
|
+
return `${ansi.bold(relation_name)} ${ansi.gray(`(${relation_count})`)}`;
|
|
154
|
+
},
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
return output_lines.length === 0
|
|
158
|
+
? `${node_summary}\n\n${ansi.yellow('No incoming references.')}\n`
|
|
159
|
+
: `${node_summary}\n\n${output_lines.join('\n')}\n`;
|
|
160
|
+
}
|
|
161
|
+
|
|
127
162
|
/**
|
|
128
163
|
* @param {OutputNodeItem} output_item
|
|
129
164
|
* @param {Ansis} ansi
|
|
@@ -162,6 +197,32 @@ function formatRichResolvedLinkItem(output_item, ansi) {
|
|
|
162
197
|
});
|
|
163
198
|
}
|
|
164
199
|
|
|
200
|
+
/**
|
|
201
|
+
* @param {ShowOutputView} output_view
|
|
202
|
+
* @param {Ansis} ansi
|
|
203
|
+
* @returns {string}
|
|
204
|
+
*/
|
|
205
|
+
function renderRichIncomingSummary(output_view, ansi) {
|
|
206
|
+
if (!hasIncomingSummary(output_view.incoming_summary)) {
|
|
207
|
+
return '';
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
const output_lines = layoutIncomingSummaryLines(output_view.incoming_summary);
|
|
211
|
+
output_lines[0] = ansi.bold(output_lines[0]);
|
|
212
|
+
|
|
213
|
+
output_lines.push('', ansi.gray(`Hint: patram refs ${output_view.path}`));
|
|
214
|
+
|
|
215
|
+
return output_lines.join('\n');
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* @param {Record<string, number>} incoming_summary
|
|
220
|
+
* @returns {boolean}
|
|
221
|
+
*/
|
|
222
|
+
function hasIncomingSummary(incoming_summary) {
|
|
223
|
+
return Object.keys(incoming_summary).length > 0;
|
|
224
|
+
}
|
|
225
|
+
|
|
165
226
|
/**
|
|
166
227
|
* @param {boolean} color_enabled
|
|
167
228
|
* @returns {Ansis}
|
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @import { ComarkElement, ComarkNode } from 'md4x';
|
|
4
4
|
* @import { BundledLanguage } from 'shiki';
|
|
5
|
-
* @import { CliColorMode } from '
|
|
6
|
-
* @import { OutputResolvedLinkItem, ShowOutputView } from '
|
|
5
|
+
* @import { CliColorMode } from '../../cli/arguments.types.ts';
|
|
6
|
+
* @import { OutputResolvedLinkItem, ShowOutputView } from '../output-view.types.ts';
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import { extname } from 'node:path';
|
|
@@ -969,8 +969,8 @@ function shouldRenderListItemGap(previous_item, next_item, has_blank_line_gap) {
|
|
|
969
969
|
}
|
|
970
970
|
|
|
971
971
|
return (
|
|
972
|
-
|
|
973
|
-
|
|
972
|
+
isSingleParagraphTopLevelListItem(previous_item) &&
|
|
973
|
+
isSingleParagraphTopLevelListItem(next_item)
|
|
974
974
|
);
|
|
975
975
|
}
|
|
976
976
|
|
|
@@ -978,7 +978,7 @@ function shouldRenderListItemGap(previous_item, next_item, has_blank_line_gap) {
|
|
|
978
978
|
* @param {ComarkElement} item_node
|
|
979
979
|
* @returns {boolean}
|
|
980
980
|
*/
|
|
981
|
-
function
|
|
981
|
+
function isSingleParagraphTopLevelListItem(item_node) {
|
|
982
982
|
const item_children = getElementChildren(item_node);
|
|
983
983
|
|
|
984
984
|
if (item_children.length !== 1) {
|
|
@@ -994,7 +994,7 @@ function isSimpleTopLevelListItem(item_node) {
|
|
|
994
994
|
return false;
|
|
995
995
|
}
|
|
996
996
|
|
|
997
|
-
return
|
|
997
|
+
return true;
|
|
998
998
|
}
|
|
999
999
|
|
|
1000
1000
|
/**
|