Merge commit 'd1562d5ff13eccee8045bad92e07982d59417efc' into releases

This commit is contained in:
RedocBot 2017-08-02 15:04:46 +00:00 committed by travis@localhost
commit a9a39d3094
47 changed files with 1864 additions and 524 deletions

1
.gitignore vendored
View File

@ -37,3 +37,4 @@ compiled
/coverage
.ghpages-tmp
stats.json
/package-lock.json

View File

@ -25,13 +25,8 @@ addons:
sauce_connect: true
cache: yarn
before_install: if [[ `npm -v` != 3* ]]; then npm i -g npm@3; fi
before_script:
- npm run e2e-server > /dev/null & # kill e2e server
- sleep 3 # give server time to start
after_script:
- kill %1 # kill e2e server
before_deploy:
- if [[ ! -z "$TRAVIS_TAG" ]]; then npm run build:prod; fi
- if [[ ! -z "$TRAVIS_TAG" ]]; then npm run build:all; fi
deploy:
- provider: npm
skip_cleanup: true

View File

@ -1,3 +1,26 @@
<a name="1.17.0"></a>
# [1.17.0](https://github.com/Rebilly/ReDoc/compare/v1.16.1...v1.17.0) (2017-08-02)
### Bug Fixes
* copy code-samples included \n\r characters ([cd962fa](https://github.com/Rebilly/ReDoc/commit/cd962fa)), closes [#296](https://github.com/Rebilly/ReDoc/issues/296)
* enum with single value not shown in non-body params ([87d9abd](https://github.com/Rebilly/ReDoc/commit/87d9abd)), closes [#284](https://github.com/Rebilly/ReDoc/issues/284)
* handle case where items is array in indexer ([5e5db72](https://github.com/Rebilly/ReDoc/commit/5e5db72)), closes [#304](https://github.com/Rebilly/ReDoc/issues/304)
* output dates as ISO 8601 strings in JSON Formatter ([#313](https://github.com/Rebilly/ReDoc/issues/313)) ([86d8179](https://github.com/Rebilly/ReDoc/commit/86d8179))
* make padding between h2 sections smaller ([2c89536](https://github.com/Rebilly/ReDoc/commit/2c89536)), closes [#291](https://github.com/Rebilly/ReDoc/issues/291)
* ready-only for nested objects samples ([be41d6d](https://github.com/Rebilly/ReDoc/commit/be41d6d)), closes [#300](https://github.com/Rebilly/ReDoc/issues/300)
### Features
* add `hide-loading` option ([2ebca4b](https://github.com/Rebilly/ReDoc/commit/2ebca4b)), closes [#315](https://github.com/Rebilly/ReDoc/issues/315)
* add special rendering for deprecated operations ([#290](https://github.com/Rebilly/ReDoc/issues/290)) ([2748aac](https://github.com/Rebilly/ReDoc/commit/2748aac))
* export angular module *<not stable yet>* ([ef5101b](https://github.com/Rebilly/ReDoc/commit/ef5101b))
* support for xml samples in response when there is no schema in response ([eb7089b](https://github.com/Rebilly/ReDoc/commit/eb7089b)), closes [#307](https://github.com/Rebilly/ReDoc/issues/307)
<a name="1.16.0"></a>
# [1.16.0](https://github.com/Rebilly/ReDoc/compare/v1.15.0...v1.16.0) (2017-05-12)

View File

@ -146,6 +146,7 @@ ReDoc makes use of the following [vendor extensions](http://swagger.io/specifica
* `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
* `path-in-middle-panel` - show path link and HTTP verb in the middle panel instead of the right one
* `hide-loading` - do not show loading animation. Useful for small docs
## Advanced usage
Instead of adding `spec-url` attribute to the `<redoc>` element you can initialize ReDoc via globally exposed `Redoc` object:

15
build/join-module-css.js Normal file
View File

@ -0,0 +1,15 @@
#!/usr/bin/env node
'use strict';
require('shelljs/global');
set('-e');
set('-v');
cat([
'lib/components/Redoc/redoc-initial-styles.css',
'node_modules/perfect-scrollbar/dist/css/perfect-scrollbar.css',
'node_modules/dropkickjs/build/css/dropkick.css',
'node_modules/prismjs/themes/prism-dark.css',
'node_modules/hint.css/hint.base.css'
]).to('dist/redoc.css')

View File

@ -8,6 +8,10 @@ function isPR() {
return process.env.TRAVIS_PULL_REQUEST && process.env.TRAVIS_PULL_REQUEST !== 'false';
}
function isCI() {
return !!process.env.CI;
}
if (process.env.JOB === 'e2e-guru') {
if (isPR()) {
console.log('Skiping E2E tests on PR');
@ -20,6 +24,10 @@ if (process.env.JOB === 'e2e-guru') {
console.log('Skiping E2E tests on PR');
return;
}
if (!isCI()) {
console.log('Skiping E2E tests locally. Use `npm run e2e` to run');
return;
}
console.log('Starting Basic E2E');
exec('npm run e2e');
}

View File

@ -10,13 +10,12 @@ const webpackMerge = require('webpack-merge'); // used to merge webpack configs
const commonConfig = require('./webpack.common.js');
module.exports = webpackMerge(commonConfig({
IS_PRODUCTION: process.env.NODE_ENV === "production",
AOT: false
IS_PRODUCTION: IS_PRODUCTION,
AOT: IS_PRODUCTION
}), {
devtool: '#inline-source-map',
entry: {
'polyfills': './lib/polyfills.ts',
'vendor': './lib/vendor.ts',
'redoc': './lib/index.ts',
},
devServer: {
@ -35,7 +34,7 @@ module.exports = webpackMerge(commonConfig({
{
test: /\.ts$/,
use: [
'awesome-typescript-loader?{configFileName: "tsconfig.webpack.json"}',
'awesome-typescript-loader',
'angular2-template-loader',
],
exclude: [/\.(spec|e2e)\.ts$/]

View File

@ -21,7 +21,7 @@ const config = webpackMerge(commonConfig({
devtool: 'source-map',
entry: {
'redoc': IS_MODULE ? ['./lib/vendor.ts', './lib/redoc.module.ts'] : ['./lib/polyfills.ts', './lib/vendor.ts', './lib/index.ts']
'redoc': IS_MODULE ? ['./lib/redoc.module.ts'] : ['./lib/polyfills.ts', './lib/index.ts']
},
output: {
@ -37,7 +37,7 @@ const config = webpackMerge(commonConfig({
{
test: /\.ts$/,
use: [
'awesome-typescript-loader?{configFileName: "tsconfig.webpack.json"}',
'awesome-typescript-loader',
'angular2-template-loader',
],
exclude: [/\.(spec|e2e)\.ts$/]
@ -52,8 +52,7 @@ const config = webpackMerge(commonConfig({
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
screw_ie8: true,
negate_iife: false // for lazy v8
screw_ie8: true
},
mangle: { screw_ie8 : true },
output: {
@ -61,6 +60,7 @@ const config = webpackMerge(commonConfig({
},
sourceMap: true
}),
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.BannerPlugin(BANNER)
]
})

View File

@ -27,12 +27,6 @@ module.exports = webpackMerge(commonConfig({
exclude: [/\.(spec|e2e)\.ts$/]
},
{
/**
* Instruments JS files with Istanbul for subsequent code coverage reporting.
* Instrument only testing sources.
*
* See: https://github.com/deepsweet/istanbul-instrumenter-loader
*/
enforce: 'post',
test: /\.(js|ts)$/, loader: 'istanbul-instrumenter-loader',
include: root('lib'),

View File

@ -15,13 +15,13 @@
width: 100%;
z-index: 100;
}
ul#links_container {
#links_container {
margin: 0;
padding: 0;
background-color: #0033a0;
}
li {
#links_container li {
display: inline-block;
padding: 10px;
color: white;

View File

@ -4,8 +4,8 @@
<title>ReDoc</title>
<link rel="stylesheet" href="main.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.vaadin.com/vaadin-core-elements/latest/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="https://cdn.vaadin.com/vaadin-core-elements/master/vaadin-combo-box/vaadin-combo-box-light.html">
<script src="https://cdn.vaadin.com/vaadin-core-elements/1.2.0/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="https://cdn.vaadin.com/vaadin-core-elements/1.2.0/vaadin-combo-box/vaadin-combo-box-light.html">
</head>
<body>
<nav>
@ -19,7 +19,7 @@
</form>
</template>
<iframe src="https://ghbtns.com/github-btn.html?user=Rebilly&repo=ReDoc&type=star&count=true&size=large"
frameborder="0" scrolling="0" width="130px" height="30px"></iframe>
frameborder="0" scrolling="0" width="150px" height="30px"></iframe>
</nav>
<redoc scroll-y-offset="body > nav" spec-url='swagger.yaml' lazy-rendering untrusted-spec></redoc>

View File

@ -4,8 +4,8 @@
<title>ReDoc</title>
<link rel="stylesheet" href="main.css">
<meta name="viewport" content="width=device-width, initial-scale=1">
<script src="https://cdn.vaadin.com/vaadin-core-elements/latest/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="https://cdn.vaadin.com/vaadin-core-elements/master/vaadin-combo-box/vaadin-combo-box-light.html">
<script src="https://cdn.vaadin.com/vaadin-core-elements/1.2.0/webcomponentsjs/webcomponents-lite.min.js"></script>
<link rel="import" href="https://cdn.vaadin.com/vaadin-core-elements/1.2.0/vaadin-combo-box/vaadin-combo-box-light.html">
</head>
<body>
<nav>
@ -19,7 +19,7 @@
</form>
</template>
<iframe src="https://ghbtns.com/github-btn.html?user=Rebilly&repo=ReDoc&type=star&count=true&size=large"
frameborder="0" scrolling="0" width="130px" height="30px"></iframe>
frameborder="0" scrolling="0" width="150px" height="30px"></iframe>
</nav>
<redoc scroll-y-offset="body > nav" spec-url='swagger.yaml' lazy-rendering untrusted-spec></redoc>
@ -32,14 +32,5 @@
<script src="/polyfills.js"></script>
<script src="/vendor.js"></script>
<script src="/redoc.js"></script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-81703547-1', 'auto');
ga('send', 'pageview');
</script>
</body>
</html>

View File

@ -336,6 +336,7 @@ paths:
summary: Finds Pets by tags
description: 'Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.'
operationId: findPetsByTags
deprecated: true
produces:
- application/xml
- application/json

View File

@ -1,6 +1,7 @@
import { NgModuleRef } from '@angular/core';
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';
export function bootstrapRedoc() {
export function bootstrapRedoc(): Promise<NgModuleRef<AppModule>> {
return platformBrowserDynamic().bootstrapModule(AppModule);
}

View File

@ -1,6 +1,8 @@
import { NgModuleRef } from '@angular/core';
import { platformBrowser } from '@angular/platform-browser';
import { AppModule } from './app.module';
import { AppModuleNgFactory } from '../compiled/lib/app.module.ngfactory';
export function bootstrapRedoc() {
export function bootstrapRedoc():Promise<NgModuleRef<AppModule>> {
return platformBrowser().bootstrapModuleFactory(AppModuleNgFactory);
}

View File

@ -22,3 +22,7 @@
:host /deep/ [section] {
padding-top: 2 * $section-spacing;
}
:host /deep/ h2[section] {
padding-top: $section-spacing;
}

View File

@ -49,12 +49,12 @@
<table class="params-wrap" [ngClass]="{'params-array': _isArray}">
<!-- <caption> {{_displayType}} </caption> -->
<ng-template ngFor [ngForOf]="properties" let-prop="$implicit" let-last="last" [ngForTrackBy]="trackByName">
<tr class="param" [ngClass]="{'last': last,
'discriminator': prop.isDiscriminator,
'complex': prop._pointer,
'additional': prop._additional,
'expanded': subSchema.open
}">
<tr class="param"
[class.last]="last"
[class.discriminator] = "prop.isDiscriminator"
[class.complex] = "prop._pointer"
[class.additional] = "prop._additional"
[class.expanded] = "subSchema.open">
<td class="param-name">
<span class="param-name-wrap" (click)="subSchema.toggle()">
<span class="param-name-content">

View File

@ -1,6 +1,6 @@
<div class="operation" *ngIf="operation">
<div class="operation-content">
<h2 class="operation-header sharable-header">
<h2 class="operation-header sharable-header" [class.deprecated]="operation.deprecated">
<a class="share-link" href="#{{operation.anchor}}"></a>{{operation.summary}}
</h2>
<endpoint-link *ngIf="pathInMiddlePanel"

View File

@ -16,6 +16,20 @@
.operation-header {
margin-bottom: calc(1em - 6px);
&.deprecated {
&:after {
content: 'Deprecated';
display: inline-block;
padding: 0 5px;
margin: 0;
background-color: $yellow;
color: white;
font-weight: bold;
font-size: 13px;
vertical-align: text-top;
}
}
}
.operation-tags {

View File

@ -7,6 +7,7 @@ import { OptionsService, MenuService } from '../../services/';
import { SwaggerBodyParameter } from '../../utils/swagger-typings';
export interface OperationInfo {
deprecated: boolean;
verb: string;
path: string;
info: {
@ -50,6 +51,7 @@ export class Operation extends BaseComponent implements OnInit {
this.operationId = this.componentSchema.operationId;
this.operation = {
deprecated: this.componentSchema.deprecated,
verb: JsonPointer.baseName(this.pointer),
path: JsonPointer.baseName(this.pointer, 2),
info: {

View File

@ -11,7 +11,8 @@
</div>
<div class="param-info">
<div>
<span *ngIf='param.type === "array"' class="param-array-format param-collection-format-{{param.collectionFormat}}">
<span *ngIf='param.type === "array"'
class="param-array-format param-collection-format-{{param.collectionFormat}}">
{{param | collectionFormat}}
</span>
<span class="param-type {{param.type}}" [ngClass]="{'with-hint': param._displayTypeHint}"
@ -21,8 +22,13 @@
<div class="param-default" *ngIf="param.default != null">
<span class="param-default-value">{{param.default | json}}</span>
</div>
<div *ngIf="param.enum" class="param-enum">
<span *ngFor="let enumItem of param.enum" class="param-enum-value {{enumItem.type}}"> {{enumItem.val | json}} </span>
<div *ngIf="param.enum || param._enumItem" class="param-enum">
<span *ngFor="let enumItem of param.enum" class="param-enum-value {{enumItem.type}}">
{{enumItem.val | json}}
</span>
<span *ngIf="param._enumItem" class="param-enum-value {{param._enumItem.type}}">
{{param._enumItem.val | json}}
</span>
</div>
<span *ngIf="param.pattern" class="param-pattern">{{param.pattern}}</span>
</div>

View File

@ -283,7 +283,7 @@ footer {
&:before, &:after {
letter-spacing: -0.2em;
content: "\00a0";
//content: "\00a0";
}
}

View File

@ -45,7 +45,7 @@ function getPreOptions() {
//changeDetection: ChangeDetectionStrategy.OnPush
})
export class Redoc extends BaseComponent implements OnInit {
static _preOptions: any;
static _preOptions: any = {};
error: any;
specLoaded: boolean;
@ -89,6 +89,9 @@ export class Redoc extends BaseComponent implements OnInit {
}
hideLoadingAnimation() {
if (this.options.hideLoading) {
return
}
requestAnimationFrame(() => {
this.specLoadingRemove = true;
setTimeout(() => {
@ -99,6 +102,9 @@ export class Redoc extends BaseComponent implements OnInit {
}
showLoadingAnimation() {
if (this.options.hideLoading) {
return
}
this.specLoading = true;
this.specLoadingRemove = false;
}

View File

@ -3,7 +3,7 @@
import { Component, Input, OnInit, ChangeDetectionStrategy } from '@angular/core';
import { BaseComponent, SpecManager } from '../base';
import JsonPointer from '../../utils/JsonPointer';
import { statusCodeType, getJsonLikeSample } from '../../utils/helpers';
import { statusCodeType, getJsonLikeSample, getXmlLikeSample } from '../../utils/helpers';
function isNumeric(n) {
@ -11,8 +11,7 @@ function isNumeric(n) {
}
function hasExample(response) {
return ((response.examples && getJsonLikeSample(response.examples)) ||
response.schema);
return response.schema || getXmlLikeSample(response.examples) || getJsonLikeSample(response.examples)
}
@Component({

View File

@ -12,7 +12,7 @@
</ng-template>
<tabs *ngIf="xmlSample; else jsonSnippet">
<tab tabTitle="JSON">
<tab tabTitle="JSON" *ngIf="sample">
<ng-container *ngTemplateOutlet="jsonSnippet"></ng-container>
</tab>
<tab tabTitle="XML" *ngIf="xmlSample">

View File

@ -1,6 +1,6 @@
<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)">
<label class="menu-item-header" [ngClass]="{disabled: !item.ready, deprecated: item?.metadata?.deprecated}" (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>
<svg *ngIf="item.items?.length" xmlns="http://www.w3.org/2000/svg" version="1.1" x="0" y="0" viewBox="0 0 24 24" xml:space="preserve">

View File

@ -21,6 +21,11 @@
color: lighten($text-color, 60%);
}
&.deprecated {
text-decoration: line-through;
color: lighten($text-color, 60%);
}
display: flex;
justify-content: space-between;

View File

@ -28,35 +28,3 @@ if (!IS_PRODUCTION) {
Error.stackTraceLimit = Infinity;
require('zone.js/dist/long-stack-trace-zone');
}
interface Element {
scrollIntoViewIfNeeded(centerIfNeeded?: boolean): void;
};
if (!(<any>Element).prototype.scrollIntoViewIfNeeded) {
(<any>Element).prototype.scrollIntoViewIfNeeded = function (centerIfNeeded) {
centerIfNeeded = arguments.length === 0 ? true : !!centerIfNeeded;
var parent = this.parentNode,
parentComputedStyle = window.getComputedStyle(parent, null),
parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue('border-top-width')),
parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue('border-left-width')),
overTop = this.offsetTop - parent.offsetTop < parent.scrollTop,
overBottom = (this.offsetTop - parent.offsetTop + this.clientHeight - parentBorderTopWidth) > (parent.scrollTop + parent.clientHeight),
overLeft = this.offsetLeft - parent.offsetLeft < parent.scrollLeft,
overRight = (this.offsetLeft - parent.offsetLeft + this.clientWidth - parentBorderLeftWidth) > (parent.scrollLeft + parent.clientWidth),
alignWithTop = overTop && !overBottom;
if ((overTop || overBottom) && centerIfNeeded) {
parent.scrollTop = this.offsetTop - parent.offsetTop - parent.clientHeight / 2 - parentBorderTopWidth + this.clientHeight / 2;
}
if ((overLeft || overRight) && centerIfNeeded) {
parent.scrollLeft = this.offsetLeft - parent.offsetLeft - parent.clientWidth / 2 - parentBorderLeftWidth + this.clientWidth / 2;
}
if ((overTop || overBottom || overLeft || overRight) && !centerIfNeeded) {
this.scrollIntoView(alignWithTop);
}
};
}

View File

@ -1,3 +1,5 @@
import './vendor';
import { NgModule, ErrorHandler, APP_ID } from '@angular/core';
import { CommonModule } from '@angular/common';

View File

@ -340,7 +340,8 @@ export class MenuService {
type: 'operation',
pointer: operationInfo._pointer,
operationId: operationInfo.operationId,
operation: operationInfo.operation
operation: operationInfo.operation,
deprecated: !!operationInfo.deprecated
},
parent: parent
};

View File

@ -19,7 +19,8 @@ const OPTION_NAMES = new Set([
'requiredPropsFirst',
'noAutoAuth',
'pathInMiddlePanel',
'untrustedSpec'
'untrustedSpec',
'hideLoading'
]);
export interface Options {
@ -35,6 +36,7 @@ export interface Options {
noAutoAuth?: boolean;
pathInMiddlePanel?: boolean;
untrustedSpec?: boolean;
hideLoading?: boolean;
spec?: any;
}
@ -104,6 +106,7 @@ export class OptionsService {
if (isString(this._options.noAutoAuth)) this._options.noAutoAuth = true;
if (isString(this._options.pathInMiddlePanel)) this._options.pathInMiddlePanel = true;
if (isString(this._options.untrustedSpec)) this._options.untrustedSpec = true;
if (isString(this._options.hideLoading)) this._options.hideLoading = true;
if (isString(this._options.expandResponses)) {
let str = this._options.expandResponses as string;
if (str === 'all') return;

View File

@ -35,8 +35,8 @@ const injectors = {
injectTo.enum = propertySchema.enum.map((value) => {
return {val: value, type: typeof value};
});
if (propertySchema.enum && propertySchema.enum.length === 1) {
injectTo._enumItem = propertySchema.enum[0];
if (injectTo.enum && injectTo.enum.length === 1) {
injectTo._enumItem = injectTo.enum[0];
injectTo.enum = null;
}
}

View File

@ -192,7 +192,13 @@ export class SearchService {
let body = schema.description; // TODO: defaults, examples, etc...
if (schema.type === 'array') {
if (Array.isArray(schema.items)) {
schema.items.map((itemSchema, idx) => {
this.indexSchema(itemSchema, title, JsonPointer.join(absolutePointer, ['items', idx]), menuPointer, parent);
});
} else {
this.indexSchema(schema.items, title, JsonPointer.join(absolutePointer, ['items']), menuPointer, parent);
}
return;
}

View File

@ -4,12 +4,9 @@ import { BehaviorSubject } from 'rxjs/BehaviorSubject';
@Injectable()
export class WarningsService {
private static _warnings: Array<string> = [];
private static _warningsObs = new BehaviorSubject<Array<string>>([]);
public static warnings = new BehaviorSubject<Array<string>>([]);
static get warnings() {
return WarningsService._warningsObs;
}
private static _warnings: Array<string> = [];
static hasWarnings() {
return !!WarningsService._warnings.length;
@ -17,7 +14,7 @@ export class WarningsService {
static warn(message:string) {
WarningsService._warnings.push(message);
WarningsService._warningsObs.next(WarningsService._warnings);
WarningsService.warnings.next(WarningsService._warnings);
console.warn(message);
}
}

View File

@ -27,7 +27,10 @@ export class CopyButton implements OnInit {
onClick() {
let copied;
if (this.copyText) {
copied = Clipboard.copyCustom(JSON.stringify(this.copyText, null, 2));
const text = (typeof this.copyText === 'string')
? this.copyText
: JSON.stringify(this.copyText, null, 2);
copied = Clipboard.copyCustom(text);
} else {
copied = Clipboard.copyElement(this.copyElement);
}

View File

@ -35,6 +35,8 @@ function valueToHTML(value) {
level++;
output += arrayToHTML(value);
level--;
} else if (value && value.constructor === Date) {
output += decorateWithSpan('"' + value.toISOString() + '"', 'type-string');
} else if (valueType === 'object') {
level++;
output += objectToHTML(value);

View File

@ -142,7 +142,7 @@ export function isXmlLike(contentType: string): boolean {
return contentType.search(/xml/i) !== -1;
}
export function getJsonLikeSample(samples: Object) {
export function getJsonLikeSample(samples: Object = {}) {
const jsonLikeKeys = Object.keys(samples).filter(isJsonLike);
if (!jsonLikeKeys.length) {
@ -152,7 +152,7 @@ export function getJsonLikeSample(samples: Object) {
return samples[jsonLikeKeys[0]];
}
export function getXmlLikeSample(samples: Object) {
export function getXmlLikeSample(samples: Object = {}) {
const xmlLikeKeys = Object.keys(samples).filter(isXmlLike);
if (!xmlLikeKeys.length) {

View File

@ -95,7 +95,8 @@ export class SpecManager {
}
if (!this._schema.info.description) this._schema.info.description = '';
if (this._schema.securityDefinitions && !this.options.noAutoAuth) {
let SecurityDefinitions = require('../components/').SecurityDefinitions;
let SecurityDefinitions =
require('../components/SecurityDefinitions/security-definitions').SecurityDefinitions;
mdRender.addPreprocessor(SecurityDefinitions.insertTagIntoDescription);
}
this._schema.info['x-redoc-html-description'] = mdRender.renderMd(this._schema.info.description);

View File

@ -24,12 +24,34 @@ import 'dropkickjs/build/css/dropkick.css';
import 'prismjs/themes/prism-dark.css';
import 'hint.css/hint.base.css';
if (!IS_PRODUCTION) {
require('@angular/platform-browser');
require('@angular/platform-browser-dynamic');
require('@angular/core');
require('@angular/common');
interface Element {
scrollIntoViewIfNeeded(centerIfNeeded?: boolean): void;
};
// RxJS
require('rxjs/Rx');
if (!(<any>Element).prototype.scrollIntoViewIfNeeded) {
(<any>Element).prototype.scrollIntoViewIfNeeded = function (centerIfNeeded) {
centerIfNeeded = arguments.length === 0 ? true : !!centerIfNeeded;
var parent = this.parentNode,
parentComputedStyle = window.getComputedStyle(parent, null),
parentBorderTopWidth = parseInt(parentComputedStyle.getPropertyValue('border-top-width')),
parentBorderLeftWidth = parseInt(parentComputedStyle.getPropertyValue('border-left-width')),
overTop = this.offsetTop - parent.offsetTop < parent.scrollTop,
overBottom = (this.offsetTop - parent.offsetTop + this.clientHeight - parentBorderTopWidth) > (parent.scrollTop + parent.clientHeight),
overLeft = this.offsetLeft - parent.offsetLeft < parent.scrollLeft,
overRight = (this.offsetLeft - parent.offsetLeft + this.clientWidth - parentBorderLeftWidth) > (parent.scrollLeft + parent.clientWidth),
alignWithTop = overTop && !overBottom;
if ((overTop || overBottom) && centerIfNeeded) {
parent.scrollTop = this.offsetTop - parent.offsetTop - parent.clientHeight / 2 - parentBorderTopWidth + this.clientHeight / 2;
}
if ((overLeft || overRight) && centerIfNeeded) {
parent.scrollLeft = this.offsetLeft - parent.offsetLeft - parent.clientWidth / 2 - parentBorderLeftWidth + this.clientWidth / 2;
}
if ((overTop || overBottom || overLeft || overRight) && !centerIfNeeded) {
this.scrollIntoView(alignWithTop);
}
};
}

View File

@ -1,7 +1,7 @@
{
"name": "redoc",
"description": "Swagger-generated API Reference Documentation",
"version": "1.16.1",
"version": "1.17.0",
"repository": {
"type": "git",
"url": "git://github.com/Rebilly/ReDoc"
@ -10,32 +10,36 @@
"node": ">=6.9",
"npm": ">=3.0.0"
},
"main": "dist/redoc-module.js",
"main": "dist/redoc.module.js",
"module": "dist/redoc.module.js",
"types": "dist/redoc.module.d.ts",
"scripts": {
"start": "webpack-dev-server --config build/webpack.dev.js --content-base demo",
"start:prod": "NODE_ENV=production npm start",
"test": "npm run lint && node ./build/run_tests.js",
"branch-release": "git reset --hard && branch-release",
"lint": "tslint -e \"lib/**/*{ngfactory|css.shim}.ts\" lib/**/*.ts",
"unit": "karma start",
"e2e": "npm run build:prod && npm run e2e-copy && npm run webdriver && protractor",
"deploy": "node ./build/prepare_deploy.js && deploy-to-gh-pages --update demo",
"ngc": "ngc -p tsconfig.webpack.json",
"clean:dist": "npm run rimraf -- dist/",
"clean:aot": "npm run rimraf -- .tmp compiled lib/**/*.css",
"rimraf": "rimraf",
"webpack:prod": "webpack --config build/webpack.prod.js --profile --bail",
"build:sass": "node-sass -q -o lib lib",
"build:prod": "npm run clean:aot && npm run build:sass && npm run ngc && npm run webpack:prod",
"build-dist": "npm run build:prod",
"stats": "webpack --config build/webpack.prod.js --json > stats.json",
"start": "webpack-dev-server --config build/webpack.dev.js --content-base demo",
"pree2e": "npm run build:prod && npm run e2e-copy",
"e2e": "run-p -r protractor e2e-server",
"protractor": "protractor",
"preprotractor": "npm run webdriver",
"e2e-server": "http-server -p 3000 tests/e2e",
"e2e-copy": "cp dist/redoc.min.js tests/e2e/",
"webdriver": "webdriver-manager update",
"serve:prod": "NODE_ENV=production npm start",
"protractor": "protractor",
"deploy": "node ./build/prepare_deploy.js && deploy-to-gh-pages --update demo",
"branch-release": "git reset --hard && branch-release",
"clean": "rimraf dist .tmp compiled lib/**/*.css",
"ngc": "ngc -p tsconfig.json",
"inline": "ng2-inline -o .tmp -r --compress \"lib/**/*.ts\"",
"build:module": "npm run build:sass && npm run inline && ngc -p tsconfig.aot.json && npm run module:css",
"module:css": "node build/join-module-css.js",
"webpack:prod": "webpack --config build/webpack.prod.js --profile --bail",
"build:sass": "node-sass -q -o lib lib",
"build:prod": "npm run build:sass && npm run ngc && npm run webpack:prod",
"build-dist": "npm run build:prod",
"build:all": "npm run clean && npm run build:prod && npm run build:module",
"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"
"stats": "webpack --config build/webpack.prod.js --json > stats.json"
},
"keywords": [
"OpenAPI",
@ -50,38 +54,34 @@
"author": "Roman Hotsiy",
"license": "MIT",
"devDependencies": {
"@angular/common": "^4.1.1",
"@angular/compiler": "^4.1.1",
"@angular/compiler-cli": "^4.1.1",
"@angular/core": "^4.1.1",
"@angular/platform-browser": "^4.1.1",
"@angular/platform-browser-dynamic": "^4.1.1",
"@angular/platform-server": "^4.1.1",
"@types/jasmine": "^2.5.47",
"@angular/common": "^4.3.2",
"@angular/compiler": "^4.3.2",
"@angular/compiler-cli": "^4.3.2",
"@angular/core": "^4.3.2",
"@angular/platform-browser": "^4.3.2",
"@angular/platform-browser-dynamic": "^4.3.2",
"@angular/platform-server": "^4.3.2",
"@types/jasmine": "^2.5.53",
"@types/requirejs": "^2.1.29",
"@types/should": "^8.3.0",
"@types/swagger-schema-official": "^2.0.5",
"@types/webpack": "^2.2.15",
"@types/webpack": "^3.0.5",
"angular2-inline-template-style": "^1.1.0",
"angular2-template-loader": "^0.6.2",
"awesome-typescript-loader": "^3.1.3",
"awesome-typescript-loader": "^3.2.2",
"branch-release": "^1.0.3",
"chalk": "^1.1.3",
"codelyzer": "^3.0.1",
"conventional-changelog-cli": "^1.3.1",
"core-js": "^2.4.1",
"chalk": "^2.0.1",
"codelyzer": "^3.1.2",
"conventional-changelog-cli": "^1.3.2",
"css-loader": "^0.28.1",
"deploy-to-gh-pages": "^1.3.3",
"dropkickjs": "^2.1.10",
"hint.css": "^2.5.0",
"exports-loader": "^0.6.4",
"http-server": "^0.10.0",
"https-browserify": "^1.0.0",
"istanbul-instrumenter-loader": "^2.0.0",
"jasmine-core": "^2.6.1",
"jasmine-spec-reporter": "^4.1.0",
"json-pointer": "^0.6.0",
"json-schema-ref-parser": "^3.1.2",
"istanbul-instrumenter-loader": "^3.0.0",
"jasmine-core": "^2.7.0",
"jasmine-spec-reporter": "^4.1.1",
"karma": "^1.6.0",
"karma-chrome-launcher": "^2.1.0",
"karma-chrome-launcher": "^2.2.0",
"karma-coverage": "^1.1.1",
"karma-coveralls": "^1.1.2",
"karma-jasmine": "^1.0.2",
@ -92,38 +92,57 @@
"karma-should": "^1.0.0",
"karma-sinon": "^1.0.4",
"karma-sourcemap-loader": "^0.3.7",
"karma-webpack": "^2.0.3",
"mark.js": "github:julmot/mark.js",
"karma-webpack": "^2.0.4",
"node-sass": "^4.5.3",
"openapi-sampler": "^0.4.1",
"npm-run-all": "^4.0.2",
"phantomjs-prebuilt": "^2.1.14",
"prismjs": "^1.5.1",
"protractor": "^5.1.1",
"raw-loader": "^0.5.1",
"remarkable": "1.7.1",
"rimraf": "^2.6.1",
"rxjs": "^5.3.1",
"sass-loader": "^6.0.3",
"scrollparent": "^2.0.1",
"rxjs": "^5.4.2",
"sass-loader": "^6.0.6",
"shelljs": "^0.7.7",
"should": "^11.2.1",
"sinon": "^2.2.0",
"slugify": "^1.0.2",
"sinon": "^2.4.1",
"source-map-loader": "^0.2.1",
"stream-http": "^2.7.0",
"string-replace-webpack-plugin": "^0.1.3",
"style-loader": "^0.17.0",
"style-loader": "^0.18.2",
"swagger-schema-official": "^2.0.0-bab6bed",
"ts-helpers": "^1.1.1",
"tslint": "^5.2.0",
"typescript": "^2.3.2",
"webpack": "^2.5.0",
"webpack-dev-server": "^2.4.5",
"webpack-merge": "^4.1.0",
"zone.js": "^0.8.10"
"tslint": "^5.5.0",
"typescript": "^2.4.2",
"webpack": "^3.4.1",
"webpack-dev-server": "^2.6.1",
"webpack-merge": "^4.1.0"
},
"peerDependencies": {
"@angular/common": "^4.1.1",
"@angular/compiler": "^4.1.1",
"@angular/compiler-cli": "^4.1.1",
"@angular/core": "^4.1.1",
"@angular/forms": "^4.1.1",
"@angular/platform-browser": "^4.1.1",
"@angular/platform-browser-dynamic": "^4.1.1",
"@angular/platform-server": "^4.1.1",
"core-js": "^2.4.1",
"rxjs": "^5.3.1"
},
"dependencies": {
"lunr": "1.0.0",
"perfect-scrollbar": "^0.7.0"
"core-js": "^2.4.1",
"dropkickjs": "^2.1.10",
"hint.css": "^2.3.2",
"https-browserify": "^1.0.0",
"json-pointer": "^0.6.0",
"json-schema-ref-parser": "^3.2.0",
"lunr": "^1.0.0",
"mark.js": "github:julmot/mark.js",
"openapi-sampler": "^0.4.2",
"perfect-scrollbar": "^0.7.0",
"prismjs": "^1.5.1",
"remarkable": "1.7.1",
"scrollparent": "^2.0.1",
"slugify": "^1.0.2",
"stream-http": "^2.6.1",
"ts-helpers": "^1.1.2",
"zone.js": "^0.8.16"
}
}

View File

@ -15,6 +15,7 @@ let config = {
global.apisGuruList = list;
return browser.getCapabilities().then(function (caps) {
browser.isIE = caps.get('browserName') === 'internet explorer';
browser.isFF = caps.get('browserName') === 'firefox';
});
});
},
@ -53,6 +54,8 @@ if (travis) {
maxDuration: 1800*2
},{
browserName: 'firefox',
platform: 'Windows 10',
version: '54.0',
'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER,
build: process.env.TRAVIS_BUILD_NUMBER,
name: 'Redoc Firefox Latest/Win build ' + process.env.TRAVIS_BUILD_NUMBER,

View File

@ -31,7 +31,7 @@ const MAX_ERROR_MESSAGE_SYMBOLS = 128;
//copied from angular/modules/angular2/src/testing/e2e_util.ts
function verifyNoBrowserErrors() {
// IE doesn't support logs method
if (browser.isIE) {
if (browser.isIE || browser.isFF) {
let err = browser.executeScript('return window.redocError');
expect(err).toBeNull();
return;

View File

@ -21,7 +21,10 @@ export function mouseclick( element ) {
// create a mouse click event
var dispatchedEvent
try {
dispatchedEvent = new MouseEvent('click', true);
dispatchedEvent = new MouseEvent('click', {
bubbles: true,
cancelable: false
});
} catch (e) {
dispatchedEvent = document.createEvent('MouseEvent');
dispatchedEvent.initEvent('click', true, false);

View File

@ -7,13 +7,11 @@
"experimentalDecorators": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"noEmit": true,
"noEmitHelpers": true,
"outDir": "./dist",
"strictNullChecks": false,
"baseUrl": "./src",
"typeRoots": [ "./node_modules/@types" ],
"paths": {
},
"declaration": true,
"declarationDir": "dist",
"lib": [
"es2015",
"dom"
@ -23,21 +21,17 @@
"swagger-schema-official"
]
},
"exclude": [
"node_modules",
"dist",
"**/*.spec.ts",
"**/*.e2e.ts"
"files": [
"custom.d.ts",
".tmp/lib/polyfills.ts",
".tmp/lib/redoc.module.ts"
],
"exclude": [
"node_modules"
],
"awesomeTypescriptLoaderOptions": {
"forkChecker": true,
"useWebpackText": true
},
"angularCompilerOptions": {
"genDir": "./compiled",
"skipMetadataEmit": true
},
"compileOnSave": false,
"buildOnSave": false,
"atom": { "rewriteTsconfig": false }
"genDir": "./dist",
"skipTemplateCodegen": true,
"strictMetadataEmit": true
}
}

View File

@ -8,26 +8,35 @@
"sourceMap": true,
"pretty": true,
"moduleResolution": "node",
"types": [
"jasmine",
"should",
"webpack",
"swagger-schema-official"
],
"outDir": "dist",
"noEmit": true,
"noEmitHelpers": true,
"strictNullChecks": false,
"typeRoots": [ "./node_modules/@types" ],
"lib": [
"dom", "es2016", "dom.iterable"
],
"noEmitHelpers": false
"types": [
"webpack",
"jasmine",
"should"
]
},
"compileOnSave": false,
"exclude": [
"node_modules",
"dist"
"dist",
"**/*.e2e.ts"
],
"awesomeTypescriptLoaderOptions": {
"resolveGlobs": true,
"forkChecker": true,
"useWebpackText": true
}
},
"angularCompilerOptions": {
"genDir": "./compiled",
"skipMetadataEmit": true
},
"compileOnSave": false,
"buildOnSave": false,
"atom": { "rewriteTsconfig": false }
}

View File

@ -1,7 +1,4 @@
{
"linterOptions": {
"typeCheck": true
},
"rulesDirectory": ["node_modules/codelyzer"],
"rules": {
"class-name": true,
@ -22,7 +19,7 @@
"no-eval": true,
"no-trailing-whitespace": true,
"no-unused-expression": true,
"no-use-before-declare": true,
"no-use-before-declare": false,
"one-line": [true,
"check-open-brace",
"check-catch",

1873
yarn.lock

File diff suppressed because it is too large Load Diff