Skip to content

Commit ba3107f

Browse files
authored
feat: add openapi support (#218)
1 parent 765523d commit ba3107f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+4298
-1705
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
</table>
4747

4848
# Core Features
49-
- 📃 Generate [payload](https://the-codegen-project.org/docs/generators/payloads), [headers](https://the-codegen-project.org/docs/generators/headers) or [parameter](https://the-codegen-project.org/docs/generators/parameters) representations from your AsyncAPI document (including Protobuf, RAML, OpenAPI Schema)
49+
- 📃 Generate [payload](https://the-codegen-project.org/docs/generators/payloads), [headers](https://the-codegen-project.org/docs/generators/headers) or [parameter](https://the-codegen-project.org/docs/generators/parameters) representations from your AsyncAPI document (including Protobuf, RAML, OpenAPI Schema) or OpenAPI (Swagger 2.0, 3.0, and 3.1)
5050
- 📊 Customize the output to your hearts desire
5151
- 💫 Regenerate once the input changes
5252
- 👀 Integrate it into any project (such as [Next.JS](./examples/typescript-nextjs), [TypeScript Libraries](./examples/typescript-library), you name it.)

docs/README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ If there has been a decision about certain technical solutions it will be marked
4343
### Inputs
4444
Each input has its own limitations, corner cases, and features; thus, each has separate documentation.
4545
- [AsyncAPI](./inputs/asyncapi.md)
46+
- [OpenAPI](./inputs/openapi.md)
4647

4748
### Protocols
4849
Each protocol has its own limitations, corner cases, and features; thus, each has separate documentation.
@@ -68,3 +69,4 @@ Get an overview of how to contribute to the project
6869

6970

7071

72+

docs/contributing.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,4 +153,5 @@ Prefix that follows specification is not enough though. Remember that the title
153153

154154

155155

156+
156157

docs/generators/README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ All available generators, across languages and inputs:
2020
| **Inputs** | [`payloads`](./payloads.md) | [`parameters`](./parameters.md) | [`headers`](./headers.md) | [`types`](./types.md) | [`channels`](./channels.md) | [`client`](./client.md) | [`custom`](./custom.md) |
2121
|---|---|---|---|---|---|---|---|
2222
| AsyncAPI | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ | ✔️ |
23+
| OpenAPI ||||||| ✔️ |
2324

2425
| **Languages** | [`payloads`](./payloads.md) | [`parameters`](./parameters.md) | [`headers`](./headers.md) | [`types`](./types.md) | [`channels`](./channels.md) | [`client`](./client.md) | [`custom`](./custom.md) |
2526
|---|---|---|---|---|---|---|---|

docs/generators/custom.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export default {
1818
{
1919
preset: 'custom',
2020
...
21-
renderFunction: ({generator, inputType, asyncapiDocument, dependencyOutputs})
21+
renderFunction: ({generator, inputType, asyncapiDocument, openapiDocument, dependencyOutputs})
2222
{
2323
const modelinaGenerator = new JavaFileGenerator({});
2424
modelinaGenerator.generateCompleteModels(...)
@@ -30,7 +30,7 @@ export default {
3030

3131
# Dependencies
3232

33-
In each generator (don't manually use it unless you use `preset: custom`, you can add `dependencies` property, which takes an array of `id`'s that the rendering engine ensures are rendered before the dependant one.
33+
In each generator (don't manually use it unless you use `preset: custom`), you can add `dependencies` property, which takes an array of `id`'s that the rendering engine ensures are rendered before the dependant one.
3434

3535
Each generator has a specific output (except `custom` which is dynamic and under your control), they are documented under each [./generators](./README.md). These outputs can be accessed under `dependencyOutputs`.
3636

@@ -70,4 +70,5 @@ In the `renderFunction` you have access to a bunch of arguments to help you crea
7070
- `generator` - is the generator configuration, where you have access to the `options` and all other information.
7171
- `inputType` - is the root `inputType` for the input document
7272
- `asyncapiDocument` - is the parsed AsyncAPI document input (according to the [AsyncAPI parser](https://github.com/asyncapi/parser-js/)), undefined if the `inputType` is not `asyncapi`
73+
- `openapiDocument` - is the parsed OpenAPI document input (according to the [readme/openapi-parser](https://github.com/readmeio/oas)), undefined if the `inputType` is not `openapi`
7374
- `dependencyOutputs` - if you have defined any `dependencies`, this is where you can access the output. Checkout the [dependency documentation](#dependencies) for more information.

docs/inputs/openapi.md

Lines changed: 140 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,140 @@
1+
---
2+
sidebar_position: 99
3+
---
4+
5+
# OpenAPI
6+
7+
Input support; `openapi`
8+
9+
- OpenAPI 3.0.x
10+
- OpenAPI 3.1.x
11+
- Swagger 2.0 (legacy support)
12+
13+
## Basic Usage
14+
15+
### Configuration
16+
17+
Create a configuration file that specifies OpenAPI as the input type:
18+
19+
```json
20+
{
21+
"inputType": "openapi",
22+
"inputPath": "./api/openapi.yaml",
23+
"language": "typescript",
24+
"generators": [ ... ]
25+
}
26+
```
27+
28+
## Supported Generators
29+
30+
### Custom Generator
31+
32+
For advanced use cases, you can create [custom generators](../generators/custom.md):
33+
34+
```json
35+
{
36+
"inputType": "openapi",
37+
"inputPath": "./api/openapi.yaml",
38+
"language": "typescript",
39+
"generators": [
40+
{
41+
preset: 'custom',
42+
...
43+
renderFunction: ({generator, inputType, openapiDocument, dependencyOutputs})
44+
{
45+
const modelinaGenerator = new JavaFileGenerator({});
46+
modelinaGenerator.generateCompleteModels(...)
47+
}
48+
}
49+
]
50+
}
51+
52+
```
53+
54+
## Advanced Features
55+
56+
### External References
57+
58+
The OpenAPI parser automatically resolves external `$ref` references:
59+
60+
```yaml
61+
components:
62+
schemas:
63+
Pet:
64+
$ref: './schemas/pet.yaml#/Pet'
65+
User:
66+
$ref: 'https://api.example.com/schemas/user.json#/User'
67+
```
68+
69+
### OpenAPI 3.1 Features
70+
71+
Full support for OpenAPI 3.1 features including:
72+
73+
- JSON Schema 2020-12 compatibility
74+
- `const` keyword
75+
- `if`/`then`/`else` conditionals
76+
- Enhanced `examples` support
77+
78+
### Validation and Error Handling
79+
80+
The parser provides detailed validation errors:
81+
82+
```typescript
83+
// If validation fails, you'll get detailed error information
84+
try {
85+
const document = await loadOpenapi(context);
86+
} catch (error) {
87+
console.error('OpenAPI validation failed:', error.message);
88+
// Error message includes line numbers and specific validation issues
89+
}
90+
```
91+
92+
## Examples
93+
94+
### REST API Client Generation
95+
96+
Generate a complete TypeScript client for your REST API:
97+
98+
```json
99+
{
100+
"inputType": "openapi",
101+
"inputPath": "./api/openapi.yaml",
102+
"language": "typescript",
103+
"generators": [ ]
104+
}
105+
```
106+
107+
## Best Practices
108+
109+
1. **Schema Organization**: Use `$ref` to organize complex schemas into separate files
110+
2. **Validation**: Always validate your OpenAPI documents before generation
111+
3. **Versioning**: Include version information in your API specifications
112+
4. **Documentation**: Use `description` fields extensively for better generated code
113+
5. **Examples**: Provide examples in your schemas for better understanding
114+
115+
## Troubleshooting
116+
117+
### Common Issues
118+
119+
1. **Invalid $ref**: Ensure all referenced files exist and are accessible
120+
2. **Schema Validation**: Check that your OpenAPI document follows the specification
121+
3. **File Format**: Verify that YAML/JSON syntax is correct
122+
4. **Circular References**: Avoid circular `$ref` dependencies
123+
124+
## FAQ
125+
126+
### Can I use both OpenAPI and AsyncAPI in the same project?
127+
128+
Yes! You can have separate configuration files for each input type and generate code to different output directories.
129+
130+
### What's the difference between OpenAPI 3.0 and 3.1?
131+
132+
OpenAPI 3.1 is fully compatible with JSON Schema 2020-12 and includes additional features like `const`, conditional schemas, and enhanced examples support.
133+
134+
### How do I handle authentication in generated clients?
135+
136+
Define security schemes in your OpenAPI document, and the generated client code will include appropriate authentication handling.
137+
138+
### Can I customize the generated code?
139+
140+
Yes, use the custom generator preset to create your own templates and generation logic.

docs/migrations/v0.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,3 +60,4 @@ const subscriber = await jetStreamPullSubscribeToReceiveUserSignedup({
6060

6161

6262

63+

docs/usage.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ $ npm install -g @the-codegen-project/cli
99
$ codegen COMMAND
1010
running command...
1111
$ codegen (--version)
12-
@the-codegen-project/cli/0.41.0 linux-x64 node-v18.20.8
12+
@the-codegen-project/cli/0.41.0 win32-x64 node-v18.20.4
1313
$ codegen --help [COMMAND]
1414
USAGE
1515
$ codegen COMMAND
@@ -109,7 +109,7 @@ Initialize The Codegen Project in your project
109109

110110
```
111111
USAGE
112-
$ codegen init [--help] [--input-file <value>] [--config-name <value>] [--input-type asyncapi]
112+
$ codegen init [--help] [--input-file <value>] [--config-name <value>] [--input-type asyncapi|openapi]
113113
[--output-directory <value>] [--config-type esm|json|yaml|ts] [--languages typescript] [--no-tty]
114114
[--include-payloads] [--include-headers] [--include-client] [--include-parameters] [--include-channels]
115115
@@ -128,7 +128,7 @@ FLAGS
128128
--include-payloads Include payloads generation, available for TypeScript
129129
--input-file=<value> File path for the code generation input such as AsyncAPI document
130130
--input-type=<option> Input file type
131-
<options: asyncapi>
131+
<options: asyncapi|openapi>
132132
--languages=<option> Which languages do you wish to generate code for?
133133
<options: typescript>
134134
--no-tty Do not use an interactive terminal

package-lock.json

Lines changed: 84 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,11 @@
1818
"@oclif/plugin-autocomplete": "^3.0.16",
1919
"@oclif/plugin-help": "^6.0.21",
2020
"@oclif/plugin-version": "^2.0.17",
21+
"@readme/openapi-parser": "^4.0.0",
2122
"cosmiconfig": "^9.0.0",
2223
"graphology": "^0.25.4",
2324
"inquirer": "^8.2.6",
25+
"openapi-types": "^12.1.3",
2426
"yaml": "^2.4.5",
2527
"zod": "^3.23.8",
2628
"zod-validation-error": "^3.3.0"

0 commit comments

Comments
 (0)