mirror of
				https://github.com/Redocly/redoc.git
				synced 2025-11-04 01:37:32 +03:00 
			
		
		
		
	Refactor
This commit is contained in:
		
							parent
							
								
									1e97ea655e
								
							
						
					
					
						commit
						53b4f55876
					
				| 
						 | 
				
			
			@ -15,7 +15,7 @@ import {
 | 
			
		|||
import { TestComponentBuilder } from '@angular/compiler/testing';
 | 
			
		||||
 | 
			
		||||
import { ApiInfo } from './api-info';
 | 
			
		||||
import { SchemaManager } from '../../utils/SchemaManager';
 | 
			
		||||
import { SpecManager } from '../../utils/SpecManager';
 | 
			
		||||
import { OptionsService } from '../../services/index';
 | 
			
		||||
 | 
			
		||||
describe('Redoc components', () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -24,11 +24,11 @@ describe('Redoc components', () => {
 | 
			
		|||
    let component;
 | 
			
		||||
    let fixture;
 | 
			
		||||
    beforeEachProviders(() => [
 | 
			
		||||
        provide(SchemaManager, {useValue: new SchemaManager()}),
 | 
			
		||||
        provide(SpecManager, {useValue: new SpecManager()}),
 | 
			
		||||
        provide(OptionsService, {useClass: OptionsService})
 | 
			
		||||
    ]);
 | 
			
		||||
 | 
			
		||||
    beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => {
 | 
			
		||||
    beforeEach(async(inject([TestComponentBuilder, SpecManager], (tcb, schemaMgr) => {
 | 
			
		||||
      builder = tcb;
 | 
			
		||||
      return schemaMgr.load('/tests/schemas/api-info-test.json');
 | 
			
		||||
    })));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
'use strict';
 | 
			
		||||
 | 
			
		||||
import { SchemaManager, RedocComponent, BaseComponent } from '../base';
 | 
			
		||||
import { SpecManager, RedocComponent, BaseComponent } from '../base';
 | 
			
		||||
import { OptionsService } from '../../services/index';
 | 
			
		||||
 | 
			
		||||
@RedocComponent({
 | 
			
		||||
| 
						 | 
				
			
			@ -11,7 +11,7 @@ import { OptionsService } from '../../services/index';
 | 
			
		|||
export class ApiInfo extends BaseComponent {
 | 
			
		||||
  data: any;
 | 
			
		||||
  specUrl: String;
 | 
			
		||||
  constructor(schemaMgr:SchemaManager, private optionsService:OptionsService) {
 | 
			
		||||
  constructor(schemaMgr:SpecManager, private optionsService:OptionsService) {
 | 
			
		||||
    super(schemaMgr);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ import {
 | 
			
		|||
import { TestComponentBuilder } from '@angular/compiler/testing';
 | 
			
		||||
 | 
			
		||||
import { ApiLogo } from './api-logo';
 | 
			
		||||
import { SchemaManager } from '../../utils/SchemaManager';
 | 
			
		||||
import { SpecManager } from '../../utils/SpecManager';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
describe('Redoc components', () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -26,9 +26,9 @@ describe('Redoc components', () => {
 | 
			
		|||
 | 
			
		||||
    let schemaUrl = '/tests/schemas/api-info-test.json';
 | 
			
		||||
    beforeEachProviders(() => [
 | 
			
		||||
        provide(SchemaManager, {useValue: new SchemaManager()})
 | 
			
		||||
        provide(SpecManager, {useValue: new SpecManager()})
 | 
			
		||||
    ]);
 | 
			
		||||
    beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, _schemaMgr) => {
 | 
			
		||||
    beforeEach(async(inject([TestComponentBuilder, SpecManager], (tcb, _schemaMgr) => {
 | 
			
		||||
      builder = tcb;
 | 
			
		||||
      schemaMgr = _schemaMgr;
 | 
			
		||||
      return schemaMgr.load(schemaUrl);
 | 
			
		||||
| 
						 | 
				
			
			@ -70,7 +70,7 @@ describe('Redoc components', () => {
 | 
			
		|||
@Component({
 | 
			
		||||
  selector: 'test-app',
 | 
			
		||||
  directives: [ApiLogo],
 | 
			
		||||
  providers: [SchemaManager],
 | 
			
		||||
  providers: [SpecManager],
 | 
			
		||||
  template:
 | 
			
		||||
      `<api-logo></api-logo>`
 | 
			
		||||
})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
'use strict';
 | 
			
		||||
 | 
			
		||||
import {RedocComponent, BaseComponent, SchemaManager} from '../base';
 | 
			
		||||
import {RedocComponent, BaseComponent, SpecManager} from '../base';
 | 
			
		||||
 | 
			
		||||
@RedocComponent({
 | 
			
		||||
  selector: 'api-logo',
 | 
			
		||||
| 
						 | 
				
			
			@ -10,7 +10,7 @@ import {RedocComponent, BaseComponent, SchemaManager} from '../base';
 | 
			
		|||
export class ApiLogo extends BaseComponent {
 | 
			
		||||
  data:any = {};
 | 
			
		||||
 | 
			
		||||
  constructor(schemaMgr:SchemaManager) {
 | 
			
		||||
  constructor(schemaMgr:SpecManager) {
 | 
			
		||||
    super(schemaMgr);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,13 +15,13 @@ import { TestComponentBuilder } from '@angular/compiler/testing';
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
import { JsonSchemaLazy } from './json-schema-lazy';
 | 
			
		||||
import { SchemaManager } from '../../utils/SchemaManager';
 | 
			
		||||
import { SpecManager } from '../../utils/SpecManager';
 | 
			
		||||
 | 
			
		||||
describe('Redoc components', () => {
 | 
			
		||||
  describe('JsonSchemaLazy Component', () => {
 | 
			
		||||
    let builder;
 | 
			
		||||
    let component;
 | 
			
		||||
    let schemaMgr = new SchemaManager();
 | 
			
		||||
    let schemaMgr = new SpecManager();
 | 
			
		||||
    let fixture;
 | 
			
		||||
    let loader;
 | 
			
		||||
    let appRefMock = {
 | 
			
		||||
| 
						 | 
				
			
			@ -31,7 +31,7 @@ describe('Redoc components', () => {
 | 
			
		|||
      hostView: { changeDetectorRef: {detectChanges : () => undefined} }
 | 
			
		||||
    };
 | 
			
		||||
    beforeEachProviders(() => [
 | 
			
		||||
        provide(SchemaManager, {useValue: schemaMgr})
 | 
			
		||||
        provide(SpecManager, {useValue: schemaMgr})
 | 
			
		||||
    ]);
 | 
			
		||||
    beforeEach(inject([TestComponentBuilder, DynamicComponentLoader], (tcb, dcl) => {
 | 
			
		||||
      builder = tcb;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -6,7 +6,7 @@ import { DynamicComponentLoader, Input } from '@angular/core';
 | 
			
		|||
 | 
			
		||||
import { JsonSchema } from './json-schema';
 | 
			
		||||
import { OptionsService } from '../../services/options.service';
 | 
			
		||||
import { SchemaManager } from '../../utils/SchemaManager';
 | 
			
		||||
import { SpecManager } from '../../utils/SpecManager';
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
var cache = {};
 | 
			
		||||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ export class JsonSchemaLazy implements OnDestroy, AfterViewInit {
 | 
			
		|||
  @Input() auto: boolean;
 | 
			
		||||
  @Input() isRequestSchema: boolean;
 | 
			
		||||
  loaded: boolean = false;
 | 
			
		||||
  constructor(private schemaMgr:SchemaManager, private viewRef:ViewContainerRef, private elementRef:ElementRef,
 | 
			
		||||
  constructor(private schemaMgr:SpecManager, private viewRef:ViewContainerRef, private elementRef:ElementRef,
 | 
			
		||||
    private dcl:DynamicComponentLoader, private optionsService:OptionsService) {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -61,7 +61,7 @@ export class JsonSchemaLazy implements OnDestroy, AfterViewInit {
 | 
			
		|||
 | 
			
		||||
          // skip caching view with tabs inside (discriminator)
 | 
			
		||||
          // as it needs attached controller
 | 
			
		||||
          if (compRef.instance.hasDiscriminator) {
 | 
			
		||||
          if (compRef.instance.hasDescendants) {
 | 
			
		||||
            this._loadAfterSelf();
 | 
			
		||||
            return;
 | 
			
		||||
          }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -21,7 +21,7 @@
 | 
			
		|||
  <!-- <caption> {{_displayType}} </caption> -->
 | 
			
		||||
  <template ngFor [ngForOf]="schema._properties" let-prop="$implicit" let-last="last">
 | 
			
		||||
    <tr class="param" [ngClass]="{'last': last,
 | 
			
		||||
        'discriminator': prop.isDiscriminator && !derivedEmtpy,
 | 
			
		||||
        'discriminator': hasDescendants && !activeDescendant.empty,
 | 
			
		||||
        'complex': prop._pointer,
 | 
			
		||||
        'additional': prop._additional
 | 
			
		||||
      }">
 | 
			
		||||
| 
						 | 
				
			
			@ -43,9 +43,9 @@
 | 
			
		|||
        <div class="param-description" [innerHtml]="prop.description | marked"></div>
 | 
			
		||||
        <div class="discriminator-info" *ngIf="prop.isDiscriminator">
 | 
			
		||||
          <span>This field value determines the exact schema:</span>
 | 
			
		||||
          <drop-down (change)="selectDerived($event)">
 | 
			
		||||
            <option *ngFor="let derived of schema._derived; let i=index"
 | 
			
		||||
            [value]="i">{{derived.name}}</option>
 | 
			
		||||
          <drop-down (change)="selectDescendant($event)">
 | 
			
		||||
            <option *ngFor="let descendant of schema._descendants; let i=index"
 | 
			
		||||
            [value]="i">{{descendant.name}}</option>
 | 
			
		||||
          </drop-down>
 | 
			
		||||
        </div>
 | 
			
		||||
      </td>
 | 
			
		||||
| 
						 | 
				
			
			@ -58,11 +58,11 @@
 | 
			
		|||
      </td>
 | 
			
		||||
    </tr>
 | 
			
		||||
  </template>
 | 
			
		||||
  <tr *ngIf="schema._derived.length" class="param-wrap discriminator-wrap" [ngClass]="{'empty': derivedEmtpy}">
 | 
			
		||||
  <tr *ngIf="hasDescendants" class="param-wrap discriminator-wrap">
 | 
			
		||||
    <td colspan="2">
 | 
			
		||||
      <div class="derived-schema" *ngFor="let derived of schema._derived" [ngClass]="{active: derived.active}">
 | 
			
		||||
        <json-schema class="discriminator-part" *ngIf="!derived.empty" [childFor]="pointer"
 | 
			
		||||
        pointer="{{derived.$ref}}" [final]="derived.final" [isRequestSchema]="isRequestSchema">
 | 
			
		||||
      <div class="derived-schema" *ngFor="let descendant of schema._descendants" [ngClass]="{active: descendant.active, empty: activeDescendant.empty}">
 | 
			
		||||
        <json-schema class="discriminator-part" *ngIf="!descendant.empty" [childFor]="pointer"
 | 
			
		||||
        pointer="{{descendant.$ref}}" [final]="descendant.final" [isRequestSchema]="isRequestSchema">
 | 
			
		||||
        </json-schema>
 | 
			
		||||
      </div>
 | 
			
		||||
    </td>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,16 +13,16 @@ import { getChildDebugElement } from '../../../tests/helpers';
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
import { JsonSchema } from './json-schema';
 | 
			
		||||
import { SchemaManager } from '../../utils/SchemaManager';;
 | 
			
		||||
import { SpecManager } from '../../utils/SpecManager';;
 | 
			
		||||
 | 
			
		||||
describe('Redoc components', () => {
 | 
			
		||||
  describe('JsonSchema Component', () => {
 | 
			
		||||
    let builder;
 | 
			
		||||
    let component;
 | 
			
		||||
    let schemaMgr = new SchemaManager();
 | 
			
		||||
    let schemaMgr = new SpecManager();
 | 
			
		||||
    let fixture;
 | 
			
		||||
    beforeEachProviders(() => [
 | 
			
		||||
        provide(SchemaManager, {useValue: schemaMgr})
 | 
			
		||||
        provide(SpecManager, {useValue: schemaMgr})
 | 
			
		||||
    ]);
 | 
			
		||||
    beforeEach(inject([TestComponentBuilder], (tcb) => {
 | 
			
		||||
      builder = tcb;
 | 
			
		||||
| 
						 | 
				
			
			@ -66,7 +66,7 @@ describe('Redoc components', () => {
 | 
			
		|||
@Component({
 | 
			
		||||
  selector: 'test-app',
 | 
			
		||||
  directives: [JsonSchema],
 | 
			
		||||
  providers: [SchemaManager],
 | 
			
		||||
  providers: [SpecManager],
 | 
			
		||||
  template:
 | 
			
		||||
      `<json-schema></json-schema>`
 | 
			
		||||
})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,11 +1,10 @@
 | 
			
		|||
'use strict';
 | 
			
		||||
 | 
			
		||||
import { ElementRef, Input } from '@angular/core';
 | 
			
		||||
import { Input } from '@angular/core';
 | 
			
		||||
 | 
			
		||||
import { RedocComponent, BaseComponent, SchemaManager } from '../base';
 | 
			
		||||
import { RedocComponent, BaseComponent, SpecManager } from '../base';
 | 
			
		||||
import { DropDown } from '../../shared/components/index';
 | 
			
		||||
import JsonPointer from '../../utils/JsonPointer';
 | 
			
		||||
import { SchemaNormalizator } from '../../services/spec-helper.service';
 | 
			
		||||
import { SchemaNormalizer, SchemaHelper } from '../../services/index';
 | 
			
		||||
 | 
			
		||||
@RedocComponent({
 | 
			
		||||
  selector: 'json-schema',
 | 
			
		||||
| 
						 | 
				
			
			@ -15,83 +14,40 @@ import { SchemaNormalizator } from '../../services/spec-helper.service';
 | 
			
		|||
  detect: true
 | 
			
		||||
})
 | 
			
		||||
export class JsonSchema extends BaseComponent {
 | 
			
		||||
  $element: any;
 | 
			
		||||
  schema: any;
 | 
			
		||||
  derivedEmtpy: boolean;
 | 
			
		||||
  hasDiscriminator: boolean = false;
 | 
			
		||||
  activeDescendant:any = {};
 | 
			
		||||
  hasDescendants: boolean = false;
 | 
			
		||||
  @Input() isArray: boolean;
 | 
			
		||||
  @Input() final: boolean = false;
 | 
			
		||||
  @Input() nestOdd: boolean;
 | 
			
		||||
  @Input() childFor: string;
 | 
			
		||||
  @Input() isRequestSchema: boolean;
 | 
			
		||||
  normalizer: SchemaNormalizator;
 | 
			
		||||
  normalizer: SchemaNormalizer;
 | 
			
		||||
 | 
			
		||||
  static injectPropertyData(propertySchema, propertyName, propPointer, hostPointer?) {
 | 
			
		||||
    propertySchema = Object.assign({}, propertySchema);
 | 
			
		||||
 | 
			
		||||
    propertySchema._name = propertyName;
 | 
			
		||||
    runInjectors(propertySchema, propertySchema, propPointer, hostPointer);
 | 
			
		||||
 | 
			
		||||
    return propertySchema;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  constructor(schemaMgr:SchemaManager, elementRef:ElementRef) {
 | 
			
		||||
  constructor(schemaMgr:SpecManager) {
 | 
			
		||||
    super(schemaMgr);
 | 
			
		||||
    this.$element = elementRef.nativeElement;
 | 
			
		||||
    this.normalizer = new SchemaNormalizator(schemaMgr);
 | 
			
		||||
    this.normalizer = new SchemaNormalizer(schemaMgr);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  selectDerived(subClassIdx) {
 | 
			
		||||
    let subClass = this.schema._derived[subClassIdx];
 | 
			
		||||
    if (!subClass || subClass.active) return;
 | 
			
		||||
    this.schema._derived.forEach((subSchema) => {
 | 
			
		||||
  get normPointer() {
 | 
			
		||||
    return this.schema._pointer || this.pointer;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  selectDescendant(idx) {
 | 
			
		||||
    let activeDescendant = this.schema._descendants[idx];
 | 
			
		||||
    if (!activeDescendant || activeDescendant.active) return;
 | 
			
		||||
    this.schema._descendants.forEach(subSchema => {
 | 
			
		||||
      subSchema.active = false;
 | 
			
		||||
    });
 | 
			
		||||
    subClass.active = true;
 | 
			
		||||
    this.derivedEmtpy = false;
 | 
			
		||||
    if (subClass.empty) this.derivedEmtpy = true;
 | 
			
		||||
    activeDescendant.active = true;
 | 
			
		||||
    this.activeDescendant = activeDescendant;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  unwrapArray(schema) {
 | 
			
		||||
    var res = schema;
 | 
			
		||||
    if (schema && schema.type === 'array') {
 | 
			
		||||
      let ptr = schema.items._pointer
 | 
			
		||||
        || JsonPointer.join(schema._pointer || this.pointer, ['items']);
 | 
			
		||||
      res = schema.items;
 | 
			
		||||
      res._isArray = true;
 | 
			
		||||
      res._pointer = ptr;
 | 
			
		||||
      res = this.unwrapArray(res);
 | 
			
		||||
    }
 | 
			
		||||
    return res;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  prepareModel() {
 | 
			
		||||
    if (!this.componentSchema) {
 | 
			
		||||
      throw new Error(`Can't load component schema at ${this.pointer}`);
 | 
			
		||||
    }
 | 
			
		||||
    if (this.componentSchema['x-redoc-js-precompiled']) {
 | 
			
		||||
      this.schema = this.unwrapArray(this.componentSchema);
 | 
			
		||||
  initDescendants() {
 | 
			
		||||
    if (!this.schema._descendants || !this.schema._descendants.length) {
 | 
			
		||||
      return;
 | 
			
		||||
    }
 | 
			
		||||
    this.componentSchema = this.normalizer.normalize(this.componentSchema, this.pointer);
 | 
			
		||||
    this.componentSchema['x-redoc-js-precompiled'] = true;
 | 
			
		||||
 | 
			
		||||
    let schema = this.componentSchema;
 | 
			
		||||
    this.schema = schema = this.unwrapArray(schema);
 | 
			
		||||
    runInjectors(schema, schema, schema._pointer || this.pointer, this.pointer);
 | 
			
		||||
 | 
			
		||||
    this.schema._derived = this.schema._derived || [];
 | 
			
		||||
 | 
			
		||||
    if (!schema.isTrivial) {
 | 
			
		||||
      this.prepareObjectPropertiesData(schema);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    this.initDerived();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  initDerived() {
 | 
			
		||||
    if (!this.schema._derived.length) return;
 | 
			
		||||
    this.hasDiscriminator = true;
 | 
			
		||||
    this.hasDescendants = true;
 | 
			
		||||
    let enumArr = this.schema._properties[this.schema._properties.length - 1].enum;
 | 
			
		||||
    if (enumArr) {
 | 
			
		||||
      let enumOrder = {};
 | 
			
		||||
| 
						 | 
				
			
			@ -103,192 +59,26 @@ export class JsonSchema extends BaseComponent {
 | 
			
		|||
        return enumOrder[a.name] > enumOrder[b.name] ? 1 : -1;
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
    this.selectDerived(0);
 | 
			
		||||
    this.selectDescendant(0);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  prepareObjectPropertiesData(schema) {
 | 
			
		||||
    let requiredMap = {};
 | 
			
		||||
    if (schema.required) {
 | 
			
		||||
      schema.required.forEach(prop => requiredMap[prop] = true);
 | 
			
		||||
  prepareModel() {
 | 
			
		||||
    let schema = this.schema = this.componentSchema;
 | 
			
		||||
    if (!schema) {
 | 
			
		||||
      throw new Error(`Can't load component schema at ${this.pointer}`);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let discriminatorFieldIdx = -1;
 | 
			
		||||
    let props = schema.properties && Object.keys(schema.properties).map((prop, idx) => {
 | 
			
		||||
      let propertySchema = schema.properties[prop];
 | 
			
		||||
      let propPointer = propertySchema._pointer ||
 | 
			
		||||
        JsonPointer.join(schema._pointer || this.pointer, ['properties', prop]);
 | 
			
		||||
      propertySchema = JsonSchema.injectPropertyData(propertySchema, prop, propPointer);
 | 
			
		||||
      // stop endless discriminator recursion
 | 
			
		||||
      if (propertySchema._pointer === this.childFor) {
 | 
			
		||||
        propertySchema._pointer = null;
 | 
			
		||||
      }
 | 
			
		||||
      propertySchema.required = !!requiredMap[prop];
 | 
			
		||||
      propertySchema.isDiscriminator = (schema.discriminator === prop);
 | 
			
		||||
      if (propertySchema.isDiscriminator) {
 | 
			
		||||
        discriminatorFieldIdx = idx;
 | 
			
		||||
      }
 | 
			
		||||
      return propertySchema;
 | 
			
		||||
    });
 | 
			
		||||
    schema = this.normalizer.normalize(schema, this.normPointer);
 | 
			
		||||
    this.schema = schema = SchemaHelper.unwrapArray(schema, this.normPointer);
 | 
			
		||||
    SchemaHelper.preprocess(schema, schema, this.normPointer, this.pointer);
 | 
			
		||||
 | 
			
		||||
    props = props || [];
 | 
			
		||||
 | 
			
		||||
    if (schema.additionalProperties && schema.additionalProperties !== false) {
 | 
			
		||||
      let propsSchema = this.prepareAdditionalProperties(schema);
 | 
			
		||||
      propsSchema._additional = true;
 | 
			
		||||
      props.push(propsSchema);
 | 
			
		||||
    if (!schema.isTrivial) {
 | 
			
		||||
      SchemaHelper.preprocessProperties(schema, this.normPointer, {
 | 
			
		||||
        childFor: this.childFor,
 | 
			
		||||
        skipReadOnly: this.isRequestSchema
 | 
			
		||||
      });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Move discriminator field to the end of properties list
 | 
			
		||||
    if (discriminatorFieldIdx > -1) {
 | 
			
		||||
      let discrProp = props.splice(discriminatorFieldIdx, 1);
 | 
			
		||||
      props.push(discrProp[0]);
 | 
			
		||||
    }
 | 
			
		||||
    // filter readOnly props for request schemas
 | 
			
		||||
    if (this.isRequestSchema) {
 | 
			
		||||
      props = props.filter(prop => !prop.readOnly);
 | 
			
		||||
    }
 | 
			
		||||
    schema._properties = props;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  prepareAdditionalProperties(schema) {
 | 
			
		||||
    var addProps = schema.additionalProperties;
 | 
			
		||||
    return JsonSchema.injectPropertyData(addProps, '<Additional Properties> *',
 | 
			
		||||
      JsonPointer.join(addProps._pointer || schema._pointer || this.pointer, ['additionalProperties']));
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const injectors = {
 | 
			
		||||
  general: {
 | 
			
		||||
    check: () => true,
 | 
			
		||||
    inject: (injectTo, propertySchema, pointer) => {
 | 
			
		||||
      injectTo._pointer = propertySchema._pointer || pointer;
 | 
			
		||||
      injectTo._displayType = propertySchema.type;
 | 
			
		||||
      if (propertySchema.format) injectTo._displayFormat = `<${propertySchema.format}>`;
 | 
			
		||||
      if (propertySchema.enum) {
 | 
			
		||||
        injectTo.enum = propertySchema.enum.map((value) => {
 | 
			
		||||
          return {val: value, type: typeof value};
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  discriminator: {
 | 
			
		||||
    check: (propertySchema) => propertySchema.discriminator,
 | 
			
		||||
    inject: (injectTo, propertySchema = injectTo, pointer) => {
 | 
			
		||||
      injectTo._derived = SchemaManager.instance().findDerivedDefinitions(pointer);
 | 
			
		||||
      injectTo.discriminator = propertySchema.discriminator;
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  array: {
 | 
			
		||||
    check: (propertySchema) => {
 | 
			
		||||
      return propertySchema.type === 'array';
 | 
			
		||||
    },
 | 
			
		||||
    inject: (injectTo, propertySchema = injectTo, propPointer) => {
 | 
			
		||||
      injectTo._isArray = true;
 | 
			
		||||
      injectTo._pointer = propertySchema.items._pointer
 | 
			
		||||
        || JsonPointer.join(propertySchema._pointer || propPointer, ['items']);
 | 
			
		||||
 | 
			
		||||
      runInjectors(injectTo, propertySchema.items, propPointer);
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  object: {
 | 
			
		||||
    check: (propertySchema) => {
 | 
			
		||||
      return propertySchema.type === 'object' && propertySchema.properties;
 | 
			
		||||
    },
 | 
			
		||||
    inject: (injectTo, propertySchema = injectTo) => {
 | 
			
		||||
      let baseName = propertySchema._pointer && JsonPointer.baseName(propertySchema._pointer);
 | 
			
		||||
      injectTo._displayType = propertySchema.title || baseName || 'object';
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  noType: {
 | 
			
		||||
    check: (propertySchema) => !propertySchema.type,
 | 
			
		||||
    inject: (injectTo) => {
 | 
			
		||||
      injectTo._displayType = '< * >';
 | 
			
		||||
      injectTo._displayTypeHint = 'This field may contain data of any type';
 | 
			
		||||
      injectTo.isTrivial = true;
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  simpleType: {
 | 
			
		||||
    check: (propertySchema) => {
 | 
			
		||||
      if (propertySchema.type === 'object') {
 | 
			
		||||
        return (!propertySchema.properties || !Object.keys(propertySchema.properties).length)
 | 
			
		||||
          && (typeof propertySchema.additionalProperties !== 'object');
 | 
			
		||||
      }
 | 
			
		||||
      return (propertySchema.type !== 'array') && propertySchema.type;
 | 
			
		||||
    },
 | 
			
		||||
    inject: (injectTo, propertySchema = injectTo) => {
 | 
			
		||||
      injectTo.isTrivial = true;
 | 
			
		||||
      if (injectTo._pointer) {
 | 
			
		||||
        injectTo._pointer = undefined;
 | 
			
		||||
        injectTo._displayType = propertySchema.title ?
 | 
			
		||||
          `${propertySchema.title} (${propertySchema.type})` : propertySchema.type;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  integer: {
 | 
			
		||||
    check: (propertySchema) => (propertySchema.type === 'integer' || propertySchema.type === 'number'),
 | 
			
		||||
    inject: (injectTo, propertySchema = injectTo) => {
 | 
			
		||||
      var range = '';
 | 
			
		||||
      if (propertySchema.minimum && propertySchema.maximum) {
 | 
			
		||||
        range += propertySchema.exclusiveMinimum ? '( ' : '[ ';
 | 
			
		||||
        range += propertySchema.minimum;
 | 
			
		||||
        range += ' .. ';
 | 
			
		||||
        range += propertySchema.maximum;
 | 
			
		||||
        range += propertySchema.exclusiveMaximum ? ' )' : ' ]';
 | 
			
		||||
      } else if (propertySchema.maximum) {
 | 
			
		||||
        range += propertySchema.exclusiveMaximum? '< ' : '<= ';
 | 
			
		||||
        range += propertySchema.maximum;
 | 
			
		||||
      } else if (propertySchema.minimum) {
 | 
			
		||||
        range += propertySchema.exclusiveMinimum ? '> ' : '>= ';
 | 
			
		||||
        range += propertySchema.minimum;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (range) {
 | 
			
		||||
        injectTo._range = range;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  string: {
 | 
			
		||||
    check: propertySchema => (propertySchema.type === 'string'),
 | 
			
		||||
    inject: (injectTo, propertySchema = injectTo) => {
 | 
			
		||||
      var range;
 | 
			
		||||
      if (propertySchema.minLength && propertySchema.maxLength) {
 | 
			
		||||
        range = `[ ${propertySchema.minLength} .. ${propertySchema.maxLength} ]`;
 | 
			
		||||
      } else if (propertySchema.maxLength) {
 | 
			
		||||
        range = '<= ' + propertySchema.maxLength;
 | 
			
		||||
      } else if (propertySchema.minimum) {
 | 
			
		||||
        range = '>= ' + propertySchema.minLength;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (range) {
 | 
			
		||||
        injectTo._range = range + ' characters';
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  file: {
 | 
			
		||||
    check: propertySchema => (propertySchema.type === 'file'),
 | 
			
		||||
    inject: (injectTo, propertySchema = injectTo, propPointer, hostPointer) => {
 | 
			
		||||
      injectTo.isFile = true;
 | 
			
		||||
      let parentPtr;
 | 
			
		||||
      if (propertySchema.in === 'formData') {
 | 
			
		||||
        parentPtr = JsonPointer.dirName(hostPointer, 1);
 | 
			
		||||
      } else {
 | 
			
		||||
        parentPtr = JsonPointer.dirName(hostPointer, 3);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      let parentParam = SchemaManager.instance().byPointer(parentPtr);
 | 
			
		||||
      let root = SchemaManager.instance().schema;
 | 
			
		||||
      injectTo._produces = parentParam && parentParam.produces || root.produces;
 | 
			
		||||
      injectTo._consumes = parentParam && parentParam.consumes || root.consumes;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
function runInjectors(injectTo, propertySchema, propertyPointer, hostPointer?) {
 | 
			
		||||
  for (var injName in injectors) {
 | 
			
		||||
    let injector = injectors[injName];
 | 
			
		||||
    if (injector.check(propertySchema)) {
 | 
			
		||||
      injector.inject(injectTo, propertySchema, propertyPointer, hostPointer);
 | 
			
		||||
    }
 | 
			
		||||
    this.initDescendants();
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -13,16 +13,16 @@ import { TestComponentBuilder } from '@angular/compiler/testing';
 | 
			
		|||
import { getChildDebugElement } from '../../../tests/helpers';
 | 
			
		||||
 | 
			
		||||
import { Method } from './method';
 | 
			
		||||
import { SchemaManager } from '../../utils/SchemaManager';;
 | 
			
		||||
import { SpecManager } from '../../utils/SpecManager';;
 | 
			
		||||
 | 
			
		||||
describe('Redoc components', () => {
 | 
			
		||||
  describe('Method Component', () => {
 | 
			
		||||
    let builder;
 | 
			
		||||
    let component;
 | 
			
		||||
    beforeEachProviders(() => [
 | 
			
		||||
        provide(SchemaManager, {useValue: new SchemaManager()})
 | 
			
		||||
        provide(SpecManager, {useValue: new SpecManager()})
 | 
			
		||||
    ]);
 | 
			
		||||
    beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => {
 | 
			
		||||
    beforeEach(async(inject([TestComponentBuilder, SpecManager], (tcb, schemaMgr) => {
 | 
			
		||||
      builder = tcb;
 | 
			
		||||
      return schemaMgr.load('/tests/schemas/extended-petstore.yml');
 | 
			
		||||
    })));
 | 
			
		||||
| 
						 | 
				
			
			@ -57,7 +57,7 @@ describe('Redoc components', () => {
 | 
			
		|||
@Component({
 | 
			
		||||
  selector: 'test-app',
 | 
			
		||||
  directives: [Method],
 | 
			
		||||
  providers: [SchemaManager],
 | 
			
		||||
  providers: [SpecManager],
 | 
			
		||||
  template:
 | 
			
		||||
      `<method pointer='#/paths/~1user~1{username}/put'></method>`
 | 
			
		||||
})
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
'use strict';
 | 
			
		||||
import { Input } from '@angular/core';
 | 
			
		||||
import JsonPointer from '../../utils/JsonPointer';
 | 
			
		||||
import { RedocComponent, BaseComponent, SchemaManager} from '../base';
 | 
			
		||||
import { RedocComponent, BaseComponent, SpecManager} from '../base';
 | 
			
		||||
 | 
			
		||||
import { ParamsList } from '../ParamsList/params-list';
 | 
			
		||||
import { ResponsesList } from '../ResponsesList/responses-list';
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ import { RequestSamples } from '../RequestSamples/request-samples';
 | 
			
		|||
export class Method extends BaseComponent {
 | 
			
		||||
  data:any;
 | 
			
		||||
  @Input() tag:string;
 | 
			
		||||
  constructor(schemaMgr:SchemaManager) {
 | 
			
		||||
  constructor(schemaMgr:SpecManager) {
 | 
			
		||||
    super(schemaMgr);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,7 +14,7 @@ import { getChildDebugElement } from '../../../tests/helpers';
 | 
			
		|||
 | 
			
		||||
 | 
			
		||||
import { MethodsList } from './methods-list';
 | 
			
		||||
import { SchemaManager } from '../../utils/SchemaManager';
 | 
			
		||||
import { SpecManager } from '../../utils/SpecManager';
 | 
			
		||||
 | 
			
		||||
describe('Redoc components', () => {
 | 
			
		||||
  describe('MethodsList Component', () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -22,9 +22,9 @@ describe('Redoc components', () => {
 | 
			
		|||
    let component;
 | 
			
		||||
    let fixture;
 | 
			
		||||
    beforeEachProviders(() => [
 | 
			
		||||
        provide(SchemaManager, {useValue: new SchemaManager()})
 | 
			
		||||
        provide(SpecManager, {useValue: new SpecManager()})
 | 
			
		||||
    ]);
 | 
			
		||||
    beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => {
 | 
			
		||||
    beforeEach(async(inject([TestComponentBuilder, SpecManager], (tcb, schemaMgr) => {
 | 
			
		||||
      builder = tcb;
 | 
			
		||||
      return schemaMgr.load('/tests/schemas/methods-list-component.json');
 | 
			
		||||
    })));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
'use strict';
 | 
			
		||||
 | 
			
		||||
import { forwardRef } from '@angular/core';
 | 
			
		||||
import { RedocComponent, BaseComponent, SchemaManager } from '../base';
 | 
			
		||||
import { RedocComponent, BaseComponent, SpecManager } from '../base';
 | 
			
		||||
import { Method } from '../Method/method';
 | 
			
		||||
import { EncodeURIComponentPipe } from '../../utils/pipes';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -15,7 +15,7 @@ import { EncodeURIComponentPipe } from '../../utils/pipes';
 | 
			
		|||
})
 | 
			
		||||
export class MethodsList extends BaseComponent {
 | 
			
		||||
  data:any;
 | 
			
		||||
  constructor(schemaMgr:SchemaManager) {
 | 
			
		||||
  constructor(schemaMgr:SpecManager) {
 | 
			
		||||
    super(schemaMgr);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
'use strict';
 | 
			
		||||
 | 
			
		||||
import { RedocComponent, BaseComponent, SchemaManager } from '../base';
 | 
			
		||||
import { RedocComponent, BaseComponent, SpecManager } from '../base';
 | 
			
		||||
import { JsonSchema } from '../JsonSchema/json-schema';
 | 
			
		||||
import {JsonSchemaLazy} from '../JsonSchema/json-schema-lazy';
 | 
			
		||||
import { JsonSchemaLazy } from '../JsonSchema/json-schema-lazy';
 | 
			
		||||
import { SchemaHelper } from '../../services/schema-helper.service';
 | 
			
		||||
 | 
			
		||||
function safePush(obj, prop, item) {
 | 
			
		||||
  if (!obj[prop]) obj[prop] = [];
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +20,7 @@ export class ParamsList extends BaseComponent {
 | 
			
		|||
 | 
			
		||||
  data:any;
 | 
			
		||||
 | 
			
		||||
  constructor(schemaMgr:SchemaManager) {
 | 
			
		||||
  constructor(schemaMgr:SpecManager) {
 | 
			
		||||
    super(schemaMgr);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -27,10 +28,10 @@ export class ParamsList extends BaseComponent {
 | 
			
		|||
    this.data = {};
 | 
			
		||||
    let paramsList = this.schemaMgr.getMethodParams(this.pointer, true);
 | 
			
		||||
 | 
			
		||||
    paramsList = paramsList.map((paramData) => {
 | 
			
		||||
      let propPointer = paramData._pointer;
 | 
			
		||||
      if (paramData.in === 'body') return paramData;
 | 
			
		||||
      return JsonSchema.injectPropertyData(paramData, paramData.name, propPointer, this.pointer);
 | 
			
		||||
    paramsList = paramsList.map(paramSchema => {
 | 
			
		||||
      let propPointer = paramSchema._pointer;
 | 
			
		||||
      if (paramSchema.in === 'body') return paramSchema;
 | 
			
		||||
      return SchemaHelper.preprocess(paramSchema, paramSchema.name, propPointer, this.pointer);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    let paramsMap = this.orderParams(paramsList);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,7 +15,7 @@ import {
 | 
			
		|||
import { TestComponentBuilder } from '@angular/compiler/testing';
 | 
			
		||||
 | 
			
		||||
import { Redoc } from './redoc';
 | 
			
		||||
import { SchemaManager } from '../../utils/SchemaManager';
 | 
			
		||||
import { SpecManager } from '../../utils/SpecManager';
 | 
			
		||||
import { OptionsService } from '../../services/index';
 | 
			
		||||
 | 
			
		||||
let optsMgr:OptionsService;
 | 
			
		||||
| 
						 | 
				
			
			@ -25,9 +25,9 @@ describe('Redoc components', () => {
 | 
			
		|||
    let builder;
 | 
			
		||||
    let schemaMgr;
 | 
			
		||||
    beforeEachProviders(() => [
 | 
			
		||||
        provide(SchemaManager, {useValue: new SchemaManager()}),
 | 
			
		||||
        provide(SpecManager, {useValue: new SpecManager()}),
 | 
			
		||||
    ]);
 | 
			
		||||
    beforeEach(async(inject([TestComponentBuilder, SchemaManager, OptionsService],
 | 
			
		||||
    beforeEach(async(inject([TestComponentBuilder, SpecManager, OptionsService],
 | 
			
		||||
      (tcb, _schemaMgr, _optsMgr) => {
 | 
			
		||||
      optsMgr = _optsMgr;
 | 
			
		||||
      builder = tcb;
 | 
			
		||||
| 
						 | 
				
			
			@ -106,11 +106,11 @@ describe('Redoc components', () => {
 | 
			
		|||
    let destroySpy;
 | 
			
		||||
    let dom = new BrowserDomAdapter();
 | 
			
		||||
    beforeEachProviders(() => [
 | 
			
		||||
        provide(SchemaManager, {useValue: new SchemaManager()}),
 | 
			
		||||
        provide(SpecManager, {useValue: new SpecManager()}),
 | 
			
		||||
        provide(BrowserDomAdapter, {useValue: new BrowserDomAdapter()}),
 | 
			
		||||
        provide(OptionsService, {useValue: optsMgr})
 | 
			
		||||
    ]);
 | 
			
		||||
    beforeEach(async(inject([TestComponentBuilder, SchemaManager], (tcb, schemaMgr) => {
 | 
			
		||||
    beforeEach(async(inject([TestComponentBuilder, SpecManager], (tcb, schemaMgr) => {
 | 
			
		||||
      builder = tcb;
 | 
			
		||||
      return schemaMgr.load('/tests/schemas/methods-list-component.json');
 | 
			
		||||
    })));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ import { MethodsList } from '../MethodsList/methods-list';
 | 
			
		|||
import { SideMenu } from '../SideMenu/side-menu';
 | 
			
		||||
 | 
			
		||||
import { StickySidebar } from '../../shared/components/index';
 | 
			
		||||
import {SchemaManager} from '../../utils/SchemaManager';
 | 
			
		||||
import {SpecManager} from '../../utils/SpecManager';
 | 
			
		||||
import { OptionsService, RedocEventsService } from '../../services/index';
 | 
			
		||||
//import redocVersion from '../../version.js';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -27,7 +27,7 @@ var _modeLocked = false;
 | 
			
		|||
@RedocComponent({
 | 
			
		||||
  selector: 'redoc',
 | 
			
		||||
  providers: [
 | 
			
		||||
    SchemaManager,
 | 
			
		||||
    SpecManager,
 | 
			
		||||
    BrowserDomAdapter,
 | 
			
		||||
    RedocEventsService
 | 
			
		||||
  ],
 | 
			
		||||
| 
						 | 
				
			
			@ -71,7 +71,7 @@ export class Redoc extends BaseComponent implements AfterViewInit {
 | 
			
		|||
      Redoc.destroy();
 | 
			
		||||
    }
 | 
			
		||||
    Redoc.showLoadingAnimation();
 | 
			
		||||
    return SchemaManager.instance().load(specUrl)
 | 
			
		||||
    return SpecManager.instance().load(specUrl)
 | 
			
		||||
    .then(() => {
 | 
			
		||||
      if (!_modeLocked && !optionsService.options.debugMode) {
 | 
			
		||||
        enableProdMode();
 | 
			
		||||
| 
						 | 
				
			
			@ -139,7 +139,7 @@ export class Redoc extends BaseComponent implements AfterViewInit {
 | 
			
		|||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  constructor(schemaMgr: SchemaManager, optionsMgr:OptionsService, elementRef:ElementRef,
 | 
			
		||||
  constructor(schemaMgr: SpecManager, optionsMgr:OptionsService, elementRef:ElementRef,
 | 
			
		||||
    public events:RedocEventsService) {
 | 
			
		||||
    super(schemaMgr);
 | 
			
		||||
    this.element = elementRef.nativeElement;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
 | 
			
		||||
import { ViewChildren, QueryList, EventEmitter, Input} from '@angular/core';
 | 
			
		||||
 | 
			
		||||
import { RedocComponent, BaseComponent, SchemaManager } from '../base';
 | 
			
		||||
import { RedocComponent, BaseComponent, SpecManager } from '../base';
 | 
			
		||||
import JsonPointer from '../../utils/JsonPointer';
 | 
			
		||||
import { Tabs, Tab } from '../../shared/components/index';
 | 
			
		||||
import { SchemaSample } from '../SchemaSample/schema-sample';
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +25,7 @@ export class RequestSamples extends BaseComponent {
 | 
			
		|||
  data: any;
 | 
			
		||||
  @Input() schemaPointer:string;
 | 
			
		||||
  @ViewChildren(Tabs) childQuery:QueryList<Tabs>;
 | 
			
		||||
  constructor(schemaMgr:SchemaManager, public events:RedocEventsService) {
 | 
			
		||||
  constructor(schemaMgr:SpecManager, public events:RedocEventsService) {
 | 
			
		||||
    super(schemaMgr);
 | 
			
		||||
 | 
			
		||||
    this.selectedLang = this.events.samplesLanguageChanged;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
'use strict';
 | 
			
		||||
 | 
			
		||||
import {RedocComponent, BaseComponent, SchemaManager} from '../base';
 | 
			
		||||
import {RedocComponent, BaseComponent, SpecManager} from '../base';
 | 
			
		||||
import JsonPointer from '../../utils/JsonPointer';
 | 
			
		||||
import { JsonSchema } from '../JsonSchema/json-schema';
 | 
			
		||||
import { JsonSchemaLazy } from '../JsonSchema/json-schema-lazy';
 | 
			
		||||
| 
						 | 
				
			
			@ -22,7 +22,7 @@ function isNumeric(n) {
 | 
			
		|||
export class ResponsesList extends BaseComponent {
 | 
			
		||||
  data: any;
 | 
			
		||||
  options: any;
 | 
			
		||||
  constructor(schemaMgr:SchemaManager, optionsMgr:OptionsService) {
 | 
			
		||||
  constructor(schemaMgr:SpecManager, optionsMgr:OptionsService) {
 | 
			
		||||
    super(schemaMgr);
 | 
			
		||||
    this.options = optionsMgr.options;
 | 
			
		||||
  }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
'use strict';
 | 
			
		||||
 | 
			
		||||
import { forwardRef } from '@angular/core';
 | 
			
		||||
import { RedocComponent, BaseComponent, SchemaManager } from '../base';
 | 
			
		||||
import { RedocComponent, BaseComponent, SpecManager } from '../base';
 | 
			
		||||
import JsonPointer from '../../utils/JsonPointer';
 | 
			
		||||
import { Tabs, Tab } from '../../shared/components/index';
 | 
			
		||||
import { SchemaSample } from '../index';
 | 
			
		||||
| 
						 | 
				
			
			@ -25,7 +25,7 @@ function hasExample(response) {
 | 
			
		|||
})
 | 
			
		||||
export class ResponsesSamples extends BaseComponent {
 | 
			
		||||
  data: any;
 | 
			
		||||
  constructor(schemaMgr:SchemaManager) {
 | 
			
		||||
  constructor(schemaMgr:SpecManager) {
 | 
			
		||||
    super(schemaMgr);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,9 +4,9 @@ import { ElementRef, Input } from '@angular/core';
 | 
			
		|||
 | 
			
		||||
import * as OpenAPISampler from 'openapi-sampler';
 | 
			
		||||
 | 
			
		||||
import { RedocComponent, BaseComponent, SchemaManager } from '../base';
 | 
			
		||||
import { RedocComponent, BaseComponent, SpecManager } from '../base';
 | 
			
		||||
import { JsonFormatter } from '../../utils/JsonFormatterPipe';
 | 
			
		||||
import { SchemaNormalizator } from '../../services/spec-helper.service';
 | 
			
		||||
import { SchemaNormalizer } from '../../services/schema-normalizer.service';
 | 
			
		||||
 | 
			
		||||
@RedocComponent({
 | 
			
		||||
  selector: 'schema-sample',
 | 
			
		||||
| 
						 | 
				
			
			@ -19,12 +19,12 @@ export class SchemaSample extends BaseComponent {
 | 
			
		|||
  data: any;
 | 
			
		||||
  @Input() skipReadOnly:boolean;
 | 
			
		||||
 | 
			
		||||
  private _normalizer:SchemaNormalizator;
 | 
			
		||||
  private _normalizer:SchemaNormalizer;
 | 
			
		||||
 | 
			
		||||
  constructor(schemaMgr:SchemaManager, elementRef:ElementRef) {
 | 
			
		||||
  constructor(schemaMgr:SpecManager, elementRef:ElementRef) {
 | 
			
		||||
    super(schemaMgr);
 | 
			
		||||
    this.element = elementRef.nativeElement;
 | 
			
		||||
    this._normalizer = new SchemaNormalizator(schemaMgr);
 | 
			
		||||
    this._normalizer = new SchemaNormalizer(schemaMgr);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  init() {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,7 +16,7 @@ import { TestComponentBuilder } from '@angular/compiler/testing';
 | 
			
		|||
 | 
			
		||||
import { MethodsList, SideMenu } from '../index';
 | 
			
		||||
 | 
			
		||||
import { SchemaManager } from '../../utils/SchemaManager';;
 | 
			
		||||
import { SpecManager } from '../../utils/SpecManager';;
 | 
			
		||||
 | 
			
		||||
let testOptions;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -26,9 +26,9 @@ describe('Redoc components', () => {
 | 
			
		|||
    let component;
 | 
			
		||||
    let fixture;
 | 
			
		||||
    beforeEachProviders(() => [
 | 
			
		||||
        provide(SchemaManager, {useValue: new SchemaManager()})
 | 
			
		||||
        provide(SpecManager, {useValue: new SpecManager()})
 | 
			
		||||
    ]);
 | 
			
		||||
    beforeEach(async(inject([TestComponentBuilder, SchemaManager, OptionsService],
 | 
			
		||||
    beforeEach(async(inject([TestComponentBuilder, SpecManager, OptionsService],
 | 
			
		||||
      (tcb, schemaMgr, opts) => {
 | 
			
		||||
      builder = tcb;
 | 
			
		||||
      testOptions = opts;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,7 +4,7 @@ import { ElementRef, ChangeDetectorRef } from '@angular/core';
 | 
			
		|||
import { BrowserDomAdapter } from '@angular/platform-browser/src/browser/browser_adapter';
 | 
			
		||||
import { global } from '@angular/core/src/facade/lang';
 | 
			
		||||
import { trigger, state, animate, transition, style } from '@angular/core';
 | 
			
		||||
import { RedocComponent, BaseComponent, SchemaManager } from '../base';
 | 
			
		||||
import { RedocComponent, BaseComponent, SpecManager } from '../base';
 | 
			
		||||
import { ScrollService, Hash, MenuService, OptionsService } from '../../services/index';
 | 
			
		||||
 | 
			
		||||
@RedocComponent({
 | 
			
		||||
| 
						 | 
				
			
			@ -35,7 +35,7 @@ export class SideMenu extends BaseComponent {
 | 
			
		|||
  activeItemCaption: string;
 | 
			
		||||
  options: any;
 | 
			
		||||
  data: any;
 | 
			
		||||
  constructor(schemaMgr:SchemaManager, elementRef:ElementRef, private dom:BrowserDomAdapter,
 | 
			
		||||
  constructor(schemaMgr:SpecManager, elementRef:ElementRef, private dom:BrowserDomAdapter,
 | 
			
		||||
  private scrollService:ScrollService, private menuService:MenuService, private hash:Hash,
 | 
			
		||||
  optionsService:OptionsService, private detectorRef:ChangeDetectorRef) {
 | 
			
		||||
    super(schemaMgr);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
'use strict';
 | 
			
		||||
 | 
			
		||||
import { SchemaManager } from '../utils/SchemaManager';
 | 
			
		||||
import { SpecManager } from '../utils/SpecManager';
 | 
			
		||||
import { BaseComponent } from '../components/base';
 | 
			
		||||
 | 
			
		||||
describe('Redoc components', () => {
 | 
			
		||||
| 
						 | 
				
			
			@ -9,7 +9,7 @@ describe('Redoc components', () => {
 | 
			
		|||
    let component;
 | 
			
		||||
 | 
			
		||||
    beforeAll(() => {
 | 
			
		||||
      schemaMgr = new SchemaManager();
 | 
			
		||||
      schemaMgr = new SpecManager();
 | 
			
		||||
      schemaMgr._schema = {tags: []};
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,10 +1,10 @@
 | 
			
		|||
'use strict';
 | 
			
		||||
import { Component, ChangeDetectionStrategy, OnInit, OnDestroy } from '@angular/core';
 | 
			
		||||
import { CORE_DIRECTIVES, JsonPipe, AsyncPipe } from '@angular/common';
 | 
			
		||||
import { SchemaManager } from '../utils/SchemaManager';
 | 
			
		||||
import { SpecManager } from '../utils/SpecManager';
 | 
			
		||||
import { MarkedPipe, JsonPointerEscapePipe } from '../utils/pipes';
 | 
			
		||||
 | 
			
		||||
export { SchemaManager };
 | 
			
		||||
export { SpecManager };
 | 
			
		||||
 | 
			
		||||
// common inputs for all components
 | 
			
		||||
let commonInputs = ['pointer']; // json pointer to the schema chunk
 | 
			
		||||
| 
						 | 
				
			
			@ -84,7 +84,7 @@ export class BaseComponent implements OnInit, OnDestroy {
 | 
			
		|||
  pointer: String;
 | 
			
		||||
  dereferencedCache = {};
 | 
			
		||||
 | 
			
		||||
  constructor(public schemaMgr: SchemaManager) {
 | 
			
		||||
  constructor(public schemaMgr: SpecManager) {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,3 +5,5 @@ export * from './options.service';
 | 
			
		|||
export * from './menu.service';
 | 
			
		||||
export * from './scroll.service';
 | 
			
		||||
export * from './hash.service';
 | 
			
		||||
export * from './schema-normalizer.service';
 | 
			
		||||
export * from './schema-helper.service';
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ import { Hash } from './hash.service';
 | 
			
		|||
import { ScrollService } from './scroll.service';
 | 
			
		||||
import { RedocEventsService } from './events.service';
 | 
			
		||||
import { MethodsList } from '../components/index';
 | 
			
		||||
import { SchemaManager } from '../utils/SchemaManager';;
 | 
			
		||||
import { SpecManager } from '../utils/SpecManager';;
 | 
			
		||||
 | 
			
		||||
describe('Menu service', () => {
 | 
			
		||||
  let menu, hashService, scroll;
 | 
			
		||||
| 
						 | 
				
			
			@ -30,10 +30,10 @@ describe('Menu service', () => {
 | 
			
		|||
      provide(Hash, {useClass: Hash}),
 | 
			
		||||
      provide(ScrollService, {useClass: ScrollService}),
 | 
			
		||||
      provide(RedocEventsService, {useClass: RedocEventsService}),
 | 
			
		||||
      provide(SchemaManager, {useClass: SchemaManager})
 | 
			
		||||
      provide(SpecManager, {useClass: SpecManager})
 | 
			
		||||
  ]);
 | 
			
		||||
 | 
			
		||||
  beforeEach(inject([Hash, ScrollService, SchemaManager, TestComponentBuilder],
 | 
			
		||||
  beforeEach(inject([Hash, ScrollService, SpecManager, TestComponentBuilder],
 | 
			
		||||
    (_hash, _scroll, _schemaMgr, tcb) => {
 | 
			
		||||
    hashService = _hash;
 | 
			
		||||
    scroll = _scroll;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -2,7 +2,7 @@
 | 
			
		|||
import { Injectable, EventEmitter } from '@angular/core';
 | 
			
		||||
import { ScrollService, INVIEW_POSITION } from './scroll.service';
 | 
			
		||||
import { Hash } from './hash.service';
 | 
			
		||||
import { SchemaManager } from '../utils/SchemaManager';
 | 
			
		||||
import { SpecManager } from '../utils/SpecManager';
 | 
			
		||||
 | 
			
		||||
const CHANGE = {
 | 
			
		||||
  NEXT : 1,
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +19,7 @@ export class MenuService {
 | 
			
		|||
  activeMethodIdx: number = -1;
 | 
			
		||||
  activeMethodPtr: string;
 | 
			
		||||
 | 
			
		||||
  constructor(private hash:Hash, private scrollService:ScrollService, schemaMgr:SchemaManager) {
 | 
			
		||||
  constructor(private hash:Hash, private scrollService:ScrollService, schemaMgr:SpecManager) {
 | 
			
		||||
    this.hash = hash;
 | 
			
		||||
 | 
			
		||||
    this.categories = Array.from(schemaMgr.buildMenuTree().entries()).map(
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										219
									
								
								lib/services/schema-helper.service.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										219
									
								
								lib/services/schema-helper.service.ts
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
				
			
			@ -0,0 +1,219 @@
 | 
			
		|||
'use strict';
 | 
			
		||||
import { JsonPointer } from '../utils/JsonPointer';
 | 
			
		||||
import { SpecManager } from '../utils/SpecManager';
 | 
			
		||||
 | 
			
		||||
interface PropertyPreprocessOptions {
 | 
			
		||||
  childFor: string;
 | 
			
		||||
  skipReadOnly: boolean;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const injectors = {
 | 
			
		||||
  general: {
 | 
			
		||||
    check: () => true,
 | 
			
		||||
    inject: (injectTo, propertySchema, pointer) => {
 | 
			
		||||
      injectTo._pointer = propertySchema._pointer || pointer;
 | 
			
		||||
      injectTo._displayType = propertySchema.type;
 | 
			
		||||
      if (propertySchema.format) injectTo._displayFormat = `<${propertySchema.format}>`;
 | 
			
		||||
      if (propertySchema.enum) {
 | 
			
		||||
        injectTo.enum = propertySchema.enum.map((value) => {
 | 
			
		||||
          return {val: value, type: typeof value};
 | 
			
		||||
        });
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  discriminator: {
 | 
			
		||||
    check: (propertySchema) => propertySchema.discriminator,
 | 
			
		||||
    inject: (injectTo, propertySchema = injectTo, pointer) => {
 | 
			
		||||
      injectTo._descendants = SpecManager.instance().findDerivedDefinitions(pointer);
 | 
			
		||||
      injectTo.discriminator = propertySchema.discriminator;
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  array: {
 | 
			
		||||
    check: (propertySchema) => {
 | 
			
		||||
      return propertySchema.type === 'array';
 | 
			
		||||
    },
 | 
			
		||||
    inject: (injectTo, propertySchema = injectTo, propPointer) => {
 | 
			
		||||
      injectTo._isArray = true;
 | 
			
		||||
      injectTo._pointer = propertySchema.items._pointer
 | 
			
		||||
        || JsonPointer.join(propertySchema._pointer || propPointer, ['items']);
 | 
			
		||||
 | 
			
		||||
      SchemaHelper.runInjectors(injectTo, propertySchema.items, propPointer);
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  object: {
 | 
			
		||||
    check: (propertySchema) => {
 | 
			
		||||
      return propertySchema.type === 'object' && propertySchema.properties;
 | 
			
		||||
    },
 | 
			
		||||
    inject: (injectTo, propertySchema = injectTo) => {
 | 
			
		||||
      let baseName = propertySchema._pointer && JsonPointer.baseName(propertySchema._pointer);
 | 
			
		||||
      injectTo._displayType = propertySchema.title || baseName || 'object';
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  noType: {
 | 
			
		||||
    check: (propertySchema) => !propertySchema.type,
 | 
			
		||||
    inject: (injectTo) => {
 | 
			
		||||
      injectTo._displayType = '< * >';
 | 
			
		||||
      injectTo._displayTypeHint = 'This field may contain data of any type';
 | 
			
		||||
      injectTo.isTrivial = true;
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  simpleType: {
 | 
			
		||||
    check: (propertySchema) => {
 | 
			
		||||
      if (propertySchema.type === 'object') {
 | 
			
		||||
        return (!propertySchema.properties || !Object.keys(propertySchema.properties).length)
 | 
			
		||||
          && (typeof propertySchema.additionalProperties !== 'object');
 | 
			
		||||
      }
 | 
			
		||||
      return (propertySchema.type !== 'array') && propertySchema.type;
 | 
			
		||||
    },
 | 
			
		||||
    inject: (injectTo, propertySchema = injectTo) => {
 | 
			
		||||
      injectTo.isTrivial = true;
 | 
			
		||||
      if (injectTo._pointer) {
 | 
			
		||||
        injectTo._pointer = undefined;
 | 
			
		||||
        injectTo._displayType = propertySchema.title ?
 | 
			
		||||
          `${propertySchema.title} (${propertySchema.type})` : propertySchema.type;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  integer: {
 | 
			
		||||
    check: (propertySchema) => (propertySchema.type === 'integer' || propertySchema.type === 'number'),
 | 
			
		||||
    inject: (injectTo, propertySchema = injectTo) => {
 | 
			
		||||
      var range = '';
 | 
			
		||||
      if (propertySchema.minimum && propertySchema.maximum) {
 | 
			
		||||
        range += propertySchema.exclusiveMinimum ? '( ' : '[ ';
 | 
			
		||||
        range += propertySchema.minimum;
 | 
			
		||||
        range += ' .. ';
 | 
			
		||||
        range += propertySchema.maximum;
 | 
			
		||||
        range += propertySchema.exclusiveMaximum ? ' )' : ' ]';
 | 
			
		||||
      } else if (propertySchema.maximum) {
 | 
			
		||||
        range += propertySchema.exclusiveMaximum? '< ' : '<= ';
 | 
			
		||||
        range += propertySchema.maximum;
 | 
			
		||||
      } else if (propertySchema.minimum) {
 | 
			
		||||
        range += propertySchema.exclusiveMinimum ? '> ' : '>= ';
 | 
			
		||||
        range += propertySchema.minimum;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (range) {
 | 
			
		||||
        injectTo._range = range;
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  string: {
 | 
			
		||||
    check: propertySchema => (propertySchema.type === 'string'),
 | 
			
		||||
    inject: (injectTo, propertySchema = injectTo) => {
 | 
			
		||||
      var range;
 | 
			
		||||
      if (propertySchema.minLength && propertySchema.maxLength) {
 | 
			
		||||
        range = `[ ${propertySchema.minLength} .. ${propertySchema.maxLength} ]`;
 | 
			
		||||
      } else if (propertySchema.maxLength) {
 | 
			
		||||
        range = '<= ' + propertySchema.maxLength;
 | 
			
		||||
      } else if (propertySchema.minimum) {
 | 
			
		||||
        range = '>= ' + propertySchema.minLength;
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      if (range) {
 | 
			
		||||
        injectTo._range = range + ' characters';
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
  file: {
 | 
			
		||||
    check: propertySchema => (propertySchema.type === 'file'),
 | 
			
		||||
    inject: (injectTo, propertySchema = injectTo, propPointer, hostPointer) => {
 | 
			
		||||
      injectTo.isFile = true;
 | 
			
		||||
      let parentPtr;
 | 
			
		||||
      if (propertySchema.in === 'formData') {
 | 
			
		||||
        parentPtr = JsonPointer.dirName(hostPointer, 1);
 | 
			
		||||
      } else {
 | 
			
		||||
        parentPtr = JsonPointer.dirName(hostPointer, 3);
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      let parentParam = SpecManager.instance().byPointer(parentPtr);
 | 
			
		||||
      let root = SpecManager.instance().schema;
 | 
			
		||||
      injectTo._produces = parentParam && parentParam.produces || root.produces;
 | 
			
		||||
      injectTo._consumes = parentParam && parentParam.consumes || root.consumes;
 | 
			
		||||
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export class SchemaHelper {
 | 
			
		||||
  static preprocess(schema, name, pointer, hostPointer?) {
 | 
			
		||||
    //propertySchema = Object.assign({}, propertySchema);
 | 
			
		||||
    if (schema['x-redoc-schema-precompiled']) {
 | 
			
		||||
      return schema;
 | 
			
		||||
    }
 | 
			
		||||
    schema._name = name;
 | 
			
		||||
    SchemaHelper.runInjectors(schema, schema, pointer, hostPointer);
 | 
			
		||||
    schema['x-redoc-schema-precompiled'] = true;
 | 
			
		||||
    return schema;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static runInjectors(injectTo, schema, pointer, hostPointer?) {
 | 
			
		||||
    for (var injName of Object.keys(injectors)) {
 | 
			
		||||
      let injector = injectors[injName];
 | 
			
		||||
      if (injector.check(schema)) {
 | 
			
		||||
        injector.inject(injectTo, schema, pointer, hostPointer);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static preprocessProperties(schema:any, pointer:string, opts: PropertyPreprocessOptions) {
 | 
			
		||||
    let requiredMap = {};
 | 
			
		||||
    if (schema.required) {
 | 
			
		||||
      schema.required.forEach(prop => requiredMap[prop] = true);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    let discriminatorFieldIdx = -1;
 | 
			
		||||
    let props = schema.properties && Object.keys(schema.properties).map((propName, idx) => {
 | 
			
		||||
      let propertySchema = schema.properties[propName];
 | 
			
		||||
      let propPointer = propertySchema._pointer ||
 | 
			
		||||
        JsonPointer.join(pointer, ['properties', propName]);
 | 
			
		||||
      propertySchema = SchemaHelper.preprocess(propertySchema, propName, propPointer);
 | 
			
		||||
      // stop endless discriminator recursion
 | 
			
		||||
      if (propertySchema._pointer === opts.childFor) {
 | 
			
		||||
        propertySchema._pointer = null;
 | 
			
		||||
      }
 | 
			
		||||
      propertySchema.required = !!requiredMap[propName];
 | 
			
		||||
      propertySchema.isDiscriminator = (schema.discriminator === propName);
 | 
			
		||||
      if (propertySchema.isDiscriminator) {
 | 
			
		||||
        discriminatorFieldIdx = idx;
 | 
			
		||||
      }
 | 
			
		||||
      return propertySchema;
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    props = props || [];
 | 
			
		||||
 | 
			
		||||
    if (schema.additionalProperties && schema.additionalProperties !== false) {
 | 
			
		||||
      let propsSchema = SchemaHelper.preprocessAdditionalProperties(schema, pointer);
 | 
			
		||||
      propsSchema._additional = true;
 | 
			
		||||
      props.push(propsSchema);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    // Move discriminator field to the end of properties list
 | 
			
		||||
    if (discriminatorFieldIdx > -1) {
 | 
			
		||||
      let discrProp = props.splice(discriminatorFieldIdx, 1);
 | 
			
		||||
      props.push(discrProp[0]);
 | 
			
		||||
    }
 | 
			
		||||
    // filter readOnly props for request schemas
 | 
			
		||||
    if (opts.skipReadOnly) {
 | 
			
		||||
      props = props.filter(prop => !prop.readOnly);
 | 
			
		||||
    }
 | 
			
		||||
    schema._properties = props;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static preprocessAdditionalProperties(schema:any, pointer:string) {
 | 
			
		||||
    var addProps = schema.additionalProperties;
 | 
			
		||||
    let ptr = addProps._pointer || JsonPointer.join(pointer, ['additionalProperties']);
 | 
			
		||||
    return SchemaHelper.preprocess(addProps, '<Additional Properties> *', ptr);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  static unwrapArray(schema, pointer) {
 | 
			
		||||
    var res = schema;
 | 
			
		||||
    if (schema && schema.type === 'array') {
 | 
			
		||||
      let ptr = schema.items._pointer || JsonPointer.join(pointer, ['items']);
 | 
			
		||||
      res = schema.items;
 | 
			
		||||
      res._isArray = true;
 | 
			
		||||
      res._pointer = ptr;
 | 
			
		||||
      res = SchemaHelper.unwrapArray(res, ptr);
 | 
			
		||||
    }
 | 
			
		||||
    return res;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -1,15 +1,15 @@
 | 
			
		|||
'use strict';
 | 
			
		||||
import { SchemaNormalizator } from './spec-helper.service';
 | 
			
		||||
import { SchemaNormalizer } from './schema-normalizer.service';
 | 
			
		||||
import {
 | 
			
		||||
  describe,
 | 
			
		||||
  it
 | 
			
		||||
} from '@angular/core/testing';
 | 
			
		||||
 | 
			
		||||
import { SchemaManager } from '../utils/SchemaManager';;
 | 
			
		||||
import { SpecManager } from '../utils/SpecManager';;
 | 
			
		||||
 | 
			
		||||
describe('Spec Helper', () => {
 | 
			
		||||
  let schemaMgr:SchemaManager = new SchemaManager();
 | 
			
		||||
  let normalizer = new SchemaNormalizator(schemaMgr);
 | 
			
		||||
  let schemaMgr:SpecManager = new SpecManager();
 | 
			
		||||
  let normalizer = new SchemaNormalizer(schemaMgr);
 | 
			
		||||
 | 
			
		||||
  describe('Dereference', () => {
 | 
			
		||||
    beforeAll(done => {
 | 
			
		||||
| 
						 | 
				
			
			@ -1,6 +1,6 @@
 | 
			
		|||
'use strict';
 | 
			
		||||
import { Injectable } from '@angular/core';
 | 
			
		||||
import { SchemaManager } from '../utils/SchemaManager';
 | 
			
		||||
import { SpecManager } from '../utils/SpecManager';
 | 
			
		||||
import { JsonPointer } from '../utils/JsonPointer';
 | 
			
		||||
import { defaults } from '../utils/helpers';
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -17,7 +17,7 @@ interface Schema {
 | 
			
		|||
}
 | 
			
		||||
 | 
			
		||||
@Injectable()
 | 
			
		||||
export class SchemaNormalizator {
 | 
			
		||||
export class SchemaNormalizer {
 | 
			
		||||
  _dereferencer:SchemaDereferencer;
 | 
			
		||||
  constructor(private _schema:any) {
 | 
			
		||||
    this._dereferencer = new SchemaDereferencer(_schema, this);
 | 
			
		||||
| 
						 | 
				
			
			@ -161,7 +161,7 @@ class RefCounter {
 | 
			
		|||
class SchemaDereferencer {
 | 
			
		||||
  private _refCouner = new RefCounter();
 | 
			
		||||
 | 
			
		||||
  constructor(private _spec: SchemaManager, private normalizator: SchemaNormalizator) {
 | 
			
		||||
  constructor(private _spec: SpecManager, private normalizator: SchemaNormalizer) {
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  dereference(schema: Reference, pointer:string):any {
 | 
			
		||||
| 
						 | 
				
			
			@ -4,21 +4,21 @@ import JsonSchemaRefParser from 'json-schema-ref-parser';
 | 
			
		|||
import JsonPointer from './JsonPointer';
 | 
			
		||||
import {methods as swaggerMethods} from  './swagger-defs';
 | 
			
		||||
 | 
			
		||||
export class SchemaManager {
 | 
			
		||||
export class SpecManager {
 | 
			
		||||
  public _schema:any = {};
 | 
			
		||||
  public apiUrl: string;
 | 
			
		||||
  private _instance:any;
 | 
			
		||||
 | 
			
		||||
  static instance() {
 | 
			
		||||
    return new SchemaManager();
 | 
			
		||||
    return new SpecManager();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  constructor() {
 | 
			
		||||
    if (SchemaManager.prototype._instance) {
 | 
			
		||||
      return SchemaManager.prototype._instance;
 | 
			
		||||
    if (SpecManager.prototype._instance) {
 | 
			
		||||
      return SpecManager.prototype._instance;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    SchemaManager.prototype._instance = this;
 | 
			
		||||
    SpecManager.prototype._instance = this;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  load(url) {
 | 
			
		||||
| 
						 | 
				
			
			@ -26,14 +26,11 @@ export class SchemaManager {
 | 
			
		|||
      this._schema = {};
 | 
			
		||||
 | 
			
		||||
      JsonSchemaRefParser.bundle(url, {http: {withCredentials: false}})
 | 
			
		||||
        .then(
 | 
			
		||||
          (schema) => {
 | 
			
		||||
            this._schema = schema;
 | 
			
		||||
            resolve(this._schema);
 | 
			
		||||
            this.init();
 | 
			
		||||
          },
 | 
			
		||||
          (err) => reject(err)
 | 
			
		||||
        );
 | 
			
		||||
      .then(schema => {
 | 
			
		||||
          this._schema = schema;
 | 
			
		||||
          resolve(this._schema);
 | 
			
		||||
          this.init();
 | 
			
		||||
      }, err => reject(err));
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    return promise;
 | 
			
		||||
| 
						 | 
				
			
			@ -49,14 +46,12 @@ export class SchemaManager {
 | 
			
		|||
  }
 | 
			
		||||
 | 
			
		||||
  get schema() {
 | 
			
		||||
    // TODO: consider returning promise
 | 
			
		||||
    return this._schema;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  byPointer(pointer) {
 | 
			
		||||
    let res = null;
 | 
			
		||||
    try {
 | 
			
		||||
      // TODO: remove decodeURIComponent after this issue is fixed: https://github.com/BigstickCarpet/swagger-parser/issues/31
 | 
			
		||||
      res = JsonPointer.get(this._schema, decodeURIComponent(pointer));
 | 
			
		||||
    } catch(e)  {/*skip*/ }
 | 
			
		||||
    return res;
 | 
			
		||||
| 
						 | 
				
			
			@ -14,7 +14,7 @@
 | 
			
		|||
    <script>
 | 
			
		||||
      window.redocError = null;
 | 
			
		||||
      /* init redoc */
 | 
			
		||||
      var url = window.location.search.substr(5) || 'http://rebilly.github.io:80/SwaggerTemplateRepo/swagger.json';
 | 
			
		||||
      var url = window.location.search.substr(5) || 'http://rebilly.github.io/SwaggerTemplateRepo/swagger.json';
 | 
			
		||||
      Redoc.init(decodeURIComponent(url), {disableLazySchemas: true}).then(function() {}, function(err) {
 | 
			
		||||
        window.redocError = err;
 | 
			
		||||
      });
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,17 +1,17 @@
 | 
			
		|||
'use strict';
 | 
			
		||||
 | 
			
		||||
import { SchemaManager } from '../../lib/utils/SchemaManager';
 | 
			
		||||
import { SpecManager } from '../../lib/utils/SpecManager';
 | 
			
		||||
describe('Utils', () => {
 | 
			
		||||
  describe('Schema manager', () => {
 | 
			
		||||
    let schemaMgr;
 | 
			
		||||
 | 
			
		||||
    beforeEach(() => {
 | 
			
		||||
      schemaMgr = new SchemaManager();
 | 
			
		||||
      schemaMgr = new SpecManager();
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('Should be a singleton', ()=> {
 | 
			
		||||
      (new SchemaManager()).should.be.equal(schemaMgr);
 | 
			
		||||
      SchemaManager.instance().should.be.equal(schemaMgr);
 | 
			
		||||
      (new SpecManager()).should.be.equal(schemaMgr);
 | 
			
		||||
      SpecManager.instance().should.be.equal(schemaMgr);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
    it('load should return a promise', ()=> {
 | 
			
		||||
		Loading…
	
		Reference in New Issue
	
	Block a user