Skip to content

Commit f8221ec

Browse files
committed
feat(typescript-fetch): add docs support
fixes #18276
1 parent 517bbeb commit f8221ec

File tree

5 files changed

+281
-29
lines changed

5 files changed

+281
-29
lines changed

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

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ public class TypeScriptFetchClientCodegen extends AbstractTypeScriptClientCodege
7373
protected boolean withoutRuntimeChecks = false;
7474
protected boolean stringEnums = false;
7575
protected String fileNaming = PASCAL_CASE;
76+
protected String apiDocPath = "docs";
77+
protected String modelDocPath = "docs";
7678

7779
// "Saga and Record" mode.
7880
public static final String SAGAS_AND_RECORDS = "sagasAndRecords";
@@ -107,10 +109,14 @@ public TypeScriptFetchClientCodegen() {
107109
// at the moment
108110
importMapping.clear();
109111

110-
outputFolder = "generated-code/typescript-fetch";
112+
outputFolder = "generated-code" + File.separator + "typescript-fetch";
111113
embeddedTemplateDir = templateDir = "typescript-fetch";
112114

113115
this.apiTemplateFiles.put("apis.mustache", ".ts");
116+
this.modelTemplateFiles.put("models.mustache", ".ts");
117+
118+
this.apiDocTemplateFiles.put("api_doc.mustache", ".md");
119+
this.modelDocTemplateFiles.put("model_doc.mustache", ".md");
114120

115121
this.addExtraReservedWords();
116122

@@ -138,6 +144,11 @@ public String toModelFilename(String name) {
138144
return convertUsingFileNamingConvention(super.toModelFilename(name));
139145
}
140146

147+
@Override
148+
public String toModelDocFilename(String name) {
149+
return toModelName(name);
150+
}
151+
141152
/**
142153
* Converts the original name according to the current <code>fileNaming</code> strategy.
143154
*
@@ -242,6 +253,10 @@ public void processOpts() {
242253
this.apiPackage = sourceDir + "apis";
243254
this.modelPackage = sourceDir + "models";
244255

256+
// make api and model doc path available in mustache template
257+
additionalProperties.put("apiDocPath", apiDocPath);
258+
additionalProperties.put("modelDocPath", modelDocPath);
259+
245260
supportingFiles.add(new SupportingFile("index.mustache", sourceDir, "index.ts"));
246261
supportingFiles.add(new SupportingFile("runtime.mustache", sourceDir, "runtime.ts"));
247262

@@ -316,6 +331,16 @@ public void processOpts() {
316331
setGenerateValidationAttributes(convertPropertyToBooleanAndWriteBack(VALIDATION_ATTRIBUTES));
317332
}
318333

334+
@Override
335+
public String apiDocFileFolder() {
336+
return (outputFolder + File.separator + apiDocPath);
337+
}
338+
339+
@Override
340+
public String modelDocFileFolder() {
341+
return (outputFolder + File.separator + modelDocPath);
342+
}
343+
319344
@Override
320345
public String toEnumDefaultValue(String value, String datatype) {
321346
if (this.getSagasAndRecords()) {
Lines changed: 109 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,127 @@
1-
## {{npmName}}@{{npmVersion}}
1+
# {{npmName}}@{{npmVersion}}
22

3-
This generator creates TypeScript/JavaScript client that utilizes [Fetch API](https://fetch.spec.whatwg.org/). The generated Node module can be used in the following environments:
3+
A TypeScript SDK client for the {{host}} API.
44

5-
Environment
6-
* Node.js
7-
* Webpack
8-
* Browserify
5+
## Usage
96

10-
Language level
11-
* ES5 - you must have a Promises/A+ library installed
12-
* ES6
7+
First, install the SDK from npm.
138

14-
Module system
15-
* CommonJS
16-
* ES6 module system
9+
```bash
10+
npm install {{npmName}} --save
11+
```
12+
13+
Next, try it out.
14+
15+
{{#apiInfo}}{{#apis}}{{#-first}}{{#operations}}{{#operation}}{{#-first}}
16+
```ts
17+
{{>api_example}}
18+
```
19+
{{/-first}}{{/operation}}{{/operations}}{{/-first}}{{/apis}}{{/apiInfo}}
20+
21+
## Documentation
22+
23+
### API Endpoints
24+
25+
All URIs are relative to *{{basePath}}*
26+
27+
| Class | Method | HTTP request | Description
28+
| ----- | ------ | ------------ | -------------
29+
{{#apiInfo}}{{#apis}}{{#operations}}{{#operation}}*{{classname}}* | [**{{operationId}}**]({{apiDocPath}}/{{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{path}} | {{summary}}
30+
{{/operation}}{{/operations}}{{/apis}}{{/apiInfo}}
31+
32+
### Models
33+
34+
{{#models}}{{#model}}- [{{{classname}}}]({{modelDocPath}}/{{{classname}}}.md){{/model}}
35+
{{/models}}
36+
37+
### Authorization
38+
39+
{{^authMethods}}Endpoints do not require authorization.{{/authMethods}}
40+
{{#hasAuthMethods}}Authentication schemes defined for the API:{{/hasAuthMethods}}
41+
{{#authMethods}}
42+
<a id="{{name}}{{#isOAuth}}-{{flow}}{{/isOAuth}}"></a>
43+
#### {{name}}{{#isOAuth}} {{flow}}{{/isOAuth}}
44+
45+
{{#isApiKey}}
46+
47+
- **Type**: API key
48+
- **API key parameter name**: `{{keyParamName}}`
49+
- **Location**: {{#isKeyInQuery}}URL query string{{/isKeyInQuery}}{{#isKeyInHeader}}HTTP header{{/isKeyInHeader}}
50+
{{/isApiKey}}
51+
{{#isBasicBasic}}
52+
53+
- **Type**: HTTP basic authentication
54+
{{/isBasicBasic}}
55+
{{#isBasicBearer}}
56+
57+
- **Type**: HTTP Bearer Token authentication{{#bearerFormat}} ({{{.}}}){{/bearerFormat}}
58+
{{/isBasicBearer}}
59+
{{#isHttpSignature}}
1760

18-
It can be used in both TypeScript and JavaScript. In TypeScript, the definition will be automatically resolved via `package.json`. ([Reference](https://www.typescriptlang.org/docs/handbook/declaration-files/consumption.html))
61+
- **Type**: HTTP signature authentication
62+
{{/isHttpSignature}}
63+
{{#isOAuth}}
64+
65+
- **Type**: OAuth
66+
- **Flow**: {{flow}}
67+
- **Authorization URL**: {{authorizationUrl}}
68+
- **Scopes**: {{^scopes}}N/A{{/scopes}}
69+
{{#scopes}} - `{{scope}}`: {{description}}
70+
{{/scopes}}
71+
{{/isOAuth}}
72+
{{/authMethods}}
73+
74+
## About
75+
76+
This TypeScript SDK client supports the [Fetch API](https://fetch.spec.whatwg.org/)
77+
and is automatically generated by the
78+
[OpenAPI Generator](https://openapi-generator.tech) project:
79+
80+
- API version: `{{appVersion}}`
81+
- Package version: `{{npmVersion}}`
82+
{{^hideGenerationTimestamp}}
83+
- Build date: `{{generatedDate}}`
84+
{{/hideGenerationTimestamp}}
85+
- Generator version: `{{generatorVersion}}`
86+
- Build package: `{{generatorClass}}`
87+
88+
The generated npm module supports the following:
89+
90+
- Environments
91+
* Node.js
92+
* Webpack
93+
* Browserify
94+
- Language levels
95+
* ES5 - you must have a Promises/A+ library installed
96+
* ES6
97+
- Module systems
98+
* CommonJS
99+
* ES6 module system
100+
101+
{{#infoUrl}}
102+
For more information, please visit [{{{infoUrl}}}]({{{infoUrl}}})
103+
{{/infoUrl}}
104+
105+
## Development
19106

20107
### Building
21108

22-
To build and compile the typescript sources to javascript use:
23-
```
109+
To build the TypeScript source code, you need to have Node.js and npm installed.
110+
After cloning the repository, navigate to the project directory and run:
111+
112+
```bash
24113
npm install
25114
npm run build
26115
```
27116

28117
### Publishing
29118

30-
First build the package then run `npm publish`
31-
32-
### Consuming
33-
34-
navigate to the folder of your consuming project and run one of the following commands.
119+
Once you've built the package, you can publish it to npm:
35120

36-
_published:_
37-
38-
```
39-
npm install {{npmName}}@{{npmVersion}} --save
121+
```bash
122+
npm publish
40123
```
41124

42-
_unPublished (not recommended):_
125+
## License
43126

44-
```
45-
npm install PATH_TO_GENERATED_PACKAGE --save
46-
```
127+
[{{licenseInfo}}]({{{licenseUrl}}})
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
# {{classname}}{{#description}}
2+
3+
{{.}}{{/description}}
4+
5+
All URIs are relative to *{{basePath}}*
6+
7+
| Method | HTTP request | Description |
8+
|------------- | ------------- | -------------|
9+
{{#operations}}{{#operation}}| [**{{operationId}}**]({{classname}}.md#{{operationIdLowerCase}}) | **{{httpMethod}}** {{commonPath}}{{path}} | {{summary}} |
10+
{{/operation}}{{/operations}}
11+
12+
{{#operations}}
13+
{{#operation}}
14+
15+
## {{operationId}}
16+
17+
> {{#returnType}}{{.}} {{/returnType}}{{operationId}}({{#allParams}}{{{paramName}}}{{^-last}}, {{/-last}}{{/allParams}})
18+
19+
{{summary}}{{#notes}}
20+
21+
{{.}}{{/notes}}
22+
23+
### Example
24+
25+
```ts
26+
{{>api_example}}
27+
```
28+
29+
### Parameters
30+
31+
{{^allParams}}This endpoint does not need any parameter.{{/allParams}}{{#allParams}}{{#-last}}
32+
| Name | Type | Description | Notes |
33+
|------------- | ------------- | ------------- | -------------|{{/-last}}{{/allParams}}
34+
{{#allParams}}| **{{paramName}}** | {{#isEnum}}{{#allowableValues}}{{#values}}`{{{.}}}`{{^-last}}, {{/-last}}{{/values}}{{/allowableValues}}{{/isEnum}}{{^isEnum}}{{#isModel}}[{{baseType}}]({{baseType}}.md){{/isModel}}{{^isModel}}`{{{dataType}}}`{{/isModel}}{{/isEnum}} | {{description}} |{{^required}} [Optional]{{/required}}{{^isContainer}}{{#defaultValue}} [Defaults to `{{.}}`]{{/defaultValue}}{{/isContainer}}{{#allowableValues}} [Enum: {{#values}}{{{.}}}{{^-last}}, {{/-last}}{{/values}}]{{/allowableValues}} |
35+
{{/allParams}}
36+
37+
### Return type
38+
39+
{{#returnType}}{{#returnTypeIsPrimitive}}**{{{returnType}}}**{{/returnTypeIsPrimitive}}{{^returnTypeIsPrimitive}}[**{{returnType}}**]({{returnBaseType}}.md){{/returnTypeIsPrimitive}}{{/returnType}}{{^returnType}}`void` (Empty response body){{/returnType}}
40+
41+
### Authorization
42+
43+
{{^authMethods}}No authorization required{{/authMethods}}{{#authMethods}}[{{{name}}}{{#isOAuth}} {{flow}}{{/isOAuth}}](../README.md#{{{name}}}{{#isOAuth}}-{{flow}}{{/isOAuth}}){{^-last}}, {{/-last}}{{/authMethods}}
44+
45+
### HTTP request headers
46+
47+
- **Content-Type**: {{#consumes}}`{{{mediaType}}}`{{^-last}}, {{/-last}}{{/consumes}}{{^consumes}}Not defined{{/consumes}}
48+
- **Accept**: {{#produces}}`{{{mediaType}}}`{{^-last}}, {{/-last}}{{/produces}}{{^produces}}Not defined{{/produces}}
49+
50+
{{#responses.0}}
51+
52+
### HTTP response details
53+
| Status code | Description | Response headers |
54+
|-------------|-------------|------------------|
55+
{{#responses}}
56+
| **{{code}}** | {{message}} | {{#headers}} * {{baseName}} - {{description}} <br> {{/headers}}{{^headers.0}} - {{/headers.0}} |
57+
{{/responses}}
58+
{{/responses.0}}
59+
60+
[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
61+
62+
{{/operation}}
63+
{{/operations}}
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import {
2+
Configuration,
3+
{{classname}},
4+
} from '{{npmName}}';
5+
import type { {{operationIdCamelCase}}Request } from '{{npmName}}';
6+
7+
async function example() {
8+
console.log("🚀 Testing {{npmName}} SDK...");
9+
{{#hasAuthMethods}}
10+
const config = new Configuration({ {{#authMethods}}{{#isBasicBasic}}
11+
// To configure HTTP basic authorization: {{{name}}}
12+
username: "YOUR USERNAME",
13+
password: "YOUR PASSWORD",{{/isBasicBasic}}{{#isBasicBearer}}
14+
// Configure HTTP bearer authorization: {{{name}}}
15+
accessToken: "YOUR BEARER TOKEN",{{/isBasicBearer}}{{#isOAuth}}
16+
// To configure OAuth2 access token for authorization: {{{name}}} {{{flow}}}
17+
accessToken: "YOUR ACCESS TOKEN",{{/isOAuth}}{{#isApiKey}}
18+
// To configure API key authorization: {{{name}}}
19+
apiKey: "YOUR API KEY",{{/isApiKey}}{{#isHttpSignature}}
20+
// To configure HTTP signature authorization: {{{name}}}
21+
headers: { "YOUR HEADER NAME": "YOUR SIGNATURE" },{{/isHttpSignature}}{{/authMethods}}
22+
});
23+
{{/hasAuthMethods}}
24+
const api = new {{classname}}({{#hasAuthMethods}}config{{/hasAuthMethods}});
25+
26+
{{#hasParams}}
27+
const body = {
28+
{{#allParams}}
29+
// {{{dataType}}}{{#description}} | {{{description}}}{{/description}}{{^required}} (optional){{/required}}
30+
{{paramName}}: {{{example}}}{{^example}}...{{/example}},
31+
{{/allParams}}
32+
} satisfies {{operationIdCamelCase}}Request;
33+
34+
{{/hasParams}}
35+
try {
36+
const data = await api.{{{operationId}}}({{#hasParams}}body{{/hasParams}});
37+
console.log(data);
38+
} catch (error) {
39+
console.error(error);
40+
}
41+
}
42+
43+
// Run the test
44+
example().catch(console.error);
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
{{#models}}{{#model}}
2+
# {{classname}}
3+
4+
{{#description}}{{&description}}
5+
{{/description}}
6+
7+
## Properties
8+
9+
Name | Type
10+
------------ | -------------
11+
{{#vars}}`{{name}}` | {{#isPrimitiveType}}{{dataType}}{{/isPrimitiveType}}{{^isPrimitiveType}}[{{dataType}}]({{complexType}}.md){{/isPrimitiveType}}
12+
{{/vars}}
13+
14+
## Example
15+
16+
```typescript
17+
import type { {{classname}} } from '{{npmName}}'
18+
19+
// TODO: Update the object below with actual values
20+
const example = {
21+
{{#vars}}
22+
"{{name}}": {{{example}}},
23+
{{/vars}}
24+
} satisfies {{classname}}
25+
26+
console.log(example)
27+
28+
// Convert the instance to a JSON string
29+
const exampleJSON: string = JSON.stringify(example)
30+
console.log(exampleJSON)
31+
32+
// Parse the JSON string back to an object
33+
const exampleParsed = JSON.parse(exampleJSON) as {{classname}}
34+
console.log(exampleParsed)
35+
```
36+
37+
[[Back to top]](#) [[Back to API list]](../README.md#api-endpoints) [[Back to Model list]](../README.md#models) [[Back to README]](../README.md)
38+
39+
{{/model}}{{/models}}

0 commit comments

Comments
 (0)