@@ -15,35 +15,6 @@ const ajv = new Ajv({
15
15
} )
16
16
addFormats ( ajv )
17
17
18
- // Proxy to resolve $refs in schema definitions
19
- const Dereference = {
20
- get ( target , property ) {
21
- const value = target [ property ]
22
-
23
- if ( Array . isArray ( value ) ) {
24
- // Schema definition returns an array for this property, return the array with all refs resolved
25
- return value . map ( ( item , i ) => {
26
- const $ref = item . $ref || this . join ( target . $id , `${ property } /${ i } ` )
27
- return Schema . resolve ( $ref , target . $id )
28
- } )
29
- } else if ( value !== null && typeof value === 'object' ) {
30
- // Schema definition returns an object for this property, return the subschema and proxy it
31
- return Schema . proxy ( this . join ( target . $id , property ) , value )
32
- } else if ( value !== undefined ) {
33
- // Schema definition returns a value for this property, just return it
34
- return value
35
- } else if ( target . $ref ) {
36
- // Schema includes a ref, so delegate to it
37
- return Schema . resolve ( target . $ref , target . $id ) [ property ]
38
- }
39
- } ,
40
-
41
- join ( $id , path ) {
42
- const url = new URL ( $id )
43
- url . hash = [ url . hash , path ] . join ( '/' )
44
- return url . toString ( )
45
- }
46
- }
47
18
48
19
// Delegate property access to the schema definition
49
20
const DelegateToDefinition = {
@@ -62,7 +33,12 @@ export class Schema {
62
33
const { href } = new URL ( $ref , $id )
63
34
const validator = ajv . getSchema ( href )
64
35
65
- if ( ! validator ) throw new TypeError ( 'Schema not found: ' + href )
36
+ if ( validator === undefined ) throw new TypeError ( 'Schema not found: ' + href )
37
+
38
+ // Schema definition is a primitive, just return it
39
+ if ( typeof validator . schema !== 'object' ) return validator . schema
40
+
41
+ // Create a new proxy to the schema definition
66
42
if ( ! validator . proxy ) validator . proxy = Schema . proxy ( href , validator . schema )
67
43
68
44
return validator . proxy
@@ -73,10 +49,11 @@ export class Schema {
73
49
}
74
50
75
51
constructor ( $id , definition ) {
76
- this . definition = new Proxy ( { $id, ...definition } , Dereference )
52
+ this . $id = $id
53
+ this . definition = new Proxy ( definition , this )
77
54
}
78
55
79
- resolve ( $ref = this . definition . $ref , $id = this . definition . $id ) {
56
+ resolve ( $ref = this . definition . $ref , $id = this . $id ) {
80
57
return Schema . resolve ( $ref , $id )
81
58
}
82
59
@@ -90,11 +67,42 @@ export class Schema {
90
67
}
91
68
92
69
validate ( data ) {
93
- const validator = ajv . getSchema ( this . definition . $id )
70
+ const validator = ajv . getSchema ( this . $id )
94
71
const valid = validator ( data )
95
72
const errors = validator . errors
96
73
return { valid, errors }
97
74
}
75
+
76
+ // This instance acts as a Proxy to resolve $refs in the schema definition
77
+ get ( target , property ) {
78
+ const value = target [ property ]
79
+
80
+ if ( Array . isArray ( value ) ) {
81
+ // Schema definition returns an array for this property, return the array with all refs resolved
82
+ return value . map ( ( item , i ) => {
83
+ if ( typeof item === 'object' ) {
84
+ return Schema . resolve ( item . $ref || this . join ( `${ property } /${ i } ` ) , this . $id )
85
+ } else {
86
+ return item
87
+ }
88
+ } )
89
+ } else if ( value !== null && typeof value === 'object' ) {
90
+ // Schema definition returns an object for this property, return the subschema and proxy it
91
+ return Schema . proxy ( this . join ( property ) , value )
92
+ } else if ( value !== undefined ) {
93
+ // Schema definition returns a value for this property, just return it
94
+ return value
95
+ } else if ( target . $ref ) {
96
+ // Schema includes a ref, so delegate to it
97
+ return Schema . resolve ( target . $ref , this . $id ) [ property ]
98
+ }
99
+ }
100
+
101
+ join ( path , $id = this . $id ) {
102
+ const url = new URL ( $id )
103
+ url . hash = [ url . hash , path ] . join ( '/' )
104
+ return url . toString ( )
105
+ }
98
106
}
99
107
100
108
export const schema = Schema . resolve ( '#' )
0 commit comments