patram 0.10.0 → 0.12.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/patram.js +4 -4
- package/lib/cli/arguments.types.d.ts +1 -0
- package/lib/cli/commands/check.js +27 -15
- package/lib/cli/commands/fields.js +0 -4
- package/lib/cli/commands/queries.js +179 -1
- 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 +106 -111
- package/lib/cli/main.js +10 -10
- package/lib/cli/parse-arguments-helpers.js +416 -66
- package/lib/cli/parse-arguments.js +4 -4
- package/lib/cli/render-help.js +10 -4
- package/lib/config/defaults.js +33 -25
- package/lib/config/load-patram-config.d.ts +19 -33
- package/lib/config/load-patram-config.js +18 -121
- package/lib/config/load-patram-config.types.d.ts +3 -40
- package/lib/config/manage-stored-queries-helpers.d.ts +69 -0
- package/lib/config/manage-stored-queries-helpers.js +320 -0
- package/lib/config/manage-stored-queries-jsonc.d.ts +31 -0
- package/lib/config/manage-stored-queries-jsonc.js +95 -0
- package/lib/config/manage-stored-queries.d.ts +77 -0
- package/lib/config/manage-stored-queries.js +300 -0
- 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.d.ts +13 -0
- package/lib/config/validate-patram-config-value.js +94 -0
- 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.d.ts +6 -0
- package/lib/graph/query/resolve.js +81 -24
- 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/resolve-check-target.js +120 -11
- 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 +9 -3
- 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 +2 -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
|
@@ -13,8 +13,16 @@
|
|
|
13
13
|
* } from '../parse-where-clause.types.ts';
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
-
import {
|
|
16
|
+
import { matchesGlob } from 'node:path';
|
|
17
|
+
|
|
18
|
+
import {
|
|
19
|
+
getGraphNodeClassName,
|
|
20
|
+
getGraphNodeId,
|
|
21
|
+
getGraphNodeMetadataValue,
|
|
22
|
+
getGraphNodePath,
|
|
23
|
+
} from '../graph-node.js';
|
|
17
24
|
import { getQuerySemanticDiagnostics } from './inspect.js';
|
|
25
|
+
import { parseQueryExpression } from './parse-query.js';
|
|
18
26
|
|
|
19
27
|
/**
|
|
20
28
|
* Query graph filtering.
|
|
@@ -22,13 +30,13 @@ import { getQuerySemanticDiagnostics } from './inspect.js';
|
|
|
22
30
|
* Applies the v0 where-clause language to graph nodes and keeps pagination
|
|
23
31
|
* separate from matching.
|
|
24
32
|
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
29
|
-
*
|
|
30
|
-
*
|
|
31
|
-
*
|
|
33
|
+
* kind: graph
|
|
34
|
+
* status: active
|
|
35
|
+
* uses_term: ../../../docs/reference/terms/graph.md
|
|
36
|
+
* uses_term: ../../../docs/reference/terms/query.md
|
|
37
|
+
* tracked_in: ../../../docs/plans/v0/source-anchor-dogfooding.md
|
|
38
|
+
* decided_by: ../../../docs/decisions/query-language.md
|
|
39
|
+
* implements: ../../../docs/tasks/v0/query-command.md
|
|
32
40
|
* @patram
|
|
33
41
|
* @see {@link ../../../docs/decisions/query-language.md}
|
|
34
42
|
* @see {@link ../load-project-graph.js}
|
|
@@ -75,7 +83,7 @@ export function queryGraph(
|
|
|
75
83
|
) {
|
|
76
84
|
const { query_options: resolved_query_options, repo_config } =
|
|
77
85
|
resolveQueryGraphOptions(repo_config_or_query_options, query_options);
|
|
78
|
-
const parse_result =
|
|
86
|
+
const parse_result = parseQueryExpression(where_clause, repo_config, {
|
|
79
87
|
bindings: resolved_query_options.bindings,
|
|
80
88
|
});
|
|
81
89
|
|
|
@@ -107,7 +115,9 @@ export function queryGraph(
|
|
|
107
115
|
nodes: graph.nodes,
|
|
108
116
|
relation_indexes: createRelationIndexes(graph.edges),
|
|
109
117
|
};
|
|
110
|
-
const graph_nodes =
|
|
118
|
+
const graph_nodes = collectCanonicalGraphNodes(graph.nodes).sort(
|
|
119
|
+
compareGraphNodes,
|
|
120
|
+
);
|
|
111
121
|
const matching_nodes = graph_nodes.filter((graph_node) =>
|
|
112
122
|
matchesExpression(graph_node, parse_result.expression, evaluation_context),
|
|
113
123
|
);
|
|
@@ -175,7 +185,7 @@ function matchesTerm(graph_node, term, evaluation_context) {
|
|
|
175
185
|
|
|
176
186
|
if (term.kind === 'relation') {
|
|
177
187
|
return hasOutgoingRelation(
|
|
178
|
-
graph_node
|
|
188
|
+
getGraphNodeId(graph_node),
|
|
179
189
|
term.relation_name,
|
|
180
190
|
evaluation_context.relation_indexes,
|
|
181
191
|
);
|
|
@@ -192,7 +202,7 @@ function matchesTerm(graph_node, term, evaluation_context) {
|
|
|
192
202
|
*/
|
|
193
203
|
function matchesAggregateTerm(graph_node, term, evaluation_context) {
|
|
194
204
|
const related_nodes = getRelatedNodes(
|
|
195
|
-
graph_node
|
|
205
|
+
getGraphNodeId(graph_node),
|
|
196
206
|
term.traversal,
|
|
197
207
|
evaluation_context,
|
|
198
208
|
);
|
|
@@ -220,6 +230,7 @@ function matchesAggregateTerm(graph_node, term, evaluation_context) {
|
|
|
220
230
|
* @param {ParsedFieldTerm} term
|
|
221
231
|
* @returns {boolean}
|
|
222
232
|
*/
|
|
233
|
+
// eslint-disable-next-line complexity
|
|
223
234
|
function matchesFieldTerm(graph_node, term) {
|
|
224
235
|
const field_values = getGraphNodeFieldValues(graph_node, term.field_name);
|
|
225
236
|
|
|
@@ -227,7 +238,7 @@ function matchesFieldTerm(graph_node, term) {
|
|
|
227
238
|
return field_values.some((field_value) => field_value === term.value);
|
|
228
239
|
}
|
|
229
240
|
|
|
230
|
-
if (term.operator === '
|
|
241
|
+
if (term.operator === '<>') {
|
|
231
242
|
return field_values.every((field_value) => field_value !== term.value);
|
|
232
243
|
}
|
|
233
244
|
|
|
@@ -237,6 +248,16 @@ function matchesFieldTerm(graph_node, term) {
|
|
|
237
248
|
);
|
|
238
249
|
}
|
|
239
250
|
|
|
251
|
+
if (term.operator === '$=') {
|
|
252
|
+
return field_values.some((field_value) => field_value.endsWith(term.value));
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (term.operator === '*=') {
|
|
256
|
+
return field_values.some((field_value) =>
|
|
257
|
+
matchesGlob(field_value, term.value),
|
|
258
|
+
);
|
|
259
|
+
}
|
|
260
|
+
|
|
240
261
|
if (term.operator === '~') {
|
|
241
262
|
const term_value = term.value.toLocaleLowerCase('en');
|
|
242
263
|
|
|
@@ -290,7 +311,7 @@ function matchesFieldSetTerm(graph_node, term) {
|
|
|
290
311
|
*/
|
|
291
312
|
function matchesRelationTargetTerm(graph_node, term, evaluation_context) {
|
|
292
313
|
const relation_targets = evaluation_context.relation_indexes.outgoing.get(
|
|
293
|
-
graph_node
|
|
314
|
+
getGraphNodeId(graph_node),
|
|
294
315
|
);
|
|
295
316
|
const matching_targets = relation_targets?.get(term.relation_name);
|
|
296
317
|
|
|
@@ -334,14 +355,35 @@ function getRelatedNodes(node_id, traversal, evaluation_context) {
|
|
|
334
355
|
});
|
|
335
356
|
}
|
|
336
357
|
|
|
358
|
+
/**
|
|
359
|
+
* @param {BuildGraphResult['nodes']} graph_nodes
|
|
360
|
+
* @returns {GraphNode[]}
|
|
361
|
+
*/
|
|
362
|
+
function collectCanonicalGraphNodes(graph_nodes) {
|
|
363
|
+
/** @type {Map<string, GraphNode>} */
|
|
364
|
+
const canonical_nodes = new Map();
|
|
365
|
+
|
|
366
|
+
for (const graph_node of Object.values(graph_nodes)) {
|
|
367
|
+
const graph_node_id = getGraphNodeId(graph_node);
|
|
368
|
+
|
|
369
|
+
if (!graph_node_id) {
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
canonical_nodes.set(graph_node_id, graph_node);
|
|
374
|
+
}
|
|
375
|
+
|
|
376
|
+
return [...canonical_nodes.values()];
|
|
377
|
+
}
|
|
378
|
+
|
|
337
379
|
/**
|
|
338
380
|
* @param {number} left_value
|
|
339
|
-
* @param {'
|
|
381
|
+
* @param {'<' | '<=' | '<>' | '=' | '>' | '>='} comparison
|
|
340
382
|
* @param {number} right_value
|
|
341
383
|
* @returns {boolean}
|
|
342
384
|
*/
|
|
343
385
|
function compareNumbers(left_value, comparison, right_value) {
|
|
344
|
-
if (comparison === '
|
|
386
|
+
if (comparison === '<>') {
|
|
345
387
|
return left_value !== right_value;
|
|
346
388
|
}
|
|
347
389
|
|
|
@@ -418,8 +460,8 @@ function createDirectionalRelationIndex(graph_edges, source_key, target_key) {
|
|
|
418
460
|
* @returns {number}
|
|
419
461
|
*/
|
|
420
462
|
function compareGraphNodes(left_node, right_node) {
|
|
421
|
-
return (left_node
|
|
422
|
-
right_node
|
|
463
|
+
return getGraphNodeId(left_node).localeCompare(
|
|
464
|
+
getGraphNodeId(right_node),
|
|
423
465
|
'en',
|
|
424
466
|
);
|
|
425
467
|
}
|
|
@@ -452,7 +494,9 @@ function getGraphNodeFieldValues(graph_node, field_name) {
|
|
|
452
494
|
return [];
|
|
453
495
|
}
|
|
454
496
|
|
|
455
|
-
return normalizeFieldValues(
|
|
497
|
+
return normalizeFieldValues(
|
|
498
|
+
getGraphNodeMetadataValue(graph_node, field_name),
|
|
499
|
+
);
|
|
456
500
|
}
|
|
457
501
|
|
|
458
502
|
/**
|
|
@@ -461,21 +505,15 @@ function getGraphNodeFieldValues(graph_node, field_name) {
|
|
|
461
505
|
* @returns {string | undefined}
|
|
462
506
|
*/
|
|
463
507
|
function getStructuralFieldValue(graph_node, field_name) {
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
}
|
|
508
|
+
const node_path = getGraphNodePath(graph_node);
|
|
509
|
+
const node_title = getGraphNodeMetadataValue(graph_node, 'title');
|
|
467
510
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
}
|
|
475
|
-
|
|
476
|
-
if (field_name === 'title') {
|
|
477
|
-
return graph_node.title;
|
|
478
|
-
}
|
|
511
|
+
return {
|
|
512
|
+
$class: getGraphNodeClassName(graph_node),
|
|
513
|
+
$id: getGraphNodeId(graph_node),
|
|
514
|
+
$path: node_path,
|
|
515
|
+
title: Array.isArray(node_title) ? node_title[0] : node_title,
|
|
516
|
+
}[field_name];
|
|
479
517
|
}
|
|
480
518
|
|
|
481
519
|
/**
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/* eslint-disable max-lines */
|
|
2
2
|
/**
|
|
3
|
-
* @import { PatramDiagnostic, PatramRepoConfig } from '../../config/load-patram-config.types.ts';
|
|
3
|
+
* @import { MetadataFieldConfig, PatramDiagnostic, PatramRepoConfig } from '../../config/load-patram-config.types.ts';
|
|
4
4
|
* @import {
|
|
5
5
|
* ParsedExpression,
|
|
6
6
|
* ParsedRelationTargetTerm,
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
|
|
13
13
|
import { Ansis } from 'ansis';
|
|
14
14
|
|
|
15
|
-
import {
|
|
15
|
+
import { parseQueryExpression } from './parse-query.js';
|
|
16
16
|
|
|
17
17
|
/**
|
|
18
18
|
* @typedef {{ kind: 'ad_hoc' } | { kind: 'stored_query', name: string }} QuerySource
|
|
@@ -56,7 +56,10 @@ export function inspectQuery(
|
|
|
56
56
|
resolved_where_clause,
|
|
57
57
|
inspection_options,
|
|
58
58
|
) {
|
|
59
|
-
const parse_result =
|
|
59
|
+
const parse_result = parseQueryExpression(
|
|
60
|
+
resolved_where_clause.where_clause,
|
|
61
|
+
repo_config,
|
|
62
|
+
);
|
|
60
63
|
|
|
61
64
|
if (!parse_result.success) {
|
|
62
65
|
return {
|
|
@@ -153,23 +156,57 @@ export function getQuerySemanticDiagnostics(
|
|
|
153
156
|
query_source,
|
|
154
157
|
expression,
|
|
155
158
|
) {
|
|
156
|
-
const known_relation_names = new Set(
|
|
157
|
-
Object.keys(repo_config.relations ?? {}),
|
|
158
|
-
);
|
|
159
|
+
const known_relation_names = new Set(['links_to']);
|
|
159
160
|
/** @type {PatramDiagnostic[]} */
|
|
160
161
|
const diagnostics = [];
|
|
161
162
|
|
|
163
|
+
for (const [field_name, field_definition] of Object.entries(
|
|
164
|
+
repo_config.fields ?? {},
|
|
165
|
+
)) {
|
|
166
|
+
if (field_definition.type === 'ref') {
|
|
167
|
+
known_relation_names.add(field_name);
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
162
171
|
collectExpressionDiagnostics(
|
|
163
172
|
expression,
|
|
164
173
|
diagnostics,
|
|
165
174
|
known_relation_names,
|
|
166
|
-
repo_config
|
|
175
|
+
createKnownFieldDefinitions(repo_config),
|
|
167
176
|
formatQueryDiagnosticPath(query_source),
|
|
168
177
|
);
|
|
169
178
|
|
|
170
179
|
return diagnostics;
|
|
171
180
|
}
|
|
172
181
|
|
|
182
|
+
/**
|
|
183
|
+
* @param {PatramRepoConfig} repo_config
|
|
184
|
+
* @returns {Record<string, MetadataFieldConfig | {type: 'string'}>}
|
|
185
|
+
*/
|
|
186
|
+
function createKnownFieldDefinitions(repo_config) {
|
|
187
|
+
/** @type {Record<string, MetadataFieldConfig | {type: 'string'}>} */
|
|
188
|
+
const known_field_definitions = {
|
|
189
|
+
description: {
|
|
190
|
+
type: 'string',
|
|
191
|
+
},
|
|
192
|
+
title: {
|
|
193
|
+
type: 'string',
|
|
194
|
+
},
|
|
195
|
+
};
|
|
196
|
+
|
|
197
|
+
for (const [field_name, field_definition] of Object.entries(
|
|
198
|
+
repo_config.fields ?? {},
|
|
199
|
+
)) {
|
|
200
|
+
if (field_definition.type === 'ref') {
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
known_field_definitions[field_name] = field_definition;
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
return known_field_definitions;
|
|
208
|
+
}
|
|
209
|
+
|
|
173
210
|
/**
|
|
174
211
|
* @param {ParsedExpression} expression
|
|
175
212
|
* @param {PatramDiagnostic[]} diagnostics
|
|
@@ -384,7 +421,7 @@ function getFieldDiagnosticsCollector(field_name) {
|
|
|
384
421
|
*/
|
|
385
422
|
function collectTitleFieldDiagnostics(term, diagnostics, diagnostic_path) {
|
|
386
423
|
const operator = term.kind === 'field' ? term.operator : term.operator;
|
|
387
|
-
const allowed = new Set(['=', '
|
|
424
|
+
const allowed = new Set(['=', '<>', 'in', 'not in', '~']);
|
|
388
425
|
|
|
389
426
|
if (allowed.has(operator)) {
|
|
390
427
|
return;
|
|
@@ -408,9 +445,9 @@ function collectTitleFieldDiagnostics(term, diagnostics, diagnostic_path) {
|
|
|
408
445
|
function collectStructuralFieldDiagnostics(term, diagnostics, diagnostic_path) {
|
|
409
446
|
const operator = term.kind === 'field' ? term.operator : term.operator;
|
|
410
447
|
const allowed_by_field = new Map([
|
|
411
|
-
['$class', new Set(['=', '
|
|
412
|
-
['$id', new Set(['=', '
|
|
413
|
-
['$path', new Set(['=', '
|
|
448
|
+
['$class', new Set(['=', '<>', 'in', 'not in'])],
|
|
449
|
+
['$id', new Set(['=', '<>', 'in', 'not in', '^='])],
|
|
450
|
+
['$path', new Set(['$=', '=', '<>', 'in', 'not in', '*=', '^='])],
|
|
414
451
|
]);
|
|
415
452
|
const allowed = allowed_by_field.get(term.field_name);
|
|
416
453
|
|
|
@@ -457,7 +494,7 @@ function getMetadataFieldOperatorDiagnostic(
|
|
|
457
494
|
* @returns {boolean}
|
|
458
495
|
*/
|
|
459
496
|
function supportsMetadataFieldOperator(operator, field_definition) {
|
|
460
|
-
if (operator === '=' || operator === '
|
|
497
|
+
if (operator === '=' || operator === '<>') {
|
|
461
498
|
return true;
|
|
462
499
|
}
|
|
463
500
|
|
|
@@ -465,6 +502,10 @@ function supportsMetadataFieldOperator(operator, field_definition) {
|
|
|
465
502
|
return supportsPrefixOperator(field_definition);
|
|
466
503
|
}
|
|
467
504
|
|
|
505
|
+
if (operator === '*=') {
|
|
506
|
+
return false;
|
|
507
|
+
}
|
|
508
|
+
|
|
468
509
|
if (operator === '~') {
|
|
469
510
|
return supportsContainsOperator(field_definition);
|
|
470
511
|
}
|
|
@@ -477,14 +518,7 @@ function supportsMetadataFieldOperator(operator, field_definition) {
|
|
|
477
518
|
* @returns {boolean}
|
|
478
519
|
*/
|
|
479
520
|
function supportsPrefixOperator(field_definition) {
|
|
480
|
-
|
|
481
|
-
return true;
|
|
482
|
-
}
|
|
483
|
-
|
|
484
|
-
return (
|
|
485
|
-
field_definition.type === 'string' &&
|
|
486
|
-
field_definition.query?.prefix === true
|
|
487
|
-
);
|
|
521
|
+
return field_definition.type === 'path' || field_definition.type === 'string';
|
|
488
522
|
}
|
|
489
523
|
|
|
490
524
|
/**
|
|
@@ -492,10 +526,7 @@ function supportsPrefixOperator(field_definition) {
|
|
|
492
526
|
* @returns {boolean}
|
|
493
527
|
*/
|
|
494
528
|
function supportsContainsOperator(field_definition) {
|
|
495
|
-
return
|
|
496
|
-
field_definition.type === 'string' &&
|
|
497
|
-
field_definition.query?.contains === true
|
|
498
|
-
);
|
|
529
|
+
return field_definition.type === 'string' || field_definition.type === 'path';
|
|
499
530
|
}
|
|
500
531
|
|
|
501
532
|
/**
|
|
@@ -732,6 +763,7 @@ function formatExpressionSummary(expression) {
|
|
|
732
763
|
return formatTermSummary(expression.term);
|
|
733
764
|
}
|
|
734
765
|
|
|
766
|
+
/* istanbul ignore next -- defensive unreachable */
|
|
735
767
|
throw new Error('Unsupported explain expression.');
|
|
736
768
|
}
|
|
737
769
|
|
|
@@ -763,6 +795,7 @@ function formatExpressionDetailLines(expression, render_options, indentation) {
|
|
|
763
795
|
}
|
|
764
796
|
|
|
765
797
|
if (expression.kind !== 'term') {
|
|
798
|
+
/* istanbul ignore next -- defensive unreachable */
|
|
766
799
|
throw new Error('Unsupported explain expression details.');
|
|
767
800
|
}
|
|
768
801
|
|
|
@@ -818,6 +851,7 @@ function formatTermSummary(term) {
|
|
|
818
851
|
return `${term.relation_name} = ${term.target_id}`;
|
|
819
852
|
}
|
|
820
853
|
|
|
854
|
+
/* istanbul ignore next -- defensive unreachable */
|
|
821
855
|
throw new Error('Expected a parsed query term.');
|
|
822
856
|
}
|
|
823
857
|
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {CypherParserState} parser_state
|
|
3
|
+
* @param {number} column
|
|
4
|
+
* @param {'any' | 'count'} aggregate_name
|
|
5
|
+
* @param {(parser_state: CypherParserState) => CypherExpressionResult} parse_boolean_expression
|
|
6
|
+
* @returns {CypherAggregateResult}
|
|
7
|
+
*/
|
|
8
|
+
export function parseSubqueryAggregate(parser_state: CypherParserState, column: number, aggregate_name: "any" | "count", parse_boolean_expression: (parser_state: CypherParserState) => CypherExpressionResult): CypherAggregateResult;
|
|
9
|
+
/**
|
|
10
|
+
* @param {CypherParserState} parser_state
|
|
11
|
+
* @returns {CypherNodePattern}
|
|
12
|
+
*/
|
|
13
|
+
export function parseNodePattern(parser_state: CypherParserState): CypherNodePattern;
|
|
14
|
+
/**
|
|
15
|
+
* @param {CypherParserState} parser_state
|
|
16
|
+
* @returns {string}
|
|
17
|
+
*/
|
|
18
|
+
export function parseCypherScalarValue(parser_state: CypherParserState): string;
|
|
19
|
+
/**
|
|
20
|
+
* @param {CypherParserState} parser_state
|
|
21
|
+
* @returns {string[]}
|
|
22
|
+
*/
|
|
23
|
+
export function parseCypherListValue(parser_state: CypherParserState): string[];
|
|
24
|
+
import type { CypherParserState } from './cypher.types.d.ts';
|
|
25
|
+
import type { CypherExpressionResult } from './cypher.types.d.ts';
|
|
26
|
+
import type { CypherAggregateResult } from './cypher.types.d.ts';
|
|
27
|
+
import type { CypherNodePattern } from './cypher.types.d.ts';
|