1- import { OpenAPIObject } from " @nestjs/swagger" ;
2- import chalk from " chalk" ;
3- import * as fsSync from " node:fs" ;
4- import * as fs from " node:fs/promises" ;
5- import openapiTS from " openapi-typescript" ;
6- import * as ts from " typescript" ;
1+ import { OpenAPIObject } from ' @nestjs/swagger' ;
2+ import chalk from ' chalk' ;
3+ import * as fsSync from ' node:fs' ;
4+ import * as fs from ' node:fs/promises' ;
5+ import openapiTS from ' openapi-typescript' ;
6+ import * as ts from ' typescript' ;
77
8- const DEFAULT_OUTPUT_DIR = " ./generated" ;
9- const DEFAULT_FILENAME = " openapi.d.ts" ;
8+ const DEFAULT_OUTPUT_DIR = ' ./generated' ;
9+ const DEFAULT_FILENAME = ' openapi.d.ts' ;
1010
1111interface OpenApiSpec {
1212 document : OpenAPIObject ;
@@ -18,79 +18,64 @@ type TransformableSchema = {
1818 nullable ?: boolean ;
1919} ;
2020
21- export async function generateOpenApiSpecs (
22- specs : OpenApiSpec [ ]
23- ) : Promise < void > {
21+ export async function generateOpenApiSpecs ( specs : OpenApiSpec [ ] ) : Promise < void > {
2422 if ( specs . length === 0 ) {
25- console . log ( chalk . yellow ( " ⚠️ No OpenAPI specs provided" ) ) ;
23+ console . log ( chalk . yellow ( ' ⚠️ No OpenAPI specs provided' ) ) ;
2624 return ;
2725 }
2826
2927 console . log ( chalk . blue ( `🔄 Generating ${ specs . length } OpenAPI spec(s)...` ) ) ;
3028
3129 // Generate all specs in parallel
32- const results = await Promise . allSettled (
33- specs . map ( spec => generateSingleSpec ( spec ) )
34- ) ;
30+ const results = await Promise . allSettled ( specs . map ( ( spec ) => generateSingleSpec ( spec ) ) ) ;
3531
3632 // Process results
37- const successful = results . filter (
38- result => result . status === "fulfilled"
39- ) . length ;
40- const failed = results . filter ( result => result . status === "rejected" ) . length ;
33+ const successful = results . filter ( ( result ) => result . status === 'fulfilled' ) . length ;
34+ const failed = results . filter ( ( result ) => result . status === 'rejected' ) . length ;
4135
4236 if ( failed > 0 ) {
4337 console . log ( chalk . yellow ( `⚠️ ${ failed } spec(s) failed to generate` ) ) ;
4438 results . forEach ( ( result , index ) => {
45- if ( result . status === " rejected" ) {
39+ if ( result . status === ' rejected' ) {
4640 console . error (
4741 chalk . red (
48- `❌ Spec ${ index + 1 } (${ specs [ index ] ?. fileName || DEFAULT_FILENAME } ): ${ result . reason } `
49- )
42+ `❌ Spec ${ index + 1 } (${ specs [ index ] ?. fileName || DEFAULT_FILENAME } ): ${ result . reason } ` ,
43+ ) ,
5044 ) ;
5145 }
5246 } ) ;
5347 }
5448
5549 if ( successful > 0 ) {
56- console . log (
57- chalk . green ( `✅ ${ successful } OpenAPI spec(s) generated successfully` )
58- ) ;
50+ console . log ( chalk . green ( `✅ ${ successful } OpenAPI spec(s) generated successfully` ) ) ;
5951 }
6052
6153 if ( failed === specs . length ) {
62- throw new Error ( " All OpenAPI specs failed to generate" ) ;
54+ throw new Error ( ' All OpenAPI specs failed to generate' ) ;
6355 }
6456}
6557
6658async function generateSingleSpec ( spec : OpenApiSpec ) : Promise < void > {
6759 const fileName = spec . fileName || DEFAULT_FILENAME ;
6860 const filePath = `${ DEFAULT_OUTPUT_DIR } /${ fileName } ` ;
6961
70- const BLOB = ts . factory . createTypeReferenceNode (
71- ts . factory . createIdentifier ( "Blob" )
72- ) ; // `Blob`
62+ const BLOB = ts . factory . createTypeReferenceNode ( ts . factory . createIdentifier ( 'Blob' ) ) ; // `Blob`
7363 const NULL = ts . factory . createLiteralTypeNode ( ts . factory . createNull ( ) ) ; // `null`
7464
7565 try {
7666 // Generate new OpenAPI types content
77- const ast = await openapiTS (
78- spec . document as Parameters < typeof openapiTS > [ 0 ] ,
79- {
80- transform ( schemaObject : TransformableSchema ) {
81- if ( schemaObject . format === "binary" ) {
82- return schemaObject . nullable
83- ? ts . factory . createUnionTypeNode ( [ BLOB , NULL ] )
84- : BLOB ;
85- }
86- return undefined ; // Use default transformation for other schema objects
67+ const ast = await openapiTS ( spec . document as Parameters < typeof openapiTS > [ 0 ] , {
68+ transform ( schemaObject : TransformableSchema ) {
69+ if ( schemaObject . format === 'binary' ) {
70+ return schemaObject . nullable ? ts . factory . createUnionTypeNode ( [ BLOB , NULL ] ) : BLOB ;
8771 }
88- }
89- ) ;
72+ return undefined ; // Use default transformation for other schema objects
73+ } ,
74+ } ) ;
9075 const sourceFile = ts . factory . createSourceFile (
9176 ast as ts . Statement [ ] ,
9277 ts . factory . createToken ( ts . SyntaxKind . EndOfFileToken ) ,
93- ts . NodeFlags . None
78+ ts . NodeFlags . None ,
9479 ) ;
9580 const newContents = ts
9681 . createPrinter ( { newLine : ts . NewLineKind . LineFeed } )
@@ -107,36 +92,30 @@ async function generateSingleSpec(spec: OpenApiSpec): Promise<void> {
10792 } catch ( error ) {
10893 const errorMessage = error instanceof Error ? error . message : String ( error ) ;
10994 throw new Error ( `Failed to generate ${ fileName } : ${ errorMessage } ` , {
110- cause : error
95+ cause : error ,
11196 } ) ;
11297 }
11398}
11499
115- async function hasContentChanged (
116- filePath : string ,
117- newContents : string
118- ) : Promise < boolean > {
100+ async function hasContentChanged ( filePath : string , newContents : string ) : Promise < boolean > {
119101 if ( ! fsSync . existsSync ( filePath ) ) {
120102 return true ;
121103 }
122104
123105 try {
124- const existingContents = await fs . readFile ( filePath , " utf8" ) ;
106+ const existingContents = await fs . readFile ( filePath , ' utf8' ) ;
125107 return existingContents !== newContents ;
126108 } catch {
127109 return true ;
128110 }
129111}
130112
131- async function writeOpenApiFile (
132- filePath : string ,
133- contents : string
134- ) : Promise < void > {
113+ async function writeOpenApiFile ( filePath : string , contents : string ) : Promise < void > {
135114 // Ensure directory exists
136115 await fs . mkdir ( DEFAULT_OUTPUT_DIR , { recursive : true } ) ;
137116
138117 // Write file
139- await fs . writeFile ( filePath , contents , " utf8" ) ;
118+ await fs . writeFile ( filePath , contents , ' utf8' ) ;
140119}
141120
142121// Convenience function for single spec (backward compatibility)
0 commit comments