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.
- package/bin/patram.js +4 -4
- package/lib/cli/commands/fields.js +0 -4
- package/lib/cli/commands/queries.js +10 -20
- package/lib/cli/commands/query.js +1 -8
- package/lib/cli/commands/refs.js +3 -10
- package/lib/cli/commands/show.js +1 -8
- package/lib/cli/help-metadata.js +71 -106
- package/lib/cli/main.js +10 -10
- package/lib/cli/parse-arguments-helpers.js +165 -59
- package/lib/cli/parse-arguments.js +4 -4
- package/lib/cli/render-help.js +2 -2
- package/lib/config/defaults.js +33 -25
- package/lib/config/load-patram-config.d.ts +8 -33
- package/lib/config/load-patram-config.js +9 -33
- package/lib/config/load-patram-config.types.d.ts +3 -40
- package/lib/config/manage-stored-queries-helpers.d.ts +4 -4
- package/lib/config/manage-stored-queries-helpers.js +91 -33
- package/lib/config/manage-stored-queries.d.ts +4 -4
- package/lib/config/manage-stored-queries.js +11 -5
- package/lib/config/patram-config.d.ts +34 -34
- package/lib/config/patram-config.js +3 -3
- package/lib/config/patram-config.types.d.ts +5 -11
- package/lib/config/resolve-patram-graph-config.d.ts +5 -1
- package/lib/config/resolve-patram-graph-config.js +3 -119
- package/lib/config/schema.d.ts +158 -269
- package/lib/config/schema.js +72 -210
- package/lib/config/validate-patram-config-value.js +6 -31
- package/lib/config/validation.d.ts +2 -12
- package/lib/config/validation.js +125 -483
- package/lib/find-close-match.d.ts +4 -1
- package/lib/graph/build-graph-identity.d.ts +1 -32
- package/lib/graph/build-graph-identity.js +5 -269
- package/lib/graph/build-graph.d.ts +13 -4
- package/lib/graph/build-graph.js +347 -488
- package/lib/graph/build-graph.types.d.ts +8 -9
- package/lib/graph/check-directive-metadata-helpers.d.ts +30 -0
- package/lib/graph/check-directive-metadata-helpers.js +126 -0
- package/lib/graph/check-directive-metadata.d.ts +8 -9
- package/lib/graph/check-directive-metadata.js +70 -561
- package/lib/graph/check-directive-path-target.d.ts +6 -13
- package/lib/graph/check-directive-path-target.js +26 -57
- package/lib/graph/check-directive-value.d.ts +1 -5
- package/lib/graph/check-directive-value.js +40 -180
- package/lib/graph/check-graph.d.ts +5 -5
- package/lib/graph/check-graph.js +8 -6
- package/lib/graph/document-node-identity.d.ts +23 -7
- package/lib/graph/document-node-identity.js +417 -160
- package/lib/graph/graph-node.d.ts +42 -0
- package/lib/graph/graph-node.js +83 -0
- package/lib/graph/inspect-reverse-references.js +16 -11
- package/lib/graph/load-project-graph.d.ts +7 -7
- package/lib/graph/load-project-graph.js +7 -7
- package/lib/graph/parse-where-clause.types.d.ts +3 -2
- package/lib/graph/query/cypher-reader.d.ts +59 -0
- package/lib/graph/query/cypher-reader.js +151 -0
- package/lib/graph/query/cypher-support.d.ts +79 -0
- package/lib/graph/query/cypher-support.js +213 -0
- package/lib/graph/query/cypher-tokenize.d.ts +13 -0
- package/lib/graph/query/cypher-tokenize.js +225 -0
- package/lib/graph/query/cypher.types.d.ts +43 -0
- package/lib/graph/query/execute.d.ts +7 -7
- package/lib/graph/query/execute.js +71 -33
- package/lib/graph/query/inspect.js +58 -24
- package/lib/graph/query/parse-cypher-patterns.d.ts +27 -0
- package/lib/graph/query/parse-cypher-patterns.js +382 -0
- package/lib/graph/query/parse-cypher.d.ts +7 -0
- package/lib/graph/query/parse-cypher.js +580 -0
- package/lib/graph/query/parse-query.d.ts +13 -0
- package/lib/graph/query/parse-query.js +97 -0
- package/lib/graph/query/resolve.js +77 -23
- package/lib/output/command-output.js +12 -5
- package/lib/output/compact-layout.js +221 -0
- package/lib/output/format-output-item-block.js +31 -1
- package/lib/output/format-output-metadata.js +16 -29
- package/lib/output/format-stored-query-block.js +95 -0
- package/lib/output/layout-incoming-references.js +101 -19
- package/lib/output/layout-stored-queries.js +23 -330
- package/lib/output/list-queries.js +1 -1
- package/lib/output/render-field-discovery.js +11 -2
- package/lib/output/render-output-view.js +9 -5
- package/lib/output/renderers/json.js +5 -26
- package/lib/output/renderers/plain.js +155 -35
- package/lib/output/renderers/rich.js +250 -36
- package/lib/output/resolved-link-layout.js +43 -0
- package/lib/output/rich-source/render.js +193 -35
- package/lib/output/show-document.js +25 -18
- package/lib/output/view-model/index.js +124 -103
- package/lib/parse/jsdoc/parse-jsdoc-blocks.js +1 -1
- package/lib/parse/jsdoc/parse-jsdoc-claims.js +12 -6
- package/lib/parse/markdown/parse-markdown-claims.js +99 -62
- package/lib/parse/markdown/parse-markdown-directives.d.ts +10 -6
- package/lib/parse/markdown/parse-markdown-directives.js +104 -18
- package/lib/parse/markdown/parse-markdown-prose.d.ts +27 -0
- package/lib/parse/markdown/parse-markdown-prose.js +243 -0
- package/lib/parse/parse-claims.d.ts +2 -6
- package/lib/parse/parse-claims.js +11 -53
- package/lib/parse/tagged-fenced/tagged-fenced-blocks.d.ts +4 -4
- package/lib/parse/tagged-fenced/tagged-fenced-blocks.js +4 -4
- package/lib/parse/yaml/parse-yaml-claims.js +4 -4
- package/lib/patram.d.ts +3 -5
- package/lib/patram.js +1 -1
- package/lib/scan/discover-fields.js +194 -55
- package/lib/scan/list-source-files.d.ts +4 -4
- package/lib/scan/list-source-files.js +4 -4
- package/package.json +1 -1
- package/lib/directive-validation-test-helpers.js +0 -87
- package/lib/graph/query/parse.d.ts +0 -75
- package/lib/graph/query/parse.js +0 -1064
- package/lib/output/derived-summary.js +0 -280
- package/lib/output/format-derived-summary-row.js +0 -9
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/* eslint-disable max-lines */
|
|
1
2
|
/**
|
|
2
3
|
* @import { CliColorMode } from '../../cli/arguments.types.ts';
|
|
3
4
|
* @import { OutputNodeItem, OutputResolvedLinkItem, OutputStoredQueryItem, OutputView, QueryOutputView, RefsOutputView, ShowOutputView } from '../output-view.types.ts';
|
|
@@ -6,14 +7,27 @@
|
|
|
6
7
|
import { Ansis } from 'ansis';
|
|
7
8
|
|
|
8
9
|
import {
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
formatOutputNodeStoredMetadataRow,
|
|
11
|
+
formatResolvedLinkStoredMetadataRow,
|
|
11
12
|
} from '../format-output-metadata.js';
|
|
13
|
+
import {
|
|
14
|
+
formatCompactMetadataLabel,
|
|
15
|
+
formatCompactTitleRow,
|
|
16
|
+
getCompactLeftTitleWidth,
|
|
17
|
+
wrapCompactBodyText,
|
|
18
|
+
} from '../compact-layout.js';
|
|
12
19
|
import { formatNodeHeader } from '../format-node-header.js';
|
|
13
|
-
import {
|
|
14
|
-
import {
|
|
20
|
+
import { formatStoredQueryBlock } from '../format-stored-query-block.js';
|
|
21
|
+
import {
|
|
22
|
+
collectIncomingRefHeaders,
|
|
23
|
+
createIncomingTreeRenderOptions,
|
|
24
|
+
layoutIncomingReferenceLines,
|
|
25
|
+
} from '../layout-incoming-references.js';
|
|
15
26
|
import { layoutIncomingSummaryLines } from '../layout-incoming-summary-lines.js';
|
|
16
|
-
import {
|
|
27
|
+
import {
|
|
28
|
+
formatResolvedLinkBodyLines,
|
|
29
|
+
formatResolvedLinkHeader,
|
|
30
|
+
} from '../resolved-link-layout.js';
|
|
17
31
|
import { renderRichSource } from '../rich-source/render.js';
|
|
18
32
|
|
|
19
33
|
const FULL_WIDTH_DIVIDER = ` ${'─'.repeat(78)} `;
|
|
@@ -22,22 +36,22 @@ const FULL_WIDTH_DIVIDER = ` ${'─'.repeat(78)} `;
|
|
|
22
36
|
* Render styled rich output while preserving the plain layout.
|
|
23
37
|
*
|
|
24
38
|
* @param {OutputView} output_view
|
|
25
|
-
* @param {{ color_mode: CliColorMode, color_enabled: boolean }} render_options
|
|
39
|
+
* @param {{ color_mode: CliColorMode, color_enabled: boolean, is_tty?: boolean, terminal_width?: number }} render_options
|
|
26
40
|
* @returns {Promise<string>}
|
|
27
41
|
*/
|
|
28
42
|
export async function renderRichOutput(output_view, render_options) {
|
|
29
43
|
const ansi = createAnsi(render_options.color_enabled);
|
|
30
44
|
|
|
31
45
|
if (output_view.command === 'query') {
|
|
32
|
-
return renderRichQueryOutput(output_view, ansi);
|
|
46
|
+
return renderRichQueryOutput(output_view, render_options, ansi);
|
|
33
47
|
}
|
|
34
48
|
|
|
35
49
|
if (output_view.command === 'queries') {
|
|
36
|
-
return renderRichStoredQueries(output_view, ansi);
|
|
50
|
+
return renderRichStoredQueries(output_view, render_options, ansi);
|
|
37
51
|
}
|
|
38
52
|
|
|
39
53
|
if (output_view.command === 'refs') {
|
|
40
|
-
return renderRichRefsOutput(output_view, ansi);
|
|
54
|
+
return renderRichRefsOutput(output_view, render_options, ansi);
|
|
41
55
|
}
|
|
42
56
|
if (output_view.command === 'show') {
|
|
43
57
|
return renderRichShowOutput(output_view, render_options, ansi);
|
|
@@ -48,10 +62,11 @@ export async function renderRichOutput(output_view, render_options) {
|
|
|
48
62
|
|
|
49
63
|
/**
|
|
50
64
|
* @param {QueryOutputView} output_view
|
|
65
|
+
* @param {{ is_tty?: boolean, terminal_width?: number }} render_options
|
|
51
66
|
* @param {Ansis} ansi
|
|
52
67
|
* @returns {string}
|
|
53
68
|
*/
|
|
54
|
-
function renderRichQueryOutput(output_view, ansi) {
|
|
69
|
+
function renderRichQueryOutput(output_view, render_options, ansi) {
|
|
55
70
|
const footer = renderRichQueryFooter(
|
|
56
71
|
output_view.summary,
|
|
57
72
|
output_view.hints,
|
|
@@ -62,11 +77,21 @@ function renderRichQueryOutput(output_view, ansi) {
|
|
|
62
77
|
return renderRichEmptyQuery(footer, ansi);
|
|
63
78
|
}
|
|
64
79
|
|
|
80
|
+
const left_title_width = getCompactLeftTitleWidth(
|
|
81
|
+
output_view.items.map((output_item) => formatNodeHeader(output_item)),
|
|
82
|
+
);
|
|
83
|
+
const output_blocks = output_view.items.map((output_item) =>
|
|
84
|
+
formatRichNodeItem(output_item, ansi, {
|
|
85
|
+
...render_options,
|
|
86
|
+
left_title_width,
|
|
87
|
+
}),
|
|
88
|
+
);
|
|
89
|
+
|
|
65
90
|
if (footer.length === 0) {
|
|
66
|
-
return `${
|
|
91
|
+
return `${output_blocks.join('\n\n')}\n`;
|
|
67
92
|
}
|
|
68
93
|
|
|
69
|
-
return `${
|
|
94
|
+
return `${output_blocks.join('\n\n')}\n\n${footer}\n`;
|
|
70
95
|
}
|
|
71
96
|
|
|
72
97
|
/**
|
|
@@ -84,28 +109,29 @@ function renderRichEmptyQuery(footer, ansi) {
|
|
|
84
109
|
|
|
85
110
|
/**
|
|
86
111
|
* @param {Extract<OutputView, { command: 'queries' }>} output_view
|
|
112
|
+
* @param {{ is_tty?: boolean, terminal_width?: number }} render_options
|
|
87
113
|
* @param {Ansis} ansi
|
|
88
114
|
* @returns {string}
|
|
89
115
|
*/
|
|
90
|
-
function renderRichStoredQueries(output_view, ansi) {
|
|
116
|
+
function renderRichStoredQueries(output_view, render_options, ansi) {
|
|
91
117
|
if (output_view.items.length === 0) {
|
|
92
118
|
return '';
|
|
93
119
|
}
|
|
94
120
|
|
|
95
|
-
const
|
|
96
|
-
(
|
|
121
|
+
const output_blocks = output_view.items.map((output_item) =>
|
|
122
|
+
formatRichStoredQueryBlock(output_item, ansi, render_options),
|
|
97
123
|
);
|
|
98
124
|
|
|
99
125
|
if (output_view.hints.length === 0) {
|
|
100
|
-
return `${
|
|
126
|
+
return `${output_blocks.join('\n')}\n`;
|
|
101
127
|
}
|
|
102
128
|
|
|
103
|
-
return `${
|
|
129
|
+
return `${output_blocks.join('\n')}\n${output_view.hints.map((hint) => ansi.gray(hint)).join('\n')}\n`;
|
|
104
130
|
}
|
|
105
131
|
|
|
106
132
|
/**
|
|
107
133
|
* @param {ShowOutputView} output_view
|
|
108
|
-
* @param {{ color_mode: CliColorMode, color_enabled: boolean }} render_options
|
|
134
|
+
* @param {{ color_mode: CliColorMode, color_enabled: boolean, is_tty?: boolean, terminal_width?: number }} render_options
|
|
109
135
|
* @param {Ansis} ansi
|
|
110
136
|
* @returns {Promise<string>}
|
|
111
137
|
*/
|
|
@@ -119,8 +145,15 @@ async function renderRichShowOutput(output_view, render_options, ansi) {
|
|
|
119
145
|
return `${rendered_source}\n`;
|
|
120
146
|
}
|
|
121
147
|
|
|
148
|
+
const left_title_width = getCompactLeftTitleWidth(
|
|
149
|
+
output_view.items.map(formatResolvedLinkHeader),
|
|
150
|
+
);
|
|
122
151
|
const summary_items = output_view.items.map((item) =>
|
|
123
|
-
formatRichResolvedLinkItem(item, ansi
|
|
152
|
+
formatRichResolvedLinkItem(item, ansi, {
|
|
153
|
+
is_tty: render_options.is_tty,
|
|
154
|
+
left_title_width,
|
|
155
|
+
terminal_width: render_options.terminal_width,
|
|
156
|
+
}),
|
|
124
157
|
);
|
|
125
158
|
|
|
126
159
|
if (incoming_summary.length > 0) {
|
|
@@ -132,14 +165,26 @@ async function renderRichShowOutput(output_view, render_options, ansi) {
|
|
|
132
165
|
|
|
133
166
|
/**
|
|
134
167
|
* @param {RefsOutputView} output_view
|
|
168
|
+
* @param {{ is_tty?: boolean, terminal_width?: number }} render_options
|
|
135
169
|
* @param {Ansis} ansi
|
|
136
170
|
* @returns {string}
|
|
137
171
|
*/
|
|
138
|
-
function renderRichRefsOutput(output_view, ansi) {
|
|
139
|
-
const
|
|
172
|
+
function renderRichRefsOutput(output_view, render_options, ansi) {
|
|
173
|
+
const left_title_width = getCompactLeftTitleWidth(
|
|
174
|
+
collectIncomingRefHeaders(output_view),
|
|
175
|
+
);
|
|
176
|
+
const incoming_render_options =
|
|
177
|
+
createIncomingTreeRenderOptions(render_options);
|
|
178
|
+
const node_summary = formatRichNodeItem(output_view.node, ansi, {
|
|
179
|
+
...render_options,
|
|
180
|
+
left_title_width,
|
|
181
|
+
});
|
|
140
182
|
const output_lines = layoutIncomingReferenceLines(output_view.incoming, {
|
|
141
|
-
|
|
142
|
-
return
|
|
183
|
+
format_node_block(output_item) {
|
|
184
|
+
return formatRichNodeItem(output_item, ansi, {
|
|
185
|
+
...incoming_render_options,
|
|
186
|
+
left_title_width,
|
|
187
|
+
});
|
|
143
188
|
},
|
|
144
189
|
format_relation_header(relation_name, relation_count) {
|
|
145
190
|
return `${ansi.bold(relation_name)} ${ansi.gray(`(${relation_count})`)}`;
|
|
@@ -154,14 +199,44 @@ function renderRichRefsOutput(output_view, ansi) {
|
|
|
154
199
|
/**
|
|
155
200
|
* @param {OutputNodeItem} output_item
|
|
156
201
|
* @param {Ansis} ansi
|
|
202
|
+
* @param {{ is_tty?: boolean, left_title_width: number, terminal_width?: number }} render_options
|
|
157
203
|
* @returns {string}
|
|
158
204
|
*/
|
|
159
|
-
function formatRichNodeItem(output_item, ansi) {
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
205
|
+
function formatRichNodeItem(output_item, ansi, render_options) {
|
|
206
|
+
const metadata_label = formatStoredMetadataLabel(
|
|
207
|
+
formatOutputNodeStoredMetadataRow(output_item),
|
|
208
|
+
);
|
|
209
|
+
/** @type {string[]} */
|
|
210
|
+
const output_lines = [
|
|
211
|
+
formatCompactTitleRow({
|
|
212
|
+
format_left(text) {
|
|
213
|
+
return ansi.green(text);
|
|
214
|
+
},
|
|
215
|
+
format_right(text) {
|
|
216
|
+
return formatRichCompactMetadataLabel(text, ansi);
|
|
217
|
+
},
|
|
218
|
+
is_tty: render_options.is_tty,
|
|
219
|
+
left_title: formatNodeHeader(output_item),
|
|
220
|
+
left_title_width: render_options.left_title_width,
|
|
221
|
+
right_title: metadata_label,
|
|
222
|
+
terminal_width: render_options.terminal_width,
|
|
223
|
+
}),
|
|
224
|
+
];
|
|
225
|
+
|
|
226
|
+
output_lines.push(` ${output_item.title}`);
|
|
227
|
+
|
|
228
|
+
if (output_item.description) {
|
|
229
|
+
for (const description_line of wrapCompactBodyText(
|
|
230
|
+
output_item.description,
|
|
231
|
+
render_options,
|
|
232
|
+
)) {
|
|
233
|
+
output_lines.push(
|
|
234
|
+
formatRichDescriptionLine(description_line, ' ', ansi),
|
|
235
|
+
);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
return output_lines.join('\n');
|
|
165
240
|
}
|
|
166
241
|
|
|
167
242
|
/**
|
|
@@ -176,19 +251,72 @@ function formatRichStoredQueryLine(line_segments, ansi) {
|
|
|
176
251
|
}
|
|
177
252
|
|
|
178
253
|
/**
|
|
179
|
-
* @param {
|
|
254
|
+
* @param {OutputStoredQueryItem} output_item
|
|
180
255
|
* @param {Ansis} ansi
|
|
256
|
+
* @param {{ is_tty?: boolean, terminal_width?: number }} render_options
|
|
181
257
|
* @returns {string}
|
|
182
258
|
*/
|
|
183
|
-
function
|
|
184
|
-
return
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
259
|
+
function formatRichStoredQueryBlock(output_item, ansi, render_options) {
|
|
260
|
+
return formatStoredQueryBlock(output_item, render_options, {
|
|
261
|
+
format_description(text) {
|
|
262
|
+
return ansi.gray(text);
|
|
263
|
+
},
|
|
264
|
+
format_line(line_segments) {
|
|
265
|
+
return formatRichStoredQueryLine(line_segments, ansi);
|
|
266
|
+
},
|
|
267
|
+
format_name(text) {
|
|
268
|
+
return ansi.green(text);
|
|
269
|
+
},
|
|
189
270
|
});
|
|
190
271
|
}
|
|
191
272
|
|
|
273
|
+
/**
|
|
274
|
+
* @param {OutputResolvedLinkItem} output_item
|
|
275
|
+
* @param {Ansis} ansi
|
|
276
|
+
* @param {{ is_tty?: boolean, left_title_width: number, terminal_width?: number }} render_options
|
|
277
|
+
* @returns {string}
|
|
278
|
+
*/
|
|
279
|
+
function formatRichResolvedLinkItem(output_item, ansi, render_options) {
|
|
280
|
+
const metadata_label = formatStoredMetadataLabel(
|
|
281
|
+
formatResolvedLinkStoredMetadataRow(output_item.target),
|
|
282
|
+
);
|
|
283
|
+
/** @type {string[]} */
|
|
284
|
+
const output_lines = [
|
|
285
|
+
formatCompactTitleRow({
|
|
286
|
+
format_left(text) {
|
|
287
|
+
const closing_bracket_index = text.indexOf(']');
|
|
288
|
+
|
|
289
|
+
if (closing_bracket_index === -1) {
|
|
290
|
+
return ansi.green(text);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
const reference_token = text.slice(0, closing_bracket_index + 1);
|
|
294
|
+
const header_suffix = text.slice(closing_bracket_index + 1);
|
|
295
|
+
|
|
296
|
+
return `${ansi.gray(reference_token)}${ansi.green(header_suffix)}`;
|
|
297
|
+
},
|
|
298
|
+
format_right(text) {
|
|
299
|
+
return formatRichCompactMetadataLabel(text, ansi);
|
|
300
|
+
},
|
|
301
|
+
is_tty: render_options.is_tty,
|
|
302
|
+
left_title: formatResolvedLinkHeader(output_item),
|
|
303
|
+
left_title_width: render_options.left_title_width,
|
|
304
|
+
right_title: metadata_label,
|
|
305
|
+
terminal_width: render_options.terminal_width,
|
|
306
|
+
}),
|
|
307
|
+
];
|
|
308
|
+
|
|
309
|
+
output_lines.push(
|
|
310
|
+
...formatRichResolvedLinkBodyLines(output_item, ansi, {
|
|
311
|
+
body_indent: ' ',
|
|
312
|
+
is_tty: render_options.is_tty,
|
|
313
|
+
terminal_width: render_options.terminal_width,
|
|
314
|
+
}),
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
return output_lines.join('\n');
|
|
318
|
+
}
|
|
319
|
+
|
|
192
320
|
/**
|
|
193
321
|
* @param {ShowOutputView} output_view
|
|
194
322
|
* @param {Ansis} ansi
|
|
@@ -223,6 +351,92 @@ function createAnsi(color_enabled) {
|
|
|
223
351
|
return new Ansis(color_enabled ? 3 : 0);
|
|
224
352
|
}
|
|
225
353
|
|
|
354
|
+
/**
|
|
355
|
+
* @param {string | undefined} metadata_row
|
|
356
|
+
* @returns {string | undefined}
|
|
357
|
+
*/
|
|
358
|
+
function formatStoredMetadataLabel(metadata_row) {
|
|
359
|
+
if (!metadata_row) {
|
|
360
|
+
return undefined;
|
|
361
|
+
}
|
|
362
|
+
|
|
363
|
+
return formatCompactMetadataLabel([metadata_row]);
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
/**
|
|
367
|
+
* @param {string} metadata_label
|
|
368
|
+
* @param {Ansis} ansi
|
|
369
|
+
* @returns {string}
|
|
370
|
+
*/
|
|
371
|
+
function formatRichCompactMetadataLabel(metadata_label, ansi) {
|
|
372
|
+
return [...metadata_label]
|
|
373
|
+
.map((character) =>
|
|
374
|
+
character === '(' ||
|
|
375
|
+
character === ')' ||
|
|
376
|
+
character === ',' ||
|
|
377
|
+
character === '='
|
|
378
|
+
? ansi.gray(character)
|
|
379
|
+
: character,
|
|
380
|
+
)
|
|
381
|
+
.join('');
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
/**
|
|
385
|
+
* @param {string} description_line
|
|
386
|
+
* @param {string} indent
|
|
387
|
+
* @param {Ansis} ansi
|
|
388
|
+
* @returns {string}
|
|
389
|
+
*/
|
|
390
|
+
function formatRichDescriptionLine(description_line, indent, ansi) {
|
|
391
|
+
if (description_line.length === 0) {
|
|
392
|
+
return '';
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
return `${indent}${ansi.gray(description_line)}`;
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* @param {OutputResolvedLinkItem} output_item
|
|
400
|
+
* @param {Ansis} ansi
|
|
401
|
+
* @param {{ body_indent?: string, is_tty?: boolean, terminal_width?: number }} render_options
|
|
402
|
+
* @returns {string[]}
|
|
403
|
+
*/
|
|
404
|
+
function formatRichResolvedLinkBodyLines(output_item, ansi, render_options) {
|
|
405
|
+
const body_indent = render_options.body_indent ?? ' ';
|
|
406
|
+
const body_lines = formatResolvedLinkBodyLines(output_item, render_options);
|
|
407
|
+
|
|
408
|
+
if (body_lines.length <= 1) {
|
|
409
|
+
return body_lines;
|
|
410
|
+
}
|
|
411
|
+
|
|
412
|
+
return [
|
|
413
|
+
body_lines[0],
|
|
414
|
+
...body_lines
|
|
415
|
+
.slice(1)
|
|
416
|
+
.map((line) =>
|
|
417
|
+
formatRichIndentedDescriptionLine(line, body_indent, ansi),
|
|
418
|
+
),
|
|
419
|
+
];
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
/**
|
|
423
|
+
* @param {string} line
|
|
424
|
+
* @param {string} indent
|
|
425
|
+
* @param {Ansis} ansi
|
|
426
|
+
* @returns {string}
|
|
427
|
+
*/
|
|
428
|
+
function formatRichIndentedDescriptionLine(line, indent, ansi) {
|
|
429
|
+
if (line.length === 0) {
|
|
430
|
+
return '';
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
if (!line.startsWith(indent)) {
|
|
434
|
+
return ansi.gray(line);
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
return `${indent}${ansi.gray(line.slice(indent.length))}`;
|
|
438
|
+
}
|
|
439
|
+
|
|
226
440
|
/**
|
|
227
441
|
* @param {{ kind: 'description' | 'field_name' | 'keyword' | 'literal' | 'name' | 'operator' | 'plain', text: string }} line_segment
|
|
228
442
|
* @param {Ansis} ansi
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @import { OutputResolvedLinkItem } from './output-view.types.ts';
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { wrapCompactBodyText } from './compact-layout.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @param {OutputResolvedLinkItem} output_item
|
|
9
|
+
* @returns {string}
|
|
10
|
+
*/
|
|
11
|
+
export function formatResolvedLinkHeader(output_item) {
|
|
12
|
+
return `[${output_item.reference}] ${output_item.target.kind} ${output_item.target.path ?? output_item.target.id}`;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* @param {OutputResolvedLinkItem} output_item
|
|
17
|
+
* @param {{ body_indent?: string, is_tty?: boolean, terminal_width?: number }} render_options
|
|
18
|
+
* @returns {string[]}
|
|
19
|
+
*/
|
|
20
|
+
export function formatResolvedLinkBodyLines(output_item, render_options = {}) {
|
|
21
|
+
const body_indent = render_options.body_indent ?? ' ';
|
|
22
|
+
/** @type {string[]} */
|
|
23
|
+
const output_lines = [`${body_indent}${output_item.target.title}`];
|
|
24
|
+
|
|
25
|
+
if (!output_item.target.description) {
|
|
26
|
+
return output_lines;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
for (const description_line of wrapCompactBodyText(
|
|
30
|
+
output_item.target.description,
|
|
31
|
+
{
|
|
32
|
+
body_indent,
|
|
33
|
+
is_tty: render_options.is_tty,
|
|
34
|
+
terminal_width: render_options.terminal_width,
|
|
35
|
+
},
|
|
36
|
+
)) {
|
|
37
|
+
output_lines.push(
|
|
38
|
+
description_line.length > 0 ? `${body_indent}${description_line}` : '',
|
|
39
|
+
);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return output_lines;
|
|
43
|
+
}
|