@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.
@@ -30,11 +30,13 @@ __export(engine_exports, {
30
30
  getFormattedValue: () => getFormattedValue,
31
31
  getOptionsVisibility: () => getOptionsVisibility,
32
32
  getPageVisibility: () => getPageVisibility,
33
+ getReadonly: () => getReadonly,
33
34
  getRequired: () => getRequired,
34
35
  getVisibility: () => getVisibility,
35
36
  getVisibleOptions: () => getVisibleOptions,
36
37
  isEnabled: () => isEnabled,
37
38
  isFieldVisible: () => isFieldVisible,
39
+ isReadonly: () => isReadonly,
38
40
  isRequired: () => isRequired,
39
41
  isValidFormat: () => isValidFormat,
40
42
  parseDecimalFormat: () => parseDecimalFormat,
@@ -315,6 +317,14 @@ function calculateField(fieldName, data, spec) {
315
317
  return computed[fieldName] ?? null;
316
318
  }
317
319
 
320
+ // src/types.ts
321
+ function isSelectionField(field) {
322
+ return field.type === "select" || field.type === "multiselect";
323
+ }
324
+ function isArrayField(field) {
325
+ return field.type === "array";
326
+ }
327
+
318
328
  // src/engine/visibility.ts
319
329
  function filterOptionsByContext(options, context) {
320
330
  return options.filter((option) => {
@@ -336,7 +346,7 @@ function processArrayItemOptions(arrayPath, fieldDef, arrayData, baseContext, re
336
346
  itemIndex: i
337
347
  };
338
348
  for (const [itemFieldName, itemFieldDef] of Object.entries(fieldDef.itemFields)) {
339
- if (itemFieldDef.options && itemFieldDef.options.length > 0) {
349
+ if (isSelectionField(itemFieldDef) && itemFieldDef.options && itemFieldDef.options.length > 0) {
340
350
  const itemFieldPath = `${arrayPath}[${i}].${itemFieldName}`;
341
351
  result[itemFieldPath] = filterOptionsByContext(itemFieldDef.options, itemContext);
342
352
  }
@@ -368,7 +378,7 @@ function evaluateFieldVisibility(path, fieldDef, data, context, result) {
368
378
  if (!result[path]) {
369
379
  return;
370
380
  }
371
- if (fieldDef.itemFields) {
381
+ if (isArrayField(fieldDef) && fieldDef.itemFields) {
372
382
  const arrayData = data[path];
373
383
  if (Array.isArray(arrayData)) {
374
384
  evaluateArrayItemVisibility(path, fieldDef, arrayData, context, result);
@@ -441,10 +451,10 @@ function getOptionsVisibility(data, spec, options = {}) {
441
451
  for (const fieldPath of spec.fieldOrder) {
442
452
  const fieldDef = spec.fields[fieldPath];
443
453
  if (!fieldDef) continue;
444
- if (fieldDef.options && fieldDef.options.length > 0) {
454
+ if (isSelectionField(fieldDef) && fieldDef.options && fieldDef.options.length > 0) {
445
455
  result[fieldPath] = filterOptionsByContext(fieldDef.options, baseContext);
446
456
  }
447
- if (fieldDef.itemFields) {
457
+ if (isArrayField(fieldDef) && fieldDef.itemFields) {
448
458
  const arrayData = data[fieldPath];
449
459
  if (Array.isArray(arrayData)) {
450
460
  processArrayItemOptions(fieldPath, fieldDef, arrayData, baseContext, result);
@@ -482,7 +492,7 @@ function getRequired(data, spec, options = {}) {
482
492
  }
483
493
  }
484
494
  for (const [fieldPath, fieldDef] of Object.entries(spec.fields)) {
485
- if (fieldDef.itemFields) {
495
+ if (fieldDef.type === "array" && fieldDef.itemFields) {
486
496
  const arrayData = data[fieldPath];
487
497
  if (Array.isArray(arrayData)) {
488
498
  for (let i = 0; i < arrayData.length; i++) {
@@ -547,23 +557,10 @@ function getEnabled(data, spec, options = {}) {
547
557
  }
548
558
  }
549
559
  for (const [fieldPath, fieldDef] of Object.entries(spec.fields)) {
550
- if (fieldDef.itemFields) {
560
+ if (fieldDef.type === "array" && fieldDef.itemFields) {
551
561
  const arrayData = data[fieldPath];
552
562
  if (Array.isArray(arrayData)) {
553
- for (let i = 0; i < arrayData.length; i++) {
554
- const item = arrayData[i];
555
- const itemContext = {
556
- data,
557
- computed,
558
- referenceData: spec.referenceData,
559
- item,
560
- itemIndex: i
561
- };
562
- for (const [itemFieldName, itemFieldDef] of Object.entries(fieldDef.itemFields)) {
563
- const itemFieldPath = `${fieldPath}[${i}].${itemFieldName}`;
564
- result[itemFieldPath] = isFieldEnabled(itemFieldDef, itemContext);
565
- }
566
- }
563
+ evaluateArrayItemEnabled(fieldPath, fieldDef, arrayData, data, computed, spec, result);
567
564
  }
568
565
  }
569
566
  }
@@ -575,6 +572,23 @@ function isFieldEnabled(fieldDef, context) {
575
572
  }
576
573
  return true;
577
574
  }
575
+ function evaluateArrayItemEnabled(arrayPath, fieldDef, arrayData, data, computed, spec, result) {
576
+ if (!fieldDef.itemFields) return;
577
+ for (let i = 0; i < arrayData.length; i++) {
578
+ const item = arrayData[i];
579
+ const itemContext = {
580
+ data,
581
+ computed,
582
+ referenceData: spec.referenceData,
583
+ item,
584
+ itemIndex: i
585
+ };
586
+ for (const [itemFieldName, itemFieldDef] of Object.entries(fieldDef.itemFields)) {
587
+ const itemFieldPath = `${arrayPath}[${i}].${itemFieldName}`;
588
+ result[itemFieldPath] = isFieldEnabled(itemFieldDef, itemContext);
589
+ }
590
+ }
591
+ }
578
592
  function isEnabled(fieldPath, data, spec) {
579
593
  const fieldDef = spec.fields[fieldPath];
580
594
  if (!fieldDef) {
@@ -592,6 +606,71 @@ function isEnabled(fieldPath, data, spec) {
592
606
  return evaluateBoolean(fieldDef.enabledWhen, context);
593
607
  }
594
608
 
609
+ // src/engine/readonly.ts
610
+ function getReadonly(data, spec, options = {}) {
611
+ const computed = options.computed ?? calculate(data, spec);
612
+ const context = {
613
+ data,
614
+ computed,
615
+ referenceData: spec.referenceData
616
+ };
617
+ const result = {};
618
+ for (const fieldPath of spec.fieldOrder) {
619
+ const fieldDef = spec.fields[fieldPath];
620
+ if (fieldDef) {
621
+ result[fieldPath] = isFieldReadonly(fieldDef, context);
622
+ }
623
+ }
624
+ for (const [fieldPath, fieldDef] of Object.entries(spec.fields)) {
625
+ if (fieldDef.type === "array" && fieldDef.itemFields) {
626
+ const arrayData = data[fieldPath];
627
+ if (Array.isArray(arrayData)) {
628
+ evaluateArrayItemReadonly(fieldPath, fieldDef, arrayData, data, computed, spec, result);
629
+ }
630
+ }
631
+ }
632
+ return result;
633
+ }
634
+ function isFieldReadonly(fieldDef, context) {
635
+ if (fieldDef.readonlyWhen) {
636
+ return evaluateBoolean(fieldDef.readonlyWhen, context);
637
+ }
638
+ return false;
639
+ }
640
+ function evaluateArrayItemReadonly(arrayPath, fieldDef, arrayData, data, computed, spec, result) {
641
+ if (!fieldDef.itemFields) return;
642
+ for (let i = 0; i < arrayData.length; i++) {
643
+ const item = arrayData[i];
644
+ const itemContext = {
645
+ data,
646
+ computed,
647
+ referenceData: spec.referenceData,
648
+ item,
649
+ itemIndex: i
650
+ };
651
+ for (const [itemFieldName, itemFieldDef] of Object.entries(fieldDef.itemFields)) {
652
+ const itemFieldPath = `${arrayPath}[${i}].${itemFieldName}`;
653
+ result[itemFieldPath] = isFieldReadonly(itemFieldDef, itemContext);
654
+ }
655
+ }
656
+ }
657
+ function isReadonly(fieldPath, data, spec) {
658
+ const fieldDef = spec.fields[fieldPath];
659
+ if (!fieldDef) {
660
+ return false;
661
+ }
662
+ if (!fieldDef.readonlyWhen) {
663
+ return false;
664
+ }
665
+ const computed = calculate(data, spec);
666
+ const context = {
667
+ data,
668
+ computed,
669
+ referenceData: spec.referenceData
670
+ };
671
+ return evaluateBoolean(fieldDef.readonlyWhen, context);
672
+ }
673
+
595
674
  // src/engine/validate.ts
596
675
  function validate(data, spec, options = {}) {
597
676
  const { onlyVisible = true } = options;
@@ -604,6 +683,9 @@ function validate(data, spec, options = {}) {
604
683
  if (onlyVisible && visibility[fieldPath] === false) {
605
684
  continue;
606
685
  }
686
+ if (fieldDef.type === "display") {
687
+ continue;
688
+ }
607
689
  const schemaProperty = spec.schema.properties[fieldPath];
608
690
  const fieldErrors = validateField(
609
691
  fieldPath,
@@ -649,7 +731,7 @@ function validateField(path, value, fieldDef, schemaProperty, spec, data, comput
649
731
  const customErrors = validateCustomRules(path, fieldDef.validations, context);
650
732
  errors.push(...customErrors);
651
733
  }
652
- if (Array.isArray(value)) {
734
+ if (Array.isArray(value) && fieldDef.type === "array") {
653
735
  const arrayErrors = validateArray(
654
736
  path,
655
737
  value,
@@ -1032,11 +1114,13 @@ function validateSingleField(fieldPath, data, spec) {
1032
1114
  getFormattedValue,
1033
1115
  getOptionsVisibility,
1034
1116
  getPageVisibility,
1117
+ getReadonly,
1035
1118
  getRequired,
1036
1119
  getVisibility,
1037
1120
  getVisibleOptions,
1038
1121
  isEnabled,
1039
1122
  isFieldVisible,
1123
+ isReadonly,
1040
1124
  isRequired,
1041
1125
  isValidFormat,
1042
1126
  parseDecimalFormat,