-
Notifications
You must be signed in to change notification settings - Fork 4
feat: generate schema from paths OpenAPI prop #230
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
`oas2json` looks fine but `oas2ts` is not creating correct types references/imports
No linked issues found. Please add the corresponding issues in the pull request description. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@toomuchdesign @ilteoood, Can you have a look here as I don't think there is any way to figure out which import statements to keep and which one to remove as @bcherny/json-schema-ref-parser
returns all references. for example here we needed to import only Pet from '../components.schemas/Pet' but it also included Category and Tags which are only required in '../components.schemas/Pet'. So wherever there is reference to ../components.schemas/Pet
it also imports Category and Tags
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to be honest I don't understand why we need this. this is the typescript representation of a path, but in which case are we going to use it?
IMO we'll use just the objects related to it, like: Pet
, Category
, Tag
...but not the structure of the entire endpoint
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hey @ilteoood, paths have only the structure and references to actual types through components/schemas. We are already generating the types like Pet
, Category
and Tag
in components.schemas. If we don't want the structure of path then I am not sure what else is left to convert to a type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about items like query params and path params?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ok, to convert /pet/findByStatus
get
parameter, what should be the type name and file name?
Will this work?
export interface PetFindByStatusGetParameters {
/**
* Status values that need to be considered for filter
*/
status?: 'available' | 'pending' | 'sold';
[k: string]: unknown;
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You can retrieve paths entities as named components only when the openAPI definition fully abstracts its return entities as components.schemas
objects.
Paths return definitions are often a mixture of inlined and ref definitions. eg:
{
"type": "array",
"items": {
"$ref" : "#/components/schemas/Pet"
}
}
.. where Pet
is abstracted but the the array is inline.
I personally find openapi-typescript output very convenient, replicating the original openAPI definition structure. But it's 100% subjective.
type SuccessResponse =
paths["/my/endpoint"]["get"]["responses"][200]["content"]["application/json"]["schema"];
type ErrorResponse =
paths["/my/endpoint"]["get"]["responses"][500]["content"]["application/json"]
...in our specific case we are trying to get a step further and split the type output in different files.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hey, we can work with mixture of inlined and ref definitions but do we really want each type to be in a separate file? For example for a particular path there can be multiple methods like get
, post
, put
which can have multiple types for responses
, parameters
, requestBody
etc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before delving into the implementation I'd suggest to focus on a single library method (oas2json
or oas2ts
) and write down the expected output given a moderately complex openAPI definition. This way we could better validate the solution we want to aim to.
Such output could be very different based on different design decisions.
Once decided what the output is supposed to be, it would be easier to find a viable implementation. You might even consider writing tests first to support your development effort.
Here is one question we could start from: should generated .json
files contain purely valid JSON schemas (as component schemas currently do) or they could even contain non-JSON schema structures representing the original OpenAPI definition structure? OpenApi paths
object is not a simple JSON schema object, but a structured object containing JSON schemas at different nesting levels.
Hi @faizplus! A few questions:
I'd personally suggest to try and implement such feature method by method (maybe starting from Thanks! |
Hey @toomuchdesign, I am currently trying to add support for With this PR, i have added one more option to const generatedSchema = fromSchema(parsedOpenAPIContent, {
definitionKeywords
}) then I have created a function ( |
) | ||
}) | ||
.map(refSchema => { | ||
let importFrom = '' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
let importFrom = '' | |
let importFrom |
]) | ||
] | ||
|
||
type pathInfoItem = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
type pathInfoItem = { | |
type PathInfoItem = { |
@@ -1,3 +1,4 @@ | |||
/* eslint-disable @typescript-eslint/no-explicit-any */ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should avoid disabling eslint rules, especially the one related to any
name: string | ||
in: string | ||
required?: boolean | ||
schema?: any |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
json schema has its own type definition
schema?: any | ||
} | ||
|
||
interface OpenApiPath { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do you need to create your own type? IMO if you look through npm you'll be able to find something like this, but officially maintained by the OAS team
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hey, can you provide the link please!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Literally the second entry if you search for openapi
on npm: https://www.npmjs.com/package/openapi3-ts
const pathObjects: { [key: string]: any } = {} | ||
for (const [path, methods] of Object.entries(paths)) { | ||
const pathObject = formatFileName(path) | ||
const schema: any = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
avoid any pls
} | ||
|
||
if (description) { | ||
schemaMethodProperties['description'] = description |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's no need for square brackets here.
same for summary
const isArray = Array.isArray(_get(parsedOpenAPIContent, key)) | ||
processSchema(schema, schemasPath, key, isArray) | ||
}) | ||
} catch (error) { | ||
console.log(error) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
there's no need for additional console log when you already have a logger
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
to be honest I don't understand why we need this. this is the typescript representation of a path, but in which case are we going to use it?
IMO we'll use just the objects related to it, like: Pet
, Category
, Tag
...but not the structure of the entire endpoint
oas2json
looks fine butoas2ts
is not creating correct types references/importscomponents.schemas
orpaths