-
Notifications
You must be signed in to change notification settings - Fork 29
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
fix: refactoring allOf schemas to be pre-merged when we generate JSON Schema #579
Conversation
@@ -222,11 +222,9 @@ | |||
"deprecated": true, | |||
"allOf": [ | |||
{ | |||
"title": "option 1", |
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.
Removed these because they were always going to be merged into a single title
property.
if ( | ||
Array.isArray(schema.properties[prop]) || | ||
(typeof schema.properties[prop] === 'object' && schema.properties[prop] !== null) | ||
) { | ||
schema.properties[prop] = toJSONSchema(schema.properties[prop] as RMOAS.SchemaObject, { | ||
currentLocation: `${currentLocation}/${encodePointer(prop)}`, | ||
globalDefaults, | ||
prevSchemas, | ||
refLogger, | ||
}); | ||
} |
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.
src/lib/openapi-to-json-schema.ts
Outdated
// If we can't merge the `allOf` for whatever reason (like if one item is a `string` and the other is a | ||
// `object`) then we should completely remove it from the schema and continue with whatever we've got. Why? | ||
// If we don't, any tooling that's ingesting this will need to account for the incompatible `allOf` and it may | ||
// be subject to more breakages than just not having it present would be. | ||
const { ...schemaWithoutAllOf } = schema; | ||
schema = schemaWithoutAllOf as RMOAS.SchemaObject; | ||
delete schema.allOf; |
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.
I'm still kind of iffy on this but this is how our schema form currently handles this case, but I still need to follow up this PR with changes to our schema form to handle if type
isn't present and treat them as a string.
const mapping = schema.discriminator.mapping; | ||
Object.keys(mapping).forEach(k => { | ||
refLogger(mapping[k]); |
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.
Had to make this change because TS didn't like how we were accessing schema.discriminator
here and didn't think that discriminator
was present on the schema
type (despite the same code working two lines above).
@@ -227,7 +214,12 @@ describe('polymorphism / inheritance', () => { | |||
}, | |||
}, | |||
{ | |||
type: 'integer', |
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.
Changed this because integer
and object
schemas can't be merged.
minimum: min, | ||
maximum: max, | ||
])('`type: %s`', (type, format, min, max) => { | ||
describe(`\`format: ${format}\``, () => { |
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.
Changed this because we were duping all of these integer + format tests under the same describe
block and they weren't properly exposing themselves in the test output. Thankfully they were still being run, it just wasn't clear what was being run for what.
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.
just one small comment, otherwise stuff looks good. will test more on the readme merge.
🧰 Changes
Last week we received an API definition that contained an
allOf
that contained another allOf with two things:data
property that evaluated to a{}
.data
property that evaluated to a complete object.Because we have handling in place to not repair
allOf
children if they are missing atype
declaration, this case was falling through that and the emptydata
object was getting atype: string
property added to it because we thought that it was malformed. Further up the stack when we render this schema out we later attempt to merge this newly "fixed"allOf
and becausetype: string
andtype: object
are incompatible we either wouldn't render out anything, or in some cases would fully crash.Less than ideal!
Since we don't have any great way of determining if a sub-object property is contained within an
allOf
and isn't malformed and will be okay when it's merged with another schema we decided to completely forgo this repair work that we had to repair schemas that were missing atype
(and weren't either implicitly an object or an array), and instead merge allallOf
schemas when we generate JSON Schema.Going forward, with this work any tooling that ingests JSON Schema generated with
getParametersAsJsonSchema()
will no longer need to worry aboutallOf
cases.Fix in support of RM-3146.
🧬 QA & Testing
There's a lot going on here, but all tests should no longer have any
allOf
expectations.As for the case that uncovered this issue lives, it in
__tests__/__datasets__/polymorphism-quirks.json
and is tested within__tests__/operation/get-parameters-as-json-schema.test.js
.