Skip to content

Commit 36aba26

Browse files
authored
[typescript-fetch] Allow to generate client without runtime checks (#7894)
* Add CLI options to remove runtime checks (serialization/deserialization). * Update templates to support the new parameter - Generates all the models in a same file to avoid import complexity - Extract interfaces creator templates to reuse them * Fix formatting and generate client examples * Add documentation
1 parent 54d6257 commit 36aba26

42 files changed

Lines changed: 1872 additions & 198 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
generatorName: typescript-fetch
2+
outputDir: samples/client/petstore/typescript-fetch/builds/without-runtime-checks
3+
inputSpec: modules/openapi-generator/src/test/resources/2_0/petstore.yaml
4+
additionalProperties:
5+
npmVersion: 1.0.0
6+
npmName: '@openapitools/typescript-fetch-petstore'
7+
npmRepository: https://skimdb.npmjs.com/registry
8+
withoutRuntimeChecks: true
9+
snapshot: false

docs/generators/typescript-fetch.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ These options may be applied as additional-properties (cli) or configOptions (pl
2727
|typescriptThreePlus|Setting this property to true will generate TypeScript 3.6+ compatible code.| |false|
2828
|useSingleRequestParameter|Setting this property to true will generate functions with a single argument containing all API endpoint parameters instead of one argument per parameter.| |true|
2929
|withInterfaces|Setting this property to true will generate interfaces next to the default class implementations.| |false|
30+
|withoutRuntimeChecks|Setting this property to true will remove any runtime checks on the request and response payloads. Payloads will be casted to their expected types.| |false|
3031

3132
## IMPORT MAPPING
3233

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

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,15 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
3939
public static final String USE_SINGLE_REQUEST_PARAMETER = "useSingleRequestParameter";
4040
public static final String PREFIX_PARAMETER_INTERFACES = "prefixParameterInterfaces";
4141
public static final String TYPESCRIPT_THREE_PLUS = "typescriptThreePlus";
42+
public static final String WITHOUT_RUNTIME_CHECKS = "withoutRuntimeChecks";
4243

4344
protected String npmRepository = null;
4445
private boolean useSingleRequestParameter = true;
4546
private boolean prefixParameterInterfaces = false;
4647
protected boolean addedApiIndex = false;
4748
protected boolean addedModelIndex = false;
4849
protected boolean typescriptThreePlus = false;
50+
protected boolean withoutRuntimeChecks = false;
4951

5052

5153
public TypeScriptFetchClientCodegen() {
@@ -61,7 +63,7 @@ public TypeScriptFetchClientCodegen() {
6163
embeddedTemplateDir = templateDir = "typescript-fetch";
6264

6365
this.apiTemplateFiles.put("apis.mustache", ".ts");
64-
this.modelTemplateFiles.put("models.mustache", ".ts");
66+
6567
this.addExtraReservedWords();
6668

6769
typeMapping.put("date", "Date");
@@ -73,6 +75,7 @@ public TypeScriptFetchClientCodegen() {
7375
this.cliOptions.add(new CliOption(CodegenConstants.USE_SINGLE_REQUEST_PARAMETER, CodegenConstants.USE_SINGLE_REQUEST_PARAMETER_DESC, SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.TRUE.toString()));
7476
this.cliOptions.add(new CliOption(PREFIX_PARAMETER_INTERFACES, "Setting this property to true will generate parameter interface declarations prefixed with API class name to avoid name conflicts.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
7577
this.cliOptions.add(new CliOption(TYPESCRIPT_THREE_PLUS, "Setting this property to true will generate TypeScript 3.6+ compatible code.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
78+
this.cliOptions.add(new CliOption(WITHOUT_RUNTIME_CHECKS, "Setting this property to true will remove any runtime checks on the request and response payloads. Payloads will be casted to their expected types.", SchemaTypeUtil.BOOLEAN_TYPE).defaultValue(Boolean.FALSE.toString()));
7679
}
7780

7881
@Override
@@ -101,6 +104,14 @@ public void setTypescriptThreePlus(Boolean typescriptThreePlus) {
101104
this.typescriptThreePlus = typescriptThreePlus;
102105
}
103106

107+
public Boolean getWithoutRuntimeChecks(){
108+
return withoutRuntimeChecks;
109+
}
110+
111+
public void setWithoutRuntimeChecks(Boolean withoutRuntimeChecks){
112+
this.withoutRuntimeChecks = withoutRuntimeChecks;
113+
}
114+
104115
@Override
105116
public void processOpts() {
106117
super.processOpts();
@@ -135,6 +146,14 @@ public void processOpts() {
135146
if (additionalProperties.containsKey(TYPESCRIPT_THREE_PLUS)) {
136147
this.setTypescriptThreePlus(convertPropertyToBoolean(TYPESCRIPT_THREE_PLUS));
137148
}
149+
150+
if (additionalProperties.containsKey(WITHOUT_RUNTIME_CHECKS)) {
151+
this.setWithoutRuntimeChecks(convertPropertyToBoolean(WITHOUT_RUNTIME_CHECKS));
152+
}
153+
154+
if(!withoutRuntimeChecks){
155+
this.modelTemplateFiles.put("models.mustache", ".ts");
156+
}
138157
}
139158

140159
@Override

modules/openapi-generator/src/main/resources/typescript-fetch/apis.mustache

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,10 @@ import * as runtime from '../runtime';
77
import {
88
{{#imports}}
99
{{className}},
10+
{{^withoutRuntimeChecks}}
1011
{{className}}FromJSON,
1112
{{className}}ToJSON,
13+
{{/withoutRuntimeChecks}}
1214
{{/imports}}
1315
} from '../models';
1416
{{/imports.0}}
@@ -242,7 +244,11 @@ export class {{classname}} extends runtime.BaseAPI {
242244
formParams.append('{{baseName}}', requestParameters.{{paramName}} as any);
243245
{{/isPrimitiveType}}
244246
{{^isPrimitiveType}}
247+
{{^withoutRuntimeChecks}}
245248
formParams.append('{{baseName}}', new Blob([JSON.stringify({{{dataType}}}ToJSON(requestParameters.{{paramName}}))], { type: "application/json", }));
249+
{{/withoutRuntimeChecks}}{{#withoutRuntimeChecks}}
250+
formParams.append('{{baseName}}', new Blob([JSON.stringify(requestParameters.{{paramName}})], { type: "application/json", }));
251+
{{/withoutRuntimeChecks}}
246252
{{/isPrimitiveType}}
247253
}
248254
@@ -257,11 +263,21 @@ export class {{classname}} extends runtime.BaseAPI {
257263
{{#hasBodyParam}}
258264
{{#bodyParam}}
259265
{{#isContainer}}
266+
{{^withoutRuntimeChecks}}
260267
body: requestParameters.{{paramName}}{{#isArray}}{{#items}}{{^isPrimitiveType}}.map({{datatype}}ToJSON){{/isPrimitiveType}}{{/items}}{{/isArray}},
268+
{{/withoutRuntimeChecks}}
269+
{{#withoutRuntimeChecks}}
270+
body: requestParameters.{{paramName}}{{#isArray}}{{#items}}{{^isPrimitiveType}}{{/isPrimitiveType}}{{/items}}{{/isArray}},
271+
{{/withoutRuntimeChecks}}
261272
{{/isContainer}}
262273
{{^isContainer}}
263274
{{^isPrimitiveType}}
275+
{{^withoutRuntimeChecks}}
264276
body: {{dataType}}ToJSON(requestParameters.{{paramName}}),
277+
{{/withoutRuntimeChecks}}
278+
{{#withoutRuntimeChecks}}
279+
body: requestParameters.{{paramName}},
280+
{{/withoutRuntimeChecks}}
265281
{{/isPrimitiveType}}
266282
{{#isPrimitiveType}}
267283
body: requestParameters.{{paramName}} as any,
@@ -292,14 +308,14 @@ export class {{classname}} extends runtime.BaseAPI {
292308
{{/returnTypeIsPrimitive}}
293309
{{^returnTypeIsPrimitive}}
294310
{{#isArray}}
295-
return new runtime.JSONApiResponse(response, (jsonValue) => jsonValue.map({{returnBaseType}}FromJSON));
311+
return new runtime.JSONApiResponse(response{{^withoutRuntimeChecks}}, (jsonValue) => jsonValue.map({{returnBaseType}}FromJSON){{/withoutRuntimeChecks}});
296312
{{/isArray}}
297313
{{^isArray}}
298314
{{#isMap}}
299-
return new runtime.JSONApiResponse(response, (jsonValue) => runtime.mapValues(jsonValue, {{returnBaseType}}FromJSON));
315+
return new runtime.JSONApiResponse(response{{^withoutRuntimeChecks}}, (jsonValue) => runtime.mapValues(jsonValue, {{returnBaseType}}FromJSON){{/withoutRuntimeChecks}});
300316
{{/isMap}}
301317
{{^isMap}}
302-
return new runtime.JSONApiResponse(response, (jsonValue) => {{returnBaseType}}FromJSON(jsonValue));
318+
return new runtime.JSONApiResponse(response{{^withoutRuntimeChecks}}, (jsonValue) => {{returnBaseType}}FromJSON(jsonValue){{/withoutRuntimeChecks}});
303319
{{/isMap}}
304320
{{/isArray}}
305321
{{/returnTypeIsPrimitive}}

modules/openapi-generator/src/main/resources/typescript-fetch/modelEnum.mustache

Lines changed: 1 addition & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,4 @@
1-
/**
2-
* {{#lambda.indented_star_1}}{{{unescapedDescription}}}{{/lambda.indented_star_1}}
3-
* @export
4-
* @enum {string}
5-
*/
6-
export enum {{classname}} {
7-
{{#allowableValues}}
8-
{{#enumVars}}
9-
{{{name}}} = {{{value}}}{{^-last}},{{/-last}}
10-
{{/enumVars}}
11-
{{/allowableValues}}
12-
}
1+
{{>modelEnumInterfaces}}
132

143
export function {{classname}}FromJSON(json: any): {{classname}} {
154
return {{classname}}FromJSONTyped(json, false);
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/**
2+
* {{#lambda.indented_star_1}}{{{unescapedDescription}}}{{/lambda.indented_star_1}}
3+
* @export
4+
* @enum {string}
5+
*/
6+
export enum {{classname}} {
7+
{{#allowableValues}}
8+
{{#enumVars}}
9+
{{{name}}} = {{{value}}}{{^-last}},{{/-last}}
10+
{{/enumVars}}
11+
{{/allowableValues}}
12+
}

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

Lines changed: 1 addition & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -18,24 +18,7 @@ import {
1818
} from './';
1919

2020
{{/discriminator}}
21-
/**
22-
* {{#lambda.indented_star_1}}{{{unescapedDescription}}}{{/lambda.indented_star_1}}
23-
* @export
24-
* @interface {{classname}}
25-
*/
26-
export interface {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{
27-
{{#additionalPropertiesType}}
28-
[key: string]: {{{additionalPropertiesType}}}{{#hasVars}} | any{{/hasVars}};
29-
{{/additionalPropertiesType}}
30-
{{#vars}}
31-
/**
32-
* {{#lambda.indented_star_4}}{{{unescapedDescription}}}{{/lambda.indented_star_4}}
33-
* @type {{=<% %>=}}{<%&datatype%>}<%={{ }}=%>
34-
* @memberof {{classname}}
35-
*/
36-
{{#isReadOnly}}readonly {{/isReadOnly}}{{name}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{#isNullable}} | null{{/isNullable}}{{/isEnum}};
37-
{{/vars}}
38-
}
21+
{{>modelGenericInterfaces}}
3922

4023
export function {{classname}}FromJSON(json: any): {{classname}} {
4124
return {{classname}}FromJSONTyped(json, false);
@@ -145,21 +128,3 @@ export function {{classname}}ToJSON(value?: {{classname}} | null): any {
145128
{{/hasVars}}
146129
}
147130

148-
{{#hasEnums}}
149-
{{#vars}}
150-
{{#isEnum}}
151-
/**
152-
* @export
153-
* @enum {string}
154-
*/
155-
export enum {{classname}}{{enumName}} {
156-
{{#allowableValues}}
157-
{{#enumVars}}
158-
{{{name}}} = {{{value}}}{{^-last}},{{/-last}}
159-
{{/enumVars}}
160-
{{/allowableValues}}
161-
}
162-
{{/isEnum}}
163-
{{/vars}}
164-
165-
{{/hasEnums}}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/**
2+
* {{#lambda.indented_star_1}}{{{unescapedDescription}}}{{/lambda.indented_star_1}}
3+
* @export
4+
* @interface {{classname}}
5+
*/
6+
export interface {{classname}} {{#parent}}extends {{{parent}}} {{/parent}}{
7+
{{#additionalPropertiesType}}
8+
[key: string]: {{{additionalPropertiesType}}}{{#hasVars}} | any{{/hasVars}};
9+
{{/additionalPropertiesType}}
10+
{{#vars}}
11+
/**
12+
* {{#lambda.indented_star_4}}{{{unescapedDescription}}}{{/lambda.indented_star_4}}
13+
* @type {{=<% %>=}}{<%&datatype%>}<%={{ }}=%>
14+
* @memberof {{classname}}
15+
*/
16+
{{#isReadOnly}}readonly {{/isReadOnly}}{{name}}{{^required}}?{{/required}}: {{#isEnum}}{{{datatypeWithEnum}}}{{/isEnum}}{{^isEnum}}{{{datatype}}}{{#isNullable}} | null{{/isNullable}}{{/isEnum}};
17+
{{/vars}}
18+
}{{#hasEnums}}
19+
20+
{{#vars}}
21+
{{#isEnum}}
22+
/**
23+
* @export
24+
* @enum {string}
25+
*/
26+
export enum {{classname}}{{enumName}} {
27+
{{#allowableValues}}
28+
{{#enumVars}}
29+
{{{name}}} = {{{value}}}{{^-last}},{{/-last}}
30+
{{/enumVars}}
31+
{{/allowableValues}}
32+
}{{/isEnum}}{{/vars}}{{/hasEnums}}

modules/openapi-generator/src/main/resources/typescript-fetch/modelOneOf.mustache

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,7 @@ import {
1010
} from './';
1111

1212
{{/hasImports}}
13-
/**
14-
* @type {{classname}}
15-
* {{#lambda.indented_star_1}}{{{unescapedDescription}}}{{/lambda.indented_star_1}}
16-
* @export
17-
*/
18-
export type {{classname}} = {{#discriminator}}{{#mappedModels}}{ {{discriminator.propertyName}}: '{{mappingName}}' } & {{modelName}}{{^-last}} | {{/-last}}{{/mappedModels}}{{/discriminator}}{{^discriminator}}{{#oneOf}}{{{.}}}{{^-last}} | {{/-last}}{{/oneOf}}{{/discriminator}};
13+
{{>modelOneOfInterfaces}}
1914

2015
export function {{classname}}FromJSON(json: any): {{classname}} {
2116
return {{classname}}FromJSONTyped(json, false);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/**
2+
* @type {{classname}}
3+
* {{#lambda.indented_star_1}}{{{unescapedDescription}}}{{/lambda.indented_star_1}}
4+
* @export
5+
*/
6+
export type {{classname}} = {{#discriminator}}{{#mappedModels}}{ {{discriminator.propertyName}}: '{{mappingName}}' } & {{modelName}}{{^-last}} | {{/-last}}{{/mappedModels}}{{/discriminator}}{{^discriminator}}{{#oneOf}}{{{.}}}{{^-last}} | {{/-last}}{{/oneOf}}{{/discriminator}};

0 commit comments

Comments
 (0)