@@ -38,24 +38,26 @@ export function registerSchemaResources<S extends object = JSONSchema, O extends
3838
3939 const seen = new Set < object > ( ) ;
4040
41- const visit = ( node : unknown , scopeBase : string ) => {
41+ const visit = ( node : unknown , scopeBase : string , pointerTokens : string [ ] ) => {
4242 if ( ! node || typeof node !== "object" || ArrayBuffer . isView ( node ) || seen . has ( node ) ) {
4343 return ;
4444 }
4545
4646 seen . add ( node ) ;
4747
4848 const nextScopeBase = getSchemaBasePath ( scopeBase , node ) ;
49+ const resourcePointerTokens = nextScopeBase === scopeBase ? pointerTokens : [ ] ;
4950 if ( nextScopeBase !== scopeBase ) {
5051 $refs . _addAlias ( nextScopeBase , node as S , pathType , dynamicIdScope ) ;
5152 }
53+ registerAnchorAliases ( $refs , nextScopeBase , resourcePointerTokens , node ) ;
5254
5355 for ( const key of Object . keys ( node ) ) {
54- visit ( ( node as Record < string , unknown > ) [ key ] , nextScopeBase ) ;
56+ visit ( ( node as Record < string , unknown > ) [ key ] , nextScopeBase , [ ... resourcePointerTokens , key ] ) ;
5557 }
5658 } ;
5759
58- visit ( value , basePath ) ;
60+ visit ( value , basePath , [ ] ) ;
5961}
6062
6163function getSchemaId ( value : unknown ) : string | undefined {
@@ -71,3 +73,37 @@ function getSchemaId(value: unknown): string | undefined {
7173
7274 return undefined ;
7375}
76+
77+ function registerAnchorAliases < S extends object = JSONSchema , O extends ParserOptions < S > = ParserOptions < S > > (
78+ $refs : $Refs < S , O > ,
79+ scopeBase : string ,
80+ pointerTokens : string [ ] ,
81+ value : unknown ,
82+ ) {
83+ if ( ! value || typeof value !== "object" || ArrayBuffer . isView ( value ) ) {
84+ return ;
85+ }
86+
87+ const resourceBase = url . stripHash ( scopeBase ) ;
88+ const targetPath = pointerTokens . length > 0 ? joinPointerPath ( resourceBase , pointerTokens ) : `${ resourceBase } #` ;
89+ const anchors = [
90+ ( value as { $anchor ?: unknown } ) . $anchor ,
91+ ( value as { $dynamicAnchor ?: unknown } ) . $dynamicAnchor ,
92+ ] ;
93+
94+ for ( const anchor of anchors ) {
95+ if ( typeof anchor === "string" && anchor . length > 0 ) {
96+ $refs . _addExactAlias ( `${ resourceBase } #${ anchor } ` , targetPath ) ;
97+ }
98+ }
99+ }
100+
101+ function joinPointerPath ( basePath : string , tokens : string [ ] ) {
102+ let path = `${ basePath } #` ;
103+
104+ for ( const token of tokens ) {
105+ path += `/${ token . replace ( / ~ / g, "~0" ) . replace ( / \/ / g, "~1" ) } ` ;
106+ }
107+
108+ return path ;
109+ }
0 commit comments