@fogpipe/forma-core 0.11.2 → 0.12.0-alpha.2
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/{chunk-XS3BLVIZ.js → chunk-ZSW7NIMY.js} +127 -22
- package/dist/chunk-ZSW7NIMY.js.map +1 -0
- package/dist/engine/enabled.d.ts.map +1 -1
- package/dist/engine/index.cjs +105 -21
- package/dist/engine/index.cjs.map +1 -1
- package/dist/engine/index.d.ts +2 -0
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js +5 -1
- package/dist/engine/readonly.d.ts +44 -0
- package/dist/engine/readonly.d.ts.map +1 -0
- package/dist/engine/validate.d.ts.map +1 -1
- package/dist/engine/visibility.d.ts.map +1 -1
- package/dist/index.cjs +133 -21
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -1
- package/dist/types.d.ts +128 -9
- package/dist/types.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/__tests__/validate.test.ts +1 -0
- package/src/engine/enabled.ts +34 -16
- package/src/engine/index.ts +10 -0
- package/src/engine/readonly.ts +169 -0
- package/src/engine/required.ts +1 -1
- package/src/engine/validate.ts +9 -3
- package/src/engine/visibility.ts +8 -6
- package/src/index.ts +20 -2
- package/src/types.ts +181 -12
- package/dist/chunk-XS3BLVIZ.js.map +0 -1
package/dist/index.cjs
CHANGED
|
@@ -35,12 +35,19 @@ __export(index_exports, {
|
|
|
35
35
|
getFormattedValue: () => getFormattedValue,
|
|
36
36
|
getOptionsVisibility: () => getOptionsVisibility,
|
|
37
37
|
getPageVisibility: () => getPageVisibility,
|
|
38
|
+
getReadonly: () => getReadonly,
|
|
38
39
|
getRequired: () => getRequired,
|
|
39
40
|
getVisibility: () => getVisibility,
|
|
40
41
|
getVisibleOptions: () => getVisibleOptions,
|
|
42
|
+
isAdornableField: () => isAdornableField,
|
|
43
|
+
isArrayField: () => isArrayField,
|
|
44
|
+
isDataField: () => isDataField,
|
|
45
|
+
isDisplayField: () => isDisplayField,
|
|
41
46
|
isEnabled: () => isEnabled,
|
|
42
47
|
isFieldVisible: () => isFieldVisible,
|
|
48
|
+
isReadonly: () => isReadonly,
|
|
43
49
|
isRequired: () => isRequired,
|
|
50
|
+
isSelectionField: () => isSelectionField,
|
|
44
51
|
isValidExpression: () => isValidExpression,
|
|
45
52
|
isValidFormat: () => isValidFormat,
|
|
46
53
|
parseDecimalFormat: () => parseDecimalFormat,
|
|
@@ -50,6 +57,32 @@ __export(index_exports, {
|
|
|
50
57
|
});
|
|
51
58
|
module.exports = __toCommonJS(index_exports);
|
|
52
59
|
|
|
60
|
+
// src/types.ts
|
|
61
|
+
var ADORNABLE_TYPES = /* @__PURE__ */ new Set([
|
|
62
|
+
"text",
|
|
63
|
+
"email",
|
|
64
|
+
"url",
|
|
65
|
+
"password",
|
|
66
|
+
"textarea",
|
|
67
|
+
"number",
|
|
68
|
+
"integer"
|
|
69
|
+
]);
|
|
70
|
+
function isAdornableField(field) {
|
|
71
|
+
return ADORNABLE_TYPES.has(field.type);
|
|
72
|
+
}
|
|
73
|
+
function isDisplayField(field) {
|
|
74
|
+
return field.type === "display";
|
|
75
|
+
}
|
|
76
|
+
function isSelectionField(field) {
|
|
77
|
+
return field.type === "select" || field.type === "multiselect";
|
|
78
|
+
}
|
|
79
|
+
function isArrayField(field) {
|
|
80
|
+
return field.type === "array";
|
|
81
|
+
}
|
|
82
|
+
function isDataField(field) {
|
|
83
|
+
return field.type !== "display";
|
|
84
|
+
}
|
|
85
|
+
|
|
53
86
|
// src/feel/index.ts
|
|
54
87
|
var import_feelin = require("feelin");
|
|
55
88
|
function buildFeelContext(ctx) {
|
|
@@ -406,7 +439,7 @@ function processArrayItemOptions(arrayPath, fieldDef, arrayData, baseContext, re
|
|
|
406
439
|
itemIndex: i
|
|
407
440
|
};
|
|
408
441
|
for (const [itemFieldName, itemFieldDef] of Object.entries(fieldDef.itemFields)) {
|
|
409
|
-
if (itemFieldDef.options && itemFieldDef.options.length > 0) {
|
|
442
|
+
if (isSelectionField(itemFieldDef) && itemFieldDef.options && itemFieldDef.options.length > 0) {
|
|
410
443
|
const itemFieldPath = `${arrayPath}[${i}].${itemFieldName}`;
|
|
411
444
|
result[itemFieldPath] = filterOptionsByContext(itemFieldDef.options, itemContext);
|
|
412
445
|
}
|
|
@@ -438,7 +471,7 @@ function evaluateFieldVisibility(path, fieldDef, data, context, result) {
|
|
|
438
471
|
if (!result[path]) {
|
|
439
472
|
return;
|
|
440
473
|
}
|
|
441
|
-
if (fieldDef.itemFields) {
|
|
474
|
+
if (isArrayField(fieldDef) && fieldDef.itemFields) {
|
|
442
475
|
const arrayData = data[path];
|
|
443
476
|
if (Array.isArray(arrayData)) {
|
|
444
477
|
evaluateArrayItemVisibility(path, fieldDef, arrayData, context, result);
|
|
@@ -511,10 +544,10 @@ function getOptionsVisibility(data, spec, options = {}) {
|
|
|
511
544
|
for (const fieldPath of spec.fieldOrder) {
|
|
512
545
|
const fieldDef = spec.fields[fieldPath];
|
|
513
546
|
if (!fieldDef) continue;
|
|
514
|
-
if (fieldDef.options && fieldDef.options.length > 0) {
|
|
547
|
+
if (isSelectionField(fieldDef) && fieldDef.options && fieldDef.options.length > 0) {
|
|
515
548
|
result[fieldPath] = filterOptionsByContext(fieldDef.options, baseContext);
|
|
516
549
|
}
|
|
517
|
-
if (fieldDef.itemFields) {
|
|
550
|
+
if (isArrayField(fieldDef) && fieldDef.itemFields) {
|
|
518
551
|
const arrayData = data[fieldPath];
|
|
519
552
|
if (Array.isArray(arrayData)) {
|
|
520
553
|
processArrayItemOptions(fieldPath, fieldDef, arrayData, baseContext, result);
|
|
@@ -552,7 +585,7 @@ function getRequired(data, spec, options = {}) {
|
|
|
552
585
|
}
|
|
553
586
|
}
|
|
554
587
|
for (const [fieldPath, fieldDef] of Object.entries(spec.fields)) {
|
|
555
|
-
if (fieldDef.itemFields) {
|
|
588
|
+
if (fieldDef.type === "array" && fieldDef.itemFields) {
|
|
556
589
|
const arrayData = data[fieldPath];
|
|
557
590
|
if (Array.isArray(arrayData)) {
|
|
558
591
|
for (let i = 0; i < arrayData.length; i++) {
|
|
@@ -617,23 +650,10 @@ function getEnabled(data, spec, options = {}) {
|
|
|
617
650
|
}
|
|
618
651
|
}
|
|
619
652
|
for (const [fieldPath, fieldDef] of Object.entries(spec.fields)) {
|
|
620
|
-
if (fieldDef.itemFields) {
|
|
653
|
+
if (fieldDef.type === "array" && fieldDef.itemFields) {
|
|
621
654
|
const arrayData = data[fieldPath];
|
|
622
655
|
if (Array.isArray(arrayData)) {
|
|
623
|
-
|
|
624
|
-
const item = arrayData[i];
|
|
625
|
-
const itemContext = {
|
|
626
|
-
data,
|
|
627
|
-
computed,
|
|
628
|
-
referenceData: spec.referenceData,
|
|
629
|
-
item,
|
|
630
|
-
itemIndex: i
|
|
631
|
-
};
|
|
632
|
-
for (const [itemFieldName, itemFieldDef] of Object.entries(fieldDef.itemFields)) {
|
|
633
|
-
const itemFieldPath = `${fieldPath}[${i}].${itemFieldName}`;
|
|
634
|
-
result[itemFieldPath] = isFieldEnabled(itemFieldDef, itemContext);
|
|
635
|
-
}
|
|
636
|
-
}
|
|
656
|
+
evaluateArrayItemEnabled(fieldPath, fieldDef, arrayData, data, computed, spec, result);
|
|
637
657
|
}
|
|
638
658
|
}
|
|
639
659
|
}
|
|
@@ -645,6 +665,23 @@ function isFieldEnabled(fieldDef, context) {
|
|
|
645
665
|
}
|
|
646
666
|
return true;
|
|
647
667
|
}
|
|
668
|
+
function evaluateArrayItemEnabled(arrayPath, fieldDef, arrayData, data, computed, spec, result) {
|
|
669
|
+
if (!fieldDef.itemFields) return;
|
|
670
|
+
for (let i = 0; i < arrayData.length; i++) {
|
|
671
|
+
const item = arrayData[i];
|
|
672
|
+
const itemContext = {
|
|
673
|
+
data,
|
|
674
|
+
computed,
|
|
675
|
+
referenceData: spec.referenceData,
|
|
676
|
+
item,
|
|
677
|
+
itemIndex: i
|
|
678
|
+
};
|
|
679
|
+
for (const [itemFieldName, itemFieldDef] of Object.entries(fieldDef.itemFields)) {
|
|
680
|
+
const itemFieldPath = `${arrayPath}[${i}].${itemFieldName}`;
|
|
681
|
+
result[itemFieldPath] = isFieldEnabled(itemFieldDef, itemContext);
|
|
682
|
+
}
|
|
683
|
+
}
|
|
684
|
+
}
|
|
648
685
|
function isEnabled(fieldPath, data, spec) {
|
|
649
686
|
const fieldDef = spec.fields[fieldPath];
|
|
650
687
|
if (!fieldDef) {
|
|
@@ -662,6 +699,71 @@ function isEnabled(fieldPath, data, spec) {
|
|
|
662
699
|
return evaluateBoolean(fieldDef.enabledWhen, context);
|
|
663
700
|
}
|
|
664
701
|
|
|
702
|
+
// src/engine/readonly.ts
|
|
703
|
+
function getReadonly(data, spec, options = {}) {
|
|
704
|
+
const computed = options.computed ?? calculate(data, spec);
|
|
705
|
+
const context = {
|
|
706
|
+
data,
|
|
707
|
+
computed,
|
|
708
|
+
referenceData: spec.referenceData
|
|
709
|
+
};
|
|
710
|
+
const result = {};
|
|
711
|
+
for (const fieldPath of spec.fieldOrder) {
|
|
712
|
+
const fieldDef = spec.fields[fieldPath];
|
|
713
|
+
if (fieldDef) {
|
|
714
|
+
result[fieldPath] = isFieldReadonly(fieldDef, context);
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
for (const [fieldPath, fieldDef] of Object.entries(spec.fields)) {
|
|
718
|
+
if (fieldDef.type === "array" && fieldDef.itemFields) {
|
|
719
|
+
const arrayData = data[fieldPath];
|
|
720
|
+
if (Array.isArray(arrayData)) {
|
|
721
|
+
evaluateArrayItemReadonly(fieldPath, fieldDef, arrayData, data, computed, spec, result);
|
|
722
|
+
}
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
return result;
|
|
726
|
+
}
|
|
727
|
+
function isFieldReadonly(fieldDef, context) {
|
|
728
|
+
if (fieldDef.readonlyWhen) {
|
|
729
|
+
return evaluateBoolean(fieldDef.readonlyWhen, context);
|
|
730
|
+
}
|
|
731
|
+
return false;
|
|
732
|
+
}
|
|
733
|
+
function evaluateArrayItemReadonly(arrayPath, fieldDef, arrayData, data, computed, spec, result) {
|
|
734
|
+
if (!fieldDef.itemFields) return;
|
|
735
|
+
for (let i = 0; i < arrayData.length; i++) {
|
|
736
|
+
const item = arrayData[i];
|
|
737
|
+
const itemContext = {
|
|
738
|
+
data,
|
|
739
|
+
computed,
|
|
740
|
+
referenceData: spec.referenceData,
|
|
741
|
+
item,
|
|
742
|
+
itemIndex: i
|
|
743
|
+
};
|
|
744
|
+
for (const [itemFieldName, itemFieldDef] of Object.entries(fieldDef.itemFields)) {
|
|
745
|
+
const itemFieldPath = `${arrayPath}[${i}].${itemFieldName}`;
|
|
746
|
+
result[itemFieldPath] = isFieldReadonly(itemFieldDef, itemContext);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
function isReadonly(fieldPath, data, spec) {
|
|
751
|
+
const fieldDef = spec.fields[fieldPath];
|
|
752
|
+
if (!fieldDef) {
|
|
753
|
+
return false;
|
|
754
|
+
}
|
|
755
|
+
if (!fieldDef.readonlyWhen) {
|
|
756
|
+
return false;
|
|
757
|
+
}
|
|
758
|
+
const computed = calculate(data, spec);
|
|
759
|
+
const context = {
|
|
760
|
+
data,
|
|
761
|
+
computed,
|
|
762
|
+
referenceData: spec.referenceData
|
|
763
|
+
};
|
|
764
|
+
return evaluateBoolean(fieldDef.readonlyWhen, context);
|
|
765
|
+
}
|
|
766
|
+
|
|
665
767
|
// src/engine/validate.ts
|
|
666
768
|
function validate(data, spec, options = {}) {
|
|
667
769
|
const { onlyVisible = true } = options;
|
|
@@ -674,6 +776,9 @@ function validate(data, spec, options = {}) {
|
|
|
674
776
|
if (onlyVisible && visibility[fieldPath] === false) {
|
|
675
777
|
continue;
|
|
676
778
|
}
|
|
779
|
+
if (fieldDef.type === "display") {
|
|
780
|
+
continue;
|
|
781
|
+
}
|
|
677
782
|
const schemaProperty = spec.schema.properties[fieldPath];
|
|
678
783
|
const fieldErrors = validateField(
|
|
679
784
|
fieldPath,
|
|
@@ -719,7 +824,7 @@ function validateField(path, value, fieldDef, schemaProperty, spec, data, comput
|
|
|
719
824
|
const customErrors = validateCustomRules(path, fieldDef.validations, context);
|
|
720
825
|
errors.push(...customErrors);
|
|
721
826
|
}
|
|
722
|
-
if (Array.isArray(value)) {
|
|
827
|
+
if (Array.isArray(value) && fieldDef.type === "array") {
|
|
723
828
|
const arrayErrors = validateArray(
|
|
724
829
|
path,
|
|
725
830
|
value,
|
|
@@ -1107,12 +1212,19 @@ function validateSingleField(fieldPath, data, spec) {
|
|
|
1107
1212
|
getFormattedValue,
|
|
1108
1213
|
getOptionsVisibility,
|
|
1109
1214
|
getPageVisibility,
|
|
1215
|
+
getReadonly,
|
|
1110
1216
|
getRequired,
|
|
1111
1217
|
getVisibility,
|
|
1112
1218
|
getVisibleOptions,
|
|
1219
|
+
isAdornableField,
|
|
1220
|
+
isArrayField,
|
|
1221
|
+
isDataField,
|
|
1222
|
+
isDisplayField,
|
|
1113
1223
|
isEnabled,
|
|
1114
1224
|
isFieldVisible,
|
|
1225
|
+
isReadonly,
|
|
1115
1226
|
isRequired,
|
|
1227
|
+
isSelectionField,
|
|
1116
1228
|
isValidExpression,
|
|
1117
1229
|
isValidFormat,
|
|
1118
1230
|
parseDecimalFormat,
|