mirror of
https://github.com/Redocly/redoc.git
synced 2024-11-28 03:23:44 +03:00
Merge commit '3d1108f447d306a7ce833299a086a4bd0dd00732' into releases
This commit is contained in:
commit
5354618c97
16
CHANGELOG.md
16
CHANGELOG.md
|
@ -1,3 +1,19 @@
|
||||||
|
<a name="1.16.0"></a>
|
||||||
|
# [1.16.0](https://github.com/Rebilly/ReDoc/compare/v1.15.0...v1.16.0) (2017-05-12)
|
||||||
|
|
||||||
|
|
||||||
|
### Bug Fixes
|
||||||
|
|
||||||
|
* do not show discriminator dropdown if it is empty ([7a5d315](https://github.com/Rebilly/ReDoc/commit/7a5d315))
|
||||||
|
* prevent possible XSS using `untrusted-spec` option ([c0698bb](https://github.com/Rebilly/ReDoc/commit/c0698bb))
|
||||||
|
* URL changes so fast ([131b437](https://github.com/Rebilly/ReDoc/commit/131b437)), closes [#252](https://github.com/Rebilly/ReDoc/issues/252)
|
||||||
|
|
||||||
|
|
||||||
|
### Features
|
||||||
|
|
||||||
|
* display xml examples if present in response examples ([cb106cc](https://github.com/Rebilly/ReDoc/commit/cb106cc))
|
||||||
|
|
||||||
|
|
||||||
<a name="1.15.0"></a>
|
<a name="1.15.0"></a>
|
||||||
# [1.15.0](https://github.com/Rebilly/ReDoc/compare/v1.14.0...v1.15.0) (2017-05-05)
|
# [1.15.0](https://github.com/Rebilly/ReDoc/compare/v1.14.0...v1.15.0) (2017-05-05)
|
||||||
|
|
||||||
|
|
|
@ -82,6 +82,8 @@ We host the latest and all the previous ReDoc releases on GitHub Pages-based **C
|
||||||
```
|
```
|
||||||
That's all folks!
|
That's all folks!
|
||||||
|
|
||||||
|
**IMPORTANT NOTE:** if you work with untrusted user spec, use `untrusted-spec` [option](#redoc-tag-attributes) to prevent XSS security risks.
|
||||||
|
|
||||||
### 1. Install ReDoc (skip this step for CDN)
|
### 1. Install ReDoc (skip this step for CDN)
|
||||||
Install using [bower](bower.io):
|
Install using [bower](bower.io):
|
||||||
|
|
||||||
|
@ -131,6 +133,7 @@ ReDoc makes use of the following [vendor extensions](http://swagger.io/specifica
|
||||||
|
|
||||||
### `<redoc>` tag attributes
|
### `<redoc>` tag attributes
|
||||||
* `spec-url` - relative or absolute url to your spec file;
|
* `spec-url` - relative or absolute url to your spec file;
|
||||||
|
* `untrusted-spec` - if set, the spec is considered untrusted and all HTML/markdown is sanitized to prevent XSS. **Disabled by default** for performance reasons. **Enable this option if you work with untrusted user data!**
|
||||||
* `scroll-y-offset` - If set, specifies a vertical scroll-offset. This is often useful when there are fixed positioned elements at the top of the page, such as navbars, headers etc;
|
* `scroll-y-offset` - If set, specifies a vertical scroll-offset. This is often useful when there are fixed positioned elements at the top of the page, such as navbars, headers etc;
|
||||||
`scroll-y-offset` can be specified in various ways:
|
`scroll-y-offset` can be specified in various ways:
|
||||||
* **number**: A fixed number of pixels to be used as offset;
|
* **number**: A fixed number of pixels to be used as offset;
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
frameborder="0" scrolling="0" width="130px" height="30px"></iframe>
|
frameborder="0" scrolling="0" width="130px" height="30px"></iframe>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<redoc scroll-y-offset="body > nav" spec-url='swagger.yaml' lazy-rendering></redoc>
|
<redoc scroll-y-offset="body > nav" spec-url='swagger.yaml' lazy-rendering untrusted-spec></redoc>
|
||||||
|
|
||||||
<script src="main.js"> </script>
|
<script src="main.js"> </script>
|
||||||
<script src="./dist/redoc.min.js"> </script>
|
<script src="./dist/redoc.min.js"> </script>
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
frameborder="0" scrolling="0" width="130px" height="30px"></iframe>
|
frameborder="0" scrolling="0" width="130px" height="30px"></iframe>
|
||||||
</nav>
|
</nav>
|
||||||
|
|
||||||
<redoc scroll-y-offset="body > nav" spec-url='swagger.yaml' lazy-rendering></redoc>
|
<redoc scroll-y-offset="body > nav" spec-url='swagger.yaml' lazy-rendering untrusted-spec></redoc>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
window.__REDOC_DEV__ = true;
|
window.__REDOC_DEV__ = true;
|
||||||
|
|
|
@ -617,6 +617,7 @@ paths:
|
||||||
type: string
|
type: string
|
||||||
examples:
|
examples:
|
||||||
application/json: OK
|
application/json: OK
|
||||||
|
application/xml: <message> OK </message>
|
||||||
headers:
|
headers:
|
||||||
X-Rate-Limit:
|
X-Rate-Limit:
|
||||||
type: integer
|
type: integer
|
||||||
|
|
|
@ -83,7 +83,7 @@
|
||||||
<span *ngIf="prop.pattern" class="param-pattern">{{prop.pattern}}</span>
|
<span *ngIf="prop.pattern" class="param-pattern">{{prop.pattern}}</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="param-description" [innerHtml]="prop.description | marked"></div>
|
<div class="param-description" [innerHtml]="prop.description | marked"></div>
|
||||||
<div class="discriminator-info" *ngIf="prop.isDiscriminator">
|
<div class="discriminator-info" *ngIf="prop.isDiscriminator && descendants.length">
|
||||||
<drop-down (change)="selectDescendantByIdx($event)" [active]="activeDescendant.idx">
|
<drop-down (change)="selectDescendantByIdx($event)" [active]="activeDescendant.idx">
|
||||||
<option *ngFor="let descendant of descendants; let i=index"
|
<option *ngFor="let descendant of descendants; let i=index"
|
||||||
[value]="i" [attr.selected]="descendant.active ? '' : null" >{{descendant.name}}</option>
|
[value]="i" [attr.selected]="descendant.active ? '' : null" >{{descendant.name}}</option>
|
||||||
|
|
|
@ -64,7 +64,7 @@ header {
|
||||||
}
|
}
|
||||||
|
|
||||||
:host /deep/ tabs ul {
|
:host /deep/ tabs ul {
|
||||||
padding-top: 10px;
|
padding-top: 10px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.code-sample pre {
|
.code-sample pre {
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
|
||||||
import { BaseComponent, SpecManager } from '../base';
|
import { BaseComponent, SpecManager } from '../base';
|
||||||
import JsonPointer from '../../utils/JsonPointer';
|
import JsonPointer from '../../utils/JsonPointer';
|
||||||
import { statusCodeType, getJsonLike } from '../../utils/helpers';
|
import { statusCodeType, getJsonLikeSample } from '../../utils/helpers';
|
||||||
|
|
||||||
|
|
||||||
function isNumeric(n) {
|
function isNumeric(n) {
|
||||||
|
@ -11,7 +11,7 @@ function isNumeric(n) {
|
||||||
}
|
}
|
||||||
|
|
||||||
function hasExample(response) {
|
function hasExample(response) {
|
||||||
return ((response.examples && getJsonLike(response.examples)) ||
|
return ((response.examples && getJsonLikeSample(response.examples)) ||
|
||||||
response.schema);
|
response.schema);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,26 @@
|
||||||
<div class="snippet">
|
<ng-template #jsonSnippet>
|
||||||
<!-- in case sample is not available for some reason -->
|
<div class="snippet">
|
||||||
<pre *ngIf="sample == undefined"> Sample unavailable </pre>
|
<!-- in case sample is not available for some reason -->
|
||||||
<div class="action-buttons">
|
<pre *ngIf="sample == undefined"> Sample unavailable </pre>
|
||||||
<span copy-button [copyText]="sample" class="hint--top-left hint--inversed"> <a>Copy</a> </span>
|
<div class="action-buttons">
|
||||||
<span> <a *ngIf="enableButtons" (click)="expandAll()">Expand all</a> </span>
|
<span copy-button [copyText]="sample" class="hint--top-left hint--inversed"> <a>Copy</a> </span>
|
||||||
<span> <a *ngIf="enableButtons" (click)="collapseAll()">Collapse all</a> </span>
|
<span> <a *ngIf="enableButtons" (click)="expandAll()">Expand all</a> </span>
|
||||||
|
<span> <a *ngIf="enableButtons" (click)="collapseAll()">Collapse all</a> </span>
|
||||||
|
</div>
|
||||||
|
<pre [innerHtml]="sample | jsonFormatter"></pre>
|
||||||
</div>
|
</div>
|
||||||
<pre [innerHtml]="sample | jsonFormatter"></pre>
|
</ng-template>
|
||||||
</div>
|
|
||||||
|
<tabs *ngIf="xmlSample; else jsonSnippet">
|
||||||
|
<tab tabTitle="JSON">
|
||||||
|
<ng-container *ngTemplateOutlet="jsonSnippet"></ng-container>
|
||||||
|
</tab>
|
||||||
|
<tab tabTitle="XML" *ngIf="xmlSample">
|
||||||
|
<div class="snippet">
|
||||||
|
<div class="action-buttons">
|
||||||
|
<span copy-button [copyText]="xmlSample" class="hint--top-left hint--inversed"> <a>Copy</a> </span>
|
||||||
|
</div>
|
||||||
|
<pre class="xml-sample" [innerHtml]="xmlSample | prism:'xml'"></pre>
|
||||||
|
</div>
|
||||||
|
</tab>
|
||||||
|
</tabs>
|
||||||
|
|
|
@ -4,6 +4,34 @@
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* tabs */
|
||||||
|
|
||||||
|
:host /deep/ tabs {
|
||||||
|
margin-top: 1em;
|
||||||
|
> ul {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
|
||||||
|
> li {
|
||||||
|
padding: 2px 10px;
|
||||||
|
display: inline-block;
|
||||||
|
background: #131a1d;
|
||||||
|
border-bottom: 1px solid trasparent;
|
||||||
|
color: $sample-panel-headers-color;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
color: white;
|
||||||
|
border-bottom: 1px solid $sample-panel-headers-color;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.action-buttons {
|
||||||
|
margin-top: -2em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pre {
|
pre {
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
@ -99,7 +127,7 @@ pre {
|
||||||
padding-left: 6px;
|
padding-left: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.redoc-json {
|
.redoc-json, .xml-sample {
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border-radius: $border-radius*2;
|
border-radius: $border-radius*2;
|
||||||
|
|
|
@ -6,7 +6,7 @@ import * as OpenAPISampler from 'openapi-sampler';
|
||||||
import JsonPointer from '../../utils/JsonPointer';
|
import JsonPointer from '../../utils/JsonPointer';
|
||||||
import { BaseComponent, SpecManager } from '../base';
|
import { BaseComponent, SpecManager } from '../base';
|
||||||
import { SchemaNormalizer } from '../../services/schema-normalizer.service';
|
import { SchemaNormalizer } from '../../services/schema-normalizer.service';
|
||||||
import { getJsonLike } from '../../utils/helpers';
|
import { getJsonLikeSample, getXmlLikeSample} from '../../utils/helpers';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'schema-sample',
|
selector: 'schema-sample',
|
||||||
|
@ -20,6 +20,7 @@ export class SchemaSample extends BaseComponent implements OnInit {
|
||||||
|
|
||||||
element: any;
|
element: any;
|
||||||
sample: any;
|
sample: any;
|
||||||
|
xmlSample: string;
|
||||||
enableButtons: boolean = false;
|
enableButtons: boolean = false;
|
||||||
|
|
||||||
private _normalizer:SchemaNormalizer;
|
private _normalizer:SchemaNormalizer;
|
||||||
|
@ -34,7 +35,7 @@ export class SchemaSample extends BaseComponent implements OnInit {
|
||||||
this.bindEvents();
|
this.bindEvents();
|
||||||
|
|
||||||
let base:any = this.componentSchema;
|
let base:any = this.componentSchema;
|
||||||
let sample;
|
let sample, xmlSample;
|
||||||
|
|
||||||
// got pointer not directly to the schema but e.g. to the response obj
|
// got pointer not directly to the schema but e.g. to the response obj
|
||||||
if (this.componentSchema.schema) {
|
if (this.componentSchema.schema) {
|
||||||
|
@ -50,7 +51,12 @@ export class SchemaSample extends BaseComponent implements OnInit {
|
||||||
base.examples = requestExamples;
|
base.examples = requestExamples;
|
||||||
}
|
}
|
||||||
|
|
||||||
let jsonLikeSample = base.examples && getJsonLike(base.examples);
|
let xmlLikeSample = base.examples && getXmlLikeSample(base.examples);
|
||||||
|
if (xmlLikeSample) {
|
||||||
|
this.xmlSample = xmlLikeSample;
|
||||||
|
}
|
||||||
|
|
||||||
|
let jsonLikeSample = base.examples && getJsonLikeSample(base.examples);
|
||||||
if (jsonLikeSample) {
|
if (jsonLikeSample) {
|
||||||
sample = jsonLikeSample;
|
sample = jsonLikeSample;
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,15 +1,20 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { PlatformLocation } from '@angular/common';
|
import { PlatformLocation } from '@angular/common';
|
||||||
|
|
||||||
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
import { BehaviorSubject } from 'rxjs/BehaviorSubject';
|
||||||
|
|
||||||
|
import { debounce } from '../utils/';
|
||||||
|
|
||||||
@Injectable()
|
@Injectable()
|
||||||
export class Hash {
|
export class Hash {
|
||||||
public value = new BehaviorSubject<string | null>(null);
|
public value = new BehaviorSubject<string | null>(null);
|
||||||
private noEmit:boolean = false;
|
private noEmit:boolean = false;
|
||||||
|
private debouncedUpdate: (hash:string, rewrite: boolean) => void;
|
||||||
|
|
||||||
constructor(private location: PlatformLocation) {
|
constructor(private location: PlatformLocation) {
|
||||||
this.bind();
|
this.bind();
|
||||||
|
|
||||||
|
this.debouncedUpdate = debounce(this._update.bind(this), 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
start() {
|
start() {
|
||||||
|
@ -28,6 +33,10 @@ export class Hash {
|
||||||
}
|
}
|
||||||
|
|
||||||
update(hash: string|null, rewriteHistory:boolean = false) {
|
update(hash: string|null, rewriteHistory:boolean = false) {
|
||||||
|
this.debouncedUpdate(hash, rewriteHistory);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _update(hash: string|null, rewriteHistory:boolean = false) {
|
||||||
if (hash == undefined) return;
|
if (hash == undefined) return;
|
||||||
if (rewriteHistory) {
|
if (rewriteHistory) {
|
||||||
window.history.replaceState(null, '', window.location.href.split('#')[0] + '#' + hash);
|
window.history.replaceState(null, '', window.location.href.split('#')[0] + '#' + hash);
|
||||||
|
@ -39,4 +48,5 @@ export class Hash {
|
||||||
this.noEmit = false;
|
this.noEmit = false;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,6 +19,7 @@ const OPTION_NAMES = new Set([
|
||||||
'requiredPropsFirst',
|
'requiredPropsFirst',
|
||||||
'noAutoAuth',
|
'noAutoAuth',
|
||||||
'pathInMiddlePanel',
|
'pathInMiddlePanel',
|
||||||
|
'untrustedSpec'
|
||||||
]);
|
]);
|
||||||
|
|
||||||
export interface Options {
|
export interface Options {
|
||||||
|
@ -33,6 +34,7 @@ export interface Options {
|
||||||
requiredPropsFirst?: boolean;
|
requiredPropsFirst?: boolean;
|
||||||
noAutoAuth?: boolean;
|
noAutoAuth?: boolean;
|
||||||
pathInMiddlePanel?: boolean;
|
pathInMiddlePanel?: boolean;
|
||||||
|
untrustedSpec?: boolean;
|
||||||
spec?: any;
|
spec?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,6 +103,7 @@ export class OptionsService {
|
||||||
if (isString(this._options.requiredPropsFirst)) this._options.requiredPropsFirst = true;
|
if (isString(this._options.requiredPropsFirst)) this._options.requiredPropsFirst = true;
|
||||||
if (isString(this._options.noAutoAuth)) this._options.noAutoAuth = true;
|
if (isString(this._options.noAutoAuth)) this._options.noAutoAuth = true;
|
||||||
if (isString(this._options.pathInMiddlePanel)) this._options.pathInMiddlePanel = true;
|
if (isString(this._options.pathInMiddlePanel)) this._options.pathInMiddlePanel = true;
|
||||||
|
if (isString(this._options.untrustedSpec)) this._options.untrustedSpec = true;
|
||||||
if (isString(this._options.expandResponses)) {
|
if (isString(this._options.expandResponses)) {
|
||||||
let str = this._options.expandResponses as string;
|
let str = this._options.expandResponses as string;
|
||||||
if (str === 'all') return;
|
if (str === 'all') return;
|
||||||
|
|
|
@ -99,6 +99,21 @@ export function throttle(fn, threshhold, scope) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function debounce(func, wait, immediate = false) {
|
||||||
|
var timeout;
|
||||||
|
return function() {
|
||||||
|
var context = this, args = arguments;
|
||||||
|
var later = function() {
|
||||||
|
timeout = null;
|
||||||
|
if (!immediate) func.apply(context, args);
|
||||||
|
};
|
||||||
|
var callNow = immediate && !timeout;
|
||||||
|
clearTimeout(timeout);
|
||||||
|
timeout = setTimeout(later, wait);
|
||||||
|
if (callNow) func.apply(context, args);
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export const isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0
|
export const isSafari = Object.prototype.toString.call(window.HTMLElement).indexOf('Constructor') > 0
|
||||||
|| (function (p) { return p.toString() === '[object SafariRemoteNotification]'; })(!window['safari']
|
|| (function (p) { return p.toString() === '[object SafariRemoteNotification]'; })(!window['safari']
|
||||||
|| safari.pushNotification);
|
|| safari.pushNotification);
|
||||||
|
@ -123,12 +138,26 @@ export function isJsonLike(contentType: string): boolean {
|
||||||
return contentType.search(/json/i) !== -1;
|
return contentType.search(/json/i) !== -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getJsonLike(object: Object) {
|
export function isXmlLike(contentType: string): boolean {
|
||||||
const jsonLikeKeys = Object.keys(object).filter(isJsonLike);
|
return contentType.search(/xml/i) !== -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getJsonLikeSample(samples: Object) {
|
||||||
|
const jsonLikeKeys = Object.keys(samples).filter(isJsonLike);
|
||||||
|
|
||||||
if (!jsonLikeKeys.length) {
|
if (!jsonLikeKeys.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return object[jsonLikeKeys.shift()];
|
return samples[jsonLikeKeys[0]];
|
||||||
|
}
|
||||||
|
|
||||||
|
export function getXmlLikeSample(samples: Object) {
|
||||||
|
const xmlLikeKeys = Object.keys(samples).filter(isXmlLike);
|
||||||
|
|
||||||
|
if (!xmlLikeKeys.length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return samples[xmlLikeKeys[0]];
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,6 +6,7 @@ import { isString, stringify, isBlank } from './helpers';
|
||||||
import JsonPointer from './JsonPointer';
|
import JsonPointer from './JsonPointer';
|
||||||
import { MdRenderer } from './';
|
import { MdRenderer } from './';
|
||||||
import { JsonFormatter } from './JsonFormatterPipe';
|
import { JsonFormatter } from './JsonFormatterPipe';
|
||||||
|
import { OptionsService } from '../services/options.service';
|
||||||
|
|
||||||
declare var Prism: any;
|
declare var Prism: any;
|
||||||
|
|
||||||
|
@ -48,18 +49,19 @@ export class JsonPointerEscapePipe implements PipeTransform {
|
||||||
@Pipe({ name: 'marked' })
|
@Pipe({ name: 'marked' })
|
||||||
export class MarkedPipe implements PipeTransform {
|
export class MarkedPipe implements PipeTransform {
|
||||||
renderer: MdRenderer;
|
renderer: MdRenderer;
|
||||||
constructor(private sanitizer: DomSanitizer) {
|
unstrustedSpec: boolean;
|
||||||
|
|
||||||
|
constructor(private sanitizer: DomSanitizer, optionsService: OptionsService) {
|
||||||
this.renderer = new MdRenderer(true);
|
this.renderer = new MdRenderer(true);
|
||||||
|
this.unstrustedSpec = !!optionsService.options.untrustedSpec;
|
||||||
}
|
}
|
||||||
transform(value:string) {
|
transform(value:string) {
|
||||||
if (isBlank(value)) return value;
|
if (isBlank(value)) return value;
|
||||||
if (!isString(value)) {
|
if (!isString(value)) {
|
||||||
throw new InvalidPipeArgumentException(JsonPointerEscapePipe, value);
|
throw new InvalidPipeArgumentException(JsonPointerEscapePipe, value);
|
||||||
}
|
}
|
||||||
|
let res = `<span class="redoc-markdown-block">${this.renderer.renderMd(value)}</span>`;
|
||||||
return this.sanitizer.bypassSecurityTrustHtml(
|
return this.unstrustedSpec ? res : this.sanitizer.bypassSecurityTrustHtml(res);
|
||||||
`<span class="redoc-markdown-block">${this.renderer.renderMd(value)}</span>`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ import 'prismjs/components/prism-bash.js';
|
||||||
import 'prismjs/components/prism-swift.js';
|
import 'prismjs/components/prism-swift.js';
|
||||||
import 'prismjs/components/prism-objectivec.js';
|
import 'prismjs/components/prism-objectivec.js';
|
||||||
import 'prismjs/components/prism-scala.js';
|
import 'prismjs/components/prism-scala.js';
|
||||||
|
import 'prismjs/components/prism-markup.js'; // xml
|
||||||
|
|
||||||
import 'dropkickjs/build/css/dropkick.css';
|
import 'dropkickjs/build/css/dropkick.css';
|
||||||
import 'prismjs/themes/prism-dark.css';
|
import 'prismjs/themes/prism-dark.css';
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"name": "redoc",
|
"name": "redoc",
|
||||||
"description": "Swagger-generated API Reference Documentation",
|
"description": "Swagger-generated API Reference Documentation",
|
||||||
"version": "1.15.0",
|
"version": "1.16.0",
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
"url": "git://github.com/Rebilly/ReDoc"
|
"url": "git://github.com/Rebilly/ReDoc"
|
||||||
|
@ -69,7 +69,6 @@
|
||||||
"codelyzer": "^3.0.1",
|
"codelyzer": "^3.0.1",
|
||||||
"conventional-changelog-cli": "^1.3.1",
|
"conventional-changelog-cli": "^1.3.1",
|
||||||
"core-js": "^2.4.1",
|
"core-js": "^2.4.1",
|
||||||
"coveralls": "^2.13.1",
|
|
||||||
"css-loader": "^0.28.1",
|
"css-loader": "^0.28.1",
|
||||||
"deploy-to-gh-pages": "^1.3.3",
|
"deploy-to-gh-pages": "^1.3.3",
|
||||||
"dropkickjs": "^2.1.10",
|
"dropkickjs": "^2.1.10",
|
||||||
|
@ -101,7 +100,7 @@
|
||||||
"prismjs": "^1.5.1",
|
"prismjs": "^1.5.1",
|
||||||
"protractor": "^5.1.1",
|
"protractor": "^5.1.1",
|
||||||
"raw-loader": "^0.5.1",
|
"raw-loader": "^0.5.1",
|
||||||
"remarkable": "^1.6.2",
|
"remarkable": "1.7.1",
|
||||||
"rimraf": "^2.6.1",
|
"rimraf": "^2.6.1",
|
||||||
"rxjs": "^5.3.1",
|
"rxjs": "^5.3.1",
|
||||||
"sass-loader": "^6.0.3",
|
"sass-loader": "^6.0.3",
|
||||||
|
|
|
@ -1,6 +1,12 @@
|
||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
import {statusCodeType, isJsonLike, getJsonLike } from '../../lib/utils/helpers';
|
import {
|
||||||
|
statusCodeType,
|
||||||
|
isJsonLike,
|
||||||
|
getJsonLikeSample,
|
||||||
|
isXmlLike,
|
||||||
|
getXmlLikeSample
|
||||||
|
} from '../../lib/utils/helpers';
|
||||||
|
|
||||||
describe('Utils', () => {
|
describe('Utils', () => {
|
||||||
describe('statusCodeType', () => {
|
describe('statusCodeType', () => {
|
||||||
|
@ -41,24 +47,45 @@ describe('Utils', () => {
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('getJsonLike', () => {
|
describe('getJsonLikeSample', () => {
|
||||||
it('Should return a value when a JSON-like key exists', () => {
|
it('Should return a value when a JSON-like key exists', () => {
|
||||||
const examples = {
|
const examples = {
|
||||||
"application/vnd.api+json": {
|
'application/vnd.api+json': {
|
||||||
"message": "Hello World"
|
'message': 'Hello World'
|
||||||
},
|
},
|
||||||
"application/xml": "<message>Hello World</message>"
|
'application/xml': '<message>Hello World</message>'
|
||||||
};
|
};
|
||||||
|
|
||||||
(getJsonLike(examples).message).should.be.equal("Hello World");
|
(getJsonLikeSample(examples).message).should.be.equal('Hello World');
|
||||||
});
|
});
|
||||||
|
|
||||||
it('Should return undefined when no JSON-like key exists', () => {
|
it('Should return undefined when no JSON-like key exists', () => {
|
||||||
const examples = {
|
const examples = {
|
||||||
"application/xml": "<message>Hello World</message>"
|
'application/xml': '<message>Hello World</message>'
|
||||||
};
|
};
|
||||||
|
|
||||||
getJsonLike(examples).should.be.equal(false);
|
getJsonLikeSample(examples).should.be.equal(false);
|
||||||
});
|
});
|
||||||
})
|
});
|
||||||
|
|
||||||
|
describe('getXmlLikeSample', () => {
|
||||||
|
it('Should return a value when a XML-like key exists', () => {
|
||||||
|
const examples = {
|
||||||
|
'application/vnd.api+json': {
|
||||||
|
'message': 'Hello World'
|
||||||
|
},
|
||||||
|
'application/vnd.api+xml': '<message>Hello World</message>'
|
||||||
|
};
|
||||||
|
|
||||||
|
(getXmlLikeSample(examples)).should.be.equal('<message>Hello World</message>');
|
||||||
|
});
|
||||||
|
|
||||||
|
it('Should return undefined when no XML-like key exists', () => {
|
||||||
|
const examples = {
|
||||||
|
'application/json': '<message>Hello World</message>'
|
||||||
|
};
|
||||||
|
|
||||||
|
getXmlLikeSample(examples).should.be.equal(false);
|
||||||
|
});
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
12
yarn.lock
12
yarn.lock
|
@ -1117,16 +1117,6 @@ corser@~2.0.0:
|
||||||
version "2.0.1"
|
version "2.0.1"
|
||||||
resolved "https://registry.yarnpkg.com/corser/-/corser-2.0.1.tgz#8eda252ecaab5840dcd975ceb90d9370c819ff87"
|
resolved "https://registry.yarnpkg.com/corser/-/corser-2.0.1.tgz#8eda252ecaab5840dcd975ceb90d9370c819ff87"
|
||||||
|
|
||||||
coveralls@^2.13.1:
|
|
||||||
version "2.13.1"
|
|
||||||
resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-2.13.1.tgz#d70bb9acc1835ec4f063ff9dac5423c17b11f178"
|
|
||||||
dependencies:
|
|
||||||
js-yaml "3.6.1"
|
|
||||||
lcov-parse "0.0.10"
|
|
||||||
log-driver "1.2.5"
|
|
||||||
minimist "1.2.0"
|
|
||||||
request "2.79.0"
|
|
||||||
|
|
||||||
coveralls@~2.11.2:
|
coveralls@~2.11.2:
|
||||||
version "2.11.16"
|
version "2.11.16"
|
||||||
resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-2.11.16.tgz#da9061265142ddee954f68379122be97be8ab4b1"
|
resolved "https://registry.yarnpkg.com/coveralls/-/coveralls-2.11.16.tgz#da9061265142ddee954f68379122be97be8ab4b1"
|
||||||
|
@ -4228,7 +4218,7 @@ remap-istanbul@0.8.4:
|
||||||
source-map ">=0.5.6"
|
source-map ">=0.5.6"
|
||||||
through2 "2.0.1"
|
through2 "2.0.1"
|
||||||
|
|
||||||
remarkable@^1.6.2:
|
remarkable@1.7.1:
|
||||||
version "1.7.1"
|
version "1.7.1"
|
||||||
resolved "https://registry.yarnpkg.com/remarkable/-/remarkable-1.7.1.tgz#aaca4972100b66a642a63a1021ca4bac1be3bff6"
|
resolved "https://registry.yarnpkg.com/remarkable/-/remarkable-1.7.1.tgz#aaca4972100b66a642a63a1021ca4bac1be3bff6"
|
||||||
dependencies:
|
dependencies:
|
||||||
|
|
Loading…
Reference in New Issue
Block a user