@@ -10,9 +10,11 @@ const path = require('path');
1010const schema = require ( './utils/schema' ) ;
1111
1212let _url2profile = { } ;
13- let _type2path = { } ;
1413let _url2schema = { } ;
1514
15+ let _type2path = { } ;
16+ let _type2parent = { } ;
17+
1618// register profile://
1719protocols . register ( 'profile' , uri => {
1820 let base = _type2path [ uri . hostname ] ;
@@ -119,6 +121,21 @@ profile.register = function ( type, path ) {
119121 _type2path [ type ] = path ;
120122} ;
121123
124+ /**
125+ * @method inherit
126+ * @param {string } type - Current type
127+ * @param {string } parent - The parent type
128+ *
129+ * Set up a type of inheritance relationship
130+ * When the data cannot be found, it will query the data at the parent type
131+ */
132+ profile . inherit = function ( type , parent ) {
133+ if ( ! _type2path [ parent ] ) {
134+ console . warn ( `The type of inheritance is not registered yet - ${ parent } ` ) ;
135+ }
136+ _type2parent [ type ] = parent ;
137+ } ;
138+
122139/**
123140 * @method reset
124141 *
@@ -146,6 +163,17 @@ profile.registerSchema = function ( url, json ) {
146163 if ( ! _url2profile [ url ] || ! json ) {
147164 return ;
148165 }
166+
167+ if ( url . indexOf ( 'profile://' ) !== 0 ) {
168+ console . error ( `Failed to load profile ${ url } : invalid protocol.` ) ;
169+ return ;
170+ }
171+
172+ let type = url . match ( / ^ p r o f i l e : \/ \/ ( [ ^ \/ ] + ) / ) [ 1 ] ;
173+
174+ if ( _type2parent [ type ] ) {
175+ console . log ( `Failed to register schema ${ url } : only root profile can register schema` ) ;
176+ }
149177 _url2schema [ url ] = schema . json2schema ( json ) ;
150178} ;
151179
@@ -158,12 +186,26 @@ class _Profile extends EventEmitter {
158186 super ( ) ;
159187 this . _url = url ;
160188 this . _data = data ;
189+
190+ let match = url . match ( / ^ p r o f i l e \: \/ \/ ( [ ^ \/ ] + ) \/ ( .* ) $ / ) ;
191+ this . _type = match [ 1 ] ;
192+ this . _file = match [ 2 ] ;
161193 }
162194
163195 get ( key ) {
164- let schema = _url2schema [ this . _url ] ;
196+ let schema = this . getSchema ( this . _type , this . _file ) ;
165197 let target = this . _data [ key ] ;
166198
199+ // Find the data on the inheritance chain
200+ let type = this . _type ;
201+ while ( target === undefined && _type2parent [ type ] ) {
202+ let parent = _type2parent [ type ] ;
203+ let parentUrl = `profile://${ parent } /${ this . _file } ` ;
204+ let patentProfile = _url2profile [ parentUrl ] ;
205+ target = patentProfile ? patentProfile . _data [ key ] : undefined ;
206+ type = parent ;
207+ }
208+
167209 if ( schema && target === undefined ) {
168210 let property = schema . properties [ key ] ;
169211 target = property ? property . default : target ;
@@ -177,7 +219,8 @@ class _Profile extends EventEmitter {
177219 }
178220
179221 set ( key , value ) {
180- let error = schema . validate ( _url2schema [ this . _url ] , key , value ) ;
222+ let json = this . getSchema ( this . _type , this . _file ) ;
223+ let error = schema . validate ( json , key , value ) ;
181224 if ( error ) {
182225 return console . warn ( `Failed to set profile ${ key } : ${ error } ` ) ;
183226 }
@@ -218,6 +261,14 @@ class _Profile extends EventEmitter {
218261 this . _data = data ;
219262 }
220263
264+ getSchema ( ) {
265+ let type = this . _type ;
266+ while ( _type2parent [ type ] ) {
267+ type = _type2parent [ type ] ;
268+ }
269+ return _url2schema [ `profile://${ type } /${ this . _file } ` ] ;
270+ }
271+
221272} // end class Profile
222273
223274// ==========================
0 commit comments