-
Notifications
You must be signed in to change notification settings - Fork 30
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(oas): account for deep $ref
pointers when reducing an API def
#926
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,12 @@ function accumulateUsedRefs(schema: Record<string, unknown>, $refs: Set<string>, | |
} | ||
|
||
getUsedRefs($refSchema).forEach(({ value: currRef }) => { | ||
// Because it's possible to have a parameter named `$ref`, which our lookup would pick up as a | ||
// false positive, we want to exclude that from `$ref` matching as it's not really a reference. | ||
if (typeof currRef !== 'string') { | ||
return; | ||
} | ||
|
||
// If we've already processed this $ref don't send us into an infinite loop. | ||
if ($refs.has(currRef)) { | ||
return; | ||
|
@@ -178,7 +184,18 @@ export default function reducer(definition: OASDocument, opts: ReducerOptions = | |
if ('components' in reduced) { | ||
Object.keys(reduced.components).forEach((componentType: keyof ComponentsObject) => { | ||
Object.keys(reduced.components[componentType]).forEach(component => { | ||
if (!$refs.has(`#/components/${componentType}/${component}`)) { | ||
// If our `$ref` either is a full, or deep match, then we should preserve it. | ||
const refIsUsed = | ||
$refs.has(`#/components/${componentType}/${component}`) || | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (non-blocking) i feel like i've seen ref syntax that uses There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i have also seen that before but it is not valid. our parser doesn't pick up on it now, but should at some point. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i had a note about this in one of my gitto PRs over the past two weeks but can't link those here. |
||
Array.from($refs).some(ref => { | ||
// Because you can have a `$ref` like `#/components/examples/event-min/value`, which | ||
// would be accumulated via our `$refs` query, we want to make sure we account for them. | ||
// If we don't look for these then we'll end up removing them from the overall reduced | ||
// definition, resulting in data loss and schema corruption. | ||
return ref.startsWith(`#/components/${componentType}/${component}/`); | ||
}); | ||
|
||
if (!refIsUsed) { | ||
delete reduced.components[componentType][component]; | ||
} | ||
}); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,5 @@ | ||
import type { OASDocument } from '../../src/types.js'; | ||
|
||
import { inspect } from 'node:util'; | ||
|
||
import swagger from '@readme/oas-examples/2.0/json/petstore.json'; | ||
import parametersCommon from '@readme/oas-examples/3.0/json/parameters-common.json'; | ||
import petstore from '@readme/oas-examples/3.0/json/petstore.json'; | ||
|
@@ -17,16 +15,6 @@ import reduceQuirks from '../__datasets__/reduce-quirks.json'; | |
import securityRootLevel from '../__datasets__/security-root-level.json'; | ||
import tagQuirks from '../__datasets__/tag-quirks.json'; | ||
|
||
declare global { | ||
interface Console { | ||
logx: any; | ||
} | ||
} | ||
|
||
console.logx = (obj: any) => { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lol wut There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. this snuck in in a commit i made this morning where i added that skipped failing test. |
||
console.log(inspect(obj, false, null, true)); | ||
}; | ||
|
||
describe('reducer', () => { | ||
it('should not do anything if no reducers are supplied', () => { | ||
expect(reducer(petstore as any)).toStrictEqual(petstore as any); | ||
|
@@ -207,10 +195,7 @@ describe('reducer', () => { | |
expect(Object.keys(reduced.paths['/anything'])).toStrictEqual(['get', 'post']); | ||
}); | ||
|
||
/** | ||
* @see {@link https://github.com/readmeio/oas/issues/925} | ||
*/ | ||
it.skip('should preserved deeply nested `example` refs', () => { | ||
it('should preserved deeply nested `example` refs', () => { | ||
const reduced = reducer(reduceQuirks as any, { | ||
paths: { | ||
'/events': ['get'], | ||
|
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.
of course you can do that 🙃
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 love it here, folks