@@ -5,6 +5,7 @@ import { isObject } from "../utils/isObject";
55import { validateNode } from "../validateNode" ;
66import { get , split } from "@sagold/json-pointer" ;
77import { mergeNode } from "../mergeNode" ;
8+ import { pick } from "../utils/pick" ;
89export const $refKeyword = {
910 id : "$ref" ,
1011 keyword : "$ref" ,
@@ -109,48 +110,53 @@ function resolveRecursiveRef(node, path) {
109110 const nonMatchingDynamicAnchor = node . context . dynamicAnchors [ refInCurrentScope ] == null ;
110111 if ( nonMatchingDynamicAnchor ) {
111112 if ( node . context . anchors [ refInCurrentScope ] ) {
112- return compileNext ( node . context . anchors [ refInCurrentScope ] , node . evaluationPath ) ;
113+ return compileNext ( node . context . anchors [ refInCurrentScope ] , node ) ;
113114 }
114115 }
115116 for ( let i = 0 ; i < history . length ; i += 1 ) {
116117 // A $dynamicRef that initially resolves to a schema with a matching $dynamicAnchor resolves to the first $dynamicAnchor in the dynamic scope
117118 if ( history [ i ] . node . schema . $dynamicAnchor ) {
118- return compileNext ( history [ i ] . node , node . evaluationPath ) ;
119+ return compileNext ( history [ i ] . node , node ) ;
119120 }
120121 // A $dynamicRef only stops at a $dynamicAnchor if it is in the same dynamic scope.
121122 const refWithoutScope = node . schema . $dynamicRef . split ( "#" ) . pop ( ) ;
122123 const ref = joinId ( history [ i ] . node . $id , `#${ refWithoutScope } ` ) ;
123124 const anchorNode = node . context . dynamicAnchors [ ref ] ;
124125 if ( anchorNode ) {
125- return compileNext ( node . context . dynamicAnchors [ ref ] , node . evaluationPath ) ;
126+ return compileNext ( node . context . dynamicAnchors [ ref ] , node ) ;
126127 }
127128 }
128129 // A $dynamicRef without a matching $dynamicAnchor in the same schema resource behaves like a normal $ref to $anchor
129130 const nextNode = getRef ( node , refInCurrentScope ) ;
130131 return nextNode ;
131132}
132- function compileNext ( referencedNode , evaluationPath = referencedNode . evaluationPath ) {
133- const referencedSchema = isObject ( referencedNode . schema )
134- ? omit ( referencedNode . schema , "$id" )
135- : referencedNode . schema ;
136- return referencedNode . compileSchema ( referencedSchema , `${ evaluationPath } /$ref` , referencedNode . schemaLocation ) ;
133+ const PROPERTIES_TO_MERGE = [ "title" , "description" , "options" , "readOnly" , "writeOnly" ] ;
134+ function compileNext ( referencedNode , sourceNode ) {
135+ let referencedSchema = referencedNode . schema ;
136+ if ( isObject ( referencedNode . schema ) ) {
137+ referencedSchema = {
138+ ...omit ( referencedNode . schema , "$id" ) ,
139+ ...pick ( sourceNode . schema , ...PROPERTIES_TO_MERGE )
140+ } ;
141+ }
142+ return referencedNode . compileSchema ( referencedSchema , `${ sourceNode . evaluationPath } /$ref` , referencedNode . schemaLocation ) ;
137143}
138144export function getRef ( node , $ref = node === null || node === void 0 ? void 0 : node . $ref ) {
139145 if ( $ref == null ) {
140146 return node ;
141147 }
142148 // resolve $ref by json-evaluationPath
143149 if ( node . context . refs [ $ref ] ) {
144- return compileNext ( node . context . refs [ $ref ] , node . evaluationPath ) ;
150+ return compileNext ( node . context . refs [ $ref ] , node ) ;
145151 }
146152 // resolve $ref from $anchor
147153 if ( node . context . anchors [ $ref ] ) {
148- return compileNext ( node . context . anchors [ $ref ] , node . evaluationPath ) ;
154+ return compileNext ( node . context . anchors [ $ref ] , node ) ;
149155 }
150156 // resolve $ref from $dynamicAnchor
151157 if ( node . context . dynamicAnchors [ $ref ] ) {
152158 // A $ref to a $dynamicAnchor in the same schema resource behaves like a normal $ref to an $anchor
153- return compileNext ( node . context . dynamicAnchors [ $ref ] , node . evaluationPath ) ;
159+ return compileNext ( node . context . dynamicAnchors [ $ref ] , node ) ;
154160 }
155161 // check for remote-host + pointer pair to switch rootSchema
156162 const fragments = splitRef ( $ref ) ;
@@ -162,7 +168,7 @@ export function getRef(node, $ref = node === null || node === void 0 ? void 0 :
162168 const $ref = fragments [ 0 ] ;
163169 // this is a reference to remote-host root node
164170 if ( node . context . remotes [ $ref ] ) {
165- return compileNext ( node . context . remotes [ $ref ] , node . evaluationPath ) ;
171+ return compileNext ( node . context . remotes [ $ref ] , node ) ;
166172 }
167173 if ( $ref [ 0 ] === "#" ) {
168174 // support refOfUnknownKeyword
0 commit comments