Skip to content

Commit 35ee280

Browse files
fix(realm): ref sibling (#227)
* fix(realm): ref sibling * Update .changeset/ref-sibling-regression.md Co-authored-by: Alex Varchuk <olexandr.varchuk@gmail.com> --------- Co-authored-by: Alex Varchuk <olexandr.varchuk@gmail.com>
1 parent 078df31 commit 35ee280

4 files changed

Lines changed: 58 additions & 2 deletions

File tree

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"openapi-sampler": patch
3+
---
4+
5+
Fixed a regression from 1.7.7: a `$ref` inside `allOf` was sampled as `null`, and `skipReadOnly`/`skipWriteOnly` ignored a `$ref` inside `oneOf` or `anyOf`.

‎src/allOf.js‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@ export function allOfSample(into, children, options, spec, context) {
77
const subSamples = [];
88

99
for (let subSchema of children) {
10-
const { type, readOnly, writeOnly, value } = traverse({ type: res.type, ...subSchema }, options, spec, {
10+
const childSchema = subSchema.$ref ? subSchema : { type: res.type, ...subSchema };
11+
const { type, readOnly, writeOnly, value } = traverse(childSchema, options, spec, {
1112
...context,
1213
isAllOfChild: true,
1314
});

‎src/traverse.js‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,9 @@ export function traverse(schema, options, spec, context) {
7878
ref = ref.substring(1);
7979
}
8080

81-
const { $ref: _, ...siblings } = schema;
81+
const siblings = Object.fromEntries(
82+
Object.entries(schema).filter(([key, value]) => key !== '$ref' && value !== undefined),
83+
);
8284
const referenced = Object.keys(siblings).length && !shouldIgnoreRefSiblings(spec)
8385
? mergeRefSiblings(JsonPointer.get(spec, ref), siblings)
8486
: JsonPointer.get(spec, ref);

‎test/integration.spec.js‎

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -939,6 +939,54 @@ describe('Integration', () => {
939939
expect(spec.components.schemas.Num).toEqual({ type: 'number' });
940940
}
941941
});
942+
943+
it('should apply a null sibling written in the document', () => {
944+
result = sample({ $ref: '#/components/schemas/Num', default: null }, {}, refSiblingsSpec({ openapi: '3.1.0' }));
945+
expect(result).toBeNull();
946+
});
947+
948+
it('should not apply the type that allOf passes to its items to a $ref', () => {
949+
for (const spec of [refSiblingsSpec({ openapi: '3.1.0' }), refSiblingsSpec({})]) {
950+
result = sample({ allOf: [{ $ref: '#/components/schemas/Pet' }] }, {}, spec);
951+
expect(result).toEqual({ name: 'string' });
952+
953+
result = sample({
954+
allOf: [
955+
{ $ref: '#/components/schemas/Pet' },
956+
{ properties: { age: { type: 'integer' } } },
957+
]
958+
}, {}, spec);
959+
expect(result).toEqual({ name: 'string', age: 0 });
960+
}
961+
});
962+
963+
it('should keep readOnly and writeOnly of a $ref in oneOf and anyOf', () => {
964+
for (const version of [{ openapi: '3.1.0' }, {}]) {
965+
const spec = {
966+
...version,
967+
components: {
968+
schemas: {
969+
Id: { type: 'string', readOnly: true },
970+
Password: { type: 'string', writeOnly: true },
971+
},
972+
},
973+
};
974+
const schema = {
975+
type: 'object',
976+
properties: {
977+
id: { oneOf: [{ $ref: '#/components/schemas/Id' }] },
978+
password: { anyOf: [{ $ref: '#/components/schemas/Password' }] },
979+
name: { type: 'string' },
980+
},
981+
};
982+
983+
result = sample(schema, { skipReadOnly: true }, spec);
984+
expect(result).toEqual({ password: 'string', name: 'string' });
985+
986+
result = sample(schema, { skipWriteOnly: true }, spec);
987+
expect(result).toEqual({ id: 'string', name: 'string' });
988+
}
989+
});
942990
});
943991
});
944992

0 commit comments

Comments
 (0)