22
33Object . defineProperty ( exports , '__esModule' , { value : true } ) ;
44
5+ const $registeredModels = [ ] ;
6+ const $registeredAttributes = [ ] ;
7+ const $registeredRelationships = [ ] ;
8+
59class Model {
6- toJSON ( ) {
7- return { ...this
10+ toDTO ( ) {
11+ const response = {
12+ ...this
13+ } ;
14+ delete response . _type ;
15+ const rels = $registeredRelationships . find ( e => e . klass === this . constructor ) ?? {
16+ attributes : { }
817 } ;
18+ for ( const key in response ) {
19+ if ( rels . attributes [ key ] || response [ key ] instanceof Model ) {
20+ response [ `${ key } Id` ] = response [ key ] ?. id ?? null ;
21+ delete response [ key ] ;
22+ }
23+ }
24+ return response ;
25+ }
26+ toJSON ( maxDepth = 100 ) {
27+ const response = {
28+ ...this
29+ } ;
30+ delete response . _type ;
31+ for ( const key in response ) {
32+ if ( response [ key ] instanceof Model ) {
33+ if ( maxDepth <= 0 ) {
34+ delete response [ key ] ;
35+ } else {
36+ response [ key ] = response [ key ] . toJSON ( maxDepth - 1 ) ;
37+ }
38+ }
39+ }
40+ return response ;
941 }
10-
1142 toFormData ( ) {
1243 const data = this . toJSON ( ) ;
1344 const formData = new FormData ( ) ;
14-
1545 for ( const key in data ) {
1646 if ( data [ key ] === null || data [ key ] === undefined ) {
1747 continue ;
1848 }
19-
2049 if ( Array . isArray ( data [ key ] ) ) {
2150 for ( const value of data [ key ] ) {
2251 formData . append ( key + "[]" , value ) ;
@@ -27,47 +56,49 @@ class Model {
2756 formData . append ( key , data [ key ] ) ;
2857 }
2958 }
30-
3159 return formData ;
3260 }
33-
3461}
3562
36- function debug ( ...args ) {
37- debug . adapter ( ...args ) ;
63+ function debug ( level , ...args ) {
64+ debug . adapter ( level , ...args ) ;
3865}
39-
40- debug . adapter = ( ...args ) => console . warn ( ...args ) ;
66+ debug . adapter = ( level , ...args ) => {
67+ switch ( level ) {
68+ case 'warn' :
69+ console . warn ( ...args ) ;
70+ break ;
71+ case 'error' :
72+ console . error ( ...args ) ;
73+ break ;
74+ case 'info' :
75+ default :
76+ console . log ( ...args ) ;
77+ break ;
78+ }
79+ } ;
4180
4281class Parser {
43- static $registeredModels = [ ] ;
44- static $registeredAttributes = [ ] ;
45- static $registeredRelationships = [ ] ;
4682 resolved = { } ;
47-
4883 constructor ( data , included = [ ] ) {
4984 this . data = data ;
5085 this . included = included ;
5186 }
52-
5387 run ( ) {
5488 if ( ! this . data ) {
5589 return null ;
5690 }
57-
5891 const {
5992 data,
6093 included
6194 } = this ;
6295 const fullIncluded = Array . isArray ( data ) ? [ ...data , ...included ] : [ data , ...included ] ;
6396 return this . parse ( data , fullIncluded ) ;
6497 }
65-
6698 parse ( data , included = [ ] ) {
6799 if ( ! data ) {
68100 return null ;
69101 }
70-
71102 if ( Array . isArray ( data ) ) {
72103 return this . parseList ( data , included ) ;
73104 } else if ( "data" in data && ! ( "id" in data ) ) {
@@ -76,119 +107,126 @@ class Parser {
76107 return this . parseElement ( data , included ) ;
77108 }
78109 }
79-
80110 parseList ( list , included ) {
81111 return list . map ( e => {
82112 return this . parseElement ( e , included ) ;
83113 } ) ;
84114 }
85-
86115 parseElement ( element , included ) {
87116 const uniqueKey = `${ element . id } $${ element . type } ` ;
88-
89117 if ( this . resolved [ uniqueKey ] ) {
90118 return this . resolved [ uniqueKey ] ;
91119 }
92-
93120 const loadedElement = Parser . load ( element , included ) ;
94- const model = Parser . $registeredModels . find ( e => e . type === loadedElement . type ) ;
95- const attrData = Parser . $registeredAttributes . find ( e => e . klass === model ?. klass ) ;
96- const relsData = Parser . $registeredRelationships . find ( e => e . klass === model ?. klass ) ;
97- const instance = new ( model ?. klass || Model ) ( ) ;
121+ const model = $registeredModels . find ( e => e . type === loadedElement . type ) ;
122+ const instance = this . wrapWhenPartial ( new ( model ?. klass || Model ) ( ) , loadedElement ) ;
98123 this . resolved [ uniqueKey ] = instance ;
124+ if ( model && model . createFn ) {
125+ return model . createFn ( instance , loadedElement , relation => this . parse ( relation , included ) ) ;
126+ }
127+ const attrData = $registeredAttributes . find ( e => e . klass === model ?. klass ) ;
128+ const relsData = $registeredRelationships . find ( e => e . klass === model ?. klass ) ;
99129 instance . id = loadedElement . id ;
100-
101- for ( const key in loadedElement . attributes ) {
102- const parser = attrData ?. attributes ?. [ key ] ;
103-
130+ instance . _type = loadedElement . type ;
131+ this . parseAttributes ( instance , loadedElement , attrData ) ;
132+ this . parseRelationships ( instance , loadedElement , relsData , included ) ;
133+ return instance ;
134+ }
135+ wrapWhenPartial ( instance , loadedElement ) {
136+ if ( loadedElement . $_partial ) {
137+ return new Proxy ( instance , {
138+ get : function ( target , prop ) {
139+ if ( prop in target ) {
140+ return target [ prop ] ;
141+ }
142+ if ( prop === "$_partial" ) {
143+ return true ;
144+ }
145+ debug ( 'error' , `Trying to call property "${ prop . toString ( ) } " to a model that is not included. Add "${ loadedElement . type } " to included models.` ) ;
146+ return undefined ;
147+ }
148+ } ) ;
149+ }
150+ return instance ;
151+ }
152+ parseRelationships ( instance , loadedElement , relsData , included ) {
153+ for ( const key in loadedElement . relationships ) {
154+ const relation = loadedElement . relationships [ key ] ;
155+ const parser = relsData ?. attributes ?. [ key ] ;
104156 if ( parser ) {
105- instance [ parser . key ] = parser . parser ( loadedElement . attributes [ key ] ) ;
157+ instance [ parser . key ] = parser . parser ( this . parse ( relation , included ) ) ;
106158 } else {
107- instance [ key ] = loadedElement . attributes [ key ] ;
108- debug ( `Undeclared key "${ key } " in "${ loadedElement . type } "` ) ;
159+ instance [ key ] = this . parse ( relation , included ) ;
160+ debug ( 'warn' , `Undeclared relationship "${ key } " in "${ loadedElement . type } "` ) ;
109161 }
110162 }
111-
112- if ( attrData ) {
113- for ( const key in attrData . attributes ) {
114- const parser = attrData . attributes [ key ] ;
115-
163+ if ( relsData ) {
164+ for ( const key in relsData . attributes ) {
165+ const parser = relsData . attributes [ key ] ;
116166 if ( ! ( parser . key in instance ) ) {
117167 if ( "default" in parser ) {
118168 instance [ parser . key ] = parser . default ;
119169 } else {
120- debug ( `Missing attribute "${ key } " in "${ loadedElement . type } "` ) ;
170+ debug ( 'warn' , `Missing relationships "${ key } " in "${ loadedElement . type } "` ) ;
121171 }
122172 }
123173 }
124174 }
125-
126- for ( const key in loadedElement . relationships ) {
127- const relation = loadedElement . relationships [ key ] ;
128- const parser = relsData ?. attributes ?. [ key ] ;
129-
175+ }
176+ parseAttributes ( instance , loadedElement , attrData ) {
177+ for ( const key in loadedElement . attributes ) {
178+ const parser = attrData ?. attributes ?. [ key ] ;
130179 if ( parser ) {
131- instance [ parser . key ] = parser . parser ( this . parse ( relation , included ) ) ;
180+ instance [ parser . key ] = parser . parser ( loadedElement . attributes [ key ] ) ;
132181 } else {
133- instance [ key ] = this . parse ( relation , included ) ;
134- debug ( `Undeclared relationship "${ key } " in "${ loadedElement . type } "` ) ;
182+ instance [ key ] = loadedElement . attributes [ key ] ;
183+ debug ( 'warn' , `Undeclared key "${ key } " in "${ loadedElement . type } "` ) ;
135184 }
136185 }
137-
138- if ( relsData ) {
139- for ( const key in relsData . attributes ) {
140- const parser = relsData . attributes [ key ] ;
141-
186+ if ( attrData ) {
187+ for ( const key in attrData . attributes ) {
188+ const parser = attrData . attributes [ key ] ;
142189 if ( ! ( parser . key in instance ) ) {
143190 if ( "default" in parser ) {
144191 instance [ parser . key ] = parser . default ;
145192 } else {
146- debug ( `Missing relationships "${ key } " in "${ loadedElement . type } "` ) ;
193+ debug ( 'warn' , `Missing attribute "${ key } " in "${ loadedElement . type } "` ) ;
147194 }
148195 }
149196 }
150197 }
151-
152- return instance ;
153198 }
154-
155199 static load ( element , included ) {
156200 const found = included . find ( e => e . id == element . id && e . type === element . type ) ;
157-
158201 if ( ! found ) {
159- debug ( `Relationship with type ${ element . type } with id ${ element . id } not present in included` ) ;
202+ debug ( 'info' , `Relationship with type ${ element . type } with id ${ element . id } not present in included` ) ;
160203 }
161-
162- return found || { ...element ,
204+ return found || {
205+ ...element ,
163206 $_partial : true
164207 } ;
165208 }
166-
167209}
168210
169211function Attr ( sourceKey , options = {
170212 parser : v => v
171213} ) {
172214 return function _Attr ( klass , key ) {
173- let model = Parser . $registeredAttributes . find ( e => e . klass === klass . constructor ) ;
174-
215+ let model = $registeredAttributes . find ( e => e . klass === klass . constructor ) ;
175216 if ( ! model ) {
176217 model = {
177218 attributes : { } ,
178219 klass : klass . constructor
179220 } ;
180- Parser . $registeredAttributes . push ( model ) ;
221+ $registeredAttributes . push ( model ) ;
181222 }
182-
183223 const data = {
184224 parser : options . parser ?? ( v => v ) ,
185225 key
186226 } ;
187-
188227 if ( "default" in options ) {
189228 data . default = options . default ;
190229 }
191-
192230 model . attributes [ sourceKey ?? key ] = data ;
193231 } ;
194232}
@@ -197,16 +235,14 @@ function Rel(sourceKey, options = {
197235 parser : v => v
198236} ) {
199237 return function _Rel ( klass , key ) {
200- let model = Parser . $registeredRelationships . find ( e => e . klass === klass . constructor ) ;
201-
238+ let model = $registeredRelationships . find ( e => e . klass === klass . constructor ) ;
202239 if ( ! model ) {
203240 model = {
204241 attributes : { } ,
205242 klass : klass . constructor
206243 } ;
207- Parser . $registeredRelationships . push ( model ) ;
244+ $registeredRelationships . push ( model ) ;
208245 }
209-
210246 model . attributes [ sourceKey ?? key ] = {
211247 parser : options . parser ?? ( v => v ) ,
212248 key,
@@ -217,7 +253,7 @@ function Rel(sourceKey, options = {
217253
218254function JSONAPI ( type ) {
219255 return function _JSONAPI ( constructor ) {
220- Parser . $registeredModels . push ( {
256+ $registeredModels . push ( {
221257 klass : constructor ,
222258 type
223259 } ) ;
0 commit comments