Skip to content

Commit 617a8f6

Browse files
[typescript-nestjs-server] #22928 add/improve support for various parameter types
1 parent 1fae8c2 commit 617a8f6

38 files changed

Lines changed: 523 additions & 36 deletions

.github/workflows/samples-typescript-nestjs-server.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ on:
55
paths:
66
- samples/server/petstore/typescript-nestjs-server/**
77
- .github/workflows/samples-typescript-nestjs-server.yaml
8+
- .github/workflows/samples-typescript-nestjs-server-parameters.yaml
89
jobs:
910
build:
1011
name: Test TypeScript NestJS Server
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
generatorName: typescript-nestjs-server
2+
outputDir: samples/server/petstore/typescript-nestjs-server/builds/parameters
3+
inputSpec: modules/openapi-generator/src/test/resources/3_0/parameter-test-spec.yaml
4+
templateDir: modules/openapi-generator/src/main/resources/typescript-nestjs-server
5+
additionalProperties:
6+
"useSingleRequestParameter" : true

docs/generators/typescript-nestjs-server.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,14 @@ These options may be applied as additional-properties (cli) or configOptions (pl
4040
|nullSafeAdditionalProps|Set to make additional properties types declare that their indexer may return undefined| |false|
4141
|paramNaming|Naming convention for parameters: 'camelCase', 'PascalCase', 'snake_case' and 'original', which keeps the original name| |camelCase|
4242
|prependFormOrBodyParameters|Add form or body parameters to the beginning of the parameter list.| |false|
43-
|rxjsVersion|The version of RxJS compatible with Angular (see ngVersion option).| |null|
43+
|rxjsVersion|The version of RxJS.| |null|
4444
|snapshot|When setting this property to true, the version will be suffixed with -SNAPSHOT.yyyyMMddHHmm| |false|
4545
|sortModelPropertiesByRequiredFlag|Sort model properties to place required parameters before optional parameters.| |true|
4646
|sortParamsByRequiredFlag|Sort method arguments to place required parameters before optional parameters.| |true|
4747
|stringEnums|Generate string enums instead of objects for enum values.| |false|
4848
|supportsES6|Generate code that conforms to ES6.| |false|
4949
|taggedUnions|Use discriminators to create tagged unions instead of extending interfaces.| |false|
50-
|tsVersion|The version of typescript compatible with Angular (see ngVersion option).| |null|
50+
|tsVersion|The version of typescript.| |null|
5151
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.| |false|
5252

5353
## IMPORT MAPPING

modules/openapi-generator/src/main/java/org/openapitools/codegen/languages/TypeScriptNestjsServerCodegen.java

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -120,8 +120,8 @@ public TypeScriptNestjsServerCodegen() {
120120
this.cliOptions.add(new CliOption(FILE_NAMING, "Naming convention for the output files: 'camelCase', 'kebab-case'.").defaultValue(this.fileNaming));
121121
this.cliOptions.add(new CliOption(STRING_ENUMS, STRING_ENUMS_DESC).defaultValue(String.valueOf(this.stringEnums)));
122122
this.cliOptions.add(new CliOption(USE_SINGLE_REQUEST_PARAMETER, "Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.").defaultValue(Boolean.FALSE.toString()));
123-
this.cliOptions.add(new CliOption(TS_VERSION, "The version of typescript compatible with Angular (see ngVersion option)."));
124-
this.cliOptions.add(new CliOption(RXJS_VERSION, "The version of RxJS compatible with Angular (see ngVersion option)."));
123+
this.cliOptions.add(new CliOption(TS_VERSION, "The version of typescript."));
124+
this.cliOptions.add(new CliOption(RXJS_VERSION, "The version of RxJS."));
125125
}
126126

127127
@Override
@@ -156,6 +156,7 @@ public void processOpts() {
156156
supportingFiles.add(new SupportingFile("api-implementations.mustache", "", "api-implementations.ts"));
157157
supportingFiles.add(new SupportingFile("api.module.mustache", "", "api.module.ts"));
158158
supportingFiles.add(new SupportingFile("controllers.mustache", "controllers", "index.ts"));
159+
supportingFiles.add(new SupportingFile("cookies-decorator.mustache", "cookies-decorator.ts"));
159160
supportingFiles.add(new SupportingFile("gitignore", "", ".gitignore"));
160161
supportingFiles.add(new SupportingFile("README.md", "", "README.md"));
161162
supportingFiles.add(new SupportingFile("tsconfig.mustache", "", "tsconfig.json"));
@@ -300,6 +301,9 @@ private boolean isRecordType(String type) {
300301
public void postProcessParameter(CodegenParameter parameter) {
301302
super.postProcessParameter(parameter);
302303
parameter.dataType = applyLocalTypeMapping(parameter.dataType);
304+
if("undefined".equals(parameter.defaultValue)) {
305+
parameter.defaultValue = null;
306+
}
303307
}
304308

305309
@Override

modules/openapi-generator/src/main/resources/typescript-nestjs-server/api.mustache

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { Injectable } from '@nestjs/common';
22
import { Observable } from 'rxjs';
3+
{{#tsImports.0}}
34
import { {{#tsImports}}{{classname}}, {{/tsImports}} } from '../{{modelPackage}}';
5+
{{/tsImports.0}}
46

57
{{#useSingleRequestParameter}}
68
{{#operations}}

modules/openapi-generator/src/main/resources/typescript-nestjs-server/controller.mustache

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
import { Body, Controller{{#httpMethods}}, {{.}}{{/httpMethods}}, Param, Query, Req } from '@nestjs/common';
1+
import { Body, Controller{{#httpMethods}}, {{.}}{{/httpMethods}}, Param, Query, Headers, Req } from '@nestjs/common';
22
import { Observable } from 'rxjs';
3+
import { Cookies } from '../cookies-decorator';
34
import { {{classname}} } from '../{{apiPackage}}';
5+
{{#tsImports.0}}
46
import { {{#tsImports}}{{classname}}, {{/tsImports}} } from '../{{modelPackage}}';
7+
{{/tsImports.0}}
58

69
@Controller()
710
export class {{classname}}Controller {
@@ -10,7 +13,7 @@ export class {{classname}}Controller {
1013
{{#operations}}
1114
{{#operation}}
1215
@{{#vendorExtensions.x-http-method}}{{.}}{{/vendorExtensions.x-http-method}}{{^vendorExtensions.x-http-method}}{{httpMethod}}{{/vendorExtensions.x-http-method}}('{{path}}')
13-
{{operationId}}({{#allParams}}{{#isPathParam}}@Param('{{paramName}}') {{/isPathParam}}{{#isQueryParam}}@Query('{{paramName}}') {{/isQueryParam}}{{#isBodyParam}}@Body() {{/isBodyParam}}{{paramName}}: {{{dataType}}}{{#isNullable}} | null{{/isNullable}}{{^required}} | undefined{{/required}}, {{/allParams}}@Req() request: Request): {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} | Promise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}> | Observable<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}> {
16+
{{operationId}}({{#allParams}}{{#isPathParam}}@Param('{{baseName}}') {{/isPathParam}}{{#isQueryParam}}@Query('{{baseName}}') {{/isQueryParam}}{{#isHeaderParam}}@Headers('{{baseName}}') {{/isHeaderParam}}{{#isCookieParam}}@Cookies('{{baseName}}') {{/isCookieParam}}{{#isBodyParam}}@Body() {{/isBodyParam}}{{paramName}}: {{{dataType}}}{{#isNullable}} | null{{/isNullable}}{{^required}} | undefined{{/required}}{{#defaultValue}} = {{{defaultValue}}}{{/defaultValue}}, {{/allParams}}@Req() request: Request): {{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}} | Promise<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}> | Observable<{{#returnType}}{{{returnType}}}{{/returnType}}{{^returnType}}void{{/returnType}}> {
1417
return this.{{classVarName}}.{{operationId}}({{#useSingleRequestParameter}}{ {{/useSingleRequestParameter}}{{#allParams}}{{paramName}}, {{/allParams}}{{#useSingleRequestParameter}}}, {{/useSingleRequestParameter}}request);
1518
}
1619

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
import { createParamDecorator, ExecutionContext } from '@nestjs/common';
2+
3+
export const Cookies = createParamDecorator((data: string, ctx: ExecutionContext) => {
4+
const request = ctx.switchToHttp().getRequest();
5+
return data ? request.cookies?.[data] : request.cookies;
6+
});

samples/server/petstore/typescript-nestjs-server/builds/default/.openapi-generator/FILES

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ controllers/PetApi.controller.ts
1010
controllers/StoreApi.controller.ts
1111
controllers/UserApi.controller.ts
1212
controllers/index.ts
13+
cookies-decorator.ts
1314
index.ts
1415
models/api-response.ts
1516
models/category.ts

samples/server/petstore/typescript-nestjs-server/builds/default/api/PetApi.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ export abstract class PetApi {
99
abstract addPet(pet: Pet, request: Request): Pet | Promise<Pet> | Observable<Pet>;
1010

1111

12-
abstract deletePet(petId: number, apiKey: string, request: Request): void | Promise<void> | Observable<void>;
12+
abstract deletePet(petId: number, apiKey: string | undefined, request: Request): void | Promise<void> | Observable<void>;
1313

1414

1515
abstract findPetsByStatus(status: Array<'available' | 'pending' | 'sold'>, request: Request): Array<Pet> | Promise<Array<Pet>> | Observable<Array<Pet>>;
@@ -24,9 +24,9 @@ export abstract class PetApi {
2424
abstract updatePet(pet: Pet, request: Request): Pet | Promise<Pet> | Observable<Pet>;
2525

2626

27-
abstract updatePetWithForm(petId: number, name: string, status: string, request: Request): void | Promise<void> | Observable<void>;
27+
abstract updatePetWithForm(petId: number, name: string | undefined, status: string | undefined, request: Request): void | Promise<void> | Observable<void>;
2828

2929

30-
abstract uploadFile(petId: number, additionalMetadata: string, file: Blob, request: Request): ApiResponse | Promise<ApiResponse> | Observable<ApiResponse>;
30+
abstract uploadFile(petId: number, additionalMetadata: string | undefined, file: Blob | undefined, request: Request): ApiResponse | Promise<ApiResponse> | Observable<ApiResponse>;
3131

3232
}

samples/server/petstore/typescript-nestjs-server/builds/default/controllers/PetApi.controller.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import { Body, Controller, Delete, Get, Post, Put, Param, Query, Req } from '@nestjs/common';
1+
import { Body, Controller, Delete, Get, Post, Put, Param, Query, Headers, Req } from '@nestjs/common';
22
import { Observable } from 'rxjs';
3+
import { Cookies } from '../cookies-decorator';
34
import { PetApi } from '../api';
45
import { ApiResponse, Pet, } from '../models';
56

@@ -13,7 +14,7 @@ export class PetApiController {
1314
}
1415

1516
@Delete('/pet/:petId')
16-
deletePet(@Param('petId') petId: number, apiKey: string, @Req() request: Request): void | Promise<void> | Observable<void> {
17+
deletePet(@Param('petId') petId: number, @Headers('api_key') apiKey: string | undefined, @Req() request: Request): void | Promise<void> | Observable<void> {
1718
return this.petApi.deletePet(petId, apiKey, request);
1819
}
1920

@@ -38,12 +39,12 @@ export class PetApiController {
3839
}
3940

4041
@Post('/pet/:petId')
41-
updatePetWithForm(@Param('petId') petId: number, name: string, status: string, @Req() request: Request): void | Promise<void> | Observable<void> {
42+
updatePetWithForm(@Param('petId') petId: number, name: string | undefined, status: string | undefined, @Req() request: Request): void | Promise<void> | Observable<void> {
4243
return this.petApi.updatePetWithForm(petId, name, status, request);
4344
}
4445

4546
@Post('/pet/:petId/uploadImage')
46-
uploadFile(@Param('petId') petId: number, additionalMetadata: string, file: Blob, @Req() request: Request): ApiResponse | Promise<ApiResponse> | Observable<ApiResponse> {
47+
uploadFile(@Param('petId') petId: number, additionalMetadata: string | undefined, file: Blob | undefined, @Req() request: Request): ApiResponse | Promise<ApiResponse> | Observable<ApiResponse> {
4748
return this.petApi.uploadFile(petId, additionalMetadata, file, request);
4849
}
4950

0 commit comments

Comments
 (0)