@@ -33,6 +33,16 @@ import {
3333} from ' ./<%= importName %>' ;
3434< % _ }); _% >
3535< % _ const isComposite = model .export === " one-of" || model .export === " any-of" || model .export === " all-of" ; _% >
36+ < % _
37+ // Nested arrays of primitives (besides dates) don't need to have .map(...) called to convert them as the base case will be a noop
38+ // eg. an array of arrays of strings doesn't need to be rendered as `value.map(item0 => item0.map(item1 => item1))`
39+ const canShortCircuitConversion = (property ) => {
40+ if ([" array" , " dictionary" ].includes (property .export )) {
41+ return canShortCircuitConversion (property .link );
42+ }
43+ return property .isPrimitive && ! [" date" , " date-time" ].includes (property .format );
44+ };
45+ _% >
3646
3747< % _ if (model .export === " enum" ) { _% >
3848/**
@@ -126,19 +136,45 @@ export function <%= model.name %>FromJSONTyped(json: any, ignoreDiscriminator: b
126136< % _ } else { _% >
127137 return {
128138
139+ < % _
140+ // Renders the appropriate nested function for .map() or mapValues() for arrays and dictionaries for the given type
141+ const renderNestedFromJsonValue = (type , depth = 0 ) => {
142+ const itemIdentifier = ` item${ depth} ` ;
143+ if (type .isPrimitive ) {
144+ return ` (${ itemIdentifier} ) => ${ [" date" , " date-time" ].includes (type .format ) ? ` new Date(${ itemIdentifier} )` : itemIdentifier} ` ;
145+ } else if (type .export === " array" ) {
146+ return ` (${ itemIdentifier} ) => ${ itemIdentifier} .map(${ renderNestedFromJsonValue (type .link , depth + 1 )} )` ;
147+ } else if (type .export === " dictionary" ) {
148+ return ` (${ itemIdentifier} ) => mapValues(${ itemIdentifier} , ${ renderNestedFromJsonValue (type .link , depth + 1 )} )` ;
149+ }
150+ return ` ${ type .name || type .type } FromJSON` ;
151+ };
152+ // Renders the code to transform a property of the model from its json representation into the model types
153+ const renderFromJsonValue = (property ) => {
154+ const value = ` json['${ property .name } ']` ;
155+ let rendered = ' ' ;
156+ if (canShortCircuitConversion (property)) {
157+ rendered = value;
158+ } else if (property .isPrimitive ) {
159+ rendered = [" date" , " date-time" ].includes (property .format ) ? ` (new Date(${ value} ))` : value;
160+ } else if (property .export === " array" ) {
161+ rendered = ` ((${ value} as Array<any>).map(${ renderNestedFromJsonValue (property .link )} ))` ;
162+ rendered = property .uniqueItems ? ` new Set(${ rendered} )` : rendered;
163+ } else if (property .export === " dictionary" ) {
164+ rendered = ` (mapValues(${ value} , ${ renderNestedFromJsonValue (property .link )} ))` ;
165+ } else {
166+ rendered = ` ${ property .type } FromJSON(${ value} )` ;
167+ }
168+ rendered = property .isNullable ? ` ${ value} === null ? null : ${ rendered} ` : rendered;
169+ rendered = ! property .isRequired ? ` !exists(json, '${ property .name } ') ? undefined : ${ rendered} ` : rendered;
170+ return rendered;
171+ };
172+ _% >
129173< % _ if (model .export === " dictionary" ) { _% >
130174 ... json,
131175< % _ } _% >
132176< % _ model .properties .forEach ((property ) => { _% >
133- < % _ if (property .isPrimitive ) { _% >
134- ' <%= property.typescriptName %>' : < % if (! property .isRequired ) { % > ! exists (json, ' <%- property.name %>' ) ? undefined : < % } % >< % if ([" date" , " date-time" ].includes (property .format ) && property .isNullable ) { % > json[' <%- property.name %>' ] === null ? null : < % } % >< % if ([" date" , " date-time" ].includes (property .format )) { % > (new Date (json[' <%= property.name %>' ]))< % } else { % > json[' <%= property.name %>' ]< % } % > ,
135- < % _ } else if (property .export === ' array' ) { _% >
136- ' <%= property.typescriptName %>' : < % if (! property .isRequired ) { % > ! exists (json, ' <%- property.name %>' ) ? undefined : < % } % >< % if (property .isNullable ) { % > json[' <%- property.name %>' ] === null ? null : < % } % >< %= property .uniqueItems ? ' new Set(' : ' ' % > ((json[' <%= property.name %>' ] as Array < any> ).map (< %= property .type % > FromJSON))< %= property .uniqueItems ? ' )' : ' ' % > ,
137- < % _ } else if (property .export === ' dictionary' ) { _% >
138- ' <%= property.typescriptName %>' : < % if (! property .isRequired ) { % > ! exists (json, ' <%- property.name %>' ) ? undefined : < % } % >< % if (property .isNullable ) { % > json[' <%- property.name %>' ] === null ? null : < % } % > (mapValues (json[' <%= property.name %>' ], < %= property .type % > FromJSON)),
139- < % _ } else { _% >
140- ' <%= property.typescriptName %>' : < % if (! property .isRequired ) { % > ! exists (json, ' <%- property.name %>' ) ? undefined : < % } % >< % if (property .isNullable ) { % > json[' <%- property.name %>' ] === null ? null : < % } % >< %= property .type % > FromJSON (json[' <%= property.name %>' ]),
141- < % _ } _% >
177+ ' <%= property.typescriptName %>' : < %- renderFromJsonValue (property) % > ,
142178< % _ }); _% >
143179 };
144180< % _ } _% >
@@ -173,24 +209,56 @@ export function <%= model.name %>ToJSON(value?: <%= model.name %> | null): any {
173209< % _ } else { _% >
174210 return {
175211
212+ < % _
213+ // Render code to convert a date to its string representation
214+ const renderToJsonDateValue = (identifier , format ) => {
215+ return ` ${ identifier} .toISOString()${ format === ' date' ? ' .substr(0,10)' : ' ' } ` ;
216+ };
217+ // Renders the appropriate nested function for .map() or mapValues() for arrays and dictionaries for the given type
218+ const renderNestedToJsonValue = (type , depth = 0 ) => {
219+ const itemIdentifier = ` item${ depth} ` ;
220+ if (type .isPrimitive ) {
221+ return ` (${ itemIdentifier} ) => ${ [" date" , " date-time" ].includes (type .format ) ? renderToJsonDateValue (itemIdentifier, type .format ) : itemIdentifier} ` ;
222+ } else if (type .export === " array" ) {
223+ return ` (${ itemIdentifier} ) => ${ itemIdentifier} .map(${ renderNestedToJsonValue (type .link , depth + 1 )} )` ;
224+ } else if (type .export === " dictionary" ) {
225+ return ` (${ itemIdentifier} ) => mapValues(${ itemIdentifier} , ${ renderNestedToJsonValue (type .link , depth + 1 )} )` ;
226+ }
227+ return ` ${ type .name || type .type } ToJSON` ;
228+ };
229+ // Renders the code to transform a property of the model to its json representation from the model types
230+ const renderToJsonValue = (property ) => {
231+ const value = ` value.${ property .typescriptName } ` ;
232+ let rendered = ' ' ;
233+
234+ if (canShortCircuitConversion (property)) {
235+ rendered = value;
236+ } else if (property .isPrimitive ) {
237+ rendered = [" date" , " date-time" ].includes (property .format ) ? ` (${ renderToJsonDateValue (value, property .format )} )` : value;
238+ } else if (property .export === " array" ) {
239+ const prefix = property .uniqueItems ? ` Array.from(${ value} as Array<any>)` : ` (${ value} as Array<any>)` ;
240+ rendered = ` (${ prefix} .map(${ renderNestedToJsonValue (property .link )} ))` ;
241+ } else if (property .export === " dictionary" ) {
242+ rendered = ` (mapValues(${ value} , ${ renderNestedToJsonValue (property .link )} ))` ;
243+ } else if (property .type !== " any" ) {
244+ rendered = ` ${ property .type } ToJSON(${ value} )` ;
245+ } else {
246+ rendered = value;
247+ }
248+
249+ if ((property .isPrimitive && [" date" , " date-time" ].includes (property .format )) || (! property .isPrimitive && [" array" , " dictionary" ].includes (property .export ))) {
250+ rendered = property .isNullable ? ` ${ value} === null ? null : ${ rendered} ` : rendered;
251+ rendered = ! property .isRequired ? ` ${ value} === undefined ? undefined : ${ rendered} ` : rendered;
252+ }
253+ return rendered;
254+ };
255+ _% >
176256< % _ if (model .export === " dictionary" ) { _% >
177257 ... value,
178258< % _ } _% >
179259< % _ model .properties .forEach ((property ) => { _% >
180260< % _ if (! property .isReadOnly ) { _% >
181- < % _ if (property .isPrimitive && [" date" , " date-time" ].includes (property .format )) { _% >
182- ' <%= property.name %>' : < % if (! property .isRequired ) { % > value.< %- property .typescriptName % > === undefined ? undefined : < % } % > (< % if (property .isNullable ) { % > value.< %- property .typescriptName % > === null ? null : < % } % > value.< %- property .typescriptName % > .toISOString ()< % if (property .format === ' date' ) { % > .substr (0 ,10 )< % } % > ),
183- < % _ } else if (property .isPrimitive ) { _% >
184- ' <%= property.name %>' : value.< %- property .typescriptName % > ,
185- < % _ } else if (property .export === ' array' ) { _% >
186- ' <%= property.name %>' : < % if (! property .isRequired ) { % > value.< %- property .typescriptName % > === undefined ? undefined : < % } % > (< % if (property .isNullable ) { % > value.< %- property .typescriptName % > === null ? null : < % } % >< % if (property .uniqueItems ) { % > Array .from (value.< %- property .typescriptName % > as Set < any> )< % } else { % > (value.< %- property .typescriptName % > as Array < any> )< % } % > .map (< %- property .type % > ToJSON)),
187- < % _ } else if (property .export === ' dictionary' ) { _% >
188- ' <%= property.name %>' : < % if (! property .isRequired ) { % > value.< %- property .typescriptName % > === undefined ? undefined : < % } % > (< % if (property .isNullable ) { % > value.< %- property .typescriptName % > === null ? null : < % } % > mapValues (value.< %- property .typescriptName % > , < %- property .type % > ToJSON)),
189- < % _ } else if (property .type !== ' any' ) { _% >
190- ' <%= property.name %>' : < %- property .type % > ToJSON (value.< %- property .typescriptName % > ),
191- < % _ } else { _% >
192- ' <%= property.name %>' : value.< %- property .typescriptName % > ,
193- < % _ } _% >
261+ ' <%= property.name %>' : < %- renderToJsonValue (property) % > ,
194262< % _ } _% >
195263< % _ }); _% >
196264 };
0 commit comments