mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-27 19:13:44 +03:00
Merge commit '99811d9eed6efefbabe9ffae26e2e9d7af23ebb5' into releases
This commit is contained in:
commit
913643b72c
|
@ -141,6 +141,7 @@ ReDoc makes use of the following [vendor extensions](http://swagger.io/specifica
|
|||
* `hide-hostname` - if set, the protocol and hostname is not shown in the operation definition.
|
||||
* `expand-responses` - specify which responses to expand by default by response codes. Values should be passed as comma-separated list without spaces e.g. `expand-responses="200,201"`. Special value `"all"` expands all responses by default. Be careful: this option can slow-down documentation rendering time.
|
||||
* `required-props-first` - show required properties first ordered in the same order as in `required` array.
|
||||
* `no-auto-auth` - do not inject Authentication section automatically
|
||||
|
||||
## Advanced usage
|
||||
Instead of adding `spec-url` attribute to the `<redoc>` element you can initialize ReDoc via globally exposed `Redoc` object:
|
||||
|
|
|
@ -23,7 +23,7 @@ module.exports = function (options) {
|
|||
extensions: ['.ts', '.js', '.json', '.css'],
|
||||
alias: {
|
||||
http: 'stream-http',
|
||||
https: 'stream-http'
|
||||
https: 'https-browserify'
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
</p>
|
||||
<p>
|
||||
<!-- TODO: create separate components for contact and license ? -->
|
||||
<span *ngIf="info?.contact"> Contact:
|
||||
<span *ngIf="info?.contact?.url || info?.contact?.email"> Contact:
|
||||
<a *ngIf="info.contact.url" href="{{info.contact.url}}">
|
||||
{{info.contact.name || info.contact.url}}</a>
|
||||
<a *ngIf="info.contact.email" href="mailto:{{info.contact.email}}">
|
||||
|
|
|
@ -110,3 +110,39 @@
|
|||
transform: translateY(0%) scaleY(1);
|
||||
}
|
||||
}
|
||||
|
||||
.http-verb {
|
||||
color: white;
|
||||
|
||||
&.get {
|
||||
background-color: $get-color;
|
||||
}
|
||||
|
||||
&.post {
|
||||
background-color: $post-color;
|
||||
}
|
||||
|
||||
&.put {
|
||||
background-color: $put-color;
|
||||
}
|
||||
|
||||
&.options {
|
||||
background-color: $options-color;
|
||||
}
|
||||
|
||||
&.patch {
|
||||
background-color: $patch-color;
|
||||
}
|
||||
|
||||
&.delete {
|
||||
background-color: $delete-color;
|
||||
}
|
||||
|
||||
&.basic {
|
||||
background-color: $basic-color;
|
||||
}
|
||||
|
||||
&.link {
|
||||
background-color: $link-color;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -36,7 +36,7 @@ export class JsonSchemaLazy implements OnDestroy, OnInit, AfterViewInit {
|
|||
return schema && schema.$ref || this.pointer;
|
||||
}
|
||||
|
||||
_loadAfterSelf() {
|
||||
private _loadAfterSelf() {
|
||||
var componentFactory = this.resolver.resolveComponentFactory(JsonSchema);
|
||||
let contextInjector = this.location.parentInjector;
|
||||
let compRef = this.location.createComponent(componentFactory, null, contextInjector, null);
|
||||
|
|
|
@ -4,9 +4,9 @@ import JsonPointer from '../../utils/JsonPointer';
|
|||
import { BaseComponent, SpecManager } from '../base';
|
||||
import { SchemaHelper } from '../../services/schema-helper.service';
|
||||
import { OptionsService, MenuService } from '../../services/';
|
||||
import { SwaggerBodyParameter } from '../../utils/swagger-typings';
|
||||
|
||||
|
||||
interface OperationInfo {
|
||||
export interface OperationInfo {
|
||||
verb: string;
|
||||
path: string;
|
||||
info: {
|
||||
|
@ -72,7 +72,7 @@ export class Operation extends BaseComponent implements OnInit {
|
|||
return tags.filter(tag => tagsMap[tag] && tagsMap[tag]['x-traitTag']);
|
||||
}
|
||||
|
||||
findBodyParam() {
|
||||
findBodyParam():SwaggerBodyParameter {
|
||||
let params = this.specMgr.getOperationParams(this.pointer);
|
||||
let bodyParam = params.find(param => param.in === 'body');
|
||||
return bodyParam;
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<div class="operations">
|
||||
<div class="tag" *ngFor="let tag of tags; trackBy:trackByTagName" [attr.section]="tag.id">
|
||||
<div class="tag-info" *ngIf="tag.name">
|
||||
<h1 class="sharable-header"> <a class="share-link" href="#{{tag.id}}"></a>{{tag.name}} </h1>
|
||||
<h1 class="sharable-header"> <a class="share-link" href="#{{tag.anchor}}"></a>{{tag.name}} </h1>
|
||||
<p *ngIf="tag.description" [innerHtml]="tag.description | marked"> </p>
|
||||
<redoc-externalDocs [docs]="tag.metadata.externalDocs"></redoc-externalDocs>
|
||||
</div>
|
||||
|
|
|
@ -12,7 +12,6 @@
|
|||
.tag-info {
|
||||
padding: $section-spacing;
|
||||
box-sizing: border-box;
|
||||
background-color: white;
|
||||
width: 60%;
|
||||
|
||||
@media (max-width: $right-panel-squash-breakpoint) {
|
||||
|
|
|
@ -30,7 +30,10 @@ export class OperationsList extends BaseComponent implements OnInit {
|
|||
if (!menuItem.metadata) return;
|
||||
|
||||
if (menuItem.metadata.type === 'tag') {
|
||||
this.tags.push(menuItem);
|
||||
this.tags.push({
|
||||
...menuItem,
|
||||
anchor: this.buildAnchor(menuItem.id)
|
||||
});
|
||||
}
|
||||
if (menuItem.metadata.type === 'operation' && !menuItem.parent) {
|
||||
emptyTag.items.push(menuItem);
|
||||
|
@ -39,6 +42,11 @@ export class OperationsList extends BaseComponent implements OnInit {
|
|||
if (emptyTag.items.length) this.tags.push(emptyTag);
|
||||
}
|
||||
|
||||
buildAnchor(tagId):string {
|
||||
return this.menu.hashFor(tagId,
|
||||
{ type: 'tag'});
|
||||
}
|
||||
|
||||
trackByTagName(_, el) {
|
||||
return el.name;
|
||||
}
|
||||
|
|
|
@ -113,6 +113,73 @@ side-menu {
|
|||
font-size: 18px;
|
||||
}
|
||||
|
||||
/* global menu items styles (search results + menu) */
|
||||
:host /deep/ {
|
||||
.menu-item-header > span {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
.menu-item-header > .operation-type + .menu-item-title {
|
||||
width: calc(100% - 32px); // 32 = 26px image width + 6px margin left
|
||||
}
|
||||
|
||||
.menu-item-header > .operation-type {
|
||||
width: 26px;
|
||||
display: inline-block;
|
||||
height: 13px;
|
||||
background-color: #333;
|
||||
border-radius: 3px;
|
||||
vertical-align: top;
|
||||
background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAACgCAYAAADuDlcXAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAyRpVFh0WE1MOmNvbS5hZG9iZS54bXAAAAAAADw/eHBhY2tldCBiZWdpbj0i77u/IiBpZD0iVzVNME1wQ2VoaUh6cmVTek5UY3prYzlkIj8+IDx4OnhtcG1ldGEgeG1sbnM6eD0iYWRvYmU6bnM6bWV0YS8iIHg6eG1wdGs9IkFkb2JlIFhNUCBDb3JlIDUuMy1jMDExIDY2LjE0NTY2MSwgMjAxMi8wMi8wNi0xNDo1NjoyNyAgICAgICAgIj4gPHJkZjpSREYgeG1sbnM6cmRmPSJodHRwOi8vd3d3LnczLm9yZy8xOTk5LzAyLzIyLXJkZi1zeW50YXgtbnMjIj4gPHJkZjpEZXNjcmlwdGlvbiByZGY6YWJvdXQ9IiIgeG1sbnM6eG1wPSJodHRwOi8vbnMuYWRvYmUuY29tL3hhcC8xLjAvIiB4bWxuczp4bXBNTT0iaHR0cDovL25zLmFkb2JlLmNvbS94YXAvMS4wL21tLyIgeG1sbnM6c3RSZWY9Imh0dHA6Ly9ucy5hZG9iZS5jb20veGFwLzEuMC9zVHlwZS9SZXNvdXJjZVJlZiMiIHhtcDpDcmVhdG9yVG9vbD0iQWRvYmUgUGhvdG9zaG9wIENTNiAoTWFjaW50b3NoKSIgeG1wTU06SW5zdGFuY2VJRD0ieG1wLmlpZDpFNjQ5N0JDQUE3OTYxMUU0ODNGMUE0RUM3NjRDRTQyNyIgeG1wTU06RG9jdW1lbnRJRD0ieG1wLmRpZDpFNjQ5N0JDQkE3OTYxMUU0ODNGMUE0RUM3NjRDRTQyNyI+IDx4bXBNTTpEZXJpdmVkRnJvbSBzdFJlZjppbnN0YW5jZUlEPSJ4bXAuaWlkOkU2NDk3QkM4QTc5NjExRTQ4M0YxQTRFQzc2NENFNDI3IiBzdFJlZjpkb2N1bWVudElEPSJ4bXAuZGlkOkU2NDk3QkM5QTc5NjExRTQ4M0YxQTRFQzc2NENFNDI3Ii8+IDwvcmRmOkRlc2NyaXB0aW9uPiA8L3JkZjpSREY+IDwveDp4bXBtZXRhPiA8P3hwYWNrZXQgZW5kPSJyIj8+mIrGwQAAAZ9JREFUeNrsmtuOwyAMRBmU//9lbx9208ayjQ1EarSDVFW56ARIGGZIIK/S3gWvX3X7LN3a6WxDHdPnnDBpcZHEOe3wrmLUMg2zatKykPOq1/5fK71tLIQR9jjYsaJfWdWAAcRsM2W1z9LNGcFkRlmtPhvpf7qmHAGEESZqLFr/qbHaCy4Is6oxLdvT+nWr0lLPCCPsFn+mA5e2UjLycL1o6qLMiapqRGoifVCDinrgU2mRyJthzZg3CSPs+2HhIM4YGq0a4oDgiGjYTKw20/OwUzAEuXz73YSqtdsV+F1a3eZpweFEGGG7Y3ULbJRk4nYPlEHbUi86wpNtbz4oB37PICOrLEdC9DKzFv7EkQ8tYY8Nr8tuyJrRsdpMrIJ0n4GPBmGEEUbYzRMKnFwug1B7rppmbCiyBjBrQ1vC8KW/CxrF7osNrRbxMjofWsIIuwU2vapnZfTRq4/wFXl3hG9bMzP6ZWV47LoB+Gym1/EyUleKI2GEPW8pQpu80bHLvsifSWFVAVEzo2VDTxxb9T16eO7sF0vmxPNPxPFHgAEA/rGUMXq/uWcAAAAASUVORK5CYII=');
|
||||
background-repeat: no-repeat;
|
||||
background-position: 6px 4px;
|
||||
text-indent: -9000px;
|
||||
margin-right: 6px;
|
||||
margin-top: 2px;
|
||||
|
||||
&.get {
|
||||
background-position: 8px -12px;
|
||||
background-color: $get-color;
|
||||
}
|
||||
|
||||
&.post {
|
||||
background-position: 6px 4px;
|
||||
background-color: $post-color;
|
||||
}
|
||||
|
||||
&.put {
|
||||
background-position: 8px -28px;
|
||||
background-color: $put-color;
|
||||
}
|
||||
|
||||
&.options {
|
||||
background-position: 4px -148px;
|
||||
background-color: $options-color;
|
||||
}
|
||||
|
||||
&.patch {
|
||||
background-position: 4px -114px;
|
||||
background-color: $patch-color;
|
||||
}
|
||||
|
||||
&.delete {
|
||||
background-position: 4px -44px;
|
||||
background-color: $delete-color;
|
||||
}
|
||||
|
||||
&.basic {
|
||||
background-position: 5px -79px;
|
||||
background-color: $basic-color;
|
||||
}
|
||||
|
||||
&.link {
|
||||
background-position: 4px -131px;
|
||||
background-color: $link-color;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* global redoc styles */
|
||||
|
||||
@for $index from 1 through 5 {
|
||||
|
@ -240,6 +307,9 @@ footer {
|
|||
padding-left: 2em;
|
||||
margin: 0;
|
||||
margin-bottom: 1em;
|
||||
font-family: $base-font, $base-font-family;
|
||||
font-weight: $base-font-weight;
|
||||
line-height: $base-line-height;
|
||||
}
|
||||
|
||||
table {
|
||||
|
|
|
@ -5,9 +5,10 @@
|
|||
<input #search (keyup)="update($event, search.value)" [value]="searchTerm" placeholder="Search">
|
||||
</div>
|
||||
<ul class="search-results" [hidden]="!items.length">
|
||||
<li class="result" *ngFor="let item of items"
|
||||
<li class="result menu-item-header" *ngFor="let item of items"
|
||||
ngClass="menu-item-depth-{{item.menuItem.depth}} {{item.menuItem.ready ? '' : 'disabled'}}"
|
||||
(click)="clickSearch(item)">
|
||||
{{item.menuItem.name}}
|
||||
<span class="operation-type" [ngClass]="item.menuItem?.metadata?.operation" *ngIf="item.menuItem?.metadata?.operation"> {{item.menuItem?.metadata?.operation}} </span><!--
|
||||
--><span class="menu-item-title">{{item.menuItem.name}}</span>
|
||||
</li>
|
||||
</ul>
|
||||
|
|
|
@ -44,6 +44,7 @@ input {
|
|||
overflow-y: auto;
|
||||
border-bottom: 1px solid darken($side-bar-bg-color, 10%);
|
||||
border-top: 1px solid darken($side-bar-bg-color, 10%);
|
||||
line-height: 1.2;
|
||||
|
||||
min-height: 150px;
|
||||
max-height: 250px;
|
||||
|
|
|
@ -74,7 +74,7 @@ export class RedocSearch implements OnInit {
|
|||
item.pointers
|
||||
);
|
||||
this.marker.remark();
|
||||
this.menu.activate(item.menuItem.flatIdx);
|
||||
this.menu.activate(item.menuItem);
|
||||
this.menu.scrollToActive();
|
||||
}
|
||||
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
<li *ngFor="let item of items; let idx = index" class="menu-item"
|
||||
ngClass="menu-item-depth-{{item.depth}} {{item.active ? 'active' : ''}} menu-item-for-{{item.metadata?.type}}">
|
||||
<label class="menu-item-header" [ngClass]="{disabled: !item.ready}" (click)="activateItem(item)"> {{item.name}}</label>
|
||||
<label class="menu-item-header" [ngClass]="{disabled: !item.ready}" (click)="activateItem(item)">
|
||||
<span class="operation-type" [ngClass]="item?.metadata?.operation" *ngIf="item?.metadata?.operation"> {{item?.metadata?.operation}} </span><!--
|
||||
--><span class="menu-item-title">{{item.name}}</span>
|
||||
</label>
|
||||
<ul *ngIf="item.items" class="menu-subitems" [@itemAnimation]="(item.active || item.isGroup) ? 'expanded' : 'collapsed'">
|
||||
<side-menu-items [items]="item.items" (activate)="activateItem($event)"> </side-menu-items>
|
||||
</ul>
|
||||
|
|
|
@ -78,7 +78,7 @@
|
|||
|
||||
.menu-item-depth-2 {
|
||||
> .menu-item-header {
|
||||
padding-left: 2*$side-menu-item-hpadding;
|
||||
padding-left: $side-menu-item-hpadding;
|
||||
}
|
||||
|
||||
> .menu-item-header:hover,
|
||||
|
|
|
@ -11,8 +11,7 @@ import { Component,
|
|||
} from '@angular/core';
|
||||
|
||||
import { trigger, state, animate, transition, style } from '@angular/core';
|
||||
import { BaseComponent, SpecManager } from '../base';
|
||||
import { ScrollService, MenuService, OptionsService, MenuItem, Marker} from '../../services/';
|
||||
import { ScrollService, MenuService, OptionsService, MenuItem } from '../../services/';
|
||||
import { BrowserDomAdapter as DOM } from '../../utils/browser-adapter';
|
||||
|
||||
const global = window;
|
||||
|
@ -47,7 +46,7 @@ export class SideMenuItems {
|
|||
templateUrl: './side-menu.html',
|
||||
styleUrls: ['./side-menu.css']
|
||||
})
|
||||
export class SideMenu extends BaseComponent implements OnInit, OnDestroy {
|
||||
export class SideMenu implements OnInit, OnDestroy {
|
||||
activeCatCaption: string;
|
||||
activeItemCaption: string;
|
||||
menuItems: Array<MenuItem>;
|
||||
|
@ -59,15 +58,12 @@ export class SideMenu extends BaseComponent implements OnInit, OnDestroy {
|
|||
private $scrollParent: any;
|
||||
|
||||
constructor(
|
||||
specMgr:SpecManager,
|
||||
elementRef:ElementRef,
|
||||
private scrollService:ScrollService,
|
||||
private menuService:MenuService,
|
||||
optionsService:OptionsService,
|
||||
private detectorRef:ChangeDetectorRef,
|
||||
private marker:Marker
|
||||
) {
|
||||
super(specMgr);
|
||||
this.$element = elementRef.nativeElement;
|
||||
|
||||
this.activeCatCaption = '';
|
||||
|
@ -108,7 +104,7 @@ export class SideMenu extends BaseComponent implements OnInit, OnDestroy {
|
|||
this.toggleMobileNav();
|
||||
}
|
||||
|
||||
this.menuService.activate(item.flatIdx);
|
||||
this.menuService.activate(item);
|
||||
this.menuService.scrollToActive();
|
||||
}
|
||||
|
||||
|
@ -154,7 +150,7 @@ export class SideMenu extends BaseComponent implements OnInit, OnDestroy {
|
|||
}
|
||||
|
||||
ngOnInit() {
|
||||
this.preinit();
|
||||
this.init();
|
||||
}
|
||||
|
||||
ngAfterViewInit() {
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import { SpecManager } from '../utils/spec-manager';
|
||||
import { BaseComponent } from '../components/base';
|
||||
import { OptionsService } from '../services/options.service';
|
||||
|
||||
describe('Redoc components', () => {
|
||||
describe('BaseComponent', () => {
|
||||
|
@ -9,7 +10,7 @@ describe('Redoc components', () => {
|
|||
let component;
|
||||
|
||||
beforeAll(() => {
|
||||
specMgr = new SpecManager();
|
||||
specMgr = new SpecManager(new OptionsService());
|
||||
specMgr._schema = {tags: []};
|
||||
});
|
||||
|
||||
|
|
|
@ -17,6 +17,7 @@ import {
|
|||
ComponentParser,
|
||||
ContentProjector,
|
||||
Marker,
|
||||
SchemaHelper,
|
||||
SearchService,
|
||||
COMPONENT_PARSER_ALLOWED } from './services/';
|
||||
|
||||
|
@ -39,9 +40,20 @@ import { SpecManager } from './utils/spec-manager';
|
|||
{ provide: ErrorHandler, useClass: CustomErrorHandler },
|
||||
{ provide: COMPONENT_PARSER_ALLOWED, useValue: { 'security-definitions': SecurityDefinitions} }
|
||||
],
|
||||
exports: [Redoc]
|
||||
exports: [Redoc, REDOC_DIRECTIVES, REDOC_COMMON_DIRECTIVES, REDOC_PIPES]
|
||||
})
|
||||
export class RedocModule {
|
||||
}
|
||||
|
||||
export { Redoc, SpecManager };
|
||||
export { Redoc, SpecManager, ScrollService,
|
||||
Hash,
|
||||
WarningsService,
|
||||
OptionsService,
|
||||
AppStateService,
|
||||
ComponentParser,
|
||||
ContentProjector,
|
||||
MenuService,
|
||||
SearchService,
|
||||
SchemaHelper,
|
||||
LazyTasksService,
|
||||
Marker };
|
||||
|
|
|
@ -10,6 +10,7 @@ export class AppStateService {
|
|||
error = new BehaviorSubject<any>(null);
|
||||
loading = new Subject<boolean>();
|
||||
initialized = new BehaviorSubject<any>(false);
|
||||
rightPanelHidden = new BehaviorSubject<any>(false);
|
||||
|
||||
searchContainingPointers = new BehaviorSubject<string|null[]>([]);
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
ComponentFactoryResolver
|
||||
} from '@angular/core';
|
||||
|
||||
type NodesOrComponents = HTMLElement | ComponentRef<any>;
|
||||
export type NodesOrComponents = HTMLElement | ComponentRef<any>;
|
||||
export const COMPONENT_PARSER_ALLOWED = 'COMPONENT_PARSER_ALLOWED';
|
||||
|
||||
const COMPONENT_REGEXP = '^\\s*<!-- ReDoc-Inject:\\s+?{component}\\s+?-->\\s*$';
|
||||
|
|
|
@ -18,7 +18,7 @@ const CHANGE = {
|
|||
BACK : -1,
|
||||
};
|
||||
|
||||
interface TagGroup {
|
||||
export interface TagGroup {
|
||||
name: string;
|
||||
tags: string[];
|
||||
}
|
||||
|
@ -50,6 +50,8 @@ export class MenuService {
|
|||
items: MenuItem[];
|
||||
activeIdx: number = -1;
|
||||
|
||||
public domRoot: Document | Element = document;
|
||||
|
||||
private _flatItems: MenuItem[];
|
||||
private _hashSubscription: Subscription;
|
||||
private _scrollSubscription: Subscription;
|
||||
|
@ -64,7 +66,11 @@ export class MenuService {
|
|||
private specMgr:SpecManager
|
||||
) {
|
||||
this.hash = hash;
|
||||
this.buildMenu();
|
||||
|
||||
this.specMgr.spec.subscribe(spec => {
|
||||
if (!spec) return;
|
||||
this.buildMenu();
|
||||
});
|
||||
|
||||
this._scrollSubscription = scrollService.scroll.subscribe((evt) => {
|
||||
this.onScroll(evt.isScrolledDown);
|
||||
|
@ -172,7 +178,7 @@ export class MenuService {
|
|||
currentItem = currentItem.parent;
|
||||
}
|
||||
selector = selector.trim();
|
||||
return selector ? document.querySelector(selector) : null;
|
||||
return selector ? this.domRoot.querySelector(selector) : null;
|
||||
}
|
||||
|
||||
isTagOrGroupItem(flatIdx: number):boolean {
|
||||
|
@ -202,13 +208,12 @@ export class MenuService {
|
|||
}
|
||||
}
|
||||
|
||||
activate(idx, force = false, replaceState = false) {
|
||||
let item = this.flatItems[idx];
|
||||
activate(item:MenuItem, force = false, replaceState = false) {
|
||||
if (!force && item && !item.ready) return;
|
||||
|
||||
this.deactivate(this.activeIdx);
|
||||
this.activeIdx = idx;
|
||||
if (idx < 0) {
|
||||
this.activeIdx = item ? item.flatIdx : -1;
|
||||
if (this.activeIdx < 0) {
|
||||
this.hash.update('', replaceState);
|
||||
return;
|
||||
}
|
||||
|
@ -224,10 +229,15 @@ export class MenuService {
|
|||
this.changedActiveItem.next(item);
|
||||
}
|
||||
|
||||
activateByIdx(idx:number, force = false, replaceState = false) {
|
||||
let item = this.flatItems[idx];
|
||||
this.activate(item, force, replaceState);
|
||||
}
|
||||
|
||||
changeActive(offset = 1):boolean {
|
||||
let noChange = (this.activeIdx <= 0 && offset === -1) ||
|
||||
(this.activeIdx === this.flatItems.length - 1 && offset === 1);
|
||||
this.activate(this.activeIdx + offset, false, true);
|
||||
this.activateByIdx(this.activeIdx + offset, false, true);
|
||||
return noChange;
|
||||
}
|
||||
|
||||
|
@ -263,12 +273,12 @@ export class MenuService {
|
|||
return item.metadata && item.metadata.operationId === ptr;
|
||||
});
|
||||
}
|
||||
this.activate(idx, true);
|
||||
this.activateByIdx(idx, true);
|
||||
return idx >= 0;
|
||||
}
|
||||
|
||||
tryScrollToId(id) {
|
||||
let $el = document.querySelector(`[section="${id}"]`);
|
||||
let $el = this.domRoot.querySelector(`[section="${id}"]`);
|
||||
if ($el) this.scrollService.scrollTo($el);
|
||||
}
|
||||
|
||||
|
@ -311,15 +321,16 @@ export class MenuService {
|
|||
if (!tag.operations || !tag.operations.length) return null;
|
||||
|
||||
let res = [];
|
||||
for (let operation of tag.operations) {
|
||||
for (let operationInfo of tag.operations) {
|
||||
let subItem = {
|
||||
name: SchemaHelper.operationSummary(operation),
|
||||
id: operation._pointer,
|
||||
description: operation.description,
|
||||
name: SchemaHelper.operationSummary(operationInfo),
|
||||
id: operationInfo._pointer,
|
||||
description: operationInfo.description,
|
||||
metadata: {
|
||||
type: 'operation',
|
||||
pointer: operation._pointer,
|
||||
operationId: operation.operationId
|
||||
pointer: operationInfo._pointer,
|
||||
operationId: operationInfo.operationId,
|
||||
operation: operationInfo.operation
|
||||
},
|
||||
parent: parent
|
||||
};
|
||||
|
@ -330,8 +341,8 @@ export class MenuService {
|
|||
|
||||
hashFor(
|
||||
id: string|null, itemMeta:
|
||||
{operationId: string, type: string, pointer: string},
|
||||
parentId: string
|
||||
{operationId?: string, type: string, pointer?: string},
|
||||
parentId?: string
|
||||
) {
|
||||
if (!id) return null;
|
||||
if (itemMeta && itemMeta.type === 'operation') {
|
||||
|
@ -434,6 +445,7 @@ export class MenuService {
|
|||
|
||||
flatMenu():MenuItem[] {
|
||||
let menu = this.items;
|
||||
if (!menu) return;
|
||||
let res = [];
|
||||
let curDepth = 1;
|
||||
|
||||
|
|
|
@ -16,7 +16,8 @@ const OPTION_NAMES = new Set([
|
|||
'hideHostname',
|
||||
'lazyRendering',
|
||||
'expandResponses',
|
||||
'requiredPropsFirst'
|
||||
'requiredPropsFirst',
|
||||
'noAutoAuth'
|
||||
]);
|
||||
|
||||
export interface Options {
|
||||
|
@ -29,6 +30,7 @@ export interface Options {
|
|||
expandResponses?: Set<string> | 'all';
|
||||
$scrollParent?: HTMLElement | Window;
|
||||
requiredPropsFirst?: boolean;
|
||||
noAutoAuth?: boolean;
|
||||
spec?: any;
|
||||
}
|
||||
|
||||
|
@ -95,6 +97,7 @@ export class OptionsService {
|
|||
if (isString(this._options.hideHostname)) this._options.hideHostname = true;
|
||||
if (isString(this._options.lazyRendering)) this._options.lazyRendering = true;
|
||||
if (isString(this._options.requiredPropsFirst)) this._options.requiredPropsFirst = true;
|
||||
if (isString(this._options.noAutoAuth)) this._options.noAutoAuth = true;
|
||||
if (isString(this._options.expandResponses)) {
|
||||
let str = this._options.expandResponses as string;
|
||||
if (str === 'all') return;
|
||||
|
|
|
@ -4,7 +4,7 @@ import { operations as swaggerOperations, keywordTypes } from '../utils/swagger
|
|||
import { WarningsService } from './warnings.service';
|
||||
import * as slugify from 'slugify';
|
||||
|
||||
interface PropertyPreprocessOptions {
|
||||
export interface PropertyPreprocessOptions {
|
||||
childFor?: string;
|
||||
skipReadOnly?: boolean;
|
||||
discriminator?: string;
|
||||
|
@ -321,6 +321,7 @@ export class SchemaHelper {
|
|||
if (!tag.operations) tag.operations = [];
|
||||
tag.operations.push(operationInfo);
|
||||
operationInfo._pointer = operationPointer;
|
||||
operationInfo.operation = operation;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,11 @@
|
|||
'use strict';
|
||||
import { SchemaNormalizer } from './schema-normalizer.service';
|
||||
import { SpecManager } from '../utils/spec-manager';;
|
||||
import { OptionsService } from '../services/options.service';
|
||||
|
||||
|
||||
describe('Spec Helper', () => {
|
||||
let specMgr:SpecManager = new SpecManager();
|
||||
let specMgr:SpecManager = new SpecManager(new OptionsService());
|
||||
let normalizer = new SchemaNormalizer(specMgr);
|
||||
|
||||
describe('Dereference', () => {
|
||||
|
|
|
@ -5,12 +5,12 @@ import { JsonPointer } from '../utils/JsonPointer';
|
|||
import { defaults } from '../utils/helpers';
|
||||
import { WarningsService } from './warnings.service';
|
||||
|
||||
interface Reference {
|
||||
export interface Reference {
|
||||
$ref: string;
|
||||
description: string;
|
||||
}
|
||||
|
||||
interface Schema {
|
||||
export interface Schema {
|
||||
properties: any;
|
||||
allOf: any;
|
||||
items: any;
|
||||
|
@ -180,7 +180,7 @@ class RefCounter {
|
|||
}
|
||||
|
||||
|
||||
class SchemaDereferencer {
|
||||
export class SchemaDereferencer {
|
||||
private _refCouner = new RefCounter();
|
||||
|
||||
constructor(private _spec: SpecManager, private normalizator: SchemaNormalizer) {
|
||||
|
|
|
@ -15,7 +15,7 @@ import {
|
|||
|
||||
import * as lunr from 'lunr';
|
||||
|
||||
interface IndexElement {
|
||||
export interface IndexElement {
|
||||
menuId: string;
|
||||
title: string;
|
||||
body: string;
|
||||
|
|
|
@ -70,3 +70,13 @@ $border-radius: 2px;
|
|||
// texts
|
||||
$array-text: 'Array of ';
|
||||
$tuple-text: 'Tuple ';
|
||||
|
||||
// HTTP Verb colors
|
||||
$get-color: #6bbd5b;
|
||||
$post-color: #248fb2;
|
||||
$put-color: #9b708b;
|
||||
$options-color: #d3ca12;
|
||||
$patch-color: #e09d43;
|
||||
$delete-color: #e27a7a;
|
||||
$basic-color: #999;
|
||||
$link-color: #31bbb6;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
'use strict';
|
||||
|
||||
import { Injectable } from '@angular/core';
|
||||
import * as JsonSchemaRefParser from 'json-schema-ref-parser';
|
||||
import { JsonPointer } from './JsonPointer';
|
||||
import { parse as urlParse, resolve as urlResolve } from 'url';
|
||||
|
@ -9,6 +9,7 @@ import { MdRenderer } from './md-renderer';
|
|||
|
||||
import { SwaggerOperation, SwaggerParameter } from './swagger-typings';
|
||||
import { snapshot } from './helpers';
|
||||
import { OptionsService, Options } from '../services/options.service';
|
||||
import { WarningsService } from '../services/warnings.service';
|
||||
|
||||
function getDiscriminator(obj) {
|
||||
|
@ -22,6 +23,7 @@ export interface DescendantInfo {
|
|||
idx?: number;
|
||||
}
|
||||
|
||||
@Injectable()
|
||||
export class SpecManager {
|
||||
public _schema: any = {};
|
||||
public apiUrl: string;
|
||||
|
@ -32,6 +34,11 @@ export class SpecManager {
|
|||
public spec = new BehaviorSubject<any|null>(null);
|
||||
public _specUrl: string;
|
||||
private parser: any;
|
||||
private options: Options;
|
||||
|
||||
constructor(optionsService: OptionsService) {
|
||||
this.options = optionsService.options;
|
||||
}
|
||||
|
||||
load(urlOrObject: string|Object) {
|
||||
let promise = new Promise((resolve, reject) => {
|
||||
|
@ -87,8 +94,8 @@ export class SpecManager {
|
|||
throw Error('Specification Error: Required field "info" is not specified at the top level of the specification');
|
||||
}
|
||||
if (!this._schema.info.description) this._schema.info.description = '';
|
||||
if (this._schema.securityDefinitions) {
|
||||
let SecurityDefinitions = require('../components/').SecurityDefinitions;
|
||||
if (this._schema.securityDefinitions && !this.options.noAutoAuth) {
|
||||
let SecurityDefinitions = require('../components/').SecurityDefinitions;
|
||||
mdRender.addPreprocessor(SecurityDefinitions.insertTagIntoDescription);
|
||||
}
|
||||
this._schema.info['x-redoc-html-description'] = mdRender.renderMd(this._schema.info.description);
|
||||
|
|
|
@ -10,7 +10,7 @@ import {
|
|||
Response
|
||||
} from '@types/swagger-schema-official';
|
||||
|
||||
interface RedocInjectedPointer {
|
||||
export interface RedocInjectedPointer {
|
||||
_pointer?: string;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
{
|
||||
"name": "redoc",
|
||||
"description": "Swagger-generated API Reference Documentation",
|
||||
"version": "1.12.1",
|
||||
"version": "1.13.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "git://github.com/Rebilly/ReDoc"
|
||||
|
@ -10,7 +10,7 @@
|
|||
"node": ">=6.9",
|
||||
"npm": ">=3.0.0"
|
||||
},
|
||||
"main": "dist/redoc.min.js",
|
||||
"main": "dist/redoc-module.js",
|
||||
"scripts": {
|
||||
"test": "npm run lint && node ./build/run_tests.js",
|
||||
"branch-release": "git reset --hard && branch-release",
|
||||
|
@ -33,7 +33,9 @@
|
|||
"webdriver": "webdriver-manager update",
|
||||
"serve:prod": "NODE_ENV=production npm start",
|
||||
"protractor": "protractor",
|
||||
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 1"
|
||||
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s -r 1",
|
||||
"build:prod-module": "npm run build:sass && npm run ngc && npm run webpack:prod && IS_MODULE=true npm run webpack:prod",
|
||||
"build:module": "npm run build:sass && npm run ngc && IS_MODULE=true npm run webpack:prod"
|
||||
},
|
||||
"keywords": [
|
||||
"OpenAPI",
|
||||
|
@ -74,6 +76,7 @@
|
|||
"dropkickjs": "^2.1.10",
|
||||
"hint.css": "^2.3.2",
|
||||
"http-server": "^0.9.0",
|
||||
"https-browserify": "^1.0.0",
|
||||
"istanbul-instrumenter-loader": "^2.0.0",
|
||||
"jasmine-core": "^2.4.1",
|
||||
"jasmine-spec-reporter": "^3.1.0",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
'use strict';
|
||||
|
||||
import { SpecManager } from '../../lib/utils/spec-manager';
|
||||
import { OptionsService } from '../../lib/services/options.service';
|
||||
import * as xExtendedDefs from './x-extended-defs.json';
|
||||
|
||||
describe('Utils', () => {
|
||||
|
@ -8,7 +9,7 @@ describe('Utils', () => {
|
|||
let specMgr: SpecManager;
|
||||
|
||||
beforeEach(() => {
|
||||
specMgr = new SpecManager();
|
||||
specMgr = new SpecManager(new OptionsService());
|
||||
});
|
||||
|
||||
it('load should return a promise', ()=> {
|
||||
|
|
|
@ -13,10 +13,11 @@
|
|||
"should",
|
||||
"webpack"
|
||||
],
|
||||
"outDir": "dist",
|
||||
"lib": [
|
||||
"DOM", "ES2016", "DOM.Iterable"
|
||||
],
|
||||
"noEmitHelpers": true
|
||||
"noEmitHelpers": false
|
||||
},
|
||||
"compileOnSave": false,
|
||||
"exclude": [
|
||||
|
|
|
@ -2369,6 +2369,10 @@ https-browserify@0.0.1:
|
|||
version "0.0.1"
|
||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82"
|
||||
|
||||
https-browserify@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-1.0.0.tgz#ec06c10e0a34c0f2faf199f7fd7fc78fffd03c73"
|
||||
|
||||
https-proxy-agent@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-1.0.0.tgz#35f7da6c48ce4ddbfa264891ac593ee5ff8671e6"
|
||||
|
|
Loading…
Reference in New Issue
Block a user