@@ -33,11 +33,7 @@ const targetCfg = {
3333// logic: https://json-schema.org/draft/2019-09/json-schema-core.html#rfc.appendix.B.1
3434function jsonSchemaResolver ( options ) {
3535 const ee = new EventEmitter ( )
36- const { clone, target } = Object . assign ( { } , defaultOpts , options )
37-
38- if ( ! targetSupported . includes ( target ) ) {
39- throw new Error ( `Unsupported JSON schema version ${ target } ` )
40- }
36+ const { clone, target, applicationUri, externalSchemas : rootExternalSchemas } = Object . assign ( { } , defaultOpts , options )
4137
4238 const allIds = new Map ( )
4339 let rolling = 0
@@ -46,26 +42,47 @@ function jsonSchemaResolver (options) {
4642 const allRefs = [ ]
4743 ee . on ( '$ref' , collectRefs )
4844
45+ if ( ! targetSupported . includes ( target ) ) {
46+ throw new Error ( `Unsupported JSON schema version ${ target } ` )
47+ }
48+
49+ let defaultUri
50+ if ( applicationUri ) {
51+ defaultUri = getRootUri ( applicationUri )
52+
53+ if ( rootExternalSchemas ) {
54+ for ( const es of rootExternalSchemas ) { mapIds ( ee , defaultUri , es ) }
55+ debug ( 'Processed root external schemas' )
56+ }
57+ } else if ( rootExternalSchemas ) {
58+ throw new Error ( 'If you set root externalSchema, the applicationUri option is needed' )
59+ }
60+
4961 return {
50- resolve
62+ resolve,
63+ definitions ( ) {
64+ const defKey = targetCfg [ target ] . def
65+ const x = { [ defKey ] : { } }
66+ allIds . forEach ( ( json , baseUri ) => {
67+ x [ defKey ] [ json [ kRefToDef ] ] = json
68+ } )
69+ return x
70+ }
5171 }
5272
5373 function resolve ( rootSchema , opts ) {
5474 const { externalSchemas } = opts || { }
5575
56- allIds . clear ( )
76+ if ( ! rootExternalSchemas ) {
77+ allIds . clear ( )
78+ }
5779 allRefs . length = 0
5880
5981 if ( clone ) {
6082 rootSchema = cloner ( rootSchema )
6183 }
6284
63- // If present, the value for this keyword MUST be a string, and MUST
64- // represent a valid URI-reference [RFC3986]. This value SHOULD be
65- // normalized, and SHOULD NOT be an empty fragment <#> or an empty
66- // string <>.
67- const appUri = URI . parse ( rootSchema . $id || 'application.uri' )
68- appUri . fragment = undefined // remove fragment
85+ const appUri = defaultUri || getRootUri ( rootSchema . $id )
6986 debug ( 'Found app URI %o' , appUri )
7087
7188 if ( externalSchemas ) {
@@ -96,16 +113,19 @@ function jsonSchemaResolver (options) {
96113 json . $ref = `#/definitions/${ evaluatedJson [ kRefToDef ] } `
97114 } )
98115
99- const defKey = targetCfg [ target ] . def
100- allIds . forEach ( ( json , baseUri ) => {
101- if ( json [ kConsumed ] === true ) {
102- if ( ! rootSchema [ defKey ] ) {
103- rootSchema [ defKey ] = { }
116+ if ( externalSchemas ) {
117+ // only if user sets external schema add it to the definitions
118+ const defKey = targetCfg [ target ] . def
119+ allIds . forEach ( ( json , baseUri ) => {
120+ if ( json [ kConsumed ] === true ) {
121+ if ( ! rootSchema [ defKey ] ) {
122+ rootSchema [ defKey ] = { }
123+ }
124+
125+ rootSchema [ defKey ] [ json [ kRefToDef ] ] = json
104126 }
105-
106- rootSchema [ defKey ] [ json [ kRefToDef ] ] = json
107- }
108- } )
127+ } )
128+ }
109129
110130 return rootSchema
111131 }
@@ -193,4 +213,14 @@ function mapIds (ee, baseUri, json) {
193213 }
194214}
195215
216+ function getRootUri ( strUri = 'application.uri' ) {
217+ // If present, the value for this keyword MUST be a string, and MUST
218+ // represent a valid URI-reference [RFC3986]. This value SHOULD be
219+ // normalized, and SHOULD NOT be an empty fragment <#> or an empty
220+ // string <>.
221+ const uri = URI . parse ( strUri )
222+ uri . fragment = undefined
223+ return uri
224+ }
225+
196226module . exports = jsonSchemaResolver
0 commit comments