mirror of
https://github.com/Redocly/redoc.git
synced 2024-12-01 21:03:45 +03:00
refactor: renamve Method to Operation
This commit is contained in:
parent
36a81ed662
commit
b9740bfe55
|
@ -138,7 +138,7 @@ ReDoc makes use of the following [vendor extensions](http://swagger.io/specifica
|
||||||
* **function**: A getter function. Must return a number representing the offset (in pixels);
|
* **function**: A getter function. Must return a number representing the offset (in pixels);
|
||||||
* `suppress-warnings` - if set, warnings are not rendered at the top of documentation (they still are logged to the console).
|
* `suppress-warnings` - if set, warnings are not rendered at the top of documentation (they still are logged to the console).
|
||||||
* `lazy-rendering` - if set, enables lazy rendering mode in ReDoc. This mode is useful for APIs with big number of operations (e.g. > 50). In this mode ReDoc shows initial screen ASAP and then renders the rest operations asynchronously while showing progress bar on the top. Check out the [demo](\\rebilly.github.io/ReDoc) for the example.
|
* `lazy-rendering` - if set, enables lazy rendering mode in ReDoc. This mode is useful for APIs with big number of operations (e.g. > 50). In this mode ReDoc shows initial screen ASAP and then renders the rest operations asynchronously while showing progress bar on the top. Check out the [demo](\\rebilly.github.io/ReDoc) for the example.
|
||||||
* `hide-hostname` - if set, the protocol and hostname is not shown in the method definition.
|
* `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.
|
* `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.
|
* `required-props-first` - show required properties first ordered in the same order as in `required` array.
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<div class="method-endpoint" (click)="handleClick()">
|
<div class="operation-endpoint" (click)="handleClick()">
|
||||||
<h5 class="http-verb" [ngClass]="verb">{{verb}}</h5>
|
<h5 class="http-verb" [ngClass]="verb">{{verb}}</h5>
|
||||||
<span><!--
|
<span><!--
|
||||||
--><span class="method-api-url-path">{{path}}</span><!--
|
--><span class="operation-api-url-path">{{path}}</span><!--
|
||||||
--></span>
|
--></span>
|
||||||
</div>
|
</div>
|
||||||
<svg class="expand-icon" xmlns="http://www.w3.org/2000/svg" version="1.1" x="0" y="0" viewBox="0 0 24 24" xml:space="preserve">
|
<svg class="expand-icon" xmlns="http://www.w3.org/2000/svg" version="1.1" x="0" y="0" viewBox="0 0 24 24" xml:space="preserve">
|
||||||
|
@ -11,7 +11,7 @@
|
||||||
<div *ngFor="let server of servers" class="server-item">
|
<div *ngFor="let server of servers" class="server-item">
|
||||||
<div class="description" [innerHtml]="server.description | marked"></div>
|
<div class="description" [innerHtml]="server.description | marked"></div>
|
||||||
<div select-on-click class="url">
|
<div select-on-click class="url">
|
||||||
<span class="method-api-url"> {{server.url}}</span>{{path}}
|
<span class="operation-api-url"> {{server.url}}</span>{{path}}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.method-endpoint {
|
.operation-endpoint {
|
||||||
padding: 10px 30px 10px 20px;
|
padding: 10px 30px 10px 20px;
|
||||||
border-radius: $border-radius*2;
|
border-radius: $border-radius*2;
|
||||||
background-color: darken($black, 2%);
|
background-color: darken($black, 2%);
|
||||||
|
@ -18,7 +18,7 @@
|
||||||
border: 1px solid transparent;
|
border: 1px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.method-endpoint > .method-params-subheader {
|
.operation-endpoint > .operation-params-subheader {
|
||||||
padding-top: 1px;
|
padding-top: 1px;
|
||||||
padding-bottom: 0;
|
padding-bottom: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -29,7 +29,7 @@
|
||||||
border-radius: $border-radius;
|
border-radius: $border-radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
.method-api-url {
|
.operation-api-url {
|
||||||
color: rgba($black, .8);
|
color: rgba($black, .8);
|
||||||
&-path {
|
&-path {
|
||||||
font-family: $headers-font, $headers-font-family;
|
font-family: $headers-font, $headers-font-family;
|
||||||
|
@ -96,7 +96,7 @@
|
||||||
transition: all 0.25s ease;
|
transition: all 0.25s ease;
|
||||||
}
|
}
|
||||||
:host.expanded {
|
:host.expanded {
|
||||||
> .method-endpoint {
|
> .operation-endpoint {
|
||||||
border-color: $side-bar-bg-color;
|
border-color: $side-bar-bg-color;
|
||||||
border-bottom-left-radius: 0;
|
border-bottom-left-radius: 0;
|
||||||
border-bottom-right-radius: 0;
|
border-bottom-right-radius: 0;
|
||||||
|
|
|
@ -72,11 +72,11 @@ describe('Redoc components', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/** Test component that contains a Method. */
|
/** Test component that contains an Operation. */
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'test-app',
|
selector: 'test-app',
|
||||||
template:
|
template:
|
||||||
`<method pointer='#/paths/~1user~1{username}/put'></method>`
|
`<operation pointer='#/paths/~1user~1{username}/put'></operation>`
|
||||||
})
|
})
|
||||||
class TestAppComponent {
|
class TestAppComponent {
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ describe('Redoc components', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/** Test component that contains a Method. */
|
/** Test component that contains a lazy schema. */
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'test-app',
|
selector: 'test-app',
|
||||||
template:
|
template:
|
||||||
|
|
|
@ -57,7 +57,7 @@ describe('Redoc components', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/** Test component that contains a Method. */
|
/** Test component that contains a json schema. */
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'test-app',
|
selector: 'test-app',
|
||||||
template:
|
template:
|
||||||
|
|
|
@ -1,30 +0,0 @@
|
||||||
<div class="method" *ngIf="method">
|
|
||||||
<div class="method-content">
|
|
||||||
<h2 class="method-header sharable-header">
|
|
||||||
<a class="share-link" href="#{{method.anchor}}"></a>{{method.summary}}
|
|
||||||
</h2>
|
|
||||||
<div class="method-tags" *ngIf="method.info.tags.length">
|
|
||||||
<a *ngFor="let tag of method.info.tags" attr.href="#tag/{{tag}}"> {{tag}} </a>
|
|
||||||
</div>
|
|
||||||
<p *ngIf="method.info.description" class="method-description"
|
|
||||||
[innerHtml]="method.info.description | marked">
|
|
||||||
</p>
|
|
||||||
<redoc-externalDocs [docs]="method.externalDocs"></redoc-externalDocs>
|
|
||||||
<params-list pointer="{{pointer}}/parameters"> </params-list>
|
|
||||||
<responses-list pointer="{{pointer}}/responses"> </responses-list>
|
|
||||||
</div>
|
|
||||||
<div class="method-samples">
|
|
||||||
<h4 class="method-params-subheader">Definition</h4>
|
|
||||||
|
|
||||||
<endpoint-link [verb]="method.verb" [path]="method.path"> </endpoint-link>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<request-samples [pointer]="pointer" [schemaPointer]="method.bodyParam?._pointer">
|
|
||||||
</request-samples>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<br>
|
|
||||||
<responses-samples pointer="{{pointer}}/responses"> </responses-samples>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
30
lib/components/Operation/operation.html
Normal file
30
lib/components/Operation/operation.html
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
<div class="operation" *ngIf="operation">
|
||||||
|
<div class="operation-content">
|
||||||
|
<h2 class="operation-header sharable-header">
|
||||||
|
<a class="share-link" href="#{{operation.anchor}}"></a>{{operation.summary}}
|
||||||
|
</h2>
|
||||||
|
<div class="operation-tags" *ngIf="operation.info.tags.length">
|
||||||
|
<a *ngFor="let tag of operation.info.tags" attr.href="#tag/{{tag}}"> {{tag}} </a>
|
||||||
|
</div>
|
||||||
|
<p *ngIf="operation.info.description" class="operation-description"
|
||||||
|
[innerHtml]="operation.info.description | marked">
|
||||||
|
</p>
|
||||||
|
<redoc-externalDocs [docs]="operation.externalDocs"></redoc-externalDocs>
|
||||||
|
<params-list pointer="{{pointer}}/parameters"> </params-list>
|
||||||
|
<responses-list pointer="{{pointer}}/responses"> </responses-list>
|
||||||
|
</div>
|
||||||
|
<div class="operation-samples">
|
||||||
|
<h4 class="operation-params-subheader">Definition</h4>
|
||||||
|
|
||||||
|
<endpoint-link [verb]="operation.verb" [path]="operation.path"> </endpoint-link>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<request-samples [pointer]="pointer" [schemaPointer]="operation.bodyParam?._pointer">
|
||||||
|
</request-samples>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<br>
|
||||||
|
<responses-samples pointer="{{pointer}}/responses"> </responses-samples>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
|
@ -14,11 +14,11 @@
|
||||||
// border-bottom: 0;
|
// border-bottom: 0;
|
||||||
// }
|
// }
|
||||||
|
|
||||||
.method-header {
|
.operation-header {
|
||||||
margin-bottom: calc(1em - 6px);
|
margin-bottom: calc(1em - 6px);
|
||||||
}
|
}
|
||||||
|
|
||||||
.method-tags {
|
.operation-tags {
|
||||||
margin-top: 20px;
|
margin-top: 20px;
|
||||||
|
|
||||||
> a {
|
> a {
|
||||||
|
@ -39,45 +39,45 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.method-content, .method-samples {
|
.operation-content, .operation-samples {
|
||||||
display: block;
|
display: block;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.method-content {
|
.operation-content {
|
||||||
width: 100% - $samples-panel-width;
|
width: 100% - $samples-panel-width;
|
||||||
padding: $section-spacing;
|
padding: $section-spacing;
|
||||||
}
|
}
|
||||||
|
|
||||||
.method-samples {
|
.operation-samples {
|
||||||
color: $sample-panel-color;
|
color: $sample-panel-color;
|
||||||
width: 40%;
|
width: 40%;
|
||||||
padding: $section-spacing;
|
padding: $section-spacing;
|
||||||
background: $samples-panel-bg-color;
|
background: $samples-panel-bg-color;
|
||||||
}
|
}
|
||||||
|
|
||||||
.method-samples header,
|
.operation-samples header,
|
||||||
.method-samples > h5 {
|
.operation-samples > h5 {
|
||||||
color: $sample-panel-headers-color;
|
color: $sample-panel-headers-color;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.method-samples > h5 {
|
.operation-samples > h5 {
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.method-samples schema-sample {
|
.operation-samples schema-sample {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.method:after {
|
.operation:after {
|
||||||
content: "";
|
content: "";
|
||||||
display: table;
|
display: table;
|
||||||
clear:both;
|
clear:both;
|
||||||
}
|
}
|
||||||
|
|
||||||
.method-description {
|
.operation-description {
|
||||||
padding: 6px 0 10px 0;
|
padding: 6px 0 10px 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
|
@ -87,15 +87,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: $right-panel-squash-breakpoint) {
|
@media (max-width: $right-panel-squash-breakpoint) {
|
||||||
.methods:before {
|
.operations:before {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.method-samples, .method-content {
|
.operation-samples, .operation-content {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.method-samples {
|
.operation-samples {
|
||||||
margin-top: 2em;
|
margin-top: 2em;
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import {
|
||||||
|
|
||||||
import { getChildDebugElement } from '../../../tests/helpers';
|
import { getChildDebugElement } from '../../../tests/helpers';
|
||||||
|
|
||||||
import { Method } from './method';
|
import { Operation } from './operation';
|
||||||
import { SpecManager } from '../../utils/spec-manager';;
|
import { SpecManager } from '../../utils/spec-manager';;
|
||||||
import { LazyTasksService } from '../../shared/components/LazyFor/lazy-for';;
|
import { LazyTasksService } from '../../shared/components/LazyFor/lazy-for';;
|
||||||
|
|
||||||
|
@ -17,9 +17,9 @@ describe('Redoc components', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({ declarations: [ TestAppComponent ] });
|
TestBed.configureTestingModule({ declarations: [ TestAppComponent ] });
|
||||||
});
|
});
|
||||||
describe('Method Component', () => {
|
describe('Operation Component', () => {
|
||||||
let builder;
|
let builder;
|
||||||
let component: Method;
|
let component: Operation;
|
||||||
let specMgr;
|
let specMgr;
|
||||||
|
|
||||||
beforeEach(async(inject([SpecManager, LazyTasksService], (_specMgr, lazyTasks) => {
|
beforeEach(async(inject([SpecManager, LazyTasksService], (_specMgr, lazyTasks) => {
|
||||||
|
@ -33,7 +33,7 @@ describe('Redoc components', () => {
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
let fixture = TestBed.createComponent(TestAppComponent);
|
let fixture = TestBed.createComponent(TestAppComponent);
|
||||||
component = getChildDebugElement(fixture.debugElement, 'method').componentInstance;
|
component = getChildDebugElement(fixture.debugElement, 'operation').componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -43,23 +43,23 @@ describe('Redoc components', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should init basic component data', () => {
|
it('should init basic component data', () => {
|
||||||
component.method.verb.should.be.equal('put');
|
component.operation.verb.should.be.equal('put');
|
||||||
component.method.path.should.be.equal('/user/{username}');
|
component.operation.path.should.be.equal('/user/{username}');
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
it('should main tag', () => {
|
it('should main tag', () => {
|
||||||
component.method.info.tags.should.be.empty();
|
component.operation.info.tags.should.be.empty();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/** Test component that contains a Method. */
|
/** Test component that contains a Operation. */
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'test-app',
|
selector: 'test-app',
|
||||||
template:
|
template:
|
||||||
`<method pointer='#/paths/~1user~1{username}/put'></method>`
|
`<operation pointer='#/paths/~1user~1{username}/put'></operation>`
|
||||||
})
|
})
|
||||||
class TestAppComponent {
|
class TestAppComponent {
|
||||||
}
|
}
|
|
@ -6,7 +6,7 @@ import { SchemaHelper } from '../../services/schema-helper.service';
|
||||||
import { OptionsService, MenuService } from '../../services/';
|
import { OptionsService, MenuService } from '../../services/';
|
||||||
|
|
||||||
|
|
||||||
interface MethodInfo {
|
interface OperationInfo {
|
||||||
verb: string;
|
verb: string;
|
||||||
path: string;
|
path: string;
|
||||||
info: {
|
info: {
|
||||||
|
@ -23,18 +23,18 @@ interface MethodInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'method',
|
selector: 'operation',
|
||||||
templateUrl: './method.html',
|
templateUrl: './operation.html',
|
||||||
styleUrls: ['./method.css'],
|
styleUrls: ['./operation.css'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class Method extends BaseComponent implements OnInit {
|
export class Operation extends BaseComponent implements OnInit {
|
||||||
@Input() pointer :string;
|
@Input() pointer :string;
|
||||||
@Input() parentTagId :string;
|
@Input() parentTagId :string;
|
||||||
|
|
||||||
@HostBinding('attr.operation-id') operationId;
|
@HostBinding('attr.operation-id') operationId;
|
||||||
|
|
||||||
method: MethodInfo;
|
operation: OperationInfo;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
specMgr:SpecManager,
|
specMgr:SpecManager,
|
||||||
|
@ -46,7 +46,7 @@ export class Method extends BaseComponent implements OnInit {
|
||||||
init() {
|
init() {
|
||||||
this.operationId = this.componentSchema.operationId;
|
this.operationId = this.componentSchema.operationId;
|
||||||
|
|
||||||
this.method = {
|
this.operation = {
|
||||||
verb: JsonPointer.baseName(this.pointer),
|
verb: JsonPointer.baseName(this.pointer),
|
||||||
path: JsonPointer.baseName(this.pointer, 2),
|
path: JsonPointer.baseName(this.pointer, 2),
|
||||||
info: {
|
info: {
|
||||||
|
@ -54,7 +54,7 @@ export class Method extends BaseComponent implements OnInit {
|
||||||
tags: this.filterMainTags(this.componentSchema.tags)
|
tags: this.filterMainTags(this.componentSchema.tags)
|
||||||
},
|
},
|
||||||
bodyParam: this.findBodyParam(),
|
bodyParam: this.findBodyParam(),
|
||||||
summary: SchemaHelper.methodSummary(this.componentSchema),
|
summary: SchemaHelper.operationSummary(this.componentSchema),
|
||||||
anchor: this.buildAnchor(),
|
anchor: this.buildAnchor(),
|
||||||
externalDocs: this.componentSchema.externalDocs
|
externalDocs: this.componentSchema.externalDocs
|
||||||
};
|
};
|
||||||
|
@ -62,7 +62,7 @@ export class Method extends BaseComponent implements OnInit {
|
||||||
|
|
||||||
buildAnchor():string {
|
buildAnchor():string {
|
||||||
return this.menu.hashFor(this.pointer,
|
return this.menu.hashFor(this.pointer,
|
||||||
{ type: 'method', operationId: this.operationId, pointer: this.pointer },
|
{ type: 'operation', operationId: this.operationId, pointer: this.pointer },
|
||||||
this.parentTagId );
|
this.parentTagId );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -73,8 +73,8 @@ export class Method extends BaseComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
findBodyParam() {
|
findBodyParam() {
|
||||||
let pathParams = this.specMgr.getMethodParams(this.pointer);
|
let params = this.specMgr.getOperationParams(this.pointer);
|
||||||
let bodyParam = pathParams.find(param => param.in === 'body');
|
let bodyParam = params.find(param => param.in === 'body');
|
||||||
return bodyParam;
|
return bodyParam;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<div class="methods">
|
<div class="operations">
|
||||||
<div class="tag" *ngFor="let tag of tags; trackBy:trackByTagName" [attr.section]="tag.id">
|
<div class="tag" *ngFor="let tag of tags; trackBy:trackByTagName" [attr.section]="tag.id">
|
||||||
<div class="tag-info" *ngIf="tag.name">
|
<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.id}}"></a>{{tag.name}} </h1>
|
||||||
<p *ngIf="tag.description" [innerHtml]="tag.description | marked"> </p>
|
<p *ngIf="tag.description" [innerHtml]="tag.description | marked"> </p>
|
||||||
<redoc-externalDocs [docs]="tag.metadata.externalDocs"></redoc-externalDocs>
|
<redoc-externalDocs [docs]="tag.metadata.externalDocs"></redoc-externalDocs>
|
||||||
</div>
|
</div>
|
||||||
<method *lazyFor="let methodItem of tag.items; let ready = ready;"
|
<operation *lazyFor="let operation of tag.items; let ready = ready;"
|
||||||
[hidden]="!ready" [pointer]="methodItem.metadata.pointer"
|
[hidden]="!ready" [pointer]="operation.metadata.pointer"
|
||||||
[parentTagId]="tag.id" [attr.section]="methodItem.id"></method>
|
[parentTagId]="tag.id" [attr.section]="operation.id"></operation>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
|
@ -32,7 +32,7 @@
|
||||||
margin-top: 0;
|
margin-top: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.methods {
|
.operations {
|
||||||
display: block;
|
display: block;
|
||||||
position: relative;;
|
position: relative;;
|
||||||
}
|
}
|
|
@ -10,14 +10,14 @@ import {
|
||||||
import { getChildDebugElement } from '../../../tests/helpers';
|
import { getChildDebugElement } from '../../../tests/helpers';
|
||||||
|
|
||||||
|
|
||||||
import { MethodsList } from './methods-list';
|
import { OperationsList } from './operations-list';
|
||||||
import { SpecManager } from '../../utils/spec-manager';
|
import { SpecManager } from '../../utils/spec-manager';
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({ declarations: [ TestAppComponent ] });
|
TestBed.configureTestingModule({ declarations: [ TestAppComponent ] });
|
||||||
});
|
});
|
||||||
describe('MethodsList Component', () => {
|
describe('OperationsList Component', () => {
|
||||||
let builder;
|
let builder;
|
||||||
let component;
|
let component;
|
||||||
let fixture;
|
let fixture;
|
||||||
|
@ -28,12 +28,12 @@ describe('Redoc components', () => {
|
||||||
})));
|
})));
|
||||||
|
|
||||||
beforeEach(done => {
|
beforeEach(done => {
|
||||||
specMgr.load('/tests/schemas/methods-list-component.json').then(done, done.fail);
|
specMgr.load('/tests/schemas/operations-list-component.json').then(done, done.fail);
|
||||||
});
|
});
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
fixture = TestBed.createComponent(TestAppComponent);
|
fixture = TestBed.createComponent(TestAppComponent);
|
||||||
component = getChildDebugElement(fixture.debugElement, 'methods-list').componentInstance;
|
component = getChildDebugElement(fixture.debugElement, 'operations-list').componentInstance;
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -56,7 +56,7 @@ describe('Redoc components', () => {
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'test-app',
|
selector: 'test-app',
|
||||||
template:
|
template:
|
||||||
`<methods-list></methods-list>`
|
`<operations-list></operations-list>`
|
||||||
})
|
})
|
||||||
class TestAppComponent {
|
class TestAppComponent {
|
||||||
}
|
}
|
|
@ -4,12 +4,12 @@ import { BaseComponent, SpecManager } from '../base';
|
||||||
import { MenuService } from '../../services/index';
|
import { MenuService } from '../../services/index';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'methods-list',
|
selector: 'operations-list',
|
||||||
templateUrl: './methods-list.html',
|
templateUrl: './operations-list.html',
|
||||||
styleUrls: ['./methods-list.css'],
|
styleUrls: ['./operations-list.css'],
|
||||||
changeDetection: ChangeDetectionStrategy.OnPush
|
changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class MethodsList extends BaseComponent implements OnInit {
|
export class OperationsList extends BaseComponent implements OnInit {
|
||||||
@Input() pointer:string;
|
@Input() pointer:string;
|
||||||
|
|
||||||
tags:Array<any> = [];
|
tags:Array<any> = [];
|
||||||
|
@ -26,13 +26,13 @@ export class MethodsList extends BaseComponent implements OnInit {
|
||||||
items: []
|
items: []
|
||||||
};
|
};
|
||||||
flatMenuItems.forEach(menuItem => {
|
flatMenuItems.forEach(menuItem => {
|
||||||
// skip items that are not bound to swagger tags/methods
|
// skip items that are not bound to swagger tags/operations
|
||||||
if (!menuItem.metadata) return;
|
if (!menuItem.metadata) return;
|
||||||
|
|
||||||
if (menuItem.metadata.type === 'tag') {
|
if (menuItem.metadata.type === 'tag') {
|
||||||
this.tags.push(menuItem);
|
this.tags.push(menuItem);
|
||||||
}
|
}
|
||||||
if (menuItem.metadata.type === 'method' && !menuItem.parent) {
|
if (menuItem.metadata.type === 'operation' && !menuItem.parent) {
|
||||||
emptyTag.items.push(menuItem);
|
emptyTag.items.push(menuItem);
|
||||||
}
|
}
|
||||||
});
|
});
|
|
@ -27,7 +27,7 @@ export class ParamsList extends BaseComponent implements OnInit {
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
this.params = [];
|
this.params = [];
|
||||||
let paramsList = this.specMgr.getMethodParams(this.pointer);
|
let paramsList = this.specMgr.getOperationParams(this.pointer);
|
||||||
|
|
||||||
paramsList = paramsList.map(paramSchema => {
|
paramsList = paramsList.map(paramSchema => {
|
||||||
let propPointer = paramSchema._pointer;
|
let propPointer = paramSchema._pointer;
|
||||||
|
|
|
@ -17,7 +17,7 @@
|
||||||
<div class="api-content">
|
<div class="api-content">
|
||||||
<warnings></warnings>
|
<warnings></warnings>
|
||||||
<api-info></api-info>
|
<api-info></api-info>
|
||||||
<methods-list> </methods-list>
|
<operations-list> </operations-list>
|
||||||
<footer>
|
<footer>
|
||||||
<div class="powered-by-badge">
|
<div class="powered-by-badge">
|
||||||
<a href="https://github.com/Rebilly/ReDoc" title="Swagger-generated API Reference Documentation" target="_blank">
|
<a href="https://github.com/Rebilly/ReDoc" title="Swagger-generated API Reference Documentation" target="_blank">
|
||||||
|
|
|
@ -15,13 +15,29 @@ import { BaseComponent } from '../base';
|
||||||
import * as detectScollParent from 'scrollparent';
|
import * as detectScollParent from 'scrollparent';
|
||||||
|
|
||||||
import { SpecManager } from '../../utils/spec-manager';
|
import { SpecManager } from '../../utils/spec-manager';
|
||||||
import { SearchService, OptionsService, Options, Hash, AppStateService, SchemaHelper } from '../../services/';
|
import {
|
||||||
|
SearchService,
|
||||||
|
OptionsService,
|
||||||
|
Options,
|
||||||
|
Hash,
|
||||||
|
AppStateService,
|
||||||
|
SchemaHelper,
|
||||||
|
MenuService,
|
||||||
|
Marker
|
||||||
|
} from '../../services/';
|
||||||
import { LazyTasksService } from '../../shared/components/LazyFor/lazy-for';
|
import { LazyTasksService } from '../../shared/components/LazyFor/lazy-for';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'redoc',
|
selector: 'redoc',
|
||||||
templateUrl: './redoc.html',
|
templateUrl: './redoc.html',
|
||||||
styleUrls: ['./redoc.css'],
|
styleUrls: ['./redoc.css'],
|
||||||
|
providers: [
|
||||||
|
SpecManager,
|
||||||
|
MenuService,
|
||||||
|
SearchService,
|
||||||
|
LazyTasksService,
|
||||||
|
Marker
|
||||||
|
]
|
||||||
//changeDetection: ChangeDetectionStrategy.OnPush
|
//changeDetection: ChangeDetectionStrategy.OnPush
|
||||||
})
|
})
|
||||||
export class Redoc extends BaseComponent implements OnInit {
|
export class Redoc extends BaseComponent implements OnInit {
|
||||||
|
|
|
@ -16,7 +16,7 @@ import { SpecManager } from '../../utils/spec-manager';
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
|
|
||||||
describe('MethodsList Component', () => {
|
describe('ResponsesList Component', () => {
|
||||||
let builder;
|
let builder;
|
||||||
let component: ResponsesList;
|
let component: ResponsesList;
|
||||||
let fixture: ComponentFixture<ResponsesList>
|
let fixture: ComponentFixture<ResponsesList>
|
||||||
|
|
|
@ -62,7 +62,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
// do not capitalize method summuary in level-1 menu
|
// do not capitalize method summuary in level-1 menu
|
||||||
&.menu-item-for-method > .menu-item-header {
|
&.menu-item-for-operation > .menu-item-header {
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ import {
|
||||||
|
|
||||||
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
import { TestBed, ComponentFixture } from '@angular/core/testing';
|
||||||
|
|
||||||
import { MethodsList, SideMenu } from '../index';
|
import { OperationsList, SideMenu } from '../index';
|
||||||
|
|
||||||
import { SpecManager } from '../../utils/spec-manager';
|
import { SpecManager } from '../../utils/spec-manager';
|
||||||
|
|
||||||
|
@ -19,7 +19,7 @@ let testOptions;
|
||||||
|
|
||||||
describe('Redoc components', () => {
|
describe('Redoc components', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({ declarations: [ TestAppComponent, MethodsList ] });
|
TestBed.configureTestingModule({ declarations: [ TestAppComponent, OperationsList ] });
|
||||||
});
|
});
|
||||||
describe('SideMenu Component', () => {
|
describe('SideMenu Component', () => {
|
||||||
let builder;
|
let builder;
|
||||||
|
@ -90,7 +90,7 @@ describe('Redoc components', () => {
|
||||||
selector: 'test-app',
|
selector: 'test-app',
|
||||||
template:
|
template:
|
||||||
`<side-menu></side-menu>
|
`<side-menu></side-menu>
|
||||||
<methods-list></methods-list>`
|
<operations-list></operations-list>`
|
||||||
})
|
})
|
||||||
class TestAppComponent {
|
class TestAppComponent {
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,15 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import { Component, EventEmitter, Input, Output, ElementRef, ChangeDetectorRef, OnInit, OnDestroy } from '@angular/core';
|
import { Component,
|
||||||
|
EventEmitter,
|
||||||
|
Input,
|
||||||
|
Output,
|
||||||
|
ElementRef,
|
||||||
|
ChangeDetectorRef,
|
||||||
|
OnInit,
|
||||||
|
OnDestroy
|
||||||
|
} from '@angular/core';
|
||||||
|
|
||||||
//import { global } from '@angular/core/src/facade/lang';
|
|
||||||
import { trigger, state, animate, transition, style } from '@angular/core';
|
import { trigger, state, animate, transition, style } from '@angular/core';
|
||||||
import { BaseComponent, SpecManager } from '../base';
|
import { BaseComponent, SpecManager } from '../base';
|
||||||
import { ScrollService, MenuService, OptionsService, MenuItem, Marker} from '../../services/';
|
import { ScrollService, MenuService, OptionsService, MenuItem, Marker} from '../../services/';
|
||||||
|
@ -51,9 +58,15 @@ export class SideMenu extends BaseComponent implements OnInit, OnDestroy {
|
||||||
private $resourcesNav: any;
|
private $resourcesNav: any;
|
||||||
private $scrollParent: any;
|
private $scrollParent: any;
|
||||||
|
|
||||||
constructor(specMgr:SpecManager, elementRef:ElementRef,
|
constructor(
|
||||||
private scrollService:ScrollService, private menuService:MenuService,
|
specMgr:SpecManager,
|
||||||
optionsService:OptionsService, private detectorRef:ChangeDetectorRef, private marker:Marker) {
|
elementRef:ElementRef,
|
||||||
|
private scrollService:ScrollService,
|
||||||
|
private menuService:MenuService,
|
||||||
|
optionsService:OptionsService,
|
||||||
|
private detectorRef:ChangeDetectorRef,
|
||||||
|
private marker:Marker
|
||||||
|
) {
|
||||||
super(specMgr);
|
super(specMgr);
|
||||||
this.$element = elementRef.nativeElement;
|
this.$element = elementRef.nativeElement;
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ import { ResponsesList } from './ResponsesList/responses-list';
|
||||||
import { ResponsesSamples } from './ResponsesSamples/responses-samples';
|
import { ResponsesSamples } from './ResponsesSamples/responses-samples';
|
||||||
import { SchemaSample } from './SchemaSample/schema-sample';
|
import { SchemaSample } from './SchemaSample/schema-sample';
|
||||||
import { SideMenu, SideMenuItems } from './SideMenu/side-menu';
|
import { SideMenu, SideMenuItems } from './SideMenu/side-menu';
|
||||||
import { MethodsList } from './MethodsList/methods-list';
|
import { OperationsList } from './OperationsList/operations-list';
|
||||||
import { Method } from './Method/method';
|
import { Operation } from './Operation/operation';
|
||||||
import { Warnings } from './Warnings/warnings';
|
import { Warnings } from './Warnings/warnings';
|
||||||
import { SecurityDefinitions } from './SecurityDefinitions/security-definitions';
|
import { SecurityDefinitions } from './SecurityDefinitions/security-definitions';
|
||||||
import { LoadingBar } from './LoadingBar/loading-bar';
|
import { LoadingBar } from './LoadingBar/loading-bar';
|
||||||
|
@ -23,10 +23,10 @@ import { Redoc } from './Redoc/redoc';
|
||||||
|
|
||||||
export const REDOC_DIRECTIVES = [
|
export const REDOC_DIRECTIVES = [
|
||||||
ApiInfo, ApiLogo, JsonSchema, JsonSchemaLazy, ParamsList, RequestSamples, ResponsesList,
|
ApiInfo, ApiLogo, JsonSchema, JsonSchemaLazy, ParamsList, RequestSamples, ResponsesList,
|
||||||
ResponsesSamples, SchemaSample, SideMenu, MethodsList, Method, Warnings, Redoc, SecurityDefinitions,
|
ResponsesSamples, SchemaSample, SideMenu, OperationsList, Operation, Warnings, Redoc, SecurityDefinitions,
|
||||||
LoadingBar, SideMenuItems, RedocSearch, ExternalDocs, EndpointLink
|
LoadingBar, SideMenuItems, RedocSearch, ExternalDocs, EndpointLink
|
||||||
];
|
];
|
||||||
|
|
||||||
export { ApiInfo, ApiLogo, JsonSchema, JsonSchemaLazy, ParamsList, RequestSamples, ResponsesList,
|
export { ApiInfo, ApiLogo, JsonSchema, JsonSchemaLazy, ParamsList, RequestSamples, ResponsesList,
|
||||||
ResponsesSamples, SchemaSample, SideMenu, MethodsList, Method, Warnings, Redoc, SecurityDefinitions,
|
ResponsesSamples, SchemaSample, SideMenu, OperationsList, Operation, Warnings, Redoc, SecurityDefinitions,
|
||||||
LoadingBar, SideMenuItems, RedocSearch, ExternalDocs, EndpointLink }
|
LoadingBar, SideMenuItems, ExternalDocs, EndpointLink }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
import { NgModule, ErrorHandler, APP_ID } from '@angular/core';
|
import { NgModule, ErrorHandler, APP_ID } from '@angular/core';
|
||||||
import { CommonModule } from '@angular/common';
|
import { CommonModule } from '@angular/common';
|
||||||
|
|
||||||
import { Redoc, SecurityDefinitions, Method, REDOC_DIRECTIVES } from './components/index';
|
import { Redoc, SecurityDefinitions, Operation, REDOC_DIRECTIVES } from './components/index';
|
||||||
import { REDOC_COMMON_DIRECTIVES, DynamicNg2Wrapper } from './shared/components/index';
|
import { REDOC_COMMON_DIRECTIVES, DynamicNg2Wrapper } from './shared/components/index';
|
||||||
import { REDOC_PIPES } from './utils/pipes';
|
import { REDOC_PIPES } from './utils/pipes';
|
||||||
import { CustomErrorHandler } from './utils/'
|
import { CustomErrorHandler } from './utils/'
|
||||||
|
@ -26,20 +26,15 @@ import { SpecManager } from './utils/spec-manager';
|
||||||
imports: [ CommonModule ],
|
imports: [ CommonModule ],
|
||||||
declarations: [ REDOC_DIRECTIVES, REDOC_COMMON_DIRECTIVES, REDOC_PIPES ],
|
declarations: [ REDOC_DIRECTIVES, REDOC_COMMON_DIRECTIVES, REDOC_PIPES ],
|
||||||
bootstrap: [ Redoc ],
|
bootstrap: [ Redoc ],
|
||||||
entryComponents: [ SecurityDefinitions, DynamicNg2Wrapper, Method ],
|
entryComponents: [ SecurityDefinitions, DynamicNg2Wrapper, Operation ],
|
||||||
providers: [
|
providers: [
|
||||||
SpecManager,
|
|
||||||
ScrollService,
|
ScrollService,
|
||||||
Hash,
|
Hash,
|
||||||
MenuService,
|
|
||||||
WarningsService,
|
WarningsService,
|
||||||
OptionsService,
|
OptionsService,
|
||||||
AppStateService,
|
AppStateService,
|
||||||
ComponentParser,
|
ComponentParser,
|
||||||
ContentProjector,
|
ContentProjector,
|
||||||
SearchService,
|
|
||||||
LazyTasksService,
|
|
||||||
Marker,
|
|
||||||
{ provide: APP_ID, useValue: 'redoc' },
|
{ provide: APP_ID, useValue: 'redoc' },
|
||||||
{ provide: ErrorHandler, useClass: CustomErrorHandler },
|
{ provide: ErrorHandler, useClass: CustomErrorHandler },
|
||||||
{ provide: COMPONENT_PARSER_ALLOWED, useValue: { 'security-definitions': SecurityDefinitions} }
|
{ provide: COMPONENT_PARSER_ALLOWED, useValue: { 'security-definitions': SecurityDefinitions} }
|
||||||
|
|
|
@ -12,7 +12,7 @@ describe('Hash Service', () => {
|
||||||
hashService = _hash;
|
hashService = _hash;
|
||||||
}));
|
}));
|
||||||
|
|
||||||
it('should trigger changed event when method start is called', () => {
|
it('should trigger changed event when method `start` is called', () => {
|
||||||
spyOn(hashService.value, 'next').and.stub();
|
spyOn(hashService.value, 'next').and.stub();
|
||||||
hashService.start();
|
hashService.start();
|
||||||
expect(hashService.value.next).toHaveBeenCalled();
|
expect(hashService.value.next).toHaveBeenCalled();
|
||||||
|
|
|
@ -5,7 +5,7 @@ import {
|
||||||
TestBed
|
TestBed
|
||||||
} from '@angular/core/testing';
|
} from '@angular/core/testing';
|
||||||
|
|
||||||
import { MethodsList } from '../components/MethodsList/methods-list';
|
import { OperationsList } from '../components/OperationsList/operations-list';
|
||||||
import { MenuService, MenuItem } from './menu.service';
|
import { MenuService, MenuItem } from './menu.service';
|
||||||
import { Hash } from './hash.service';
|
import { Hash } from './hash.service';
|
||||||
import { LazyTasksService } from '../shared/components/LazyFor/lazy-for';
|
import { LazyTasksService } from '../shared/components/LazyFor/lazy-for';
|
||||||
|
@ -15,7 +15,7 @@ import { SpecManager } from '../utils/spec-manager';
|
||||||
|
|
||||||
describe('Menu service', () => {
|
describe('Menu service', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
TestBed.configureTestingModule({ declarations: [ TestAppComponent, MethodsList ] });
|
TestBed.configureTestingModule({ declarations: [ TestAppComponent, OperationsList ] });
|
||||||
});
|
});
|
||||||
|
|
||||||
let menu:MenuService, hashService, scroll, tasks;
|
let menu:MenuService, hashService, scroll, tasks;
|
||||||
|
@ -41,7 +41,7 @@ describe('Menu service', () => {
|
||||||
fixture.detectChanges();
|
fixture.detectChanges();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should scroll to method when location hash is present [jp]', (done) => {
|
it('should scroll to operation when location hash is present [jp]', (done) => {
|
||||||
let hash = '#tag/pet/paths/~1pet~1findByStatus/get';
|
let hash = '#tag/pet/paths/~1pet~1findByStatus/get';
|
||||||
spyOn(menu, 'scrollToActive').and.callThrough();
|
spyOn(menu, 'scrollToActive').and.callThrough();
|
||||||
spyOn(window, 'scrollTo').and.stub();
|
spyOn(window, 'scrollTo').and.stub();
|
||||||
|
@ -56,7 +56,7 @@ describe('Menu service', () => {
|
||||||
hashService.value.next(hash);
|
hashService.value.next(hash);
|
||||||
});
|
});
|
||||||
//
|
//
|
||||||
it('should scroll to method when location hash is present [operation]', (done) => {
|
it('should scroll to operation when location hash is present [operation]', (done) => {
|
||||||
let hash = '#operation/getPetById';
|
let hash = '#operation/getPetById';
|
||||||
spyOn(menu, 'scrollToActive').and.callThrough();
|
spyOn(menu, 'scrollToActive').and.callThrough();
|
||||||
spyOn(window, 'scrollTo').and.stub();
|
spyOn(window, 'scrollTo').and.stub();
|
||||||
|
@ -133,7 +133,7 @@ describe('Menu service', () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return Array with correct number of items', () => {
|
it('should return Array with correct number of items', () => {
|
||||||
// 3 - defined tags, 1 - tag3 and 1 method item for method without tag
|
// 3 - defined tags, 1 - tag3 and 1 operation item for operation without tag
|
||||||
items.length.should.be.equal(3 + 1 + 1);
|
items.length.should.be.equal(3 + 1 + 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -144,19 +144,19 @@ describe('Menu service', () => {
|
||||||
item.items[0].name.should.be.equal('test put');
|
item.items[0].name.should.be.equal('test put');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should append method items without tags to the end of list', () => {
|
it('should append operation items without tags to the end of list', () => {
|
||||||
let methodItem = items[4];
|
let operationItem = items[4];
|
||||||
methodItem.name.should.be.equal('test post');
|
operationItem.name.should.be.equal('test post');
|
||||||
methodItem.metadata.type.should.be.equal('method');
|
operationItem.metadata.type.should.be.equal('operation');
|
||||||
should.not.exist(methodItem.items);
|
should.not.exist(operationItem.items);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should map x-traitTag to empty method list', () => {
|
it('should map x-traitTag to empty operation list', () => {
|
||||||
let item = items[0];
|
let item = items[0];
|
||||||
should.not.exist(item.items);
|
should.not.exist(item.items);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('methods for tag should contain valid pointer and name', () => {
|
it('operations for tag should contain valid pointer and name', () => {
|
||||||
for (let item of items) {
|
for (let item of items) {
|
||||||
item.should.be.an.Object();
|
item.should.be.an.Object();
|
||||||
if (item.items) {
|
if (item.items) {
|
||||||
|
@ -186,7 +186,7 @@ describe('Menu service', () => {
|
||||||
template:
|
template:
|
||||||
`<div id='parent' style='height: 500px; overflow:auto'>
|
`<div id='parent' style='height: 500px; overflow:auto'>
|
||||||
<api-info></api-info>
|
<api-info></api-info>
|
||||||
<methods-list></methods-list>
|
<operations-list></operations-list>
|
||||||
</div>`
|
</div>`
|
||||||
})
|
})
|
||||||
class TestAppComponent {
|
class TestAppComponent {
|
||||||
|
|
|
@ -54,7 +54,7 @@ export class MenuService {
|
||||||
private _hashSubscription: Subscription;
|
private _hashSubscription: Subscription;
|
||||||
private _scrollSubscription: Subscription;
|
private _scrollSubscription: Subscription;
|
||||||
private _progressSubscription: Subscription;
|
private _progressSubscription: Subscription;
|
||||||
private _tagsWithMethods: any;
|
private _tagsWithOperations: any;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
private hash:Hash,
|
private hash:Hash,
|
||||||
|
@ -162,7 +162,7 @@ export class MenuService {
|
||||||
while(currentItem) {
|
while(currentItem) {
|
||||||
if (currentItem.id) {
|
if (currentItem.id) {
|
||||||
selector = `[section="${currentItem.id}"] ` + selector;
|
selector = `[section="${currentItem.id}"] ` + selector;
|
||||||
// We only need to go up the chain for methods that
|
// We only need to go up the chain for operations that
|
||||||
// might have multiple tags. For headers/subheaders
|
// might have multiple tags. For headers/subheaders
|
||||||
// we need to siply early terminate.
|
// we need to siply early terminate.
|
||||||
if (!currentItem.metadata) {
|
if (!currentItem.metadata) {
|
||||||
|
@ -254,7 +254,10 @@ export class MenuService {
|
||||||
}
|
}
|
||||||
|
|
||||||
idx = this.flatItems.findIndex(item => item.id === searchId);
|
idx = this.flatItems.findIndex(item => item.id === searchId);
|
||||||
if (idx < 0) this.tryScrollToId(searchId);
|
if (idx < 0) {
|
||||||
|
this.tryScrollToId(searchId);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
} else if (namespace === 'operation') {
|
} else if (namespace === 'operation') {
|
||||||
idx = this.flatItems.findIndex(item => {
|
idx = this.flatItems.findIndex(item => {
|
||||||
return item.metadata && item.metadata.operationId === ptr;
|
return item.metadata && item.metadata.operationId === ptr;
|
||||||
|
@ -304,19 +307,19 @@ export class MenuService {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
getMethodsItems(parent: MenuItem, tag:any):MenuItem[] {
|
getOperationsItems(parent: MenuItem, tag:any):MenuItem[] {
|
||||||
if (!tag.methods || !tag.methods.length) return null;
|
if (!tag.operations || !tag.operations.length) return null;
|
||||||
|
|
||||||
let res = [];
|
let res = [];
|
||||||
for (let method of tag.methods) {
|
for (let operation of tag.operations) {
|
||||||
let subItem = {
|
let subItem = {
|
||||||
name: SchemaHelper.methodSummary(method),
|
name: SchemaHelper.operationSummary(operation),
|
||||||
id: method._pointer,
|
id: operation._pointer,
|
||||||
description: method.description,
|
description: operation.description,
|
||||||
metadata: {
|
metadata: {
|
||||||
type: 'method',
|
type: 'operation',
|
||||||
pointer: method._pointer,
|
pointer: operation._pointer,
|
||||||
operationId: method.operationId
|
operationId: operation.operationId
|
||||||
},
|
},
|
||||||
parent: parent
|
parent: parent
|
||||||
};
|
};
|
||||||
|
@ -331,7 +334,7 @@ export class MenuService {
|
||||||
parentId: string
|
parentId: string
|
||||||
) {
|
) {
|
||||||
if (!id) return null;
|
if (!id) return null;
|
||||||
if (itemMeta && itemMeta.type === 'method') {
|
if (itemMeta && itemMeta.type === 'operation') {
|
||||||
if (itemMeta.operationId) {
|
if (itemMeta.operationId) {
|
||||||
return 'operation/' + encodeURIComponent(itemMeta.operationId);
|
return 'operation/' + encodeURIComponent(itemMeta.operationId);
|
||||||
} else {
|
} else {
|
||||||
|
@ -348,18 +351,18 @@ export class MenuService {
|
||||||
let tags;
|
let tags;
|
||||||
if (!tagGroup) {
|
if (!tagGroup) {
|
||||||
// all tags
|
// all tags
|
||||||
tags = Object.keys(this._tagsWithMethods);
|
tags = Object.keys(this._tagsWithOperations);
|
||||||
} else {
|
} else {
|
||||||
tags = tagGroup.tags;
|
tags = tagGroup.tags;
|
||||||
}
|
}
|
||||||
|
|
||||||
tags = tags.map(k => {
|
tags = tags.map(k => {
|
||||||
if (!this._tagsWithMethods[k]) {
|
if (!this._tagsWithOperations[k]) {
|
||||||
WarningsService.warn(`Non-existing tag "${k}" is added to the group "${tagGroup.name}"`);
|
WarningsService.warn(`Non-existing tag "${k}" is added to the group "${tagGroup.name}"`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
this._tagsWithMethods[k].used = true;
|
this._tagsWithOperations[k].used = true;
|
||||||
return this._tagsWithMethods[k];
|
return this._tagsWithOperations[k];
|
||||||
});
|
});
|
||||||
|
|
||||||
let res = [];
|
let res = [];
|
||||||
|
@ -368,9 +371,9 @@ export class MenuService {
|
||||||
let id = 'tag/' + slugify(tag.name);
|
let id = 'tag/' + slugify(tag.name);
|
||||||
let item: MenuItem;
|
let item: MenuItem;
|
||||||
|
|
||||||
// don't put empty tag into menu, instead put their methods
|
// don't put empty tag into menu, instead put their operations
|
||||||
if (tag.name === '') {
|
if (tag.name === '') {
|
||||||
let items = this.getMethodsItems(null, tag);
|
let items = this.getOperationsItems(null, tag);
|
||||||
res.push(...items);
|
res.push(...items);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -383,7 +386,7 @@ export class MenuService {
|
||||||
parent: parent,
|
parent: parent,
|
||||||
items: null
|
items: null
|
||||||
};
|
};
|
||||||
item.items = this.getMethodsItems(item, tag);
|
item.items = this.getOperationsItems(item, tag);
|
||||||
|
|
||||||
res.push(item);
|
res.push(item);
|
||||||
}
|
}
|
||||||
|
@ -410,15 +413,15 @@ export class MenuService {
|
||||||
}
|
}
|
||||||
|
|
||||||
checkAllTagsUsedInGroups() {
|
checkAllTagsUsedInGroups() {
|
||||||
for (let tag of Object.keys(this._tagsWithMethods)) {
|
for (let tag of Object.keys(this._tagsWithOperations)) {
|
||||||
if (!this._tagsWithMethods[tag].used) {
|
if (!this._tagsWithOperations[tag].used) {
|
||||||
WarningsService.warn(`Tag "${tag}" is not added to any group`);
|
WarningsService.warn(`Tag "${tag}" is not added to any group`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
buildMenu() {
|
buildMenu() {
|
||||||
this._tagsWithMethods = SchemaHelper.getTagsWithMethods(this.specMgr.schema);
|
this._tagsWithOperations = SchemaHelper.getTagsWithOperations(this.specMgr.schema);
|
||||||
|
|
||||||
this.items = this.items || [];
|
this.items = this.items || [];
|
||||||
this.addMarkdownItems();
|
this.addMarkdownItems();
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
import { JsonPointer } from '../utils/JsonPointer';
|
import { JsonPointer } from '../utils/JsonPointer';
|
||||||
import { methods as swaggerMethods, keywordTypes } from '../utils/swagger-defs';
|
import { operations as swaggerOperations, keywordTypes } from '../utils/swagger-defs';
|
||||||
import { WarningsService } from './warnings.service';
|
import { WarningsService } from './warnings.service';
|
||||||
import * as slugify from 'slugify';
|
import * as slugify from 'slugify';
|
||||||
|
|
||||||
|
@ -273,9 +273,9 @@ export class SchemaHelper {
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static methodSummary(method) {
|
static operationSummary(operation) {
|
||||||
return method.summary || method.operationId ||
|
return operation.summary || operation.operationId ||
|
||||||
(method.description && method.description.substring(0, 50)) || '<no description>';
|
(operation.description && operation.description.substring(0, 50)) || '<no description>';
|
||||||
}
|
}
|
||||||
|
|
||||||
static detectType(schema) {
|
static detectType(schema) {
|
||||||
|
@ -290,26 +290,26 @@ export class SchemaHelper {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static getTagsWithMethods(schema) {
|
static getTagsWithOperations(schema) {
|
||||||
let tags = {};
|
let tags = {};
|
||||||
for (let tag of schema.tags || []) {
|
for (let tag of schema.tags || []) {
|
||||||
tags[tag.name] = tag;
|
tags[tag.name] = tag;
|
||||||
tag.methods = [];
|
tag.operations = [];
|
||||||
}
|
}
|
||||||
|
|
||||||
let paths = schema.paths;
|
let paths = schema.paths;
|
||||||
for (let path of Object.keys(paths)) {
|
for (let path of Object.keys(paths)) {
|
||||||
let methods = Object.keys(paths[path]).filter((k) => swaggerMethods.has(k));
|
let operations = Object.keys(paths[path]).filter((k) => swaggerOperations.has(k));
|
||||||
for (let method of methods) {
|
for (let operation of operations) {
|
||||||
let methodInfo = paths[path][method];
|
let operationInfo = paths[path][operation];
|
||||||
let methodTags = methodInfo.tags;
|
let operationTags = operationInfo.tags;
|
||||||
|
|
||||||
// empty tag
|
// empty tag
|
||||||
if (!(methodTags && methodTags.length)) {
|
if (!(operationTags && operationTags.length)) {
|
||||||
methodTags = [''];
|
operationTags = [''];
|
||||||
}
|
}
|
||||||
let methodPointer = JsonPointer.compile(['paths', path, method]);
|
let operationPointer = JsonPointer.compile(['paths', path, operation]);
|
||||||
for (let tagName of methodTags) {
|
for (let tagName of operationTags) {
|
||||||
let tag = tags[tagName];
|
let tag = tags[tagName];
|
||||||
if (!tag) {
|
if (!tag) {
|
||||||
tag = {
|
tag = {
|
||||||
|
@ -318,9 +318,9 @@ export class SchemaHelper {
|
||||||
tags[tagName] = tag;
|
tags[tagName] = tag;
|
||||||
}
|
}
|
||||||
if (tag['x-traitTag']) continue;
|
if (tag['x-traitTag']) continue;
|
||||||
if (!tag.methods) tag.methods = [];
|
if (!tag.operations) tag.operations = [];
|
||||||
tag.methods.push(methodInfo);
|
tag.operations.push(operationInfo);
|
||||||
methodInfo._pointer = methodPointer;
|
operationInfo._pointer = operationPointer;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
|
||||||
import { AppStateService } from './app-state.service';
|
import { AppStateService } from './app-state.service';
|
||||||
import { SchemaNormalizer } from './schema-normalizer.service';
|
import { SchemaNormalizer } from './schema-normalizer.service';
|
||||||
import { JsonPointer, groupBy, SpecManager, StringMap, snapshot, MarkdownHeading } from '../utils/';
|
import { JsonPointer, groupBy, SpecManager, StringMap, snapshot, MarkdownHeading } from '../utils/';
|
||||||
import { methods as swaggerMethods } from '../utils/swagger-defs';
|
import { operations as swaggerOperations } from '../utils/swagger-defs';
|
||||||
import * as slugify from 'slugify';
|
import * as slugify from 'slugify';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
@ -102,7 +102,7 @@ export class SearchService {
|
||||||
Object.keys(paths).forEach(path => {
|
Object.keys(paths).forEach(path => {
|
||||||
let opearations = paths[path];
|
let opearations = paths[path];
|
||||||
Object.keys(opearations).forEach(verb => {
|
Object.keys(opearations).forEach(verb => {
|
||||||
if (!swaggerMethods.has(verb)) return;
|
if (!swaggerOperations.has(verb)) return;
|
||||||
const opearation = opearations[verb];
|
const opearation = opearations[verb];
|
||||||
const ptr = JsonPointer.join(basePtr, [path, verb]);
|
const ptr = JsonPointer.join(basePtr, [path, verb]);
|
||||||
|
|
||||||
|
@ -123,7 +123,7 @@ export class SearchService {
|
||||||
}
|
}
|
||||||
|
|
||||||
indexOperationParameters(operation: SwaggerOperation, operationPointer: string) {
|
indexOperationParameters(operation: SwaggerOperation, operationPointer: string) {
|
||||||
const parameters = this.spec.getMethodParams(operationPointer);
|
const parameters = this.spec.getOperationParams(operationPointer);
|
||||||
if (!parameters) return;
|
if (!parameters) return;
|
||||||
for (let i=0; i<parameters.length; ++i) {
|
for (let i=0; i<parameters.length; ++i) {
|
||||||
const param = parameters[i];
|
const param = parameters[i];
|
||||||
|
|
|
@ -32,7 +32,6 @@ $headers-font: Montserrat;
|
||||||
$headers-font-family: sans-serif;
|
$headers-font-family: sans-serif;
|
||||||
$headers-font-weight: $regular;
|
$headers-font-weight: $regular;
|
||||||
$headers-color: $primary-color;
|
$headers-color: $primary-color;
|
||||||
$method-headers-color: $primary-color;
|
|
||||||
$h1: 1.85714285714286em;
|
$h1: 1.85714285714286em;
|
||||||
$h2: 1.5714285714285714em;
|
$h2: 1.5714285714285714em;
|
||||||
$h3: 1.2857142857142858em;
|
$h3: 1.2857142857142858em;
|
||||||
|
|
|
@ -130,7 +130,7 @@ export class SpecManager {
|
||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
getMethodParams(methodPtr:string):SwaggerParameter[] {
|
getOperationParams(operationPtr:string):SwaggerParameter[] {
|
||||||
/* inject JsonPointer into array elements */
|
/* inject JsonPointer into array elements */
|
||||||
function injectPointers(array:SwaggerParameter[], root) {
|
function injectPointers(array:SwaggerParameter[], root) {
|
||||||
if (!Array.isArray(array)) {
|
if (!Array.isArray(array)) {
|
||||||
|
@ -143,23 +143,23 @@ export class SpecManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
// accept pointer directly to parameters as well
|
// accept pointer directly to parameters as well
|
||||||
if (JsonPointer.baseName(methodPtr) === 'parameters') {
|
if (JsonPointer.baseName(operationPtr) === 'parameters') {
|
||||||
methodPtr = JsonPointer.dirName(methodPtr);
|
operationPtr = JsonPointer.dirName(operationPtr);
|
||||||
}
|
}
|
||||||
|
|
||||||
//get path params
|
//get path params
|
||||||
let pathParamsPtr = JsonPointer.join(JsonPointer.dirName(methodPtr), ['parameters']);
|
let pathParamsPtr = JsonPointer.join(JsonPointer.dirName(operationPtr), ['parameters']);
|
||||||
let pathParams:SwaggerParameter[] = this.byPointer(pathParamsPtr) || [];
|
let pathParams:SwaggerParameter[] = this.byPointer(pathParamsPtr) || [];
|
||||||
|
|
||||||
let methodParamsPtr = JsonPointer.join(methodPtr, ['parameters']);
|
let operationParamsPtr = JsonPointer.join(operationPtr, ['parameters']);
|
||||||
let methodParams:SwaggerParameter[] = this.byPointer(methodParamsPtr) || [];
|
let operationParams:SwaggerParameter[] = this.byPointer(operationParamsPtr) || [];
|
||||||
pathParams = injectPointers(pathParams, pathParamsPtr);
|
pathParams = injectPointers(pathParams, pathParamsPtr);
|
||||||
methodParams = injectPointers(methodParams, methodParamsPtr);
|
operationParams = injectPointers(operationParams, operationParamsPtr);
|
||||||
|
|
||||||
// resolve references
|
// resolve references
|
||||||
methodParams = this.resolveRefs(methodParams);
|
operationParams = this.resolveRefs(operationParams);
|
||||||
pathParams = this.resolveRefs(pathParams);
|
pathParams = this.resolveRefs(pathParams);
|
||||||
return methodParams.concat(pathParams);
|
return operationParams.concat(pathParams);
|
||||||
}
|
}
|
||||||
|
|
||||||
getTagsMap() {
|
getTagsMap() {
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
export const methods = new Set(['get', 'put', 'post', 'delete', 'options', 'head', 'patch']);
|
export const operations = new Set(['get', 'put', 'post', 'delete', 'options', 'head', 'patch']);
|
||||||
|
|
||||||
export const keywordTypes = {
|
export const keywordTypes = {
|
||||||
multipleOf: 'number',
|
multipleOf: 'number',
|
||||||
|
|
|
@ -35,8 +35,8 @@ function basicTests(swaggerUrl, title) {
|
||||||
let $redoc = $('redoc');
|
let $redoc = $('redoc');
|
||||||
expect($redoc.isPresent()).toBe(true);
|
expect($redoc.isPresent()).toBe(true);
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
let $methods = $$('method');
|
let $operations = $$('operation');
|
||||||
expect($methods.count()).toBeGreaterThan(0);
|
expect($operations.count()).toBeGreaterThan(0);
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -26,7 +26,7 @@
|
||||||
"summary": "test get",
|
"summary": "test get",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"name": "methodParam",
|
"name": "operationParam",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@
|
||||||
"summary": "test get",
|
"summary": "test get",
|
||||||
"parameters": [
|
"parameters": [
|
||||||
{
|
{
|
||||||
"name": "methodParam",
|
"name": "operationParam",
|
||||||
"in": "path",
|
"in": "path",
|
||||||
"type": "string"
|
"type": "string"
|
||||||
}
|
}
|
|
@ -104,47 +104,47 @@ describe('Utils', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getMethodParams method', () => {
|
describe('getOperationParams method', () => {
|
||||||
beforeEach((done:any) => {
|
beforeEach((done:any) => {
|
||||||
specMgr.load('/tests/schemas/schema-mgr-methodparams.json').then(done, done.fail);
|
specMgr.load('/tests/schemas/schema-mgr-operationParams.json').then(done, done.fail);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should propagate path parameters', () => {
|
it('should propagate path parameters', () => {
|
||||||
let params = specMgr.getMethodParams('/paths/test1/get');
|
let params = specMgr.getOperationParams('/paths/test1/get');
|
||||||
params.length.should.be.equal(2);
|
params.length.should.be.equal(2);
|
||||||
params[0].name.should.be.equal('methodParam');
|
params[0].name.should.be.equal('operationParam');
|
||||||
params[1].name.should.be.equal('pathParam');
|
params[1].name.should.be.equal('pathParam');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should inject correct pointers', () => {
|
it('should inject correct pointers', () => {
|
||||||
let params = specMgr.getMethodParams('/paths/test1/get');
|
let params = specMgr.getOperationParams('/paths/test1/get');
|
||||||
params[0]._pointer.should.be.equal('/paths/test1/get/parameters/0');
|
params[0]._pointer.should.be.equal('/paths/test1/get/parameters/0');
|
||||||
params[1]._pointer.should.be.equal('/paths/test1/parameters/0');
|
params[1]._pointer.should.be.equal('/paths/test1/parameters/0');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should accept pointer directly to parameters', () => {
|
it('should accept pointer directly to parameters', () => {
|
||||||
let params = specMgr.getMethodParams('/paths/test1/get/parameters');
|
let params = specMgr.getOperationParams('/paths/test1/get/parameters');
|
||||||
expect(params).not.toBeNull();
|
expect(params).not.toBeNull();
|
||||||
params.length.should.be.equal(2);
|
params.length.should.be.equal(2);
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should resolve path params from Parameters Definitions Object', () => {
|
it('should resolve path params from Parameters Definitions Object', () => {
|
||||||
let params = specMgr.getMethodParams('/paths/test2/get');
|
let params = specMgr.getOperationParams('/paths/test2/get');
|
||||||
params.length.should.be.equal(2);
|
params.length.should.be.equal(2);
|
||||||
params[0].name.should.be.equal('methodParam');
|
params[0].name.should.be.equal('operationParam');
|
||||||
params[1].name.should.be.equal('extParam');
|
params[1].name.should.be.equal('extParam');
|
||||||
params[1]._pointer.should.be.equal('#/parameters/extparam');
|
params[1]._pointer.should.be.equal('#/parameters/extparam');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should resolve method params from Parameters Definitions Object', () => {
|
it('should resolve operation params from Parameters Definitions Object', () => {
|
||||||
let params = specMgr.getMethodParams('/paths/test3/get');
|
let params = specMgr.getOperationParams('/paths/test3/get');
|
||||||
params.length.should.be.equal(1);
|
params.length.should.be.equal(1);
|
||||||
params[0].name.should.be.equal('extParam');
|
params[0].name.should.be.equal('extParam');
|
||||||
params[0]._pointer.should.be.equal('#/parameters/extparam');
|
params[0]._pointer.should.be.equal('#/parameters/extparam');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should throw for parameters other than array', () => {
|
it('should throw for parameters other than array', () => {
|
||||||
let func = () => specMgr.getMethodParams('/paths/test4/get');
|
let func = () => specMgr.getOperationParams('/paths/test4/get');
|
||||||
expect(func).toThrow();
|
expect(func).toThrow();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue
Block a user