UNPKG

angular6-json-schema-form

Version:
784 lines 102 kB
import cloneDeep from 'lodash-es/cloneDeep'; import { forEach, hasOwn, mergeFilteredObject } from './utility.functions'; import { getType, hasValue, inArray, isArray, isNumber, isObject, isString } from './validator.functions'; import { JsonPointer } from './jsonpointer.functions'; import { mergeSchemas } from './merge-schemas.function'; /** * JSON Schema function library: * * buildSchemaFromLayout: TODO: Write this function * * buildSchemaFromData: * * getFromSchema: * * removeRecursiveReferences: * * getInputType: * * checkInlineType: * * isInputRequired: * * updateInputOptions: * * getTitleMapFromOneOf: * * getControlValidators: * * resolveSchemaReferences: * * getSubSchema: * * combineAllOf: * * fixRequiredArrayProperties: */ /** * 'buildSchemaFromLayout' function * * TODO: Build a JSON Schema from a JSON Form layout * * // layout - The JSON Form layout * // - The new JSON Schema */ export function buildSchemaFromLayout(layout) { return; // let newSchema: any = { }; // const walkLayout = (layoutItems: any[], callback: Function): any[] => { // let returnArray: any[] = []; // for (let layoutItem of layoutItems) { // const returnItem: any = callback(layoutItem); // if (returnItem) { returnArray = returnArray.concat(callback(layoutItem)); } // if (layoutItem.items) { // returnArray = returnArray.concat(walkLayout(layoutItem.items, callback)); // } // } // return returnArray; // }; // walkLayout(layout, layoutItem => { // let itemKey: string; // if (typeof layoutItem === 'string') { // itemKey = layoutItem; // } else if (layoutItem.key) { // itemKey = layoutItem.key; // } // if (!itemKey) { return; } // // // }); } /** * 'buildSchemaFromData' function * * Build a JSON Schema from a data object * * // data - The data object * // { boolean = false } requireAllFields - Require all fields? * // { boolean = true } isRoot - is root * // - The new JSON Schema */ export function buildSchemaFromData(data, requireAllFields = false, isRoot = true) { const newSchema = {}; const getFieldType = (value) => { const fieldType = getType(value, 'strict'); return { integer: 'number', null: 'string' }[fieldType] || fieldType; }; const buildSubSchema = (value) => buildSchemaFromData(value, requireAllFields, false); if (isRoot) { newSchema.$schema = 'http://json-schema.org/draft-06/schema#'; } newSchema.type = getFieldType(data); if (newSchema.type === 'object') { newSchema.properties = {}; if (requireAllFields) { newSchema.required = []; } for (const key of Object.keys(data)) { newSchema.properties[key] = buildSubSchema(data[key]); if (requireAllFields) { newSchema.required.push(key); } } } else if (newSchema.type === 'array') { newSchema.items = data.map(buildSubSchema); // If all items are the same type, use an object for items instead of an array if ((new Set(data.map(getFieldType))).size === 1) { newSchema.items = newSchema.items.reduce((a, b) => (Object.assign({}, a, b)), {}); } if (requireAllFields) { newSchema.minItems = 1; } } return newSchema; } /** * 'getFromSchema' function * * Uses a JSON Pointer for a value within a data object to retrieve * the schema for that value within schema for the data object. * * The optional third parameter can also be set to return something else: * 'schema' (default): the schema for the value indicated by the data pointer * 'parentSchema': the schema for the value's parent object or array * 'schemaPointer': a pointer to the value's schema within the object's schema * 'parentSchemaPointer': a pointer to the schema for the value's parent object or array * * // schema - The schema to get the sub-schema from * // { Pointer } dataPointer - JSON Pointer (string or array) * // { string = 'schema' } returnType - what to return? * // - The located sub-schema */ export function getFromSchema(schema, dataPointer, returnType = 'schema') { const dataPointerArray = JsonPointer.parse(dataPointer); if (dataPointerArray === null) { console.error(`getFromSchema error: Invalid JSON Pointer: ${dataPointer}`); return null; } let subSchema = schema; const schemaPointer = []; const length = dataPointerArray.length; if (returnType.slice(0, 6) === 'parent') { dataPointerArray.length--; } for (let i = 0; i < length; ++i) { const parentSchema = subSchema; const key = dataPointerArray[i]; let subSchemaFound = false; if (typeof subSchema !== 'object') { console.error(`getFromSchema error: Unable to find "${key}" key in schema.`); console.error(schema); console.error(dataPointer); return null; } if (subSchema.type === 'array' && (!isNaN(key) || key === '-')) { if (hasOwn(subSchema, 'items')) { if (isObject(subSchema.items)) { subSchemaFound = true; subSchema = subSchema.items; schemaPointer.push('items'); } else if (isArray(subSchema.items)) { if (!isNaN(key) && subSchema.items.length >= +key) { subSchemaFound = true; subSchema = subSchema.items[+key]; schemaPointer.push('items', key); } } } if (!subSchemaFound && isObject(subSchema.additionalItems)) { subSchemaFound = true; subSchema = subSchema.additionalItems; schemaPointer.push('additionalItems'); } else if (subSchema.additionalItems !== false) { subSchemaFound = true; subSchema = {}; schemaPointer.push('additionalItems'); } } else if (subSchema.type === 'object') { if (isObject(subSchema.properties) && hasOwn(subSchema.properties, key)) { subSchemaFound = true; subSchema = subSchema.properties[key]; schemaPointer.push('properties', key); } else if (isObject(subSchema.additionalProperties)) { subSchemaFound = true; subSchema = subSchema.additionalProperties; schemaPointer.push('additionalProperties'); } else if (subSchema.additionalProperties !== false) { subSchemaFound = true; subSchema = {}; schemaPointer.push('additionalProperties'); } } if (!subSchemaFound) { console.error(`getFromSchema error: Unable to find "${key}" item in schema.`); console.error(schema); console.error(dataPointer); return; } } return returnType.slice(-7) === 'Pointer' ? schemaPointer : subSchema; } /** * 'removeRecursiveReferences' function * * Checks a JSON Pointer against a map of recursive references and returns * a JSON Pointer to the shallowest equivalent location in the same object. * * Using this functions enables an object to be constructed with unlimited * recursion, while maintaing a fixed set of metadata, such as field data types. * The object can grow as large as it wants, and deeply recursed nodes can * just refer to the metadata for their shallow equivalents, instead of having * to add additional redundant metadata for each recursively added node. * * Example: * * pointer: '/stuff/and/more/and/more/and/more/and/more/stuff' * recursiveRefMap: [['/stuff/and/more/and/more', '/stuff/and/more/']] * returned: '/stuff/and/more/stuff' * * // { Pointer } pointer - * // { Map<string, string> } recursiveRefMap - * // { Map<string, number> = new Map() } arrayMap - optional * // { string } - */ export function removeRecursiveReferences(pointer, recursiveRefMap, arrayMap = new Map()) { if (!pointer) { return ''; } let genericPointer = JsonPointer.toGenericPointer(JsonPointer.compile(pointer), arrayMap); if (genericPointer.indexOf('/') === -1) { return genericPointer; } let possibleReferences = true; while (possibleReferences) { possibleReferences = false; recursiveRefMap.forEach((toPointer, fromPointer) => { if (JsonPointer.isSubPointer(toPointer, fromPointer)) { while (JsonPointer.isSubPointer(fromPointer, genericPointer, true)) { genericPointer = JsonPointer.toGenericPointer(toPointer + genericPointer.slice(fromPointer.length), arrayMap); possibleReferences = true; } } }); } return genericPointer; } /** * 'getInputType' function * * // schema * // { any = null } layoutNode * // { string } */ export function getInputType(schema, layoutNode = null) { // x-schema-form = Angular Schema Form compatibility // widget & component = React Jsonschema Form compatibility const controlType = JsonPointer.getFirst([ [schema, '/x-schema-form/type'], [schema, '/x-schema-form/widget/component'], [schema, '/x-schema-form/widget'], [schema, '/widget/component'], [schema, '/widget'] ]); if (isString(controlType)) { return checkInlineType(controlType, schema, layoutNode); } let schemaType = schema.type; if (schemaType) { if (isArray(schemaType)) { // If multiple types listed, use most inclusive type schemaType = inArray('object', schemaType) && hasOwn(schema, 'properties') ? 'object' : inArray('array', schemaType) && hasOwn(schema, 'items') ? 'array' : inArray('array', schemaType) && hasOwn(schema, 'additionalItems') ? 'array' : inArray('string', schemaType) ? 'string' : inArray('number', schemaType) ? 'number' : inArray('integer', schemaType) ? 'integer' : inArray('boolean', schemaType) ? 'boolean' : 'unknown'; } if (schemaType === 'boolean') { return 'checkbox'; } if (schemaType === 'object') { if (hasOwn(schema, 'properties') || hasOwn(schema, 'additionalProperties')) { return 'section'; } // TODO: Figure out how to handle additionalProperties if (hasOwn(schema, '$ref')) { return '$ref'; } } if (schemaType === 'array') { const itemsObject = JsonPointer.getFirst([ [schema, '/items'], [schema, '/additionalItems'] ]) || {}; return hasOwn(itemsObject, 'enum') && schema.maxItems !== 1 ? checkInlineType('checkboxes', schema, layoutNode) : 'array'; } if (schemaType === 'null') { return 'none'; } if (JsonPointer.has(layoutNode, '/options/titleMap') || hasOwn(schema, 'enum') || getTitleMapFromOneOf(schema, null, true)) { return 'select'; } if (schemaType === 'number' || schemaType === 'integer') { return (schemaType === 'integer' || hasOwn(schema, 'multipleOf')) && hasOwn(schema, 'maximum') && hasOwn(schema, 'minimum') ? 'range' : schemaType; } if (schemaType === 'string') { return { 'color': 'color', 'date': 'date', 'date-time': 'datetime-local', 'email': 'email', 'uri': 'url', }[schema.format] || 'text'; } } if (hasOwn(schema, '$ref')) { return '$ref'; } if (isArray(schema.oneOf) || isArray(schema.anyOf)) { return 'one-of'; } console.error(`getInputType error: Unable to determine input type for ${schemaType}`); console.error('schema', schema); if (layoutNode) { console.error('layoutNode', layoutNode); } return 'none'; } /** * 'checkInlineType' function * * Checks layout and schema nodes for 'inline: true', and converts * 'radios' or 'checkboxes' to 'radios-inline' or 'checkboxes-inline' * * // { string } controlType - * // schema - * // { any = null } layoutNode - * // { string } */ export function checkInlineType(controlType, schema, layoutNode = null) { if (!isString(controlType) || (controlType.slice(0, 8) !== 'checkbox' && controlType.slice(0, 5) !== 'radio')) { return controlType; } if (JsonPointer.getFirst([ [layoutNode, '/inline'], [layoutNode, '/options/inline'], [schema, '/inline'], [schema, '/x-schema-form/inline'], [schema, '/x-schema-form/options/inline'], [schema, '/x-schema-form/widget/inline'], [schema, '/x-schema-form/widget/component/inline'], [schema, '/x-schema-form/widget/component/options/inline'], [schema, '/widget/inline'], [schema, '/widget/component/inline'], [schema, '/widget/component/options/inline'], ]) === true) { return controlType.slice(0, 5) === 'radio' ? 'radios-inline' : 'checkboxes-inline'; } else { return controlType; } } /** * 'isInputRequired' function * * Checks a JSON Schema to see if an item is required * * // schema - the schema to check * // { string } schemaPointer - the pointer to the item to check * // { boolean } - true if the item is required, false if not */ export function isInputRequired(schema, schemaPointer) { if (!isObject(schema)) { console.error('isInputRequired error: Input schema must be an object.'); return false; } const listPointerArray = JsonPointer.parse(schemaPointer); if (isArray(listPointerArray)) { if (!listPointerArray.length) { return schema.required === true; } const keyName = listPointerArray.pop(); const nextToLastKey = listPointerArray[listPointerArray.length - 1]; if (['properties', 'additionalProperties', 'patternProperties', 'items', 'additionalItems'] .includes(nextToLastKey)) { listPointerArray.pop(); } const parentSchema = JsonPointer.get(schema, listPointerArray) || {}; if (isArray(parentSchema.required)) { return parentSchema.required.includes(keyName); } if (parentSchema.type === 'array') { return hasOwn(parentSchema, 'minItems') && isNumber(keyName) && +parentSchema.minItems > +keyName; } } return false; } /** * 'updateInputOptions' function * * // layoutNode * // schema * // jsf * // { void } */ export function updateInputOptions(layoutNode, schema, jsf) { if (!isObject(layoutNode) || !isObject(layoutNode.options)) { return; } // Set all option values in layoutNode.options const newOptions = {}; const fixUiKeys = key => key.slice(0, 3).toLowerCase() === 'ui:' ? key.slice(3) : key; mergeFilteredObject(newOptions, jsf.formOptions.defautWidgetOptions, [], fixUiKeys); [[JsonPointer.get(schema, '/ui:widget/options'), []], [JsonPointer.get(schema, '/ui:widget'), []], [schema, [ 'additionalProperties', 'additionalItems', 'properties', 'items', 'required', 'type', 'x-schema-form', '$ref' ]], [JsonPointer.get(schema, '/x-schema-form/options'), []], [JsonPointer.get(schema, '/x-schema-form'), ['items', 'options']], [layoutNode, [ '_id', '$ref', 'arrayItem', 'arrayItemType', 'dataPointer', 'dataType', 'items', 'key', 'name', 'options', 'recursiveReference', 'type', 'widget' ]], [layoutNode.options, []], ].forEach(([object, excludeKeys]) => mergeFilteredObject(newOptions, object, excludeKeys, fixUiKeys)); if (!hasOwn(newOptions, 'titleMap')) { let newTitleMap = null; newTitleMap = getTitleMapFromOneOf(schema, newOptions.flatList); if (newTitleMap) { newOptions.titleMap = newTitleMap; } if (!hasOwn(newOptions, 'titleMap') && !hasOwn(newOptions, 'enum') && hasOwn(schema, 'items')) { if (JsonPointer.has(schema, '/items/titleMap')) { newOptions.titleMap = schema.items.titleMap; } else if (JsonPointer.has(schema, '/items/enum')) { newOptions.enum = schema.items.enum; if (!hasOwn(newOptions, 'enumNames') && JsonPointer.has(schema, '/items/enumNames')) { newOptions.enumNames = schema.items.enumNames; } } else if (JsonPointer.has(schema, '/items/oneOf')) { newTitleMap = getTitleMapFromOneOf(schema.items, newOptions.flatList); if (newTitleMap) { newOptions.titleMap = newTitleMap; } } } } // If schema type is integer, enforce by setting multipleOf = 1 if (schema.type === 'integer' && !hasValue(newOptions.multipleOf)) { newOptions.multipleOf = 1; } // Copy any typeahead word lists to options.typeahead.source if (JsonPointer.has(newOptions, '/autocomplete/source')) { newOptions.typeahead = newOptions.autocomplete; } else if (JsonPointer.has(newOptions, '/tagsinput/source')) { newOptions.typeahead = newOptions.tagsinput; } else if (JsonPointer.has(newOptions, '/tagsinput/typeahead/source')) { newOptions.typeahead = newOptions.tagsinput.typeahead; } layoutNode.options = newOptions; } /** * 'getTitleMapFromOneOf' function * * // { schema } schema * // { boolean = null } flatList * // { boolean = false } validateOnly * // { validators } */ export function getTitleMapFromOneOf(schema = {}, flatList = null, validateOnly = false) { let titleMap = null; const oneOf = schema.oneOf || schema.anyOf || null; if (isArray(oneOf) && oneOf.every(item => item.title)) { if (oneOf.every(item => isArray(item.enum) && item.enum.length === 1)) { if (validateOnly) { return true; } titleMap = oneOf.map(item => ({ name: item.title, value: item.enum[0] })); } else if (oneOf.every(item => item.const)) { if (validateOnly) { return true; } titleMap = oneOf.map(item => ({ name: item.title, value: item.const })); } // if flatList !== false and some items have colons, make grouped map if (flatList !== false && (titleMap || []) .filter(title => ((title || {}).name || '').indexOf(': ')).length > 1) { // Split name on first colon to create grouped map (name -> group: name) const newTitleMap = titleMap.map(title => { const [group, name] = title.name.split(/: (.+)/); return group && name ? Object.assign({}, title, { group, name }) : title; }); // If flatList === true or at least one group has multiple items, use grouped map if (flatList === true || newTitleMap.some((title, index) => index && hasOwn(title, 'group') && title.group === newTitleMap[index - 1].group)) { titleMap = newTitleMap; } } } return validateOnly ? false : titleMap; } /** * 'getControlValidators' function * * // schema * // { validators } */ export function getControlValidators(schema) { if (!isObject(schema)) { return null; } const validators = {}; if (hasOwn(schema, 'type')) { switch (schema.type) { case 'string': forEach(['pattern', 'format', 'minLength', 'maxLength'], (prop) => { if (hasOwn(schema, prop)) { validators[prop] = [schema[prop]]; } }); break; case 'number': case 'integer': forEach(['Minimum', 'Maximum'], (ucLimit) => { const eLimit = 'exclusive' + ucLimit; const limit = ucLimit.toLowerCase(); if (hasOwn(schema, limit)) { const exclusive = hasOwn(schema, eLimit) && schema[eLimit] === true; validators[limit] = [schema[limit], exclusive]; } }); forEach(['multipleOf', 'type'], (prop) => { if (hasOwn(schema, prop)) { validators[prop] = [schema[prop]]; } }); break; case 'object': forEach(['minProperties', 'maxProperties', 'dependencies'], (prop) => { if (hasOwn(schema, prop)) { validators[prop] = [schema[prop]]; } }); break; case 'array': forEach(['minItems', 'maxItems', 'uniqueItems'], (prop) => { if (hasOwn(schema, prop)) { validators[prop] = [schema[prop]]; } }); break; } } if (hasOwn(schema, 'enum')) { validators.enum = [schema.enum]; } return validators; } /** * 'resolveSchemaReferences' function * * Find all $ref links in schema and save links and referenced schemas in * schemaRefLibrary, schemaRecursiveRefMap, and dataRecursiveRefMap * * // schema * // schemaRefLibrary * // { Map<string, string> } schemaRecursiveRefMap * // { Map<string, string> } dataRecursiveRefMap * // { Map<string, number> } arrayMap * // */ export function resolveSchemaReferences(schema, schemaRefLibrary, schemaRecursiveRefMap, dataRecursiveRefMap, arrayMap) { if (!isObject(schema)) { console.error('resolveSchemaReferences error: schema must be an object.'); return; } const refLinks = new Set(); const refMapSet = new Set(); const refMap = new Map(); const recursiveRefMap = new Map(); const refLibrary = {}; // Search schema for all $ref links, and build full refLibrary JsonPointer.forEachDeep(schema, (subSchema, subSchemaPointer) => { if (hasOwn(subSchema, '$ref') && isString(subSchema['$ref'])) { const refPointer = JsonPointer.compile(subSchema['$ref']); refLinks.add(refPointer); refMapSet.add(subSchemaPointer + '~~' + refPointer); refMap.set(subSchemaPointer, refPointer); } }); refLinks.forEach(ref => refLibrary[ref] = getSubSchema(schema, ref)); // Follow all ref links and save in refMapSet, // to find any multi-link recursive refernces let checkRefLinks = true; while (checkRefLinks) { checkRefLinks = false; Array.from(refMap).forEach(([fromRef1, toRef1]) => Array.from(refMap) .filter(([fromRef2, toRef2]) => JsonPointer.isSubPointer(toRef1, fromRef2, true) && !JsonPointer.isSubPointer(toRef2, toRef1, true) && !refMapSet.has(fromRef1 + fromRef2.slice(toRef1.length) + '~~' + toRef2)) .forEach(([fromRef2, toRef2]) => { refMapSet.add(fromRef1 + fromRef2.slice(toRef1.length) + '~~' + toRef2); checkRefLinks = true; })); } // Build full recursiveRefMap // First pass - save all internally recursive refs from refMapSet Array.from(refMapSet) .map(refLink => refLink.split('~~')) .filter(([fromRef, toRef]) => JsonPointer.isSubPointer(toRef, fromRef)) .forEach(([fromRef, toRef]) => recursiveRefMap.set(fromRef, toRef)); // Second pass - create recursive versions of any other refs that link to recursive refs Array.from(refMap) .filter(([fromRef1, toRef1]) => Array.from(recursiveRefMap.keys()) .every(fromRef2 => !JsonPointer.isSubPointer(fromRef1, fromRef2, true))) .forEach(([fromRef1, toRef1]) => Array.from(recursiveRefMap) .filter(([fromRef2, toRef2]) => !recursiveRefMap.has(fromRef1 + fromRef2.slice(toRef1.length)) && JsonPointer.isSubPointer(toRef1, fromRef2, true) && !JsonPointer.isSubPointer(toRef1, fromRef1, true)) .forEach(([fromRef2, toRef2]) => recursiveRefMap.set(fromRef1 + fromRef2.slice(toRef1.length), fromRef1 + toRef2.slice(toRef1.length)))); // Create compiled schema by replacing all non-recursive $ref links with // thieir linked schemas and, where possible, combining schemas in allOf arrays. let compiledSchema = Object.assign({}, schema); delete compiledSchema.definitions; compiledSchema = getSubSchema(compiledSchema, '', refLibrary, recursiveRefMap); // Make sure all remaining schema $refs are recursive, and build final // schemaRefLibrary, schemaRecursiveRefMap, dataRecursiveRefMap, & arrayMap JsonPointer.forEachDeep(compiledSchema, (subSchema, subSchemaPointer) => { if (isString(subSchema['$ref'])) { let refPointer = JsonPointer.compile(subSchema['$ref']); if (!JsonPointer.isSubPointer(refPointer, subSchemaPointer, true)) { refPointer = removeRecursiveReferences(subSchemaPointer, recursiveRefMap); JsonPointer.set(compiledSchema, subSchemaPointer, { $ref: `#${refPointer}` }); } if (!hasOwn(schemaRefLibrary, 'refPointer')) { schemaRefLibrary[refPointer] = !refPointer.length ? compiledSchema : getSubSchema(compiledSchema, refPointer, schemaRefLibrary, recursiveRefMap); } if (!schemaRecursiveRefMap.has(subSchemaPointer)) { schemaRecursiveRefMap.set(subSchemaPointer, refPointer); } const fromDataRef = JsonPointer.toDataPointer(subSchemaPointer, compiledSchema); if (!dataRecursiveRefMap.has(fromDataRef)) { const toDataRef = JsonPointer.toDataPointer(refPointer, compiledSchema); dataRecursiveRefMap.set(fromDataRef, toDataRef); } } if (subSchema.type === 'array' && (hasOwn(subSchema, 'items') || hasOwn(subSchema, 'additionalItems'))) { const dataPointer = JsonPointer.toDataPointer(subSchemaPointer, compiledSchema); if (!arrayMap.has(dataPointer)) { const tupleItems = isArray(subSchema.items) ? subSchema.items.length : 0; arrayMap.set(dataPointer, tupleItems); } } }, true); return compiledSchema; } /** * 'getSubSchema' function * * // schema * // { Pointer } pointer * // { object } schemaRefLibrary * // { Map<string, string> } schemaRecursiveRefMap * // { string[] = [] } usedPointers * // */ export function getSubSchema(schema, pointer, schemaRefLibrary = null, schemaRecursiveRefMap = null, usedPointers = []) { if (!schemaRefLibrary || !schemaRecursiveRefMap) { return JsonPointer.getCopy(schema, pointer); } if (typeof pointer !== 'string') { pointer = JsonPointer.compile(pointer); } usedPointers = [...usedPointers, pointer]; let newSchema = null; if (pointer === '') { newSchema = cloneDeep(schema); } else { const shortPointer = removeRecursiveReferences(pointer, schemaRecursiveRefMap); if (shortPointer !== pointer) { usedPointers = [...usedPointers, shortPointer]; } newSchema = JsonPointer.getFirstCopy([ [schemaRefLibrary, [shortPointer]], [schema, pointer], [schema, shortPointer] ]); } return JsonPointer.forEachDeepCopy(newSchema, (subSchema, subPointer) => { if (isObject(subSchema)) { // Replace non-recursive $ref links with referenced schemas if (isString(subSchema.$ref)) { const refPointer = JsonPointer.compile(subSchema.$ref); if (refPointer.length && usedPointers.every(ptr => !JsonPointer.isSubPointer(refPointer, ptr, true))) { const refSchema = getSubSchema(schema, refPointer, schemaRefLibrary, schemaRecursiveRefMap, usedPointers); if (Object.keys(subSchema).length === 1) { return refSchema; } else { const extraKeys = Object.assign({}, subSchema); delete extraKeys.$ref; return mergeSchemas(refSchema, extraKeys); } } } // TODO: Convert schemas with 'type' arrays to 'oneOf' // Combine allOf subSchemas if (isArray(subSchema.allOf)) { return combineAllOf(subSchema); } // Fix incorrectly placed array object required lists if (subSchema.type === 'array' && isArray(subSchema.required)) { return fixRequiredArrayProperties(subSchema); } } return subSchema; }, true, pointer); } /** * 'combineAllOf' function * * Attempt to convert an allOf schema object into * a non-allOf schema object with equivalent rules. * * // schema - allOf schema object * // - converted schema object */ export function combineAllOf(schema) { if (!isObject(schema) || !isArray(schema.allOf)) { return schema; } let mergedSchema = mergeSchemas(...schema.allOf); if (Object.keys(schema).length > 1) { const extraKeys = Object.assign({}, schema); delete extraKeys.allOf; mergedSchema = mergeSchemas(mergedSchema, extraKeys); } return mergedSchema; } /** * 'fixRequiredArrayProperties' function * * Fixes an incorrectly placed required list inside an array schema, by moving * it into items.properties or additionalItems.properties, where it belongs. * * // schema - allOf schema object * // - converted schema object */ export function fixRequiredArrayProperties(schema) { if (schema.type === 'array' && isArray(schema.required)) { const itemsObject = hasOwn(schema.items, 'properties') ? 'items' : hasOwn(schema.additionalItems, 'properties') ? 'additionalItems' : null; if (itemsObject && !hasOwn(schema[itemsObject], 'required') && (hasOwn(schema[itemsObject], 'additionalProperties') || schema.required.every(key => hasOwn(schema[itemsObject].properties, key)))) { schema = cloneDeep(schema); schema[itemsObject].required = schema.required; delete schema.required; } } return schema; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoianNvbi1zY2hlbWEuZnVuY3Rpb25zLmpzIiwic291cmNlUm9vdCI6Im5nOi8vYW5ndWxhcjYtanNvbi1zY2hlbWEtZm9ybS8iLCJzb3VyY2VzIjpbImxpYi9zaGFyZWQvanNvbi1zY2hlbWEuZnVuY3Rpb25zLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sU0FBUyxNQUFNLHFCQUFxQixDQUFDO0FBQzVDLE9BQU8sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFFLG1CQUFtQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDM0UsT0FBTyxFQUNMLE9BQU8sRUFDUCxRQUFRLEVBQ1IsT0FBTyxFQUNQLE9BQU8sRUFDUCxRQUFRLEVBQ1IsUUFBUSxFQUNSLFFBQVEsRUFDUCxNQUFNLHVCQUF1QixDQUFDO0FBQ2pDLE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sMEJBQTBCLENBQUM7QUFHeEQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQThCRztBQUVIOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUscUJBQXFCLENBQUMsTUFBTTtJQUMxQyxPQUFPO0lBQ1AsNEJBQTRCO0lBQzVCLDBFQUEwRTtJQUMxRSxpQ0FBaUM7SUFDakMsMENBQTBDO0lBQzFDLG9EQUFvRDtJQUNwRCxrRkFBa0Y7SUFDbEYsOEJBQThCO0lBQzlCLGtGQUFrRjtJQUNsRixRQUFRO0lBQ1IsTUFBTTtJQUNOLHdCQUF3QjtJQUN4QixLQUFLO0lBQ0wscUNBQXFDO0lBQ3JDLHlCQUF5QjtJQUN6QiwwQ0FBMEM7SUFDMUMsNEJBQTRCO0lBQzVCLGlDQUFpQztJQUNqQyxnQ0FBZ0M7SUFDaEMsTUFBTTtJQUNOLDhCQUE4QjtJQUM5QixPQUFPO0lBQ1AsTUFBTTtBQUNSLENBQUM7QUFFRDs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLFVBQVUsbUJBQW1CLENBQ2pDLElBQUksRUFBRSxnQkFBZ0IsR0FBRyxL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QUFLLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztTQUMzRTthQUFNLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUMxQyxJQUFJLFlBQVksRUFBRTtnQkFBRSxPQUFPLElBQUksQ0FBQzthQUFFO1lBQ2xDLFFBQVEsR0FBRyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO1NBQ3pFO1FBRUQscUVBQXFFO1FBQ3JFLElBQUksUUFBUSxLQUFLLEtBQUssSUFBSSxDQUFDLFFBQVEsSUFBSSxFQUFFLENBQUM7YUFDdkMsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxFQUFFLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsTUFBT