UNPKG

@snups/rjsf-utils

Version:
1,421 lines (1,392 loc) 133 kB
"use strict"; var __create = Object.create; var __defProp = Object.defineProperty; var __getOwnPropDesc = Object.getOwnPropertyDescriptor; var __getOwnPropNames = Object.getOwnPropertyNames; var __getProtoOf = Object.getPrototypeOf; var __hasOwnProp = Object.prototype.hasOwnProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true }); }; var __copyProps = (to, from, except, desc) => { if (from && typeof from === "object" || typeof from === "function") { for (let key of __getOwnPropNames(from)) if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); } return to; }; var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( // If the importer is in node compatibility mode or this is not an ESM // file that has been converted to a CommonJS file using a Babel- // compatible transform (i.e. "__esModule" has not been set), then set // "default" to the CommonJS "module.exports" for node compatibility. isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, mod )); var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); // src/index.ts var index_exports = {}; __export(index_exports, { ADDITIONAL_PROPERTIES_KEY: () => ADDITIONAL_PROPERTIES_KEY, ADDITIONAL_PROPERTY_FLAG: () => ADDITIONAL_PROPERTY_FLAG, ALL_OF_KEY: () => ALL_OF_KEY, ANY_OF_KEY: () => ANY_OF_KEY, CONST_KEY: () => CONST_KEY, DEFAULT_KEY: () => DEFAULT_KEY, DEFINITIONS_KEY: () => DEFINITIONS_KEY, DEPENDENCIES_KEY: () => DEPENDENCIES_KEY, DISCRIMINATOR_PATH: () => DISCRIMINATOR_PATH, ENUM_KEY: () => ENUM_KEY, ERRORS_KEY: () => ERRORS_KEY, ErrorSchemaBuilder: () => ErrorSchemaBuilder, FORM_CONTEXT_NAME: () => FORM_CONTEXT_NAME, ID_KEY: () => ID_KEY, IF_KEY: () => IF_KEY, ITEMS_KEY: () => ITEMS_KEY, JSON_SCHEMA_DRAFT_2019_09: () => JSON_SCHEMA_DRAFT_2019_09, JSON_SCHEMA_DRAFT_2020_12: () => JSON_SCHEMA_DRAFT_2020_12, JUNK_OPTION_ID: () => JUNK_OPTION_ID, LOOKUP_MAP_NAME: () => LOOKUP_MAP_NAME, NAME_KEY: () => NAME_KEY, ONE_OF_KEY: () => ONE_OF_KEY, PATTERN_PROPERTIES_KEY: () => PATTERN_PROPERTIES_KEY, PROPERTIES_KEY: () => PROPERTIES_KEY, READONLY_KEY: () => READONLY_KEY, REF_KEY: () => REF_KEY, REQUIRED_KEY: () => REQUIRED_KEY, RJSF_ADDITIONAL_PROPERTIES_FLAG: () => RJSF_ADDITIONAL_PROPERTIES_FLAG, ROOT_SCHEMA_PREFIX: () => ROOT_SCHEMA_PREFIX, SCHEMA_KEY: () => SCHEMA_KEY, SUBMIT_BTN_OPTIONS_KEY: () => SUBMIT_BTN_OPTIONS_KEY, TranslatableString: () => TranslatableString, UI_FIELD_KEY: () => UI_FIELD_KEY, UI_GLOBAL_OPTIONS_KEY: () => UI_GLOBAL_OPTIONS_KEY, UI_OPTIONS_KEY: () => UI_OPTIONS_KEY, UI_WIDGET_KEY: () => UI_WIDGET_KEY, allowAdditionalItems: () => allowAdditionalItems, ariaDescribedByIds: () => ariaDescribedByIds, asNumber: () => asNumber, buttonId: () => buttonId, canExpand: () => canExpand, createErrorHandler: () => createErrorHandler, createSchemaUtils: () => createSchemaUtils, dataURItoBlob: () => dataURItoBlob, dateRangeOptions: () => dateRangeOptions, deepEquals: () => deepEquals, descriptionId: () => descriptionId, englishStringTranslator: () => englishStringTranslator, enumOptionsDeselectValue: () => enumOptionsDeselectValue, enumOptionsIndexForValue: () => enumOptionsIndexForValue, enumOptionsIsSelected: () => enumOptionsIsSelected, enumOptionsSelectValue: () => enumOptionsSelectValue, enumOptionsValueForIndex: () => enumOptionsValueForIndex, errorId: () => errorId, examplesId: () => examplesId, findFieldInSchema: () => findFieldInSchema, findSchemaDefinition: () => findSchemaDefinition, findSelectedOptionInXxxOf: () => findSelectedOptionInXxxOf, getChangedFields: () => getChangedFields, getClosestMatchingOption: () => getClosestMatchingOption, getDateElementProps: () => getDateElementProps, getDefaultFormState: () => getDefaultFormState, getDiscriminatorFieldFromSchema: () => getDiscriminatorFieldFromSchema, getDisplayLabel: () => getDisplayLabel, getFirstMatchingOption: () => getFirstMatchingOption, getFromSchema: () => getFromSchema, getInputProps: () => getInputProps, getOptionMatchingSimpleDiscriminator: () => getOptionMatchingSimpleDiscriminator, getSchemaType: () => getSchemaType, getSubmitButtonOptions: () => getSubmitButtonOptions, getTemplate: () => getTemplate, getTestIds: () => getTestIds, getUiOptions: () => getUiOptions, getWidget: () => getWidget, guessType: () => guessType, hasWidget: () => hasWidget, hashForSchema: () => hashForSchema, hashObject: () => hashObject, hashString: () => hashString, helpId: () => helpId, isConstant: () => isConstant, isCustomWidget: () => isCustomWidget, isFilesArray: () => isFilesArray, isFixedItems: () => isFixedItems, isMultiSelect: () => isMultiSelect, isObject: () => isObject, isSelect: () => isSelect, labelValue: () => labelValue, localToUTC: () => localToUTC, lookupFromFormContext: () => lookupFromFormContext, mergeDefaultsWithFormData: () => mergeDefaultsWithFormData, mergeObjects: () => mergeObjects, mergeSchemas: () => mergeSchemas, optionId: () => optionId, optionsList: () => optionsList, orderProperties: () => orderProperties, pad: () => pad, parseDateString: () => parseDateString, rangeSpec: () => rangeSpec, replaceStringParameters: () => replaceStringParameters, retrieveSchema: () => retrieveSchema, sanitizeDataForNewSchema: () => sanitizeDataForNewSchema, schemaParser: () => schemaParser, schemaRequiresTrueValue: () => schemaRequiresTrueValue, shallowEquals: () => shallowEquals, shouldRender: () => shouldRender, sortedJSONStringify: () => sortedJSONStringify, titleId: () => titleId, toConstant: () => toConstant, toDateString: () => toDateString, toErrorList: () => toErrorList, toErrorSchema: () => toErrorSchema, toIdSchema: () => toIdSchema, toPathSchema: () => toPathSchema, unwrapErrorHandler: () => unwrapErrorHandler, utcToLocal: () => utcToLocal, validationDataMerge: () => validationDataMerge, withIdRefPrefix: () => withIdRefPrefix }); module.exports = __toCommonJS(index_exports); // src/isObject.ts function isObject(thing) { if (typeof thing !== "object" || thing === null) { return false; } if (typeof thing.lastModified === "number" && typeof File !== "undefined" && thing instanceof File) { return false; } if (typeof thing.getMonth === "function" && typeof Date !== "undefined" && thing instanceof Date) { return false; } return !Array.isArray(thing); } // src/allowAdditionalItems.ts function allowAdditionalItems(schema) { if (schema.additionalItems === true) { console.warn("additionalItems=true is currently not supported"); } return isObject(schema.additionalItems); } // src/asNumber.ts function asNumber(value) { if (value === "") { return void 0; } if (value === null) { return null; } if (/\.$/.test(value)) { return value; } if (/\.0$/.test(value)) { return value; } if (/\.\d*0$/.test(value)) { return value; } const n = Number(value); const valid = typeof n === "number" && !Number.isNaN(n); return valid ? n : value; } // src/constants.ts var ADDITIONAL_PROPERTY_FLAG = "__additional_property"; var ADDITIONAL_PROPERTIES_KEY = "additionalProperties"; var ALL_OF_KEY = "allOf"; var ANY_OF_KEY = "anyOf"; var CONST_KEY = "const"; var DEFAULT_KEY = "default"; var DEFINITIONS_KEY = "definitions"; var DEPENDENCIES_KEY = "dependencies"; var ENUM_KEY = "enum"; var ERRORS_KEY = "__errors"; var ID_KEY = "$id"; var IF_KEY = "if"; var ITEMS_KEY = "items"; var JUNK_OPTION_ID = "_$junk_option_schema_id$_"; var NAME_KEY = "$name"; var ONE_OF_KEY = "oneOf"; var PATTERN_PROPERTIES_KEY = "patternProperties"; var PROPERTIES_KEY = "properties"; var READONLY_KEY = "readonly"; var REQUIRED_KEY = "required"; var SUBMIT_BTN_OPTIONS_KEY = "submitButtonOptions"; var REF_KEY = "$ref"; var SCHEMA_KEY = "$schema"; var DISCRIMINATOR_PATH = ["discriminator", "propertyName"]; var FORM_CONTEXT_NAME = "formContext"; var LOOKUP_MAP_NAME = "layoutGridLookupMap"; var RJSF_ADDITIONAL_PROPERTIES_FLAG = "__rjsf_additionalProperties"; var ROOT_SCHEMA_PREFIX = "__rjsf_rootSchema"; var UI_FIELD_KEY = "ui:field"; var UI_WIDGET_KEY = "ui:widget"; var UI_OPTIONS_KEY = "ui:options"; var UI_GLOBAL_OPTIONS_KEY = "ui:globalOptions"; var JSON_SCHEMA_DRAFT_2019_09 = "https://json-schema.org/draft/2019-09/schema"; var JSON_SCHEMA_DRAFT_2020_12 = "https://json-schema.org/draft/2020-12/schema"; // src/getUiOptions.ts function getUiOptions(uiSchema = {}, globalOptions = {}) { if (!uiSchema) { return { ...globalOptions }; } return Object.keys(uiSchema).filter((key) => key.indexOf("ui:") === 0).reduce( (options, key) => { const value = uiSchema[key]; if (key === UI_WIDGET_KEY && isObject(value)) { console.error("Setting options via ui:widget object is no longer supported, use ui:options instead"); return options; } if (key === UI_OPTIONS_KEY && isObject(value)) { return { ...options, ...value }; } return { ...options, [key.substring(3)]: value }; }, { ...globalOptions } ); } // src/canExpand.ts function canExpand(schema, uiSchema = {}, formData) { if (!(schema.additionalProperties || schema.patternProperties)) { return false; } const { expandable = true } = getUiOptions(uiSchema); if (expandable === false) { return expandable; } if (schema.maxProperties !== void 0 && formData) { return Object.keys(formData).length < schema.maxProperties; } return true; } // src/createErrorHandler.ts var import_isPlainObject = __toESM(require("lodash/isPlainObject")); function createErrorHandler(formData) { const handler = { // We store the list of errors for this node in a property named __errors // to avoid name collision with a possible sub schema field named // 'errors' (see `utils.toErrorSchema`). [ERRORS_KEY]: [], addError(message) { this[ERRORS_KEY].push(message); } }; if (Array.isArray(formData)) { return formData.reduce((acc, value, key) => { return { ...acc, [key]: createErrorHandler(value) }; }, handler); } if ((0, import_isPlainObject.default)(formData)) { const formObject = formData; return Object.keys(formObject).reduce((acc, key) => { return { ...acc, [key]: createErrorHandler(formObject[key]) }; }, handler); } return handler; } // src/deepEquals.ts var import_isEqualWith = __toESM(require("lodash/isEqualWith")); function deepEquals(a, b) { return (0, import_isEqualWith.default)(a, b, (obj, other) => { if (typeof obj === "function" && typeof other === "function") { return true; } return void 0; }); } // src/schema/findFieldInSchema.ts var import_get8 = __toESM(require("lodash/get")); var import_has3 = __toESM(require("lodash/has")); // src/schema/findSelectedOptionInXxxOf.ts var import_get6 = __toESM(require("lodash/get")); var import_isEqual = __toESM(require("lodash/isEqual")); // src/schema/retrieveSchema.ts var import_get5 = __toESM(require("lodash/get")); var import_set = __toESM(require("lodash/set")); var import_times = __toESM(require("lodash/times")); var import_transform = __toESM(require("lodash/transform")); var import_merge = __toESM(require("lodash/merge")); var import_flattenDeep = __toESM(require("lodash/flattenDeep")); var import_uniq = __toESM(require("lodash/uniq")); var import_json_schema_merge_allof = __toESM(require("json-schema-merge-allof")); // src/findSchemaDefinition.ts var import_jsonpointer = __toESM(require("jsonpointer")); var import_omit = __toESM(require("lodash/omit")); var import_isObject3 = __toESM(require("lodash/isObject")); var import_isEmpty = __toESM(require("lodash/isEmpty")); var import_fast_uri = __toESM(require("fast-uri")); var import_get = __toESM(require("lodash/get")); function findEmbeddedSchemaRecursive(schema, ref) { if (ID_KEY in schema && import_fast_uri.default.equal(schema[ID_KEY], ref)) { return schema; } for (const subSchema of Object.values(schema)) { if (Array.isArray(subSchema)) { for (const item of subSchema) { if ((0, import_isObject3.default)(item)) { const result = findEmbeddedSchemaRecursive(item, ref); if (result !== void 0) { return result; } } } } else if ((0, import_isObject3.default)(subSchema)) { const result = findEmbeddedSchemaRecursive(subSchema, ref); if (result !== void 0) { return result; } } } return void 0; } function makeAllReferencesAbsolute(schema, baseURI) { const currentURI = (0, import_get.default)(schema, ID_KEY, baseURI); if (REF_KEY in schema) { schema = { ...schema, [REF_KEY]: import_fast_uri.default.resolve(currentURI, schema[REF_KEY]) }; } for (const [key, subSchema] of Object.entries(schema)) { if (Array.isArray(subSchema)) { schema = { ...schema, [key]: subSchema.map((item) => (0, import_isObject3.default)(item) ? makeAllReferencesAbsolute(item, currentURI) : item) }; } else if ((0, import_isObject3.default)(subSchema)) { schema = { ...schema, [key]: makeAllReferencesAbsolute(subSchema, currentURI) }; } } return schema; } function splitKeyElementFromObject(key, object) { const value = object[key]; const remaining = (0, import_omit.default)(object, [key]); return [remaining, value]; } function findSchemaDefinitionRecursive($ref, rootSchema = {}, recurseList = [], baseURI = (0, import_get.default)(rootSchema, [ID_KEY])) { const ref = $ref || ""; let current = void 0; if (ref.startsWith("#")) { const decodedRef = decodeURIComponent(ref.substring(1)); if (baseURI === void 0 || ID_KEY in rootSchema && rootSchema[ID_KEY] === baseURI) { current = import_jsonpointer.default.get(rootSchema, decodedRef); } else if (rootSchema[SCHEMA_KEY] === JSON_SCHEMA_DRAFT_2020_12) { current = findEmbeddedSchemaRecursive(rootSchema, baseURI.replace(/\/$/, "")); if (current !== void 0) { current = import_jsonpointer.default.get(current, decodedRef); } } } else if (rootSchema[SCHEMA_KEY] === JSON_SCHEMA_DRAFT_2020_12) { const resolvedRef = baseURI ? import_fast_uri.default.resolve(baseURI, ref) : ref; const [refId, ...refAnchor] = resolvedRef.replace(/#\/?$/, "").split("#"); current = findEmbeddedSchemaRecursive(rootSchema, refId.replace(/\/$/, "")); if (current !== void 0) { baseURI = current[ID_KEY]; if (!(0, import_isEmpty.default)(refAnchor)) { current = import_jsonpointer.default.get(current, decodeURIComponent(refAnchor.join("#"))); } } } if (current === void 0) { throw new Error(`Could not find a definition for ${$ref}.`); } const nextRef = current[REF_KEY]; if (nextRef) { if (recurseList.includes(nextRef)) { if (recurseList.length === 1) { throw new Error(`Definition for ${$ref} is a circular reference`); } const [firstRef, ...restRefs] = recurseList; const circularPath = [...restRefs, ref, firstRef].join(" -> "); throw new Error(`Definition for ${firstRef} contains a circular reference through ${circularPath}`); } const [remaining, theRef] = splitKeyElementFromObject(REF_KEY, current); const subSchema = findSchemaDefinitionRecursive(theRef, rootSchema, [...recurseList, ref], baseURI); if (Object.keys(remaining).length > 0) { if (rootSchema[SCHEMA_KEY] === JSON_SCHEMA_DRAFT_2019_09 || rootSchema[SCHEMA_KEY] === JSON_SCHEMA_DRAFT_2020_12) { return { [ALL_OF_KEY]: [remaining, subSchema] }; } else { return { ...remaining, ...subSchema }; } } return subSchema; } return current; } function findSchemaDefinition($ref, rootSchema = {}, baseURI = (0, import_get.default)(rootSchema, [ID_KEY])) { const recurseList = []; return findSchemaDefinitionRecursive($ref, rootSchema, recurseList, baseURI); } // src/getDiscriminatorFieldFromSchema.ts var import_get2 = __toESM(require("lodash/get")); var import_isString = __toESM(require("lodash/isString")); function getDiscriminatorFieldFromSchema(schema) { let discriminator; const maybeString = (0, import_get2.default)(schema, DISCRIMINATOR_PATH); if ((0, import_isString.default)(maybeString)) { discriminator = maybeString; } else if (maybeString !== void 0) { console.warn(`Expecting discriminator to be a string, got "${typeof maybeString}" instead`); } return discriminator; } // src/guessType.ts function guessType(value) { if (Array.isArray(value)) { return "array"; } if (typeof value === "string") { return "string"; } if (value == null) { return "null"; } if (typeof value === "boolean") { return "boolean"; } if (!isNaN(value)) { return "number"; } if (typeof value === "object") { return "object"; } return "string"; } // src/mergeSchemas.ts var import_union = __toESM(require("lodash/union")); // src/getSchemaType.ts function getSchemaType(schema) { let { type } = schema; if (!type && schema.const) { return guessType(schema.const); } if (!type && schema.enum) { return "string"; } if (!type && (schema.properties || schema.additionalProperties || schema.patternProperties)) { return "object"; } if (Array.isArray(type)) { if (type.length === 2 && type.includes("null")) { type = type.find((type2) => type2 !== "null"); } else { type = type[0]; } } return type; } // src/mergeSchemas.ts function mergeSchemas(obj1, obj2) { const acc = Object.assign({}, obj1); return Object.keys(obj2).reduce((acc2, key) => { const left = obj1 ? obj1[key] : {}, right = obj2[key]; if (obj1 && key in obj1 && isObject(right)) { acc2[key] = mergeSchemas(left, right); } else if (obj1 && obj2 && (getSchemaType(obj1) === "object" || getSchemaType(obj2) === "object") && key === REQUIRED_KEY && Array.isArray(left) && Array.isArray(right)) { acc2[key] = (0, import_union.default)(left, right); } else { acc2[key] = right; } return acc2; }, acc); } // src/schema/getFirstMatchingOption.ts var import_get4 = __toESM(require("lodash/get")); var import_has = __toESM(require("lodash/has")); var import_isNumber = __toESM(require("lodash/isNumber")); // src/getOptionMatchingSimpleDiscriminator.ts var import_get3 = __toESM(require("lodash/get")); function getOptionMatchingSimpleDiscriminator(formData, options, discriminatorField) { if (formData && discriminatorField) { const value = (0, import_get3.default)(formData, discriminatorField); if (value === void 0) { return; } for (let i = 0; i < options.length; i++) { const option = options[i]; const discriminator = (0, import_get3.default)(option, [PROPERTIES_KEY, discriminatorField], {}); if (discriminator.type === "object" || discriminator.type === "array") { continue; } if (discriminator.const === value) { return i; } if (discriminator.enum?.includes(value)) { return i; } } } return; } // src/schema/getFirstMatchingOption.ts function getFirstMatchingOption(validator, formData, options, rootSchema, discriminatorField) { if (formData === void 0) { return 0; } const simpleDiscriminatorMatch = getOptionMatchingSimpleDiscriminator(formData, options, discriminatorField); if ((0, import_isNumber.default)(simpleDiscriminatorMatch)) { return simpleDiscriminatorMatch; } for (let i = 0; i < options.length; i++) { const option = options[i]; if (discriminatorField && (0, import_has.default)(option, [PROPERTIES_KEY, discriminatorField])) { const value = (0, import_get4.default)(formData, discriminatorField); const discriminator = (0, import_get4.default)(option, [PROPERTIES_KEY, discriminatorField], {}); if (validator.isValid(discriminator, value, rootSchema)) { return i; } } else if (option[PROPERTIES_KEY]) { const requiresAnyOf = { anyOf: Object.keys(option[PROPERTIES_KEY]).map((key) => ({ required: [key] })) }; let augmentedSchema; if (option.anyOf) { const { ...shallowClone } = option; if (!shallowClone.allOf) { shallowClone.allOf = []; } else { shallowClone.allOf = shallowClone.allOf.slice(); } shallowClone.allOf.push(requiresAnyOf); augmentedSchema = shallowClone; } else { augmentedSchema = Object.assign({}, option, requiresAnyOf); } delete augmentedSchema.required; if (validator.isValid(augmentedSchema, formData, rootSchema)) { return i; } } else if (validator.isValid(option, formData, rootSchema)) { return i; } } return 0; } // src/schema/retrieveSchema.ts var import_isEmpty2 = __toESM(require("lodash/isEmpty")); function retrieveSchema(validator, schema, rootSchema = {}, rawFormData, experimental_customMergeAllOf) { return retrieveSchemaInternal( validator, schema, rootSchema, rawFormData, void 0, void 0, experimental_customMergeAllOf )[0]; } function resolveCondition(validator, schema, rootSchema, expandAllBranches, recurseList, formData, experimental_customMergeAllOf) { const { if: expression, then, else: otherwise, ...resolvedSchemaLessConditional } = schema; const conditionValue = validator.isValid(expression, formData || {}, rootSchema); let resolvedSchemas = [resolvedSchemaLessConditional]; let schemas = []; if (expandAllBranches) { if (then && typeof then !== "boolean") { schemas = schemas.concat( retrieveSchemaInternal( validator, then, rootSchema, formData, expandAllBranches, recurseList, experimental_customMergeAllOf ) ); } if (otherwise && typeof otherwise !== "boolean") { schemas = schemas.concat( retrieveSchemaInternal( validator, otherwise, rootSchema, formData, expandAllBranches, recurseList, experimental_customMergeAllOf ) ); } } else { const conditionalSchema = conditionValue ? then : otherwise; if (conditionalSchema && typeof conditionalSchema !== "boolean") { schemas = schemas.concat( retrieveSchemaInternal( validator, conditionalSchema, rootSchema, formData, expandAllBranches, recurseList, experimental_customMergeAllOf ) ); } } if (schemas.length) { resolvedSchemas = schemas.map((s) => mergeSchemas(resolvedSchemaLessConditional, s)); } return resolvedSchemas.flatMap( (s) => retrieveSchemaInternal( validator, s, rootSchema, formData, expandAllBranches, recurseList, experimental_customMergeAllOf ) ); } function getAllPermutationsOfXxxOf(listOfLists) { const allPermutations = listOfLists.reduce( (permutations, list) => { if (list.length > 1) { return list.flatMap((element) => (0, import_times.default)(permutations.length, (i) => [...permutations[i]].concat(element))); } permutations.forEach((permutation) => permutation.push(list[0])); return permutations; }, [[]] // Start with an empty list ); return allPermutations; } function getMatchingPatternProperties(schema, key) { return Object.keys(schema.patternProperties).filter((pattern) => RegExp(pattern).test(key)).reduce( (obj, pattern) => { (0, import_set.default)(obj, [pattern], schema.patternProperties[pattern]); return obj; }, {} ); } function resolveSchema(validator, schema, rootSchema, expandAllBranches, recurseList, formData, experimental_customMergeAllOf) { const updatedSchemas = resolveReference( validator, schema, rootSchema, expandAllBranches, recurseList, formData ); if (updatedSchemas.length > 1 || updatedSchemas[0] !== schema) { return updatedSchemas; } if (DEPENDENCIES_KEY in schema) { const resolvedSchemas = resolveDependencies( validator, schema, rootSchema, expandAllBranches, recurseList, formData ); return resolvedSchemas.flatMap((s) => { return retrieveSchemaInternal( validator, s, rootSchema, formData, expandAllBranches, recurseList, experimental_customMergeAllOf ); }); } if (ALL_OF_KEY in schema && Array.isArray(schema.allOf)) { const allOfSchemaElements = schema.allOf.map( (allOfSubschema) => retrieveSchemaInternal( validator, allOfSubschema, rootSchema, formData, expandAllBranches, recurseList, experimental_customMergeAllOf ) ); const allPermutations = getAllPermutationsOfXxxOf(allOfSchemaElements); return allPermutations.map((permutation) => ({ ...schema, allOf: permutation })); } return [schema]; } function resolveReference(validator, schema, rootSchema, expandAllBranches, recurseList, formData, experimental_customMergeAllOf) { const updatedSchema = resolveAllReferences(schema, rootSchema, recurseList); if (updatedSchema !== schema) { return retrieveSchemaInternal( validator, updatedSchema, rootSchema, formData, expandAllBranches, recurseList, experimental_customMergeAllOf ); } return [schema]; } function resolveAllReferences(schema, rootSchema, recurseList, baseURI) { if (!isObject(schema)) { return schema; } let resolvedSchema = schema; if (REF_KEY in resolvedSchema) { const { $ref, ...localSchema } = resolvedSchema; if (recurseList.includes($ref)) { return resolvedSchema; } recurseList.push($ref); const refSchema = findSchemaDefinition($ref, rootSchema, baseURI); resolvedSchema = { ...refSchema, ...localSchema }; if (ID_KEY in resolvedSchema) { baseURI = resolvedSchema[ID_KEY]; } } if (PROPERTIES_KEY in resolvedSchema) { const childrenLists = []; const updatedProps = (0, import_transform.default)( resolvedSchema[PROPERTIES_KEY], (result, value, key) => { const childList = [...recurseList]; result[key] = resolveAllReferences(value, rootSchema, childList, baseURI); childrenLists.push(childList); }, {} ); (0, import_merge.default)(recurseList, (0, import_uniq.default)((0, import_flattenDeep.default)(childrenLists))); resolvedSchema = { ...resolvedSchema, [PROPERTIES_KEY]: updatedProps }; } if (ITEMS_KEY in resolvedSchema && !Array.isArray(resolvedSchema.items) && typeof resolvedSchema.items !== "boolean") { resolvedSchema = { ...resolvedSchema, items: resolveAllReferences(resolvedSchema.items, rootSchema, recurseList, baseURI) }; } return deepEquals(schema, resolvedSchema) ? schema : resolvedSchema; } function stubExistingAdditionalProperties(validator, theSchema, rootSchema, aFormData, experimental_customMergeAllOf) { const schema = { ...theSchema, properties: { ...theSchema.properties } }; const formData = aFormData && isObject(aFormData) ? aFormData : {}; Object.keys(formData).forEach((key) => { if (key in schema.properties) { return; } if (PATTERN_PROPERTIES_KEY in schema) { const matchingProperties = getMatchingPatternProperties(schema, key); if (!(0, import_isEmpty2.default)(matchingProperties)) { schema.properties[key] = retrieveSchema( validator, { [ALL_OF_KEY]: Object.values(matchingProperties) }, rootSchema, (0, import_get5.default)(formData, [key]), experimental_customMergeAllOf ); (0, import_set.default)(schema.properties, [key, ADDITIONAL_PROPERTY_FLAG], true); return; } } if (ADDITIONAL_PROPERTIES_KEY in schema && schema.additionalProperties !== false) { let additionalProperties = {}; if (typeof schema.additionalProperties !== "boolean") { if (REF_KEY in schema.additionalProperties) { additionalProperties = retrieveSchema( validator, { [REF_KEY]: (0, import_get5.default)(schema.additionalProperties, [REF_KEY]) }, rootSchema, formData, experimental_customMergeAllOf ); } else if ("type" in schema.additionalProperties) { additionalProperties = { ...schema.additionalProperties }; } else if (ANY_OF_KEY in schema.additionalProperties || ONE_OF_KEY in schema.additionalProperties) { additionalProperties = { type: "object", ...schema.additionalProperties }; } else { additionalProperties = { type: guessType((0, import_get5.default)(formData, [key])) }; } } else { additionalProperties = { type: guessType((0, import_get5.default)(formData, [key])) }; } schema.properties[key] = additionalProperties; (0, import_set.default)(schema.properties, [key, ADDITIONAL_PROPERTY_FLAG], true); } else { schema.properties[key] = { type: "null" }; (0, import_set.default)(schema.properties, [key, ADDITIONAL_PROPERTY_FLAG], true); } }); return schema; } function retrieveSchemaInternal(validator, schema, rootSchema, rawFormData, expandAllBranches = false, recurseList = [], experimental_customMergeAllOf) { if (!isObject(schema)) { return [{}]; } const resolvedSchemas = resolveSchema( validator, schema, rootSchema, expandAllBranches, recurseList, rawFormData, experimental_customMergeAllOf ); return resolvedSchemas.flatMap((s) => { let resolvedSchema = s; if (IF_KEY in resolvedSchema) { return resolveCondition( validator, resolvedSchema, rootSchema, expandAllBranches, recurseList, rawFormData, experimental_customMergeAllOf ); } if (ALL_OF_KEY in resolvedSchema) { if (expandAllBranches) { const { allOf, ...restOfSchema } = resolvedSchema; return [...allOf, restOfSchema]; } try { const withContainsSchemas = []; const withoutContainsSchemas = []; resolvedSchema.allOf?.forEach((s2) => { if (typeof s2 === "object" && s2.contains) { withContainsSchemas.push(s2); } else { withoutContainsSchemas.push(s2); } }); if (withContainsSchemas.length) { resolvedSchema = { ...resolvedSchema, allOf: withoutContainsSchemas }; } resolvedSchema = experimental_customMergeAllOf ? experimental_customMergeAllOf(resolvedSchema) : (0, import_json_schema_merge_allof.default)(resolvedSchema, { deep: false, resolvers: { $defs: import_json_schema_merge_allof.default.options.resolvers.definitions } }); if (withContainsSchemas.length) { resolvedSchema.allOf = withContainsSchemas; } } catch (e) { console.warn("could not merge subschemas in allOf:\n", e); const { allOf, ...resolvedSchemaWithoutAllOf } = resolvedSchema; return resolvedSchemaWithoutAllOf; } } if (PROPERTIES_KEY in resolvedSchema && PATTERN_PROPERTIES_KEY in resolvedSchema) { resolvedSchema = Object.keys(resolvedSchema.properties).reduce( (schema2, key) => { const matchingProperties = getMatchingPatternProperties(schema2, key); if (!(0, import_isEmpty2.default)(matchingProperties)) { schema2.properties[key] = retrieveSchema( validator, { allOf: [schema2.properties[key], ...Object.values(matchingProperties)] }, rootSchema, (0, import_get5.default)(rawFormData, [key]), experimental_customMergeAllOf ); } return schema2; }, { ...resolvedSchema, properties: { ...resolvedSchema.properties } } ); } const hasAdditionalProperties = PATTERN_PROPERTIES_KEY in resolvedSchema || ADDITIONAL_PROPERTIES_KEY in resolvedSchema && resolvedSchema.additionalProperties !== false; if (hasAdditionalProperties) { return stubExistingAdditionalProperties( validator, resolvedSchema, rootSchema, rawFormData, experimental_customMergeAllOf ); } return resolvedSchema; }); } function resolveAnyOrOneOfSchemas(validator, schema, rootSchema, expandAllBranches, rawFormData) { let anyOrOneOf; const { oneOf, anyOf, ...remaining } = schema; if (Array.isArray(oneOf)) { anyOrOneOf = oneOf; } else if (Array.isArray(anyOf)) { anyOrOneOf = anyOf; } if (anyOrOneOf) { const formData = rawFormData === void 0 && expandAllBranches ? {} : rawFormData; const discriminator = getDiscriminatorFieldFromSchema(schema); anyOrOneOf = anyOrOneOf.map((s) => { return resolveAllReferences(s, rootSchema, []); }); const option = getFirstMatchingOption(validator, formData, anyOrOneOf, rootSchema, discriminator); if (expandAllBranches) { return anyOrOneOf.map((item) => mergeSchemas(remaining, item)); } schema = mergeSchemas(remaining, anyOrOneOf[option]); } return [schema]; } function resolveDependencies(validator, schema, rootSchema, expandAllBranches, recurseList, formData, experimental_customMergeAllOf) { const { dependencies, ...remainingSchema } = schema; const resolvedSchemas = resolveAnyOrOneOfSchemas( validator, remainingSchema, rootSchema, expandAllBranches, formData ); return resolvedSchemas.flatMap( (resolvedSchema) => processDependencies( validator, dependencies, resolvedSchema, rootSchema, expandAllBranches, recurseList, formData, experimental_customMergeAllOf ) ); } function processDependencies(validator, dependencies, resolvedSchema, rootSchema, expandAllBranches, recurseList, formData, experimental_customMergeAllOf) { let schemas = [resolvedSchema]; for (const dependencyKey in dependencies) { if (!expandAllBranches && (0, import_get5.default)(formData, [dependencyKey]) === void 0) { continue; } if (resolvedSchema.properties && !(dependencyKey in resolvedSchema.properties)) { continue; } const [remainingDependencies, dependencyValue] = splitKeyElementFromObject( dependencyKey, dependencies ); if (Array.isArray(dependencyValue)) { schemas[0] = withDependentProperties(resolvedSchema, dependencyValue); } else if (isObject(dependencyValue)) { schemas = withDependentSchema( validator, resolvedSchema, rootSchema, dependencyKey, dependencyValue, expandAllBranches, recurseList, formData, experimental_customMergeAllOf ); } return schemas.flatMap( (schema) => processDependencies( validator, remainingDependencies, schema, rootSchema, expandAllBranches, recurseList, formData, experimental_customMergeAllOf ) ); } return schemas; } function withDependentProperties(schema, additionallyRequired) { if (!additionallyRequired) { return schema; } const required = Array.isArray(schema.required) ? Array.from(/* @__PURE__ */ new Set([...schema.required, ...additionallyRequired])) : additionallyRequired; return { ...schema, required }; } function withDependentSchema(validator, schema, rootSchema, dependencyKey, dependencyValue, expandAllBranches, recurseList, formData, experimental_customMergeAllOf) { const dependentSchemas = retrieveSchemaInternal( validator, dependencyValue, rootSchema, formData, expandAllBranches, recurseList, experimental_customMergeAllOf ); return dependentSchemas.flatMap((dependent) => { const { oneOf, ...dependentSchema } = dependent; schema = mergeSchemas(schema, dependentSchema); if (oneOf === void 0) { return schema; } const resolvedOneOfs = oneOf.map((subschema) => { if (typeof subschema === "boolean" || !(REF_KEY in subschema)) { return [subschema]; } return resolveReference(validator, subschema, rootSchema, expandAllBranches, recurseList, formData); }); const allPermutations = getAllPermutationsOfXxxOf(resolvedOneOfs); return allPermutations.flatMap( (resolvedOneOf) => withExactlyOneSubschema( validator, schema, rootSchema, dependencyKey, resolvedOneOf, expandAllBranches, recurseList, formData, experimental_customMergeAllOf ) ); }); } function withExactlyOneSubschema(validator, schema, rootSchema, dependencyKey, oneOf, expandAllBranches, recurseList, formData, experimental_customMergeAllOf) { const validSubschemas = oneOf.filter((subschema) => { if (typeof subschema === "boolean" || !subschema || !subschema.properties) { return false; } const { [dependencyKey]: conditionPropertySchema } = subschema.properties; if (conditionPropertySchema) { const conditionSchema = { type: "object", properties: { [dependencyKey]: conditionPropertySchema } }; return validator.isValid(conditionSchema, formData, rootSchema) || expandAllBranches; } return false; }); if (!expandAllBranches && validSubschemas.length !== 1) { console.warn("ignoring oneOf in dependencies because there isn't exactly one subschema that is valid"); return [schema]; } return validSubschemas.flatMap((s) => { const subschema = s; const [dependentSubschema] = splitKeyElementFromObject(dependencyKey, subschema.properties); const dependentSchema = { ...subschema, properties: dependentSubschema }; const schemas = retrieveSchemaInternal( validator, dependentSchema, rootSchema, formData, expandAllBranches, recurseList, experimental_customMergeAllOf ); return schemas.map((s2) => mergeSchemas(schema, s2)); }); } // src/schema/findSelectedOptionInXxxOf.ts function findSelectedOptionInXxxOf(validator, rootSchema, schema, fallbackField, xxx, formData = {}, experimental_customMergeAllOf) { if (Array.isArray(schema[xxx])) { const discriminator = getDiscriminatorFieldFromSchema(schema); const selectorField = discriminator || fallbackField; const xxxOfs = schema[xxx].map( (xxxOf) => retrieveSchema(validator, xxxOf, rootSchema, formData, experimental_customMergeAllOf) ); const data = (0, import_get6.default)(formData, selectorField); if (data !== void 0) { return xxxOfs.find((xxx2) => { return (0, import_isEqual.default)( (0, import_get6.default)(xxx2, [PROPERTIES_KEY, selectorField, DEFAULT_KEY], (0, import_get6.default)(xxx2, [PROPERTIES_KEY, selectorField, CONST_KEY])), data ); }); } } return void 0; } // src/schema/getFromSchema.ts var import_get7 = __toESM(require("lodash/get")); var import_has2 = __toESM(require("lodash/has")); var import_isEmpty3 = __toESM(require("lodash/isEmpty")); function getFromSchemaInternal(validator, rootSchema, schema, path, experimental_customMergeAllOf) { let fieldSchema = schema; if ((0, import_has2.default)(schema, REF_KEY)) { fieldSchema = retrieveSchema(validator, schema, rootSchema, void 0, experimental_customMergeAllOf); } if ((0, import_isEmpty3.default)(path)) { return fieldSchema; } const pathList = Array.isArray(path) ? path : path.split("."); const [part, ...nestedPath] = pathList; if (part && (0, import_has2.default)(fieldSchema, part)) { fieldSchema = (0, import_get7.default)(fieldSchema, part); return getFromSchemaInternal( validator, rootSchema, fieldSchema, nestedPath, experimental_customMergeAllOf ); } return void 0; } function getFromSchema(validator, rootSchema, schema, path, defaultValue, experimental_customMergeAllOf) { const result = getFromSchemaInternal(validator, rootSchema, schema, path, experimental_customMergeAllOf); if (result === void 0) { return defaultValue; } return result; } // src/schema/findFieldInSchema.ts var NOT_FOUND_SCHEMA = { title: "!@#$_UNKNOWN_$#@!" }; function findFieldInSchema(validator, rootSchema, schema, path, formData = {}, experimental_customMergeAllOf) { const pathList = Array.isArray(path) ? [...path] : path.split("."); let parentField = schema; const fieldName = pathList.pop(); if (pathList.length) { pathList.forEach((subPath) => { parentField = getFromSchema( validator, rootSchema, parentField, [PROPERTIES_KEY, subPath], {}, experimental_customMergeAllOf ); if ((0, import_has3.default)(parentField, ONE_OF_KEY)) { parentField = findSelectedOptionInXxxOf( validator, rootSchema, parentField, fieldName, ONE_OF_KEY, (0, import_get8.default)(formData, subPath), experimental_customMergeAllOf ); } else if ((0, import_has3.default)(parentField, ANY_OF_KEY)) { parentField = findSelectedOptionInXxxOf( validator, rootSchema, parentField, fieldName, ANY_OF_KEY, (0, import_get8.default)(formData, subPath), experimental_customMergeAllOf ); } }); } if ((0, import_has3.default)(parentField, ONE_OF_KEY)) { parentField = findSelectedOptionInXxxOf( validator, rootSchema, parentField, fieldName, ONE_OF_KEY, formData, experimental_customMergeAllOf ); } else if ((0, import_has3.default)(parentField, ANY_OF_KEY)) { parentField = findSelectedOptionInXxxOf( validator, rootSchema, parentField, fieldName, ANY_OF_KEY, formData, experimental_customMergeAllOf ); } let field = getFromSchema( validator, rootSchema, parentField, [PROPERTIES_KEY, fieldName], NOT_FOUND_SCHEMA, experimental_customMergeAllOf ); if (field === NOT_FOUND_SCHEMA) { field = void 0; } const requiredArray = getFromSchema( validator, rootSchema, parentField, REQUIRED_KEY, [], experimental_customMergeAllOf ); let isRequired; if (field && Array.isArray(requiredArray)) { isRequired = requiredArray.includes(fieldName); } return { field, isRequired }; } // src/schema/getDefaultFormState.ts var import_get12 = __toESM(require("lodash/get")); var import_isEmpty4 = __toESM(require("lodash/isEmpty")); // src/schema/getClosestMatchingOption.ts var import_get9 = __toESM(require("lodash/get")); var import_has4 = __toESM(require("lodash/has")); var import_isNumber2 = __toESM(require("lodash/isNumber")); var import_isObject6 = __toESM(require("lodash/isObject")); var import_isString2 = __toESM(require("lodash/isString")); var import_reduce = __toESM(require("lodash/reduce")); var import_times2 = __toESM(require("lodash/times")); var JUNK_OPTION = { type: "object", $id: JUNK_OPTION_ID, properties: { __not_really_there__: { type: "number" } } }; function calculateIndexScore(validator, rootSchema, schema, formData, experimental_customMergeAllOf) { let totalScore = 0; if (schema) { if ((0, import_isObject6.default)(schema.properties)) { totalScore += (0, import_reduce.default)( schema.properties, (score, value, key) => { const formValue = (0, import_get9.default)(formData, key); if (typeof value === "boolean") { return score; } if ((0, import_has4.default)(value, REF_KEY)) { const newSchema = retrieveSchema( validator, value, rootSchema, formValue, experimental_customMergeAllOf ); return score + calculateIndexScore( validator, rootSchema, newSchema, formValue || {}, experimental_customMergeAllOf ); } if (((0, import_has4.default)(value, ONE_OF_KEY) || (0, import_has4.default)(value, ANY_OF_KEY)) && formValue) { const key2 = (0, import_has4.default)(value, ONE_OF_KEY) ? ONE_OF_KEY : ANY_OF_KEY; const discriminator = getDiscriminatorFieldFromSchema(value); return score + getClosestMatchingOption( validator, rootSchema, formValue, (0, import_get9.default)(value, key2), -1, discriminator, experimental_customMergeAllOf ); } if (value.type === "object") { if ((0, import_isObject6.default)(formValue)) { score += 1; } return score + calculateIndexScore(validator, rootSchema, value, formValue, experimental_customMergeAllOf); } if (value.type === guessType(formValue)) { let newScore = score + 1; if (value.default) { newScore += formValue === value.default ? 1 : -1; } else if (value.const) { newScore += formValue === value.const ? 1 : -1; } return newScore; } return score; }, 0 ); } else if ((0, import_isString2.default)(schema.type) && schema.type === guessType(formData)) { totalScore += 1; } } return totalScore; } function getClosestMatchingOption(validator, rootSchema, formData, options, selectedOption = -1, discriminatorField, experimental_customMergeAllOf) { const resolvedOptions = options.map((option) => { return resolveAllReferences(option, rootSchema, []); }); const simpleDiscriminatorMatch = getOptionMatchingSimpleDiscriminator(formData, options, discriminatorField); if ((0, import_isNumber2.default)(simpleDiscriminatorMatch)) { return simpleDiscriminatorMatch; } const allValidIndexes = resolvedOptions.reduce((validList, option, index) => { const testOptions = [JUNK_OPTION, option]; const match = getFirstMatchingOption(validator, formData, testOptions, rootSchema, discriminatorField); if (match === 1) { validList.push(index); } return validList; }, []); if (allValidIndexes.length === 1) { return allValidIndexes[0]; } if (!allValidIndexes.length) { (0, import_times2.default)(resolvedOptions.length, (i) => allValidIndexes.push(i)); } const scoreCount = /* @__PURE__ */ new Set(); const { bestIndex } = allValidIndexes.reduce( (scoreData, index) => { const { bestScore } = scoreData; const option = resolvedOptions[index]; const score = calculateIndexScore(validator, rootSchema, option, formData, experimental_customMergeAllOf); scoreCount.add(score); if (score > bestScore) { return { bestIndex: index, bestScore: score }; } return scoreData; }, { bestIndex: selectedOption, bestScore: 0 } ); if (scoreCount.size === 1 && selectedOption >= 0) { return selectedOption; } return bestIndex; } // src/isFixedItems.ts function isFixedItems(schema) { return Array.isArray(schema.items) && schema.items.length > 0 && schema.items.every((item) => isObject(item)); } // src/mergeDefaultsWithFormData.ts var import_get10 = __toESM(require("lodash/get")); var import_isNil = __toESM(require("lodash/isNil")); function mergeDefaultsWithFormData(defaults, formData, mergeExtraArrayDefaults = false, defaultSupercedesUndefined = false, overrideFormDataWithDefaults = false) { if (Array.isArray(formData)) { const defaultsArray = Array.isArray(defaults) ? defaults : []; const overrideArray = overrideFormDataWithDefaults ? defaultsArray : formData; const overrideOppositeArray = overrideFormDataWithDefaults ? formData : defaultsArray; const mapped = overrideArray.map((value, idx) => { if (overrideOppositeArray[idx] !== void 0) { return mergeDefaultsWithFormData( defaultsArray[idx], formData[idx], mergeExtraArrayDefaults, defaultSupercedesUndefined, overrideFormDataWithDefaults ); } return value; }); if ((mergeExtraArrayDefaults || overrideFormDataWithDefaults) && mapped.length < overrideOppositeArray.length) { mapped.push(...overrideOppositeArray.slice(mapped.length)); } return mapped; } if (isObject(formData)) { const acc = Object.assign({}, defaults); return Object.keys(formData).reduce((acc2, key) => { const keyValue = (0, import_get10.default)(formData, key); const keyExistsInDefaults = isObject(defaults) && key in defaults; const keyExistsInFormData = key in formData; const keyDefault = (0, import_get10.default)(defaults, key) ?? {}; const defaultValueIsNestedObject = keyExistsInDefaults && Object.entries(keyDefault).some(([, v]) => isObject(v)); const keyDefaultIsObject = keyExistsInDefaults && isObject((0, import_get10.default)(defaults, key)); const keyHasFormDataObject = keyExistsInFormData &&