Skip to content

Commit cf78f10

Browse files
Fix dangerous destructuration in typescript-nestjs services (#20157)
* refactor: remove requestParameters destructuration * feat: add reserved param names sample * feat: quote params * feat: improve with reservedWords * feat: use vendorExtensions instead of extending CodegenParameter
1 parent 26609e9 commit cf78f10

File tree

20 files changed

+659
-5
lines changed

20 files changed

+659
-5
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
generatorName: typescript-nestjs
2+
outputDir: samples/client/petstore/typescript-nestjs/builds/reservedParamNames
3+
inputSpec: modules/openapi-generator/src/test/resources/3_0/typescript-nestjs/reserved-param-names.yaml
4+
templateDir: modules/openapi-generator/src/main/resources/typescript-nestjs
5+
additionalProperties:
6+
"useSingleRequestParameter" : true

docs/generators/typescript-nestjs.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,11 @@ These options may be applied as additional-properties (cli) or configOptions (pl
116116
<li>float</li>
117117
<li>for</li>
118118
<li>formParams</li>
119+
<li>from</li>
119120
<li>function</li>
120121
<li>goto</li>
121122
<li>headerParams</li>
123+
<li>headers</li>
122124
<li>if</li>
123125
<li>implements</li>
124126
<li>import</li>

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

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,8 @@ public TypeScriptNestjsClientCodegen() {
8888
apiPackage = "api";
8989
modelPackage = "model";
9090

91+
reservedWords.addAll(Arrays.asList("from", "headers"));
92+
9193
this.cliOptions.add(new CliOption(NPM_REPOSITORY,
9294
"Use this property to set an url your private npmRepo in the package.json"));
9395
this.cliOptions.add(CliOption.newBoolean(WITH_INTERFACES,
@@ -327,6 +329,10 @@ public OperationsMap postProcessOperationsWithModels(OperationsMap operations, L
327329

328330
// Overwrite path to TypeScript template string, after applying everything we just did.
329331
op.path = pathBuffer.toString();
332+
333+
for (CodegenParameter param : op.allParams) {
334+
param.vendorExtensions.putIfAbsent("x-param-has-sanitized-name", !param.baseName.equals(param.paramName));
335+
}
330336
}
331337

332338
operations.put("hasSomeFormParams", hasSomeFormParams);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ export interface {{classname}}{{operationIdCamelCase}}Request {
3535
* @type {{=<% %>=}}{<%&dataType%>}<%={{ }}=%>
3636
* @memberof {{classname}}{{operationIdCamelCase}}
3737
*/
38-
readonly {{paramName}}{{^required}}?{{/required}}: {{{dataType}}}
38+
readonly {{#vendorExtensions.x-param-has-sanitized-name}}'{{{baseName}}}'{{/vendorExtensions.x-param-has-sanitized-name}}{{^vendorExtensions.x-param-has-sanitized-name}}{{{paramName}}}{{/vendorExtensions.x-param-has-sanitized-name}}{{^required}}?{{/required}}: {{{dataType}}}
3939
{{^-last}}
4040

4141
{{/-last}}
@@ -106,7 +106,7 @@ export class {{classname}} {
106106
{{#useSingleRequestParameter}}
107107
const {
108108
{{#allParams}}
109-
{{paramName}},
109+
{{#vendorExtensions.x-param-has-sanitized-name}}'{{{baseName}}}': {{/vendorExtensions.x-param-has-sanitized-name}}{{paramName}},
110110
{{/allParams}}
111111
} = requestParameters;
112112

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,6 @@ export interface {{classname}}{{#allParents}}{{#-first}} extends {{/-first}}{{{.
55
* {{{.}}}
66
*/
77
{{/description}}
8-
{{#isReadOnly}}readonly {{/isReadOnly}}{{{name}}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}} | null{{/isNullable}};
8+
{{#isReadOnly}}readonly {{/isReadOnly}}{{#hasSanitizedName}}'{{{baseName}}}'{{/hasSanitizedName}}{{^hasSanitizedName}}{{{name}}}{{/hasSanitizedName}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{#isNullable}} | null{{/isNullable}};
99
{{/vars}}
1010
}{{>modelGenericEnums}}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,12 @@ export interface {{classname}} { {{>modelGenericAdditionalProperties}}
1010
* {{{.}}}
1111
*/
1212
{{/description}}
13-
{{name}}{{^required}}?{{/required}}: {{#discriminatorValue}}'{{.}}'{{/discriminatorValue}}{{^discriminatorValue}}{{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{/discriminatorValue}}{{#isNullable}} | null{{/isNullable}};
13+
{{#hasSanitizedName}}'{{{baseName}}}'{{/hasSanitizedName}}{{^hasSanitizedName}}{{{name}}}{{/hasSanitizedName}}{{^required}}?{{/required}}: {{#discriminatorValue}}'{{.}}'{{/discriminatorValue}}{{^discriminatorValue}}{{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{dataType}}}{{/isEnum}}{{/discriminatorValue}}{{#isNullable}} | null{{/isNullable}};
1414
{{/allVars}}
1515
}
1616
{{>modelGenericEnums}}
1717
{{/parent}}
1818
{{^parent}}
1919
{{>modelGeneric}}
2020
{{/parent}}
21-
{{/discriminator}}
21+
{{/discriminator}}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
openapi: 3.0.0
2+
info:
3+
description: Test reserved param names
4+
version: 1.0.0
5+
title: Reserved param names
6+
paths:
7+
/test:
8+
post:
9+
security:
10+
- bearerAuth: []
11+
summary: Test reserved param names
12+
description: ''
13+
operationId: testReservedParamNames
14+
parameters:
15+
- name: notReserved
16+
in: query
17+
description: Should not be treated as a reserved param name
18+
required: true
19+
schema:
20+
type: string
21+
- name: from
22+
in: query
23+
description: Might conflict with rxjs import
24+
required: true
25+
schema:
26+
type: string
27+
- name: headers
28+
in: header
29+
description: Might conflict with headers const
30+
required: true
31+
schema:
32+
type: string
33+
responses:
34+
'200':
35+
description: successful operation
36+
'405':
37+
description: Invalid input
38+
components:
39+
securitySchemes:
40+
bearerAuth:
41+
type: http
42+
scheme: bearer
43+
bearerFormat: JWT
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
wwwroot/*.js
2+
node_modules
3+
typings
4+
dist
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
# OpenAPI Generator Ignore
2+
# Generated by openapi-generator https://github.com/openapitools/openapi-generator
3+
4+
# Use this file to prevent files from being overwritten by the generator.
5+
# The patterns follow closely to .gitignore or .dockerignore.
6+
7+
# As an example, the C# client generator defines ApiClient.cs.
8+
# You can make changes and tell OpenAPI Generator to ignore just this file by uncommenting the following line:
9+
#ApiClient.cs
10+
11+
# You can match any string of characters against a directory, file or extension with a single asterisk (*):
12+
#foo/*/qux
13+
# The above matches foo/bar/qux and foo/baz/qux, but not foo/bar/baz/qux
14+
15+
# You can recursively match patterns against a directory, file or extension with a double asterisk (**):
16+
#foo/**/qux
17+
# This matches foo/bar/qux, foo/baz/qux, and foo/bar/baz/qux
18+
19+
# You can also negate patterns with an exclamation (!).
20+
# For example, you can ignore all files in a docs folder with the file extension .md:
21+
#docs/*.md
22+
# Then explicitly reverse the ignore rule for a single file:
23+
#!docs/README.md
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.gitignore
2+
README.md
3+
api.module.ts
4+
api/api.ts
5+
api/default.service.ts
6+
configuration.ts
7+
git_push.sh
8+
index.ts
9+
model/models.ts
10+
variables.ts

0 commit comments

Comments
 (0)