diff --git a/packages/apidom-ns-json-schema-draft-6/src/refractor/plugins/replace-empty-element.ts b/packages/apidom-ns-json-schema-draft-6/src/refractor/plugins/replace-empty-element.ts index 1bfb1f8641..3f18357dab 100644 --- a/packages/apidom-ns-json-schema-draft-6/src/refractor/plugins/replace-empty-element.ts +++ b/packages/apidom-ns-json-schema-draft-6/src/refractor/plugins/replace-empty-element.ts @@ -1,11 +1,12 @@ import { - MemberElement, ArrayElement, ObjectElement, StringElement, isStringElement, - includesClasses, isArrayElement, + isElement, + isMemberElement, + includesClasses, cloneDeep, toValue, } from '@swagger-api/apidom-core'; @@ -198,58 +199,35 @@ const findElementFactory = (ancestor: any, keyName: string) => { : keyMapping[keyName]; }; -const plugin = () => () => { - return { - visitor: { - MemberElement(element: MemberElement, ...rest: any) { - // no empty Element, continue with next one - if (!isEmptyElement(element.value)) return undefined; - - const [, , , ancestors] = rest; - const ancestor = ancestors[ancestors.length - 1]; // @TODO(vladimir.gorej@gmail.com): can be replaced by Array.prototype.at in future - const elementFactory = findElementFactory(ancestor, toValue(element.key)); - - // no element factory found - if (typeof elementFactory === 'undefined') return undefined; - - const originalValue = element.value as StringElement; - - return new MemberElement( - element.key, - elementFactory.call( - { context: ancestor }, - undefined, - cloneDeep(originalValue.meta), - cloneDeep(originalValue.attributes), - ), - cloneDeep(element.meta), - cloneDeep(element.attributes), - ); - }, - - StringElement(element: StringElement, ...rest: any) { - if (!isEmptyElement(element)) return undefined; - - const [, , , ancestors] = rest; - const ancestor = ancestors[ancestors.length - 1]; - - // we're only interested in empty elements in ArrayElements - if (!isArrayElement(ancestor)) return undefined; - - const elementFactory = findElementFactory(ancestor, '<*>'); - - // no element factory found - if (typeof elementFactory === 'undefined') return undefined; - - return elementFactory.call( - { context: element }, - undefined, - cloneDeep(element.meta), - cloneDeep(element.attributes), - ); - }, - }, - }; -}; +const plugin = () => () => ({ + visitor: { + StringElement(element: StringElement, key: any, parent: any, path: any, ancestors: any[]) { + if (!isEmptyElement(element)) return undefined; + + const lineage = [...ancestors, parent].filter(isElement); + const parentElement = lineage[lineage.length - 1]; // @TODO(vladimir.gorej@gmail.com): can be replaced by Array.prototype.at in future + let elementFactory; + let context; + + if (isArrayElement(parentElement)) { + context = element; + elementFactory = findElementFactory(parentElement, '<*>'); + } else if (isMemberElement(parentElement)) { + context = lineage[lineage.length - 2]; // @TODO(vladimir.gorej@gmail.com): can be replaced by Array.prototype.at in future + elementFactory = findElementFactory(context, toValue(parentElement.key)); + } + + // no element factory found + if (typeof elementFactory !== 'function') return undefined; + + return elementFactory.call( + { context }, + undefined, + cloneDeep(element.meta), + cloneDeep(element.attributes), + ); + }, + }, +}); export default plugin;