@@ -74,9 +74,10 @@ module.exports = class JSONAPISerializer {
7474 * @param {string|object } [schema='default'] resource's schema name.
7575 * @param {object } [extraData] additional data that can be used in topLevelMeta options.
7676 * @param {boolean } [excludeData] boolean that can be set to exclude the `data` property in serialized data.
77+ * @param {object } [overrideSchemaOptions=] additional schema options, a map of types with options to override
7778 * @returns {object } serialized data.
7879 */
79- serialize ( type , data , schema , extraData , excludeData ) {
80+ serialize ( type , data , schema , extraData , excludeData , overrideSchemaOptions = { } ) {
8081 // Support optional arguments (schema)
8182 if ( arguments . length === 3 ) {
8283 if ( typeof schema === 'object' ) {
@@ -108,14 +109,33 @@ module.exports = class JSONAPISerializer {
108109 options = this . schemas [ type ] [ schema ] ;
109110 }
110111
112+ const overrideType = isDynamicType ? type . type : type ;
113+ if ( overrideSchemaOptions [ overrideType ] ) {
114+ // Merge default (registered) options and extra options into new options object
115+ options = { ...options , ...overrideSchemaOptions [ overrideType ] } ;
116+ }
117+
111118 let dataProperty ;
112119
113120 if ( excludeData ) {
114121 dataProperty = undefined ;
115122 } else if ( isDynamicType ) {
116- dataProperty = this . serializeMixedResource ( options , data , included , extraData ) ;
123+ dataProperty = this . serializeMixedResource (
124+ options ,
125+ data ,
126+ included ,
127+ extraData ,
128+ overrideSchemaOptions
129+ ) ;
117130 } else {
118- dataProperty = this . serializeResource ( type , data , options , included , extraData ) ;
131+ dataProperty = this . serializeResource (
132+ type ,
133+ data ,
134+ options ,
135+ included ,
136+ extraData ,
137+ overrideSchemaOptions
138+ ) ;
119139 }
120140
121141 return {
@@ -138,9 +158,10 @@ module.exports = class JSONAPISerializer {
138158 * @param {string } [schema='default'] resource's schema name.
139159 * @param {object } [extraData] additional data that can be used in topLevelMeta options.
140160 * @param {boolean } [excludeData] boolean that can be set to exclude the `data` property in serialized data.
161+ * @param {object } [overrideSchemaOptions=] additional schema options, a map of types with options to override
141162 * @returns {Promise } resolves with serialized data.
142163 */
143- serializeAsync ( type , data , schema , extraData , excludeData ) {
164+ serializeAsync ( type , data , schema , extraData , excludeData , overrideSchemaOptions = { } ) {
144165 // Support optional arguments (schema)
145166 if ( arguments . length === 3 ) {
146167 if ( typeof schema === 'object' ) {
@@ -175,6 +196,12 @@ module.exports = class JSONAPISerializer {
175196 options = this . schemas [ type ] [ schema ] ;
176197 }
177198
199+ const overrideType = isDynamicType ? type . type : type ;
200+ if ( overrideSchemaOptions [ overrideType ] ) {
201+ // Merge default (registered) options and extra options into new options object
202+ options = { ...options , ...overrideSchemaOptions [ overrideType ] } ;
203+ }
204+
178205 return new Promise ( ( resolve , reject ) => {
179206 /**
180207 * Non-blocking serialization using the immediate queue.
@@ -193,8 +220,21 @@ module.exports = class JSONAPISerializer {
193220 try {
194221 // Serialize a single item of the data-array.
195222 const serializedItem = isDynamicType
196- ? that . serializeMixedResource ( type , arrayData [ i ] , included , extraData )
197- : that . serializeResource ( type , arrayData [ i ] , options , included , extraData ) ;
223+ ? that . serializeMixedResource (
224+ type ,
225+ arrayData [ i ] ,
226+ included ,
227+ extraData ,
228+ overrideSchemaOptions
229+ )
230+ : that . serializeResource (
231+ type ,
232+ arrayData [ i ] ,
233+ options ,
234+ included ,
235+ extraData ,
236+ overrideSchemaOptions
237+ ) ;
198238
199239 if ( serializedItem !== null ) {
200240 serializedData . push ( serializedItem ) ;
@@ -525,23 +565,32 @@ module.exports = class JSONAPISerializer {
525565 * @param {object } options resource's configuration options.
526566 * @param {Map<string, object> } [included] Included resources.
527567 * @param {object } [extraData] additional data.
568+ * @param {object } [overrideSchemaOptions=] additional schema options, a map of types with options to override
528569 * @returns {object|object[] } serialized data.
529570 */
530- serializeResource ( type , data , options , included , extraData ) {
571+ serializeResource ( type , data , options , included , extraData , overrideSchemaOptions = { } ) {
531572 if ( isEmpty ( data ) ) {
532573 // Return [] or null
533574 return Array . isArray ( data ) ? data : null ;
534575 }
535576
536577 if ( Array . isArray ( data ) ) {
537- return data . map ( d => this . serializeResource ( type , d , options , included , extraData ) ) ;
578+ return data . map ( d =>
579+ this . serializeResource ( type , d , options , included , extraData , overrideSchemaOptions )
580+ ) ;
538581 }
539582
540583 return {
541584 type,
542585 id : data [ options . id ] ? data [ options . id ] . toString ( ) : undefined ,
543586 attributes : this . serializeAttributes ( data , options ) ,
544- relationships : this . serializeRelationships ( data , options , included , extraData ) ,
587+ relationships : this . serializeRelationships (
588+ data ,
589+ options ,
590+ included ,
591+ extraData ,
592+ overrideSchemaOptions
593+ ) ,
545594 meta : this . processOptionsValues ( data , extraData , options . meta ) ,
546595 links : this . processOptionsValues ( data , extraData , options . links )
547596 } ;
@@ -557,16 +606,19 @@ module.exports = class JSONAPISerializer {
557606 * @param {object|object[] } data input data.
558607 * @param {Map<string, object> } [included] Included resources.
559608 * @param {object } [extraData] additional data.
609+ * @param {object } [overrideSchemaOptions=] additional schema options, a map of types with options to override
560610 * @returns {object|object[] } serialized data.
561611 */
562- serializeMixedResource ( typeOption , data , included , extraData ) {
612+ serializeMixedResource ( typeOption , data , included , extraData , overrideSchemaOptions = { } ) {
563613 if ( isEmpty ( data ) ) {
564614 // Return [] or null
565615 return Array . isArray ( data ) ? data : null ;
566616 }
567617
568618 if ( Array . isArray ( data ) ) {
569- return data . map ( d => this . serializeMixedResource ( typeOption , d , included , extraData ) ) ;
619+ return data . map ( d =>
620+ this . serializeMixedResource ( typeOption , d , included , extraData , overrideSchemaOptions )
621+ ) ;
570622 }
571623
572624 // Resolve type from data (can be a string or a function deriving a type-string from each data-item)
@@ -581,7 +633,13 @@ module.exports = class JSONAPISerializer {
581633 throw new Error ( `No type registered for ${ type } ` ) ;
582634 }
583635
584- return this . serializeResource ( type , data , this . schemas [ type ] . default , included , extraData ) ;
636+ let options = this . schemas [ type ] . default ;
637+ if ( overrideSchemaOptions [ type ] ) {
638+ // Merge default (registered) options and extra options into new options object
639+ options = { ...options , ...overrideSchemaOptions [ type ] } ;
640+ }
641+
642+ return this . serializeResource ( type , data , options , included , extraData , overrideSchemaOptions ) ;
585643 }
586644
587645 /**
@@ -633,9 +691,10 @@ module.exports = class JSONAPISerializer {
633691 * @param {object } options resource's configuration options.
634692 * @param {Map<string, object> } [included] Included resources.
635693 * @param {object } [extraData] additional data.
694+ * @param {object } [overrideSchemaOptions=] additional schema options, a map of types with options to override
636695 * @returns {object } serialized relationships.
637696 */
638- serializeRelationships ( data , options , included , extraData ) {
697+ serializeRelationships ( data , options , included , extraData , overrideSchemaOptions = { } ) {
639698 const serializedRelationships = { } ;
640699
641700 Object . keys ( options . relationships ) . forEach ( relationship => {
@@ -656,7 +715,8 @@ module.exports = class JSONAPISerializer {
656715 get ( data , relationshipKey ) ,
657716 included ,
658717 data ,
659- extraData
718+ extraData ,
719+ overrideSchemaOptions
660720 )
661721 } ;
662722
@@ -689,9 +749,18 @@ module.exports = class JSONAPISerializer {
689749 * @param {Map<string, object> } [included] Included resources.
690750 * @param {object } [data] the entire resource's data.
691751 * @param {object } [extraData] additional data.
752+ * @param {object } [overrideSchemaOptions=] additional schema options, a map of types with options to override
692753 * @returns {object|object[] } serialized relationship data.
693754 */
694- serializeRelationship ( rType , rSchema , rData , included , data , extraData ) {
755+ serializeRelationship (
756+ rType ,
757+ rSchema ,
758+ rData ,
759+ included ,
760+ data ,
761+ extraData ,
762+ overrideSchemaOptions = { }
763+ ) {
695764 included = included || new Map ( ) ;
696765 const schema = rSchema || 'default' ;
697766
@@ -707,7 +776,15 @@ module.exports = class JSONAPISerializer {
707776
708777 if ( Array . isArray ( rData ) ) {
709778 return rData . map ( d =>
710- this . serializeRelationship ( rType , schema , d , included , data , extraData )
779+ this . serializeRelationship (
780+ rType ,
781+ schema ,
782+ d ,
783+ included ,
784+ data ,
785+ extraData ,
786+ overrideSchemaOptions
787+ )
711788 ) ;
712789 }
713790
@@ -726,7 +803,13 @@ module.exports = class JSONAPISerializer {
726803 throw new Error ( `No schema "${ schema } " registered for type "${ type } "` ) ;
727804 }
728805
729- const rOptions = this . schemas [ type ] [ schema ] ;
806+ let rOptions = this . schemas [ type ] [ schema ] ;
807+
808+ if ( overrideSchemaOptions [ type ] ) {
809+ // Merge default (registered) options and extra options into new options object
810+ rOptions = { ...rOptions , ...overrideSchemaOptions [ type ] } ;
811+ }
812+
730813 const serializedRelationship = { type } ;
731814
732815 // Support for unpopulated relationships (an id, or array of ids)
@@ -738,7 +821,7 @@ module.exports = class JSONAPISerializer {
738821 if ( ! ( Object . keys ( rData ) . length === 1 && rData [ rOptions . id ] ) ) {
739822 included . set (
740823 `${ type } -${ serializedRelationship . id } ` ,
741- this . serializeResource ( type , rData , rOptions , included , extraData )
824+ this . serializeResource ( type , rData , rOptions , included , extraData , overrideSchemaOptions )
742825 ) ;
743826 }
744827 }
0 commit comments