@@ -12,7 +12,19 @@ import {
12
12
requireOption ,
13
13
resolvePath ,
14
14
} from '@zenstackhq/sdk' ;
15
- import { DataModel , DataModelField , DataModelFieldType , Enum , isDataModel , isEnum , Model } from '@zenstackhq/sdk/ast' ;
15
+ import {
16
+ DataModel ,
17
+ DataModelField ,
18
+ DataModelFieldType ,
19
+ Enum ,
20
+ isDataModel ,
21
+ isEnum ,
22
+ isTypeDef ,
23
+ Model ,
24
+ TypeDef ,
25
+ TypeDefField ,
26
+ TypeDefFieldType ,
27
+ } from '@zenstackhq/sdk/ast' ;
16
28
import type { DMMF } from '@zenstackhq/sdk/prisma' ;
17
29
import fs from 'fs' ;
18
30
import { lowerCaseFirst } from 'lower-case-first' ;
@@ -79,6 +91,9 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase {
79
91
security,
80
92
} ;
81
93
94
+ // ensure output folder exists
95
+ fs . mkdirSync ( path . dirname ( output ) , { recursive : true } ) ;
96
+
82
97
const ext = path . extname ( output ) ;
83
98
if ( ext && ( ext . toLowerCase ( ) === '.yaml' || ext . toLowerCase ( ) === '.yml' ) ) {
84
99
fs . writeFileSync ( output , YAML . stringify ( openapi ) ) ;
@@ -494,6 +509,8 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase {
494
509
schema = this . ref ( fieldDecl . name ) ;
495
510
} else if ( isDataModel ( fieldDecl ) ) {
496
511
schema = { type : 'string' } ;
512
+ } else if ( isTypeDef ( fieldDecl ) || field . type . type === 'Json' ) {
513
+ schema = { type : 'string' , format : 'json' } ;
497
514
} else {
498
515
invariant ( field . type . type ) ;
499
516
schema = this . fieldTypeToOpenAPISchema ( field . type ) ;
@@ -540,6 +557,11 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase {
540
557
}
541
558
}
542
559
560
+ // type defs
561
+ for ( const typeDef of this . model . declarations . filter ( isTypeDef ) ) {
562
+ schemas [ typeDef . name ] = this . generateTypeDefComponent ( typeDef ) ;
563
+ }
564
+
543
565
return components ;
544
566
}
545
567
@@ -771,7 +793,7 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase {
771
793
} ;
772
794
}
773
795
774
- private generateEnumComponent ( _enum : Enum ) : OAPI . SchemaObject {
796
+ private generateEnumComponent ( _enum : Enum ) {
775
797
const schema : OAPI . SchemaObject = {
776
798
type : 'string' ,
777
799
description : `The "${ _enum . name } " Enum` ,
@@ -780,6 +802,18 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase {
780
802
return schema ;
781
803
}
782
804
805
+ private generateTypeDefComponent ( typeDef : TypeDef ) {
806
+ const schema : OAPI . SchemaObject = {
807
+ type : 'object' ,
808
+ description : `The "${ typeDef . name } " TypeDef` ,
809
+ properties : typeDef . fields . reduce ( ( acc , field ) => {
810
+ acc [ field . name ] = this . generateField ( field ) ;
811
+ return acc ;
812
+ } , { } as Record < string , OAPI . SchemaObject > ) ,
813
+ } ;
814
+ return schema ;
815
+ }
816
+
783
817
private generateDataModelComponents ( model : DataModel ) {
784
818
const result : Record < string , OAPI . SchemaObject > = { } ;
785
819
result [ `${ model . name } ` ] = this . generateModelEntity ( model , 'read' ) ;
@@ -945,14 +979,16 @@ export class RESTfulOpenAPIGenerator extends OpenAPIGeneratorBase {
945
979
return result ;
946
980
}
947
981
948
- private generateField ( field : DataModelField ) {
982
+ private generateField ( field : DataModelField | TypeDefField ) {
949
983
return this . wrapArray (
950
984
this . wrapNullable ( this . fieldTypeToOpenAPISchema ( field . type ) , field . type . optional ) ,
951
985
field . type . array
952
986
) ;
953
987
}
954
988
955
- private fieldTypeToOpenAPISchema ( type : DataModelFieldType ) : OAPI . ReferenceObject | OAPI . SchemaObject {
989
+ private fieldTypeToOpenAPISchema (
990
+ type : DataModelFieldType | TypeDefFieldType
991
+ ) : OAPI . ReferenceObject | OAPI . SchemaObject {
956
992
return match ( type . type )
957
993
. with ( 'String' , ( ) => ( { type : 'string' } ) )
958
994
. with ( P . union ( 'Int' , 'BigInt' ) , ( ) => ( { type : 'integer' } ) )
0 commit comments