@@ -64,13 +64,12 @@ export type TsSchemaGeneratorOptions = {
6464
6565export class TsSchemaGenerator {
6666 private usedExpressionUtils = false ;
67+ private usedAttributeApplication = false ;
68+ private usedFieldDefault = false ;
6769
6870 async generate ( model : Model , options : TsSchemaGeneratorOptions ) {
6971 fs . mkdirSync ( options . outDir , { recursive : true } ) ;
7072
71- // Reset the flag for each generation
72- this . usedExpressionUtils = false ;
73-
7473 // the schema itself
7574 this . generateSchema ( model , options ) ;
7675
@@ -95,6 +94,11 @@ export class TsSchemaGenerator {
9594 }
9695
9796 for ( const { lite, file } of targets ) {
97+ // Reset per-target import flags so each target tracks its own usage
98+ this . usedExpressionUtils = false ;
99+ this . usedAttributeApplication = false ;
100+ this . usedFieldDefault = false ;
101+
98102 const statements : ts . Statement [ ] = [ ] ;
99103 this . generateSchemaStatements ( model , statements , lite ) ;
100104 this . generateBannerComments ( statements ) ;
@@ -130,6 +134,24 @@ export class TsSchemaGenerator {
130134 undefined ,
131135 ts . factory . createNamedImports ( [
132136 ts . factory . createImportSpecifier ( true , undefined , ts . factory . createIdentifier ( 'SchemaDef' ) ) ,
137+ ...( this . usedAttributeApplication
138+ ? [
139+ ts . factory . createImportSpecifier (
140+ true ,
141+ undefined ,
142+ ts . factory . createIdentifier ( 'AttributeApplication' ) ,
143+ ) ,
144+ ]
145+ : [ ] ) ,
146+ ...( this . usedFieldDefault
147+ ? [
148+ ts . factory . createImportSpecifier (
149+ true ,
150+ undefined ,
151+ ts . factory . createIdentifier ( 'FieldDefault' ) ,
152+ ) ,
153+ ]
154+ : [ ] ) ,
133155 ...( this . usedExpressionUtils
134156 ? [
135157 ts . factory . createImportSpecifier (
@@ -285,6 +307,22 @@ export class TsSchemaGenerator {
285307 return ts . factory . createAsExpression ( expr , ts . factory . createTypeReferenceNode ( 'const' ) ) ;
286308 }
287309
310+ private createAttributesTypeAssertion ( expr : ts . Expression ) : ts . Expression {
311+ this . usedAttributeApplication = true ;
312+ return ts . factory . createAsExpression (
313+ expr ,
314+ ts . factory . createTypeOperatorNode (
315+ ts . SyntaxKind . ReadonlyKeyword ,
316+ ts . factory . createArrayTypeNode ( ts . factory . createTypeReferenceNode ( 'AttributeApplication' ) ) ,
317+ ) ,
318+ ) ;
319+ }
320+
321+ private createDefaultTypeAssertion ( expr : ts . Expression ) : ts . Expression {
322+ this . usedFieldDefault = true ;
323+ return ts . factory . createAsExpression ( expr , ts . factory . createTypeReferenceNode ( 'FieldDefault' ) ) ;
324+ }
325+
288326 private createProviderObject ( model : Model ) : ts . Expression {
289327 const dsProvider = this . getDataSourceProvider ( model ) ;
290328 const defaultSchema = this . getDataSourceDefaultSchema ( model ) ;
@@ -374,9 +412,11 @@ export class TsSchemaGenerator {
374412 ? [
375413 ts . factory . createPropertyAssignment (
376414 'attributes' ,
377- ts . factory . createArrayLiteralExpression (
378- allAttributes . map ( ( attr ) => this . createAttributeObject ( attr ) ) ,
379- true ,
415+ this . createAttributesTypeAssertion (
416+ ts . factory . createArrayLiteralExpression (
417+ allAttributes . map ( ( attr ) => this . createAttributeObject ( attr ) ) ,
418+ true ,
419+ ) ,
380420 ) ,
381421 ) ,
382422 ]
@@ -458,9 +498,11 @@ export class TsSchemaGenerator {
458498 ? [
459499 ts . factory . createPropertyAssignment (
460500 'attributes' ,
461- ts . factory . createArrayLiteralExpression (
462- allAttributes . map ( ( attr ) => this . createAttributeObject ( attr ) ) ,
463- true ,
501+ this . createAttributesTypeAssertion (
502+ ts . factory . createArrayLiteralExpression (
503+ allAttributes . map ( ( attr ) => this . createAttributeObject ( attr ) ) ,
504+ true ,
505+ ) ,
464506 ) ,
465507 ) ,
466508 ]
@@ -608,71 +650,56 @@ export class TsSchemaGenerator {
608650 objectFields . push (
609651 ts . factory . createPropertyAssignment (
610652 'attributes' ,
611- ts . factory . createArrayLiteralExpression (
612- field . attributes . map ( ( attr ) => this . createAttributeObject ( attr ) ) ,
653+ this . createAttributesTypeAssertion (
654+ ts . factory . createArrayLiteralExpression (
655+ field . attributes . map ( ( attr ) => this . createAttributeObject ( attr ) ) ,
656+ ) ,
613657 ) ,
614658 ) ,
615659 ) ;
616660 }
617661
618662 const defaultValue = this . getFieldMappedDefault ( field ) ;
619663 if ( defaultValue !== undefined ) {
664+ let defaultExpr : ts . Expression ;
620665 if ( defaultValue === null ) {
621- objectFields . push (
622- ts . factory . createPropertyAssignment ( 'default' , this . createExpressionUtilsCall ( '_null' ) ) ,
623- ) ;
666+ defaultExpr = this . createExpressionUtilsCall ( '_null' ) ;
624667 } else if ( typeof defaultValue === 'object' && ! Array . isArray ( defaultValue ) ) {
625668 if ( 'call' in defaultValue ) {
626- objectFields . push (
627- ts . factory . createPropertyAssignment (
628- 'default' ,
629- this . createExpressionUtilsCall ( 'call' , [
630- ts . factory . createStringLiteral ( defaultValue . call ) ,
631- ...( defaultValue . args . length > 0
632- ? [
633- ts . factory . createArrayLiteralExpression (
634- defaultValue . args . map ( ( arg ) =>
635- this . createExpressionUtilsCall ( 'literal' , [
636- this . createLiteralNode ( arg ) ,
637- ] ) ,
638- ) ,
639- ) ,
640- ]
641- : [ ] ) ,
642- ] ) ,
643- ) ,
644- ) ;
669+ defaultExpr = this . createExpressionUtilsCall ( 'call' , [
670+ ts . factory . createStringLiteral ( defaultValue . call ) ,
671+ ...( defaultValue . args . length > 0
672+ ? [
673+ ts . factory . createArrayLiteralExpression (
674+ defaultValue . args . map ( ( arg ) =>
675+ this . createExpressionUtilsCall ( 'literal' , [
676+ this . createLiteralNode ( arg ) ,
677+ ] ) ,
678+ ) ,
679+ ) ,
680+ ]
681+ : [ ] ) ,
682+ ] ) ;
645683 } else if ( 'authMember' in defaultValue ) {
646- objectFields . push (
647- ts . factory . createPropertyAssignment (
648- 'default' ,
649- this . createExpressionUtilsCall ( 'member' , [
650- this . createExpressionUtilsCall ( 'call' , [ ts . factory . createStringLiteral ( 'auth' ) ] ) ,
651- ts . factory . createArrayLiteralExpression (
652- defaultValue . authMember . map ( ( m ) => ts . factory . createStringLiteral ( m ) ) ,
653- ) ,
654- ] ) ,
684+ defaultExpr = this . createExpressionUtilsCall ( 'member' , [
685+ this . createExpressionUtilsCall ( 'call' , [ ts . factory . createStringLiteral ( 'auth' ) ] ) ,
686+ ts . factory . createArrayLiteralExpression (
687+ defaultValue . authMember . map ( ( m ) => ts . factory . createStringLiteral ( m ) ) ,
655688 ) ,
656- ) ;
689+ ] ) ;
657690 } else {
658691 throw new Error ( `Unsupported default value type for field ${ field . name } ` ) ;
659692 }
693+ } else if ( Array . isArray ( defaultValue ) ) {
694+ defaultExpr = ts . factory . createArrayLiteralExpression (
695+ defaultValue . map ( ( item ) => this . createLiteralNode ( item as any ) ) ,
696+ ) ;
660697 } else {
661- if ( Array . isArray ( defaultValue ) ) {
662- objectFields . push (
663- ts . factory . createPropertyAssignment (
664- 'default' ,
665- ts . factory . createArrayLiteralExpression (
666- defaultValue . map ( ( item ) => this . createLiteralNode ( item as any ) ) ,
667- ) ,
668- ) ,
669- ) ;
670- } else {
671- objectFields . push (
672- ts . factory . createPropertyAssignment ( 'default' , this . createLiteralNode ( defaultValue ) ) ,
673- ) ;
674- }
698+ defaultExpr = this . createLiteralNode ( defaultValue ) ;
675699 }
700+ objectFields . push (
701+ ts . factory . createPropertyAssignment ( 'default' , this . createDefaultTypeAssertion ( defaultExpr ) ) ,
702+ ) ;
676703 }
677704
678705 if ( hasAttribute ( field , '@computed' ) ) {
@@ -688,9 +715,17 @@ export class TsSchemaGenerator {
688715 objectFields . push (
689716 ts . factory . createPropertyAssignment (
690717 'foreignKeyFor' ,
691- ts . factory . createArrayLiteralExpression (
692- fkFor . map ( ( fk ) => ts . factory . createStringLiteral ( fk ) ) ,
693- true ,
718+ ts . factory . createAsExpression (
719+ ts . factory . createArrayLiteralExpression (
720+ fkFor . map ( ( fk ) => ts . factory . createStringLiteral ( fk ) ) ,
721+ true ,
722+ ) ,
723+ ts . factory . createTypeOperatorNode (
724+ ts . SyntaxKind . ReadonlyKeyword ,
725+ ts . factory . createArrayTypeNode (
726+ ts . factory . createKeywordTypeNode ( ts . SyntaxKind . StringKeyword ) ,
727+ ) ,
728+ ) ,
694729 ) ,
695730 ) ,
696731 ) ;
@@ -1070,11 +1105,13 @@ export class TsSchemaGenerator {
10701105 ? [
10711106 ts . factory . createPropertyAssignment (
10721107 'attributes' ,
1073- ts . factory . createArrayLiteralExpression (
1074- field . attributes ?. map ( ( attr ) =>
1075- this . createAttributeObject ( attr ) ,
1076- ) ?? [ ] ,
1077- true ,
1108+ this . createAttributesTypeAssertion (
1109+ ts . factory . createArrayLiteralExpression (
1110+ field . attributes ?. map ( ( attr ) =>
1111+ this . createAttributeObject ( attr ) ,
1112+ ) ?? [ ] ,
1113+ true ,
1114+ ) ,
10781115 ) ,
10791116 ) ,
10801117 ]
@@ -1094,9 +1131,11 @@ export class TsSchemaGenerator {
10941131 ? [
10951132 ts . factory . createPropertyAssignment (
10961133 'attributes' ,
1097- ts . factory . createArrayLiteralExpression (
1098- e . attributes . map ( ( attr ) => this . createAttributeObject ( attr ) ) ,
1099- true ,
1134+ this . createAttributesTypeAssertion (
1135+ ts . factory . createArrayLiteralExpression (
1136+ e . attributes . map ( ( attr ) => this . createAttributeObject ( attr ) ) ,
1137+ true ,
1138+ ) ,
11001139 ) ,
11011140 ) ,
11021141 ]
0 commit comments