Skip to content

Commit 8da8d77

Browse files
committed
return payload data from typescript-axios-slim
1 parent 5c92a6c commit 8da8d77

File tree

3 files changed

+57
-7
lines changed

3 files changed

+57
-7
lines changed

modules/openapi-generator/src/main/resources/typescript-axios-slim/api.mustache

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
{{^withSeparateModelsAndApi}}
77
import type { Configuration } from './configuration{{importFileExtension}}';
8-
import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig, AxiosResponse } from 'axios';
8+
import type { AxiosInstance, RawAxiosRequestConfig } from 'axios';
99
import globalAxios from 'axios';
1010
{{#withNodeImports}}
1111
// URLSearchParams not necessarily used

modules/openapi-generator/src/main/resources/typescript-axios-slim/apiInner.mustache

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66

77
import type { Configuration } from '{{apiRelativeToRoot}}configuration{{importFileExtension}}';
8-
import type { AxiosPromise, AxiosInstance, RawAxiosRequestConfig, AxiosResponse } from 'axios';
8+
import type { AxiosInstance, RawAxiosRequestConfig } from 'axios';
99
import globalAxios from 'axios';
1010
{{#withNodeImports}}
1111
// URLSearchParams not necessarily used
@@ -62,7 +62,7 @@ export interface {{classname}}Interface {
6262
* @deprecated{{/isDeprecated}}
6363
* @throws {RequiredError}
6464
*/
65-
{{nickname}}({{#allParams.0}}requestParameters{{^hasRequiredParams}}?{{/hasRequiredParams}}: {{classname}}{{operationIdCamelCase}}Request, {{/allParams.0}}options?: RawAxiosRequestConfig): AxiosPromise<{{{returnType}}}{{^returnType}}void{{/returnType}}>;
65+
{{nickname}}({{#allParams.0}}requestParameters{{^hasRequiredParams}}?{{/hasRequiredParams}}: {{classname}}{{operationIdCamelCase}}Request, {{/allParams.0}}options?: RawAxiosRequestConfig): Promise<{{{returnType}}}{{^returnType}}void{{/returnType}}>;
6666
6767
{{/operation}}
6868
}
@@ -114,7 +114,7 @@ export class {{classname}} extends BaseAPI {
114114
* @deprecated{{/isDeprecated}}
115115
* @throws {RequiredError}
116116
*/
117-
public async {{nickname}}({{#allParams.0}}requestParameters: {{classname}}{{operationIdCamelCase}}Request{{^hasRequiredParams}} = {}{{/hasRequiredParams}}, {{/allParams.0}}options: RawAxiosRequestConfig = {}): Promise<AxiosResponse<{{{returnType}}}{{^returnType}}void{{/returnType}}>> {
117+
public async {{nickname}}({{#allParams.0}}requestParameters: {{classname}}{{operationIdCamelCase}}Request{{^hasRequiredParams}} = {}{{/hasRequiredParams}}, {{/allParams.0}}options: RawAxiosRequestConfig = {}): Promise<{{{returnType}}}{{^returnType}}void{{/returnType}}> {
118118
{{#allParams.0}}
119119
validateRequestParameters('{{nickname}}', {{nickname}}RequestSchema, requestParameters);
120120
{{/allParams.0}}
@@ -308,7 +308,8 @@ export class {{classname}} extends BaseAPI {
308308
const effectiveBasePath = localVarOperationServerBasePath || this.basePath || BASE_PATH;
309309
localVarRequestOptions.url = (this.axios.defaults.baseURL ? '' : this.configuration?.basePath ?? effectiveBasePath) + toPathString(localVarUrlObj);
310310

311-
return this.axios.request<{{{returnType}}}{{^returnType}}void{{/returnType}}, AxiosResponse<{{{returnType}}}{{^returnType}}void{{/returnType}}>>(localVarRequestOptions);
311+
const localVarResponse = await this.axios.request<{{{returnType}}}{{^returnType}}void{{/returnType}}>(localVarRequestOptions);
312+
return localVarResponse.data;
312313
}
313314
{{^-last}}
314315

modules/openapi-generator/src/test/java/org/openapitools/codegen/typescript/axios/TypeScriptAxiosSlimParityTest.java

Lines changed: 51 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,10 @@ public class TypeScriptAxiosSlimParityTest {
3333

3434
private static final Pattern REQUEST_INTERFACE_PATTERN = Pattern.compile("export interface (\\w+Request) \\{([\\s\\S]*?)\\n\\}");
3535
private static final Pattern API_INTERFACE_PATTERN = Pattern.compile("export interface (\\w+Interface) \\{([\\s\\S]*?)\\n\\}");
36-
private static final Pattern API_INTERFACE_METHOD_PATTERN = Pattern.compile("(\\w+)\\(([^)]*)\\):\\s*AxiosPromise<([^;]+)>;");
36+
private static final Pattern API_INTERFACE_METHOD_PATTERN = Pattern.compile("^\\s*(\\w+)\\((.*)\\):\\s*(.+);\\s*$", Pattern.MULTILINE);
3737
private static final Pattern ENUM_DECL_PATTERN = Pattern.compile("export enum (\\w+) \\{([\\s\\S]*?)\\n\\}");
3838
private static final Pattern CONST_ENUM_DECL_PATTERN = Pattern.compile("export const (\\w+) = \\{([\\s\\S]*?)\\} as const;");
39+
private static final Pattern WRAPPED_RETURN_TYPE_PATTERN = Pattern.compile("^(AxiosPromise|Promise|AxiosResponse)\\s*<\\s*(.+)\\s*>$");
3940

4041
private static final List<String> API_DIR_CANDIDATES = Arrays.asList("api", "apis");
4142
private static final List<String> MODEL_DIR_CANDIDATES = Arrays.asList("model", "models");
@@ -119,6 +120,17 @@ public void shouldPreserveMappedGenericResponseSignature() throws Exception {
119120
assertIdentitySurfaceEquals("generic-type-mapping-signature", axiosSurface, slimSurface);
120121
}
121122

123+
@Test(description = "slim: object-oriented methods return payload data directly")
124+
public void shouldReturnPayloadDataFromObjectOrientedMethods() throws Exception {
125+
IdentitySurface slimSurface = generateIdentity("typescript-axios-slim", EDGE_CASE_SPEC, NO_CUSTOMIZER);
126+
String apiSource = String.join(" ", slimSurface.apiFiles.values());
127+
128+
assertTrue(apiSource.contains("): Promise<"), "Slim API methods should return Promise payload types");
129+
assertFalse(apiSource.contains("AxiosPromise<"), "Slim API interface should not expose AxiosPromise return wrappers");
130+
assertFalse(apiSource.contains("Promise<AxiosResponse<"), "Slim API class should not return Promise<AxiosResponse<T>>");
131+
assertTrue(apiSource.contains("return localVarResponse.data;"), "Slim API class should resolve axios response data directly");
132+
}
133+
122134
private IdentitySurface generateIdentity(String generatorName, String specPath, Consumer<CodegenConfigurator> customizer) throws Exception {
123135
File output = Files.createTempDirectory("typescript_axios_identity_").toFile().getCanonicalFile();
124136
output.deleteOnExit();
@@ -220,13 +232,50 @@ private void extractApiInterfaceMethods(Map<String, Set<String>> target, String
220232
while (methodMatcher.find()) {
221233
String methodName = methodMatcher.group(1);
222234
String params = normalize(methodMatcher.group(2));
223-
String returnType = normalize(methodMatcher.group(3));
235+
String returnType = normalizeComparableReturnType(methodMatcher.group(3));
224236
target.computeIfAbsent(interfaceName, ignored -> new TreeSet<>())
225237
.add(methodName + "(" + params + "):" + returnType);
226238
}
227239
}
228240
}
229241

242+
private String normalizeComparableReturnType(String returnType) {
243+
String current = normalize(returnType);
244+
while (true) {
245+
Matcher wrapperMatcher = WRAPPED_RETURN_TYPE_PATTERN.matcher(current);
246+
if (!wrapperMatcher.matches()) {
247+
return current;
248+
}
249+
250+
String wrapperType = wrapperMatcher.group(1);
251+
String innerType = wrapperMatcher.group(2).trim();
252+
if ("AxiosResponse".equals(wrapperType)) {
253+
innerType = firstTopLevelTypeArgument(innerType);
254+
}
255+
256+
if (innerType.equals(current)) {
257+
return innerType;
258+
}
259+
current = innerType;
260+
}
261+
}
262+
263+
private String firstTopLevelTypeArgument(String typeArguments) {
264+
int depth = 0;
265+
for (int i = 0; i < typeArguments.length(); i++) {
266+
char current = typeArguments.charAt(i);
267+
if (current == '<') {
268+
depth++;
269+
} else if (current == '>') {
270+
depth = Math.max(0, depth - 1);
271+
} else if (current == ',' && depth == 0) {
272+
return typeArguments.substring(0, i).trim();
273+
}
274+
}
275+
276+
return typeArguments.trim();
277+
}
278+
230279
private void extractOperationEnums(Map<String, String> target, String apiSource) {
231280
Matcher enumMatcher = ENUM_DECL_PATTERN.matcher(apiSource);
232281
while (enumMatcher.find()) {

0 commit comments

Comments
 (0)