@@ -284,12 +284,7 @@ export class TsSchemaGenerator {
284284 }
285285
286286 private createDataModelFieldObject ( field : DataModelField ) {
287- const objectFields = [
288- ts . factory . createPropertyAssignment (
289- 'type' ,
290- ts . factory . createStringLiteral ( field . type . type ?? field . type . reference ! . $refText ) ,
291- ) ,
292- ] ;
287+ const objectFields = [ ts . factory . createPropertyAssignment ( 'type' , this . generateFieldTypeLiteral ( field ) ) ] ;
293288
294289 if ( isIdField ( field ) ) {
295290 objectFields . push ( ts . factory . createPropertyAssignment ( 'id' , ts . factory . createTrue ( ) ) ) ;
@@ -323,9 +318,9 @@ export class TsSchemaGenerator {
323318 ) ;
324319 }
325320
326- const defaultValue = this . getMappedDefault ( field ) ;
321+ const defaultValue = this . getFieldMappedDefault ( field ) ;
327322 if ( defaultValue !== undefined ) {
328- if ( typeof defaultValue === 'object' ) {
323+ if ( typeof defaultValue === 'object' && ! Array . isArray ( defaultValue ) ) {
329324 if ( 'call' in defaultValue ) {
330325 objectFields . push (
331326 ts . factory . createPropertyAssignment (
@@ -371,18 +366,20 @@ export class TsSchemaGenerator {
371366 throw new Error ( `Unsupported default value type for field ${ field . name } ` ) ;
372367 }
373368 } else {
374- objectFields . push (
375- ts . factory . createPropertyAssignment (
376- 'default' ,
377- typeof defaultValue === 'string'
378- ? ts . factory . createStringLiteral ( defaultValue )
379- : typeof defaultValue === 'number'
380- ? ts . factory . createNumericLiteral ( defaultValue )
381- : defaultValue === true
382- ? ts . factory . createTrue ( )
383- : ts . factory . createFalse ( ) ,
384- ) ,
385- ) ;
369+ if ( Array . isArray ( defaultValue ) ) {
370+ objectFields . push (
371+ ts . factory . createPropertyAssignment (
372+ 'default' ,
373+ ts . factory . createArrayLiteralExpression (
374+ defaultValue . map ( ( item ) => this . createLiteralNode ( item as any ) ) ,
375+ ) ,
376+ ) ,
377+ ) ;
378+ } else {
379+ objectFields . push (
380+ ts . factory . createPropertyAssignment ( 'default' , this . createLiteralNode ( defaultValue ) ) ,
381+ ) ;
382+ }
386383 }
387384 }
388385
@@ -438,37 +435,44 @@ export class TsSchemaGenerator {
438435 }
439436 }
440437
441- private getMappedDefault (
438+ private getFieldMappedDefault (
442439 field : DataModelField ,
443- ) : string | number | boolean | { call : string ; args : any [ ] } | { authMember : string [ ] } | undefined {
440+ ) : string | number | boolean | unknown [ ] | { call : string ; args : any [ ] } | { authMember : string [ ] } | undefined {
444441 const defaultAttr = getAttribute ( field , '@default' ) ;
445442 if ( ! defaultAttr ) {
446443 return undefined ;
447444 }
448-
449445 const defaultValue = defaultAttr . args [ 0 ] ?. value ;
450446 invariant ( defaultValue , 'Expected a default value' ) ;
447+ return this . getMappedValue ( defaultValue , field . type ) ;
448+ }
451449
452- if ( isLiteralExpr ( defaultValue ) ) {
453- const lit = ( defaultValue as LiteralExpr ) . value ;
454- return field . type . type === 'Boolean'
450+ private getMappedValue (
451+ expr : Expression ,
452+ fieldType : DataModelFieldType ,
453+ ) : string | number | boolean | unknown [ ] | { call : string ; args : any [ ] } | { authMember : string [ ] } | undefined {
454+ if ( isLiteralExpr ( expr ) ) {
455+ const lit = ( expr as LiteralExpr ) . value ;
456+ return fieldType . type === 'Boolean'
455457 ? ( lit as boolean )
456- : [ 'Int' , 'Float' , 'Decimal' , 'BigInt' ] . includes ( field . type . type ! )
458+ : [ 'Int' , 'Float' , 'Decimal' , 'BigInt' ] . includes ( fieldType . type ! )
457459 ? Number ( lit )
458460 : lit ;
459- } else if ( isReferenceExpr ( defaultValue ) && isEnumField ( defaultValue . target . ref ) ) {
460- return defaultValue . target . ref . name ;
461- } else if ( isInvocationExpr ( defaultValue ) ) {
461+ } else if ( isArrayExpr ( expr ) ) {
462+ return expr . items . map ( ( item ) => this . getMappedValue ( item , fieldType ) ) ;
463+ } else if ( isReferenceExpr ( expr ) && isEnumField ( expr . target . ref ) ) {
464+ return expr . target . ref . name ;
465+ } else if ( isInvocationExpr ( expr ) ) {
462466 return {
463- call : defaultValue . function . $refText ,
464- args : defaultValue . args . map ( ( arg ) => this . getLiteral ( arg . value ) ) ,
467+ call : expr . function . $refText ,
468+ args : expr . args . map ( ( arg ) => this . getLiteral ( arg . value ) ) ,
465469 } ;
466- } else if ( this . isAuthMemberAccess ( defaultValue ) ) {
470+ } else if ( this . isAuthMemberAccess ( expr ) ) {
467471 return {
468- authMember : this . getMemberAccessChain ( defaultValue ) ,
472+ authMember : this . getMemberAccessChain ( expr ) ,
469473 } ;
470474 } else {
471- throw new Error ( `Unsupported default value type for field ${ field . name } ` ) ;
475+ throw new Error ( `Unsupported default value type for ${ expr . $type } ` ) ;
472476 }
473477 }
474478
@@ -682,8 +686,16 @@ export class TsSchemaGenerator {
682686 }
683687
684688 private generateFieldTypeLiteral ( field : DataModelField ) : ts . Expression {
685- invariant ( field . type . type || field . type . reference , 'Field type must be a primitive or reference' ) ;
686- return ts . factory . createStringLiteral ( field . type . type ?? field . type . reference ! . $refText ) ;
689+ invariant (
690+ field . type . type || field . type . reference || field . type . unsupported ,
691+ 'Field type must be a primitive, reference, or Unsupported' ,
692+ ) ;
693+
694+ return field . type . type
695+ ? ts . factory . createStringLiteral ( field . type . type )
696+ : field . type . reference
697+ ? ts . factory . createStringLiteral ( field . type . reference . $refText )
698+ : ts . factory . createStringLiteral ( 'unknown' ) ;
687699 }
688700
689701 private createEnumObject ( e : Enum ) {
0 commit comments