patram 0.10.0 → 0.11.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/cli/arguments.types.d.ts +1 -0
- package/lib/cli/commands/check.js +27 -15
- package/lib/cli/commands/queries.js +189 -1
- package/lib/cli/help-metadata.js +43 -13
- package/lib/cli/parse-arguments-helpers.js +278 -34
- package/lib/cli/render-help.js +8 -2
- package/lib/config/load-patram-config.d.ts +11 -0
- package/lib/config/load-patram-config.js +9 -88
- package/lib/config/manage-stored-queries-helpers.d.ts +69 -0
- package/lib/config/manage-stored-queries-helpers.js +262 -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 +294 -0
- package/lib/config/validate-patram-config-value.d.ts +13 -0
- package/lib/config/validate-patram-config-value.js +119 -0
- package/lib/graph/query/resolve.d.ts +6 -0
- package/lib/graph/query/resolve.js +4 -1
- package/lib/output/resolve-check-target.js +120 -11
- package/lib/patram.d.ts +8 -0
- package/package.json +2 -1
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* @typedef {import('./arguments.types.ts').CliParseError} CliParseError
|
|
6
6
|
* @typedef {import('./arguments.types.ts').ParsedCliHelpRequest} ParsedCliHelpRequest
|
|
7
7
|
* @typedef {{ kind: string, name?: string, rawName?: string, value?: string | boolean }} CliOptionToken
|
|
8
|
-
* @typedef {{ color?: string, explain?: boolean, help?: boolean, json?: boolean, limit?: string, lint?: boolean, 'no-color'?: boolean, offset?: string, plain?: boolean, where?: string }} CliOptionValues
|
|
8
|
+
* @typedef {{ color?: string, desc?: string, explain?: boolean, help?: boolean, json?: boolean, limit?: string, lint?: boolean, name?: string, 'no-color'?: boolean, offset?: string, plain?: boolean, query?: string, where?: string }} CliOptionValues
|
|
9
9
|
* @typedef {{ option_tokens: CliOptionToken[], positionals: string[], values: CliOptionValues }} ParsedCommandLine
|
|
10
10
|
*/
|
|
11
11
|
|
|
@@ -23,14 +23,17 @@ import { findInvalidQueryPagination } from './query-pagination.js';
|
|
|
23
23
|
|
|
24
24
|
export const CLI_OPTIONS = /** @type {const} */ ({
|
|
25
25
|
color: { type: 'string' },
|
|
26
|
+
desc: { type: 'string' },
|
|
26
27
|
explain: { type: 'boolean' },
|
|
27
28
|
help: { type: 'boolean' },
|
|
28
29
|
json: { type: 'boolean' },
|
|
29
30
|
limit: { type: 'string' },
|
|
30
31
|
lint: { type: 'boolean' },
|
|
32
|
+
name: { type: 'string' },
|
|
31
33
|
'no-color': { type: 'boolean' },
|
|
32
34
|
offset: { type: 'string' },
|
|
33
35
|
plain: { type: 'boolean' },
|
|
36
|
+
query: { type: 'string' },
|
|
34
37
|
where: { type: 'string' },
|
|
35
38
|
});
|
|
36
39
|
|
|
@@ -123,6 +126,11 @@ export function validateParsedCommand(command_name, command_line) {
|
|
|
123
126
|
command_line.values,
|
|
124
127
|
command_positionals,
|
|
125
128
|
) ??
|
|
129
|
+
findInvalidQueriesMutation(
|
|
130
|
+
command_name,
|
|
131
|
+
command_line.values,
|
|
132
|
+
command_positionals,
|
|
133
|
+
) ??
|
|
126
134
|
validateCommandPositionals(command_name, command_positionals)
|
|
127
135
|
);
|
|
128
136
|
}
|
|
@@ -162,6 +170,25 @@ export function buildCommandArguments(
|
|
|
162
170
|
return [command_positionals[0], '--where', parsed_values.where];
|
|
163
171
|
}
|
|
164
172
|
|
|
173
|
+
if (command_name === 'queries') {
|
|
174
|
+
/** @type {string[]} */
|
|
175
|
+
const command_arguments = [...command_positionals];
|
|
176
|
+
|
|
177
|
+
if (parsed_values.name !== undefined) {
|
|
178
|
+
command_arguments.push('--name', parsed_values.name);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
if (parsed_values.query !== undefined) {
|
|
182
|
+
command_arguments.push('--query', parsed_values.query);
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
if (parsed_values.desc !== undefined) {
|
|
186
|
+
command_arguments.push('--desc', parsed_values.desc);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
return command_arguments;
|
|
190
|
+
}
|
|
191
|
+
|
|
165
192
|
return command_positionals;
|
|
166
193
|
}
|
|
167
194
|
|
|
@@ -305,24 +332,10 @@ function findInvalidCommandOption(command_name, option_tokens) {
|
|
|
305
332
|
*/
|
|
306
333
|
function findMissingOptionValue(option_tokens) {
|
|
307
334
|
for (const token of option_tokens) {
|
|
308
|
-
|
|
309
|
-
return {
|
|
310
|
-
argument_label: "<name> or --where '<clause>'",
|
|
311
|
-
code: 'missing_required_argument',
|
|
312
|
-
command_name: 'query',
|
|
313
|
-
};
|
|
314
|
-
}
|
|
315
|
-
|
|
316
|
-
if (token.name === 'offset' && typeof token.value !== 'string') {
|
|
317
|
-
return createMessageParseError('Offset requires a value.');
|
|
318
|
-
}
|
|
335
|
+
const missing_value_error = findMissingOptionValueError(token);
|
|
319
336
|
|
|
320
|
-
if (
|
|
321
|
-
return
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
if (token.name === 'color' && typeof token.value !== 'string') {
|
|
325
|
-
return createMessageParseError('Color requires a value.');
|
|
337
|
+
if (missing_value_error) {
|
|
338
|
+
return missing_value_error;
|
|
326
339
|
}
|
|
327
340
|
}
|
|
328
341
|
|
|
@@ -386,6 +399,42 @@ function findInvalidQueryInspection(command_name, parsed_values) {
|
|
|
386
399
|
return null;
|
|
387
400
|
}
|
|
388
401
|
|
|
402
|
+
/**
|
|
403
|
+
* @param {CliCommandName} command_name
|
|
404
|
+
* @param {CliOptionValues} parsed_values
|
|
405
|
+
* @param {string[]} command_positionals
|
|
406
|
+
* @returns {CliParseError | null}
|
|
407
|
+
*/
|
|
408
|
+
function findInvalidQueriesMutation(
|
|
409
|
+
command_name,
|
|
410
|
+
parsed_values,
|
|
411
|
+
command_positionals,
|
|
412
|
+
) {
|
|
413
|
+
if (command_name !== 'queries' || command_positionals.length === 0) {
|
|
414
|
+
return null;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
const subcommand_name = command_positionals[0];
|
|
418
|
+
|
|
419
|
+
if (
|
|
420
|
+
subcommand_name !== 'add' &&
|
|
421
|
+
subcommand_name !== 'remove' &&
|
|
422
|
+
subcommand_name !== 'update'
|
|
423
|
+
) {
|
|
424
|
+
return createUnexpectedArgumentError('queries', subcommand_name);
|
|
425
|
+
}
|
|
426
|
+
|
|
427
|
+
if (subcommand_name === 'add') {
|
|
428
|
+
return validateQueriesAddMutation(parsed_values, command_positionals);
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
if (subcommand_name === 'remove') {
|
|
432
|
+
return validateQueriesRemoveMutation(parsed_values, command_positionals);
|
|
433
|
+
}
|
|
434
|
+
|
|
435
|
+
return validateQueriesUpdateMutation(parsed_values, command_positionals);
|
|
436
|
+
}
|
|
437
|
+
|
|
389
438
|
/**
|
|
390
439
|
* @param {CliCommandName} command_name
|
|
391
440
|
* @param {string[]} command_positionals
|
|
@@ -394,24 +443,18 @@ function findInvalidQueryInspection(command_name, parsed_values) {
|
|
|
394
443
|
function validateCommandPositionals(command_name, command_positionals) {
|
|
395
444
|
const command_definition = getCommandDefinition(command_name);
|
|
396
445
|
|
|
446
|
+
if (allowsQueriesMutationPositionals(command_name, command_positionals)) {
|
|
447
|
+
return null;
|
|
448
|
+
}
|
|
449
|
+
|
|
397
450
|
if (command_positionals.length < command_definition.min_positionals) {
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
command_name: 'query',
|
|
403
|
-
};
|
|
404
|
-
}
|
|
451
|
+
const missing_argument_error = createMissingArgumentError(
|
|
452
|
+
command_name,
|
|
453
|
+
command_definition.missing_argument_label,
|
|
454
|
+
);
|
|
405
455
|
|
|
406
|
-
if (
|
|
407
|
-
|
|
408
|
-
command_definition.missing_argument_label
|
|
409
|
-
) {
|
|
410
|
-
return {
|
|
411
|
-
argument_label: command_definition.missing_argument_label,
|
|
412
|
-
code: 'missing_required_argument',
|
|
413
|
-
command_name,
|
|
414
|
-
};
|
|
456
|
+
if (missing_argument_error) {
|
|
457
|
+
return missing_argument_error;
|
|
415
458
|
}
|
|
416
459
|
|
|
417
460
|
return createMessageParseError(
|
|
@@ -443,14 +486,215 @@ function validateCommandPositionals(command_name, command_positionals) {
|
|
|
443
486
|
*/
|
|
444
487
|
function isKnownCommandOptionName(option_name) {
|
|
445
488
|
return (
|
|
489
|
+
option_name === 'desc' ||
|
|
446
490
|
option_name === 'explain' ||
|
|
447
491
|
option_name === 'limit' ||
|
|
448
492
|
option_name === 'lint' ||
|
|
493
|
+
option_name === 'name' ||
|
|
449
494
|
option_name === 'offset' ||
|
|
495
|
+
option_name === 'query' ||
|
|
450
496
|
option_name === 'where'
|
|
451
497
|
);
|
|
452
498
|
}
|
|
453
499
|
|
|
500
|
+
/**
|
|
501
|
+
* @param {CliOptionToken} option_token
|
|
502
|
+
* @returns {CliParseError | null}
|
|
503
|
+
*/
|
|
504
|
+
function findMissingOptionValueError(option_token) {
|
|
505
|
+
if (typeof option_token.value === 'string') {
|
|
506
|
+
return null;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
if (option_token.name === 'where') {
|
|
510
|
+
return {
|
|
511
|
+
argument_label: "<name> or --where '<clause>'",
|
|
512
|
+
code: 'missing_required_argument',
|
|
513
|
+
command_name: 'query',
|
|
514
|
+
};
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
const message = getMissingOptionValueMessage(option_token.name);
|
|
518
|
+
|
|
519
|
+
if (!message) {
|
|
520
|
+
return null;
|
|
521
|
+
}
|
|
522
|
+
|
|
523
|
+
return createMessageParseError(message);
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
/**
|
|
527
|
+
* @param {string | undefined} option_name
|
|
528
|
+
* @returns {string | null}
|
|
529
|
+
*/
|
|
530
|
+
function getMissingOptionValueMessage(option_name) {
|
|
531
|
+
/** @type {Record<string, string>} */
|
|
532
|
+
const option_messages = {
|
|
533
|
+
color: 'Color requires a value.',
|
|
534
|
+
desc: 'Desc requires a value.',
|
|
535
|
+
limit: 'Limit requires a value.',
|
|
536
|
+
name: 'Name requires a value.',
|
|
537
|
+
offset: 'Offset requires a value.',
|
|
538
|
+
query: 'Query requires a value.',
|
|
539
|
+
};
|
|
540
|
+
|
|
541
|
+
if (!option_name || !Object.hasOwn(option_messages, option_name)) {
|
|
542
|
+
return null;
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
return option_messages[option_name];
|
|
546
|
+
}
|
|
547
|
+
|
|
548
|
+
/**
|
|
549
|
+
* @param {CliOptionValues} parsed_values
|
|
550
|
+
* @param {string[]} command_positionals
|
|
551
|
+
* @returns {CliParseError | null}
|
|
552
|
+
*/
|
|
553
|
+
function validateQueriesAddMutation(parsed_values, command_positionals) {
|
|
554
|
+
const positional_error = validateQueriesMutationPositionals(
|
|
555
|
+
command_positionals,
|
|
556
|
+
'Queries add requires a stored query name.',
|
|
557
|
+
);
|
|
558
|
+
|
|
559
|
+
if (positional_error) {
|
|
560
|
+
return positional_error;
|
|
561
|
+
}
|
|
562
|
+
|
|
563
|
+
if (parsed_values.name !== undefined) {
|
|
564
|
+
return createMessageParseError('Queries add does not accept "--name".');
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
if (parsed_values.query === undefined) {
|
|
568
|
+
return createMessageParseError('Queries add requires "--query <clause>".');
|
|
569
|
+
}
|
|
570
|
+
|
|
571
|
+
return null;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
/**
|
|
575
|
+
* @param {CliOptionValues} parsed_values
|
|
576
|
+
* @param {string[]} command_positionals
|
|
577
|
+
* @returns {CliParseError | null}
|
|
578
|
+
*/
|
|
579
|
+
function validateQueriesRemoveMutation(parsed_values, command_positionals) {
|
|
580
|
+
const positional_error = validateQueriesMutationPositionals(
|
|
581
|
+
command_positionals,
|
|
582
|
+
'Queries remove requires a stored query name.',
|
|
583
|
+
);
|
|
584
|
+
|
|
585
|
+
if (positional_error) {
|
|
586
|
+
return positional_error;
|
|
587
|
+
}
|
|
588
|
+
|
|
589
|
+
if (
|
|
590
|
+
parsed_values.desc !== undefined ||
|
|
591
|
+
parsed_values.name !== undefined ||
|
|
592
|
+
parsed_values.query !== undefined
|
|
593
|
+
) {
|
|
594
|
+
return createMessageParseError(
|
|
595
|
+
'Queries remove does not accept mutation options.',
|
|
596
|
+
);
|
|
597
|
+
}
|
|
598
|
+
|
|
599
|
+
return null;
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* @param {CliOptionValues} parsed_values
|
|
604
|
+
* @param {string[]} command_positionals
|
|
605
|
+
* @returns {CliParseError | null}
|
|
606
|
+
*/
|
|
607
|
+
function validateQueriesUpdateMutation(parsed_values, command_positionals) {
|
|
608
|
+
const positional_error = validateQueriesMutationPositionals(
|
|
609
|
+
command_positionals,
|
|
610
|
+
'Queries update requires a stored query name.',
|
|
611
|
+
);
|
|
612
|
+
|
|
613
|
+
if (positional_error) {
|
|
614
|
+
return positional_error;
|
|
615
|
+
}
|
|
616
|
+
|
|
617
|
+
if (
|
|
618
|
+
parsed_values.desc === undefined &&
|
|
619
|
+
parsed_values.name === undefined &&
|
|
620
|
+
parsed_values.query === undefined
|
|
621
|
+
) {
|
|
622
|
+
return createMessageParseError(
|
|
623
|
+
'Queries update requires at least one of "--name", "--query", or "--desc".',
|
|
624
|
+
);
|
|
625
|
+
}
|
|
626
|
+
|
|
627
|
+
return null;
|
|
628
|
+
}
|
|
629
|
+
|
|
630
|
+
/**
|
|
631
|
+
* @param {string[]} command_positionals
|
|
632
|
+
* @param {string} missing_name_message
|
|
633
|
+
* @returns {CliParseError | null}
|
|
634
|
+
*/
|
|
635
|
+
function validateQueriesMutationPositionals(
|
|
636
|
+
command_positionals,
|
|
637
|
+
missing_name_message,
|
|
638
|
+
) {
|
|
639
|
+
if (command_positionals.length < 2) {
|
|
640
|
+
return createMessageParseError(missing_name_message);
|
|
641
|
+
}
|
|
642
|
+
|
|
643
|
+
if (command_positionals.length > 2) {
|
|
644
|
+
return createUnexpectedArgumentError('queries', command_positionals[2]);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
return null;
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
/**
|
|
651
|
+
* @param {CliCommandName} command_name
|
|
652
|
+
* @param {string[]} command_positionals
|
|
653
|
+
* @returns {boolean}
|
|
654
|
+
*/
|
|
655
|
+
function allowsQueriesMutationPositionals(command_name, command_positionals) {
|
|
656
|
+
if (command_name !== 'queries' || command_positionals.length === 0) {
|
|
657
|
+
return false;
|
|
658
|
+
}
|
|
659
|
+
|
|
660
|
+
const subcommand_name = command_positionals[0];
|
|
661
|
+
|
|
662
|
+
return (
|
|
663
|
+
subcommand_name === 'add' ||
|
|
664
|
+
subcommand_name === 'remove' ||
|
|
665
|
+
subcommand_name === 'update'
|
|
666
|
+
);
|
|
667
|
+
}
|
|
668
|
+
|
|
669
|
+
/**
|
|
670
|
+
* @param {CliCommandName} command_name
|
|
671
|
+
* @param {string | null} missing_argument_label
|
|
672
|
+
* @returns {CliParseError | null}
|
|
673
|
+
*/
|
|
674
|
+
function createMissingArgumentError(command_name, missing_argument_label) {
|
|
675
|
+
if (!missing_argument_label) {
|
|
676
|
+
return null;
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
if (command_name === 'query') {
|
|
680
|
+
return {
|
|
681
|
+
argument_label: missing_argument_label,
|
|
682
|
+
code: 'missing_required_argument',
|
|
683
|
+
command_name: 'query',
|
|
684
|
+
};
|
|
685
|
+
}
|
|
686
|
+
|
|
687
|
+
if (command_name === 'refs' || command_name === 'show') {
|
|
688
|
+
return {
|
|
689
|
+
argument_label: missing_argument_label,
|
|
690
|
+
code: 'missing_required_argument',
|
|
691
|
+
command_name,
|
|
692
|
+
};
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
return null;
|
|
696
|
+
}
|
|
697
|
+
|
|
454
698
|
/**
|
|
455
699
|
* @param {'help' | CliCommandName} command_name
|
|
456
700
|
* @param {string | undefined} token
|
package/lib/cli/render-help.js
CHANGED
|
@@ -85,6 +85,7 @@ export function renderCliParseError(parse_error) {
|
|
|
85
85
|
if (parse_error.code === 'unknown_stored_query') {
|
|
86
86
|
return renderUnknownStoredQueryError(
|
|
87
87
|
parse_error.name,
|
|
88
|
+
parse_error.next_path,
|
|
88
89
|
parse_error.suggestion,
|
|
89
90
|
);
|
|
90
91
|
}
|
|
@@ -359,10 +360,15 @@ function renderUnexpectedArgumentError(command_name, invalid_token) {
|
|
|
359
360
|
|
|
360
361
|
/**
|
|
361
362
|
* @param {string} stored_query_name
|
|
363
|
+
* @param {string | undefined} next_path
|
|
362
364
|
* @param {string | undefined} suggestion
|
|
363
365
|
* @returns {string}
|
|
364
366
|
*/
|
|
365
|
-
function renderUnknownStoredQueryError(
|
|
367
|
+
function renderUnknownStoredQueryError(
|
|
368
|
+
stored_query_name,
|
|
369
|
+
next_path,
|
|
370
|
+
suggestion,
|
|
371
|
+
) {
|
|
366
372
|
if (suggestion) {
|
|
367
373
|
return joinOutputLines([
|
|
368
374
|
`Unknown stored query: ${stored_query_name}`,
|
|
@@ -371,7 +377,7 @@ function renderUnknownStoredQueryError(stored_query_name, suggestion) {
|
|
|
371
377
|
` ${suggestion}`,
|
|
372
378
|
'',
|
|
373
379
|
'Next:',
|
|
374
|
-
` patram query ${suggestion}`,
|
|
380
|
+
` ${next_path ?? `patram query ${suggestion}`}`,
|
|
375
381
|
]);
|
|
376
382
|
}
|
|
377
383
|
|
|
@@ -49,6 +49,17 @@
|
|
|
49
49
|
* @returns {Promise<LoadPatramConfigResult>}
|
|
50
50
|
*/
|
|
51
51
|
export function loadPatramConfig(project_directory?: string): Promise<LoadPatramConfigResult>;
|
|
52
|
+
/**
|
|
53
|
+
* @param {string} config_source
|
|
54
|
+
* @returns {{ success: true, value: unknown } | { success: false, diagnostic: PatramDiagnostic }}
|
|
55
|
+
*/
|
|
56
|
+
export function parsePatramConfigSource(config_source: string): {
|
|
57
|
+
success: true;
|
|
58
|
+
value: unknown;
|
|
59
|
+
} | {
|
|
60
|
+
success: false;
|
|
61
|
+
diagnostic: PatramDiagnostic;
|
|
62
|
+
};
|
|
52
63
|
export type PatramDiagnostic = {
|
|
53
64
|
code: string;
|
|
54
65
|
column: number;
|
|
@@ -18,15 +18,9 @@ import { readFile } from 'node:fs/promises';
|
|
|
18
18
|
import { resolve } from 'node:path';
|
|
19
19
|
import process from 'node:process';
|
|
20
20
|
|
|
21
|
-
import { CONFIG_FILE_NAME
|
|
22
|
-
import { createDefaultRepoConfig
|
|
23
|
-
import {
|
|
24
|
-
validateDerivedSummaries,
|
|
25
|
-
validateFieldSchemaConfig,
|
|
26
|
-
validateGraphSchema,
|
|
27
|
-
validateLegacyConfigShape,
|
|
28
|
-
validateStoredQueries,
|
|
29
|
-
} from './validation.js';
|
|
21
|
+
import { CONFIG_FILE_NAME } from './schema.js';
|
|
22
|
+
import { createDefaultRepoConfig } from './defaults.js';
|
|
23
|
+
import { validatePatramConfigValue } from './validate-patram-config-value.js';
|
|
30
24
|
|
|
31
25
|
/**
|
|
32
26
|
* Repo config loading.
|
|
@@ -90,56 +84,19 @@ export async function loadPatramConfig(project_directory = process.cwd()) {
|
|
|
90
84
|
return createLoadResult(createDefaultRepoConfig(), []);
|
|
91
85
|
}
|
|
92
86
|
|
|
93
|
-
const parse_result =
|
|
87
|
+
const parse_result = parsePatramConfigSource(config_source);
|
|
94
88
|
|
|
95
89
|
if (!parse_result.success) {
|
|
96
90
|
return createLoadResult(null, [parse_result.diagnostic]);
|
|
97
91
|
}
|
|
98
92
|
|
|
99
|
-
const
|
|
100
|
-
parse_result.value,
|
|
101
|
-
);
|
|
93
|
+
const validation_result = validatePatramConfigValue(parse_result.value);
|
|
102
94
|
|
|
103
|
-
if (
|
|
104
|
-
return createLoadResult(null,
|
|
95
|
+
if (!validation_result.success) {
|
|
96
|
+
return createLoadResult(null, validation_result.diagnostics);
|
|
105
97
|
}
|
|
106
98
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
if (!config_result.success) {
|
|
110
|
-
return createLoadResult(
|
|
111
|
-
null,
|
|
112
|
-
config_result.error.issues.map(createValidationDiagnostic),
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
const graph_schema_diagnostics = validateGraphSchema(config_result.data);
|
|
117
|
-
|
|
118
|
-
if (graph_schema_diagnostics.length > 0) {
|
|
119
|
-
return createLoadResult(null, graph_schema_diagnostics);
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const normalized_config = normalizeRepoConfig(config_result.data);
|
|
123
|
-
const field_schema_diagnostics = validateFieldSchemaConfig(normalized_config);
|
|
124
|
-
|
|
125
|
-
if (field_schema_diagnostics.length > 0) {
|
|
126
|
-
return createLoadResult(null, field_schema_diagnostics);
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
const stored_query_diagnostics = validateStoredQueries(normalized_config);
|
|
130
|
-
|
|
131
|
-
if (stored_query_diagnostics.length > 0) {
|
|
132
|
-
return createLoadResult(null, stored_query_diagnostics);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
const derived_summary_diagnostics =
|
|
136
|
-
validateDerivedSummaries(normalized_config);
|
|
137
|
-
|
|
138
|
-
if (derived_summary_diagnostics.length > 0) {
|
|
139
|
-
return createLoadResult(null, derived_summary_diagnostics);
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
return createLoadResult(normalized_config, []);
|
|
99
|
+
return createLoadResult(validation_result.config, []);
|
|
143
100
|
}
|
|
144
101
|
|
|
145
102
|
/**
|
|
@@ -162,7 +119,7 @@ async function readConfigSource(config_file_path) {
|
|
|
162
119
|
* @param {string} config_source
|
|
163
120
|
* @returns {{ success: true, value: unknown } | { success: false, diagnostic: PatramDiagnostic }}
|
|
164
121
|
*/
|
|
165
|
-
function
|
|
122
|
+
export function parsePatramConfigSource(config_source) {
|
|
166
123
|
try {
|
|
167
124
|
return {
|
|
168
125
|
success: true,
|
|
@@ -211,34 +168,6 @@ function createInvalidJsonDiagnostic(config_source, error) {
|
|
|
211
168
|
};
|
|
212
169
|
}
|
|
213
170
|
|
|
214
|
-
/**
|
|
215
|
-
* @param {import('zod').core.$ZodIssue} issue
|
|
216
|
-
* @returns {PatramDiagnostic}
|
|
217
|
-
*/
|
|
218
|
-
function createValidationDiagnostic(issue) {
|
|
219
|
-
const issue_path = formatIssuePath(issue.path);
|
|
220
|
-
|
|
221
|
-
if (issue_path) {
|
|
222
|
-
return {
|
|
223
|
-
code: 'config.invalid',
|
|
224
|
-
column: 1,
|
|
225
|
-
level: 'error',
|
|
226
|
-
line: 1,
|
|
227
|
-
message: `Invalid config at "${issue_path}": ${issue.message}`,
|
|
228
|
-
path: CONFIG_FILE_NAME,
|
|
229
|
-
};
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
return {
|
|
233
|
-
code: 'config.invalid',
|
|
234
|
-
column: 1,
|
|
235
|
-
level: 'error',
|
|
236
|
-
line: 1,
|
|
237
|
-
message: `Invalid config: ${issue.message}`,
|
|
238
|
-
path: CONFIG_FILE_NAME,
|
|
239
|
-
};
|
|
240
|
-
}
|
|
241
|
-
|
|
242
171
|
/**
|
|
243
172
|
* @param {unknown} error
|
|
244
173
|
* @returns {error is NodeJS.ErrnoException}
|
|
@@ -281,14 +210,6 @@ function getJsonSyntaxOrigin(config_source, error_message) {
|
|
|
281
210
|
};
|
|
282
211
|
}
|
|
283
212
|
|
|
284
|
-
/**
|
|
285
|
-
* @param {(string | number | symbol | undefined)[]} issue_path
|
|
286
|
-
* @returns {string}
|
|
287
|
-
*/
|
|
288
|
-
function formatIssuePath(issue_path) {
|
|
289
|
-
return issue_path.map(String).join('.');
|
|
290
|
-
}
|
|
291
|
-
|
|
292
213
|
/**
|
|
293
214
|
* @param {string} source_text
|
|
294
215
|
* @param {number} offset
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @param {string} config_file_path
|
|
3
|
+
* @returns {Promise<
|
|
4
|
+
* | { success: true, value: Record<string, unknown> }
|
|
5
|
+
* | { diagnostic: PatramDiagnostic, success: false }
|
|
6
|
+
* >}
|
|
7
|
+
*/
|
|
8
|
+
export function loadRawConfig(config_file_path: string): Promise<{
|
|
9
|
+
success: true;
|
|
10
|
+
value: Record<string, unknown>;
|
|
11
|
+
} | {
|
|
12
|
+
diagnostic: PatramDiagnostic;
|
|
13
|
+
success: false;
|
|
14
|
+
}>;
|
|
15
|
+
/**
|
|
16
|
+
* @param {string} config_file_path
|
|
17
|
+
* @param {Record<string, unknown>} raw_config
|
|
18
|
+
* @param {StoredQueryMutationResult} mutation_result
|
|
19
|
+
* @returns {Promise<
|
|
20
|
+
* | { success: true, value: StoredQueryMutationResult }
|
|
21
|
+
* | { diagnostics: PatramDiagnostic[], success: false }
|
|
22
|
+
* >}
|
|
23
|
+
*/
|
|
24
|
+
export function persistStoredQueryMutation(config_file_path: string, raw_config: Record<string, unknown>, mutation_result: StoredQueryMutationResult): Promise<{
|
|
25
|
+
success: true;
|
|
26
|
+
value: StoredQueryMutationResult;
|
|
27
|
+
} | {
|
|
28
|
+
diagnostics: PatramDiagnostic[];
|
|
29
|
+
success: false;
|
|
30
|
+
}>;
|
|
31
|
+
/**
|
|
32
|
+
* @param {string} where_clause
|
|
33
|
+
* @param {string | undefined} description
|
|
34
|
+
* @returns {StoredQueryConfig}
|
|
35
|
+
*/
|
|
36
|
+
export function createStoredQueryDefinition(where_clause: string, description: string | undefined): StoredQueryConfig;
|
|
37
|
+
/**
|
|
38
|
+
* @param {Record<string, unknown> | null} raw_query_value
|
|
39
|
+
* @param {StoredQueryConfig} existing_query
|
|
40
|
+
* @param {{ description?: string, where?: string }} stored_query_mutation
|
|
41
|
+
* @returns {StoredQueryConfig}
|
|
42
|
+
*/
|
|
43
|
+
export function createUpdatedStoredQueryDefinition(raw_query_value: Record<string, unknown> | null, existing_query: StoredQueryConfig, stored_query_mutation: {
|
|
44
|
+
description?: string;
|
|
45
|
+
where?: string;
|
|
46
|
+
}): StoredQueryConfig;
|
|
47
|
+
/**
|
|
48
|
+
* @param {Record<string, unknown>} raw_config
|
|
49
|
+
* @returns {Record<string, unknown>}
|
|
50
|
+
*/
|
|
51
|
+
export function ensureRawQueries(raw_config: Record<string, unknown>): Record<string, unknown>;
|
|
52
|
+
/**
|
|
53
|
+
* @param {unknown} raw_query_value
|
|
54
|
+
* @returns {Record<string, unknown> | null}
|
|
55
|
+
*/
|
|
56
|
+
export function rawQueryValueToRecord(raw_query_value: unknown): Record<string, unknown> | null;
|
|
57
|
+
export type StoredQueryMutationResult = {
|
|
58
|
+
action: "added";
|
|
59
|
+
name: string;
|
|
60
|
+
} | {
|
|
61
|
+
action: "removed";
|
|
62
|
+
name: string;
|
|
63
|
+
} | {
|
|
64
|
+
action: "updated";
|
|
65
|
+
name: string;
|
|
66
|
+
previous_name?: string;
|
|
67
|
+
};
|
|
68
|
+
import type { PatramDiagnostic } from './load-patram-config.types.d.ts';
|
|
69
|
+
import type { StoredQueryConfig } from './load-patram-config.types.d.ts';
|