1
1
import * as ts from 'typescript' ;
2
- import * as fs from 'fs' ;
3
- import chalk from 'chalk' ;
2
+ import * as path from 'path' ;
4
3
import { camelCase } from 'lodash' ;
5
4
import ApiGenerator , {
6
5
getOperationName ,
@@ -12,15 +11,16 @@ import { createQuestionToken, keywordType } from 'oazapfts/lib/codegen/tscodegen
12
11
import { OpenAPIV3 } from 'openapi-types' ;
13
12
import { generateReactHooks } from './generators/react-hooks' ;
14
13
import { GenerationOptions , OperationDefinition } from './types' ;
15
- import { capitalize , getOperationDefinitions , getV3Doc , isQuery , MESSAGES , stripFileExtension } from './utils' ;
14
+ import { capitalize , getOperationDefinitions , getV3Doc , isQuery , MESSAGES } from './utils' ;
16
15
import { removeUndefined } from './utils/removeUndefined' ;
17
16
import {
18
17
generateCreateApiCall ,
19
- generateImportNode ,
20
18
generateEndpointDefinition ,
21
19
generateStringLiteralArray ,
22
20
ObjectPropertyDefinitions ,
23
21
} from './codegen' ;
22
+ import { generateSmartImportNode } from './generators/smart-import-node' ;
23
+ import { generateImportNode } from './generators/import-node' ;
24
24
25
25
const { factory } = ts ;
26
26
@@ -30,7 +30,7 @@ function defaultIsDataResponse(code: string) {
30
30
}
31
31
32
32
let customBaseQueryNode : ts . ImportDeclaration | undefined ;
33
- let baseQueryFn : string , filePath : string ;
33
+ let moduleName : string ;
34
34
35
35
export async function generateApi (
36
36
spec : string ,
@@ -42,7 +42,9 @@ export async function generateApi(
42
42
responseSuffix = 'ApiResponse' ,
43
43
baseUrl,
44
44
hooks,
45
+ outputFile,
45
46
isDataResponse = defaultIsDataResponse ,
47
+ compilerOptions,
46
48
} : GenerationOptions
47
49
) {
48
50
const v3Doc = await getV3Doc ( spec ) ;
@@ -80,76 +82,37 @@ export async function generateApi(
80
82
* 3. If there is a not a seperator, file presence + default export existence is verified.
81
83
*/
82
84
83
- function fnExportExists ( path : string , fnName : string ) {
84
- const fileName = `${ process . cwd ( ) } /${ path } ` ;
85
-
86
- const sourceFile = ts . createSourceFile (
87
- fileName ,
88
- fs . readFileSync ( fileName ) . toString ( ) ,
89
- ts . ScriptTarget . ES2015 ,
90
- /*setParentNodes */ true
91
- ) ;
92
-
93
- let found = false ;
94
-
95
- ts . forEachChild ( sourceFile , ( node ) => {
96
- const text = node . getText ( ) ;
97
- if ( ts . isExportAssignment ( node ) ) {
98
- if ( text . includes ( fnName ) ) {
99
- found = true ;
100
- }
101
- } else if ( ts . isVariableStatement ( node ) || ts . isFunctionDeclaration ( node ) || ts . isExportDeclaration ( node ) ) {
102
- if ( text . includes ( fnName ) && text . includes ( 'export' ) ) {
103
- found = true ;
104
- }
105
- } else if ( ts . isExportAssignment ( node ) ) {
106
- if ( text . includes ( `export ${ fnName } ` ) ) {
107
- found = true ;
108
- }
109
- }
110
- } ) ;
111
-
112
- return found ;
85
+ if ( outputFile ) {
86
+ outputFile = path . resolve ( process . cwd ( ) , outputFile ) ;
113
87
}
114
88
115
89
// If a baseQuery was specified as an arg, we try to parse and resolve it. If not, fallback to `fetchBaseQuery` or throw when appropriate.
90
+
91
+ let targetName = 'default' ;
116
92
if ( baseQuery !== 'fetchBaseQuery' ) {
117
93
if ( baseQuery . includes ( ':' ) ) {
118
94
// User specified a named function
119
- [ filePath , baseQueryFn ] = baseQuery . split ( ':' ) ;
95
+ [ moduleName , baseQuery ] = baseQuery . split ( ':' ) ;
120
96
121
- if ( ! baseQueryFn || ! fnExportExists ( filePath , baseQueryFn ) ) {
97
+ if ( ! baseQuery ) {
122
98
throw new Error ( MESSAGES . NAMED_EXPORT_MISSING ) ;
123
- } else if ( ! fs . existsSync ( filePath ) ) {
124
- throw new Error ( MESSAGES . FILE_NOT_FOUND ) ;
125
99
}
126
-
127
- customBaseQueryNode = generateImportNode ( stripFileExtension ( filePath ) , {
128
- [ baseQueryFn ] : baseQueryFn ,
129
- } ) ;
100
+ targetName = baseQuery ;
130
101
} else {
131
- filePath = baseQuery ;
132
- baseQueryFn = 'fetchBaseQuery' ;
133
-
134
- if ( ! fs . existsSync ( filePath ) ) {
135
- throw new Error ( MESSAGES . FILE_NOT_FOUND ) ;
136
- } else if ( ! fnExportExists ( filePath , 'default' ) ) {
137
- throw new Error ( MESSAGES . DEFAULT_EXPORT_MISSING ) ;
138
- }
139
-
140
- console . warn ( chalk `
141
- {yellow.bold A custom baseQuery was specified without a named function. We're going to import the default as {underline customBaseQuery}}
142
- ` ) ;
143
-
144
- baseQueryFn = 'customBaseQuery' ;
145
-
146
- customBaseQueryNode = generateImportNode ( stripFileExtension ( filePath ) , {
147
- default : baseQueryFn ,
148
- } ) ;
102
+ moduleName = baseQuery ;
103
+ baseQuery = 'customBaseQuery' ;
149
104
}
105
+
106
+ customBaseQueryNode = generateSmartImportNode ( {
107
+ moduleName,
108
+ containingFile : outputFile ,
109
+ targetName,
110
+ targetAlias : baseQuery ,
111
+ compilerOptions,
112
+ } ) ;
150
113
}
151
114
152
- const baseQueryCall = factory . createCallExpression ( factory . createIdentifier ( baseQueryFn || baseQuery ) , undefined , [
115
+ const baseQueryCall = factory . createCallExpression ( factory . createIdentifier ( baseQuery ) , undefined , [
153
116
factory . createObjectLiteralExpression (
154
117
[
155
118
factory . createPropertyAssignment (
@@ -197,28 +160,6 @@ export async function generateApi(
197
160
198
161
return sourceCode ;
199
162
200
- function generateImportNode ( pkg : string , namedImports : Record < string , string > , defaultImportName ?: string ) {
201
- return factory . createImportDeclaration (
202
- undefined ,
203
- undefined ,
204
- factory . createImportClause (
205
- false ,
206
- defaultImportName !== undefined ? factory . createIdentifier ( defaultImportName ) : undefined ,
207
- factory . createNamedImports (
208
- Object . entries ( namedImports )
209
- . filter ( ( args ) => args [ 1 ] )
210
- . map ( ( [ propertyName , name ] ) =>
211
- factory . createImportSpecifier (
212
- name === propertyName ? undefined : factory . createIdentifier ( propertyName ) ,
213
- factory . createIdentifier ( name as string )
214
- )
215
- )
216
- )
217
- ) ,
218
- factory . createStringLiteral ( pkg )
219
- ) ;
220
- }
221
-
222
163
function generateEntityTypes ( _ : { operationDefinitions : OperationDefinition [ ] ; v3Doc : OpenAPIV3 . Document } ) {
223
164
return generateStringLiteralArray ( [ ] ) ; // TODO
224
165
}
0 commit comments