patram 0.8.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.
Files changed (140) hide show
  1. package/bin/patram.js +2 -2
  2. package/lib/{parse-cli-color-options.js → cli/color-options.js} +2 -2
  3. package/lib/cli/command-helpers.js +35 -0
  4. package/lib/cli/commands/check.js +73 -0
  5. package/lib/cli/commands/fields.js +57 -0
  6. package/lib/cli/commands/queries.js +41 -0
  7. package/lib/cli/commands/query.js +239 -0
  8. package/lib/cli/commands/refs.js +72 -0
  9. package/lib/cli/commands/show.js +58 -0
  10. package/lib/{cli-help-metadata.js → cli/help-metadata.js} +6 -6
  11. package/lib/cli/main.js +76 -0
  12. package/lib/{parse-cli-arguments-helpers.js → cli/parse-arguments-helpers.js} +7 -7
  13. package/lib/{parse-cli-arguments.js → cli/parse-arguments.js} +12 -12
  14. package/lib/{parse-cli-query-pagination.js → cli/query-pagination.js} +2 -2
  15. package/lib/{render-cli-help.js → cli/render-help.js} +3 -3
  16. package/lib/{resolve-output-mode.js → cli/resolve-output-mode.js} +2 -2
  17. package/lib/cli/test-helpers.js +30 -0
  18. package/lib/config/defaults.d.ts +10 -0
  19. package/lib/config/defaults.js +80 -0
  20. package/lib/config/load-patram-config.d.ts +76 -0
  21. package/lib/config/load-patram-config.js +315 -0
  22. package/lib/config/load-patram-config.types.d.ts +45 -0
  23. package/lib/{patram-config.d.ts → config/patram-config.d.ts} +31 -31
  24. package/lib/{patram-config.js → config/patram-config.js} +3 -3
  25. package/lib/{patram-config.types.d.ts → config/patram-config.types.d.ts} +1 -1
  26. package/lib/{resolve-patram-graph-config.d.ts → config/resolve-patram-graph-config.d.ts} +2 -2
  27. package/lib/{resolve-patram-graph-config.js → config/resolve-patram-graph-config.js} +3 -3
  28. package/lib/{load-patram-config.d.ts → config/schema.d.ts} +147 -191
  29. package/lib/config/schema.js +324 -0
  30. package/lib/{source-file-defaults.d.ts → config/source-file-defaults.d.ts} +0 -1
  31. package/lib/{source-file-defaults.js → config/source-file-defaults.js} +1 -1
  32. package/lib/config/validation.d.ts +27 -0
  33. package/lib/config/validation.js +615 -0
  34. package/lib/directive-validation-test-helpers.js +1 -1
  35. package/lib/{build-graph-identity.d.ts → graph/build-graph-identity.d.ts} +2 -2
  36. package/lib/{build-graph-identity.js → graph/build-graph-identity.js} +1 -1
  37. package/lib/{build-graph.d.ts → graph/build-graph.d.ts} +3 -3
  38. package/lib/{build-graph.js → graph/build-graph.js} +17 -13
  39. package/lib/{build-graph.types.d.ts → graph/build-graph.types.d.ts} +1 -1
  40. package/lib/graph/check-directive-metadata.d.ts +23 -0
  41. package/lib/{check-directive-metadata.js → graph/check-directive-metadata.js} +7 -7
  42. package/lib/graph/check-directive-path-target.d.ts +32 -0
  43. package/lib/{check-directive-path-target.js → graph/check-directive-path-target.js} +4 -4
  44. package/lib/graph/check-directive-value.d.ts +19 -0
  45. package/lib/{check-directive-value.js → graph/check-directive-value.js} +3 -3
  46. package/lib/graph/check-graph.d.ts +29 -0
  47. package/lib/{check-graph.js → graph/check-graph.js} +6 -6
  48. package/lib/graph/directive-diagnostics.d.ts +20 -0
  49. package/lib/{directive-diagnostics.js → graph/directive-diagnostics.js} +2 -2
  50. package/lib/graph/directive-type-rules.d.ts +18 -0
  51. package/lib/{directive-type-rules.js → graph/directive-type-rules.js} +3 -3
  52. package/lib/{document-node-identity.d.ts → graph/document-node-identity.d.ts} +2 -2
  53. package/lib/{document-node-identity.js → graph/document-node-identity.js} +2 -2
  54. package/lib/graph/inspect-reverse-references.d.ts +22 -0
  55. package/lib/{inspect-reverse-references.js → graph/inspect-reverse-references.js} +2 -2
  56. package/lib/{load-project-graph.d.ts → graph/load-project-graph.d.ts} +10 -10
  57. package/lib/{load-project-graph.js → graph/load-project-graph.js} +12 -12
  58. package/lib/{parse-where-clause.types.d.ts → graph/parse-where-clause.types.d.ts} +1 -1
  59. package/lib/{query-graph.d.ts → graph/query/execute.d.ts} +11 -11
  60. package/lib/{query-graph.js → graph/query/execute.js} +12 -12
  61. package/lib/{query-inspection.d.ts → graph/query/inspect.d.ts} +10 -8
  62. package/lib/{query-inspection.js → graph/query/inspect.js} +16 -17
  63. package/lib/{parse-where-clause.d.ts → graph/query/parse.d.ts} +6 -6
  64. package/lib/{parse-where-clause.js → graph/query/parse.js} +2 -2
  65. package/lib/graph/query/resolve.d.ts +30 -0
  66. package/lib/{resolve-where-clause.js → graph/query/resolve.js} +1 -1
  67. package/lib/graph/reverse-reference-test-helpers.d.ts +55 -0
  68. package/lib/{command-output.js → output/command-output.js} +5 -5
  69. package/lib/{derived-summary.js → output/derived-summary.js} +7 -7
  70. package/lib/{layout-incoming-references.js → output/layout-incoming-references.js} +4 -4
  71. package/lib/{layout-incoming-summary-lines.js → output/layout-incoming-summary-lines.js} +0 -5
  72. package/lib/{layout-stored-queries.js → output/layout-stored-queries.js} +9 -9
  73. package/lib/{list-queries.js → output/list-queries.js} +1 -1
  74. package/lib/{render-check-output.js → output/render-check-output.js} +1 -1
  75. package/lib/{render-field-discovery.js → output/render-field-discovery.js} +3 -3
  76. package/lib/output/render-output-view.js +56 -0
  77. package/lib/{render-json-output.js → output/renderers/json.js} +1 -1
  78. package/lib/{render-plain-output.js → output/renderers/plain.js} +19 -7
  79. package/lib/{render-rich-output.js → output/renderers/rich.js} +29 -13
  80. package/lib/{resolve-check-target.js → output/resolve-check-target.js} +1 -1
  81. package/lib/{render-rich-source.js → output/rich-source/render.js} +6 -6
  82. package/lib/{show-document.js → output/show-document.js} +12 -12
  83. package/lib/{render-output-view.js → output/view-model/index.js} +6 -52
  84. package/lib/{write-paged-output.js → output/write-paged-output.js} +9 -5
  85. package/lib/{claim-helpers.d.ts → parse/claim-helpers.d.ts} +2 -2
  86. package/lib/{parse-jsdoc-claims.d.ts → parse/jsdoc/parse-jsdoc-claims.d.ts} +2 -2
  87. package/lib/{parse-jsdoc-claims.js → parse/jsdoc/parse-jsdoc-claims.js} +9 -9
  88. package/lib/{parse-jsdoc-prose.d.ts → parse/jsdoc/parse-jsdoc-prose.d.ts} +1 -1
  89. package/lib/{parse-jsdoc-prose.js → parse/jsdoc/parse-jsdoc-prose.js} +1 -1
  90. package/lib/{parse-markdown-claims.d.ts → parse/markdown/parse-markdown-claims.d.ts} +3 -3
  91. package/lib/{parse-markdown-claims.js → parse/markdown/parse-markdown-claims.js} +8 -8
  92. package/lib/{parse-markdown-directives.d.ts → parse/markdown/parse-markdown-directives.d.ts} +2 -2
  93. package/lib/{parse-markdown-directives.js → parse/markdown/parse-markdown-directives.js} +3 -3
  94. package/lib/{parse-claims.d.ts → parse/parse-claims.d.ts} +4 -13
  95. package/lib/{parse-claims.js → parse/parse-claims.js} +18 -26
  96. package/lib/{parse-claims.types.d.ts → parse/parse-claims.types.d.ts} +1 -1
  97. package/lib/{tagged-fenced-block-error.d.ts → parse/tagged-fenced/tagged-fenced-block-error.d.ts} +2 -2
  98. package/lib/{tagged-fenced-block-parser.d.ts → parse/tagged-fenced/tagged-fenced-block-parser.d.ts} +3 -3
  99. package/lib/{tagged-fenced-blocks.d.ts → parse/tagged-fenced/tagged-fenced-blocks.d.ts} +7 -7
  100. package/lib/{tagged-fenced-blocks.js → parse/tagged-fenced/tagged-fenced-blocks.js} +3 -3
  101. package/lib/{parse-yaml-claims.d.ts → parse/yaml/parse-yaml-claims.d.ts} +4 -4
  102. package/lib/{parse-yaml-claims.js → parse/yaml/parse-yaml-claims.js} +22 -13
  103. package/lib/patram.d.ts +29 -28
  104. package/lib/patram.js +5 -6
  105. package/lib/{discover-fields.js → scan/discover-fields.js} +9 -8
  106. package/lib/scan/list-repo-files.d.ts +16 -0
  107. package/lib/{list-source-files.js → scan/list-repo-files.js} +2 -35
  108. package/lib/{list-source-files.d.ts → scan/list-source-files.d.ts} +4 -11
  109. package/lib/scan/list-source-files.js +45 -0
  110. package/package.json +8 -7
  111. package/lib/build-graph.types.ts +0 -27
  112. package/lib/discover-fields.types.ts +0 -52
  113. package/lib/load-patram-config.js +0 -1215
  114. package/lib/load-patram-config.types.d.ts +0 -45
  115. package/lib/load-patram-config.types.ts +0 -56
  116. package/lib/output-view.types.d.ts +0 -88
  117. package/lib/output-view.types.ts +0 -113
  118. package/lib/overlay-graph.d.ts +0 -43
  119. package/lib/overlay-graph.js +0 -191
  120. package/lib/parse-claims.types.ts +0 -41
  121. package/lib/parse-cli-arguments.types.ts +0 -75
  122. package/lib/parse-where-clause.types.ts +0 -87
  123. package/lib/patram-cli.js +0 -593
  124. package/lib/patram-config.types.ts +0 -22
  125. package/lib/tagged-fenced-blocks.types.ts +0 -38
  126. /package/lib/{reverse-reference-test-helpers.js → graph/reverse-reference-test-helpers.js} +0 -0
  127. /package/lib/{format-derived-summary-row.js → output/format-derived-summary-row.js} +0 -0
  128. /package/lib/{format-node-header.js → output/format-node-header.js} +0 -0
  129. /package/lib/{format-output-item-block.js → output/format-output-item-block.js} +0 -0
  130. /package/lib/{format-output-metadata.js → output/format-output-metadata.js} +0 -0
  131. /package/lib/{claim-helpers.js → parse/claim-helpers.js} +0 -0
  132. /package/lib/{parse-jsdoc-blocks.d.ts → parse/jsdoc/parse-jsdoc-blocks.d.ts} +0 -0
  133. /package/lib/{parse-jsdoc-blocks.js → parse/jsdoc/parse-jsdoc-blocks.js} +0 -0
  134. /package/lib/{tagged-fenced-block-error.js → parse/tagged-fenced/tagged-fenced-block-error.js} +0 -0
  135. /package/lib/{tagged-fenced-block-markdown.d.ts → parse/tagged-fenced/tagged-fenced-block-markdown.d.ts} +0 -0
  136. /package/lib/{tagged-fenced-block-markdown.js → parse/tagged-fenced/tagged-fenced-block-markdown.js} +0 -0
  137. /package/lib/{tagged-fenced-block-metadata.d.ts → parse/tagged-fenced/tagged-fenced-block-metadata.d.ts} +0 -0
  138. /package/lib/{tagged-fenced-block-metadata.js → parse/tagged-fenced/tagged-fenced-block-metadata.js} +0 -0
  139. /package/lib/{tagged-fenced-block-parser.js → parse/tagged-fenced/tagged-fenced-block-parser.js} +0 -0
  140. /package/lib/{tagged-fenced-blocks.types.d.ts → parse/tagged-fenced/tagged-fenced-blocks.types.d.ts} +0 -0
@@ -1,87 +0,0 @@
1
- import type { PatramDiagnostic } from './load-patram-config.types.ts';
2
-
3
- export type ParsedFieldName = string;
4
-
5
- export interface ParsedFieldTerm {
6
- column: number;
7
- field_name: ParsedFieldName;
8
- kind: 'field';
9
- operator: '!=' | '<' | '<=' | '=' | '>' | '>=' | '^=' | '~';
10
- value: string;
11
- }
12
-
13
- export interface ParsedFieldSetTerm {
14
- column: number;
15
- field_name: ParsedFieldName;
16
- kind: 'field_set';
17
- operator: 'in' | 'not in';
18
- values: string[];
19
- }
20
-
21
- export interface ParsedTraversalTerm {
22
- column: number;
23
- direction: 'in' | 'out';
24
- relation_name: string;
25
- }
26
-
27
- export interface ParsedRelationTerm {
28
- column: number;
29
- kind: 'relation';
30
- relation_name: string;
31
- }
32
-
33
- export interface ParsedRelationTargetTerm {
34
- column: number;
35
- kind: 'relation_target';
36
- relation_name: string;
37
- target_id: string;
38
- }
39
-
40
- export type ParsedAggregateComparison = '!=' | '<' | '<=' | '=' | '>' | '>=';
41
- export type ParsedAggregateName = 'any' | 'count' | 'none';
42
-
43
- export interface ParsedAggregateTerm {
44
- aggregate_name: ParsedAggregateName;
45
- comparison?: ParsedAggregateComparison;
46
- expression: ParsedExpression;
47
- kind: 'aggregate';
48
- traversal: ParsedTraversalTerm;
49
- value?: number;
50
- }
51
-
52
- export interface ParsedTermExpression {
53
- kind: 'term';
54
- term: ParsedTerm;
55
- }
56
-
57
- export interface ParsedNotExpression {
58
- expression: ParsedExpression;
59
- kind: 'not';
60
- }
61
-
62
- export interface ParsedBooleanExpression {
63
- expressions: ParsedExpression[];
64
- kind: 'and' | 'or';
65
- }
66
-
67
- export type ParsedTerm =
68
- | ParsedAggregateTerm
69
- | ParsedFieldSetTerm
70
- | ParsedFieldTerm
71
- | ParsedRelationTargetTerm
72
- | ParsedRelationTerm;
73
-
74
- export type ParsedExpression =
75
- | ParsedBooleanExpression
76
- | ParsedNotExpression
77
- | ParsedTermExpression;
78
-
79
- export type ParseWhereClauseResult =
80
- | {
81
- expression: ParsedExpression;
82
- success: true;
83
- }
84
- | {
85
- diagnostic: PatramDiagnostic;
86
- success: false;
87
- };
package/lib/patram-cli.js DELETED
@@ -1,593 +0,0 @@
1
- /* eslint-disable max-lines */
2
- /**
3
- * @import { ParsedCliCommandRequest } from './parse-cli-arguments.types.ts';
4
- */
5
-
6
- import process from 'node:process';
7
-
8
- import { checkGraph } from './check-graph.js';
9
- import {
10
- shouldPageCommandOutput,
11
- writeCommandOutput,
12
- writeRenderedCommandOutput,
13
- } from './command-output.js';
14
- import { discoverFields } from './discover-fields.js';
15
- import { inspectReverseReferences } from './inspect-reverse-references.js';
16
- import { listRepoFiles } from './list-source-files.js';
17
- import { listQueries } from './list-queries.js';
18
- import { loadPatramConfig } from './load-patram-config.js';
19
- import { loadProjectGraph } from './load-project-graph.js';
20
- import { parseCliArguments } from './parse-cli-arguments.js';
21
- import { DEFAULT_QUERY_LIMIT, queryGraph } from './query-graph.js';
22
- import { inspectQuery, renderQueryInspection } from './query-inspection.js';
23
- import { createDerivedSummaryEvaluator } from './derived-summary.js';
24
- import {
25
- renderCheckDiagnostics,
26
- renderCheckSuccess,
27
- } from './render-check-output.js';
28
- import {
29
- renderCliParseError,
30
- renderHelpRequest,
31
- renderInvalidWhereDiagnostic,
32
- } from './render-cli-help.js';
33
- import {
34
- resolveCheckTarget,
35
- selectCheckTargetDiagnostics,
36
- selectCheckTargetSourceFiles,
37
- } from './resolve-check-target.js';
38
- import {
39
- createOutputView,
40
- createRefsOutputView,
41
- createShowOutputView,
42
- } from './render-output-view.js';
43
- import { renderFieldDiscovery } from './render-field-discovery.js';
44
- import { resolveWhereClause } from './resolve-where-clause.js';
45
- import { resolveOutputMode } from './resolve-output-mode.js';
46
- import { loadShowOutput } from './show-document.js';
47
-
48
- /**
49
- * Patram command execution flow.
50
- *
51
- * Loads repo state and routes `check`, `fields`, `query`, `queries`, and
52
- * `show` through the shared output pipeline.
53
- *
54
- * Kind: cli
55
- * Status: active
56
- * Implements Command: ../docs/reference/commands/check.md
57
- * Implements Command: ../docs/reference/commands/query.md
58
- * Implements Command: ../docs/reference/commands/queries.md
59
- * Implements Command: ../docs/reference/commands/refs.md
60
- * Implements Command: ../docs/reference/commands/show.md
61
- * Tracked in: ../docs/plans/v0/source-anchor-dogfooding.md
62
- * Decided by: ../docs/decisions/cli-output-architecture.md
63
- * Decided by: ../docs/decisions/cli-argument-parser.md
64
- * @patram
65
- * @see {@link ./parse-cli-arguments.js}
66
- * @see {@link ./render-output-view.js}
67
- */
68
-
69
- /**
70
- * Run the Patram CLI.
71
- *
72
- * @param {string[]} cli_arguments
73
- * @param {{ stderr: { write(chunk: string): boolean }, stdout: { isTTY?: boolean, write(chunk: string): boolean }, write_paged_output?: (output_text: string) => Promise<void> }} io_context
74
- * @returns {Promise<number>}
75
- */
76
- export async function main(cli_arguments, io_context) {
77
- const parsed_arguments = parseCliArguments(cli_arguments);
78
-
79
- if (!parsed_arguments.success) {
80
- io_context.stderr.write(renderCliParseError(parsed_arguments.error));
81
-
82
- return 1;
83
- }
84
-
85
- if (parsed_arguments.value.kind === 'help') {
86
- io_context.stdout.write(renderHelpRequest(parsed_arguments.value));
87
-
88
- return 0;
89
- }
90
-
91
- const parsed_command = /** @type {ParsedCliCommandRequest} */ (
92
- parsed_arguments.value
93
- );
94
-
95
- if (parsed_command.command_name === 'check') {
96
- return runCheckCommand(parsed_command, io_context);
97
- }
98
-
99
- if (parsed_command.command_name === 'query') {
100
- return runQueryCommand(parsed_command, io_context);
101
- }
102
-
103
- if (parsed_command.command_name === 'fields') {
104
- return runFieldsCommand(parsed_command, io_context);
105
- }
106
-
107
- if (parsed_command.command_name === 'queries') {
108
- return runQueriesCommand(parsed_command, io_context);
109
- }
110
-
111
- if (parsed_command.command_name === 'refs') {
112
- return runRefsCommand(parsed_command, io_context);
113
- }
114
-
115
- if (parsed_command.command_name === 'show') {
116
- return runShowCommand(parsed_command, io_context);
117
- }
118
-
119
- io_context.stderr.write('Unknown command.\n');
120
-
121
- return 1;
122
- }
123
-
124
- /**
125
- * @param {ParsedCliCommandRequest} parsed_command
126
- * @param {{ stderr: { write(chunk: string): boolean }, stdout: { isTTY?: boolean, write(chunk: string): boolean }, write_paged_output?: (output_text: string) => Promise<void> }} io_context
127
- * @returns {Promise<number>}
128
- */
129
- async function runCheckCommand(parsed_command, io_context) {
130
- const output_mode = resolveOutputMode(parsed_command, {
131
- is_tty: io_context.stdout.isTTY === true,
132
- no_color: process.env.NO_COLOR !== undefined,
133
- term: process.env.TERM,
134
- });
135
- const resolved_target = await resolveCheckTarget(
136
- parsed_command.command_arguments[0],
137
- );
138
- const project_graph_result = await loadProjectGraph(
139
- resolved_target.project_directory,
140
- );
141
- const repo_file_paths = await listRepoFiles(
142
- resolved_target.project_directory,
143
- );
144
- const selected_source_file_paths = selectCheckTargetSourceFiles(
145
- project_graph_result.source_file_paths,
146
- resolved_target,
147
- );
148
-
149
- if (project_graph_result.diagnostics.length > 0) {
150
- io_context.stderr.write(
151
- renderCheckDiagnostics(project_graph_result.diagnostics, output_mode),
152
- );
153
-
154
- return 1;
155
- }
156
-
157
- const diagnostics = checkGraph(
158
- project_graph_result.graph,
159
- repo_file_paths,
160
- project_graph_result.config,
161
- project_graph_result.claims,
162
- );
163
- const selected_diagnostics = selectCheckTargetDiagnostics(
164
- diagnostics,
165
- resolved_target,
166
- );
167
-
168
- if (selected_diagnostics.length > 0) {
169
- io_context.stderr.write(
170
- renderCheckDiagnostics(selected_diagnostics, output_mode),
171
- );
172
-
173
- return 1;
174
- }
175
-
176
- io_context.stdout.write(
177
- renderCheckSuccess(selected_source_file_paths.length, output_mode),
178
- );
179
-
180
- return 0;
181
- }
182
-
183
- /**
184
- * @param {ParsedCliCommandRequest} parsed_command
185
- * @param {{ stderr: { write(chunk: string): boolean }, stdout: { isTTY?: boolean, write(chunk: string): boolean }, write_paged_output?: (output_text: string) => Promise<void> }} io_context
186
- * @returns {Promise<number>}
187
- */
188
- async function runQueryCommand(parsed_command, io_context) {
189
- const use_pager = shouldPageCommandOutput(parsed_command, io_context.stdout);
190
- const output_mode = resolveOutputMode(parsed_command, {
191
- is_tty: io_context.stdout.isTTY === true,
192
- no_color: process.env.NO_COLOR !== undefined,
193
- term: process.env.TERM,
194
- });
195
-
196
- if (parsed_command.query_inspection_mode) {
197
- return runQueryInspectionCommand(
198
- parsed_command,
199
- io_context,
200
- output_mode,
201
- use_pager,
202
- );
203
- }
204
-
205
- const project_graph_result = await loadProjectGraph(process.cwd());
206
-
207
- if (project_graph_result.diagnostics.length > 0) {
208
- writeDiagnostics(io_context.stderr, project_graph_result.diagnostics);
209
-
210
- return 1;
211
- }
212
-
213
- const where_clause = resolveWhereClause(
214
- project_graph_result.config,
215
- parsed_command.command_arguments,
216
- );
217
-
218
- if (!where_clause.success) {
219
- io_context.stderr.write(`${where_clause.message}\n`);
220
-
221
- return 1;
222
- }
223
-
224
- const query_result = queryGraph(
225
- project_graph_result.graph,
226
- where_clause.value.where_clause,
227
- project_graph_result.config,
228
- createQueryPaginationOptions(parsed_command, use_pager),
229
- );
230
-
231
- if (query_result.diagnostics.length > 0) {
232
- io_context.stderr.write(
233
- renderInvalidWhereDiagnostic(query_result.diagnostics[0]),
234
- );
235
-
236
- return 1;
237
- }
238
-
239
- const derived_summary_evaluator = createDerivedSummaryEvaluator(
240
- project_graph_result.config,
241
- project_graph_result.graph,
242
- );
243
-
244
- await writeCommandOutput(
245
- io_context,
246
- parsed_command,
247
- createOutputView('query', query_result.nodes, {
248
- derived_summary_evaluator,
249
- ...createQueryOutputOptions(parsed_command, query_result, use_pager),
250
- repo_config: project_graph_result.config,
251
- }),
252
- );
253
-
254
- return 0;
255
- }
256
-
257
- /**
258
- * @param {ParsedCliCommandRequest} parsed_command
259
- * @param {{ stderr: { write(chunk: string): boolean }, stdout: { isTTY?: boolean, write(chunk: string): boolean } }} io_context
260
- * @returns {Promise<number>}
261
- */
262
- async function runFieldsCommand(parsed_command, io_context) {
263
- const output_mode = resolveOutputMode(parsed_command, {
264
- is_tty: io_context.stdout.isTTY === true,
265
- no_color: process.env.NO_COLOR !== undefined,
266
- term: process.env.TERM,
267
- });
268
- const load_result = await loadPatramConfig(process.cwd());
269
- const defined_field_names =
270
- load_result.diagnostics.length === 0
271
- ? collectDefinedDiscoveryNames(load_result.config)
272
- : new Set();
273
- const discovery_result = await discoverFields(process.cwd(), {
274
- defined_field_names,
275
- });
276
-
277
- await writeRenderedCommandOutput(
278
- io_context,
279
- parsed_command,
280
- renderFieldDiscovery(discovery_result, output_mode),
281
- );
282
-
283
- return 0;
284
- }
285
-
286
- /**
287
- * @param {ParsedCliCommandRequest} parsed_command
288
- * @param {{ stderr: { write(chunk: string): boolean }, stdout: { isTTY?: boolean, write(chunk: string): boolean } }} io_context
289
- * @param {import('./output-view.types.ts').ResolvedOutputMode} output_mode
290
- * @param {boolean} use_pager
291
- * @returns {Promise<number>}
292
- */
293
- async function runQueryInspectionCommand(
294
- parsed_command,
295
- io_context,
296
- output_mode,
297
- use_pager,
298
- ) {
299
- const query_inspection_mode = parsed_command.query_inspection_mode;
300
-
301
- if (!query_inspection_mode) {
302
- throw new Error('Expected a query inspection mode.');
303
- }
304
-
305
- const load_result = await loadPatramConfig(process.cwd());
306
-
307
- if (load_result.diagnostics.length > 0) {
308
- io_context.stderr.write(
309
- renderCheckDiagnostics(load_result.diagnostics, output_mode),
310
- );
311
-
312
- return 1;
313
- }
314
-
315
- const repo_config = load_result.config;
316
-
317
- if (!repo_config) {
318
- throw new Error('Expected a valid Patram repo config.');
319
- }
320
-
321
- const where_clause = resolveWhereClause(
322
- repo_config,
323
- parsed_command.command_arguments,
324
- );
325
-
326
- if (!where_clause.success) {
327
- io_context.stderr.write(`${where_clause.message}\n`);
328
-
329
- return 1;
330
- }
331
-
332
- const query_inspection = inspectQuery(repo_config, where_clause.value, {
333
- inspection_mode: query_inspection_mode,
334
- ...createQueryExecutionOptions(parsed_command, use_pager),
335
- });
336
-
337
- if (!query_inspection.success) {
338
- io_context.stderr.write(
339
- renderCheckDiagnostics(query_inspection.diagnostics, output_mode),
340
- );
341
-
342
- return 1;
343
- }
344
-
345
- io_context.stdout.write(
346
- renderQueryInspection(query_inspection.value, output_mode),
347
- );
348
-
349
- return 0;
350
- }
351
-
352
- /**
353
- * @param {ParsedCliCommandRequest} parsed_command
354
- * @param {{ stderr: { write(chunk: string): boolean }, stdout: { isTTY?: boolean, write(chunk: string): boolean }, write_paged_output?: (output_text: string) => Promise<void> }} io_context
355
- * @returns {Promise<number>}
356
- */
357
- async function runQueriesCommand(parsed_command, io_context) {
358
- const load_result = await loadPatramConfig(process.cwd());
359
-
360
- if (load_result.diagnostics.length > 0) {
361
- writeDiagnostics(io_context.stderr, load_result.diagnostics);
362
-
363
- return 1;
364
- }
365
-
366
- const repo_config = load_result.config;
367
-
368
- if (!repo_config) {
369
- throw new Error('Expected a valid Patram repo config.');
370
- }
371
-
372
- await writeCommandOutput(
373
- io_context,
374
- parsed_command,
375
- createOutputView('queries', listQueries(repo_config.queries)),
376
- );
377
-
378
- return 0;
379
- }
380
-
381
- /**
382
- * @param {ParsedCliCommandRequest} parsed_command
383
- * @param {{ stderr: { write(chunk: string): boolean }, stdout: { isTTY?: boolean, write(chunk: string): boolean }, write_paged_output?: (output_text: string) => Promise<void> }} io_context
384
- * @returns {Promise<number>}
385
- */
386
- async function runRefsCommand(parsed_command, io_context) {
387
- const project_graph_result = await loadProjectGraph(process.cwd());
388
-
389
- if (project_graph_result.diagnostics.length > 0) {
390
- writeDiagnostics(io_context.stderr, project_graph_result.diagnostics);
391
-
392
- return 1;
393
- }
394
-
395
- const refs_output = inspectReverseReferences(
396
- project_graph_result.graph,
397
- parsed_command.command_arguments[0],
398
- project_graph_result.config,
399
- resolveRefsWhereClause(parsed_command.command_arguments),
400
- );
401
-
402
- if (refs_output.diagnostics.length > 0) {
403
- io_context.stderr.write(
404
- renderInvalidWhereDiagnostic(refs_output.diagnostics[0]),
405
- );
406
-
407
- return 1;
408
- }
409
-
410
- const derived_summary_evaluator = createDerivedSummaryEvaluator(
411
- project_graph_result.config,
412
- project_graph_result.graph,
413
- );
414
-
415
- await writeCommandOutput(
416
- io_context,
417
- parsed_command,
418
- createRefsOutputView(refs_output, {
419
- derived_summary_evaluator,
420
- repo_config: project_graph_result.config,
421
- }),
422
- );
423
-
424
- return 0;
425
- }
426
-
427
- /**
428
- * @param {ParsedCliCommandRequest} parsed_command
429
- * @param {{ stderr: { write(chunk: string): boolean }, stdout: { isTTY?: boolean, write(chunk: string): boolean }, write_paged_output?: (output_text: string) => Promise<void> }} io_context
430
- * @returns {Promise<number>}
431
- */
432
- async function runShowCommand(parsed_command, io_context) {
433
- const project_graph_result = await loadProjectGraph(process.cwd());
434
-
435
- if (project_graph_result.diagnostics.length > 0) {
436
- writeDiagnostics(io_context.stderr, project_graph_result.diagnostics);
437
-
438
- return 1;
439
- }
440
-
441
- const show_output = await loadShowOutput(
442
- parsed_command.command_arguments[0],
443
- process.cwd(),
444
- project_graph_result.graph,
445
- );
446
-
447
- if (!show_output.success) {
448
- writeDiagnostics(io_context.stderr, [show_output.diagnostic]);
449
-
450
- return 1;
451
- }
452
-
453
- const derived_summary_evaluator = createDerivedSummaryEvaluator(
454
- project_graph_result.config,
455
- project_graph_result.graph,
456
- );
457
-
458
- await writeCommandOutput(
459
- io_context,
460
- parsed_command,
461
- createShowOutputView(show_output.value, {
462
- derived_summary_evaluator,
463
- document_node_ids: project_graph_result.graph.document_node_ids,
464
- graph_nodes: project_graph_result.graph.nodes,
465
- repo_config: project_graph_result.config,
466
- }),
467
- );
468
-
469
- return 0;
470
- }
471
-
472
- /**
473
- * @param {{ write(chunk: string): boolean }} output_stream
474
- * @param {import('./load-patram-config.types.ts').PatramDiagnostic[]} diagnostics
475
- */
476
- function writeDiagnostics(output_stream, diagnostics) {
477
- for (const diagnostic of diagnostics) {
478
- output_stream.write(formatDiagnostic(diagnostic));
479
- }
480
- }
481
-
482
- /**
483
- * @param {ParsedCliCommandRequest} parsed_command
484
- * @param {{ total_count: number, nodes: import('./build-graph.types.ts').GraphNode[] }} query_result
485
- * @param {boolean} use_pager
486
- * @returns {{ hints: string[], limit: number, offset: number, total_count: number }}
487
- */
488
- function createQueryOutputOptions(parsed_command, query_result, use_pager) {
489
- /** @type {string[]} */
490
- const hints = [];
491
- const limit =
492
- parsed_command.query_limit ??
493
- (use_pager ? query_result.nodes.length : DEFAULT_QUERY_LIMIT);
494
- const offset = parsed_command.query_offset ?? 0;
495
-
496
- if (query_result.total_count === 0) {
497
- hints.push("Try: patram query --where '$class=task'");
498
- }
499
-
500
- if (
501
- !use_pager &&
502
- parsed_command.query_limit === undefined &&
503
- parsed_command.query_offset === undefined &&
504
- query_result.total_count > DEFAULT_QUERY_LIMIT
505
- ) {
506
- hints.push(
507
- 'Hint: use --offset <n> or --limit <n> to page through more matches.',
508
- );
509
- }
510
-
511
- return {
512
- hints,
513
- limit,
514
- offset,
515
- total_count: query_result.total_count,
516
- };
517
- }
518
-
519
- /**
520
- * @param {ParsedCliCommandRequest} parsed_command
521
- * @param {boolean} use_pager
522
- * @returns {{ limit?: number, offset: number }}
523
- */
524
- function createQueryPaginationOptions(parsed_command, use_pager) {
525
- /** @type {{ limit?: number, offset: number }} */
526
- const pagination_options = {
527
- offset: parsed_command.query_offset ?? 0,
528
- };
529
-
530
- if (parsed_command.query_limit !== undefined) {
531
- pagination_options.limit = parsed_command.query_limit;
532
- } else if (!use_pager) {
533
- pagination_options.limit = DEFAULT_QUERY_LIMIT;
534
- }
535
-
536
- return pagination_options;
537
- }
538
-
539
- /**
540
- * @param {ParsedCliCommandRequest} parsed_command
541
- * @param {boolean} use_pager
542
- * @returns {{ limit: number | null, offset: number }}
543
- */
544
- function createQueryExecutionOptions(parsed_command, use_pager) {
545
- const pagination_options = createQueryPaginationOptions(
546
- parsed_command,
547
- use_pager,
548
- );
549
-
550
- return {
551
- limit: pagination_options.limit ?? null,
552
- offset: pagination_options.offset,
553
- };
554
- }
555
-
556
- /**
557
- * @param {string[]} command_arguments
558
- * @returns {string | undefined}
559
- */
560
- function resolveRefsWhereClause(command_arguments) {
561
- if (command_arguments[1] !== '--where') {
562
- return undefined;
563
- }
564
-
565
- return command_arguments.slice(2).join(' ').trim();
566
- }
567
-
568
- /**
569
- * @param {import('./load-patram-config.types.ts').PatramDiagnostic} diagnostic
570
- * @returns {string}
571
- */
572
- function formatDiagnostic(diagnostic) {
573
- return `${diagnostic.path}:${diagnostic.line}:${diagnostic.column} ${diagnostic.level} ${diagnostic.code} ${diagnostic.message}\n`;
574
- }
575
-
576
- /**
577
- * @param {import('./load-patram-config.types.ts').PatramRepoConfig | null} repo_config
578
- * @returns {Set<string>}
579
- */
580
- function collectDefinedDiscoveryNames(repo_config) {
581
- /** @type {Set<string>} */
582
- const defined_field_names = new Set();
583
-
584
- for (const field_name of Object.keys(repo_config?.fields ?? {})) {
585
- defined_field_names.add(field_name);
586
- }
587
-
588
- for (const relation_name of Object.keys(repo_config?.relations ?? {})) {
589
- defined_field_names.add(relation_name);
590
- }
591
-
592
- return defined_field_names;
593
- }
@@ -1,22 +0,0 @@
1
- import type {
2
- ClassSchemaConfig,
3
- MetadataFieldConfig,
4
- } from './load-patram-config.types.ts';
5
-
6
- export type ClassDefinition = import('./patram-config.js').ClassDefinition;
7
- export type RelationDefinition =
8
- import('./patram-config.js').RelationDefinition;
9
- export type MappingNodeDefinition =
10
- import('./patram-config.js').MappingNodeDefinition;
11
- export type MappingEmitDefinition =
12
- import('./patram-config.js').MappingEmitDefinition;
13
- export type MappingDefinition = import('./patram-config.js').MappingDefinition;
14
- export type PatramGraphConfig = import('./patram-config.js').PatramGraphConfig;
15
- export type PatramClassConfig = ClassDefinition & {
16
- schema?: ClassSchemaConfig;
17
- };
18
-
19
- export type PatramConfig = Omit<PatramGraphConfig, 'classes'> & {
20
- classes: Record<string, PatramClassConfig>;
21
- fields?: Record<string, MetadataFieldConfig>;
22
- };