redoc/lib/components/JsonSchema/json-schema.js

138 lines
4.3 KiB
JavaScript
Raw Normal View History

2015-11-19 00:23:18 +03:00
'use strict';
import {RedocComponent, BaseComponent} from '../base';
2016-01-09 23:34:44 +03:00
import {Tabs, Tab} from '../../common/components/Tabs/tabs';
import {ElementRef} from 'angular2/core';
2015-11-29 18:06:08 +03:00
import JsonPointer from '../../utils/JsonPointer';
2015-11-19 00:23:18 +03:00
@RedocComponent({
selector: 'json-schema',
templateUrl: './lib/components/JsonSchema/json-schema.html',
styleUrls: ['./lib/components/JsonSchema/json-schema.css'],
2016-01-09 23:34:44 +03:00
directives: [JsonSchema, Tabs, Tab],
inputs: ['isArray', 'final']
2015-11-19 00:23:18 +03:00
})
export default class JsonSchema extends BaseComponent {
constructor(schemaMgr, elementRef) {
super(schemaMgr);
this.element = elementRef.nativeElement;
2016-01-09 23:34:44 +03:00
this.final = false;
2015-11-19 00:23:18 +03:00
}
prepareModel() {
this.data = {};
this.data.properties = [];
2016-01-09 23:34:44 +03:00
this.data.derived = [];
if (!this.componentSchema) {
2016-01-09 18:16:43 +03:00
throw new Error(`Can't load component schema at ${this.pointer}`);
2015-11-19 00:23:18 +03:00
}
2015-11-28 01:44:35 +03:00
this.dereference();
let schema = this.componentSchema;
2015-11-28 01:44:35 +03:00
if (schema.type === 'array') {
this.isArray = true;
2016-01-17 00:24:05 +03:00
if (schema._pointer) {
this.pointer = JsonPointer.join(schema._pointer, 'items');
}
2015-11-28 01:44:35 +03:00
schema = schema.items;
}
2016-01-09 23:34:44 +03:00
let normPtr = schema._pointer || this.pointer;
let derived = this.schemaMgr.findDerivedDefinitions( normPtr );
if (!this.final && derived.length) {
this.data.derived = derived;
this.data.discriminator = schema.discriminator;
}
2016-01-10 18:29:35 +03:00
this.joinAllOf(schema, {omitParent: true});
2016-01-17 00:24:05 +03:00
if (schema.type !== 'object') {
this.isTrivial = true;
this._displayType = schema.type;
if (schema.format) this._displayType = `${this.displayType} <${schema.format}>`;
return;
2015-11-28 01:44:35 +03:00
}
this.pointer = schema._pointer || this.pointer;
this.requiredMap = {};
if (this.schema.required) {
this.schema.required.forEach(prop => this.requiredMap[prop] = true);
}
2015-11-28 01:44:35 +03:00
if (!schema.properties) {
this.isTrivial = true;
this._displayType = schema.type;
this._displayTypeHint = 'This field may contain data of any type';
return;
}
2016-01-10 18:29:35 +03:00
let discriminatorFieldIdx = -1;
let props = Object.keys(schema.properties).map((prop, idx) => {
2015-11-19 00:23:18 +03:00
let propData = schema.properties[prop];
2016-01-23 17:29:34 +03:00
propData = this.injectPropData(prop, propData, schema);
2016-01-10 18:29:35 +03:00
if (propData.isDiscriminator) discriminatorFieldIdx = idx;
2015-11-19 00:23:18 +03:00
return propData;
2015-11-19 00:51:19 +03:00
});
2016-01-10 18:29:35 +03:00
// Move discriminator field to the end of properties list
if (discriminatorFieldIdx > -1) {
let discrProp = props.splice(discriminatorFieldIdx, 1);
props.push(discrProp[0]);
}
2015-11-19 00:23:18 +03:00
this.data.properties = props;
}
adjustNameColumnWidth() {
// TODO handle internal schemes differently
let names = [].slice.call(this.element.querySelectorAll('.param-name'));
let widths = names.map(el => el.offsetWidth);
let maxWidth = Math.max(...widths);
2015-11-24 01:08:11 +03:00
if (!maxWidth) return;
2015-11-19 00:23:18 +03:00
names.forEach(el => {
el.style.minWidth = maxWidth + 'px';
});
2016-01-10 18:29:35 +03:00
let discrValues = this.element.querySelector('tabs ul');
if (discrValues) discrValues.style.paddingLeft = maxWidth + 'px';
2015-11-19 00:23:18 +03:00
}
2016-01-17 00:24:05 +03:00
injectPropData(prop, propData, schema) {
2016-01-23 17:29:34 +03:00
propData = Object.assign({}, propData);
2015-11-19 00:23:18 +03:00
propData._name = prop;
propData.isRequired = this.requiredMap[prop];
2015-11-28 01:44:35 +03:00
propData._displayType = propData.type;
2016-01-17 00:24:05 +03:00
propData.isDiscriminator = (schema.discriminator === prop);
2015-11-19 00:23:18 +03:00
if (propData.type === 'array') {
let itemType = propData.items.type;
let itemFormat = propData.items.format;
2016-01-16 01:44:10 +03:00
if (itemType === 'object' || !itemType) {
2015-11-19 00:51:19 +03:00
itemType = propData.items.title || 'object';
2015-11-29 18:06:08 +03:00
propData._pointer = propData.items._pointer || JsonPointer.join(this.pointer, ['properties', prop, 'items']);
2015-11-19 00:51:19 +03:00
}
2016-01-23 17:29:34 +03:00
propData._displayType = `${itemType}`;
propData.format = itemFormat;
2015-11-28 01:44:35 +03:00
propData._isArray = true;
2016-01-23 17:29:34 +03:00
propData.type = 'array ' + propData.items.type;
2015-11-19 00:23:18 +03:00
}
if (propData.type === 'object') {
2015-11-28 01:44:35 +03:00
propData._displayType = propData.title || 'object';
2015-11-19 00:23:18 +03:00
}
if (!propData.type) {
propData._displayType = '< * >';
propData._displayTypeHint = 'This field may contain data of any type';
}
if (propData.format) propData._displayFormat = `<${propData.format}>`;
2016-01-23 17:29:34 +03:00
return propData;
2015-11-19 00:23:18 +03:00
}
init() {
setTimeout(() => this.adjustNameColumnWidth());
}
}
JsonSchema.parameters = JsonSchema.parameters.concat([[ElementRef]]);