mirror of
https://github.com/Redocly/redoc.git
synced 2025-08-07 13:44:54 +03:00
feat: oas3.1 merge $refs
This commit is contained in:
parent
0a4d172333
commit
fa6957f22f
|
@ -964,8 +964,7 @@ components:
|
|||
properties:
|
||||
id:
|
||||
description: Category ID
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Id'
|
||||
$ref: '#/components/schemas/Id'
|
||||
name:
|
||||
description: Category name
|
||||
type: string
|
||||
|
@ -1015,12 +1014,10 @@ components:
|
|||
properties:
|
||||
id:
|
||||
description: Order ID
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Id'
|
||||
$ref: '#/components/schemas/Id'
|
||||
petId:
|
||||
description: Pet ID
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Id'
|
||||
$ref: '#/components/schemas/Id'
|
||||
quantity:
|
||||
type: integer
|
||||
format: int32
|
||||
|
@ -1065,12 +1062,10 @@ components:
|
|||
description: "Find more info here"
|
||||
url: "https://example.com"
|
||||
description: Pet ID
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Id'
|
||||
$ref: '#/components/schemas/Id'
|
||||
category:
|
||||
description: Categories this pet belongs to
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Category'
|
||||
$ref: '#/components/schemas/Category'
|
||||
name:
|
||||
description: The name given to a pet
|
||||
type: string
|
||||
|
@ -1087,8 +1082,7 @@ components:
|
|||
type: string
|
||||
format: url
|
||||
friend:
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Pet'
|
||||
$ref: '#/components/schemas/Pet'
|
||||
tags:
|
||||
description: Tags attached to the pet
|
||||
type: array
|
||||
|
@ -1117,8 +1111,7 @@ components:
|
|||
properties:
|
||||
id:
|
||||
description: Tag ID
|
||||
allOf:
|
||||
- $ref: '#/components/schemas/Id'
|
||||
$ref: '#/components/schemas/Id'
|
||||
name:
|
||||
description: Tag name
|
||||
type: string
|
||||
|
@ -1133,6 +1126,7 @@ components:
|
|||
pet:
|
||||
oneOf:
|
||||
- $ref: '#/components/schemas/Pet'
|
||||
title: Pettie
|
||||
- $ref: '#/components/schemas/Tag'
|
||||
username:
|
||||
description: User supplied username
|
||||
|
@ -1179,10 +1173,9 @@ components:
|
|||
content:
|
||||
application/json:
|
||||
schema:
|
||||
allOf:
|
||||
- description: My Pet
|
||||
title: Pettie
|
||||
- $ref: '#/components/schemas/Pet'
|
||||
description: My Pet
|
||||
title: Pettie
|
||||
$ref: '#/components/schemas/Pet'
|
||||
application/xml:
|
||||
schema:
|
||||
type: 'object'
|
||||
|
|
|
@ -9,7 +9,7 @@ const swagger = window.location.search.indexOf('swagger') > -1;
|
|||
const userUrl = window.location.search.match(/url=(.*)$/);
|
||||
|
||||
const specUrl =
|
||||
(userUrl && userUrl[1]) || (swagger ? 'swagger.yaml' : big ? 'big-openapi.json' : 'openapi.yaml');
|
||||
(userUrl && userUrl[1]) || (swagger ? 'swagger.yaml' : big ? 'big-openapi.json' : 'openapi-3-1.yaml');
|
||||
|
||||
const options: RedocRawOptions = { nativeScrollbars: false, maxDisplayedEnumValues: 3 };
|
||||
|
||||
|
|
|
@ -45,9 +45,9 @@ class RefCounter {
|
|||
export class OpenAPIParser {
|
||||
specUrl?: string;
|
||||
spec: OpenAPISpec;
|
||||
mergeRefs: Set<string>;
|
||||
|
||||
private _refCounter: RefCounter = new RefCounter();
|
||||
private allowMergeRefs: boolean = false;
|
||||
|
||||
constructor(
|
||||
spec: OpenAPISpec,
|
||||
|
@ -58,8 +58,7 @@ export class OpenAPIParser {
|
|||
this.preprocess(spec);
|
||||
|
||||
this.spec = spec;
|
||||
|
||||
this.mergeRefs = new Set();
|
||||
this.allowMergeRefs = spec.openapi.startsWith('3.1');
|
||||
|
||||
const href = IS_BROWSER ? window.location.href : '';
|
||||
if (typeof specUrl === 'string') {
|
||||
|
@ -165,16 +164,36 @@ export class OpenAPIParser {
|
|||
return Object.assign({}, resolved, { 'x-circular-ref': true });
|
||||
}
|
||||
// deref again in case one more $ref is here
|
||||
let result = resolved;
|
||||
if (this.isRef(resolved)) {
|
||||
const res = this.deref(resolved);
|
||||
result = this.deref(resolved);
|
||||
this.exitRef(resolved);
|
||||
return res;
|
||||
}
|
||||
return resolved;
|
||||
return this.allowMergeRefs ? this.mergeRefs(obj, resolved) : result;
|
||||
}
|
||||
return obj;
|
||||
}
|
||||
|
||||
mergeRefs(ref, resolved) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||
const { $ref, ...rest } = ref;
|
||||
const keys = Object.keys(rest);
|
||||
if (keys.length === 0) {
|
||||
return resolved;
|
||||
}
|
||||
if (keys.some((k) => k !== 'description' && k !== 'title' && k !== 'externalDocs')) {
|
||||
return {
|
||||
allOf: [resolved, rest],
|
||||
};
|
||||
} else {
|
||||
// small optimization
|
||||
return {
|
||||
...resolved,
|
||||
...rest,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
shalowDeref<T extends object>(obj: OpenAPIRef | T): T {
|
||||
if (this.isRef(obj)) {
|
||||
return this.byRef<T>(obj.$ref)!;
|
||||
|
@ -234,7 +253,7 @@ export class OpenAPIParser {
|
|||
schema: subMerged,
|
||||
};
|
||||
})
|
||||
.filter(child => child !== undefined) as Array<{
|
||||
.filter((child) => child !== undefined) as Array<{
|
||||
$ref: string | undefined;
|
||||
schema: MergedOpenAPISchema;
|
||||
}>;
|
||||
|
@ -265,7 +284,7 @@ export class OpenAPIParser {
|
|||
{ allOf: [receiver.properties[prop], subSchema.properties[prop]] },
|
||||
$ref + '/properties/' + prop,
|
||||
);
|
||||
receiver.properties[prop] = mergedProp
|
||||
receiver.properties[prop] = mergedProp;
|
||||
this.exitParents(mergedProp); // every prop resolution should have separate recursive stack
|
||||
}
|
||||
}
|
||||
|
@ -313,7 +332,7 @@ export class OpenAPIParser {
|
|||
const def = this.deref(schemas[defName]);
|
||||
if (
|
||||
def.allOf !== undefined &&
|
||||
def.allOf.find(obj => obj.$ref !== undefined && $refs.indexOf(obj.$ref) > -1)
|
||||
def.allOf.find((obj) => obj.$ref !== undefined && $refs.indexOf(obj.$ref) > -1)
|
||||
) {
|
||||
res['#/components/schemas/' + defName] = [def['x-discriminator-value'] || defName];
|
||||
}
|
||||
|
@ -339,7 +358,7 @@ export class OpenAPIParser {
|
|||
const beforeAllOf = allOf.slice(0, i);
|
||||
const afterAllOf = allOf.slice(i + 1);
|
||||
return {
|
||||
oneOf: sub.oneOf.map(part => {
|
||||
oneOf: sub.oneOf.map((part) => {
|
||||
const merged = this.mergeAllOf({
|
||||
allOf: [...beforeAllOf, part, ...afterAllOf],
|
||||
});
|
||||
|
|
Loading…
Reference in New Issue
Block a user