@makehq/forman-schema 1.8.2 → 1.8.3
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/dist/index.cjs +163 -69
- package/dist/index.d.cts +6 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +163 -69
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -412,31 +412,92 @@ function handleArrayType(field, result, context) {
|
|
|
412
412
|
return result;
|
|
413
413
|
}
|
|
414
414
|
function handleFilterType(field, result, context) {
|
|
415
|
-
const
|
|
415
|
+
const operandOptions = isObject(field.options) ? field.options.store : field.options;
|
|
416
|
+
const operandSchema = {
|
|
417
|
+
title: "Operand A",
|
|
418
|
+
description: "The first operand of the filter."
|
|
419
|
+
};
|
|
420
|
+
if (Array.isArray(operandOptions)) {
|
|
421
|
+
operandSchema.type = "string";
|
|
422
|
+
operandSchema.oneOf = operandOptions.flatMap((optionOrGroup) => {
|
|
423
|
+
if (isOptionGroup(optionOrGroup)) {
|
|
424
|
+
return optionOrGroup.options.map((option) => ({
|
|
425
|
+
title: `${optionOrGroup.label}: ${option.label || option.value}`,
|
|
426
|
+
const: option.value
|
|
427
|
+
}));
|
|
428
|
+
}
|
|
429
|
+
return {
|
|
430
|
+
title: optionOrGroup.label || String(optionOrGroup.value),
|
|
431
|
+
const: optionOrGroup.value
|
|
432
|
+
};
|
|
433
|
+
});
|
|
434
|
+
} else if (typeof operandOptions === "string") {
|
|
435
|
+
operandSchema.type = "string";
|
|
436
|
+
Object.defineProperty(operandSchema, "x-fetch", {
|
|
437
|
+
configurable: true,
|
|
438
|
+
enumerable: true,
|
|
439
|
+
writable: true,
|
|
440
|
+
value: appendQueryString(operandOptions, context.domain, context.tail)
|
|
441
|
+
});
|
|
442
|
+
} else {
|
|
443
|
+
operandSchema.type = IML_FILTER_ENTRY_TYPES;
|
|
444
|
+
}
|
|
445
|
+
const operatorOptions = isObject(field.options) ? field.options.operators : void 0;
|
|
446
|
+
const operatorSchema = {
|
|
447
|
+
title: "Operator",
|
|
448
|
+
description: "The operator of the filter."
|
|
449
|
+
};
|
|
450
|
+
if (Array.isArray(operatorOptions)) {
|
|
451
|
+
operatorSchema.type = "string";
|
|
452
|
+
operatorSchema.oneOf = operatorOptions.flatMap((optionOrGroup) => {
|
|
453
|
+
if (isOptionGroup(optionOrGroup)) {
|
|
454
|
+
return optionOrGroup.options.map((option) => ({
|
|
455
|
+
title: `${optionOrGroup.label}: ${option.label || option.value}`,
|
|
456
|
+
const: option.value
|
|
457
|
+
}));
|
|
458
|
+
}
|
|
459
|
+
return {
|
|
460
|
+
title: optionOrGroup.label || String(optionOrGroup.value),
|
|
461
|
+
const: optionOrGroup.value
|
|
462
|
+
};
|
|
463
|
+
});
|
|
464
|
+
} else {
|
|
465
|
+
operatorSchema.enum = IML_BINARY_FILTER_OPERATORS;
|
|
466
|
+
}
|
|
467
|
+
const filterDefinition = {
|
|
416
468
|
oneOf: [
|
|
417
469
|
{
|
|
418
470
|
type: "object",
|
|
419
471
|
properties: {
|
|
420
|
-
a:
|
|
421
|
-
o:
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
properties: {
|
|
428
|
-
a: { type: IML_FILTER_ENTRY_TYPES },
|
|
429
|
-
b: { type: IML_FILTER_ENTRY_TYPES },
|
|
430
|
-
o: { enum: IML_BINARY_FILTER_OPERATORS }
|
|
472
|
+
a: operandSchema,
|
|
473
|
+
o: operatorSchema,
|
|
474
|
+
b: {
|
|
475
|
+
title: "Operand B",
|
|
476
|
+
description: "The second operand of the filter.",
|
|
477
|
+
type: IML_FILTER_ENTRY_TYPES
|
|
478
|
+
}
|
|
431
479
|
},
|
|
432
480
|
required: ["a", "b", "o"]
|
|
433
481
|
}
|
|
434
482
|
]
|
|
435
483
|
};
|
|
484
|
+
if (!operatorOptions) {
|
|
485
|
+
filterDefinition.oneOf?.push({
|
|
486
|
+
type: "object",
|
|
487
|
+
properties: {
|
|
488
|
+
a: operandSchema,
|
|
489
|
+
o: {
|
|
490
|
+
...operatorSchema,
|
|
491
|
+
enum: IML_UNARY_FILTER_OPERATORS
|
|
492
|
+
}
|
|
493
|
+
},
|
|
494
|
+
required: ["a", "o"]
|
|
495
|
+
});
|
|
496
|
+
}
|
|
436
497
|
const logic = field.logic ?? "default";
|
|
437
|
-
result.items = ["and", "or"].includes(logic) ?
|
|
498
|
+
result.items = ["and", "or"].includes(logic) ? filterDefinition : {
|
|
438
499
|
type: "array",
|
|
439
|
-
items:
|
|
500
|
+
items: filterDefinition
|
|
440
501
|
};
|
|
441
502
|
Object.defineProperty(result, "x-filter", {
|
|
442
503
|
configurable: true,
|
|
@@ -462,9 +523,7 @@ function handleSelectOrPathType(field, result, context) {
|
|
|
462
523
|
}
|
|
463
524
|
});
|
|
464
525
|
}
|
|
465
|
-
const nested
|
|
466
|
-
const nestedContainsStrings = Array.isArray(nested) && nested.some((item) => typeof item === "string");
|
|
467
|
-
const domain = isObject(field.options) ? isObject(field.options.nested) && field.options.nested.domain ? field.options.nested.domain : void 0 : void 0;
|
|
526
|
+
const { nested, domain } = extractNestedAndDomain(field);
|
|
468
527
|
if (typeof optionsOrGroups === "string") {
|
|
469
528
|
Object.defineProperty(result, "x-fetch", {
|
|
470
529
|
configurable: true,
|
|
@@ -533,46 +592,7 @@ function handleSelectOrPathType(field, result, context) {
|
|
|
533
592
|
result.enum = (options || []).map((option) => option.value);
|
|
534
593
|
}
|
|
535
594
|
}
|
|
536
|
-
|
|
537
|
-
const normalizedNested = typeof nested === "string" ? [nested] : nested;
|
|
538
|
-
let root = context.roots[domain];
|
|
539
|
-
if (!root) {
|
|
540
|
-
const buffer = [];
|
|
541
|
-
root = context.roots[domain] = {
|
|
542
|
-
buffer,
|
|
543
|
-
addFields: (nested2, tail) => {
|
|
544
|
-
buffer.push(...nested2.map((field2) => ({ field: field2, tail })));
|
|
545
|
-
}
|
|
546
|
-
};
|
|
547
|
-
}
|
|
548
|
-
root.addFields(normalizedNested, [...context.tail, field.name]);
|
|
549
|
-
} else if (nested) {
|
|
550
|
-
Object.defineProperty(result, "x-nested", {
|
|
551
|
-
configurable: true,
|
|
552
|
-
enumerable: true,
|
|
553
|
-
writable: true,
|
|
554
|
-
value: typeof nested === "string" ? { $ref: appendQueryString(nested, context.domain, [...context.tail, field.name]) } : nestedContainsStrings ? {
|
|
555
|
-
type: "object",
|
|
556
|
-
allOf: nested.map(
|
|
557
|
-
(item) => typeof item === "string" ? { $ref: appendQueryString(item, context.domain, [...context.tail, field.name]) } : toJSONSchemaInternal(
|
|
558
|
-
{ type: "collection", spec: [item] },
|
|
559
|
-
{
|
|
560
|
-
...context,
|
|
561
|
-
domain: domain || context.domain,
|
|
562
|
-
tail: [...context.tail, field.name]
|
|
563
|
-
}
|
|
564
|
-
)
|
|
565
|
-
)
|
|
566
|
-
} : toJSONSchemaInternal(
|
|
567
|
-
{ type: "collection", spec: nested },
|
|
568
|
-
{
|
|
569
|
-
...context,
|
|
570
|
-
domain: domain || context.domain,
|
|
571
|
-
tail: [...context.tail, field.name]
|
|
572
|
-
}
|
|
573
|
-
)
|
|
574
|
-
});
|
|
575
|
-
}
|
|
595
|
+
result = handleNestedWithDomain(field, nested, domain, result, context);
|
|
576
596
|
if (field.rpc) result = processRpcDirective(field, result, context);
|
|
577
597
|
return result;
|
|
578
598
|
}
|
|
@@ -595,6 +615,10 @@ function handlePrimitiveType(field, result, context) {
|
|
|
595
615
|
}
|
|
596
616
|
}
|
|
597
617
|
if (field.rpc) result = processRpcDirective(field, result, context);
|
|
618
|
+
if (field.nested) {
|
|
619
|
+
const { nested, domain } = extractNestedAndDomain(field);
|
|
620
|
+
result = handleNestedWithDomain(field, nested, domain, result, context);
|
|
621
|
+
}
|
|
598
622
|
return result;
|
|
599
623
|
}
|
|
600
624
|
function processRpcDirective(field, result, context) {
|
|
@@ -611,6 +635,60 @@ function processRpcDirective(field, result, context) {
|
|
|
611
635
|
});
|
|
612
636
|
return result;
|
|
613
637
|
}
|
|
638
|
+
function extractNestedAndDomain(field) {
|
|
639
|
+
const nested = isObject(field.options) ? isObject(field.options.nested) ? field.options.nested.store : field.options.nested : isObject(field.nested) ? field.nested.store : field.nested;
|
|
640
|
+
const domain = isObject(field.options) ? isObject(field.options.nested) && field.options.nested.domain ? field.options.nested.domain : void 0 : isObject(field.nested) && field.nested.domain ? field.nested.domain : void 0;
|
|
641
|
+
return { nested, domain };
|
|
642
|
+
}
|
|
643
|
+
function handleNestedWithDomain(field, nested, domain, result, context) {
|
|
644
|
+
if (!nested) return result;
|
|
645
|
+
if (domain && domain !== context.domain) {
|
|
646
|
+
const normalizedNested = typeof nested === "string" ? [nested] : nested;
|
|
647
|
+
let root = context.roots[domain];
|
|
648
|
+
if (!root) {
|
|
649
|
+
const buffer = [];
|
|
650
|
+
root = context.roots[domain] = {
|
|
651
|
+
buffer,
|
|
652
|
+
addFields: (nested2, tail) => {
|
|
653
|
+
buffer.push(...nested2.map((field2) => ({ field: field2, tail })));
|
|
654
|
+
}
|
|
655
|
+
};
|
|
656
|
+
}
|
|
657
|
+
root.addFields(normalizedNested, [...context.tail, field.name]);
|
|
658
|
+
return result;
|
|
659
|
+
}
|
|
660
|
+
return processNestedDirective(field, nested, domain, result, context);
|
|
661
|
+
}
|
|
662
|
+
function processNestedDirective(field, nested, domain, result, context) {
|
|
663
|
+
if (!nested) return result;
|
|
664
|
+
const nestedContainsStrings = Array.isArray(nested) && nested.some((item) => typeof item === "string");
|
|
665
|
+
Object.defineProperty(result, "x-nested", {
|
|
666
|
+
configurable: true,
|
|
667
|
+
enumerable: true,
|
|
668
|
+
writable: true,
|
|
669
|
+
value: typeof nested === "string" ? { $ref: appendQueryString(nested, context.domain, [...context.tail, field.name]) } : nestedContainsStrings ? {
|
|
670
|
+
type: "object",
|
|
671
|
+
allOf: nested.map(
|
|
672
|
+
(item) => typeof item === "string" ? { $ref: appendQueryString(item, context.domain, [...context.tail, field.name]) } : toJSONSchemaInternal(
|
|
673
|
+
{ type: "collection", spec: [item] },
|
|
674
|
+
{
|
|
675
|
+
...context,
|
|
676
|
+
domain: domain || context.domain,
|
|
677
|
+
tail: [...context.tail, field.name]
|
|
678
|
+
}
|
|
679
|
+
)
|
|
680
|
+
)
|
|
681
|
+
} : toJSONSchemaInternal(
|
|
682
|
+
{ type: "collection", spec: nested },
|
|
683
|
+
{
|
|
684
|
+
...context,
|
|
685
|
+
domain: domain || context.domain,
|
|
686
|
+
tail: [...context.tail, field.name]
|
|
687
|
+
}
|
|
688
|
+
)
|
|
689
|
+
});
|
|
690
|
+
return result;
|
|
691
|
+
}
|
|
614
692
|
|
|
615
693
|
// src/validator.ts
|
|
616
694
|
var FORMAN_TYPE_MAP2 = {
|
|
@@ -932,24 +1010,40 @@ async function handleArrayType2(value, field, context) {
|
|
|
932
1010
|
};
|
|
933
1011
|
}
|
|
934
1012
|
async function handleFilterType2(value, field, context) {
|
|
1013
|
+
const operandOptions = isObject(field.options) ? field.options.store : field.options;
|
|
1014
|
+
const operandSpec = {
|
|
1015
|
+
name: "a",
|
|
1016
|
+
type: "any",
|
|
1017
|
+
required: true
|
|
1018
|
+
};
|
|
1019
|
+
if (Array.isArray(operandOptions)) {
|
|
1020
|
+
operandSpec.type = "select";
|
|
1021
|
+
operandSpec.options = operandOptions;
|
|
1022
|
+
}
|
|
1023
|
+
const operatorOptions = isObject(field.options) ? field.options.operators : void 0;
|
|
1024
|
+
const operatorSpec = {
|
|
1025
|
+
name: "o",
|
|
1026
|
+
type: "any",
|
|
1027
|
+
required: true
|
|
1028
|
+
};
|
|
1029
|
+
if (Array.isArray(operatorOptions)) {
|
|
1030
|
+
operatorSpec.type = "select";
|
|
1031
|
+
operatorSpec.grouped = true;
|
|
1032
|
+
operatorSpec.options = operatorOptions;
|
|
1033
|
+
} else {
|
|
1034
|
+
operatorSpec.type = "text";
|
|
1035
|
+
operatorSpec.validate = {
|
|
1036
|
+
enum: IML_FILTER_OPERATORS
|
|
1037
|
+
};
|
|
1038
|
+
}
|
|
935
1039
|
const filterEntry = {
|
|
936
1040
|
type: "collection",
|
|
937
1041
|
spec: [
|
|
938
|
-
|
|
939
|
-
|
|
940
|
-
type: "any",
|
|
941
|
-
required: true
|
|
942
|
-
},
|
|
1042
|
+
operandSpec,
|
|
1043
|
+
operatorSpec,
|
|
943
1044
|
{
|
|
944
1045
|
name: "b",
|
|
945
1046
|
type: "any"
|
|
946
|
-
},
|
|
947
|
-
{
|
|
948
|
-
name: "o",
|
|
949
|
-
type: "text",
|
|
950
|
-
validate: {
|
|
951
|
-
enum: IML_FILTER_OPERATORS
|
|
952
|
-
}
|
|
953
1047
|
}
|
|
954
1048
|
]
|
|
955
1049
|
};
|
package/dist/index.d.cts
CHANGED
|
@@ -145,6 +145,10 @@ type FormanSchemaOptionGroup = {
|
|
|
145
145
|
/** Group options */
|
|
146
146
|
options: FormanSchemaOption[];
|
|
147
147
|
};
|
|
148
|
+
/**
|
|
149
|
+
* Helper type for store of select, where options can be either plain options, or groups
|
|
150
|
+
*/
|
|
151
|
+
type FormanSchemaSelectOptionsStore = (FormanSchemaOption | FormanSchemaOptionGroup)[];
|
|
148
152
|
/**
|
|
149
153
|
* Extended options for a select field
|
|
150
154
|
*/
|
|
@@ -162,6 +166,8 @@ type FormanSchemaExtendedOptions = {
|
|
|
162
166
|
label: string;
|
|
163
167
|
nested?: FormanSchemaNested;
|
|
164
168
|
};
|
|
169
|
+
/** Definition of field operators, applicable on Filter fields. */
|
|
170
|
+
operators?: FormanSchemaSelectOptionsStore;
|
|
165
171
|
};
|
|
166
172
|
/**
|
|
167
173
|
* Nested fields
|
package/dist/index.d.ts
CHANGED
|
@@ -145,6 +145,10 @@ type FormanSchemaOptionGroup = {
|
|
|
145
145
|
/** Group options */
|
|
146
146
|
options: FormanSchemaOption[];
|
|
147
147
|
};
|
|
148
|
+
/**
|
|
149
|
+
* Helper type for store of select, where options can be either plain options, or groups
|
|
150
|
+
*/
|
|
151
|
+
type FormanSchemaSelectOptionsStore = (FormanSchemaOption | FormanSchemaOptionGroup)[];
|
|
148
152
|
/**
|
|
149
153
|
* Extended options for a select field
|
|
150
154
|
*/
|
|
@@ -162,6 +166,8 @@ type FormanSchemaExtendedOptions = {
|
|
|
162
166
|
label: string;
|
|
163
167
|
nested?: FormanSchemaNested;
|
|
164
168
|
};
|
|
169
|
+
/** Definition of field operators, applicable on Filter fields. */
|
|
170
|
+
operators?: FormanSchemaSelectOptionsStore;
|
|
165
171
|
};
|
|
166
172
|
/**
|
|
167
173
|
* Nested fields
|
package/dist/index.js
CHANGED
|
@@ -383,31 +383,92 @@ function handleArrayType(field, result, context) {
|
|
|
383
383
|
return result;
|
|
384
384
|
}
|
|
385
385
|
function handleFilterType(field, result, context) {
|
|
386
|
-
const
|
|
386
|
+
const operandOptions = isObject(field.options) ? field.options.store : field.options;
|
|
387
|
+
const operandSchema = {
|
|
388
|
+
title: "Operand A",
|
|
389
|
+
description: "The first operand of the filter."
|
|
390
|
+
};
|
|
391
|
+
if (Array.isArray(operandOptions)) {
|
|
392
|
+
operandSchema.type = "string";
|
|
393
|
+
operandSchema.oneOf = operandOptions.flatMap((optionOrGroup) => {
|
|
394
|
+
if (isOptionGroup(optionOrGroup)) {
|
|
395
|
+
return optionOrGroup.options.map((option) => ({
|
|
396
|
+
title: `${optionOrGroup.label}: ${option.label || option.value}`,
|
|
397
|
+
const: option.value
|
|
398
|
+
}));
|
|
399
|
+
}
|
|
400
|
+
return {
|
|
401
|
+
title: optionOrGroup.label || String(optionOrGroup.value),
|
|
402
|
+
const: optionOrGroup.value
|
|
403
|
+
};
|
|
404
|
+
});
|
|
405
|
+
} else if (typeof operandOptions === "string") {
|
|
406
|
+
operandSchema.type = "string";
|
|
407
|
+
Object.defineProperty(operandSchema, "x-fetch", {
|
|
408
|
+
configurable: true,
|
|
409
|
+
enumerable: true,
|
|
410
|
+
writable: true,
|
|
411
|
+
value: appendQueryString(operandOptions, context.domain, context.tail)
|
|
412
|
+
});
|
|
413
|
+
} else {
|
|
414
|
+
operandSchema.type = IML_FILTER_ENTRY_TYPES;
|
|
415
|
+
}
|
|
416
|
+
const operatorOptions = isObject(field.options) ? field.options.operators : void 0;
|
|
417
|
+
const operatorSchema = {
|
|
418
|
+
title: "Operator",
|
|
419
|
+
description: "The operator of the filter."
|
|
420
|
+
};
|
|
421
|
+
if (Array.isArray(operatorOptions)) {
|
|
422
|
+
operatorSchema.type = "string";
|
|
423
|
+
operatorSchema.oneOf = operatorOptions.flatMap((optionOrGroup) => {
|
|
424
|
+
if (isOptionGroup(optionOrGroup)) {
|
|
425
|
+
return optionOrGroup.options.map((option) => ({
|
|
426
|
+
title: `${optionOrGroup.label}: ${option.label || option.value}`,
|
|
427
|
+
const: option.value
|
|
428
|
+
}));
|
|
429
|
+
}
|
|
430
|
+
return {
|
|
431
|
+
title: optionOrGroup.label || String(optionOrGroup.value),
|
|
432
|
+
const: optionOrGroup.value
|
|
433
|
+
};
|
|
434
|
+
});
|
|
435
|
+
} else {
|
|
436
|
+
operatorSchema.enum = IML_BINARY_FILTER_OPERATORS;
|
|
437
|
+
}
|
|
438
|
+
const filterDefinition = {
|
|
387
439
|
oneOf: [
|
|
388
440
|
{
|
|
389
441
|
type: "object",
|
|
390
442
|
properties: {
|
|
391
|
-
a:
|
|
392
|
-
o:
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
properties: {
|
|
399
|
-
a: { type: IML_FILTER_ENTRY_TYPES },
|
|
400
|
-
b: { type: IML_FILTER_ENTRY_TYPES },
|
|
401
|
-
o: { enum: IML_BINARY_FILTER_OPERATORS }
|
|
443
|
+
a: operandSchema,
|
|
444
|
+
o: operatorSchema,
|
|
445
|
+
b: {
|
|
446
|
+
title: "Operand B",
|
|
447
|
+
description: "The second operand of the filter.",
|
|
448
|
+
type: IML_FILTER_ENTRY_TYPES
|
|
449
|
+
}
|
|
402
450
|
},
|
|
403
451
|
required: ["a", "b", "o"]
|
|
404
452
|
}
|
|
405
453
|
]
|
|
406
454
|
};
|
|
455
|
+
if (!operatorOptions) {
|
|
456
|
+
filterDefinition.oneOf?.push({
|
|
457
|
+
type: "object",
|
|
458
|
+
properties: {
|
|
459
|
+
a: operandSchema,
|
|
460
|
+
o: {
|
|
461
|
+
...operatorSchema,
|
|
462
|
+
enum: IML_UNARY_FILTER_OPERATORS
|
|
463
|
+
}
|
|
464
|
+
},
|
|
465
|
+
required: ["a", "o"]
|
|
466
|
+
});
|
|
467
|
+
}
|
|
407
468
|
const logic = field.logic ?? "default";
|
|
408
|
-
result.items = ["and", "or"].includes(logic) ?
|
|
469
|
+
result.items = ["and", "or"].includes(logic) ? filterDefinition : {
|
|
409
470
|
type: "array",
|
|
410
|
-
items:
|
|
471
|
+
items: filterDefinition
|
|
411
472
|
};
|
|
412
473
|
Object.defineProperty(result, "x-filter", {
|
|
413
474
|
configurable: true,
|
|
@@ -433,9 +494,7 @@ function handleSelectOrPathType(field, result, context) {
|
|
|
433
494
|
}
|
|
434
495
|
});
|
|
435
496
|
}
|
|
436
|
-
const nested
|
|
437
|
-
const nestedContainsStrings = Array.isArray(nested) && nested.some((item) => typeof item === "string");
|
|
438
|
-
const domain = isObject(field.options) ? isObject(field.options.nested) && field.options.nested.domain ? field.options.nested.domain : void 0 : void 0;
|
|
497
|
+
const { nested, domain } = extractNestedAndDomain(field);
|
|
439
498
|
if (typeof optionsOrGroups === "string") {
|
|
440
499
|
Object.defineProperty(result, "x-fetch", {
|
|
441
500
|
configurable: true,
|
|
@@ -504,46 +563,7 @@ function handleSelectOrPathType(field, result, context) {
|
|
|
504
563
|
result.enum = (options || []).map((option) => option.value);
|
|
505
564
|
}
|
|
506
565
|
}
|
|
507
|
-
|
|
508
|
-
const normalizedNested = typeof nested === "string" ? [nested] : nested;
|
|
509
|
-
let root = context.roots[domain];
|
|
510
|
-
if (!root) {
|
|
511
|
-
const buffer = [];
|
|
512
|
-
root = context.roots[domain] = {
|
|
513
|
-
buffer,
|
|
514
|
-
addFields: (nested2, tail) => {
|
|
515
|
-
buffer.push(...nested2.map((field2) => ({ field: field2, tail })));
|
|
516
|
-
}
|
|
517
|
-
};
|
|
518
|
-
}
|
|
519
|
-
root.addFields(normalizedNested, [...context.tail, field.name]);
|
|
520
|
-
} else if (nested) {
|
|
521
|
-
Object.defineProperty(result, "x-nested", {
|
|
522
|
-
configurable: true,
|
|
523
|
-
enumerable: true,
|
|
524
|
-
writable: true,
|
|
525
|
-
value: typeof nested === "string" ? { $ref: appendQueryString(nested, context.domain, [...context.tail, field.name]) } : nestedContainsStrings ? {
|
|
526
|
-
type: "object",
|
|
527
|
-
allOf: nested.map(
|
|
528
|
-
(item) => typeof item === "string" ? { $ref: appendQueryString(item, context.domain, [...context.tail, field.name]) } : toJSONSchemaInternal(
|
|
529
|
-
{ type: "collection", spec: [item] },
|
|
530
|
-
{
|
|
531
|
-
...context,
|
|
532
|
-
domain: domain || context.domain,
|
|
533
|
-
tail: [...context.tail, field.name]
|
|
534
|
-
}
|
|
535
|
-
)
|
|
536
|
-
)
|
|
537
|
-
} : toJSONSchemaInternal(
|
|
538
|
-
{ type: "collection", spec: nested },
|
|
539
|
-
{
|
|
540
|
-
...context,
|
|
541
|
-
domain: domain || context.domain,
|
|
542
|
-
tail: [...context.tail, field.name]
|
|
543
|
-
}
|
|
544
|
-
)
|
|
545
|
-
});
|
|
546
|
-
}
|
|
566
|
+
result = handleNestedWithDomain(field, nested, domain, result, context);
|
|
547
567
|
if (field.rpc) result = processRpcDirective(field, result, context);
|
|
548
568
|
return result;
|
|
549
569
|
}
|
|
@@ -566,6 +586,10 @@ function handlePrimitiveType(field, result, context) {
|
|
|
566
586
|
}
|
|
567
587
|
}
|
|
568
588
|
if (field.rpc) result = processRpcDirective(field, result, context);
|
|
589
|
+
if (field.nested) {
|
|
590
|
+
const { nested, domain } = extractNestedAndDomain(field);
|
|
591
|
+
result = handleNestedWithDomain(field, nested, domain, result, context);
|
|
592
|
+
}
|
|
569
593
|
return result;
|
|
570
594
|
}
|
|
571
595
|
function processRpcDirective(field, result, context) {
|
|
@@ -582,6 +606,60 @@ function processRpcDirective(field, result, context) {
|
|
|
582
606
|
});
|
|
583
607
|
return result;
|
|
584
608
|
}
|
|
609
|
+
function extractNestedAndDomain(field) {
|
|
610
|
+
const nested = isObject(field.options) ? isObject(field.options.nested) ? field.options.nested.store : field.options.nested : isObject(field.nested) ? field.nested.store : field.nested;
|
|
611
|
+
const domain = isObject(field.options) ? isObject(field.options.nested) && field.options.nested.domain ? field.options.nested.domain : void 0 : isObject(field.nested) && field.nested.domain ? field.nested.domain : void 0;
|
|
612
|
+
return { nested, domain };
|
|
613
|
+
}
|
|
614
|
+
function handleNestedWithDomain(field, nested, domain, result, context) {
|
|
615
|
+
if (!nested) return result;
|
|
616
|
+
if (domain && domain !== context.domain) {
|
|
617
|
+
const normalizedNested = typeof nested === "string" ? [nested] : nested;
|
|
618
|
+
let root = context.roots[domain];
|
|
619
|
+
if (!root) {
|
|
620
|
+
const buffer = [];
|
|
621
|
+
root = context.roots[domain] = {
|
|
622
|
+
buffer,
|
|
623
|
+
addFields: (nested2, tail) => {
|
|
624
|
+
buffer.push(...nested2.map((field2) => ({ field: field2, tail })));
|
|
625
|
+
}
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
root.addFields(normalizedNested, [...context.tail, field.name]);
|
|
629
|
+
return result;
|
|
630
|
+
}
|
|
631
|
+
return processNestedDirective(field, nested, domain, result, context);
|
|
632
|
+
}
|
|
633
|
+
function processNestedDirective(field, nested, domain, result, context) {
|
|
634
|
+
if (!nested) return result;
|
|
635
|
+
const nestedContainsStrings = Array.isArray(nested) && nested.some((item) => typeof item === "string");
|
|
636
|
+
Object.defineProperty(result, "x-nested", {
|
|
637
|
+
configurable: true,
|
|
638
|
+
enumerable: true,
|
|
639
|
+
writable: true,
|
|
640
|
+
value: typeof nested === "string" ? { $ref: appendQueryString(nested, context.domain, [...context.tail, field.name]) } : nestedContainsStrings ? {
|
|
641
|
+
type: "object",
|
|
642
|
+
allOf: nested.map(
|
|
643
|
+
(item) => typeof item === "string" ? { $ref: appendQueryString(item, context.domain, [...context.tail, field.name]) } : toJSONSchemaInternal(
|
|
644
|
+
{ type: "collection", spec: [item] },
|
|
645
|
+
{
|
|
646
|
+
...context,
|
|
647
|
+
domain: domain || context.domain,
|
|
648
|
+
tail: [...context.tail, field.name]
|
|
649
|
+
}
|
|
650
|
+
)
|
|
651
|
+
)
|
|
652
|
+
} : toJSONSchemaInternal(
|
|
653
|
+
{ type: "collection", spec: nested },
|
|
654
|
+
{
|
|
655
|
+
...context,
|
|
656
|
+
domain: domain || context.domain,
|
|
657
|
+
tail: [...context.tail, field.name]
|
|
658
|
+
}
|
|
659
|
+
)
|
|
660
|
+
});
|
|
661
|
+
return result;
|
|
662
|
+
}
|
|
585
663
|
|
|
586
664
|
// src/validator.ts
|
|
587
665
|
var FORMAN_TYPE_MAP2 = {
|
|
@@ -903,24 +981,40 @@ async function handleArrayType2(value, field, context) {
|
|
|
903
981
|
};
|
|
904
982
|
}
|
|
905
983
|
async function handleFilterType2(value, field, context) {
|
|
984
|
+
const operandOptions = isObject(field.options) ? field.options.store : field.options;
|
|
985
|
+
const operandSpec = {
|
|
986
|
+
name: "a",
|
|
987
|
+
type: "any",
|
|
988
|
+
required: true
|
|
989
|
+
};
|
|
990
|
+
if (Array.isArray(operandOptions)) {
|
|
991
|
+
operandSpec.type = "select";
|
|
992
|
+
operandSpec.options = operandOptions;
|
|
993
|
+
}
|
|
994
|
+
const operatorOptions = isObject(field.options) ? field.options.operators : void 0;
|
|
995
|
+
const operatorSpec = {
|
|
996
|
+
name: "o",
|
|
997
|
+
type: "any",
|
|
998
|
+
required: true
|
|
999
|
+
};
|
|
1000
|
+
if (Array.isArray(operatorOptions)) {
|
|
1001
|
+
operatorSpec.type = "select";
|
|
1002
|
+
operatorSpec.grouped = true;
|
|
1003
|
+
operatorSpec.options = operatorOptions;
|
|
1004
|
+
} else {
|
|
1005
|
+
operatorSpec.type = "text";
|
|
1006
|
+
operatorSpec.validate = {
|
|
1007
|
+
enum: IML_FILTER_OPERATORS
|
|
1008
|
+
};
|
|
1009
|
+
}
|
|
906
1010
|
const filterEntry = {
|
|
907
1011
|
type: "collection",
|
|
908
1012
|
spec: [
|
|
909
|
-
|
|
910
|
-
|
|
911
|
-
type: "any",
|
|
912
|
-
required: true
|
|
913
|
-
},
|
|
1013
|
+
operandSpec,
|
|
1014
|
+
operatorSpec,
|
|
914
1015
|
{
|
|
915
1016
|
name: "b",
|
|
916
1017
|
type: "any"
|
|
917
|
-
},
|
|
918
|
-
{
|
|
919
|
-
name: "o",
|
|
920
|
-
type: "text",
|
|
921
|
-
validate: {
|
|
922
|
-
enum: IML_FILTER_OPERATORS
|
|
923
|
-
}
|
|
924
1018
|
}
|
|
925
1019
|
]
|
|
926
1020
|
};
|