Merge branch 'master' into releases

This commit is contained in:
Roman Hotsiy 2016-01-18 17:53:49 +02:00
commit e1847867ed
39 changed files with 1042 additions and 289 deletions

View File

@ -1,4 +1,12 @@
build
demo
.DS_Store
**/.*
.tmp
node_modules
jspm_packages
tests
lib
demo
build
coverage

View File

@ -1,12 +1,27 @@
language: node_js
node_js:
- '4.0'
branches:
except:
- releases
matrix:
include:
- env: JOB=e2e
fast_finish: true
allow_failures:
- env: JOB=e2e
env:
global:
- GH_REF: github.com/Rebilly/ReDoc.git
- secure: ijk9zRQxw1XKVt1zjuJ4uc3iyU622HB0qSPdwVECqhUMm3Gh3MAmTH1bqubsSHKZbfNNIehUvu+X/3LeKZNUK+zBS8qbLXWQKZ4ime4RHT8ADjZV+NY2GdQUxs5rklb3kjVK6cOQ8A51jU/8Zw738iFDDPz3NxbXC+MP3CQANxYCeX2axdxVFzQcldA89vZr0K8DBMPW1EZP+e1jORB3YFwyKZMppB9XvI7GAjt2OQvZDQegNuVaPuECZcJjPh2VBopQ3+Giun2AIe3C0Q/DmU+rZd8M2/t2VEv0e6BZNtbpycq8ST3mWloTPhmL9F2xlm4ZuWUVWuxB3LgOTZUw11KRg51MUTv/9Xfrqf16CUvR4TJ7EDYAKt5NwVFNUJsIy9cpuI6fsndFeI7EWFFYN7m4FX/SWLhVzFcrZeWpwbMn+qFCE0S+VgUjwYwMMA667YgRPhIAGoJfL5MxrhE/HPUIDJU91t9ON7UpFcdcUex6jX9pKUvyP52uJQKIwP10ZgehvL3S0iutMYVYY0YNkKF4tIPiQPsCK4lx7Up4D/tR9jSZl11CLMBZ0jLk1sEtgMf9+v0emOiGIgmBBYwVec6Jy1kSJyEeAJThmLjdVtAVgT0T3jPhM0Z8BE0xkwFY/5myQeoo8QWdBcDZw3iAxgatHXnPLqoa5rViuA1thyw=
- GIT_AUTHOR_EMAIL: redoc-bot@users.noreply.github.com
- GIT_AUTHOR_NAME: RedocBot
- SAUCE_USERNAME: redoc
- secure: OgYIXlyF3tvHVrMjqIMR7UPhNvMzNZRkKE++LsQPUT4aoUmHoeukjgE9tKCZac3Z+PcAlgHQ6dPUqjqij2d/emYBIrCx4ABvTOnxQYHbk+8GriwPvQjV33MCfKvRQAf3XPNcga02aOO/EEGejrtY/i5sz86XPZFXap4scxbvnF0rzOwGU9/A40JLsvKjtfdRxJ3aC2QBnUHP9JkfBOzbs3jjwEWYN7HdUBqtYU+wiUwvHhpEPQ8BVNF5ETp5OxxkTdqJlMRf3azC4U/Rl8dhUXZP2l1ZBdpgahDvSkx1zXPwKRg1jos88jahqH/v8DLHtXNuYQy4S48nKWZfaRtQegG/XsYAftYPtYage7L9D0nFQW9YZI0vwUBEzh2YTf+QNpVwUSyZhVuS1oS+scTb8RU8BVVZd6hRpJiaI2YiPM6ZFN7a69deV0cASov3yI7GSfeq4MmB4hu72Le+GhemQMLRxNgtr32c18XW1XoHEnpV7s0eKXnZrevnM06tW/nX9TQXGloaMUeQzoZY0AuF00zmrHDaNgwT63ULjY0W591Ey1Ztfq4ixdCoi6IPAtl49vTnNMMMqatI7Si/haI6hGyTy+H0xK1GlUpBCe5CGusXDSKUqrlKS5Izreepfj1G+12391ixiapkwV3SbYdQEhcDt7HWupyI4Zfkvg8EwwE=
- secure: H2GClDJ7TEQaWgnk8d2fIVDpLwG3rTmN8TalUzrCqXGoG6ylCVmlwzKLgfPPWrVgSA7QTdfNV0ab7c2KyPoZBinHmeGMSuKNLVbhOXRc2VFxTBntBTuyJhfCgQEpUKvJesJUuv5RuBn//wC7VZcVVNc06TZDEe8+aDVYQuCRMXZJ4X3e6nSZ64QX2veyVcr+TjnRsZPkeBVcK9hngvuaxLb/hbJ85CvjiseZRt47PGIcrEpMn9n2GMw1m0fNnPoN+MBTSCnIklTmdjPG7t4GUSLmD6H0lNLdXuehYqmQAHgYrLec1aiFlV57QaDoDZrq2hSf4vDmCB/FVydGhD5JunI67pujoV2OnD1V80eUZhYNWOYsJ2Nfp4NxgXsPUcE6zWLYsLfktMPZADhOXInQRACt1cnx8zMYKLnch1RY/ZqjSg0nPtRjLzQ0lNsw5leixvBdBnMjxYHVyAWVwg8WiJMaLO9vog2Qnxg1NTacHO2CsOmm2rw6stpg7ndp/+nOleRlfUKggjt0Tn3FjwCIXeGup2P2EBa+WW2YMAaoMFofYviR5vRlKBgdKo9fsAruaO1r6nm2EdAjOlniyw92bEfU/qOey1nVp/oK2S82uT5In8KB7vl6rF3ak7WAsT9Q5vZUhsrG+eE4PVyIyWNBhs4A7pSwZGHDR/MYtp0E2ug=
- secure: QiSLFxMS0fNLQAuG081Oi22OkL8BqCDnZVGk0a69azNzl5vv3PCcYO2Sjbloe48gPVH3p5AonDTtDEtnUbMcCJjtrhggqs5gSilO+UVgDb+4LfrYDnJ8ffaeVGIugay9wl2aJVz3iNbnIovGP7Nw+M/OWtLc2xq6zE1rIJkdRJ4K55PYfO8EMDvzI7hjZxSZ+Kgglcdl/wdBSKXy/qG0atALQU9ilJnk/DcobCjaUjgH/v0HXTSO8K3TNso6Zo4HOO6xWXHDZnJ2sLNltW1jveBpfCr/ZlccgPASU03nIudJyKvX8V4fXQ+2Z2Rj3JtR0x95SSH3M7ixx3s4teiXNFe9HPMfN1NLh/zf8UmgWIN1uwyYecsjRVzz+ZsfnrNBjGyXdEJg5c6SZGIa/UMSxaQFdRzEA419qw2eJ9qcmfNPyIvijugEBupJsxK6MW+mrD8qaGKQDzEP1dD7PUlr1BBckFNI8SZKD0gEaqM/ibebxrMS2IcGE5Nk7qLdaOAdB1plXAhMl+PGNaPx4+cniUqIIpgDTX8hlmd/Qk8ThyN5Z4aQyWI2WfH1BSqwg8dQfB5B6WNUDbJh/4Z6AX7e7ACiMLKoRkBTWpQ1FIwEJh5j8X/mtMBjf4+HSf8kfnAWFCmPTpRcYz9i4ZUDfa/9QKMoumCjokfItU7Ue2UE5v4=
- secure: apiavCfCQngL9Een1m7MIXMf3bqO3rY4YY59TMBl/yFKi80CEsHPHhgVUkl6hC+aM5PeBt/vgjh37rHMX31j/pcSZ4Z8SO/4Bwr36iHfhSxSEuAQog8P07qWqH7wYYWGIVmF682stgl0fYF+GN92sx/6edFVzsWVECf2G7imtICKSTbhKGm3Dhn2JwGnhD7eyfgZ33omgiaswumdu0xABoXDfqSZR+16fC4Ap5rhv3fXO9ndvRNy1STn376nT+my6e86UrQL4aS/S+HNHgIe1BUs+5cOp6Jgw6t0ie7phY0EAiECsRxy9K4e3Dctv9m6+Wma4+vy65MS0zGyrqey6oyV4l827sCOjrD1qcqc9bX6FlMSouVoNfE4ZjINNAbgigTaiLSoDSPcf5I5smkkM2ezzFOMSZwZxNdaNL2LKb97vc8m/ZUkv0sKZyT7oqVL7aJweEivsSHj5l2KR8Z7XrVB1y2eI6GvyTSa/d+CL4dSRzjh8+IRN047YBrdTKD5IkdT0upfoBu14WPUfFmLKxX+iMCslXRWb6kwojhrWNYmZvL65KRAzJ6+eIPDG/W5QUOpYyYT77bLlBQjVo6NmVvl9v3HMECq9CHH0ivKFBGPiKMOx7cJkTax3FuyznOW2WCXB9kTb5Zk9toaiNlSp9L6ll/h2Eyxa6n6sWUgmmM=
addons:
sauce_connect: true
cache:
directories:
- node_modules
@ -17,14 +32,19 @@ before_install:
before_deploy:
- npm run build-dist
deploy:
skip_cleanup: true
provider: script
script: ./build/deploy_gh_pages.sh
on:
branch: master
deploy:
skip_cleanup: true
provider: script
script: "npm run branch-release"
on:
branch: master
- skip_cleanup: true
provider: script
script: ./build/deploy_gh_pages.sh
on:
branch: master
- skip_cleanup: true
provider: script
script: npm run branch-release
on:
branch: master
- provider: npm
skip_cleanup: true
api_key:
secure: PuhWLERrCEFmXmdFpw2OVFlqpOIVDmgwk5JUJOYaFdVCh/smp0+jZCQ4vrdFpuG96rnDVirD+A8xvW6NgsNNaRthLgOB/LRdFN69rU6Gvn3At6wlnC55t5dlhxPvCfnzJcHVBLXX4EmMkjnZqDg2uczXTzPodr3FnQJNuXmP8B33fzDVLyHccvXZ90abwXWVrgRIXPU28niqCR8DOC2OTzs7wqz+BLNkYDRRbyYXsg62HWuD33x5iof5IqBmhzBt3usCGmF3QGcgHrXHdZw3sZnit8+Bua++3KrXR0x6HGXXN1AoXVmCAkCa5OTQ5R3tCRxiJN3P2KLnvWeZR74sTFkovJB/6pGCvbJ/c7Wnuw6sD7SgOUBD359ULB6lAf5OnxBLoNebX4JxxVXF+zA4E3Bl44VxkzDpPWc15xqBPMB5vBREzMVmJ5mExn2s5cmLQjADbl9h0y6gZnhnNJ+iTmqtrVyM0ZkF2rPrzrTdGD+ULmRIlTMkdD1bh+/TJ3RdXT3P4/zNUJmiNnvgnnJVYYvsGaXWF+7uCVHT/8k2RsoSHqgkqh0gkDqGSwVix55y5mC7T2Vk9lMBhm6MvFJXaonOX0kxJS4EDQ3plPd6/ybG+TLhwggYnQ8o9msU5Nt6FpUShKiezjKurIhbQZdwlVivX3tahjW2QjNDO58xGgY=
on:
tags: true

View File

@ -1,11 +1,15 @@
# ReDoc
[![travis-ci-status]](https://travis-ci.org/Rebilly/ReDoc) [![coverage-status-badge]](https://coveralls.io/github/Rebilly/ReDoc?branch=master) [![code-climate-badge]](https://codeclimate.com/github/Rebilly/ReDoc) [![dev-dependency-badge]](https://david-dm.org/Rebilly/ReDoc#info=devDependencies) [![license-badge]](https://github.com/Rebilly/ReDoc/blob/master/LICENSE)
[![Build Status](https://travis-ci.org/Rebilly/ReDoc.svg?branch=master)](https://travis-ci.org/Rebilly/ReDoc) [![Coverage Status](https://coveralls.io/repos/Rebilly/ReDoc/badge.svg?branch=master&service=github)](https://coveralls.io/github/Rebilly/ReDoc?branch=master) [![Code Climate](https://codeclimate.com/github/Rebilly/ReDoc/badges/gpa.svg)](https://codeclimate.com/github/Rebilly/ReDoc) [![David](https://david-dm.org/Rebilly/ReDoc/dev-status.svg)](https://david-dm.org/Rebilly/ReDoc#info=devDependencies)
[![npm](http://img.shields.io/npm/v/redoc.svg)](https://www.npmjs.com/package/swagger-parser) [![Bower](http://img.shields.io/bower/v/redoc.svg)](http://bower.io/) [![License](https://img.shields.io/npm/l/redoc.svg)](https://github.com/Rebilly/ReDoc/blob/master/LICENSE)
[![Browser Compatibility](https://saucelabs.com/browser-matrix/redoc.svg)](https://saucelabs.com/u/redoc)
Swagger-generated API Reference Documentation
**Under development**
[Live demo][demo]
[Live demo](http://rebilly.github.io/ReDoc/)
## Running locally
1. Clone repository
@ -18,11 +22,3 @@ Swagger-generated API Reference Documentation
5. Start the server
`npm start`
6. Open `http://localhost:9000`
[travis-ci-status]: https://travis-ci.org/Rebilly/ReDoc.svg?branch=master "TravisCI Status"
[license-badge]: https://img.shields.io/github/license/rebilly/redoc.svg "Github license"
[coverage-status-badge]:https://coveralls.io/repos/Rebilly/ReDoc/badge.svg?branch=master&service=github) "Coverage Status"
[dev-dependency-badge]: https://david-dm.org/Rebilly/ReDoc/dev-status.svg
[code-climate-badge]: https://codeclimate.com/github/Rebilly/ReDoc/badges/gpa.svg "Code Climate"
[demo]: http://rebilly.github.io/ReDoc/

6
build/run_tests.sh Executable file
View File

@ -0,0 +1,6 @@
#!/bin/bash
if [ "$JOB" = "e2e" ]; then
npm run e2e
else
npm run unit
fi

View File

@ -10,11 +10,19 @@ var concat = require('gulp-concat');
var gulp = require('gulp');
var sass = require('gulp-sass');
var replace = require('gulp-replace');
var uglify = require('gulp-uglify');
var rename = require('gulp-rename');
paths.redocBuilt = path.join(paths.output, paths.outputName) + '.js';
paths.redocBuilt = path.join(paths.output, paths.outputName);
gulp.task('build', function (callback) {
return runSequence(
'clean',
'bundleProd',
callback
);
});
gulp.task('buildDev', function (callback) {
return runSequence(
'clean',
'bundle',
@ -22,7 +30,9 @@ gulp.task('build', function (callback) {
);
});
gulp.task('bundle', ['bundleSfx', 'concatDeps', 'uglify']);
gulp.task('bundle', ['buildStatic', 'concatDeps']);
gulp.task('bundleProd', ['bundle', 'buildStaticMin', 'concatDepsMin']);
gulp.task('inlineTemplates', ['sass'], function() {
return gulp.src(paths.source, { base: './' })
@ -31,21 +41,18 @@ gulp.task('inlineTemplates', ['sass'], function() {
.pipe(gulp.dest(paths.tmp));
});
// produces minimized verstion of sfx bundle
gulp.task('uglify', ['concatDeps'], function() {
return gulp.src(paths.redocBuilt)
.pipe(sourcemaps.init())
.pipe(uglify())
.pipe(rename(paths.outputName + '.min.js'))
.pipe(sourcemaps.write('./'))
.pipe(gulp.dest(paths.output));
});
var JS_DEV_DEPS = [
'node_modules/zone.js/dist/zone-microtask.js',
'node_modules/reflect-metadata/Reflect.js'
'node_modules/reflect-metadata/Reflect.js',
'node_modules/babel-polyfill/dist/polyfill.js'
];
var JS_DEV_DEPS_MIN = [
'node_modules/zone.js/dist/zone-microtask.min.js',
'node_modules/reflect-metadata/Reflect.js',
'node_modules/babel-polyfill/dist/polyfill.min.js'
]
gulp.task('sass', function () {
return gulp.src(paths.scss, { base: './' })
.pipe(sass.sync().on('error', sass.logError))
@ -53,15 +60,31 @@ gulp.task('sass', function () {
});
// concatenate angular2 deps
gulp.task('concatDeps', ['bundleSfx'], function() {
gulp.src(JS_DEV_DEPS.concat([paths.redocBuilt]))
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(concat(paths.outputName + '.js'))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(paths.output))
gulp.task('concatDeps', ['buildStatic'], function() {
return concatDeps(JS_DEV_DEPS, paths.redocBuilt + '.js');
});
gulp.task('bundleSfx', ['inlineTemplates'], function(cb) {
gulp.task('concatDepsMin', ['buildStatic'], function() {
return concatDeps(JS_DEV_DEPS_MIN, paths.redocBuilt + '.min.js');
});
gulp.task('buildStatic', ['inlineTemplates'], function(cb) {
bundle(paths.redocBuilt + '.js', false, cb);
});
gulp.task('buildStaticMin', ['inlineTemplates'], function(cb) {
bundle(paths.redocBuilt + '.min.js', true, cb);
});
function concatDeps(deps, file) {
return gulp.src(deps.concat([file]))
.pipe(sourcemaps.init({loadMaps: true}))
.pipe(concat(file))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('.'))
}
function bundle(outputFile, minify, cb) {
fs.existsSync('dist') || fs.mkdirSync('dist');
var builder = new Builder('./', 'system.config.js');
builder.config({
@ -70,8 +93,8 @@ gulp.task('bundleSfx', ['inlineTemplates'], function(cb) {
builder
.buildStatic(path.join(paths.tmp, paths.sourceEntryPoint),
paths.redocBuilt,
{ format:'amd', sourceMaps: true, lowResSourceMaps: true }
outputFile,
{ format:'umd', sourceMaps: true, lowResSourceMaps: true, minify: minify }
)
.then(function() {
cb();
@ -79,4 +102,4 @@ gulp.task('bundleSfx', ['inlineTemplates'], function(cb) {
.catch(function(err) {
cb(new Error(err));
});
});
}

34
build/tasks/e2e.js Normal file
View File

@ -0,0 +1,34 @@
var gulp = require('gulp');
var gp = require('gulp-protractor');
var browserSync = require('browser-sync').create('bs-e2e');
gulp.task('test-server', function (done) {
browserSync.init({
open: false,
notify: false,
port: 3000,
ghostMode: false,
server: {
baseDir: './tests/e2e',
routes: {
'/dist': './dist',
'/swagger.json': './demo/swagger.json'
},
}
}, done);
});
gulp.task('e2e', ['bundleProd', 'test-server'], function(done) {
gulp.src(['tests/e2e/**/*.js'], { read:false })
.pipe(gp.protractor({
configFile: './protractor.conf.js'
})).on('error', function(e) {
browserSync.exit();
throw e;
done();
}).on('end', function() {
browserSync.exit();
done();
});
});

View File

@ -6,7 +6,7 @@ function changed(event) {
console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
}
gulp.task('watch', ['build'], function () {
gulp.task('watch', ['buildDev'], function () {
gulp.watch([ paths.source ], [ 'bundle', browserSync.reload ]).on('change', changed);
gulp.watch([ paths.html ], [ 'bundle', browserSync.reload]).on('change', changed);
gulp.watch([ paths.scss ], [ 'bundle', browserSync.reload]).on('change', changed);

View File

@ -1,4 +1,4 @@
<!-- index.html -->
<!DOCTYPE html>
<html>
<head>
<title>ReDoc</title>

View File

@ -7,10 +7,6 @@ body {
padding-top: 50px;
}
p {
margin: 0;
}
nav input, nav button {
font-size: 16px;
height: 28px;
@ -50,20 +46,3 @@ nav {
top: 0;
z-index: 1;
}
redoc {
display: block;
box-sizing: border-box;
}
pre {
white-space: pre-wrap;
background-color: #f2f2f2;
padding: 10px;
overflow-x: auto;
line-height: normal;
}
code {
background-color: #f2f2f2;
}

View File

@ -773,7 +773,11 @@
"Pet": {
"type": "object",
"required": ["name", "photoUrls"],
"discriminator": "petType",
"properties": {
"petType": {
"type": "string"
},
"id": {
"type": "integer",
"format": "int64"
@ -815,6 +819,56 @@
"name": "Pet"
}
},
"Cat": {
"description": "A representation of a cat",
"allOf": [
{
"$ref": "#/definitions/Pet"
},
{
"type": "object",
"properties": {
"huntingSkill": {
"type": "string",
"description": "The measured skill for hunting",
"default": "lazy",
"enum": [
"clueless",
"lazy",
"adventurous",
"aggressive"
]
}
},
"required": [
"huntingSkill"
]
}
]
},
"Dog": {
"description": "A representation of a dog",
"allOf": [
{
"$ref": "#/definitions/Pet"
},
{
"type": "object",
"properties": {
"packSize": {
"type": "integer",
"format": "int32",
"description": "the size of the pack the dog is from",
"default": 0,
"minimum": 0
}
},
"required": [
"packSize"
]
}
]
},
"ApiResponse": {
"type": "object",
"properties": {

View File

@ -54,7 +54,7 @@ module.exports = function (config) {
jspm: {
config: 'system.config.js',
loadFiles: ['tests/**/*.spec.js', 'tests/helpers.js', 'lib/**/*.js'],
loadFiles: ['tests/unit/*.spec.js', 'tests/helpers.js', 'lib/**/*.js'],
serveFiles: ['tests/schemas/**/*.json', 'lib/**/*.html', '.tmp/lib/**/*.css'],
nocache: true
},

View File

@ -46,7 +46,7 @@ export default class StickySidebar {
stick() {
this.adapter.setStyle(this.element, 'position', 'fixed');
this.adapter.setStyle(this.element, 'top', this.scrollYOffset());
this.adapter.setStyle(this.element, 'top', this.scrollYOffset() + 'px');
}
unstick() {
@ -55,7 +55,7 @@ export default class StickySidebar {
}
get scrollY() {
return this.scrollParent.scrollY || this.scrollParent.scrollTop || 0;
return (this.scrollParent.pageYOffset !== null) ? this.scrollParent.pageYOffset : this.scrollParent.scrollTop;
}
ngOnInit() {

View File

@ -49,7 +49,9 @@ describe('Common components', () => {
it('should stick if scrolled more than scrollYOffset', () => {
spyOn(component, 'stick').and.callThrough();
fixture.detectChanges();
window.scrollY = 40;
component.scrollParent = {
pageYOffset: 40
};
component.updatePosition();
expect(component.stick).toHaveBeenCalled();
});

View File

@ -10,8 +10,7 @@ import {CORE_DIRECTIVES} from 'angular2/common';
template: `
<ul>
<li *ngFor="#tab of tabs" [ngClass]="{active: tab.active}" (click)="selectTab(tab)"
class="tab-{{tab.tabStatus}}"> {{tab.tabTitle}}
</li>
class="tab-{{tab.tabStatus}}">{{tab.tabTitle}}</li>
</ul>
<ng-content></ng-content>
`,

View File

@ -3,24 +3,16 @@
ul {
display: block;
margin: 0;
padding: 10px 0px 0 0;
padding: 0;
}
li {
font-size: 13px;
list-style: none;
margin: 2px 0;
padding: 2px 5px;
display: inline-block;
cursor: pointer;
color: #8A9094;
line-height: 1.25;
color: $sample-panel-headers-color;
}
li.active {
background-color: white;
color: #666;
}
.tab-success, .tab-error, .tab-redirect, .tab-info {
@ -31,9 +23,8 @@ li.active {
height: 6px;
width: 6px;
border-radius: 50%;
margin-right: 0.5em;
}
}
.tab-success:before {

View File

@ -1,6 +1,6 @@
<div class="zippy zippy-{{type}}" [ngClass]="{'zippy-empty': empty}">
<div class="zippy-title" (click)="toggle()">
<span class="zippy-indicator">{{ visible ? '▾' : '▸' }}</span>
<span class="zippy-indicator">{{ visible ? '&#9662;' : '&#9656;' }}</span>
{{title}}
</div>
<div class="zippy-content" [ngClass]="{'zippy-hidden': !visible}">

View File

@ -1,8 +1,7 @@
<small *ngIf="errorMessage">{{errorMessage}}</small>
<span *ngIf="isTrivial" class="param-type param-type-trivial" [ngClass]="type">{{_displayType}}</span>
<div *ngIf="!isTrivial" class="params-wrap" [ngClass]="{'params-array': isArray}">
<div *ngFor="#prop of data.properties" class="param-wrap">
<div class="param">
<div class="param" [ngClass]="{'discriminator': prop.isDiscriminator}">
<div class="param-name">
<span>{{prop._name}}</span>
</div>
@ -12,6 +11,7 @@
<span *ngIf="prop.isRequired" class="param-required">Required</span>
</div>
<div class="param-description" innerHtml="{{prop.description | marked}}"></div>
<div class="discriminator-info" *ngIf="prop.isDiscriminator"> This field value determines the exact schema: </div>
</div>
</div>
<div class="param-schema" [ngClass]="{'param-array': prop._isArray}" *ngIf="prop._pointer">
@ -19,4 +19,12 @@
</json-schema>
</div>
</div>
<div *ngIf="data.derived.length" class="param-wrap">
<tabs>
<tab *ngFor="#derived of data.derived" tabTitle="{{derived.name}}">
<json-schema pointer="{{derived.$ref}}" [final]="derived.final">
</json-schema>
</tab>
</tabs>
</div>
</div>

View File

@ -1,6 +1,7 @@
'use strict';
import {RedocComponent, BaseComponent} from '../base';
import {Tabs, Tab} from '../../common/components/Tabs/tabs';
import {ElementRef} from 'angular2/core';
import JsonPointer from '../../utils/JsonPointer';
@ -8,24 +9,23 @@ import JsonPointer from '../../utils/JsonPointer';
selector: 'json-schema',
templateUrl: './lib/components/JsonSchema/json-schema.html',
styleUrls: ['./lib/components/JsonSchema/json-schema.css'],
directives: [JsonSchema],
inputs: ['isArray']
directives: [JsonSchema, Tabs, Tab],
inputs: ['isArray', 'final']
})
export default class JsonSchema extends BaseComponent {
constructor(schemaMgr, elementRef) {
super(schemaMgr);
this.element = elementRef.nativeElement;
this.final = false;
}
prepareModel() {
this.data = {};
this.data.properties = [];
this.data.derived = [];
if (!this.componentSchema) {
// TODO
this.errorMessage = 'Can\'t load component schema';
console.warn(`${this.errorMessage}: ${this.pointer}`);
return;
throw new Error(`Can't load component schema at ${this.pointer}`);
}
this.dereference();
@ -33,9 +33,19 @@ export default class JsonSchema extends BaseComponent {
if (schema.type === 'array') {
this.isArray = true;
if (schema._pointer) {
this.pointer = JsonPointer.join(schema._pointer, 'items');
}
schema = schema.items;
}
this.joinAllOf(schema);
let normPtr = schema._pointer || this.pointer;
let derived = this.schemaMgr.findDerivedDefinitions( normPtr );
if (!this.final && derived.length) {
this.data.derived = derived;
this.data.discriminator = schema.discriminator;
}
this.joinAllOf(schema, {omitParent: true});
if (schema.type !== 'object') {
this.isTrivial = true;
@ -56,11 +66,19 @@ export default class JsonSchema extends BaseComponent {
this._displayType = `${schema.type} (Custom key-value pairs)`;
return;
}
let props = Object.keys(schema.properties).map(prop => {
let discriminatorFieldIdx = -1;
let props = Object.keys(schema.properties).map((prop, idx) => {
let propData = schema.properties[prop];
this.injectPropData(prop, propData);
this.injectPropData(prop, propData, schema);
if (propData.isDiscriminator) discriminatorFieldIdx = idx;
return propData;
});
// Move discriminator field to the end of properties list
if (discriminatorFieldIdx > -1) {
let discrProp = props.splice(discriminatorFieldIdx, 1);
props.push(discrProp[0]);
}
this.data.properties = props;
}
@ -73,16 +91,20 @@ export default class JsonSchema extends BaseComponent {
names.forEach(el => {
el.style.minWidth = maxWidth + 'px';
});
let discrValues = this.element.querySelector('tabs ul');
if (discrValues) discrValues.style.paddingLeft = maxWidth + 'px';
}
injectPropData(prop, propData) {
injectPropData(prop, propData, schema) {
propData._name = prop;
propData.isRequired = this.requiredMap[prop];
propData._displayType = propData.type;
propData.isDiscriminator = (schema.discriminator === prop);
if (propData.type === 'array') {
let itemType = propData.items.type;
let itemFormat = propData.items.format;
if (itemType === 'object') {
if (itemType === 'object' || !itemType) {
itemType = propData.items.title || 'object';
propData._pointer = propData.items._pointer || JsonPointer.join(this.pointer, ['properties', prop, 'items']);
}

View File

@ -5,7 +5,7 @@ $cell-spacing: 25px;
$cell-padding: 10px;
$bullet-margin: 10px;
$line-border: $lines-width solid $tree-lines-color;
$line-border-erase: $lines-width solid white;
$line-border-erase: ($lines-width + 1px) solid white;
$param-name-height: 20px;
@ -38,10 +38,6 @@ $sub-schema-offset: ($bullet-size/2) + $bullet-margin;
border-left: $line-border;
white-space: nowrap;
position: relative;
> span {
vertical-align: middle;
}
}
.param-info {
@ -113,7 +109,7 @@ $sub-schema-offset: ($bullet-size/2) + $bullet-margin;
content: "";
display: block;
position: absolute;
left: -$lines-width;
left: -$lines-width - 1px;
border-left: $line-border-erase;
top: ($param-name-height/2) + $cell-padding + $lines-width;
background-color: white;
@ -146,6 +142,7 @@ $array-marker-line-height: 1.5;
.params-wrap.params-array:before {
content: "Array [";
padding-top: 1em;
}
.params-wrap.params-array {
@ -168,3 +165,37 @@ $array-marker-line-height: 1.5;
border-left: $line-border-erase;
height: ($param-name-height/2) + $cell-padding;
}
.param.discriminator {
> div {
padding-bottom: 0;
border-bottom: 0;
}
}
.discriminator-info {
font-weight: bold;
}
:host tabs {
display: block;
border-left: 1px solid $tree-lines-color;
}
:host tabs li {
margin: 0.2em 0.5em 0.2em 0;
font-size: 14px;
border: 0;
color: white;
padding: 0 15px;
border-radius: 10px;
background-color: #8A9094;
&:last-of-type {
margin: 0;
}
&.active {
background-color: $headers-color;
}
}

View File

@ -31,6 +31,7 @@ export default class Method extends BaseComponent {
filterMainTags(tags) {
var tagsMap = this.schemaMgr.getTagsMap();
if (!tags) return [];
return tags.filter(tag => tagsMap[tag] && tagsMap[tag]['x-traitTag']);
}

View File

@ -82,29 +82,44 @@ export default class Redoc extends BaseComponent {
}
static init(schemaUrl, options) {
var promise = new Promise(function(resolve, reject) {
if (Redoc.appRef) {
Redoc.dispose();
}
return SchemaManager.instance().load(schemaUrl)
.then(() => {
(new OptionsManager()).options = options;
return bootstrap(Redoc);
})
.then(
(appRef) => {
Redoc.appRef = appRef;
redocEvents.bootstrapped.next();
console.log('ReDoc bootstrapped!');
},
error => {
console.log(error);
throw error;
}
);
}
SchemaManager.instance().load(schemaUrl)
.then(() => {
(new OptionsManager()).options = options;
return bootstrap(Redoc);
})
.then(
() => {
redocEvents.bootstrapped.next();
console.log('ReDoc bootstrapped!');
resolve();
},
error => {
console.log(error);
reject();
}
);
});
return promise;
static dispose() {
let dom = new BrowserDomAdapter();
let el = dom.query('redoc');
let parent = el.parentElement;
let nextSibling = el.nextElementSibling;
Redoc.appRef && Redoc.appRef.dispose();
Redoc.appRef = null;
// Redoc dispose removes host element, so need to restore it
el = dom.createElement('redoc');
el.innerText = 'Loading...';
parent.insertBefore(el, nextSibling);
}
}
Redoc.parameters = Redoc.parameters.concat([[OptionsManager], [ElementRef], [BrowserDomAdapter]]);
// TODO
// this doesn't work in side-menu.js because of some circular references issue
SideMenu.parameters = SideMenu.parameters.concat([[Redoc]]);

View File

@ -1,5 +1,28 @@
@import '../../common/styles/variables';
:host {
display: block;
box-sizing: border-box;
}
:host {
pre {
white-space: pre-wrap;
background-color: #f2f2f2;
padding: 10px;
overflow-x: auto;
line-height: normal;
}
code {
background-color: #f2f2f2;
}
p {
margin: 0;
}
}
.redoc-wrap {
position: relative;
}

View File

@ -14,3 +14,21 @@ header {
color: $sample-panel-headers-color;
text-transform: uppercase;
}
:host tabs li {
font-size: 13px;
margin: 2px 0;
padding: 2px 5px;
color: #8A9094;
line-height: 1.25;
color: $sample-panel-headers-color;
&.active {
background-color: white;
color: #666;
}
}
:host tabs ul {
padding-top: 10px;
}

View File

@ -48,7 +48,7 @@ export default class SideMenu extends BaseComponent {
}
scrollY() {
return (this.scrollParent.scrollY != null) ? this.scrollParent.scrollY : this.scrollParent.scrollTop;
return (this.scrollParent.pageYOffset != null) ? this.scrollParent.pageYOffset : this.scrollParent.scrollTop;
}
hashScroll(evt) {

View File

@ -15,6 +15,22 @@ function safeConcat(a, b) {
return res.concat(b);
}
function snapshot(obj) {
if(obj == null || typeof(obj) != 'object') {
return obj;
}
var temp = new obj.constructor();
for(var key in obj) {
if (obj.hasOwnProperty(key)) {
temp[key] = snapshot(obj[key]);
}
}
return temp;
}
/**
* Class decorator
* Simplifies setup of component metainfo
@ -72,7 +88,7 @@ export class BaseComponent {
* onInit method is run by angular2 after all component inputs are resolved
*/
ngOnInit() {
this.componentSchema = this.schemaMgr.byPointer(this.pointer || '');
this.componentSchema = snapshot(this.schemaMgr.byPointer(this.pointer || ''));
this.prepareModel();
this.init();
}
@ -83,31 +99,57 @@ export class BaseComponent {
/**
* simple in-place schema dereferencing. Schema is already bundled so no need in global dereferencing.
* TODO: doesn't support circular references
*/
dereference(schema = Object.assign({}, this.componentSchema)) {
//schema = Object.assign({}, schema);
if (schema && schema.$ref) {
let resolved = this.schemaMgr.byPointer(schema.$ref);
let baseName = JsonPointer.baseName(schema.$ref);
// if resolved schema doesn't have title use name from ref
resolved = Object.assign({}, resolved);
resolved.title = resolved.title || baseName;
resolved._pointer = schema.$ref;
Object.assign(schema, resolved);
delete schema.$ref;
}
let dereferencedCache = {};
Object.keys(schema).forEach((key) => {
let value = schema[key];
if (value && typeof value === 'object') {
this.dereference(value);
let resolve = (schema) => {
if (schema && schema.$ref) {
let resolved = this.schemaMgr.byPointer(schema.$ref);
let baseName = JsonPointer.baseName(schema.$ref);
if (!dereferencedCache[schema.$ref]) {
// if resolved schema doesn't have title use name from ref
resolved = Object.assign({}, resolved);
resolved._pointer = schema.$ref;
} else {
// for circular referenced save only title and type
resolved = {
title: resolved.title
};
}
dereferencedCache[schema.$ref] = true;
resolved.title = resolved.title || baseName;
let keysCount = Object.keys(schema).length;
if ( keysCount > 2 || (keysCount === 2 && !schema.description) ) {
// allow only description field on the same level as $ref because it is
// common pattern over specs in the wild
console.warn(`other properties defined at the same level as $ref at '${this.pointer}'.
They are IGNORRED according to JsonSchema spec`);
}
schema = schema.description ? {
description: schema.description
} : {};
//for (var prop in schema) delete schema[prop];
Object.assign(schema, resolved);
}
});
this.componentSchema = schema;
Object.keys(schema).forEach((key) => {
let value = schema[key];
if (value && typeof value === 'object') {
schema[key] = resolve(value);
}
});
return schema;
};
this.componentSchema = resolve(schema);
}
joinAllOf(schema = this.componentSchema) {
joinAllOf(schema = this.componentSchema, opts) {
var self = this;
function merge(into, schemas) {
if (into.required || into.properties) {
@ -118,6 +160,7 @@ export class BaseComponent {
into.required = [];
into.properties = {};
for (let subSchema of schemas) {
if (opts && opts.omitParent && subSchema.discriminator) continue;
// TODO: add support for merge array schemas
if (typeof subSchema !== 'object' || subSchema.type !== 'object') {

View File

@ -26,7 +26,7 @@ describe('Redoc components', () => {
it('should set componentSchema based on pointer on ngOnInit', () => {
component.pointer = '/tags';
component.ngOnInit();
component.componentSchema.should.be.equal(schemaMgr._schema.tags);
component.componentSchema.should.be.deepEqual(schemaMgr._schema.tags);
});
it('should call prepareModel and init virtual methods after init', () => {
@ -111,6 +111,47 @@ describe('Redoc components', () => {
paramWithRef.items.schema.type.should.be.equal('object');
});
});
describe('circular dereference', () => {
let paramWithRef;
beforeAll(() => {
component.pointer = '/paths/test4/get';
component.ngOnInit();
component.dereference();
paramWithRef = component.componentSchema.parameters[0];
});
it('should resolve circular schema', () => {
expect(paramWithRef.$ref).toBeUndefined();
expect(paramWithRef.items.schema.$ref).toBeUndefined();
paramWithRef.type.should.be.equal('array');
paramWithRef._pointer.should.be.equal('#/definitions/Circular');
expect(paramWithRef.items.schema._pointer).toBeUndefined();
paramWithRef.items.schema.title.should.be.equal('Circular');
});
});
describe('$ref with other fields on the same level', () => {
let paramWithRef;
beforeAll(() => {
component.pointer = '/paths/test5/get';
component.ngOnInit();
component.dereference();
paramWithRef = component.componentSchema.parameters[0];
});
it('should skip other fields', () => {
expect(paramWithRef.$ref).toBeUndefined();
expect(paramWithRef.title).toBeDefined();
paramWithRef.title.should.be.equal('Simple');
});
it('should preserve description field', () => {
expect(paramWithRef.$ref).toBeUndefined();
expect(paramWithRef.description).toBeDefined();
paramWithRef.description.should.be.equal('test');
});
});
});
describe('mergeAllOf', () => {

View File

@ -1,7 +1,9 @@
'use strict';
import {Redoc} from './components/index';
import {enableProdMode} from 'angular2/core';
export var init = Redoc.init;
window.Redoc = Redoc;
enableProdMode();

View File

@ -52,7 +52,8 @@ export default class SchemaManager {
byPointer(pointer) {
let res = null;
try {
res = JsonPointer.get(this._schema, pointer);
// TODO: remove decodeURIComponent after this issue is fixed: https://github.com/BigstickCarpet/swagger-parser/issues/31
res = JsonPointer.get(this._schema, decodeURIComponent(pointer));
} catch(e) {/*skip*/ }
return res;
}
@ -156,4 +157,26 @@ export default class SchemaManager {
return tag2MethodMapping;
}
findDerivedDefinitions(defPointer) {
let definition = this.byPointer(defPointer);
if (!definition) throw new Error(`Can't load schema at ${defPointer}`);
if (!definition.discriminator) return [];
let globalDefs = this._schema.definitions || {};
let res = [];
for (let defName of Object.keys(globalDefs)) {
if (!globalDefs[defName].allOf) continue;
let subTypes = globalDefs[defName].allOf;
let idx = subTypes.findIndex((subType) => {
if (subType.$ref === defPointer) return true;
return false;
});
if (idx < 0) continue;
res.push({name: defName, $ref: `#/definitions/${defName}`});
}
return res;
}
}

View File

@ -1,18 +1,21 @@
{
"name": "ReDoc",
"name": "redoc",
"description": "Swagger-generated API Reference Documentation",
"version": "0.0.1",
"private": true,
"version": "0.1.0",
"repository": {
"type": "git",
"url": "git://github.com/Rebilly/ReDoc"
},
"main": "dist/redoc.full.min.js",
"scripts": {
"test": "gulp lint && gulp test",
"test": "gulp lint && ./build/run_tests.sh",
"prepublish": "gulp build",
"postinstall": "jspm install",
"start": "gulp serve",
"build-dist": "gulp build",
"branch-release": "branch-release"
"branch-release": "git reset --hard && branch-release",
"unit": "gulp test",
"e2e": "gulp e2e"
},
"keywords": [
"Swagger",
@ -26,16 +29,15 @@
"jspm": {
"configFile": "system.config.js",
"dependencies": {
"RomanGotsiy/json-schema-ref-parser": "github:RomanGotsiy/json-schema-ref-parser@master",
"angular2": "npm:angular2@^2.0.0-beta.0",
"es6-shim": "github:es-shims/es6-shim@^0.33.6",
"json-formatter-js": "npm:json-formatter-js@^0.2.0",
"json-pointer": "npm:json-pointer@^0.3.0",
"json-schema-instantiator": "npm:json-schema-instantiator@^0.3.0",
"json-schema-view-js": "npm:json-schema-view-js@^0.2.0",
"json-schema-ref-parser": "npm:json-schema-ref-parser@2.2.0",
"marked": "npm:marked@^0.3.5",
"scrollparent": "npm:scrollparent@^0.1.0",
"swagger-parser": "npm:swagger-parser@^3.3.0"
"swagger-parser": "npm:swagger-parser@^3.4.0"
},
"devDependencies": {
"babel": "npm:babel-core@^5.8.34",
@ -44,31 +46,27 @@
"core-js": "npm:core-js@^1.2.6",
"css": "github:systemjs/plugin-css@^0.1.18",
"systemjs/plugin-json": "github:systemjs/plugin-json@^0.1.0"
},
"overrides": {
"github:RomanGotsiy/json-schema-ref-parser@master": {
"registry": "npm"
}
}
},
"devDependencies": {
"babel-eslint": "^4.1.6",
"babel-polyfill": "^6.3.14",
"branch-release": "^0.2.1",
"branch-release": "^0.3.1",
"browser-sync": "^2.10.1",
"del": "^2.2.0",
"gulp": "^3.9.0",
"gulp-concat": "^2.6.0",
"gulp-eslint": "^1.1.1",
"gulp-inline-ng2-template": "^0.0.9",
"gulp-protractor": "^2.1.0",
"gulp-rename": "^1.2.2",
"gulp-replace": "^0.5.4",
"gulp-sass": "^2.1.1",
"gulp-sourcemaps": "^1.6.0",
"gulp-uglify": "^1.5.1",
"isparta": "^4.0.0",
"istanbul": "github:gotwarlost/istanbul#source-map",
"jasmine-core": "^2.4.1",
"jasmine-spec-reporter": "^2.4.0",
"jspm": "^0.16.19",
"karma": "^0.13.15",
"karma-babel-preprocessor": "^5.2.2",
@ -84,12 +82,13 @@
"karma-should": "^1.0.0",
"karma-sinon": "^1.0.4",
"phantomjs": "^1.9.19",
"protractor": "^3.0.0",
"reflect-metadata": "^0.1.2",
"require-dir": "^0.3.0",
"run-sequence": "^1.1.5",
"should": "^8.0.2",
"sinon": "^1.17.2",
"systemjs-builder": "^0.14.15",
"systemjs-builder": "^0.15.2",
"vinyl-paths": "^2.0.0",
"zone.js": "^0.5.10"
}

69
protractor.conf.js Normal file
View File

@ -0,0 +1,69 @@
'use strict';
const loadJson = require('./tests/e2e/helpers').loadJson;
const travis = process.env.TRAVIS;
let config = {
specs: ['./tests/e2e/**/*.js'],
baseUrl: 'http://localhost:3000',
framework: 'jasmine2',
onPrepare: function() {
var SpecReporter = require('jasmine-spec-reporter');
// add jasmine spec reporter
jasmine.getEnv().addReporter(new SpecReporter({displaySpecDuration: true}));
// load APIs.guru list
return loadJson('https://apis-guru.github.io/api-models/api/v1/list.json').then((list) => {
global.apisGuruList = list;
return browser.getCapabilities().then(function (cap) {
browser.isIE = cap.caps_.browserName === 'internet explorer';
});
});
},
//directConnect: true,
useAllAngular2AppRoots: true,
allScriptsTimeout: 180000,
jasmineNodeOpts: {
showTiming: true,
showColors: true,
defaultTimeoutInterval: 180000,
print: function() {}
},
multiCapabilities: [
{ browserName: 'chrome' },
{ browserName: 'firefox' }
]
};
if (travis) {
config.sauceUser = process.env.SAUCE_USERNAME;
config.sauceKey = process.env.SAUCE_ACCESS_KEY;
config.sauceSeleniumAddres = 'localhost:4445/wd/hub';
config.multiCapabilities = [{
browserName: 'chrome',
'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER,
build: process.env.TRAVIS_BUILD_NUMBER,
name: 'Redoc Chrome/Linux build ' + process.env.TRAVIS_BUILD_NUMBER
},{
browserName: 'safari',
platform: 'OS X 10.11',
version: '9.0',
'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER,
build: process.env.TRAVIS_BUILD_NUMBER,
name: 'Redoc Safari Latest/OSX build ' + process.env.TRAVIS_BUILD_NUMBER,
idleTimeout: 180
},{
browserName: 'firefox',
'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER,
build: process.env.TRAVIS_BUILD_NUMBER,
name: 'Redoc Firefox Latest/Win build ' + process.env.TRAVIS_BUILD_NUMBER
},{
browserName: 'internet explorer',
version: '11.0',
'tunnel-identifier': process.env.TRAVIS_JOB_NUMBER,
build: process.env.TRAVIS_BUILD_NUMBER,
name: 'Redoc IE11/Win build ' + process.env.TRAVIS_BUILD_NUMBER
}];
} else {
config.directConnect = true;
}
exports.config = config;

View File

@ -16,7 +16,7 @@ System.config({
},
packages: {
"npm:swagger-schema-official@2.0.0-d79c205": {
"npm:swagger-schema-official@2.0.0-bab6bed": {
"defaultExtension": "json",
"main": "schema.json",
"meta": {
@ -37,7 +37,6 @@ System.config({
},
map: {
"RomanGotsiy/json-schema-ref-parser": "github:RomanGotsiy/json-schema-ref-parser@master",
"angular2": "npm:angular2@2.0.0-beta.0",
"babel": "npm:babel-core@5.8.34",
"babel-runtime": "npm:babel-runtime@5.8.34",
@ -49,40 +48,16 @@ System.config({
"json-formatter-js": "npm:json-formatter-js@0.2.0",
"json-pointer": "npm:json-pointer@0.3.0",
"json-schema-instantiator": "npm:json-schema-instantiator@0.3.0",
"json-schema-view-js": "npm:json-schema-view-js@0.2.0",
"json-schema-ref-parser": "npm:json-schema-ref-parser@2.2.0",
"marked": "npm:marked@0.3.5",
"scrollparent": "npm:scrollparent@0.1.0",
"swagger-parser": "npm:swagger-parser@3.3.0",
"swagger-parser": "npm:swagger-parser@3.4.0",
"systemjs/plugin-json": "github:systemjs/plugin-json@0.1.0",
"github:RomanGotsiy/json-schema-ref-parser@master": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"call-me-maybe": "npm:call-me-maybe@1.0.1",
"child_process": "github:jspm/nodelibs-child_process@0.1.0",
"debug": "npm:debug@2.2.0",
"es6-promise": "npm:es6-promise@3.0.2",
"events": "github:jspm/nodelibs-events@0.1.1",
"fs": "github:jspm/nodelibs-fs@0.1.2",
"http": "github:jspm/nodelibs-http@1.7.1",
"https": "github:jspm/nodelibs-https@0.1.0",
"js-yaml": "npm:js-yaml@3.4.3",
"ono": "npm:ono@1.0.22",
"os": "github:jspm/nodelibs-os@0.1.0",
"path": "github:jspm/nodelibs-path@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2",
"punycode": "github:jspm/nodelibs-punycode@0.1.0",
"querystring": "github:jspm/nodelibs-querystring@0.1.0",
"stream": "github:jspm/nodelibs-stream@0.1.0",
"string_decoder": "github:jspm/nodelibs-string_decoder@0.1.0",
"systemjs-json": "github:systemjs/plugin-json@0.1.0",
"tty": "github:jspm/nodelibs-tty@0.1.0",
"url": "github:jspm/nodelibs-url@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"github:jspm/nodelibs-assert@0.1.0": {
"assert": "npm:assert@1.3.0"
},
"github:jspm/nodelibs-buffer@0.1.0": {
"buffer": "npm:buffer@3.5.5"
"buffer": "npm:buffer@3.6.0"
},
"github:jspm/nodelibs-constants@0.1.0": {
"constants-browserify": "npm:constants-browserify@0.0.1"
@ -177,15 +152,15 @@ System.config({
"sprintf-js": "npm:sprintf-js@1.0.3",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:asn1.js@4.2.1": {
"npm:asn1.js@4.3.0": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
"bn.js": "npm:bn.js@4.5.2",
"bn.js": "npm:bn.js@4.6.4",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"inherits": "npm:inherits@2.0.1",
"minimalistic-assert": "npm:minimalistic-assert@1.0.0",
"vm": "github:jspm/nodelibs-vm@0.1.0"
},
"npm:asn1@0.1.11": {
"npm:asn1@0.2.3": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"sys": "github:jspm/nodelibs-util@0.1.0",
@ -198,13 +173,20 @@ System.config({
"stream": "github:jspm/nodelibs-stream@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:assert-plus@0.2.0": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2",
"stream": "github:jspm/nodelibs-stream@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:assert@1.3.0": {
"util": "npm:util@0.10.3"
},
"npm:async@1.4.2": {
"npm:async@1.5.2": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:aws-sign2@0.5.0": {
"npm:aws-sign2@0.6.0": {
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"url": "github:jspm/nodelibs-url@0.1.0"
},
@ -213,13 +195,10 @@ System.config({
},
"npm:bl@1.0.0": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"readable-stream": "npm:readable-stream@2.0.2",
"readable-stream": "npm:readable-stream@2.0.5",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:bluebird@2.10.2": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:boom@2.9.0": {
"npm:boom@2.10.1": {
"hoek": "npm:hoek@2.16.3",
"http": "github:jspm/nodelibs-http@1.7.1"
},
@ -249,14 +228,14 @@ System.config({
"inherits": "npm:inherits@2.0.1"
},
"npm:browserify-rsa@4.0.0": {
"bn.js": "npm:bn.js@4.5.2",
"bn.js": "npm:bn.js@4.6.4",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"constants": "github:jspm/nodelibs-constants@0.1.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"randombytes": "npm:randombytes@2.0.1"
"randombytes": "npm:randombytes@2.0.2"
},
"npm:browserify-sign@4.0.0": {
"bn.js": "npm:bn.js@4.5.2",
"bn.js": "npm:bn.js@4.6.4",
"browserify-rsa": "npm:browserify-rsa@4.0.0",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"create-hash": "npm:create-hash@1.1.2",
@ -272,14 +251,14 @@ System.config({
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"pako": "npm:pako@0.2.8",
"process": "github:jspm/nodelibs-process@0.1.2",
"readable-stream": "npm:readable-stream@1.1.13",
"readable-stream": "npm:readable-stream@2.0.5",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:buffer-xor@1.0.3": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
},
"npm:buffer@3.5.5": {
"npm:buffer@3.6.0": {
"base64-js": "npm:base64-js@0.0.8",
"child_process": "github:jspm/nodelibs-child_process@0.1.0",
"fs": "github:jspm/nodelibs-fs@0.1.2",
@ -292,7 +271,7 @@ System.config({
},
"npm:chalk@1.1.1": {
"ansi-styles": "npm:ansi-styles@2.1.0",
"escape-string-regexp": "npm:escape-string-regexp@1.0.3",
"escape-string-regexp": "npm:escape-string-regexp@1.0.4",
"has-ansi": "npm:has-ansi@2.0.0",
"process": "github:jspm/nodelibs-process@0.1.2",
"strip-ansi": "npm:strip-ansi@3.0.0",
@ -331,6 +310,14 @@ System.config({
"path": "github:jspm/nodelibs-path@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:commander@2.9.0": {
"child_process": "github:jspm/nodelibs-child_process@0.1.0",
"events": "github:jspm/nodelibs-events@0.1.1",
"fs": "github:jspm/nodelibs-fs@0.1.2",
"graceful-readlink": "npm:graceful-readlink@1.0.1",
"path": "github:jspm/nodelibs-path@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:constants-browserify@0.0.1": {
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
},
@ -340,14 +327,11 @@ System.config({
"process": "github:jspm/nodelibs-process@0.1.2",
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
},
"npm:core-util-is@1.0.1": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0"
},
"npm:core-util-is@1.0.2": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0"
},
"npm:create-ecdh@4.0.0": {
"bn.js": "npm:bn.js@4.5.2",
"bn.js": "npm:bn.js@4.6.4",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"elliptic": "npm:elliptic@6.0.2"
@ -369,7 +353,7 @@ System.config({
"stream": "github:jspm/nodelibs-stream@0.1.0"
},
"npm:cryptiles@2.0.5": {
"boom": "npm:boom@2.9.0",
"boom": "npm:boom@2.10.1",
"crypto": "github:jspm/nodelibs-crypto@0.1.0"
},
"npm:crypto-browserify@3.11.0": {
@ -378,16 +362,18 @@ System.config({
"create-ecdh": "npm:create-ecdh@4.0.0",
"create-hash": "npm:create-hash@1.1.2",
"create-hmac": "npm:create-hmac@1.1.4",
"diffie-hellman": "npm:diffie-hellman@5.0.0",
"diffie-hellman": "npm:diffie-hellman@5.0.1",
"inherits": "npm:inherits@2.0.1",
"pbkdf2": "npm:pbkdf2@3.0.4",
"public-encrypt": "npm:public-encrypt@4.0.0",
"randombytes": "npm:randombytes@2.0.1"
"randombytes": "npm:randombytes@2.0.2"
},
"npm:ctype@0.5.3": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2"
"npm:dashdash@1.12.1": {
"assert-plus": "npm:assert-plus@0.1.5",
"fs": "github:jspm/nodelibs-fs@0.1.2",
"path": "github:jspm/nodelibs-path@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:debug@2.2.0": {
"fs": "github:jspm/nodelibs-fs@0.1.2",
@ -406,16 +392,21 @@ System.config({
"inherits": "npm:inherits@2.0.1",
"minimalistic-assert": "npm:minimalistic-assert@1.0.0"
},
"npm:diffie-hellman@5.0.0": {
"bn.js": "npm:bn.js@4.5.2",
"npm:diffie-hellman@5.0.1": {
"bn.js": "npm:bn.js@4.6.4",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"miller-rabin": "npm:miller-rabin@4.0.0",
"randombytes": "npm:randombytes@2.0.1",
"randombytes": "npm:randombytes@2.0.2",
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
},
"npm:ecc-jsbn@0.1.1": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"jsbn": "npm:jsbn@0.1.0"
},
"npm:elliptic@6.0.2": {
"bn.js": "npm:bn.js@4.5.2",
"bn.js": "npm:bn.js@4.6.4",
"brorand": "npm:brorand@1.0.5",
"hash.js": "npm:hash.js@1.0.3",
"inherits": "npm:inherits@2.0.1",
@ -427,7 +418,7 @@ System.config({
"npm:es6-shim@0.33.13": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:esprima@2.7.0": {
"npm:esprima@2.7.1": {
"fs": "github:jspm/nodelibs-fs@0.1.2",
"process": "github:jspm/nodelibs-process@0.1.2"
},
@ -436,6 +427,10 @@ System.config({
"create-hash": "npm:create-hash@1.1.2",
"crypto": "github:jspm/nodelibs-crypto@0.1.0"
},
"npm:extsprintf@1.0.2": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:forever-agent@0.6.1": {
"http": "github:jspm/nodelibs-http@1.7.1",
"https": "github:jspm/nodelibs-https@0.1.0",
@ -444,13 +439,13 @@ System.config({
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:form-data@1.0.0-rc3": {
"async": "npm:async@1.4.2",
"async": "npm:async@1.5.2",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"combined-stream": "npm:combined-stream@1.0.5",
"fs": "github:jspm/nodelibs-fs@0.1.2",
"http": "github:jspm/nodelibs-http@1.7.1",
"https": "github:jspm/nodelibs-https@0.1.0",
"mime-types": "npm:mime-types@2.1.7",
"mime-types": "npm:mime-types@2.1.9",
"path": "github:jspm/nodelibs-path@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2",
"url": "github:jspm/nodelibs-url@0.1.0",
@ -465,11 +460,11 @@ System.config({
"npm:graceful-readlink@1.0.1": {
"fs": "github:jspm/nodelibs-fs@0.1.2"
},
"npm:har-validator@1.8.0": {
"bluebird": "npm:bluebird@2.10.2",
"npm:har-validator@2.0.5": {
"chalk": "npm:chalk@1.1.1",
"commander": "npm:commander@2.8.1",
"is-my-json-valid": "npm:is-my-json-valid@2.12.2",
"commander": "npm:commander@2.9.0",
"is-my-json-valid": "npm:is-my-json-valid@2.12.3",
"pinkie-promise": "npm:pinkie-promise@2.0.0",
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
},
"npm:has-ansi@2.0.0": {
@ -478,8 +473,8 @@ System.config({
"npm:hash.js@1.0.3": {
"inherits": "npm:inherits@2.0.1"
},
"npm:hawk@3.1.0": {
"boom": "npm:boom@2.9.0",
"npm:hawk@3.1.2": {
"boom": "npm:boom@2.10.1",
"cryptiles": "npm:cryptiles@2.0.5",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"hoek": "npm:hoek@2.16.3",
@ -495,13 +490,13 @@ System.config({
"process": "github:jspm/nodelibs-process@0.1.2",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:http-signature@0.11.0": {
"asn1": "npm:asn1@0.1.11",
"npm:http-signature@1.1.0": {
"assert-plus": "npm:assert-plus@0.1.5",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"ctype": "npm:ctype@0.5.3",
"http": "github:jspm/nodelibs-http@1.7.1",
"jsprim": "npm:jsprim@1.2.2",
"sshpk": "npm:sshpk@1.7.3",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:https-browserify@0.0.0": {
@ -510,26 +505,30 @@ System.config({
"npm:inherits@2.0.1": {
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:is-my-json-valid@2.12.2": {
"npm:is-my-json-valid@2.12.3": {
"fs": "github:jspm/nodelibs-fs@0.1.2",
"generate-function": "npm:generate-function@2.0.0",
"generate-object-property": "npm:generate-object-property@1.2.0",
"jsonpointer": "npm:jsonpointer@2.0.0",
"path": "github:jspm/nodelibs-path@0.1.0",
"xtend": "npm:xtend@4.0.0"
"xtend": "npm:xtend@4.0.1"
},
"npm:isstream@0.1.2": {
"events": "github:jspm/nodelibs-events@0.1.1",
"stream": "github:jspm/nodelibs-stream@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:js-yaml@3.4.3": {
"npm:jodid25519@1.0.2": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"jsbn": "npm:jsbn@0.1.0"
},
"npm:js-yaml@3.5.2": {
"argparse": "npm:argparse@1.0.3",
"esprima": "npm:esprima@2.7.0",
"esprima": "npm:esprima@2.7.1",
"fs": "github:jspm/nodelibs-fs@0.1.2",
"process": "github:jspm/nodelibs-process@0.1.2",
"systemjs-json": "github:systemjs/plugin-json@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
},
"npm:json-formatter-js@0.2.0": {
"fs": "github:jspm/nodelibs-fs@0.1.2",
@ -539,14 +538,55 @@ System.config({
"npm:json-pointer@0.3.0": {
"foreach": "npm:foreach@2.0.5"
},
"npm:json-schema-view-js@0.2.0": {
"npm:json-schema-ref-parser@1.4.1": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"call-me-maybe": "npm:call-me-maybe@1.0.1",
"debug": "npm:debug@2.2.0",
"es6-promise": "npm:es6-promise@3.0.2",
"events": "github:jspm/nodelibs-events@0.1.1",
"fs": "github:jspm/nodelibs-fs@0.1.2",
"http": "github:jspm/nodelibs-http@1.7.1",
"https": "github:jspm/nodelibs-https@0.1.0",
"js-yaml": "npm:js-yaml@3.5.2",
"ono": "npm:ono@2.0.1",
"process": "github:jspm/nodelibs-process@0.1.2",
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
"punycode": "github:jspm/nodelibs-punycode@0.1.0",
"querystring": "github:jspm/nodelibs-querystring@0.1.0",
"stream": "github:jspm/nodelibs-stream@0.1.0",
"string_decoder": "github:jspm/nodelibs-string_decoder@0.1.0",
"url": "github:jspm/nodelibs-url@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:json-schema-ref-parser@2.2.0": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"call-me-maybe": "npm:call-me-maybe@1.0.1",
"debug": "npm:debug@2.2.0",
"es6-promise": "npm:es6-promise@3.0.2",
"events": "github:jspm/nodelibs-events@0.1.1",
"fs": "github:jspm/nodelibs-fs@0.1.2",
"http": "github:jspm/nodelibs-http@1.7.1",
"https": "github:jspm/nodelibs-https@0.1.0",
"js-yaml": "npm:js-yaml@3.5.2",
"ono": "npm:ono@2.0.1",
"process": "github:jspm/nodelibs-process@0.1.2",
"punycode": "github:jspm/nodelibs-punycode@0.1.0",
"querystring": "github:jspm/nodelibs-querystring@0.1.0",
"stream": "github:jspm/nodelibs-stream@0.1.0",
"string_decoder": "github:jspm/nodelibs-string_decoder@0.1.0",
"url": "github:jspm/nodelibs-url@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:jsonpointer@2.0.0": {
"assert": "github:jspm/nodelibs-assert@0.1.0"
},
"npm:jsprim@1.2.2": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
"extsprintf": "npm:extsprintf@1.0.2",
"json-schema": "npm:json-schema@0.2.2",
"process": "github:jspm/nodelibs-process@0.1.2",
"util": "github:jspm/nodelibs-util@0.1.0",
"verror": "npm:verror@1.3.6"
},
"npm:lodash._baseget@3.7.2": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
@ -562,18 +602,19 @@ System.config({
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:miller-rabin@4.0.0": {
"bn.js": "npm:bn.js@4.5.2",
"bn.js": "npm:bn.js@4.6.4",
"brorand": "npm:brorand@1.0.5"
},
"npm:mime-db@1.19.0": {
"npm:mime-db@1.21.0": {
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
},
"npm:mime-types@2.1.7": {
"mime-db": "npm:mime-db@1.19.0",
"npm:mime-types@2.1.9": {
"mime-db": "npm:mime-db@1.21.0",
"path": "github:jspm/nodelibs-path@0.1.0"
},
"npm:node-uuid@1.4.3": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0"
"npm:node-uuid@1.4.7": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0"
},
"npm:oauth-sign@0.8.0": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
@ -581,7 +622,7 @@ System.config({
"process": "github:jspm/nodelibs-process@0.1.2",
"querystring": "github:jspm/nodelibs-querystring@0.1.0"
},
"npm:ono@1.0.22": {
"npm:ono@2.0.1": {
"process": "github:jspm/nodelibs-process@0.1.2",
"util": "github:jspm/nodelibs-util@0.1.0"
},
@ -593,7 +634,7 @@ System.config({
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:parse-asn1@5.0.0": {
"asn1.js": "npm:asn1.js@4.2.1",
"asn1.js": "npm:asn1.js@4.3.0",
"browserify-aes": "npm:browserify-aes@1.0.5",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"create-hash": "npm:create-hash@1.1.2",
@ -613,25 +654,31 @@ System.config({
"process": "github:jspm/nodelibs-process@0.1.2",
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
},
"npm:process-nextick-args@1.0.3": {
"npm:pinkie-promise@2.0.0": {
"pinkie": "npm:pinkie@2.0.1"
},
"npm:pinkie@2.0.1": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:process-nextick-args@1.0.6": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:process@0.11.2": {
"assert": "github:jspm/nodelibs-assert@0.1.0"
},
"npm:public-encrypt@4.0.0": {
"bn.js": "npm:bn.js@4.5.2",
"bn.js": "npm:bn.js@4.6.4",
"browserify-rsa": "npm:browserify-rsa@4.0.0",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"create-hash": "npm:create-hash@1.1.2",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"parse-asn1": "npm:parse-asn1@5.0.0",
"randombytes": "npm:randombytes@2.0.1"
"randombytes": "npm:randombytes@2.0.2"
},
"npm:punycode@1.3.2": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:randombytes@2.0.1": {
"npm:randombytes@2.0.2": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2"
@ -646,23 +693,23 @@ System.config({
"stream-browserify": "npm:stream-browserify@1.0.0",
"string_decoder": "npm:string_decoder@0.10.31"
},
"npm:readable-stream@2.0.2": {
"npm:readable-stream@2.0.5": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"core-util-is": "npm:core-util-is@1.0.1",
"core-util-is": "npm:core-util-is@1.0.2",
"events": "github:jspm/nodelibs-events@0.1.1",
"inherits": "npm:inherits@2.0.1",
"isarray": "npm:isarray@0.0.1",
"process": "github:jspm/nodelibs-process@0.1.2",
"process-nextick-args": "npm:process-nextick-args@1.0.3",
"process-nextick-args": "npm:process-nextick-args@1.0.6",
"string_decoder": "npm:string_decoder@0.10.31",
"util-deprecate": "npm:util-deprecate@1.0.1"
"util-deprecate": "npm:util-deprecate@1.0.2"
},
"npm:reflect-metadata@0.1.2": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:request@2.64.0": {
"aws-sign2": "npm:aws-sign2@0.5.0",
"npm:request@2.67.0": {
"aws-sign2": "npm:aws-sign2@0.6.0",
"bl": "npm:bl@1.0.0",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"caseless": "npm:caseless@0.11.0",
@ -672,23 +719,24 @@ System.config({
"forever-agent": "npm:forever-agent@0.6.1",
"form-data": "npm:form-data@1.0.0-rc3",
"fs": "github:jspm/nodelibs-fs@0.1.2",
"har-validator": "npm:har-validator@1.8.0",
"hawk": "npm:hawk@3.1.0",
"har-validator": "npm:har-validator@2.0.5",
"hawk": "npm:hawk@3.1.2",
"http": "github:jspm/nodelibs-http@1.7.1",
"http-signature": "npm:http-signature@0.11.0",
"http-signature": "npm:http-signature@1.1.0",
"https": "github:jspm/nodelibs-https@0.1.0",
"is-typedarray": "npm:is-typedarray@1.0.0",
"isstream": "npm:isstream@0.1.2",
"json-stringify-safe": "npm:json-stringify-safe@5.0.1",
"mime-types": "npm:mime-types@2.1.7",
"node-uuid": "npm:node-uuid@1.4.3",
"mime-types": "npm:mime-types@2.1.9",
"node-uuid": "npm:node-uuid@1.4.7",
"oauth-sign": "npm:oauth-sign@0.8.0",
"process": "github:jspm/nodelibs-process@0.1.2",
"qs": "npm:qs@5.1.0",
"qs": "npm:qs@5.2.0",
"querystring": "github:jspm/nodelibs-querystring@0.1.0",
"stream": "github:jspm/nodelibs-stream@0.1.0",
"stringstream": "npm:stringstream@0.0.4",
"tough-cookie": "npm:tough-cookie@2.1.0",
"tunnel-agent": "npm:tunnel-agent@0.4.1",
"stringstream": "npm:stringstream@0.0.5",
"tough-cookie": "npm:tough-cookie@2.2.1",
"tunnel-agent": "npm:tunnel-agent@0.4.2",
"url": "github:jspm/nodelibs-url@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0",
"zlib": "github:jspm/nodelibs-zlib@0.1.0"
@ -718,6 +766,19 @@ System.config({
"amdefine": "npm:amdefine@1.0.0",
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:sshpk@1.7.3": {
"asn1": "npm:asn1@0.2.3",
"assert-plus": "npm:assert-plus@0.2.0",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"dashdash": "npm:dashdash@1.12.1",
"ecc-jsbn": "npm:ecc-jsbn@0.1.1",
"jodid25519": "npm:jodid25519@1.0.2",
"jsbn": "npm:jsbn@0.1.0",
"stream": "github:jspm/nodelibs-stream@0.1.0",
"tweetnacl": "npm:tweetnacl@0.13.3",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:stream-browserify@1.0.0": {
"events": "github:jspm/nodelibs-events@0.1.1",
"inherits": "npm:inherits@2.0.1",
@ -726,7 +787,7 @@ System.config({
"npm:string_decoder@0.10.31": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0"
},
"npm:stringstream@0.0.4": {
"npm:stringstream@0.0.5": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"fs": "github:jspm/nodelibs-fs@0.1.2",
"process": "github:jspm/nodelibs-process@0.1.2",
@ -741,7 +802,7 @@ System.config({
"npm:supports-color@2.0.0": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:swagger-parser@3.3.0": {
"npm:swagger-parser@3.4.0": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"call-me-maybe": "npm:call-me-maybe@1.0.1",
"debug": "npm:debug@2.2.0",
@ -750,31 +811,31 @@ System.config({
"fs": "github:jspm/nodelibs-fs@0.1.2",
"http": "github:jspm/nodelibs-http@1.7.1",
"https": "github:jspm/nodelibs-https@0.1.0",
"json-schema-ref-parser": "github:RomanGotsiy/json-schema-ref-parser@master",
"ono": "npm:ono@1.0.22",
"json-schema-ref-parser": "npm:json-schema-ref-parser@2.2.0",
"ono": "npm:ono@2.0.1",
"process": "github:jspm/nodelibs-process@0.1.2",
"punycode": "github:jspm/nodelibs-punycode@0.1.0",
"querystring": "github:jspm/nodelibs-querystring@0.1.0",
"stream": "github:jspm/nodelibs-stream@0.1.0",
"string_decoder": "github:jspm/nodelibs-string_decoder@0.1.0",
"swagger-methods": "npm:swagger-methods@1.0.0",
"swagger-schema-official": "npm:swagger-schema-official@2.0.0-d79c205",
"swagger-schema-official": "npm:swagger-schema-official@2.0.0-bab6bed",
"systemjs-json": "github:systemjs/plugin-json@0.1.0",
"url": "github:jspm/nodelibs-url@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0",
"z-schema": "npm:z-schema@3.15.3"
"z-schema": "npm:z-schema@3.16.1"
},
"npm:timers-browserify@1.4.2": {
"process": "npm:process@0.11.2"
},
"npm:tough-cookie@2.1.0": {
"npm:tough-cookie@2.2.1": {
"net": "github:jspm/nodelibs-net@0.1.2",
"punycode": "github:jspm/nodelibs-punycode@0.1.0",
"systemjs-json": "github:systemjs/plugin-json@0.1.0",
"url": "github:jspm/nodelibs-url@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:tunnel-agent@0.4.1": {
"npm:tunnel-agent@0.4.2": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"events": "github:jspm/nodelibs-events@0.1.1",
@ -791,27 +852,33 @@ System.config({
"querystring": "npm:querystring@0.2.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:util-deprecate@1.0.1": {
"npm:util-deprecate@1.0.2": {
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:util@0.10.3": {
"inherits": "npm:inherits@2.0.1",
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:validator@4.1.0": {
"npm:validator@4.5.0": {
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
},
"npm:verror@1.3.6": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
"extsprintf": "npm:extsprintf@1.0.2",
"fs": "github:jspm/nodelibs-fs@0.1.2",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:vm-browserify@0.0.4": {
"indexof": "npm:indexof@0.0.1"
},
"npm:z-schema@3.15.3": {
"commander": "npm:commander@2.8.1",
"npm:z-schema@3.16.1": {
"commander": "npm:commander@2.9.0",
"lodash.get": "npm:lodash.get@3.7.0",
"process": "github:jspm/nodelibs-process@0.1.2",
"request": "npm:request@2.64.0",
"request": "npm:request@2.67.0",
"systemjs-json": "github:systemjs/plugin-json@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0",
"validator": "npm:validator@4.1.0"
"validator": "npm:validator@4.5.0"
},
"npm:zone.js@0.5.10": {
"es6-promise": "npm:es6-promise@3.0.2",

12
tests/e2e/.eslintrc Normal file
View File

@ -0,0 +1,12 @@
{
"parser": "babel-eslint",
"extends": "eslint:recommended",
"env": {
"node": true,
"jasmine": true,
"protractor": true
},
"rules": {
"no-console": 0,
}
}

BIN
tests/e2e/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 318 B

90
tests/e2e/helpers.js Normal file
View File

@ -0,0 +1,90 @@
'use strict';
var https = require('https');
function loadJson(url) {
let promise = new Promise((resolve, reject) => {
https.get(url, function(res){
var body = '';
res.on('data', function(chunk){
body += chunk;
});
res.on('end', function(){
let resp = JSON.parse(body);
resolve(resp);
});
}).on('error', function(e){
reject(e);
});
});
return promise;
}
const LogLevel = {
INFO: 800,
WARNING: 900
};
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) {
let err = browser.executeScript('return window.redocError');
expect(err).toBeNull();
return;
}
// Bug in ChromeDriver: Need to execute at least one command
// so that the browser logs can be read out!
browser.executeScript('1+1');
browser.manage().logs().get('browser').then(function(browserLog) {
let filteredLog = browserLog.filter((logEntry) => {
let message = logEntry.message;
// skip browser-sync errors
if (message.indexOf('browser-sync') > -1) return false;
// skip firefox-specific warning
if (message.indexOf('mutating the [[Prototype]]') > -1) return false;
if (logEntry.level.value >= LogLevel.INFO) {
if (message.length > MAX_ERROR_MESSAGE_SYMBOLS) {
message = message.substr(0, MAX_ERROR_MESSAGE_SYMBOLS) + '...';
}
console.log('>> ' + message);
}
return logEntry.level.value > LogLevel.WARNING;
});
expect(filteredLog.length).toEqual(0, `Found ${filteredLog.length} browser errors`);
});
}
function scrollToEl(selector) {
let script = `
document.querySelector('${selector}').scrollIntoView(true);
window.scrollBy(0, 10);
`;
return browser.driver.executeScript(script);
}
function fixFFTest(done) {
// firefox issue. the first try to access something from webpage fails
// but the second works fine. So skipping first error
$('body').isPresent().then(()=> {
done();
}, () => {
//error skipped
done();
})
}
module.exports = {
loadJson: loadJson,
verifyNoBrowserErrors: verifyNoBrowserErrors,
scrollToEl: scrollToEl,
fixFFTest: fixFFTest
}

23
tests/e2e/index.html Normal file
View File

@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>ReDoc</title>
</head>
<body>
<redoc>
Loading...
</redoc>
<!-- ReDoc built file with all dependencies included -->
<script src="dist/redoc.full.min.js"> </script>
<script>
window.redocError = null;
/* init redoc */
var url = window.location.search.substr(5) || 'swagger.json';
Redoc.init(decodeURIComponent(url)).then(function() {}, function(err) {
window.redocError = err;
});
</script>
</body>
</html>

71
tests/e2e/redoc.spec.js Normal file
View File

@ -0,0 +1,71 @@
'use strict';
const verifyNoBrowserErrors = require('./helpers').verifyNoBrowserErrors;
const scrollToEl = require('./helpers').scrollToEl;
const fixFFTest = require('./helpers').fixFFTest;
const URL = 'index.html';
function basicTests(swaggerUrl, title) {
describe(`Basic suite for ${title}`, () => {
let specUrl = URL;
if (swaggerUrl) {
specUrl += `?url=${encodeURIComponent(swaggerUrl)}`;
}
beforeEach((done) => {
browser.get(specUrl);
fixFFTest(done);
});
afterEach(() => {
verifyNoBrowserErrors();
});
it('should init redoc without errors', () => {
let $redoc = $('redoc');
expect($redoc.isPresent()).toBe(true);
let $methods = $$('method');
expect($methods.count()).toBeGreaterThan(0);
});
});
}
basicTests(null, 'Extended Petstore');
describe('Scroll sync', () => {
let specUrl = URL;
beforeEach((done) => {
browser.get(specUrl);
fixFFTest(done);
});
it('should update active menu entries on page scroll', () => {
scrollToEl('[tag="store"]').then(function() {
expect($('.menu-cat-header.active').getText()).toBe('STORE');
});
});
});
describe('APIs.guru specs test', ()=> {
// global.apisGuruList was loaded in onPrepare method of protractor config
let apisGuruList = global.apisGuruList;
// Remove certain APIs that are known to cause problems
delete apisGuruList['motaword.com']; // invalid (see https://github.com/BigstickCarpet/swagger-parser/issues/26)
delete apisGuruList['learnifier.com']; // allof object and no type
delete apisGuruList['googleapis.com:mirror']; // bad urls in images
delete apisGuruList['googleapis.com:discovery']; // non-string references
for (let apiName of Object.keys(apisGuruList)) {
let apiInfo = apisGuruList[apiName].versions[apisGuruList[apiName].preferred];
let url = apiInfo.swaggerUrl;
// temporary hack due to this issue: https://github.com/substack/https-browserify/issues/6
url = url.replace('https://', 'http://');
url = url.replace('apis-guru.github.io/', 'apis-guru.github.io:80/');
basicTests(url, `${apiName}:${apiInfo.info.version}\n${url}`);
}
});

View File

@ -31,6 +31,14 @@
"$ref": "#/definitions/Simple"
}
}
},
"Circular": {
"type": "array",
"items": {
"schema": {
"$ref": "#/definitions/Circular"
}
}
}
},
"paths": {
@ -63,6 +71,28 @@
}
]
}
},
"test4": {
"get": {
"summary": "test get",
"parameters": [
{
"$ref": "#/definitions/Circular"
}
]
}
},
"test5": {
"get": {
"summary": "test get",
"parameters": [
{
"$ref": "#/definitions/Simple",
"title": "test",
"description": "test"
}
]
}
}
}
}

View File

@ -772,8 +772,12 @@
},
"Pet": {
"type": "object",
"required": ["name", "photoUrls"],
"required": ["name", "photoUrls", "petType"],
"discriminator": "petType",
"properties": {
"petType": {
"type": "string"
},
"id": {
"type": "integer",
"format": "int64"
@ -815,6 +819,33 @@
"name": "Pet"
}
},
"Cat": {
"description": "A representation of a cat",
"allOf": [
{
"type": "object",
"properties": {
"huntingSkill": {
"type": "string",
"description": "The measured skill for hunting",
"default": "lazy",
"enum": [
"clueless",
"lazy",
"adventurous",
"aggressive"
]
}
},
"required": [
"huntingSkill"
]
},
{
"$ref": "#/definitions/Pet"
},
]
},
"ApiResponse": {
"type": "object",
"properties": {

View File

@ -225,5 +225,27 @@ describe('Utils', () => {
});
});
describe('findDerivedDefinitions method', () => {
beforeAll((done) => {
schemaMgr.load('/tests/schemas/extended-petstore.json').then(() => {
done();
}, () => {
done(new Error('Error handler should not be called'));
});
});
it('should find derived definitions for Pet', () => {
let deriveDefs = schemaMgr.findDerivedDefinitions('#/definitions/Pet');
deriveDefs.should.be.instanceof(Array);
deriveDefs.should.not.be.empty;
deriveDefs.should.be.deepEqual([{name: 'Cat', $ref: '#/definitions/Cat'}]);
});
it('should return emtpy array for definitions that dont have discriminator', () => {
let deriveDefs = schemaMgr.findDerivedDefinitions('#/definitions/Order');
deriveDefs.should.be.instanceof(Array);
deriveDefs.should.be.empty;
});
});
});
});