diff --git a/lib/components/ApiInfo/api-info.spec.ts b/lib/components/ApiInfo/api-info.spec.ts index 15e2611b..2e760ca2 100644 --- a/lib/components/ApiInfo/api-info.spec.ts +++ b/lib/components/ApiInfo/api-info.spec.ts @@ -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'); }))); diff --git a/lib/components/ApiInfo/api-info.ts b/lib/components/ApiInfo/api-info.ts index 8d8c4a3e..0e9d15ad 100644 --- a/lib/components/ApiInfo/api-info.ts +++ b/lib/components/ApiInfo/api-info.ts @@ -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); } diff --git a/lib/components/ApiLogo/api-logo.spec.ts b/lib/components/ApiLogo/api-logo.spec.ts index e53a24a7..7434d0c7 100644 --- a/lib/components/ApiLogo/api-logo.spec.ts +++ b/lib/components/ApiLogo/api-logo.spec.ts @@ -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: `` }) diff --git a/lib/components/ApiLogo/api-logo.ts b/lib/components/ApiLogo/api-logo.ts index 929e8626..5b97f307 100644 --- a/lib/components/ApiLogo/api-logo.ts +++ b/lib/components/ApiLogo/api-logo.ts @@ -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); } diff --git a/lib/components/JsonSchema/json-schema-lazy.spec.ts b/lib/components/JsonSchema/json-schema-lazy.spec.ts index 5b45428c..c69889ee 100644 --- a/lib/components/JsonSchema/json-schema-lazy.spec.ts +++ b/lib/components/JsonSchema/json-schema-lazy.spec.ts @@ -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; diff --git a/lib/components/JsonSchema/json-schema-lazy.ts b/lib/components/JsonSchema/json-schema-lazy.ts index 66b91239..2afa2594 100644 --- a/lib/components/JsonSchema/json-schema-lazy.ts +++ b/lib/components/JsonSchema/json-schema-lazy.ts @@ -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; } diff --git a/lib/components/JsonSchema/json-schema.html b/lib/components/JsonSchema/json-schema.html index a788448c..85d3df36 100644 --- a/lib/components/JsonSchema/json-schema.html +++ b/lib/components/JsonSchema/json-schema.html @@ -21,7 +21,7 @@ - + -
- +
+
diff --git a/lib/components/JsonSchema/json-schema.spec.ts b/lib/components/JsonSchema/json-schema.spec.ts index d8e1ebca..26371ce6 100644 --- a/lib/components/JsonSchema/json-schema.spec.ts +++ b/lib/components/JsonSchema/json-schema.spec.ts @@ -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: `` }) diff --git a/lib/components/JsonSchema/json-schema.ts b/lib/components/JsonSchema/json-schema.ts index 7bfd337d..46057a57 100644 --- a/lib/components/JsonSchema/json-schema.ts +++ b/lib/components/JsonSchema/json-schema.ts @@ -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, ' *', - 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(); } } diff --git a/lib/components/Method/method.spec.ts b/lib/components/Method/method.spec.ts index 6ce561e9..e58b5eb3 100644 --- a/lib/components/Method/method.spec.ts +++ b/lib/components/Method/method.spec.ts @@ -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: `` }) diff --git a/lib/components/Method/method.ts b/lib/components/Method/method.ts index 04c85077..30a67d1e 100644 --- a/lib/components/Method/method.ts +++ b/lib/components/Method/method.ts @@ -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); } diff --git a/lib/components/MethodsList/methods-list.spec.ts b/lib/components/MethodsList/methods-list.spec.ts index aea0b207..28f783fb 100644 --- a/lib/components/MethodsList/methods-list.spec.ts +++ b/lib/components/MethodsList/methods-list.spec.ts @@ -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'); }))); diff --git a/lib/components/MethodsList/methods-list.ts b/lib/components/MethodsList/methods-list.ts index fe80c592..76ec32b9 100644 --- a/lib/components/MethodsList/methods-list.ts +++ b/lib/components/MethodsList/methods-list.ts @@ -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); } diff --git a/lib/components/ParamsList/params-list.ts b/lib/components/ParamsList/params-list.ts index d9b6ce27..9eee6a2a 100644 --- a/lib/components/ParamsList/params-list.ts +++ b/lib/components/ParamsList/params-list.ts @@ -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); diff --git a/lib/components/Redoc/redoc.spec.ts b/lib/components/Redoc/redoc.spec.ts index 5b6c463e..cd7e4495 100644 --- a/lib/components/Redoc/redoc.spec.ts +++ b/lib/components/Redoc/redoc.spec.ts @@ -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'); }))); diff --git a/lib/components/Redoc/redoc.ts b/lib/components/Redoc/redoc.ts index f721aad0..76703e09 100644 --- a/lib/components/Redoc/redoc.ts +++ b/lib/components/Redoc/redoc.ts @@ -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; diff --git a/lib/components/RequestSamples/request-samples.ts b/lib/components/RequestSamples/request-samples.ts index c7631ace..10b07062 100644 --- a/lib/components/RequestSamples/request-samples.ts +++ b/lib/components/RequestSamples/request-samples.ts @@ -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; - constructor(schemaMgr:SchemaManager, public events:RedocEventsService) { + constructor(schemaMgr:SpecManager, public events:RedocEventsService) { super(schemaMgr); this.selectedLang = this.events.samplesLanguageChanged; diff --git a/lib/components/ResponsesList/responses-list.ts b/lib/components/ResponsesList/responses-list.ts index aa80497c..4a3a14f0 100644 --- a/lib/components/ResponsesList/responses-list.ts +++ b/lib/components/ResponsesList/responses-list.ts @@ -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; } diff --git a/lib/components/ResponsesSamples/responses-samples.ts b/lib/components/ResponsesSamples/responses-samples.ts index ab1d0827..50e2c7de 100644 --- a/lib/components/ResponsesSamples/responses-samples.ts +++ b/lib/components/ResponsesSamples/responses-samples.ts @@ -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); } diff --git a/lib/components/SchemaSample/schema-sample.ts b/lib/components/SchemaSample/schema-sample.ts index 892210ac..9c7d9f68 100644 --- a/lib/components/SchemaSample/schema-sample.ts +++ b/lib/components/SchemaSample/schema-sample.ts @@ -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() { diff --git a/lib/components/SideMenu/side-menu.spec.ts b/lib/components/SideMenu/side-menu.spec.ts index 1d7ae5f2..a4e4df09 100644 --- a/lib/components/SideMenu/side-menu.spec.ts +++ b/lib/components/SideMenu/side-menu.spec.ts @@ -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; diff --git a/lib/components/SideMenu/side-menu.ts b/lib/components/SideMenu/side-menu.ts index cc34f82b..ae9b162d 100644 --- a/lib/components/SideMenu/side-menu.ts +++ b/lib/components/SideMenu/side-menu.ts @@ -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); diff --git a/lib/components/base.spec.ts b/lib/components/base.spec.ts index 9cd78f59..00479375 100644 --- a/lib/components/base.spec.ts +++ b/lib/components/base.spec.ts @@ -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: []}; }); diff --git a/lib/components/base.ts b/lib/components/base.ts index 7c314158..1683a9ea 100644 --- a/lib/components/base.ts +++ b/lib/components/base.ts @@ -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) { } /** diff --git a/lib/services/index.ts b/lib/services/index.ts index fed26281..02376ee0 100644 --- a/lib/services/index.ts +++ b/lib/services/index.ts @@ -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'; diff --git a/lib/services/menu.service.spec.ts b/lib/services/menu.service.spec.ts index 3adafe2c..21f7257e 100644 --- a/lib/services/menu.service.spec.ts +++ b/lib/services/menu.service.spec.ts @@ -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; diff --git a/lib/services/menu.service.ts b/lib/services/menu.service.ts index 880cf777..b27ade12 100644 --- a/lib/services/menu.service.ts +++ b/lib/services/menu.service.ts @@ -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( diff --git a/lib/services/schema-helper.service.ts b/lib/services/schema-helper.service.ts new file mode 100644 index 00000000..4fda5d44 --- /dev/null +++ b/lib/services/schema-helper.service.ts @@ -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, ' *', 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; + } +} diff --git a/lib/services/spec-helper.service.spec.ts b/lib/services/schema-normalizer.service.spec.ts similarity index 97% rename from lib/services/spec-helper.service.spec.ts rename to lib/services/schema-normalizer.service.spec.ts index 2c6a84b5..a3795261 100644 --- a/lib/services/spec-helper.service.spec.ts +++ b/lib/services/schema-normalizer.service.spec.ts @@ -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 => { diff --git a/lib/services/spec-helper.service.ts b/lib/services/schema-normalizer.service.ts similarity index 97% rename from lib/services/spec-helper.service.ts rename to lib/services/schema-normalizer.service.ts index bce12fe6..9f74dd5b 100644 --- a/lib/services/spec-helper.service.ts +++ b/lib/services/schema-normalizer.service.ts @@ -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 { diff --git a/lib/utils/SchemaManager.ts b/lib/utils/SpecManager.ts similarity index 90% rename from lib/utils/SchemaManager.ts rename to lib/utils/SpecManager.ts index 2779df49..ba9ceb25 100644 --- a/lib/utils/SchemaManager.ts +++ b/lib/utils/SpecManager.ts @@ -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; diff --git a/tests/e2e/index.html b/tests/e2e/index.html index 2b360322..a1dc3a28 100644 --- a/tests/e2e/index.html +++ b/tests/e2e/index.html @@ -14,7 +14,7 @@