@remoteoss/json-schema-form 0.5.0-dev.20230719162322 → 0.5.0-dev.20230901130231

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.
@@ -1,8 +1,8 @@
1
1
 
2
2
  /*!
3
3
  Copyright (c) 2023 Remote Technology, Inc.
4
- NPM Package: @remoteoss/json-schema-form@0.5.0-dev.20230719162322
5
- Generated: Wed, 19 Jul 2023 16:23:38 GMT
4
+ NPM Package: @remoteoss/json-schema-form@0.5.0-dev.20230901130231
5
+ Generated: Fri, 01 Sep 2023 13:03:04 GMT
6
6
 
7
7
  MIT License
8
8
 
@@ -6421,6 +6421,384 @@ var require_randexp = __commonJS({
6421
6421
  }
6422
6422
  });
6423
6423
 
6424
+ // node_modules/json-logic-js/logic.js
6425
+ var require_logic = __commonJS({
6426
+ "node_modules/json-logic-js/logic.js"(exports2, module2) {
6427
+ (function(root2, factory) {
6428
+ if (typeof define === "function" && define.amd) {
6429
+ define(factory);
6430
+ } else if (typeof exports2 === "object") {
6431
+ module2.exports = factory();
6432
+ } else {
6433
+ root2.jsonLogic = factory();
6434
+ }
6435
+ })(exports2, function() {
6436
+ "use strict";
6437
+ if (!Array.isArray) {
6438
+ Array.isArray = function(arg) {
6439
+ return Object.prototype.toString.call(arg) === "[object Array]";
6440
+ };
6441
+ }
6442
+ function arrayUnique(array2) {
6443
+ var a = [];
6444
+ for (var i = 0, l = array2.length; i < l; i++) {
6445
+ if (a.indexOf(array2[i]) === -1) {
6446
+ a.push(array2[i]);
6447
+ }
6448
+ }
6449
+ return a;
6450
+ }
6451
+ var jsonLogic2 = {};
6452
+ var operations = {
6453
+ "==": function(a, b) {
6454
+ return a == b;
6455
+ },
6456
+ "===": function(a, b) {
6457
+ return a === b;
6458
+ },
6459
+ "!=": function(a, b) {
6460
+ return a != b;
6461
+ },
6462
+ "!==": function(a, b) {
6463
+ return a !== b;
6464
+ },
6465
+ ">": function(a, b) {
6466
+ return a > b;
6467
+ },
6468
+ ">=": function(a, b) {
6469
+ return a >= b;
6470
+ },
6471
+ "<": function(a, b, c) {
6472
+ return c === void 0 ? a < b : a < b && b < c;
6473
+ },
6474
+ "<=": function(a, b, c) {
6475
+ return c === void 0 ? a <= b : a <= b && b <= c;
6476
+ },
6477
+ "!!": function(a) {
6478
+ return jsonLogic2.truthy(a);
6479
+ },
6480
+ "!": function(a) {
6481
+ return !jsonLogic2.truthy(a);
6482
+ },
6483
+ "%": function(a, b) {
6484
+ return a % b;
6485
+ },
6486
+ "log": function(a) {
6487
+ console.log(a);
6488
+ return a;
6489
+ },
6490
+ "in": function(a, b) {
6491
+ if (!b || typeof b.indexOf === "undefined")
6492
+ return false;
6493
+ return b.indexOf(a) !== -1;
6494
+ },
6495
+ "cat": function() {
6496
+ return Array.prototype.join.call(arguments, "");
6497
+ },
6498
+ "substr": function(source, start, end) {
6499
+ if (end < 0) {
6500
+ var temp = String(source).substr(start);
6501
+ return temp.substr(0, temp.length + end);
6502
+ }
6503
+ return String(source).substr(start, end);
6504
+ },
6505
+ "+": function() {
6506
+ return Array.prototype.reduce.call(arguments, function(a, b) {
6507
+ return parseFloat(a, 10) + parseFloat(b, 10);
6508
+ }, 0);
6509
+ },
6510
+ "*": function() {
6511
+ return Array.prototype.reduce.call(arguments, function(a, b) {
6512
+ return parseFloat(a, 10) * parseFloat(b, 10);
6513
+ });
6514
+ },
6515
+ "-": function(a, b) {
6516
+ if (b === void 0) {
6517
+ return -a;
6518
+ } else {
6519
+ return a - b;
6520
+ }
6521
+ },
6522
+ "/": function(a, b) {
6523
+ return a / b;
6524
+ },
6525
+ "min": function() {
6526
+ return Math.min.apply(this, arguments);
6527
+ },
6528
+ "max": function() {
6529
+ return Math.max.apply(this, arguments);
6530
+ },
6531
+ "merge": function() {
6532
+ return Array.prototype.reduce.call(arguments, function(a, b) {
6533
+ return a.concat(b);
6534
+ }, []);
6535
+ },
6536
+ "var": function(a, b) {
6537
+ var not_found = b === void 0 ? null : b;
6538
+ var data = this;
6539
+ if (typeof a === "undefined" || a === "" || a === null) {
6540
+ return data;
6541
+ }
6542
+ var sub_props = String(a).split(".");
6543
+ for (var i = 0; i < sub_props.length; i++) {
6544
+ if (data === null || data === void 0) {
6545
+ return not_found;
6546
+ }
6547
+ data = data[sub_props[i]];
6548
+ if (data === void 0) {
6549
+ return not_found;
6550
+ }
6551
+ }
6552
+ return data;
6553
+ },
6554
+ "missing": function() {
6555
+ var missing = [];
6556
+ var keys2 = Array.isArray(arguments[0]) ? arguments[0] : arguments;
6557
+ for (var i = 0; i < keys2.length; i++) {
6558
+ var key = keys2[i];
6559
+ var value = jsonLogic2.apply({ "var": key }, this);
6560
+ if (value === null || value === "") {
6561
+ missing.push(key);
6562
+ }
6563
+ }
6564
+ return missing;
6565
+ },
6566
+ "missing_some": function(need_count, options) {
6567
+ var are_missing = jsonLogic2.apply({ "missing": options }, this);
6568
+ if (options.length - are_missing.length >= need_count) {
6569
+ return [];
6570
+ } else {
6571
+ return are_missing;
6572
+ }
6573
+ }
6574
+ };
6575
+ jsonLogic2.is_logic = function(logic) {
6576
+ return typeof logic === "object" && // An object
6577
+ logic !== null && // but not null
6578
+ !Array.isArray(logic) && // and not an array
6579
+ Object.keys(logic).length === 1;
6580
+ };
6581
+ jsonLogic2.truthy = function(value) {
6582
+ if (Array.isArray(value) && value.length === 0) {
6583
+ return false;
6584
+ }
6585
+ return !!value;
6586
+ };
6587
+ jsonLogic2.get_operator = function(logic) {
6588
+ return Object.keys(logic)[0];
6589
+ };
6590
+ jsonLogic2.get_values = function(logic) {
6591
+ return logic[jsonLogic2.get_operator(logic)];
6592
+ };
6593
+ jsonLogic2.apply = function(logic, data) {
6594
+ if (Array.isArray(logic)) {
6595
+ return logic.map(function(l) {
6596
+ return jsonLogic2.apply(l, data);
6597
+ });
6598
+ }
6599
+ if (!jsonLogic2.is_logic(logic)) {
6600
+ return logic;
6601
+ }
6602
+ var op = jsonLogic2.get_operator(logic);
6603
+ var values2 = logic[op];
6604
+ var i;
6605
+ var current;
6606
+ var scopedLogic;
6607
+ var scopedData;
6608
+ var initial;
6609
+ if (!Array.isArray(values2)) {
6610
+ values2 = [values2];
6611
+ }
6612
+ if (op === "if" || op == "?:") {
6613
+ for (i = 0; i < values2.length - 1; i += 2) {
6614
+ if (jsonLogic2.truthy(jsonLogic2.apply(values2[i], data))) {
6615
+ return jsonLogic2.apply(values2[i + 1], data);
6616
+ }
6617
+ }
6618
+ if (values2.length === i + 1) {
6619
+ return jsonLogic2.apply(values2[i], data);
6620
+ }
6621
+ return null;
6622
+ } else if (op === "and") {
6623
+ for (i = 0; i < values2.length; i += 1) {
6624
+ current = jsonLogic2.apply(values2[i], data);
6625
+ if (!jsonLogic2.truthy(current)) {
6626
+ return current;
6627
+ }
6628
+ }
6629
+ return current;
6630
+ } else if (op === "or") {
6631
+ for (i = 0; i < values2.length; i += 1) {
6632
+ current = jsonLogic2.apply(values2[i], data);
6633
+ if (jsonLogic2.truthy(current)) {
6634
+ return current;
6635
+ }
6636
+ }
6637
+ return current;
6638
+ } else if (op === "filter") {
6639
+ scopedData = jsonLogic2.apply(values2[0], data);
6640
+ scopedLogic = values2[1];
6641
+ if (!Array.isArray(scopedData)) {
6642
+ return [];
6643
+ }
6644
+ return scopedData.filter(function(datum) {
6645
+ return jsonLogic2.truthy(jsonLogic2.apply(scopedLogic, datum));
6646
+ });
6647
+ } else if (op === "map") {
6648
+ scopedData = jsonLogic2.apply(values2[0], data);
6649
+ scopedLogic = values2[1];
6650
+ if (!Array.isArray(scopedData)) {
6651
+ return [];
6652
+ }
6653
+ return scopedData.map(function(datum) {
6654
+ return jsonLogic2.apply(scopedLogic, datum);
6655
+ });
6656
+ } else if (op === "reduce") {
6657
+ scopedData = jsonLogic2.apply(values2[0], data);
6658
+ scopedLogic = values2[1];
6659
+ initial = typeof values2[2] !== "undefined" ? values2[2] : null;
6660
+ if (!Array.isArray(scopedData)) {
6661
+ return initial;
6662
+ }
6663
+ return scopedData.reduce(
6664
+ function(accumulator, current2) {
6665
+ return jsonLogic2.apply(
6666
+ scopedLogic,
6667
+ { current: current2, accumulator }
6668
+ );
6669
+ },
6670
+ initial
6671
+ );
6672
+ } else if (op === "all") {
6673
+ scopedData = jsonLogic2.apply(values2[0], data);
6674
+ scopedLogic = values2[1];
6675
+ if (!Array.isArray(scopedData) || !scopedData.length) {
6676
+ return false;
6677
+ }
6678
+ for (i = 0; i < scopedData.length; i += 1) {
6679
+ if (!jsonLogic2.truthy(jsonLogic2.apply(scopedLogic, scopedData[i]))) {
6680
+ return false;
6681
+ }
6682
+ }
6683
+ return true;
6684
+ } else if (op === "none") {
6685
+ scopedData = jsonLogic2.apply(values2[0], data);
6686
+ scopedLogic = values2[1];
6687
+ if (!Array.isArray(scopedData) || !scopedData.length) {
6688
+ return true;
6689
+ }
6690
+ for (i = 0; i < scopedData.length; i += 1) {
6691
+ if (jsonLogic2.truthy(jsonLogic2.apply(scopedLogic, scopedData[i]))) {
6692
+ return false;
6693
+ }
6694
+ }
6695
+ return true;
6696
+ } else if (op === "some") {
6697
+ scopedData = jsonLogic2.apply(values2[0], data);
6698
+ scopedLogic = values2[1];
6699
+ if (!Array.isArray(scopedData) || !scopedData.length) {
6700
+ return false;
6701
+ }
6702
+ for (i = 0; i < scopedData.length; i += 1) {
6703
+ if (jsonLogic2.truthy(jsonLogic2.apply(scopedLogic, scopedData[i]))) {
6704
+ return true;
6705
+ }
6706
+ }
6707
+ return false;
6708
+ }
6709
+ values2 = values2.map(function(val) {
6710
+ return jsonLogic2.apply(val, data);
6711
+ });
6712
+ if (operations.hasOwnProperty(op) && typeof operations[op] === "function") {
6713
+ return operations[op].apply(data, values2);
6714
+ } else if (op.indexOf(".") > 0) {
6715
+ var sub_ops = String(op).split(".");
6716
+ var operation = operations;
6717
+ for (i = 0; i < sub_ops.length; i++) {
6718
+ if (!operation.hasOwnProperty(sub_ops[i])) {
6719
+ throw new Error("Unrecognized operation " + op + " (failed at " + sub_ops.slice(0, i + 1).join(".") + ")");
6720
+ }
6721
+ operation = operation[sub_ops[i]];
6722
+ }
6723
+ return operation.apply(data, values2);
6724
+ }
6725
+ throw new Error("Unrecognized operation " + op);
6726
+ };
6727
+ jsonLogic2.uses_data = function(logic) {
6728
+ var collection = [];
6729
+ if (jsonLogic2.is_logic(logic)) {
6730
+ var op = jsonLogic2.get_operator(logic);
6731
+ var values2 = logic[op];
6732
+ if (!Array.isArray(values2)) {
6733
+ values2 = [values2];
6734
+ }
6735
+ if (op === "var") {
6736
+ collection.push(values2[0]);
6737
+ } else {
6738
+ values2.forEach(function(val) {
6739
+ collection.push.apply(collection, jsonLogic2.uses_data(val));
6740
+ });
6741
+ }
6742
+ }
6743
+ return arrayUnique(collection);
6744
+ };
6745
+ jsonLogic2.add_operation = function(name, code) {
6746
+ operations[name] = code;
6747
+ };
6748
+ jsonLogic2.rm_operation = function(name) {
6749
+ delete operations[name];
6750
+ };
6751
+ jsonLogic2.rule_like = function(rule, pattern) {
6752
+ if (pattern === rule) {
6753
+ return true;
6754
+ }
6755
+ if (pattern === "@") {
6756
+ return true;
6757
+ }
6758
+ if (pattern === "number") {
6759
+ return typeof rule === "number";
6760
+ }
6761
+ if (pattern === "string") {
6762
+ return typeof rule === "string";
6763
+ }
6764
+ if (pattern === "array") {
6765
+ return Array.isArray(rule) && !jsonLogic2.is_logic(rule);
6766
+ }
6767
+ if (jsonLogic2.is_logic(pattern)) {
6768
+ if (jsonLogic2.is_logic(rule)) {
6769
+ var pattern_op = jsonLogic2.get_operator(pattern);
6770
+ var rule_op = jsonLogic2.get_operator(rule);
6771
+ if (pattern_op === "@" || pattern_op === rule_op) {
6772
+ return jsonLogic2.rule_like(
6773
+ jsonLogic2.get_values(rule, false),
6774
+ jsonLogic2.get_values(pattern, false)
6775
+ );
6776
+ }
6777
+ }
6778
+ return false;
6779
+ }
6780
+ if (Array.isArray(pattern)) {
6781
+ if (Array.isArray(rule)) {
6782
+ if (pattern.length !== rule.length) {
6783
+ return false;
6784
+ }
6785
+ for (var i = 0; i < pattern.length; i += 1) {
6786
+ if (!jsonLogic2.rule_like(rule[i], pattern[i])) {
6787
+ return false;
6788
+ }
6789
+ }
6790
+ return true;
6791
+ } else {
6792
+ return false;
6793
+ }
6794
+ }
6795
+ return false;
6796
+ };
6797
+ return jsonLogic2;
6798
+ });
6799
+ }
6800
+ });
6801
+
6424
6802
  // node_modules/lodash/_baseInRange.js
6425
6803
  var require_baseInRange = __commonJS({
6426
6804
  "node_modules/lodash/_baseInRange.js"(exports2, module2) {
@@ -11025,6 +11403,69 @@ var lazy = function lazy2(fn) {
11025
11403
  return new Lazy_default(fn);
11026
11404
  };
11027
11405
 
11406
+ // src/utils.js
11407
+ function convertDiskSizeFromTo(from2, to) {
11408
+ const units = ["bytes", "kb", "mb"];
11409
+ return function convert(value) {
11410
+ return value * Math.pow(1024, units.indexOf(from2.toLowerCase())) / Math.pow(1024, units.indexOf(to.toLowerCase()));
11411
+ };
11412
+ }
11413
+ function containsHTML(str = "") {
11414
+ return /<[a-z][\s\S]*>/i.test(str);
11415
+ }
11416
+ function wrapWithSpan(html, properties = {}) {
11417
+ const attributes = Object.entries(properties).reduce((acc, [key, value]) => `${acc}${key}="${value}" `, "").trim();
11418
+ return `<span ${attributes}>${html}</span>`;
11419
+ }
11420
+ function hasProperty(object2, propertyName) {
11421
+ return Object.prototype.hasOwnProperty.call(object2, propertyName);
11422
+ }
11423
+
11424
+ // src/checkIfConditionMatches.js
11425
+ function checkIfConditionMatches(node, formValues, formFields) {
11426
+ return Object.keys(node.if.properties).every((name) => {
11427
+ const currentProperty = node.if.properties[name];
11428
+ const value = formValues[name];
11429
+ const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
11430
+ value === null;
11431
+ const hasIfExplicit = node.if.required?.includes(name);
11432
+ if (hasEmptyValue && !hasIfExplicit) {
11433
+ return true;
11434
+ }
11435
+ if (hasProperty(currentProperty, "const")) {
11436
+ return compareFormValueWithSchemaValue(value, currentProperty.const);
11437
+ }
11438
+ if (currentProperty.contains?.pattern) {
11439
+ const formValue = value || [];
11440
+ if (Array.isArray(formValue)) {
11441
+ const pattern = new RegExp(currentProperty.contains.pattern);
11442
+ return (value || []).some((item) => pattern.test(item));
11443
+ }
11444
+ }
11445
+ if (currentProperty.enum) {
11446
+ return currentProperty.enum.includes(value);
11447
+ }
11448
+ if (currentProperty.properties) {
11449
+ return checkIfConditionMatches(
11450
+ { if: currentProperty },
11451
+ formValues[name],
11452
+ getField(name, formFields).fields
11453
+ );
11454
+ }
11455
+ const field = getField(name, formFields);
11456
+ return validateFieldSchema(
11457
+ {
11458
+ options: field.options,
11459
+ // @TODO/CODE SMELL. We are passing the property (raw field), but buildYupSchema() expected the output field.
11460
+ ...currentProperty,
11461
+ inputType: field.inputType,
11462
+ required: true
11463
+ },
11464
+ value
11465
+ );
11466
+ });
11467
+ }
11468
+
11028
11469
  // src/internals/helpers.js
11029
11470
  var import_merge = __toESM(require_merge2());
11030
11471
  var import_get2 = __toESM(require_get());
@@ -11284,28 +11725,107 @@ function _composeFieldCustomClosure(defaultComposeFn) {
11284
11725
  };
11285
11726
  }
11286
11727
 
11287
- // src/utils.js
11288
- function convertDiskSizeFromTo(from2, to) {
11289
- const units = ["bytes", "kb", "mb"];
11290
- return function convert(value) {
11291
- return value * Math.pow(1024, units.indexOf(from2.toLowerCase())) / Math.pow(1024, units.indexOf(to.toLowerCase()));
11728
+ // src/yupSchema.js
11729
+ var import_flow = __toESM(require_flow());
11730
+ var import_noop = __toESM(require_noop());
11731
+ var import_randexp = __toESM(require_randexp());
11732
+
11733
+ // src/jsonLogic.js
11734
+ var import_json_logic_js = __toESM(require_logic());
11735
+ function createValidationChecker(schema) {
11736
+ const scopes = /* @__PURE__ */ new Map();
11737
+ function createScopes(jsonSchema, key = "root") {
11738
+ scopes.set(key, createValidationsScope(jsonSchema));
11739
+ Object.entries(jsonSchema?.properties ?? {}).filter(([, property2]) => property2.type === "object" || property2.type === "array").forEach(([key2, property2]) => {
11740
+ if (property2.type === "array") {
11741
+ createScopes(property2.items, `${key2}[]`);
11742
+ } else {
11743
+ createScopes(property2, key2);
11744
+ }
11745
+ });
11746
+ }
11747
+ createScopes(schema);
11748
+ return {
11749
+ scopes,
11750
+ getScope(name = "root") {
11751
+ return scopes.get(name);
11752
+ }
11292
11753
  };
11293
11754
  }
11294
- function containsHTML(str = "") {
11295
- return /<[a-z][\s\S]*>/i.test(str);
11755
+ function createValidationsScope(schema) {
11756
+ const validationMap = /* @__PURE__ */ new Map();
11757
+ const computedValuesMap = /* @__PURE__ */ new Map();
11758
+ const logic = schema?.["x-jsf-logic"] ?? {
11759
+ validations: {},
11760
+ computedValues: {}
11761
+ };
11762
+ const validations = Object.entries(logic.validations ?? {});
11763
+ const computedValues = Object.entries(logic.computedValues ?? {});
11764
+ validations.forEach(([id, validation]) => {
11765
+ validationMap.set(id, validation);
11766
+ });
11767
+ computedValues.forEach(([id, computedValue]) => {
11768
+ computedValuesMap.set(id, computedValue);
11769
+ });
11770
+ function validate2(rule, values2) {
11771
+ return import_json_logic_js.default.apply(rule, replaceUndefinedValuesWithNulls(values2));
11772
+ }
11773
+ return {
11774
+ validationMap,
11775
+ computedValuesMap,
11776
+ validate: validate2,
11777
+ applyValidationRuleInCondition(id, values2) {
11778
+ const validation = validationMap.get(id);
11779
+ return validate2(validation.rule, values2);
11780
+ },
11781
+ applyComputedValueInField(id, values2) {
11782
+ const validation = computedValuesMap.get(id);
11783
+ return validate2(validation.rule, values2);
11784
+ },
11785
+ applyComputedValueRuleInCondition(id, values2) {
11786
+ const validation = computedValuesMap.get(id);
11787
+ return validate2(validation.rule, values2);
11788
+ }
11789
+ };
11296
11790
  }
11297
- function wrapWithSpan(html, properties = {}) {
11298
- const attributes = Object.entries(properties).reduce((acc, [key, value]) => `${acc}${key}="${value}" `, "").trim();
11299
- return `<span ${attributes}>${html}</span>`;
11791
+ function replaceUndefinedValuesWithNulls(values2 = {}) {
11792
+ return Object.entries(values2).reduce((prev, [key, value]) => {
11793
+ return { ...prev, [key]: value === void 0 ? null : value };
11794
+ }, {});
11300
11795
  }
11301
- function hasProperty(object2, propertyName) {
11302
- return Object.prototype.hasOwnProperty.call(object2, propertyName);
11796
+ function yupSchemaWithCustomJSONLogic({ field, logic, config, id }) {
11797
+ const { parentID = "root" } = config;
11798
+ const validation = logic.getScope(parentID).validationMap.get(id);
11799
+ return (yupSchema) => yupSchema.test(
11800
+ `${field.name}-validation-${id}`,
11801
+ validation?.errorMessage ?? "This field is invalid.",
11802
+ (value, { parent }) => {
11803
+ if (value === void 0 && !field.required)
11804
+ return true;
11805
+ return import_json_logic_js.default.apply(validation.rule, parent);
11806
+ }
11807
+ );
11808
+ }
11809
+ function calculateComputedAttributes(fieldParams, { parentID = "root" } = {}) {
11810
+ return ({ logic, formValues }) => {
11811
+ const { computedAttributes } = fieldParams;
11812
+ const attributes = Object.fromEntries(
11813
+ Object.entries(computedAttributes).map(handleComputedAttribute(logic, formValues, parentID)).filter(([, value]) => value !== null)
11814
+ );
11815
+ return attributes;
11816
+ };
11817
+ }
11818
+ function handleComputedAttribute(logic, formValues, parentID) {
11819
+ return ([key, value]) => {
11820
+ if (key === "const")
11821
+ return [key, logic.getScope(parentID).applyComputedValueInField(value, formValues)];
11822
+ if (typeof value === "string") {
11823
+ return [key, logic.getScope(parentID).applyComputedValueInField(value, formValues)];
11824
+ }
11825
+ };
11303
11826
  }
11304
11827
 
11305
11828
  // src/yupSchema.js
11306
- var import_flow = __toESM(require_flow());
11307
- var import_noop = __toESM(require_noop());
11308
- var import_randexp = __toESM(require_randexp());
11309
11829
  var DEFAULT_DATE_FORMAT = "yyyy-MM-dd";
11310
11830
  var baseString = StringSchema().trim();
11311
11831
  var todayDateHint = (/* @__PURE__ */ new Date()).toISOString().substring(0, 10);
@@ -11428,7 +11948,7 @@ var getYupSchema = ({ inputType, ...field }) => {
11428
11948
  }
11429
11949
  return yupSchemas[inputType] || yupSchemasToJsonTypes[jsonType];
11430
11950
  };
11431
- function buildYupSchema(field, config) {
11951
+ function buildYupSchema(field, config, logic) {
11432
11952
  const { inputType, jsonType: jsonTypeValue, errorMessage = {}, ...propertyFields } = field;
11433
11953
  const isCheckboxBoolean = typeof propertyFields.checkboxValue === "boolean";
11434
11954
  let baseSchema;
@@ -11501,6 +12021,13 @@ function buildYupSchema(field, config) {
11501
12021
  }) : true
11502
12022
  );
11503
12023
  }
12024
+ function withConst(yupSchema) {
12025
+ return yupSchema.test(
12026
+ "isConst",
12027
+ errorMessage.const ?? errorMessageFromConfig.const ?? `The only accepted value is ${propertyFields.const}.`,
12028
+ (value) => propertyFields.required === false && value === void 0 || value === null || value === propertyFields.const
12029
+ );
12030
+ }
11504
12031
  function withBaseSchema() {
11505
12032
  const customErrorMsg = errorMessage.type || errorMessageFromConfig.type;
11506
12033
  if (customErrorMsg) {
@@ -11568,6 +12095,14 @@ function buildYupSchema(field, config) {
11568
12095
  if (propertyFields.accept) {
11569
12096
  validators.push(withFileFormat);
11570
12097
  }
12098
+ if (propertyFields.const) {
12099
+ validators.push(withConst);
12100
+ }
12101
+ if (propertyFields.requiredValidations) {
12102
+ propertyFields.requiredValidations.forEach(
12103
+ (id) => validators.push(yupSchemaWithCustomJSONLogic({ field, id, logic, config }))
12104
+ );
12105
+ }
11571
12106
  return (0, import_flow.default)(validators);
11572
12107
  }
11573
12108
  function getNoSortEdges(fields = []) {
@@ -11607,50 +12142,14 @@ function hasType(type, typeName) {
11607
12142
  function getField(fieldName, fields) {
11608
12143
  return fields.find(({ name }) => name === fieldName);
11609
12144
  }
11610
- function validateFieldSchema(field, value) {
11611
- const validator = buildYupSchema(field);
12145
+ function validateFieldSchema(field, value, logic) {
12146
+ const validator = buildYupSchema(field, {}, logic);
11612
12147
  return validator().isValidSync(value);
11613
12148
  }
11614
12149
  function compareFormValueWithSchemaValue(formValue, schemaValue) {
11615
12150
  const currentPropertyValue = typeof schemaValue === "number" ? schemaValue : schemaValue || void 0;
11616
12151
  return String(formValue) === String(currentPropertyValue);
11617
12152
  }
11618
- function checkIfConditionMatches(node, formValues, formFields) {
11619
- return Object.keys(node.if.properties).every((name) => {
11620
- const currentProperty = node.if.properties[name];
11621
- const value = formValues[name];
11622
- const hasEmptyValue = typeof value === "undefined" || // NOTE: This is a "Remote API" dependency, as empty fields are sent as "null".
11623
- value === null;
11624
- const hasIfExplicit = node.if.required?.includes(name);
11625
- if (hasEmptyValue && !hasIfExplicit) {
11626
- return true;
11627
- }
11628
- if (hasProperty(currentProperty, "const")) {
11629
- return compareFormValueWithSchemaValue(value, currentProperty.const);
11630
- }
11631
- if (currentProperty.contains?.pattern) {
11632
- const formValue = value || [];
11633
- if (Array.isArray(formValue)) {
11634
- const pattern = new RegExp(currentProperty.contains.pattern);
11635
- return (value || []).some((item) => pattern.test(item));
11636
- }
11637
- }
11638
- if (currentProperty.enum) {
11639
- return currentProperty.enum.includes(value);
11640
- }
11641
- const field = getField(name, formFields);
11642
- return validateFieldSchema(
11643
- {
11644
- options: field.options,
11645
- // @TODO/CODE SMELL. We are passing the property (raw field), but buildYupSchema() expected the output field.
11646
- ...currentProperty,
11647
- inputType: field.inputType,
11648
- required: true
11649
- },
11650
- value
11651
- );
11652
- });
11653
- }
11654
12153
  function isFieldFilled(fieldValue) {
11655
12154
  return Array.isArray(fieldValue) ? fieldValue.length > 0 : !!fieldValue;
11656
12155
  }
@@ -11680,7 +12179,16 @@ function getPrefillSubFieldValues(field, defaultValues, parentFieldKeyPath) {
11680
12179
  initialValue[field.name] = subFieldValues;
11681
12180
  }
11682
12181
  } else {
11683
- initialValue = getPrefillValues([field], initialValue);
12182
+ if (typeof initialValue !== "object") {
12183
+ console.warn(
12184
+ `Field "${parentFieldKeyPath}"'s value is "${initialValue}", but should be type object.`
12185
+ );
12186
+ initialValue = getPrefillValues([field], {
12187
+ // TODO nested fieldsets are not handled
12188
+ });
12189
+ } else {
12190
+ initialValue = getPrefillValues([field], initialValue);
12191
+ }
11684
12192
  }
11685
12193
  return initialValue;
11686
12194
  }
@@ -11709,7 +12217,7 @@ function getPrefillValues(fields, initialValues = {}) {
11709
12217
  });
11710
12218
  return initialValues;
11711
12219
  }
11712
- function updateField(field, requiredFields, node, formValues) {
12220
+ function updateField(field, requiredFields, node, formValues, logic, config) {
11713
12221
  if (!field) {
11714
12222
  return;
11715
12223
  }
@@ -11731,6 +12239,17 @@ function updateField(field, requiredFields, node, formValues) {
11731
12239
  }
11732
12240
  }
11733
12241
  });
12242
+ if (field.getComputedAttributes) {
12243
+ const computedFieldValues = field.getComputedAttributes({
12244
+ field,
12245
+ isRequired: fieldIsRequired,
12246
+ node,
12247
+ formValues,
12248
+ config,
12249
+ logic
12250
+ });
12251
+ updateValues(computedFieldValues);
12252
+ }
11734
12253
  if (field.calculateConditionalProperties) {
11735
12254
  const newFieldValues = field.calculateConditionalProperties(fieldIsRequired, node);
11736
12255
  updateValues(newFieldValues);
@@ -11744,33 +12263,46 @@ function updateField(field, requiredFields, node, formValues) {
11744
12263
  updateValues(newFieldValues);
11745
12264
  }
11746
12265
  }
11747
- function processNode(node, formValues, formFields, accRequired = /* @__PURE__ */ new Set()) {
12266
+ function processNode({
12267
+ node,
12268
+ formValues,
12269
+ formFields,
12270
+ accRequired = /* @__PURE__ */ new Set(),
12271
+ parentID = "root",
12272
+ logic
12273
+ }) {
11748
12274
  const requiredFields = new Set(accRequired);
11749
12275
  Object.keys(node.properties ?? []).forEach((fieldName) => {
11750
12276
  const field = getField(fieldName, formFields);
11751
- updateField(field, requiredFields, node, formValues);
12277
+ updateField(field, requiredFields, node, formValues, logic, { parentID });
11752
12278
  });
11753
12279
  node.required?.forEach((fieldName) => {
11754
12280
  requiredFields.add(fieldName);
11755
- updateField(getField(fieldName, formFields), requiredFields, node, formValues);
12281
+ updateField(getField(fieldName, formFields), requiredFields, node, formValues, logic, {
12282
+ parentID
12283
+ });
11756
12284
  });
11757
12285
  if (node.if) {
11758
- const matchesCondition = checkIfConditionMatches(node, formValues, formFields);
12286
+ const matchesCondition = checkIfConditionMatches(node, formValues, formFields, logic);
11759
12287
  if (matchesCondition && node.then) {
11760
- const { required: branchRequired } = processNode(
11761
- node.then,
12288
+ const { required: branchRequired } = processNode({
12289
+ node: node.then,
11762
12290
  formValues,
11763
12291
  formFields,
11764
- requiredFields
11765
- );
12292
+ accRequired: requiredFields,
12293
+ parentID,
12294
+ logic
12295
+ });
11766
12296
  branchRequired.forEach((field) => requiredFields.add(field));
11767
12297
  } else if (node.else) {
11768
- const { required: branchRequired } = processNode(
11769
- node.else,
12298
+ const { required: branchRequired } = processNode({
12299
+ node: node.else,
11770
12300
  formValues,
11771
12301
  formFields,
11772
- requiredFields
11773
- );
12302
+ accRequired: requiredFields,
12303
+ parentID,
12304
+ logic
12305
+ });
11774
12306
  branchRequired.forEach((field) => requiredFields.add(field));
11775
12307
  }
11776
12308
  }
@@ -11782,12 +12314,21 @@ function processNode(node, formValues, formFields, accRequired = /* @__PURE__ */
11782
12314
  node.anyOf.forEach(({ required: required2 = [] }) => {
11783
12315
  required2.forEach((fieldName) => {
11784
12316
  const field = getField(fieldName, formFields);
11785
- updateField(field, requiredFields, node, formValues);
12317
+ updateField(field, requiredFields, node, formValues, logic, { parentID });
11786
12318
  });
11787
12319
  });
11788
12320
  }
11789
12321
  if (node.allOf) {
11790
- node.allOf.map((allOfNode) => processNode(allOfNode, formValues, formFields, requiredFields)).forEach(({ required: allOfItemRequired }) => {
12322
+ node.allOf.map(
12323
+ (allOfNode) => processNode({
12324
+ node: allOfNode,
12325
+ formValues,
12326
+ formFields,
12327
+ accRequired: requiredFields,
12328
+ parentID,
12329
+ logic
12330
+ })
12331
+ ).forEach(({ required: allOfItemRequired }) => {
11791
12332
  allOfItemRequired.forEach(requiredFields.add, requiredFields);
11792
12333
  });
11793
12334
  }
@@ -11795,7 +12336,13 @@ function processNode(node, formValues, formFields, accRequired = /* @__PURE__ */
11795
12336
  Object.entries(node.properties).forEach(([name, nestedNode]) => {
11796
12337
  const inputType = getInputType(nestedNode);
11797
12338
  if (inputType === supportedTypes.FIELDSET) {
11798
- processNode(nestedNode, formValues[name] || {}, getField(name, formFields).fields);
12339
+ processNode({
12340
+ node: nestedNode,
12341
+ formValues: formValues[name] || {},
12342
+ formFields: getField(name, formFields).fields,
12343
+ parentID: name,
12344
+ logic
12345
+ });
11799
12346
  }
11800
12347
  });
11801
12348
  }
@@ -11813,11 +12360,11 @@ function clearValuesIfNotVisible(fields, formValues) {
11813
12360
  }
11814
12361
  });
11815
12362
  }
11816
- function updateFieldsProperties(fields, formValues, jsonSchema) {
12363
+ function updateFieldsProperties(fields, formValues, jsonSchema, logic) {
11817
12364
  if (!jsonSchema?.properties) {
11818
12365
  return;
11819
12366
  }
11820
- processNode(jsonSchema, formValues, fields);
12367
+ processNode({ node: jsonSchema, formValues, formFields: fields, logic });
11821
12368
  clearValuesIfNotVisible(fields, formValues);
11822
12369
  }
11823
12370
  var notNullOption = (opt) => opt.const !== null;
@@ -11860,11 +12407,15 @@ function extractParametersFromNode(schemaNode) {
11860
12407
  }
11861
12408
  const presentation = pickXKey(schemaNode, "presentation") ?? {};
11862
12409
  const errorMessage = pickXKey(schemaNode, "errorMessage") ?? {};
12410
+ const requiredValidations = schemaNode["x-jsf-logic-validations"];
12411
+ const computedAttributes = schemaNode["x-jsf-logic-computedAttrs"];
12412
+ const decoratedComputedAttributes = getDecoratedComputedAttributes(computedAttributes);
11863
12413
  const node = (0, import_omit.default)(schemaNode, ["x-jsf-presentation", "presentation"]);
11864
12414
  const description = presentation?.description || node.description;
11865
12415
  const statementDescription = containsHTML(presentation.statement?.description) ? wrapWithSpan(presentation.statement.description, { class: "jsf-statement" }) : presentation.statement?.description;
11866
12416
  return (0, import_omitBy.default)(
11867
12417
  {
12418
+ const: node.const,
11868
12419
  label: node.title,
11869
12420
  readOnly: node.readOnly,
11870
12421
  ...node.deprecated && {
@@ -11899,6 +12450,8 @@ function extractParametersFromNode(schemaNode) {
11899
12450
  },
11900
12451
  // Handle [name].presentation
11901
12452
  ...presentation,
12453
+ requiredValidations,
12454
+ computedAttributes: decoratedComputedAttributes,
11902
12455
  description: containsHTML(description) ? wrapWithSpan(description, {
11903
12456
  class: "jsf-description"
11904
12457
  }) : description,
@@ -11935,8 +12488,8 @@ function yupToFormErrors(yupError) {
11935
12488
  }
11936
12489
  return errors;
11937
12490
  }
11938
- var handleValuesChange = (fields, jsonSchema, config) => (values2) => {
11939
- updateFieldsProperties(fields, values2, jsonSchema);
12491
+ var handleValuesChange = (fields, jsonSchema, config, logic) => (values2) => {
12492
+ updateFieldsProperties(fields, values2, jsonSchema, logic);
11940
12493
  const lazySchema = lazy(() => buildCompleteYupSchema(fields, config));
11941
12494
  let errors;
11942
12495
  try {
@@ -11955,6 +12508,12 @@ var handleValuesChange = (fields, jsonSchema, config) => (values2) => {
11955
12508
  formErrors: yupToFormErrors(errors)
11956
12509
  };
11957
12510
  };
12511
+ function getDecoratedComputedAttributes(computedAttributes) {
12512
+ return {
12513
+ ...computedAttributes ?? {},
12514
+ ...computedAttributes?.const && computedAttributes?.default ? { value: computedAttributes.const } : {}
12515
+ };
12516
+ }
11958
12517
 
11959
12518
  // src/calculateConditionalProperties.js
11960
12519
  function isFieldRequired(node, field) {
@@ -12156,6 +12715,9 @@ function applyFieldsDependencies(fieldsParameters, node) {
12156
12715
  applyFieldsDependencies(fieldsParameters, condition);
12157
12716
  });
12158
12717
  }
12718
+ if (node?.["x-jsf-logic"]) {
12719
+ applyFieldsDependencies(fieldsParameters, node["x-jsf-logic"]);
12720
+ }
12159
12721
  }
12160
12722
  function getCustomPropertiesForField(fieldParams, config) {
12161
12723
  return config?.customProperties?.[fieldParams.name];
@@ -12167,15 +12729,16 @@ function getComposeFunctionForField(fieldParams, hasCustomizations) {
12167
12729
  }
12168
12730
  return composeFn;
12169
12731
  }
12170
- function buildField(fieldParams, config, scopedJsonSchema) {
12732
+ function buildField(fieldParams, config, scopedJsonSchema, logic) {
12171
12733
  const customProperties = getCustomPropertiesForField(fieldParams, config);
12172
12734
  const composeFn = getComposeFunctionForField(fieldParams, !!customProperties);
12173
- const yupSchema = buildYupSchema(fieldParams, config);
12735
+ const yupSchema = buildYupSchema(fieldParams, config, logic);
12174
12736
  const calculateConditionalFieldsClosure = fieldParams.isDynamic && calculateConditionalProperties(fieldParams, customProperties);
12175
12737
  const calculateCustomValidationPropertiesClosure = calculateCustomValidationProperties(
12176
12738
  fieldParams,
12177
12739
  customProperties
12178
12740
  );
12741
+ const getComputedAttributes = Object.keys(fieldParams.computedAttributes).length > 0 && calculateComputedAttributes(fieldParams, config);
12179
12742
  const hasCustomValidations = !!customProperties && (0, import_size.default)((0, import_pick2.default)(customProperties, SUPPORTED_CUSTOM_VALIDATION_FIELD_PARAMS)) > 0;
12180
12743
  const finalFieldParams = {
12181
12744
  // invalid attribute cleanup
@@ -12188,6 +12751,7 @@ function buildField(fieldParams, config, scopedJsonSchema) {
12188
12751
  ...hasCustomValidations && {
12189
12752
  calculateCustomValidationProperties: calculateCustomValidationPropertiesClosure
12190
12753
  },
12754
+ ...getComputedAttributes && { getComputedAttributes },
12191
12755
  // field customization properties
12192
12756
  ...customProperties && { fieldCustomization: customProperties },
12193
12757
  // base schema
@@ -12196,7 +12760,7 @@ function buildField(fieldParams, config, scopedJsonSchema) {
12196
12760
  };
12197
12761
  return composeFn(finalFieldParams);
12198
12762
  }
12199
- function getFieldsFromJSONSchema(scopedJsonSchema, config) {
12763
+ function getFieldsFromJSONSchema(scopedJsonSchema, config, logic) {
12200
12764
  if (!scopedJsonSchema) {
12201
12765
  return [];
12202
12766
  }
@@ -12220,11 +12784,11 @@ function getFieldsFromJSONSchema(scopedJsonSchema, config) {
12220
12784
  fields: () => groupArrayFields,
12221
12785
  addFieldText: fieldParams.addFieldText
12222
12786
  };
12223
- buildField(fieldParams, config, scopedJsonSchema).forEach((groupField) => {
12787
+ buildField(fieldParams, config, scopedJsonSchema, logic).forEach((groupField) => {
12224
12788
  fields.push(groupField);
12225
12789
  });
12226
12790
  } else {
12227
- fields.push(buildField(fieldParams, config, scopedJsonSchema));
12791
+ fields.push(buildField(fieldParams, config, scopedJsonSchema, logic));
12228
12792
  }
12229
12793
  });
12230
12794
  return fields;
@@ -12235,9 +12799,15 @@ function createHeadlessForm(jsonSchema, customConfig = {}) {
12235
12799
  ...customConfig
12236
12800
  };
12237
12801
  try {
12238
- const fields = getFieldsFromJSONSchema(jsonSchema, config);
12239
- const handleValidation = handleValuesChange(fields, jsonSchema, config);
12240
- updateFieldsProperties(fields, getPrefillValues(fields, config.initialValues), jsonSchema);
12802
+ const logic = createValidationChecker(jsonSchema);
12803
+ const fields = getFieldsFromJSONSchema(jsonSchema, config, logic);
12804
+ const handleValidation = handleValuesChange(fields, jsonSchema, config, logic);
12805
+ updateFieldsProperties(
12806
+ fields,
12807
+ getPrefillValues(fields, config.initialValues),
12808
+ jsonSchema,
12809
+ logic
12810
+ );
12241
12811
  return {
12242
12812
  fields,
12243
12813
  handleValidation,