mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-28 03:23:44 +03:00
Merge branch 'master' into releases
This commit is contained in:
commit
20915ed40f
|
@ -139,21 +139,21 @@ api-logo {
|
||||||
color: $red;
|
color: $red;
|
||||||
border: 1px solid rgba(38,50,56,0.1);
|
border: 1px solid rgba(38,50,56,0.1);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
footer {
|
||||||
|
text-align: right;
|
||||||
|
padding: 10px;
|
||||||
|
font-size: 15px;
|
||||||
|
background-color: white;
|
||||||
|
|
||||||
strong {
|
strong {
|
||||||
font-size: 18px;
|
font-size: 18px;
|
||||||
color: $headers-color;
|
color: $headers-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
footer {
|
|
||||||
text-align: right;
|
|
||||||
padding: 10px;
|
|
||||||
font-size: 15px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* markdown elements */
|
/* markdown elements */
|
||||||
|
|
||||||
:host .redoc-markdown-block {
|
:host .redoc-markdown-block {
|
||||||
|
|
|
@ -17,6 +17,21 @@ function safeConcat(a, b) {
|
||||||
return res.concat(b);
|
return res.concat(b);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function defaults(target, src) {
|
||||||
|
var props = Object.keys(src);
|
||||||
|
|
||||||
|
var index = -1,
|
||||||
|
length = props.length;
|
||||||
|
|
||||||
|
while (++index < length) {
|
||||||
|
var key = props[index];
|
||||||
|
if (target[key] === undefined) {
|
||||||
|
target[key] = src[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return target;
|
||||||
|
}
|
||||||
|
|
||||||
function snapshot(obj) {
|
function snapshot(obj) {
|
||||||
if(obj == null || typeof(obj) != 'object') {
|
if(obj == null || typeof(obj) != 'object') {
|
||||||
return obj;
|
return obj;
|
||||||
|
@ -156,41 +171,57 @@ export class BaseComponent {
|
||||||
}
|
}
|
||||||
|
|
||||||
joinAllOf(schema = this.componentSchema, opts) {
|
joinAllOf(schema = this.componentSchema, opts) {
|
||||||
var self = this;
|
|
||||||
function merge(into, schemas) {
|
function merge(into, schemas) {
|
||||||
if (into.required || into.properties) {
|
|
||||||
let errMessage = `Can\'t merge allOf: properties or required fields are specified on the same level as allOf
|
|
||||||
${into}`;
|
|
||||||
throw new Error(errMessage);
|
|
||||||
}
|
|
||||||
into.required = [];
|
|
||||||
into.properties = {};
|
|
||||||
for (let subSchema of schemas) {
|
for (let subSchema of schemas) {
|
||||||
if (opts && opts.omitParent && subSchema.discriminator) continue;
|
if (opts && opts.omitParent && subSchema.discriminator) continue;
|
||||||
|
|
||||||
// TODO: add support for merge array schemas
|
// TODO: add support for merge array schemas
|
||||||
if (typeof subSchema !== 'object' || subSchema.type !== 'object') {
|
if (typeof subSchema !== 'object') {
|
||||||
let errMessage = `Can\'t merge allOf: only subschemas with type: object can be merged
|
let errMessage = `Items of allOf should be Object: ${typeof subSchema} found
|
||||||
${subSchema}`;
|
${subSchema}`;
|
||||||
throw new Error(errMessage);
|
throw new Error(errMessage);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.joinAllOf(subSchema);
|
if (into.type && into.type !== subSchema.type) {
|
||||||
|
let errMessage = `allOf merging error: schemas with different types can't be merged`;
|
||||||
|
throw new Error(errMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (into.type === 'array') {
|
||||||
|
console.warn('allOf: subschemas with type array are not supported yet');
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: add check if can be merged correctly (no different properties with the same name)
|
// TODO: add check if can be merged correctly (no different properties with the same name)
|
||||||
if (subSchema.properties) {
|
if (subSchema.type === 'object' && subSchema.properties) {
|
||||||
|
into.properties || (into.properties = {});
|
||||||
Object.assign(into.properties, subSchema.properties);
|
Object.assign(into.properties, subSchema.properties);
|
||||||
}
|
}
|
||||||
if (subSchema.required) {
|
if (subSchema.type === 'object' && subSchema.required) {
|
||||||
|
into.required || (into.required = []);
|
||||||
into.required.push(...subSchema.required);
|
into.required.push(...subSchema.required);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
defaults(into, subSchema);
|
||||||
}
|
}
|
||||||
into.type = 'object';
|
|
||||||
into.allOf = null;
|
into.allOf = null;
|
||||||
}
|
}
|
||||||
if (schema.allOf) {
|
|
||||||
merge(schema, schema.allOf);
|
function traverse(obj) {
|
||||||
|
if (obj === null || typeof(obj) !== 'object') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(var key in obj) {
|
||||||
|
if (obj.hasOwnProperty(key)) {
|
||||||
|
traverse(obj[key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (obj.allOf) {
|
||||||
|
merge(obj, obj.allOf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
traverse(schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -217,19 +217,66 @@ describe('Redoc components', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('Incorrect or not supported allOf', () => {
|
describe('AllOf with other properties on the allOf level', () => {
|
||||||
it('should throw when properties or required is set on the same level as allOf', () => {
|
let joined;
|
||||||
component.pointer = '/definitions/BadAllOf2';
|
beforeAll(() => {
|
||||||
|
component.pointer = '/definitions/AllOfWithOther';
|
||||||
|
component.ngOnInit();
|
||||||
|
component.dereference();
|
||||||
|
component.joinAllOf();
|
||||||
|
joined = component.componentSchema;
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should remove $allOf field', () => {
|
||||||
|
expect(joined.allOf).toBeNull();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should set type object', () => {
|
||||||
|
joined.type.should.be.equal('object');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should merge properties', () => {
|
||||||
|
Object.keys(joined.properties).length.should.be.equal(1);
|
||||||
|
Object.keys(joined.properties).should.be.deepEqual(['id']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should merge required', () => {
|
||||||
|
joined.required.length.should.be.equal(1);
|
||||||
|
joined.required.should.be.deepEqual(['id']);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should preserve parent properties', () => {
|
||||||
|
joined.description.should.be.equal('Test');
|
||||||
|
joined.readOnly.should.be.equal(true);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('allOf edgecases', () => {
|
||||||
|
it('should merge properties and required when defined on allOf level', () => {
|
||||||
|
component.pointer = '/definitions/PropertiesOnAllOfLevel';
|
||||||
|
component.ngOnInit();
|
||||||
|
component.dereference();
|
||||||
|
(() => component.joinAllOf()).should.not.throw();
|
||||||
|
let joined = component.componentSchema;
|
||||||
|
Object.keys(joined.properties).length.should.be.equal(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
it('should throw when merging schemas with different types', () => {
|
||||||
|
component.pointer = '/definitions/BadAllOf1';
|
||||||
component.ngOnInit();
|
component.ngOnInit();
|
||||||
component.dereference();
|
component.dereference();
|
||||||
(() => component.joinAllOf()).should.throw();
|
(() => component.joinAllOf()).should.throw();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw when merging non-object schemas', () => {
|
it('should handle nested allOF', () => {
|
||||||
component.pointer = '/definitions/BadAllOf1';
|
component.pointer = '/definitions/NestedAllOf';
|
||||||
component.ngOnInit();
|
component.ngOnInit();
|
||||||
component.dereference();
|
component.dereference();
|
||||||
(() => component.joinAllOf()).should.throw();
|
(() => component.joinAllOf()).should.not.throw();
|
||||||
|
let joined = component.componentSchema;
|
||||||
|
Object.keys(joined.properties).length.should.be.equal(4);
|
||||||
|
Object.keys(joined.properties).should.be.deepEqual(['prop1', 'prop2', 'prop3', 'prop4']);
|
||||||
|
joined.required.should.be.deepEqual(['prop1', 'prop3']);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "redoc",
|
"name": "redoc",
|
||||||
"description": "Swagger-generated API Reference Documentation",
|
"description": "Swagger-generated API Reference Documentation",
|
||||||
"version": "0.7.2",
|
"version": "0.7.3",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git://github.com/Rebilly/ReDoc"
|
"url": "git://github.com/Rebilly/ReDoc"
|
||||||
|
|
|
@ -61,6 +61,7 @@ describe('APIs.guru specs test', ()=> {
|
||||||
delete apisGuruList['googleapis.com:mirror']; // bad urls in images
|
delete apisGuruList['googleapis.com:mirror']; // bad urls in images
|
||||||
delete apisGuruList['googleapis.com:discovery']; // non-string references
|
delete apisGuruList['googleapis.com:discovery']; // non-string references
|
||||||
delete apisGuruList['clarify.io']; // non-string references
|
delete apisGuruList['clarify.io']; // non-string references
|
||||||
|
delete apisGuruList['pushpay.com']; // https://github.com/Rebilly/ReDoc/issues/30
|
||||||
|
|
||||||
// run quick version of e2e test on all builds except releases
|
// run quick version of e2e test on all builds except releases
|
||||||
if (process.env.TRAVIS && !process.env.TRAVIS_TAG) {
|
if (process.env.TRAVIS && !process.env.TRAVIS_TAG) {
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
"basePath": "/v2/",
|
"basePath": "/v2/",
|
||||||
"definitions": {
|
"definitions": {
|
||||||
"Simple": {
|
"Simple": {
|
||||||
|
"description": "simple",
|
||||||
"type": "object",
|
"type": "object",
|
||||||
"required": ["id"],
|
"required": ["id"],
|
||||||
"properties": {
|
"properties": {
|
||||||
|
@ -57,6 +58,15 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
"AllOfWithOther": {
|
||||||
|
"description": "Test",
|
||||||
|
"readOnly": true,
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/Simple"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"BadAllOf1": {
|
"BadAllOf1": {
|
||||||
"allOf": [
|
"allOf": [
|
||||||
{
|
{
|
||||||
|
@ -67,8 +77,12 @@
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"BadAllOf2": {
|
"PropertiesOnAllOfLevel": {
|
||||||
"properties": {},
|
"properties": {
|
||||||
|
"prop": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
"allOf": [
|
"allOf": [
|
||||||
{
|
{
|
||||||
"$ref": "#/definitions/Simple"
|
"$ref": "#/definitions/Simple"
|
||||||
|
@ -83,6 +97,21 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"NestedAllOf": {
|
||||||
|
"allOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/definitions/SimpleAllOf"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"prop4": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"paths": {
|
"paths": {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user