patram 0.3.0 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/build-graph-identity.js +70 -84
- package/lib/build-graph.js +171 -19
- package/lib/build-graph.types.ts +1 -0
- package/lib/check-directive-metadata.js +36 -4
- package/lib/check-directive-value.js +9 -0
- package/lib/check-graph.js +1 -2
- package/lib/cli-help-metadata.js +12 -0
- package/lib/command-output.js +16 -1
- package/lib/discover-fields.js +9 -1
- package/lib/document-node-identity.js +317 -0
- package/lib/layout-stored-queries.js +122 -29
- package/lib/load-patram-config.js +172 -112
- package/lib/load-patram-config.types.ts +50 -152
- package/lib/parse-claims.js +2 -3
- package/lib/parse-jsdoc-claims.js +3 -3
- package/lib/parse-where-clause.js +237 -66
- package/lib/parse-where-clause.types.ts +21 -6
- package/lib/patram-cli.js +34 -2
- package/lib/patram-config.js +26 -9
- package/lib/patram-config.types.ts +18 -36
- package/lib/query-graph.js +29 -19
- package/lib/query-inspection.js +173 -68
- package/lib/render-field-discovery.js +44 -8
- package/lib/render-output-view.js +72 -27
- package/lib/render-rich-source.js +245 -14
- package/lib/resolve-patram-graph-config.js +40 -2
- package/lib/show-document.js +15 -2
- package/package.json +1 -1
|
@@ -1,12 +1,8 @@
|
|
|
1
|
+
/** @import * as $k$$l$patram$j$config$k$js from './patram-config.js'; */
|
|
1
2
|
/* eslint-disable max-lines */
|
|
3
|
+
|
|
2
4
|
/**
|
|
3
|
-
* @import {
|
|
4
|
-
* ClassSchemaConfig,
|
|
5
|
-
* LoadPatramConfigResult,
|
|
6
|
-
* MetadataFieldConfig,
|
|
7
|
-
* PatramDiagnostic,
|
|
8
|
-
* PatramRepoConfig,
|
|
9
|
-
* } from './load-patram-config.types.ts';
|
|
5
|
+
* @import { ClassDefinition } from './patram-config.js';
|
|
10
6
|
*/
|
|
11
7
|
|
|
12
8
|
import { readFile } from 'node:fs/promises';
|
|
@@ -15,7 +11,12 @@ import process from 'node:process';
|
|
|
15
11
|
|
|
16
12
|
import { z } from 'zod';
|
|
17
13
|
|
|
18
|
-
import {
|
|
14
|
+
import {
|
|
15
|
+
class_definition_schema,
|
|
16
|
+
mapping_definition_schema,
|
|
17
|
+
parsePatramConfig,
|
|
18
|
+
relation_definition_schema,
|
|
19
|
+
} from './patram-config.js';
|
|
19
20
|
import { parseWhereClause } from './parse-where-clause.js';
|
|
20
21
|
import { getQuerySemanticDiagnostics } from './query-inspection.js';
|
|
21
22
|
import { resolvePatramGraphConfig } from './resolve-patram-graph-config.js';
|
|
@@ -40,12 +41,28 @@ import { DEFAULT_INCLUDE_PATTERNS } from './source-file-defaults.js';
|
|
|
40
41
|
const CONFIG_FILE_NAME = '.patram.json';
|
|
41
42
|
const RESERVED_STRUCTURAL_FIELD_NAMES = new Set(['$class', '$id', '$path']);
|
|
42
43
|
|
|
44
|
+
/**
|
|
45
|
+
* @typedef {object} PatramDiagnostic
|
|
46
|
+
* @property {string} code
|
|
47
|
+
* @property {number} column
|
|
48
|
+
* @property {'error'} level
|
|
49
|
+
* @property {number} line
|
|
50
|
+
* @property {string} message
|
|
51
|
+
* @property {string} path
|
|
52
|
+
*/
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* @typedef {z.output<typeof stored_query_schema>} StoredQueryConfig
|
|
56
|
+
*/
|
|
43
57
|
const stored_query_schema = z
|
|
44
58
|
.object({
|
|
45
59
|
where: z.string().min(1, 'Stored query "where" must not be empty.'),
|
|
46
60
|
})
|
|
47
61
|
.strict();
|
|
48
62
|
|
|
63
|
+
/**
|
|
64
|
+
* @typedef {z.output<typeof derived_summary_scalar_schema>} DerivedSummaryScalar
|
|
65
|
+
*/
|
|
49
66
|
const derived_summary_scalar_schema = z.union([
|
|
50
67
|
z.boolean(),
|
|
51
68
|
z.number(),
|
|
@@ -53,6 +70,9 @@ const derived_summary_scalar_schema = z.union([
|
|
|
53
70
|
z.null(),
|
|
54
71
|
]);
|
|
55
72
|
|
|
73
|
+
/**
|
|
74
|
+
* @typedef {z.output<typeof derived_summary_count_schema>} DerivedSummaryCountConfig
|
|
75
|
+
*/
|
|
56
76
|
const derived_summary_count_schema = z
|
|
57
77
|
.object({
|
|
58
78
|
traversal: z
|
|
@@ -64,6 +84,9 @@ const derived_summary_count_schema = z
|
|
|
64
84
|
})
|
|
65
85
|
.strict();
|
|
66
86
|
|
|
87
|
+
/**
|
|
88
|
+
* @typedef {z.output<typeof derived_summary_select_case_schema>} DerivedSummarySelectCaseConfig
|
|
89
|
+
*/
|
|
67
90
|
const derived_summary_select_case_schema = z
|
|
68
91
|
.object({
|
|
69
92
|
value: derived_summary_scalar_schema,
|
|
@@ -71,21 +94,41 @@ const derived_summary_select_case_schema = z
|
|
|
71
94
|
})
|
|
72
95
|
.strict();
|
|
73
96
|
|
|
74
|
-
const
|
|
97
|
+
const derived_summary_field_name_schema = z
|
|
98
|
+
.string()
|
|
99
|
+
.regex(
|
|
100
|
+
/^[a-z][a-z0-9_]*$/du,
|
|
101
|
+
'Derived summary field names must use lower_snake_case.',
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
/**
|
|
105
|
+
* @typedef {z.output<typeof derived_summary_field_schema>} DerivedSummaryFieldConfig
|
|
106
|
+
*/
|
|
107
|
+
const derived_summary_count_field_schema = z
|
|
75
108
|
.object({
|
|
76
|
-
count: derived_summary_count_schema
|
|
77
|
-
|
|
78
|
-
name: z
|
|
79
|
-
.string()
|
|
80
|
-
.regex(
|
|
81
|
-
/^[a-z][a-z0-9_]*$/du,
|
|
82
|
-
'Derived summary field names must use lower_snake_case.',
|
|
83
|
-
),
|
|
84
|
-
select: z.array(derived_summary_select_case_schema).optional(),
|
|
109
|
+
count: derived_summary_count_schema,
|
|
110
|
+
name: derived_summary_field_name_schema,
|
|
85
111
|
})
|
|
86
|
-
.strict()
|
|
87
|
-
|
|
112
|
+
.strict();
|
|
113
|
+
|
|
114
|
+
const derived_summary_select_field_schema = z
|
|
115
|
+
.object({
|
|
116
|
+
default: derived_summary_scalar_schema,
|
|
117
|
+
name: derived_summary_field_name_schema,
|
|
118
|
+
select: z
|
|
119
|
+
.array(derived_summary_select_case_schema)
|
|
120
|
+
.min(1, 'Derived summary "select" must contain at least one case.'),
|
|
121
|
+
})
|
|
122
|
+
.strict();
|
|
123
|
+
|
|
124
|
+
const derived_summary_field_schema = z.union([
|
|
125
|
+
derived_summary_count_field_schema,
|
|
126
|
+
derived_summary_select_field_schema,
|
|
127
|
+
]);
|
|
88
128
|
|
|
129
|
+
/**
|
|
130
|
+
* @typedef {z.output<typeof derived_summary_schema>} DerivedSummaryConfig
|
|
131
|
+
*/
|
|
89
132
|
const derived_summary_schema = z
|
|
90
133
|
.object({
|
|
91
134
|
classes: z
|
|
@@ -98,6 +141,9 @@ const derived_summary_schema = z
|
|
|
98
141
|
.strict()
|
|
99
142
|
.superRefine(validateDerivedSummaryDefinition);
|
|
100
143
|
|
|
144
|
+
/**
|
|
145
|
+
* @typedef {z.output<typeof field_display_schema>} FieldDisplayConfig
|
|
146
|
+
*/
|
|
101
147
|
const field_display_schema = z
|
|
102
148
|
.object({
|
|
103
149
|
hidden: z.boolean().optional(),
|
|
@@ -105,6 +151,9 @@ const field_display_schema = z
|
|
|
105
151
|
})
|
|
106
152
|
.strict();
|
|
107
153
|
|
|
154
|
+
/**
|
|
155
|
+
* @typedef {z.output<typeof field_query_schema>} FieldQueryConfig
|
|
156
|
+
*/
|
|
108
157
|
const field_query_schema = z
|
|
109
158
|
.object({
|
|
110
159
|
contains: z.boolean().optional(),
|
|
@@ -118,6 +167,9 @@ const field_base_shape = {
|
|
|
118
167
|
path_class: z.string().min(1).optional(),
|
|
119
168
|
};
|
|
120
169
|
|
|
170
|
+
/**
|
|
171
|
+
* @typedef {z.output<typeof metadata_field_schema>} MetadataFieldConfig
|
|
172
|
+
*/
|
|
121
173
|
const metadata_field_schema = z.discriminatedUnion('type', [
|
|
122
174
|
z
|
|
123
175
|
.object({
|
|
@@ -167,12 +219,18 @@ const metadata_field_schema = z.discriminatedUnion('type', [
|
|
|
167
219
|
.strict(),
|
|
168
220
|
]);
|
|
169
221
|
|
|
222
|
+
/**
|
|
223
|
+
* @typedef {z.output<typeof class_field_rule_schema>} ClassFieldRuleConfig
|
|
224
|
+
*/
|
|
170
225
|
const class_field_rule_schema = z
|
|
171
226
|
.object({
|
|
172
227
|
presence: z.enum(['required', 'optional', 'forbidden']),
|
|
173
228
|
})
|
|
174
229
|
.strict();
|
|
175
230
|
|
|
231
|
+
/**
|
|
232
|
+
* @typedef {z.output<typeof class_schema_schema>} ClassSchemaConfig
|
|
233
|
+
*/
|
|
176
234
|
const class_schema_schema = z
|
|
177
235
|
.object({
|
|
178
236
|
document_path_class: z.string().min(1).optional(),
|
|
@@ -181,6 +239,16 @@ const class_schema_schema = z
|
|
|
181
239
|
})
|
|
182
240
|
.strict();
|
|
183
241
|
|
|
242
|
+
/**
|
|
243
|
+
* @typedef {z.output<typeof repo_class_definition_schema>} RepoClassConfig
|
|
244
|
+
*/
|
|
245
|
+
const repo_class_definition_schema = class_definition_schema.extend({
|
|
246
|
+
schema: class_schema_schema.optional(),
|
|
247
|
+
});
|
|
248
|
+
|
|
249
|
+
/**
|
|
250
|
+
* @typedef {z.output<typeof path_class_schema>} PathClassConfig
|
|
251
|
+
*/
|
|
184
252
|
const path_class_schema = z
|
|
185
253
|
.object({
|
|
186
254
|
prefixes: z
|
|
@@ -189,10 +257,14 @@ const path_class_schema = z
|
|
|
189
257
|
})
|
|
190
258
|
.strict();
|
|
191
259
|
|
|
260
|
+
/**
|
|
261
|
+
* @typedef {z.output<typeof patram_repo_config_schema>} PatramRepoConfig
|
|
262
|
+
*/
|
|
192
263
|
const patram_repo_config_schema = z
|
|
193
264
|
.object({
|
|
194
|
-
|
|
195
|
-
|
|
265
|
+
classes: z
|
|
266
|
+
.record(z.string().min(1), repo_class_definition_schema)
|
|
267
|
+
.optional(),
|
|
196
268
|
derived_summaries: z
|
|
197
269
|
.record(z.string().min(1), derived_summary_schema)
|
|
198
270
|
.optional(),
|
|
@@ -201,14 +273,23 @@ const patram_repo_config_schema = z
|
|
|
201
273
|
.array(z.string().min(1, 'Include globs must not be empty.'))
|
|
202
274
|
.min(1, 'Include must contain at least one glob.')
|
|
203
275
|
.default(DEFAULT_INCLUDE_PATTERNS),
|
|
204
|
-
mappings: z.
|
|
276
|
+
mappings: z.record(z.string().min(1), mapping_definition_schema).optional(),
|
|
205
277
|
path_classes: z.record(z.string().min(1), path_class_schema).optional(),
|
|
206
278
|
queries: z.record(z.string().min(1), stored_query_schema).default({}),
|
|
207
|
-
relations: z
|
|
279
|
+
relations: z
|
|
280
|
+
.record(z.string().min(1), relation_definition_schema)
|
|
281
|
+
.optional(),
|
|
208
282
|
})
|
|
209
283
|
.strict()
|
|
210
284
|
.superRefine(validateFieldDefinitionKeys);
|
|
211
285
|
|
|
286
|
+
/**
|
|
287
|
+
* @typedef {object} LoadPatramConfigResult
|
|
288
|
+
* @property {PatramRepoConfig | null} config
|
|
289
|
+
* @property {string} config_path
|
|
290
|
+
* @property {PatramDiagnostic[]} diagnostics
|
|
291
|
+
*/
|
|
292
|
+
|
|
212
293
|
/**
|
|
213
294
|
* Load and validate the repo Patram config.
|
|
214
295
|
*
|
|
@@ -229,6 +310,14 @@ export async function loadPatramConfig(project_directory = process.cwd()) {
|
|
|
229
310
|
return createLoadResult(null, [parse_result.diagnostic]);
|
|
230
311
|
}
|
|
231
312
|
|
|
313
|
+
const legacy_config_diagnostics = validateLegacyConfigShape(
|
|
314
|
+
parse_result.value,
|
|
315
|
+
);
|
|
316
|
+
|
|
317
|
+
if (legacy_config_diagnostics.length > 0) {
|
|
318
|
+
return createLoadResult(null, legacy_config_diagnostics);
|
|
319
|
+
}
|
|
320
|
+
|
|
232
321
|
const config_result = patram_repo_config_schema.safeParse(parse_result.value);
|
|
233
322
|
|
|
234
323
|
if (!config_result.success) {
|
|
@@ -382,61 +471,6 @@ function validateFieldDefinitionKeys(repo_config, refinement_context) {
|
|
|
382
471
|
}
|
|
383
472
|
}
|
|
384
473
|
|
|
385
|
-
/**
|
|
386
|
-
* @param {{ count?: unknown, default?: unknown, select?: unknown }} field_definition
|
|
387
|
-
* @param {import('zod').RefinementCtx} refinement_context
|
|
388
|
-
*/
|
|
389
|
-
function validateDerivedSummaryFieldDefinition(
|
|
390
|
-
field_definition,
|
|
391
|
-
refinement_context,
|
|
392
|
-
) {
|
|
393
|
-
const evaluator_count =
|
|
394
|
-
Number(field_definition.count !== undefined) +
|
|
395
|
-
Number(field_definition.select !== undefined);
|
|
396
|
-
|
|
397
|
-
if (evaluator_count !== 1) {
|
|
398
|
-
refinement_context.addIssue({
|
|
399
|
-
code: 'custom',
|
|
400
|
-
message:
|
|
401
|
-
'Derived summary fields must define exactly one of "count" or "select".',
|
|
402
|
-
});
|
|
403
|
-
}
|
|
404
|
-
|
|
405
|
-
if (
|
|
406
|
-
field_definition.count !== undefined &&
|
|
407
|
-
field_definition.default !== undefined
|
|
408
|
-
) {
|
|
409
|
-
refinement_context.addIssue({
|
|
410
|
-
code: 'custom',
|
|
411
|
-
message: 'Derived summary count fields must not define "default".',
|
|
412
|
-
path: ['default'],
|
|
413
|
-
});
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
if (field_definition.select === undefined) {
|
|
417
|
-
return;
|
|
418
|
-
}
|
|
419
|
-
|
|
420
|
-
if (
|
|
421
|
-
Array.isArray(field_definition.select) &&
|
|
422
|
-
field_definition.select.length === 0
|
|
423
|
-
) {
|
|
424
|
-
refinement_context.addIssue({
|
|
425
|
-
code: 'custom',
|
|
426
|
-
message: 'Derived summary "select" must contain at least one case.',
|
|
427
|
-
path: ['select'],
|
|
428
|
-
});
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
if (field_definition.default === undefined) {
|
|
432
|
-
refinement_context.addIssue({
|
|
433
|
-
code: 'custom',
|
|
434
|
-
message: 'Derived summary select fields must define "default".',
|
|
435
|
-
path: ['default'],
|
|
436
|
-
});
|
|
437
|
-
}
|
|
438
|
-
}
|
|
439
|
-
|
|
440
474
|
/**
|
|
441
475
|
* @param {{ fields: Array<{ name: string }> }} summary_definition
|
|
442
476
|
* @param {import('zod').RefinementCtx} refinement_context
|
|
@@ -465,7 +499,7 @@ function validateDerivedSummaryDefinition(
|
|
|
465
499
|
}
|
|
466
500
|
|
|
467
501
|
/**
|
|
468
|
-
* @param {
|
|
502
|
+
* @param {PatramRepoConfig} repo_config
|
|
469
503
|
* @returns {PatramDiagnostic[]}
|
|
470
504
|
*/
|
|
471
505
|
function validateGraphSchema(repo_config) {
|
|
@@ -479,7 +513,7 @@ function validateGraphSchema(repo_config) {
|
|
|
479
513
|
|
|
480
514
|
try {
|
|
481
515
|
parsePatramConfig({
|
|
482
|
-
classes: repo_config.classes
|
|
516
|
+
classes: collectGraphClassDefinitions(repo_config.classes),
|
|
483
517
|
mappings: repo_config.mappings ?? {},
|
|
484
518
|
relations: repo_config.relations ?? {},
|
|
485
519
|
});
|
|
@@ -509,9 +543,8 @@ function validateFieldSchemaConfig(repo_config) {
|
|
|
509
543
|
collectClassSchemaConfigDiagnostics(
|
|
510
544
|
diagnostics,
|
|
511
545
|
path_classes,
|
|
512
|
-
classes,
|
|
513
546
|
fields,
|
|
514
|
-
|
|
547
|
+
classes,
|
|
515
548
|
);
|
|
516
549
|
|
|
517
550
|
return diagnostics;
|
|
@@ -586,7 +619,7 @@ function createDefaultRepoConfig() {
|
|
|
586
619
|
}
|
|
587
620
|
|
|
588
621
|
/**
|
|
589
|
-
* @param {
|
|
622
|
+
* @param {PatramRepoConfig} repo_config
|
|
590
623
|
* @returns {PatramRepoConfig}
|
|
591
624
|
*/
|
|
592
625
|
function normalizeRepoConfig(repo_config) {
|
|
@@ -596,11 +629,6 @@ function normalizeRepoConfig(repo_config) {
|
|
|
596
629
|
queries: { ...repo_config.queries },
|
|
597
630
|
};
|
|
598
631
|
|
|
599
|
-
assignOptionalRepoConfigField(
|
|
600
|
-
normalized_config,
|
|
601
|
-
'class_schemas',
|
|
602
|
-
repo_config.class_schemas,
|
|
603
|
-
);
|
|
604
632
|
assignOptionalRepoConfigField(
|
|
605
633
|
normalized_config,
|
|
606
634
|
'classes',
|
|
@@ -635,6 +663,27 @@ function normalizeRepoConfig(repo_config) {
|
|
|
635
663
|
return normalized_config;
|
|
636
664
|
}
|
|
637
665
|
|
|
666
|
+
/**
|
|
667
|
+
* @param {unknown} config_value
|
|
668
|
+
* @returns {PatramDiagnostic[]}
|
|
669
|
+
*/
|
|
670
|
+
function validateLegacyConfigShape(config_value) {
|
|
671
|
+
if (
|
|
672
|
+
config_value === null ||
|
|
673
|
+
typeof config_value !== 'object' ||
|
|
674
|
+
!Object.hasOwn(config_value, 'class_schemas')
|
|
675
|
+
) {
|
|
676
|
+
return [];
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
return [
|
|
680
|
+
createConfigDiagnostic(
|
|
681
|
+
'class_schemas',
|
|
682
|
+
'Top-level "class_schemas" is not supported. Move entries into classes.<name>.schema.',
|
|
683
|
+
),
|
|
684
|
+
];
|
|
685
|
+
}
|
|
686
|
+
|
|
638
687
|
/**
|
|
639
688
|
* @param {PatramDiagnostic[]} diagnostics
|
|
640
689
|
* @param {Map<string, string>} class_coverage
|
|
@@ -669,7 +718,7 @@ function collectDuplicateClassDiagnostics(
|
|
|
669
718
|
* @param {Set<string>} known_relation_names
|
|
670
719
|
* @param {PatramRepoConfig} repo_config
|
|
671
720
|
* @param {string} summary_name
|
|
672
|
-
* @param {
|
|
721
|
+
* @param {DerivedSummaryFieldConfig[]} field_definitions
|
|
673
722
|
*/
|
|
674
723
|
function collectDerivedSummaryFieldDiagnostics(
|
|
675
724
|
diagnostics,
|
|
@@ -861,35 +910,22 @@ function collectFieldPathClassDiagnostic(
|
|
|
861
910
|
/**
|
|
862
911
|
* @param {PatramDiagnostic[]} diagnostics
|
|
863
912
|
* @param {Record<string, { prefixes: string[] }>} path_classes
|
|
864
|
-
* @param {Record<string, unknown>} classes
|
|
865
913
|
* @param {Record<string, MetadataFieldConfig>} fields
|
|
866
|
-
* @param {PatramRepoConfig['
|
|
914
|
+
* @param {NonNullable<PatramRepoConfig['classes']>} classes
|
|
867
915
|
*/
|
|
868
916
|
function collectClassSchemaConfigDiagnostics(
|
|
869
917
|
diagnostics,
|
|
870
918
|
path_classes,
|
|
871
|
-
classes,
|
|
872
919
|
fields,
|
|
873
|
-
|
|
920
|
+
classes,
|
|
874
921
|
) {
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
}
|
|
922
|
+
for (const [class_name, class_definition] of Object.entries(classes)) {
|
|
923
|
+
const schema_definition = class_definition.schema;
|
|
878
924
|
|
|
879
|
-
|
|
880
|
-
if (classes[class_name]) {
|
|
925
|
+
if (!schema_definition) {
|
|
881
926
|
continue;
|
|
882
927
|
}
|
|
883
928
|
|
|
884
|
-
diagnostics.push(
|
|
885
|
-
createConfigDiagnostic(
|
|
886
|
-
`class_schemas.${class_name}`,
|
|
887
|
-
`Unknown class "${class_name}".`,
|
|
888
|
-
),
|
|
889
|
-
);
|
|
890
|
-
}
|
|
891
|
-
|
|
892
|
-
for (const [class_name, schema_definition] of Object.entries(class_schemas)) {
|
|
893
929
|
for (const field_name of Object.keys(schema_definition.fields)) {
|
|
894
930
|
if (fields[field_name]) {
|
|
895
931
|
continue;
|
|
@@ -897,14 +933,20 @@ function collectClassSchemaConfigDiagnostics(
|
|
|
897
933
|
|
|
898
934
|
diagnostics.push(
|
|
899
935
|
createConfigDiagnostic(
|
|
900
|
-
`
|
|
936
|
+
`classes.${class_name}.schema.fields.${field_name}`,
|
|
901
937
|
`Unknown field "${field_name}".`,
|
|
902
938
|
),
|
|
903
939
|
);
|
|
904
940
|
}
|
|
905
941
|
}
|
|
906
942
|
|
|
907
|
-
for (const [class_name,
|
|
943
|
+
for (const [class_name, class_definition] of Object.entries(classes)) {
|
|
944
|
+
const schema_definition = class_definition.schema;
|
|
945
|
+
|
|
946
|
+
if (!schema_definition) {
|
|
947
|
+
continue;
|
|
948
|
+
}
|
|
949
|
+
|
|
908
950
|
if (
|
|
909
951
|
schema_definition.document_path_class === undefined ||
|
|
910
952
|
path_classes[schema_definition.document_path_class]
|
|
@@ -914,13 +956,31 @@ function collectClassSchemaConfigDiagnostics(
|
|
|
914
956
|
|
|
915
957
|
diagnostics.push(
|
|
916
958
|
createConfigDiagnostic(
|
|
917
|
-
`
|
|
959
|
+
`classes.${class_name}.schema.document_path_class`,
|
|
918
960
|
`Unknown path class "${schema_definition.document_path_class}".`,
|
|
919
961
|
),
|
|
920
962
|
);
|
|
921
963
|
}
|
|
922
964
|
}
|
|
923
965
|
|
|
966
|
+
/**
|
|
967
|
+
* @param {PatramRepoConfig['classes']} classes
|
|
968
|
+
* @returns {Record<string, ClassDefinition>}
|
|
969
|
+
*/
|
|
970
|
+
function collectGraphClassDefinitions(classes) {
|
|
971
|
+
/** @type {Record<string, ClassDefinition>} */
|
|
972
|
+
const graph_class_definitions = {};
|
|
973
|
+
|
|
974
|
+
for (const [class_name, class_definition] of Object.entries(classes ?? {})) {
|
|
975
|
+
graph_class_definitions[class_name] = {
|
|
976
|
+
builtin: class_definition.builtin,
|
|
977
|
+
label: class_definition.label,
|
|
978
|
+
};
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
return graph_class_definitions;
|
|
982
|
+
}
|
|
983
|
+
|
|
924
984
|
/**
|
|
925
985
|
* @template {Exclude<keyof PatramRepoConfig, 'include' | 'queries'>} TKey
|
|
926
986
|
* @param {PatramRepoConfig} normalized_config
|
|
@@ -966,7 +1026,7 @@ function collectWhereClauseDiagnostics(
|
|
|
966
1026
|
const semantic_diagnostics = getQuerySemanticDiagnostics(
|
|
967
1027
|
repo_config,
|
|
968
1028
|
{ kind: 'ad_hoc' },
|
|
969
|
-
parse_result.
|
|
1029
|
+
parse_result.expression,
|
|
970
1030
|
);
|
|
971
1031
|
|
|
972
1032
|
for (const semantic_diagnostic of semantic_diagnostics) {
|
|
@@ -1,158 +1,56 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
export interface StoredQueryConfig {
|
|
8
|
-
where: string;
|
|
9
|
-
}
|
|
10
|
-
|
|
1
|
+
export type StoredQueryConfig =
|
|
2
|
+
import('./load-patram-config.js').StoredQueryConfig;
|
|
3
|
+
export type FieldDisplayConfig =
|
|
4
|
+
import('./load-patram-config.js').FieldDisplayConfig;
|
|
5
|
+
export type FieldQueryConfig =
|
|
6
|
+
import('./load-patram-config.js').FieldQueryConfig;
|
|
11
7
|
export type FieldValueTypeName =
|
|
12
|
-
|
|
13
|
-
| 'integer'
|
|
14
|
-
| 'enum'
|
|
15
|
-
| 'path'
|
|
16
|
-
| 'glob'
|
|
17
|
-
| 'date'
|
|
18
|
-
| 'date_time';
|
|
19
|
-
|
|
20
|
-
export interface FieldDisplayConfig {
|
|
21
|
-
hidden?: boolean;
|
|
22
|
-
order?: number;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
export interface FieldQueryConfig {
|
|
26
|
-
contains?: boolean;
|
|
27
|
-
prefix?: boolean;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
export interface StringFieldConfig {
|
|
31
|
-
display?: FieldDisplayConfig;
|
|
32
|
-
multiple?: boolean;
|
|
33
|
-
query?: FieldQueryConfig;
|
|
34
|
-
type: 'string';
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export interface IntegerFieldConfig {
|
|
38
|
-
display?: FieldDisplayConfig;
|
|
39
|
-
multiple?: boolean;
|
|
40
|
-
type: 'integer';
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
export interface EnumFieldConfig {
|
|
44
|
-
display?: FieldDisplayConfig;
|
|
45
|
-
multiple?: boolean;
|
|
46
|
-
type: 'enum';
|
|
47
|
-
values: string[];
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
export interface PathFieldConfig {
|
|
51
|
-
display?: FieldDisplayConfig;
|
|
52
|
-
multiple?: boolean;
|
|
53
|
-
path_class?: string;
|
|
54
|
-
type: 'path';
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
export interface GlobFieldConfig {
|
|
58
|
-
display?: FieldDisplayConfig;
|
|
59
|
-
multiple?: boolean;
|
|
60
|
-
type: 'glob';
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
export interface DateFieldConfig {
|
|
64
|
-
display?: FieldDisplayConfig;
|
|
65
|
-
multiple?: boolean;
|
|
66
|
-
type: 'date';
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export interface DateTimeFieldConfig {
|
|
70
|
-
display?: FieldDisplayConfig;
|
|
71
|
-
multiple?: boolean;
|
|
72
|
-
type: 'date_time';
|
|
73
|
-
}
|
|
74
|
-
|
|
8
|
+
import('./load-patram-config.js').MetadataFieldConfig['type'];
|
|
75
9
|
export type MetadataFieldConfig =
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
|
|
10
|
+
import('./load-patram-config.js').MetadataFieldConfig;
|
|
11
|
+
export type StringFieldConfig = Extract<
|
|
12
|
+
MetadataFieldConfig,
|
|
13
|
+
{ type: 'string' }
|
|
14
|
+
>;
|
|
15
|
+
export type IntegerFieldConfig = Extract<
|
|
16
|
+
MetadataFieldConfig,
|
|
17
|
+
{ type: 'integer' }
|
|
18
|
+
>;
|
|
19
|
+
export type EnumFieldConfig = Extract<MetadataFieldConfig, { type: 'enum' }>;
|
|
20
|
+
export type PathFieldConfig = Extract<MetadataFieldConfig, { type: 'path' }>;
|
|
21
|
+
export type GlobFieldConfig = Extract<MetadataFieldConfig, { type: 'glob' }>;
|
|
22
|
+
export type DateFieldConfig = Extract<MetadataFieldConfig, { type: 'date' }>;
|
|
23
|
+
export type DateTimeFieldConfig = Extract<
|
|
24
|
+
MetadataFieldConfig,
|
|
25
|
+
{ type: 'date_time' }
|
|
26
|
+
>;
|
|
27
|
+
export type ClassFieldRuleConfig =
|
|
28
|
+
import('./load-patram-config.js').ClassFieldRuleConfig;
|
|
88
29
|
export type DirectiveTypeConfig = MetadataFieldConfig;
|
|
89
30
|
export type MetadataDirectiveRuleConfig = ClassFieldRuleConfig;
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
document_path_class?: string;
|
|
93
|
-
fields: Record<string, ClassFieldRuleConfig>;
|
|
94
|
-
unknown_fields?: 'ignore' | 'error';
|
|
95
|
-
}
|
|
96
|
-
|
|
31
|
+
export type ClassSchemaConfig =
|
|
32
|
+
import('./load-patram-config.js').ClassSchemaConfig;
|
|
97
33
|
export type MetadataSchemaConfig = ClassSchemaConfig;
|
|
98
|
-
|
|
99
|
-
export
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
export type DerivedSummaryScalar = boolean | number | string | null;
|
|
104
|
-
|
|
105
|
-
export interface DerivedSummaryCountFieldConfig {
|
|
106
|
-
count: {
|
|
107
|
-
traversal: string;
|
|
108
|
-
where: string;
|
|
109
|
-
};
|
|
110
|
-
name: string;
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
export interface DerivedSummarySelectCaseConfig {
|
|
114
|
-
value: DerivedSummaryScalar;
|
|
115
|
-
when: string;
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
export interface DerivedSummarySelectFieldConfig {
|
|
119
|
-
default: DerivedSummaryScalar;
|
|
120
|
-
name: string;
|
|
121
|
-
select: DerivedSummarySelectCaseConfig[];
|
|
122
|
-
}
|
|
123
|
-
|
|
34
|
+
export type PathClassConfig = import('./load-patram-config.js').PathClassConfig;
|
|
35
|
+
export type DerivedSummaryScalar =
|
|
36
|
+
import('./load-patram-config.js').DerivedSummaryScalar;
|
|
37
|
+
export type DerivedSummarySelectCaseConfig =
|
|
38
|
+
import('./load-patram-config.js').DerivedSummarySelectCaseConfig;
|
|
124
39
|
export type DerivedSummaryFieldConfig =
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
relations?: Record<string, RelationDefinition>;
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
export interface PatramDiagnostic {
|
|
146
|
-
code: string;
|
|
147
|
-
column: number;
|
|
148
|
-
level: 'error';
|
|
149
|
-
line: number;
|
|
150
|
-
message: string;
|
|
151
|
-
path: string;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
export interface LoadPatramConfigResult {
|
|
155
|
-
config: PatramRepoConfig | null;
|
|
156
|
-
config_path: string;
|
|
157
|
-
diagnostics: PatramDiagnostic[];
|
|
158
|
-
}
|
|
40
|
+
import('./load-patram-config.js').DerivedSummaryFieldConfig;
|
|
41
|
+
export type DerivedSummaryCountFieldConfig = Extract<
|
|
42
|
+
DerivedSummaryFieldConfig,
|
|
43
|
+
{ count: unknown }
|
|
44
|
+
>;
|
|
45
|
+
export type DerivedSummarySelectFieldConfig = Extract<
|
|
46
|
+
DerivedSummaryFieldConfig,
|
|
47
|
+
{ select: unknown }
|
|
48
|
+
>;
|
|
49
|
+
export type DerivedSummaryConfig =
|
|
50
|
+
import('./load-patram-config.js').DerivedSummaryConfig;
|
|
51
|
+
export type PatramRepoConfig =
|
|
52
|
+
import('./load-patram-config.js').PatramRepoConfig;
|
|
53
|
+
export type PatramDiagnostic =
|
|
54
|
+
import('./load-patram-config.js').PatramDiagnostic;
|
|
55
|
+
export type LoadPatramConfigResult =
|
|
56
|
+
import('./load-patram-config.js').LoadPatramConfigResult;
|