Merge remote-tracking branch 'redoc-proto/master'

This commit is contained in:
Roman Hotsiy 2015-11-14 15:18:26 +02:00
commit f681b6510a
55 changed files with 3495 additions and 0 deletions

26
.gitignore vendored Normal file
View File

@ -0,0 +1,26 @@
### Linux ###
*~
# KDE directory preferences
.directory
# Linux trash folder which might appear on any partition or disk
.Trash-*
### Node ###
# Logs
logs
*.log
npm-debug.log*
# Dependency directory
# https://docs.npmjs.com/misc/faq#should-i-check-my-node-modules-folder-into-git
node_modules
#jspm
jspm_packages
/dist
/demo/build
.tmp

22
.travis.yml Normal file
View File

@ -0,0 +1,22 @@
language: node_js
node_js:
- '0.12'
env:
global:
- GH_REF: github.com/RomanGotsiy/redoc-prototype.git
- secure: gpLnG4Jgac401YmoOPVD5D2oiCAlOAgDXIQmISYDQOX1HwzDK0B+9210Nu+Vf1HY5OCWEYK+9Fc+MliAQgX1JIX3VXODd7PKLBY53YJEha9KyiQePBvH8QLzVEhVWb4PU/Rird/h4ndBLhlVeVZ9kXH5Qi2wAFV0GJHIOl3lapRqqDO5l3OcHTT/q9E4NdgTBa5tX0xRDB6015nb8We55lL+RvmAAFKaDY0g11LySj8aCVsyEgRgnFAHiM27GrsulDLcEXxu2+Om9Lwx7cnMzRs773GNVAyFeE+JChO94XHB4C0cVmTSXZE57lxRFhtAGcwdSpVSDU++xIGbdhCpuQ5swT3bk/Old0kxbvp6OpWlZTYzFTY40G/E+bs3NmITBc5mxy1hRYHyTi6nMBE0UpczEiFSOLr0eOMEFVKcOhusGrGD4veKm9Ho3M9fJYh6m8jLvqLKovui3Td3W2i/x9NIA88UWlfOUVfpIbNmxgWVBCKnQFMR+5XxkLeSV6E6Hx/zUNGuRSLEQNIBw9aj8FPOem0Rg3PmSjExyAx+QWB+vW1s90J4S+r7LZPsvSJNMAQI9kBDP75D9qrv1YBfs+kNY+PPRXjk2MhyGJLByhdxQsYQ7nOV0OPjxj3gUm2kH9uQIYx7zgSv4rcTphdh6rWfWCggbHJBeWBdrtdnf+M=
- secure: EbOO3vHJAsuzvW1encS7lGFOQtoHrTF45HP+tcu9YW6VmMr9FPJXsf7AFmquama3w3miWJayAXtoEdrx3WM5kRnK7sP9xg/X4emWKIE8MAlS//PyiQlrRRNakA5L7vlEX/w/goIApapWiwQ9OFDlVZAnH1/y05Hf411qsVCThfuKCdUfrbjnMkaVBuWVXggfllBVyFKVzk97AJiYrZtOw4rUljyG6pb3EhHKwP6QbJN/I4rKRtlQ0gMFnDFCqrcBntaQjMRZK3HNMuAoEzhzLRjNc6j8mcJdBHcon0+HhLCpn2Isoo3WRQQB85eaAg9xryPBWXGAGS/e2yyL6nHNqnrbrA7O27HA53L5jQFNnzrWtCJMSApVJXGtLxwYpdHFln4QYNSKVXP5tNyLidvq+7iUFRHMyIyAlOiOXNDcYk7Wo0/TBbAawmfhQ0oSj8SweA2XEfH0gqFEiYedjlzafyLkB6tmiX6POOEgDRkDB6QrI5gWJpRsNbcA+/lMwBbaZbfncZ1zolyMA8l71Q/yuMFfrw32qJlwFG7cwMqHqMhUlVri3129XYOzkuE5DDsK5xpd9n/jRMgZXz+hJdAPCeUds9TTjXP0f4NGhxPL8vJpuHiiQ6dnZ9YuQqz4AHKbWqlEYaF681XnOlEb1360hIQOFT7ixcWl1A//bq5Ip3w=
cache:
directories:
- node_modules
before_install:
- travis_retry npm install jspm
- jspm config registries.github.auth $JSPM_GITHUB_AUTH_TOKEN
before_deploy:
- npm run build
deploy:
skip_cleanup: true
provider: script
script: "./build/deploy_gh_pages.sh"
on:
branch: master

14
build/deploy_gh_pages.sh Executable file
View File

@ -0,0 +1,14 @@
#!/bin/bash
set -o pipefail
(
set -e
set -x
cd demo
git init
git config user.name "Travis-CI"
git config user.email "travis@travis"
cp -r ../dist ./dist
git add .
git commit -m "Deployed to Github Pages"
git push --force "https://${GH_TOKEN}@${GH_REF}" master:gh-pages 2>&1
) 2>&1 | sed "s/${GH_TOKEN}/xxPASSxx/"

10
build/paths.js Normal file
View File

@ -0,0 +1,10 @@
module.exports = {
source: 'lib/**/*.js',
html: 'lib/**/*.html',
css: 'lib/**/*.css',
sourceEntryPoint: 'lib/index.js',
outputName: 'redoc.full.js',
output: 'dist/',
tmp: '.tmp/',
demo: 'demo/**/*'
};

60
build/tasks/build.js Normal file
View File

@ -0,0 +1,60 @@
var gulp = require('gulp');
var runSequence = require('run-sequence');
var Builder = require('systemjs-builder');
var inlineNg2Template = require('gulp-inline-ng2-template');
var path = require('path');
var sourcemaps = require('gulp-sourcemaps');
var paths = require('../paths');
var fs= require('fs');
var concat = require('gulp-concat');
paths.redocBuilt = path.join(paths.output, paths.outputName);
gulp.task('build', function (callback) {
return runSequence(
'clean',
'bundle',
callback
);
});
gulp.task('bundle', ['bundleSfx', 'concatDeps']);
gulp.task('inlineTemplates', function() {
return gulp.src(paths.source, { base: './' })
.pipe(inlineNg2Template({ base: '/' }))
.pipe(gulp.dest(paths.tmp));
});
var JS_DEV_DEPS = [
'node_modules/zone.js/dist/zone-microtask.js',
'node_modules/reflect-metadata/Reflect.js'
];
// 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))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest(paths.output))
});
gulp.task('bundleSfx', ['inlineTemplates'], function(cb) {
fs.existsSync('dist') || fs.mkdirSync('dist');
var builder = new Builder('./', 'system.config.js');
builder.config({
separateCSS: true
});
builder
.buildStatic(path.join(paths.tmp, paths.sourceEntryPoint),
paths.redocBuilt,
{ globalName: 'Redoc', sourceMaps: true, lowResSourceMaps: true }
)
.then(function() {
cb();
})
.catch(function(err) {
cb(new Error(err));
});
});

9
build/tasks/clean.js Normal file
View File

@ -0,0 +1,9 @@
var gulp = require('gulp');
var paths = require('../paths');
var del = require('del');
var vinylPaths = require('vinyl-paths');
gulp.task('clean', function () {
return gulp.src([paths.output, paths.tmp])
.pipe(vinylPaths(del));
});

10
build/tasks/lint.js Normal file
View File

@ -0,0 +1,10 @@
var gulp = require('gulp');
var eslint = require('gulp-eslint');
var paths = require('../paths');
gulp.task('lint', function () {
return gulp.src(paths.source)
.pipe(eslint())
.pipe(eslint.format())
.pipe(eslint.failAfterError());
});

17
build/tasks/serve.js Normal file
View File

@ -0,0 +1,17 @@
var gulp = require('gulp');
var browserSync = require('browser-sync').create('bs');
gulp.task('serve', ['watch'], function (done) {
browserSync.init({
open: false,
notify: false,
port: 9000,
server: {
baseDir: './demo',
routes: {
'/dist': './dist'
},
},
reloadDelay: 500
}, done);
});

14
build/tasks/watch.js Normal file
View File

@ -0,0 +1,14 @@
var gulp = require('gulp');
var paths = require('../paths');
var browserSync = require('browser-sync').get('bs');
function changed(event) {
console.log('File ' + event.path + ' was ' + event.type + ', running tasks...');
}
gulp.task('watch', ['build'], function () {
gulp.watch([ paths.source ], [ 'bundle', browserSync.reload ]).on('change', changed);
gulp.watch([ paths.html ], [ 'bundle', browserSync.reload]).on('change', changed);
gulp.watch([ paths.css ], [ 'bundle', browserSync.reload]).on('change', changed);
gulp.watch([ paths.demo ], [ '', browserSync.reload ]).on('change', changed);
});

30
demo/index.html Normal file
View File

@ -0,0 +1,30 @@
<!-- index.html -->
<html>
<head>
<title>ReDoc prototype</title>
<link rel="stylesheet" href="main.css">
<link rel="stylesheet" href="dist/redoc.full.css">
</head>
<body>
<nav>
<header> ReDoc </header>
<input id="schema-url-input" value='swagger.json'>
<button id="load-button"> Explore </button>
</nav>
</nav>
<side-menu>
</side-menu>
<!-- The wrapper component -->
<redoc>
Loading...
</redoc>
<!-- ReDoc built file with all dependencies included -->
<script src="dist/redoc.full.js"> </script>
<script src="main.js"> </script>
<script>
/* init redoc */
Redoc.init('swagger.json');
</script>
</body>
</html>

85
demo/main.css Normal file
View File

@ -0,0 +1,85 @@
body {
font-family: Verdana, Geneva, sans-serif;
font-size: 14px;
color: #333;
margin: 0;
line-height: 1.5;
padding-top: 50px;
}
nav input, nav button {
font-size: 16px;
line-height: 28px;
height: 28px;
box-sizing: border-box;
vertical-align: middle;
line-height: 1;
outline: none;
}
nav header {
float: left;
margin-left: 20px;
font-size: 25px;
color: white;
position: absolute;
}
nav input {
width: 50%;
box-sizing: border-box;
max-width: 500px;
}
nav button {
background-color: white;
border: 1px solid #FFFFFF;
cursor: pointer;
color: white;
background-color: #21476D;
padding: 2px 10px;
}
nav {
width: 100%;
height: 50px;
line-height: 50px;
text-align: center;
background-color: #053361;
position: fixed;
top: 0;
z-index: 1;
}
side-menu, redoc {
display: block;
box-sizing: border-box;
}
api-info, side-menu {
display: block;
padding: 10px 20px;
}
side-menu {
position: fixed;
width: 260px;
height: 100%;
overflow-y: auto;
overflow-x: hidden;;
background-color: #f2f2f2;
}
redoc {
margin-left: 260px;
}
pre {
white-space: pre-wrap;
background-color: #f2f2f2;
padding: 10px;
overflow-x: auto;
line-height: normal;
}
code {
background-color: #f2f2f2;
}

9
demo/main.js Normal file
View File

@ -0,0 +1,9 @@
;(function() {
'use strict';
var loadButton = document.getElementById('load-button');
var schemaUrlInput = document.getElementById('schema-url-input');
loadButton.addEventListener('click', function() {
Redoc.init(schemaUrlInput.value);
})
})();

835
demo/swagger.json Normal file
View File

@ -0,0 +1,835 @@
{
"swagger": "2.0",
"info": {
"description": "This is a sample server Petstore server. You can find out more about Swagger at [http://swagger.io](http://swagger.io) or on [irc.freenode.net, #swagger](http://swagger.io/irc/). For this sample, you can use the api key `special-key` to test the authorization filters.",
"version": "1.0.0",
"title": "Swagger Petstore",
"termsOfService": "http://swagger.io/terms/",
"contact": {
"email": "apiteam@swagger.io"
},
"license": {
"name": "Apache 2.0",
"url": "http://www.apache.org/licenses/LICENSE-2.0.html"
}
},
"host": "petstore.swagger.io",
"basePath": "/v2",
"tags": [{
"name": "Pagination",
"x-secondaryTag": true,
"description": "Sometimes you just can't get enough. For this reason, we've provided a convenient way to access more data in any request for sequential data. Simply call the url in the next_url parameter and we'll respond with the next set of data.\n```json\n{\n ...\n \"pagination\": {\n \"next_url\": \"https://api.instagram.com/v1/tags/puppy/media/recent?access_token=fb2e77d.47a0479900504cb3ab4a1f626d174d2d&max_id=13872296\",\n \"next_max_id\": \"13872296\"\n }\n}\n```\n On views where pagination is present, we also support the `count` parameter. Simply set this to the number of items you'd like to receive. Note that the default values should be fine for most applications - but if you decide to increase this number there is a maximum value defined on each endpoint.",
"externalDocs": {
"description": "Find out more",
"url": "http://swagger.io"
}
},{
"name": "JSONP",
"x-secondaryTag": true,
"description": "If you're writing an AJAX application, and you'd like to wrap our response with a callback, all you have to do is specify a callback parameter with any API call:\n```\n https://api.instagram.com/v1/tags/coffee/media/recent?access_token=fb2e77d.47a0479900504cb3ab4a1f626d174d2d&callback=callbackFunction\n```\nWould respond with:\n```js\ncallbackFunction({\n ...\n});\n```",
"externalDocs": {
"description": "Find out more",
"url": "http://swagger.io"
}
},{
"name": "pet",
"description": "Everything about your Pets",
"externalDocs": {
"description": "Find out more",
"url": "http://swagger.io"
}
}, {
"name": "store",
"description": "Access to Petstore orders"
}, {
"name": "user",
"description": "Operations about user",
"externalDocs": {
"description": "Find out more about our store",
"url": "http://swagger.io"
}
}],
"schemes": ["http"],
"paths": {
"/pet": {
"post": {
"tags": ["pet"],
"summary": "Add a new pet to the store",
"description": "",
"operationId": "addPet",
"consumes": ["application/json", "application/xml"],
"produces": ["application/xml", "application/json"],
"parameters": [{
"in": "body",
"name": "body",
"description": "Pet object that needs to be added to the store",
"required": true,
"schema": {
"$ref": "#/definitions/Pet"
}
}],
"responses": {
"405": {
"description": "Invalid input"
}
},
"security": [{
"petstore_auth": ["write:pets", "read:pets"]
}]
},
"put": {
"tags": ["pet"],
"summary": "Update an existing pet",
"description": "",
"operationId": "updatePet",
"consumes": ["application/json", "application/xml"],
"produces": ["application/xml", "application/json"],
"parameters": [{
"in": "body",
"name": "body",
"description": "Pet object that needs to be added to the store",
"required": true,
"schema": {
"$ref": "#/definitions/Pet"
}
}],
"responses": {
"400": {
"description": "Invalid ID supplied"
},
"404": {
"description": "Pet not found"
},
"405": {
"description": "Validation exception"
}
},
"security": [{
"petstore_auth": ["write:pets", "read:pets"]
}]
}
},
"/pet/findByStatus": {
"get": {
"tags": ["pet", "Pagination", "JSONP"],
"summary": "Finds Pets by status",
"description": "Multiple status values can be provided with comma seperated strings",
"operationId": "findPetsByStatus",
"produces": ["application/xml", "application/json"],
"parameters": [{
"name": "status",
"in": "query",
"description": "Status values that need to be considered for filter",
"required": true,
"type": "array",
"items": {
"type": "string",
"enum": ["available", "pending", "sold"],
"default": "available"
},
"collectionFormat": "csv"
}],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/Pet"
}
}
},
"400": {
"description": "Invalid status value"
}
},
"security": [{
"petstore_auth": ["write:pets", "read:pets"]
}]
}
},
"/pet/findByTags": {
"get": {
"tags": ["pet", "Pagination", "JSONP"],
"summary": "Finds Pets by tags",
"description": "Muliple tags can be provided with comma seperated strings. Use tag1, tag2, tag3 for testing.",
"operationId": "findPetsByTags",
"produces": ["application/xml", "application/json"],
"parameters": [{
"name": "tags",
"in": "query",
"description": "Tags to filter by",
"required": true,
"type": "array",
"items": {
"type": "string"
},
"collectionFormat": "csv"
}],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/Pet"
}
}
},
"400": {
"description": "Invalid tag value"
}
},
"security": [{
"petstore_auth": ["write:pets", "read:pets"]
}]
}
},
"/pet/{petId}": {
"get": {
"tags": ["pet", "JSONP"],
"summary": "Find pet by ID",
"description": "Returns a single pet",
"operationId": "getPetById",
"produces": ["application/xml", "application/json"],
"parameters": [{
"name": "petId",
"in": "path",
"description": "ID of pet to return",
"required": true,
"type": "integer",
"format": "int64"
}],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"$ref": "#/definitions/Pet"
}
},
"400": {
"description": "Invalid ID supplied"
},
"404": {
"description": "Pet not found"
}
},
"security": [{
"api_key": []
}]
},
"post": {
"tags": ["pet"],
"summary": "Updates a pet in the store with form data",
"description": "",
"operationId": "updatePetWithForm",
"consumes": ["application/x-www-form-urlencoded"],
"produces": ["application/xml", "application/json"],
"parameters": [{
"name": "petId",
"in": "path",
"description": "ID of pet that needs to be updated",
"required": true,
"type": "integer",
"format": "int64"
}, {
"name": "name",
"in": "formData",
"description": "Updated name of the pet",
"required": false,
"type": "string"
}, {
"name": "status",
"in": "formData",
"description": "Updated status of the pet",
"required": false,
"type": "string"
}],
"responses": {
"405": {
"description": "Invalid input"
}
},
"security": [{
"petstore_auth": ["write:pets", "read:pets"]
}]
},
"delete": {
"tags": ["pet"],
"summary": "Deletes a pet",
"description": "",
"operationId": "deletePet",
"produces": ["application/xml", "application/json"],
"parameters": [{
"name": "api_key",
"in": "header",
"required": false,
"type": "string"
}, {
"name": "petId",
"in": "path",
"description": "Pet id to delete",
"required": true,
"type": "integer",
"format": "int64"
}],
"responses": {
"400": {
"description": "Invalid pet value"
}
},
"security": [{
"petstore_auth": ["write:pets", "read:pets"]
}]
}
},
"/pet/{petId}/uploadImage": {
"post": {
"tags": ["pet"],
"summary": "uploads an image",
"description": "",
"operationId": "uploadFile",
"consumes": ["multipart/form-data"],
"produces": ["application/json"],
"parameters": [{
"name": "petId",
"in": "path",
"description": "ID of pet to update",
"required": true,
"type": "integer",
"format": "int64"
}, {
"name": "additionalMetadata",
"in": "formData",
"description": "Additional data to pass to server",
"required": false,
"type": "string"
}, {
"name": "file",
"in": "formData",
"description": "file to upload",
"required": false,
"type": "file"
}],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"$ref": "#/definitions/ApiResponse"
}
}
},
"security": [{
"petstore_auth": ["write:pets", "read:pets"]
}]
}
},
"/store/inventory": {
"get": {
"tags": ["store", "JSONP"],
"summary": "Returns pet inventories by status",
"description": "Returns a map of status codes to quantities",
"operationId": "getInventory",
"produces": ["application/json"],
"parameters": [],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"type": "object",
"additionalProperties": {
"type": "integer",
"format": "int32"
}
}
}
},
"security": [{
"api_key": []
}]
}
},
"/store/order": {
"post": {
"tags": ["store"],
"summary": "Place an order for a pet",
"description": "",
"operationId": "placeOrder",
"produces": ["application/xml", "application/json"],
"parameters": [{
"in": "body",
"name": "body",
"description": "order placed for purchasing the pet",
"required": true,
"schema": {
"$ref": "#/definitions/Order"
}
}],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"$ref": "#/definitions/Order"
}
},
"400": {
"description": "Invalid Order"
}
}
}
},
"/store/order/{orderId}": {
"get": {
"tags": ["store", "JSONP"],
"summary": "Find purchase order by ID",
"description": "For valid response try integer IDs with value <= 5 or > 10. Other values will generated exceptions",
"operationId": "getOrderById",
"produces": ["application/xml", "application/json"],
"parameters": [{
"name": "orderId",
"in": "path",
"description": "ID of pet that needs to be fetched",
"required": true,
"type": "integer",
"maximum": 5.0,
"minimum": 1.0,
"format": "int64"
}],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"$ref": "#/definitions/Order"
}
},
"400": {
"description": "Invalid ID supplied"
},
"404": {
"description": "Order not found"
}
}
},
"delete": {
"tags": ["store"],
"summary": "Delete purchase order by ID",
"description": "For valid response try integer IDs with value < 1000. Anything above 1000 or nonintegers will generate API errors",
"operationId": "deleteOrder",
"produces": ["application/xml", "application/json"],
"parameters": [{
"name": "orderId",
"in": "path",
"description": "ID of the order that needs to be deleted",
"required": true,
"type": "string",
"minimum": 1.0
}],
"responses": {
"400": {
"description": "Invalid ID supplied"
},
"404": {
"description": "Order not found"
}
}
}
},
"/user": {
"post": {
"tags": ["user"],
"summary": "Create user",
"description": "This can only be done by the logged in user.",
"operationId": "createUser",
"produces": ["application/xml", "application/json"],
"parameters": [{
"in": "body",
"name": "body",
"description": "Created user object",
"required": true,
"schema": {
"$ref": "#/definitions/User"
}
}],
"responses": {
"default": {
"description": "successful operation"
}
}
}
},
"/user/createWithArray": {
"post": {
"tags": ["user"],
"summary": "Creates list of users with given input array",
"description": "",
"operationId": "createUsersWithArrayInput",
"produces": ["application/xml", "application/json"],
"parameters": [{
"in": "body",
"name": "body",
"description": "List of user object",
"required": true,
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/User"
}
}
}],
"responses": {
"default": {
"description": "successful operation"
}
}
}
},
"/user/createWithList": {
"post": {
"tags": ["user"],
"summary": "Creates list of users with given input array",
"description": "",
"operationId": "createUsersWithListInput",
"produces": ["application/xml", "application/json"],
"parameters": [{
"in": "body",
"name": "body",
"description": "List of user object",
"required": true,
"schema": {
"type": "array",
"items": {
"$ref": "#/definitions/User"
}
}
}],
"responses": {
"default": {
"description": "successful operation"
}
}
}
},
"/user/login": {
"get": {
"tags": ["user"],
"summary": "Logs user into the system",
"description": "",
"operationId": "loginUser",
"produces": ["application/xml", "application/json"],
"parameters": [{
"name": "username",
"in": "query",
"description": "The user name for login",
"required": true,
"type": "string"
}, {
"name": "password",
"in": "query",
"description": "The password for login in clear text",
"required": true,
"type": "string"
}],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"type": "string"
},
"headers": {
"X-Rate-Limit": {
"type": "integer",
"format": "int32",
"description": "calls per hour allowed by the user"
},
"X-Expires-After": {
"type": "string",
"format": "date-time",
"description": "date in UTC when toekn expires"
}
}
},
"400": {
"description": "Invalid username/password supplied"
}
}
}
},
"/user/logout": {
"get": {
"tags": ["user"],
"summary": "Logs out current logged in user session",
"description": "",
"operationId": "logoutUser",
"produces": ["application/xml", "application/json"],
"parameters": [],
"responses": {
"default": {
"description": "successful operation"
}
}
}
},
"/user/{username}": {
"get": {
"tags": ["user", "JSONP"],
"summary": "Get user by user name",
"description": "",
"operationId": "getUserByName",
"produces": ["application/xml", "application/json"],
"parameters": [{
"name": "username",
"in": "path",
"description": "The name that needs to be fetched. Use user1 for testing. ",
"required": true,
"type": "string"
}],
"responses": {
"200": {
"description": "successful operation",
"schema": {
"$ref": "#/definitions/User"
}
},
"400": {
"description": "Invalid username supplied"
},
"404": {
"description": "User not found"
}
}
},
"put": {
"tags": ["user"],
"summary": "Updated user",
"description": "This can only be done by the logged in user.",
"operationId": "updateUser",
"produces": ["application/xml", "application/json"],
"parameters": [{
"name": "username",
"in": "path",
"description": "name that need to be deleted",
"required": true,
"type": "string"
}, {
"in": "body",
"name": "body",
"description": "Updated user object",
"required": true,
"schema": {
"$ref": "#/definitions/User"
}
}],
"responses": {
"400": {
"description": "Invalid user supplied"
},
"404": {
"description": "User not found"
}
}
},
"delete": {
"tags": ["user"],
"summary": "Delete user",
"description": "This can only be done by the logged in user.",
"operationId": "deleteUser",
"produces": ["application/xml", "application/json"],
"parameters": [{
"name": "username",
"in": "path",
"description": "The name that needs to be deleted",
"required": true,
"type": "string"
}],
"responses": {
"400": {
"description": "Invalid username supplied"
},
"404": {
"description": "User not found"
}
}
}
}
},
"securityDefinitions": {
"petstore_auth": {
"type": "oauth2",
"authorizationUrl": "http://petstore.swagger.io/api/oauth/dialog",
"flow": "implicit",
"scopes": {
"write:pets": "modify pets in your account",
"read:pets": "read your pets"
}
},
"api_key": {
"type": "apiKey",
"name": "api_key",
"in": "header"
}
},
"definitions": {
"Order": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"petId": {
"type": "integer",
"format": "int64"
},
"quantity": {
"type": "integer",
"format": "int32"
},
"shipDate": {
"type": "string",
"format": "date-time"
},
"status": {
"type": "string",
"description": "Order Status",
"enum": ["placed", "approved", "delivered"]
},
"complete": {
"type": "boolean",
"default": false
}
},
"xml": {
"name": "Order"
}
},
"User": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"username": {
"type": "string"
},
"firstName": {
"type": "string"
},
"lastName": {
"type": "string"
},
"email": {
"type": "string"
},
"password": {
"type": "string"
},
"phone": {
"type": "string"
},
"userStatus": {
"type": "integer",
"format": "int32",
"description": "User Status"
}
},
"xml": {
"name": "User"
}
},
"Category": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
},
"xml": {
"name": "Category"
}
},
"Tag": {
"type": "object",
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"name": {
"type": "string"
}
},
"xml": {
"name": "Tag"
}
},
"Pet": {
"type": "object",
"required": ["name", "photoUrls"],
"properties": {
"id": {
"type": "integer",
"format": "int64"
},
"category": {
"$ref": "#/definitions/Category"
},
"name": {
"type": "string",
"example": "doggie"
},
"photoUrls": {
"type": "array",
"xml": {
"name": "photoUrl",
"wrapped": true
},
"items": {
"type": "string"
}
},
"tags": {
"type": "array",
"xml": {
"name": "tag",
"wrapped": true
},
"items": {
"$ref": "#/definitions/Tag"
}
},
"status": {
"type": "string",
"description": "pet status in the store",
"enum": ["available", "pending", "sold"]
}
},
"xml": {
"name": "Pet"
}
},
"ApiResponse": {
"type": "object",
"properties": {
"code": {
"type": "integer",
"format": "int32"
},
"type": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
},
"externalDocs": {
"description": "Find out more about Swagger",
"url": "http://swagger.io"
}
}

1
gulpfile.js Normal file
View File

@ -0,0 +1 @@
require('require-dir')('build/tasks');

24
lib/.eslintrc Normal file
View File

@ -0,0 +1,24 @@
{
"parser": "babel-eslint",
"extends": "eslint:recommended",
"env": {
"browser": true,
},
"rules": {
"quotes": [2, "single"],
"no-console": 0,
"comma-spacing": 2,
"comma-style": [2, "last"],
"consistent-return": 2,
"strict": [2, "global"],
"eqeqeq": [2, "smart"],
"curly": [2, "multi-line"],
"semi-spacing": [2, {"before": false, "after": true}],
"semi": [2, "always"],
"no-extra-semi": 2,
"comma-dangle": [2, "never"],
"no-sequences": 2,
"comma-spacing": [2, {"before": false, "after": true}],
"comma-style": [2, "last"]
}
}

View File

@ -0,0 +1,20 @@
ul {
display: block;
margin: 0;
padding: 10px 0px 0 0;
}
li {
list-style: none;
margin: 0;
display: inline-block;
padding: 5px 15px;
background-color: #262673;
border-left: 1px solid #1C1C50;
border-bottom: 2px solid transparent;
cursor: pointer;
}
li.active {
border-bottom: 2px solid blue;
}

View File

@ -0,0 +1,55 @@
'use strict';
import {Component, View, CORE_DIRECTIVES} from 'angular2/angular2';
@Component({
selector: 'tabs'
})
@View({
template: `
<ul>
<li *ng-for="#tab of tabs" [ng-class]="{active: tab.active}" (click)="selectTab(tab)">{{tab.tabTitle}}</li>
</ul>
<ng-content></ng-content>
`,
directives: [CORE_DIRECTIVES],
styleUrls: ['./lib/common-components/Tabs/tabs.css']
})
export class Tabs {
constructor() {
this.tabs = [];
}
selectTab(tab) {
this.tabs.forEach((tab) => {
tab.active = false;
});
tab.active = true;
}
addTab(tab: Tab) {
if (this.tabs.length === 0) {
tab.active = true;
}
this.tabs.push(tab);
}
}
@Component({
selector: 'tab',
inputs: ['tabTitle: tab-title']
})
@View({
template: `
<div class="tab-wrap" [hidden]="!active">
<ng-content></ng-content>
</div>
`
})
export class Tab {
constructor(tabs) {
tabs.addTab(this);
}
}
Tab.parameters = [ [ Tabs ] ];

View File

@ -0,0 +1,3 @@
h1 {
color: #1976D3;
}

View File

@ -0,0 +1,15 @@
<h1>{{data.title}} ({{data.version}})</h1>
<p *ng-if="data.description" inner-html="{{data.description | marked}}"> </p>
<p>
<!-- TODO: create separate components for contact and license ? -->
<span *ng-if="data.contact"> Contact:
<a *ng-if="data.contact.url" href="{{data.contact.url}}">
{{data.contact.name || data.contact.url}}</a>
<a *ng-if="data.contact.email" href="mailto:{{data.contact.email}}">
{{data.contact.email}}</a>
</span>
<span *ng-if="data.license"> License:
<a *ng-if="data.license.url" href="{{data.license.url}}"> {{data.license.name}} </a>
<span *ng-if="!data.license.url"> {{data.license.name}} </span>
</span>
</p>

View File

@ -0,0 +1,18 @@
'use strict';
import {RedocComponent, BaseComponent} from '../base';
@RedocComponent({
selector: 'api-info',
styleUrls: ['./lib/components/ApiInfo/api-info.css'],
templateUrl: './lib/components/ApiInfo/api-info.html'
})
export default class ApiInfo extends BaseComponent {
constructor(schemaMgr) {
super(schemaMgr);
}
prepareModel() {
this.data = this.componentSchema.info;
}
}

View File

@ -0,0 +1,30 @@
'use strict';
import {RedocComponent, BaseComponent} from '../base';
/* temporarily this component uses json-schema-view-js lib */
import 'json-formatter-js/src/index';
import 'json-formatter-js/dist/style.css!';
import JSONSchemaView from 'json-schema-view-js/src/index';
import 'json-schema-view-js/dist/style.css!';
import {ElementRef} from 'angular2/angular2';
@RedocComponent({
selector: 'schema',
template: ''
})
export default class JsonSchemaView extends BaseComponent {
constructor(schemaMgr, elementRef) {
super(schemaMgr);
this.element = elementRef.nativeElement;
}
init() {
this.dereference();
const formatter = new JSONSchemaView(this.componentSchema, 1);
this.element.appendChild(formatter.render());
}
}
JsonSchemaView.parameters = JsonSchemaView.parameters.concat([[ElementRef]]);

View File

@ -0,0 +1,112 @@
responses-list, params-list {
display: block;
}
h2 {
font-size: 25px;
font-weight: 200;
color: #666;
}
h3 {
margin: 0;
font-weight: 200;
}
h3 > span {
padding: 5px 10px;
vertical-align: middle;
}
span.path {
font-family: monospace;
font-weight: bold;
}
.method-tags {
margin-top: 10px;
color: #666;
font-weight: bold;
}
.method-tags a {
color: #666;
font-weight: bold;
display: inline-block;
padding: 0 5px;
font-style: italic;
}
.content, .samples {
display: block;
box-sizing: border-box;
float: left;
}
.content {
width: 60%;
padding: 0 20px;
}
.samples {
color: white;
width: 40%;
padding: 10px 20px;
}
responses-samples {
display: block;
}
.samples header {
font-size: 20px;
margin: 5px 0;
}
.samples schema-sample {
display: block;
padding: 5px;
background-color: rgb(18, 20, 39);
}
.method:after {
content: "";
display: table;
clear:both;
}
.method-description {
padding: 30px 0;
}
.http-method {
font-size: 13px;
color: white;
background-color: #1976D3;
border-radius: 0 10px 10px 0;
font-weight: bold;
}
.http-method.delete {
background-color: red;
}
.http-method.post {
background-color: green;
}
.http-method.patch {
background-color: orange;
}
.http-method.put {
background-color: crimson;
}
.http-method.options {
background-color: black;
}
.http-method.head {
background-color: darkkhaki;
}

View File

@ -0,0 +1,29 @@
<div class="method">
<div class="content">
<h2>{{data.methodInfo.summary}}</h2>
<h3>
<span class="http-method" [ng-class]="data.method">{{data.method}}</span>
<span class="path">{{data.path}}</span>
</h3>
<div class="method-tags"> Tags:
<a *ng-for="#tag of data.methodInfo.tags" attr.href="#{{tag}}"> {{tag}} </a>
</div>
<p *ng-if="data.methodInfo.description" class="method-description"
inner-html="{{data.methodInfo.description | marked}}">
</p>
<br>
<params-list pointer="{{pointer}}/parameters"> </params-list>
<br>
<responses-list pointer="{{pointer}}/responses"> </responses-list>
</div>
<div class="samples">
<div *ng-if="data.bodyParam">
<header> Body sample </header>
<schema-sample pointer="{{data.bodyParam._pointer}}/schema"> </schema-sample>
</div>
<div>
<header> Responses samples </header>
<responses-samples pointer="{{pointer}}/responses"> </responses-samples>
</div>
</div>
<div>

View File

@ -0,0 +1,34 @@
'use strict';
import {JsonPointer} from '../../utils/JsonPointer';
import {RedocComponent, BaseComponent} from '../base';
import ParamsList from '../ParamsList/params-list';
import ResponsesList from '../ResponsesList/responses-list';
import ResponsesSamples from '../ResponsesSamples/responses-samples';
import SchemaSample from '../SchemaSample/schema-sample';
@RedocComponent({
selector: 'method',
templateUrl: './lib/components/Method/method.html',
styleUrls: ['./lib/components/Method/method.css'],
directives: [ParamsList, ResponsesList, ResponsesSamples, SchemaSample]
})
export default class Method extends BaseComponent {
constructor(schemaMgr) {
super(schemaMgr);
}
prepareModel() {
this.data = {};
this.data.method = JsonPointer.baseName(this.pointer);
this.data.path = JsonPointer.baseName(this.pointer, 2);
this.data.methodInfo = this.componentSchema;
this.data.bodyParam = this.findBodyParam();
}
findBodyParam() {
let pathParams = this.schemaMgr.getMethodParams(JsonPointer.join(this.pointer, 'parameters'), true);
let bodyParam = pathParams.find(param => param.in === 'body');
return bodyParam;
}
}

View File

@ -0,0 +1,39 @@
method {
padding-bottom: 100px;
display: block;
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
}
.tag-info {
padding: 0 20px;
box-sizing: border-box;
background-color: white;
}
.tag-info:after, .tag-info:before {
content: "";
display: table;
}
.tag-info h1 {
color: rgb(102, 102, 102);
text-transform: capitalize;
padding-left: 10px;
border-left: 5px solid darkgreen;
}
.methods {
display: block;
position: relative;;
}
.methods:before {
content: "";
background: #2C2E3E;
height: 100%;
width: 40%;
top: 0;
right: 0;
position: absolute;
z-index: -1;
}

View File

@ -0,0 +1,11 @@
<div class="methods">
<div class="tag" *ng-for="#tag of data.tags">
<div class="tag-info" [attr.tag]="tag.name">
<a [attr.name]="tag.name"></a>
<h1> {{tag.name}} </h1>
<p *ng-if="tag.description" inner-html="{{ tag.description | marked }}"> </p>
</div>
<method *ng-for="#method of tag.methods" [pointer]="method.pointer" [attr.pointer]="method.pointer"
[attr.tag]="method.tag"></method>
</tag>
</div>

View File

@ -0,0 +1,41 @@
'use strict';
import {RedocComponent, BaseComponent} from '../base';
import Method from '../Method/method';
@RedocComponent({
selector: 'methods-list',
templateUrl: './lib/components/MethodsList/methods-list.html',
styleUrls: ['./lib/components/MethodsList/methods-list.css'],
directives: [Method]
})
export default class MethodsList extends BaseComponent {
constructor(schemaMgr) {
super(schemaMgr);
}
prepareModel() {
this.data = {};
// follow SwaggerUI behavior for cases when one method has more than one tag:
// duplicate methods
let menuStructure = this.schemaMgr.buildMenuTree();
let tags = Array.from(menuStructure.entries())
.map((entry) => {
let [tag, {description, methods}] = entry;
// inject tag name into method info
methods = methods || [];
methods.forEach(method => {
method.tag = tag;
});
return {
name: tag,
description: description,
methods: methods
};
});
this.data.tags = tags;
// TODO: check $ref field
}
}

View File

@ -0,0 +1,58 @@
h4 {
font-size: 16px;
font-weight: 200;
color: black;
}
table {
width: 100%;
border-spacing: 0;
border: 2px solid #053361;
}
td.param-name {
width: 20%;
}
td.param-description {
width: 30%;
}
thead tr:first-child {
background: #053361;
color: #fff;
border: none;
}
thead tr:last-child th {
border-bottom: 3px solid #ddd;
}
tbody tr:last-child td {
border: none;
}
tbody td {
border-bottom: 1px solid #ddd;
}
td, th {
vertical-align: top;
padding: 10px 10px;
font-size: 12px;
}
th {
text-align: left;
}
.param-type {
background-color: #EAEAEA;
border: silver 1px solid;
padding: 5px 10px;
line-height: 14px;
font-family: monospace;
}
.body-schema {
display: inline-block;
}

View File

@ -0,0 +1,40 @@
<table class="inline">
<!-- No params -->
<tr *ng-if="data.noParams">
<td colspan="3">
<small class="no-params" > No parameters </small>
</td>
</tr>
<thead>
<tr>
<th colspan="3"> Parameters </th>
</tr>
<tr *ng-if="!data.noParams">
<th> Name </th>
<th> Description </th>
<th> Type </th>
</tr>
</thead>
<tbody>
<!-- General parameters -->
<tr *ng-for="#param of data.params">
<!--<div class="param">-->
<td class="param-name">{{param.name}}</td>
<td class="param-description" inner-html="{{param.description | marked}}"></td>
<td>
<span class="type" [ng-class]="param.type">{{param.type}}</span>
</td>
<!--</div>-->
</tr>
<!-- in-body parameter -->
<tr class="param body-param" *ng-if="data.bodyParam">
<td class="param-name">{{data.bodyParam.name}}</td>
<td class="param-description" inner-html="{{data.bodyParam.description | marked}}"></td>
<td>
<schema class="body-schema param-type" pointer="{{data.bodyParam.pointer}}/schema">
</schema>
</td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,44 @@
'use strict';
import {RedocComponent, BaseComponent} from '../base';
import JsonSchemaView from '../JsonSchemaView/json-schema-view';
@RedocComponent({
selector: 'params-list',
templateUrl: './lib/components/ParamsList/params-list.html',
styleUrls: ['./lib/components/ParamsList/params-list.css'],
directives: [JsonSchemaView]
})
export default class ParamsList extends BaseComponent {
constructor(schemaMgr) {
super(schemaMgr);
}
prepareModel() {
this.data = {};
let params = this.schemaMgr.getMethodParams(this.pointer, true);
this.sortParams(params);
// temporary handle body param
if (params.length && params[params.length - 1].in === 'body') {
let bodyParam = params.pop();
bodyParam.pointer = bodyParam._pointer;
this.data.bodyParam = bodyParam;
}
this.data.noParams = !(params.length || this.data.bodyParam);
this.data.params = params;
}
sortParams(params) {
const sortOrder = {
'path' : 0,
'query' : 10,
'formData' : 20,
'header': 40,
'body': 50
};
params.sort((a, b) => sortOrder[a.in] - sortOrder[b.in]);
}
}

View File

@ -0,0 +1,2 @@
<api-info> </api-info>
<methods-list> </methods-list>

View File

@ -0,0 +1,18 @@
'use strict';
import {RedocComponent, BaseComponent} from '../base';
import SchemaManager from '../../utils/SchemaManager';
import ApiInfo from '../ApiInfo/api-info';
import MethodsList from '../MethodsList/methods-list';
@RedocComponent({
selector: 'redoc',
providers: [SchemaManager],
templateUrl: './lib/components/Redoc/redoc.html',
directives: [ApiInfo, MethodsList]
})
export default class Redoc extends BaseComponent {
constructor(schemaMgr) {
super(schemaMgr);
}
}

View File

@ -0,0 +1,44 @@
small {
color: #999;
}
table {
width: 100%;
border-spacing: 0;
border: 2px solid darkgreen;
}
th.response-code {
width: 10%;
}
th.response-description {
width: 30%;
}
thead tr:first-child {
background: darkgreen;
color: #fff;
border: none;
}
thead tr:last-child th {
border-bottom: 3px solid #ddd;
}
tbody tr:last-child td {
border: none;
}
tbody td {
border-bottom: 1px solid #ddd;
}
td, th {
vertical-align: top;
padding: 10px 10px;
font-size: 12px;
}
th {
text-align: left;
}

View File

@ -0,0 +1,23 @@
<table class="inline">
<thead>
<tr>
<th colspan="3"> Responses </th>
</tr>
<tr>
<th class="response-code"> Code </th>
<th class="response-description"> Description </th>
<th> Response schema </th>
</tr>
</thead>
<tbody>
<tr *ng-for="#response of data.responses">
<td>{{response.code}}</td>
<td inner-html="{{response.description | marked}}"></td>
<td>
<schema *ng-if="response.schema" class="schema type" pointer="{{response.pointer}}/schema">
</schema>
<small *ng-if="!response.schema"> N/A </small>
</td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,42 @@
'use strict';
import {RedocComponent, BaseComponent} from '../base';
import JsonPointer from '../../utils/JsonPointer';
import JsonSchemaView from '../JsonSchemaView/json-schema-view';
function isNumeric(n) {
return (!isNaN(parseFloat(n)) && isFinite(n));
}
@RedocComponent({
selector: 'responses-list',
templateUrl: './lib/components/ResponsesList/responses-list.html',
styleUrls: ['./lib/components/ResponsesList/responses-list.css'],
directives: [JsonSchemaView]
})
export default class ResponsesList extends BaseComponent {
constructor(schemaMgr) {
super(schemaMgr);
}
prepareModel() {
this.data = {};
let responses = this.componentSchema;
responses = Object.keys(responses).filter(respCode => {
// only response-codes and "default"
return ( isNumeric(respCode) || (respCode === 'default'));
}).map(respCode => {
let resp = responses[respCode];
resp.pointer = JsonPointer.join(this.pointer, respCode);
if (resp.$ref) {
let ref = resp.$ref;
resp = this.schemaMgr.byPointer(resp.$ref);
resp.pointer = ref;
}
resp.code = respCode;
return resp;
});
this.data.responses = responses;
}
}

View File

@ -0,0 +1,7 @@
tab, tabs {
display: block;
}
schema-sample {
display: block;
}

View File

@ -0,0 +1,6 @@
<small *ng-if="!data.responses.length"> No samples </small>
<tabs *ng-if="data.responses.length">
<tab *ng-for="#response of data.responses" [tab-title]="response.code">
<schema-sample [pointer]="response.pointer"><schema-sample>
</tab>
</tabs>

View File

@ -0,0 +1,50 @@
'use strict';
import {RedocComponent, BaseComponent} from '../base';
import JsonPointer from '../../utils/JsonPointer';
import {Tabs, Tab} from '../../common-components/Tabs/tabs';
import SchemaSample from '../SchemaSample/schema-sample';
function isNumeric(n) {
return (!isNaN(parseFloat(n)) && isFinite(n));
}
function hasExample(response) {
return ((response.examples && response.examples['application/json']) ||
response.schema);
}
@RedocComponent({
selector: 'responses-samples',
templateUrl: './lib/components/ResponsesSamples/responses-samples.html',
styleUrls: ['./lib/components/ResponsesSamples/responses-samples.css'],
directives: [SchemaSample, Tabs, Tab]
})
export default class ResponsesSamples extends BaseComponent {
constructor(schemaMgr) {
super(schemaMgr);
}
prepareModel() {
this.data = {};
let responses = this.componentSchema;
responses = Object.keys(responses).filter(respCode => {
// only response-codes and "default"
return ( isNumeric(respCode) || (respCode === 'default'));
}).map(respCode => {
let resp = responses[respCode];
resp.pointer = JsonPointer.join(this.pointer, respCode);
if (resp.$ref) {
let ref = resp.$ref;
resp = this.schemaMgr.byPointer(resp.$ref);
resp.pointer = ref;
}
resp.code = respCode;
return resp;
})
.filter(response => hasExample(response));
this.data.responses = responses;
}
}

View File

@ -0,0 +1,5 @@
<div class="snippet">
<!-- in case sample is not available for some reason -->
<pre *ng-if="data.sample == null"> Sample unavailable </pre>
<pre>{{data.sample | json}}</pre>
</div>

View File

@ -0,0 +1,47 @@
'use strict';
import {RedocComponent, BaseComponent} from '../base';
import SchemaSampler from 'json-schema-instantiator';
@RedocComponent({
selector: 'schema-sample',
templateUrl: './lib/components/SchemaSample/schema-sample.html',
styles: [`
pre {
background-color: #121427;
}
`]
})
export default class SchemaSample extends BaseComponent {
constructor(schemaMgr) {
super(schemaMgr);
}
init() {
this.data = {};
// sometimes for some reason this method is called without resolved pointer
// TODO: fix it and remove the following workaround
if (!this.componentSchema || !this.pointer) {
return;
}
let base = {};
let sample;
// got pointer not directly to the schema but e.g. to response obj
if (this.componentSchema.schema) {
base = this.componentSchema;
this.componentSchema = this.componentSchema.schema;
}
if (base.examples && base.examples['application/json']) {
sample = base.examples['application/json'];
} else {
this.dereference(this.componentSchema);
sample = SchemaSampler.instantiate(this.componentSchema);
}
this.data.sample = sample;
}
}

View File

@ -0,0 +1,4 @@
h2 {
text-transform: uppercase;
color: #1976D3;
}

View File

@ -0,0 +1,6 @@
<h2> Api reference </h2>
<div *ng-for="var cat of data.menu; var idx = index">
<side-menu-cat [cat-details]="cat" (expand)="activateAndScroll(idx, -1)"
(activate)="activateAndScroll(idx, $event.methodIdx)">
</side-menu-cat>
</div>

View File

@ -0,0 +1,147 @@
'use strict';
import {RedocComponent, BaseComponent} from '../base';
import SchemaManager from '../../utils/SchemaManager';
import SideMenuCat from '../SideMenuCat/side-menu-cat';
import {NgZone} from 'angular2/angular2';
const CHANGE = {
NEXT : 1,
BACK : -1,
INITIAL : 0
};
@RedocComponent({
selector: 'side-menu',
providers: [SchemaManager],
templateUrl: './lib/components/SideMenu/side-menu.html',
styleUrls: ['./lib/components/SideMenu/side-menu.css'],
directives: [SideMenuCat]
})
export default class SideMenu extends BaseComponent {
constructor(schemaMgr, zone) {
super(schemaMgr);
this.zone = zone;
// for some reason constructor is not run inside zone
// as workaround running it manually
this.zone.run(() => {
this.bindScroll();
});
this.activeCatIdx = 0;
this.activeMethodIdx = -1;
this.prevOffsetY = null;
}
bindScroll() {
this.prevOffsetY = window.scrollY;
window.addEventListener('scroll', () => this.scrollHandler());
}
activateAndScroll(idx, methodIdx) {
this.activate(idx, methodIdx);
this.scrollToActive();
}
scrollToActive() {
let subjRect = this.getMethodEl().getBoundingClientRect();
let offset = window.scrollY + subjRect.top;
window.scrollTo(0, offset);
}
activate(catIdx, methodIdx) {
let menu = this.data.menu;
menu[this.activeCatIdx].active = false;
if (menu[this.activeCatIdx].methods.length) {
if (this.activeMethodIdx >= 0) {
menu[this.activeCatIdx].methods[this.activeMethodIdx].active = false;
}
}
this.activeCatIdx = catIdx;
this.activeMethodIdx = methodIdx;
menu[catIdx].active = true;
this.activeMethodPtr = null;
if (menu[catIdx].methods.length && (methodIdx > -1)) {
let currentItem = menu[catIdx].methods[methodIdx];
currentItem.active = true;
this.activeMethodPtr = currentItem.pointer;
}
}
_calcActiveIndexes(offset) {
let menu = this.data.menu;
let catCount = menu.length;
let catLength = menu[this.activeCatIdx].methods.length;
let resMethodIdx = this.activeMethodIdx + offset;
let resCatIdx = this.activeCatIdx;
if (resMethodIdx > catLength - 1) {
resCatIdx++;
resMethodIdx = -1;
}
if (resMethodIdx < -1) {
let prevCatIdx = --resCatIdx;
catLength = menu[Math.max(prevCatIdx, 0)].methods.length;
resMethodIdx = catLength - 1;
}
if (resCatIdx > catCount - 1) {
resCatIdx = catCount - 1;
resMethodIdx = catLength - 1;
}
if (resCatIdx < 0) {
resCatIdx = 0;
resMethodIdx = 0;
}
return [resCatIdx, resMethodIdx];
}
changeActive(offset = 1) {
let [catIdx, methodIdx] = this._calcActiveIndexes(offset);
this.activate(catIdx, methodIdx);
return (methodIdx === 0 && catIdx === 0);
}
getMethodEl() {
let ptr = this.activeMethodPtr;
let tag = this.data.menu[this.activeCatIdx].name;
let selector = ptr ? `[pointer="${ptr}"][tag="${tag}"]` : `[tag="${tag}"]`;
return document.querySelector(selector);
}
scrollHandler() {
let isScrolledDown = (window.scrollY - this.prevOffsetY > 0);
this.prevOffsetY = window.scrollY;
let stable = false;
while(!stable) {
let activeMethodHost = this.getMethodEl();
if (!activeMethodHost) return;
if(isScrolledDown && activeMethodHost.getBoundingClientRect().bottom <= 0 ) {
stable = this.changeActive(CHANGE.NEXT);
continue;
}
if(!isScrolledDown && Math.floor(activeMethodHost.getBoundingClientRect().top) > 0 ) {
stable = this.changeActive(CHANGE.BACK);
continue;
}
stable = true;
}
}
prepareModel() {
this.data = {};
this.data.menu = Array.from(this.schemaMgr.buildMenuTree().entries()).map(
el => ({name: el[0], description: el[1].description, methods: el[1].methods})
);
}
init() {
this.changeActive(CHANGE.INITIAL);
}
}
SideMenu.parameters = SideMenu.parameters.concat([NgZone]);

View File

@ -0,0 +1,28 @@
label {
font-weight: bold;
font-size: 15px;
cursor: pointer;
color: #666;
text-transform: capitalize;
}
ul {
padding-left: 20px;
margin: 0;
height: 0;
overflow: hidden;
}
ul.active {
height: auto;
}
li {
list-style: none inside none;
padding: 5px 0;
cursor: pointer;
}
label.active, li.active {
color: #1976D3;
}

View File

@ -0,0 +1,8 @@
<label (click)="expandCat()" [ng-class]="{active: data.active}"> {{data.name}}</label>
<ul [ng-class]="{active: data.active}">
<li *ng-for="var method of data.methods; var idx = index"
[ng-class]="{active: method.active}"
(click)="activateMethod(idx)">
{{method.summary}}
</li>
</ul>

View File

@ -0,0 +1,31 @@
'use strict';
import {RedocComponent, BaseComponent} from '../base';
import {EventEmitter} from 'angular2/angular2';
@RedocComponent({
selector: 'side-menu-cat',
inputs: ['catDetails'],
outputs: ['expand', 'activate'],
styleUrls: ['./lib/components/SideMenuCat/side-menu-cat.css'],
templateUrl: './lib/components/SideMenuCat/side-menu-cat.html'
})
export default class SideMenuCat extends BaseComponent {
constructor(schemaMgr) {
super(schemaMgr);
this.expand = new EventEmitter();
this.activate = new EventEmitter();
}
expandCat() {
this.expand.next();
}
activateMethod(methodIdx) {
this.activate.next({methodIdx: methodIdx});
}
prepareModel() {
this.data = this.catDetails;
}
}

112
lib/components/base.js Normal file
View File

@ -0,0 +1,112 @@
'use strict';
import {Component, View, OnInit, CORE_DIRECTIVES} from 'angular2/angular2';
import SchemaManager from '../utils/SchemaManager';
import JsonPointer from '../utils/JsonPointer';
import {MarkedPipe, JsonPointerEscapePipe} from '../utils/pipes';
// common inputs for all components
let commonInputs = ['pointer']; // json pointer to the schema chunk
// internal helper function
function safeConcat(a, b) {
let res = a && a.slice() || [];
b = (b == null) ? [] : b;
return res.concat(b);
}
/**
* Class decorator
* Simplifies setup of component metainfo
* All options are options from either Component or View angular2 decorator
* For detailed info look angular2 doc
* @param {Object} options - component options
* @param {string[]} options.inputs - component inputs
* @param {*[]} options.directives - directives used by component
* (except CORE_DIRECTIVES)
* @param {*[]} options.pipes - pipes used by component
* @param {*[]} options.providers - component providers
* @param {string} options.templateUrl - path to component template
* @param {string} options.template - component template html
* @param {string} options.styles - component css styles
*/
export function RedocComponent(options) {
let inputs = safeConcat(options.inputs, commonInputs);
let directives = safeConcat(options.directives, CORE_DIRECTIVES);
let pipes = safeConcat(options.pipes, [JsonPointerEscapePipe, MarkedPipe]);
return function decorator(target) {
let componentDecorator = Component({
selector: options.selector,
inputs: inputs,
outputs: options.outputs,
lifecycle: [OnInit],
providers: options.providers
});
let viewDecorator = View({
templateUrl: options.templateUrl,
template: options.template,
styles: options.styles,
directives: directives,
pipes: pipes
});
return componentDecorator(viewDecorator(target) || target) || target;
};
}
/**
* Generic Component
* @class
*/
export class BaseComponent {
constructor(schemaMgr) {
this.schemaMgr = schemaMgr;
this.schema = schemaMgr.schema;
this.componentSchema = null;
}
/**
* onInit method is run by angular2 after all component inputs are resolved
*/
onInit() {
this.componentSchema = this.schemaMgr.byPointer(this.pointer || '');
this.prepareModel();
this.init();
}
/**
* simple in-place schema dereferencing. Schema is already bundled so no need in global dereferencing.
* TODO: doesn't support circular references
*/
dereference(schema = this.componentSchema) {
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.title = resolved.title || baseName;
Object.assign(schema, resolved);
delete schema.$ref;
}
Object.keys(schema).forEach((key) => {
let value = schema[key];
if (value && typeof value === 'object') {
this.dereference(value);
}
});
}
/**
* Used to prepare model based on component schema
* @abstract
*/
prepareModel() {}
/**
* Used to initialize component. Run after prepareModel
* @abstract
*/
init() {}
}
BaseComponent.parameters = [[SchemaManager]];

42
lib/components/index.js Normal file
View File

@ -0,0 +1,42 @@
'use strict';
import ApiInfo from './ApiInfo/api-info';
import JsonSchemaView from './JsonSchemaView/json-schema-view';
import Method from './Method/method.js';
import MethodsList from './MethodsList/methods-list';
import ParamsList from './ParamsList/params-list';
import Redoc from './Redoc/redoc';
import ResponsesList from './ResponsesList/responses-list';
import ResponsesSamples from './ResponsesSamples/responses-samples';
import SchemaSample from './SchemaSample/schema-sample';
import SideMenu from './SideMenu/side-menu';
import SideMenuCat from './SideMenuCat/side-menu-cat';
const REDOC_COMPONENTS = [
ApiInfo,
JsonSchemaView,
Method,
MethodsList,
ParamsList,
Redoc,
ResponsesList,
ResponsesSamples,
SchemaSample,
SideMenu,
SideMenuCat
];
export {
ApiInfo,
JsonSchemaView,
Method,
MethodsList,
ParamsList,
Redoc,
ResponsesList,
ResponsesSamples,
SchemaSample,
SideMenu,
SideMenuCat,
REDOC_COMPONENTS
};

21
lib/index.js Normal file
View File

@ -0,0 +1,21 @@
'use strict';
import {bootstrap} from 'angular2/angular2';
import {Redoc, SideMenu} from './components/index';
import SchemaManager from './utils/SchemaManager';
export * from './components/index';
export function init(schemaUrl) {
SchemaManager.instance().load(schemaUrl).then(
() => {
return bootstrap(SideMenu);
}
).then(() => bootstrap(Redoc))
.then(
() => console.log('ReDoc bootstrapped!'),
error => console.log(error)
);
}
window.Redoc = Redoc;

66
lib/utils/JsonPointer.js Normal file
View File

@ -0,0 +1,66 @@
'use strict';
import JsonPointerLib from 'json-pointer';
/**
* Wrapper for JsonPointer. Provides common operations
*/
export class JsonPointer extends JsonPointerLib {
/**
* returns last JsonPointer token
* if level > 1 returns levels last (second last/third last)
* @example
* // returns subpath
* JsonPointerHelper.baseName('/path/0/subpath')
* // returns foo
* JsonPointerHelper.baseName('/path/foo/subpath', 2)
*/
static baseName(pointer, level=1) {
let tokens = JsonPointer.parse(pointer);
return tokens[tokens.length - (level)];
}
/**
* returns dirname of pointer
* if level > 1 returns corresponding dirname in the hierarchy
* @example
* // returns /path/0
* JsonPointerHelper.dirName('/path/0/subpath')
* // returns /path
* JsonPointerHelper.dirName('/path/foo/subpath', 2)
*/
static dirName(pointer, level=1) {
let tokens = JsonPointer.parse(pointer);
return JsonPointer.compile(tokens.slice(0, tokens.length - level));
}
/**
* overridden JsonPointer original parse to take care of prefixing '#' symbol
* that is not valid JsonPointer
*/
static parse(pointer) {
let ptr = pointer;
if (ptr.charAt(0) === '#') {
ptr = ptr.substring(1);
}
return JsonPointerLib._origParse(ptr);
}
/**
* Creates a JSON pointer path, by joining one or more tokens to a base path.
*
* @param {string} base - The base path
* @param {string|string[]} tokens - The token(s) to append (e.g. ["name", "first"])
* @returns {string}
*/
static join(base, tokens) {
// TODO: optimize
let baseTokens = JsonPointer.parse(base);
let resTokens = baseTokens.concat(tokens);
return JsonPointer.compile(resTokens);
}
}
JsonPointerLib._origParse = JsonPointerLib.parse;
JsonPointerLib.parse = JsonPointer.parse;
export default JsonPointer;

131
lib/utils/SchemaManager.js Normal file
View File

@ -0,0 +1,131 @@
'use strict';
import SwaggerParser from 'swagger-parser';
import JsonPointer from './JsonPointer';
import {methods as swaggerMethods} from './swagger-defs';
export default class SchemaManager {
constructor() {
if (SchemaManager.prototype._instance) {
return SchemaManager.prototype._instance;
}
SchemaManager.prototype._instance = this;
this._schema = {};
}
static instance() {
return new SchemaManager();
}
load(url) {
let promise = new Promise((resolve, reject) => {
this._schema = {};
SwaggerParser.bundle(url, {http: {withCredentials: false}})
.then(
(schema) => {
this._schema = schema;
resolve(this._schema);
},
(err) => reject(err)
);
});
return promise;
}
get schema() {
// TODO: consider returning promise
return this._schema;
}
byPointer(pointer) {
let res = null;
try {
res = JsonPointer.get(this._schema, pointer);
} catch(e) {/*skip*/ }
return res;
}
resolveRefs(obj) {
Object.keys(obj).forEach(key => {
if (obj[key].$ref) {
obj[key] = this.byPointer(obj[key].$ref);
}
});
return obj;
}
getMethodParams(methodPtr, resolveRefs) {
/* inject JsonPointer into array elements */
function injectPointers(array, root) {
if (!array) return array;
return array.map((element, idx) => {
element._pointer = JsonPointer.join(root, idx);
return element;
});
}
//get path params
let ptr = JsonPointer.dirName(methodPtr, 2) + '/parameters';
let pathParams = this.byPointer(ptr);
if (Array.isArray(pathParams)) {
pathParams = injectPointers(pathParams, ptr);
} else if (pathParams && pathParams.$ref) {
pathParams = injectPointers(this.byPointer(pathParams.$ref), pathParams.$ref);
} else {
pathParams = [];
}
let methodParams = injectPointers(this.byPointer(methodPtr), methodPtr) || [];
if (resolveRefs) {
methodParams = this.resolveRefs(methodParams);
pathParams = this.resolveRefs(pathParams);
}
return methodParams.concat(pathParams);
}
/* returns ES6 Map */
buildMenuTree() {
let tag2MethodMapping = new Map();
let definedTags = this._schema.tags || [];
// add tags into map to preserve order
for (let tag of definedTags) {
tag2MethodMapping.set(tag.name, {
'description': tag.description,
'x-secondaryTag': tag['x-secondaryTag'],
'methods': []
});
}
let paths = this._schema.paths;
for (let path of Object.keys(paths)) {
let methods = Object.keys(paths[path]).filter((k) => swaggerMethods.has(k));
for (let method of methods) {
let methodInfo = paths[path][method];
let tags = methodInfo.tags;
//TODO: mb need to do something cleverer
if (!tags || !tags.length) {
tags = ['[Other]'];
}
let methodPointer = JsonPointer.compile(['paths', path, method]);
let methodSummary = methodInfo.summary;
for (let tag of tags) {
let tagDetails = tag2MethodMapping.get(tag);
if (!tagDetails) {
tagDetails = {};
tag2MethodMapping.set(tag, tagDetails);
}
if (tagDetails['x-secondaryTag']) continue;
if (!tagDetails.methods) tagDetails.methods = [];
tagDetails.methods.push({pointer: methodPointer, summary: methodSummary});
}
}
}
return tag2MethodMapping;
}
}

53
lib/utils/pipes.js Normal file
View File

@ -0,0 +1,53 @@
'use strict';
import {Pipe} from 'angular2/angular2';
import {JsonPointer} from './JsonPointer';
import marked from 'marked';
marked.setOptions({
renderer: new marked.Renderer(),
gfm: true,
tables: true,
breaks: false,
pedantic: false,
smartLists: true,
smartypants: false
});
@Pipe({
name: 'keys'
})
export class KeysPipe {
transform(obj) {
return Object.keys(obj);
}
}
@Pipe({
name: 'values'
})
export class ValuesPipe {
transform(obj) {
return Object.keys(obj).map(key => obj[key]);
}
}
@Pipe({
name: 'jsonPointerEscape'
})
export class JsonPointerEscapePipe {
transform(str) {
return JsonPointer.escape(str);
}
}
@Pipe({
name: 'marked'
})
export class MarkedPipe {
transform(str) {
if (!str) return str;
return marked(str);
}
}

View File

@ -0,0 +1,3 @@
'use strict';
export var methods = new Set(['get', 'put', 'post', 'delete', 'options', 'head', 'patch']);

71
package.json Normal file
View File

@ -0,0 +1,71 @@
{
"name": "redoc-proto",
"description": "Prototype of component based Swagger documentation",
"version": "0.0.1",
"private": true,
"repository": "RomanGotsiy/redoc-prototype",
"scripts": {
"test": "gulp lint",
"postinstall": "jspm install",
"start": "gulp serve",
"build": "gulp build"
},
"keywords": [
"Swagger",
"JSON-Schema",
"API",
"documentation",
"Angular 2"
],
"author": "Roman Hotsiy",
"license": "MIT",
"jspm": {
"configFile": "system.config.js",
"dependencies": {
"RomanGotsiy/json-schema-ref-parser": "github:RomanGotsiy/json-schema-ref-parser@master",
"angular2": "npm:angular2@^2.0.0-alpha.45",
"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",
"marked": "npm:marked@^0.3.5",
"reflect-metadata": "npm:reflect-metadata@^0.1.2",
"swagger-parser": "npm:swagger-parser@^3.3.0",
"zone.js": "npm:zone.js@^0.5.7"
},
"devDependencies": {
"babel": "npm:babel-core@^5.8.24",
"babel-runtime": "npm:babel-runtime@^5.8.24",
"clean-css": "npm:clean-css@^3.4.6",
"core-js": "npm:core-js@^1.1.4",
"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.3",
"browser-sync": "^2.9.8",
"del": "^2.0.2",
"gulp": "^3.9.0",
"gulp-concat": "^2.6.0",
"gulp-eslint": "^1.0.0",
"gulp-inline-ng2-template": "0.0.7",
"gulp-jshint": "^1.11.2",
"gulp-replace": "^0.5.4",
"gulp-sourcemaps": "^1.6.0",
"jshint-stylish": "^2.0.1",
"jspm": "^0.16.11",
"reflect-metadata": "^0.1.2",
"require-dir": "^0.3.0",
"run-sequence": "^1.1.4",
"systemjs-builder": "^0.14.7",
"vinyl-paths": "^2.0.0",
"zone.js": "^0.5.8"
}
}

813
system.config.js Normal file
View File

@ -0,0 +1,813 @@
System.config({
baseURL: "/",
defaultJSExtensions: true,
transpiler: "babel",
babelOptions: {
"optional": [
"runtime",
"optimisation.modules.system",
"es7.decorators",
"es7.classProperties"
]
},
paths: {
"github:*": "jspm_packages/github/*",
"npm:*": "jspm_packages/npm/*"
},
packages: {
"npm:swagger-schema-official@2.0.0-d79c205": {
"defaultExtension": "json",
"main": "schema.json",
"meta": {
"*": {
"loader": "json"
}
}
}
},
meta: {
"jspm_packages/npm/json-formatter-js@0.2.0/src/*": {
"format": "es6"
},
"jspm_packages/npm/json-schema-view-js@0.2.0/src/*": {
"format": "es6"
}
},
map: {
"RomanGotsiy/json-schema-ref-parser": "github:RomanGotsiy/json-schema-ref-parser@master",
"angular2": "npm:angular2@2.0.0-alpha.45",
"babel": "npm:babel-core@5.8.25",
"babel-runtime": "npm:babel-runtime@5.8.25",
"clean-css": "npm:clean-css@3.4.6",
"core-js": "npm:core-js@1.2.0",
"css": "github:systemjs/plugin-css@0.1.18",
"es6-shim": "github:es-shims/es6-shim@0.33.6",
"json": "github:systemjs/plugin-json@0.1.0",
"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",
"marked": "npm:marked@0.3.5",
"reflect-metadata": "npm:reflect-metadata@0.1.2",
"swagger-parser": "npm:swagger-parser@3.3.0",
"systemjs/plugin-json": "github:systemjs/plugin-json@0.1.0",
"zone.js": "npm:zone.js@0.5.8",
"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.1"
},
"github:jspm/nodelibs-constants@0.1.0": {
"constants-browserify": "npm:constants-browserify@0.0.1"
},
"github:jspm/nodelibs-crypto@0.1.0": {
"crypto-browserify": "npm:crypto-browserify@3.11.0"
},
"github:jspm/nodelibs-events@0.1.1": {
"events": "npm:events@1.0.2"
},
"github:jspm/nodelibs-http@1.7.1": {
"Base64": "npm:Base64@0.2.1",
"events": "github:jspm/nodelibs-events@0.1.1",
"inherits": "npm:inherits@2.0.1",
"stream": "github:jspm/nodelibs-stream@0.1.0",
"url": "github:jspm/nodelibs-url@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"github:jspm/nodelibs-https@0.1.0": {
"https-browserify": "npm:https-browserify@0.0.0"
},
"github:jspm/nodelibs-net@0.1.2": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"http": "github:jspm/nodelibs-http@1.7.1",
"net": "github:jspm/nodelibs-net@0.1.2",
"process": "github:jspm/nodelibs-process@0.1.2",
"stream": "github:jspm/nodelibs-stream@0.1.0",
"timers": "github:jspm/nodelibs-timers@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"github:jspm/nodelibs-os@0.1.0": {
"os-browserify": "npm:os-browserify@0.1.2"
},
"github:jspm/nodelibs-path@0.1.0": {
"path-browserify": "npm:path-browserify@0.0.0"
},
"github:jspm/nodelibs-process@0.1.2": {
"process": "npm:process@0.11.2"
},
"github:jspm/nodelibs-punycode@0.1.0": {
"punycode": "npm:punycode@1.3.2"
},
"github:jspm/nodelibs-querystring@0.1.0": {
"querystring": "npm:querystring@0.2.0"
},
"github:jspm/nodelibs-stream@0.1.0": {
"stream-browserify": "npm:stream-browserify@1.0.0"
},
"github:jspm/nodelibs-string_decoder@0.1.0": {
"string_decoder": "npm:string_decoder@0.10.31"
},
"github:jspm/nodelibs-timers@0.1.0": {
"timers-browserify": "npm:timers-browserify@1.4.1"
},
"github:jspm/nodelibs-tty@0.1.0": {
"tty-browserify": "npm:tty-browserify@0.0.0"
},
"github:jspm/nodelibs-url@0.1.0": {
"url": "npm:url@0.10.3"
},
"github:jspm/nodelibs-util@0.1.0": {
"util": "npm:util@0.10.3"
},
"github:jspm/nodelibs-vm@0.1.0": {
"vm-browserify": "npm:vm-browserify@0.0.4"
},
"github:jspm/nodelibs-zlib@0.1.0": {
"browserify-zlib": "npm:browserify-zlib@0.1.4"
},
"npm:@reactivex/rxjs@5.0.0-alpha.4": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"path": "github:jspm/nodelibs-path@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:amdefine@1.0.0": {
"fs": "github:jspm/nodelibs-fs@0.1.2",
"module": "github:jspm/nodelibs-module@0.1.0",
"path": "github:jspm/nodelibs-path@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:angular2@2.0.0-alpha.45": {
"@reactivex/rxjs": "npm:@reactivex/rxjs@5.0.0-alpha.4",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"fs": "github:jspm/nodelibs-fs@0.1.2",
"path": "github:jspm/nodelibs-path@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2",
"reflect-metadata": "npm:reflect-metadata@0.1.2",
"zone.js": "npm:zone.js@0.5.8"
},
"npm:argparse@1.0.3": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
"fs": "github:jspm/nodelibs-fs@0.1.2",
"lodash": "npm:lodash@3.10.1",
"path": "github:jspm/nodelibs-path@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2",
"sprintf-js": "npm:sprintf-js@1.0.3",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:asn1.js@4.0.0": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
"bn.js": "npm:bn.js@4.1.1",
"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": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"sys": "github:jspm/nodelibs-util@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:assert-plus@0.1.5": {
"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": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:aws-sign2@0.5.0": {
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"url": "github:jspm/nodelibs-url@0.1.0"
},
"npm:babel-runtime@5.8.25": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:bl@1.0.0": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"readable-stream": "npm:readable-stream@2.0.2",
"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": {
"hoek": "npm:hoek@2.16.3",
"http": "github:jspm/nodelibs-http@1.7.1"
},
"npm:browserify-aes@1.0.5": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"buffer-xor": "npm:buffer-xor@1.0.3",
"cipher-base": "npm:cipher-base@1.0.2",
"create-hash": "npm:create-hash@1.1.2",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"evp_bytestokey": "npm:evp_bytestokey@1.0.0",
"fs": "github:jspm/nodelibs-fs@0.1.2",
"inherits": "npm:inherits@2.0.1",
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
},
"npm:browserify-cipher@1.0.0": {
"browserify-aes": "npm:browserify-aes@1.0.5",
"browserify-des": "npm:browserify-des@1.0.0",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"evp_bytestokey": "npm:evp_bytestokey@1.0.0"
},
"npm:browserify-des@1.0.0": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"cipher-base": "npm:cipher-base@1.0.2",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"des.js": "npm:des.js@1.0.0",
"inherits": "npm:inherits@2.0.1"
},
"npm:browserify-rsa@4.0.0": {
"bn.js": "npm:bn.js@4.1.1",
"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"
},
"npm:browserify-sign@4.0.0": {
"bn.js": "npm:bn.js@4.1.1",
"browserify-rsa": "npm:browserify-rsa@4.0.0",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"create-hash": "npm:create-hash@1.1.2",
"create-hmac": "npm:create-hmac@1.1.4",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"elliptic": "npm:elliptic@6.0.1",
"inherits": "npm:inherits@2.0.1",
"parse-asn1": "npm:parse-asn1@5.0.0",
"stream": "github:jspm/nodelibs-stream@0.1.0"
},
"npm:browserify-zlib@0.1.4": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
"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",
"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.1": {
"base64-js": "npm:base64-js@0.0.8",
"ieee754": "npm:ieee754@1.1.6",
"is-array": "npm:is-array@1.0.1"
},
"npm:call-me-maybe@1.0.1": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:chalk@1.1.1": {
"ansi-styles": "npm:ansi-styles@2.1.0",
"escape-string-regexp": "npm:escape-string-regexp@1.0.3",
"has-ansi": "npm:has-ansi@2.0.0",
"process": "github:jspm/nodelibs-process@0.1.2",
"strip-ansi": "npm:strip-ansi@3.0.0",
"supports-color": "npm:supports-color@2.0.0"
},
"npm:cipher-base@1.0.2": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"inherits": "npm:inherits@2.0.1",
"stream": "github:jspm/nodelibs-stream@0.1.0",
"string_decoder": "github:jspm/nodelibs-string_decoder@0.1.0"
},
"npm:clean-css@3.4.6": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"commander": "npm:commander@2.8.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",
"os": "github:jspm/nodelibs-os@0.1.0",
"path": "github:jspm/nodelibs-path@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2",
"source-map": "npm:source-map@0.4.4",
"url": "github:jspm/nodelibs-url@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:combined-stream@1.0.5": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"delayed-stream": "npm:delayed-stream@1.0.0",
"stream": "github:jspm/nodelibs-stream@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:commander@2.8.1": {
"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"
},
"npm:core-js@1.2.0": {
"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"
},
"npm:core-util-is@1.0.1": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0"
},
"npm:create-ecdh@4.0.0": {
"bn.js": "npm:bn.js@4.1.1",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"elliptic": "npm:elliptic@6.0.1"
},
"npm:create-hash@1.1.2": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"cipher-base": "npm:cipher-base@1.0.2",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"fs": "github:jspm/nodelibs-fs@0.1.2",
"inherits": "npm:inherits@2.0.1",
"ripemd160": "npm:ripemd160@1.0.1",
"sha.js": "npm:sha.js@2.4.4"
},
"npm:create-hmac@1.1.4": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"create-hash": "npm:create-hash@1.1.2",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"inherits": "npm:inherits@2.0.1",
"stream": "github:jspm/nodelibs-stream@0.1.0"
},
"npm:cryptiles@2.0.5": {
"boom": "npm:boom@2.9.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0"
},
"npm:crypto-browserify@3.11.0": {
"browserify-cipher": "npm:browserify-cipher@1.0.0",
"browserify-sign": "npm:browserify-sign@4.0.0",
"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",
"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"
},
"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:debug@2.2.0": {
"fs": "github:jspm/nodelibs-fs@0.1.2",
"ms": "npm:ms@0.7.1",
"net": "github:jspm/nodelibs-net@0.1.2",
"process": "github:jspm/nodelibs-process@0.1.2",
"tty": "github:jspm/nodelibs-tty@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:delayed-stream@1.0.0": {
"stream": "github:jspm/nodelibs-stream@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:des.js@1.0.0": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"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.1.1",
"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",
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
},
"npm:elliptic@6.0.1": {
"bn.js": "npm:bn.js@4.1.1",
"brorand": "npm:brorand@1.0.5",
"hash.js": "npm:hash.js@1.0.3",
"inherits": "npm:inherits@2.0.1",
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
},
"npm:es6-promise@3.0.2": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:esprima@2.7.0": {
"fs": "github:jspm/nodelibs-fs@0.1.2",
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:evp_bytestokey@1.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"
},
"npm:forever-agent@0.6.1": {
"http": "github:jspm/nodelibs-http@1.7.1",
"https": "github:jspm/nodelibs-https@0.1.0",
"net": "github:jspm/nodelibs-net@0.1.2",
"tls": "github:jspm/nodelibs-tls@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:form-data@1.0.0-rc3": {
"async": "npm:async@1.4.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",
"path": "github:jspm/nodelibs-path@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2",
"url": "github:jspm/nodelibs-url@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:generate-function@2.0.0": {
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:generate-object-property@1.2.0": {
"is-property": "npm:is-property@1.0.2"
},
"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",
"chalk": "npm:chalk@1.1.1",
"commander": "npm:commander@2.8.1",
"is-my-json-valid": "npm:is-my-json-valid@2.12.2",
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
},
"npm:has-ansi@2.0.0": {
"ansi-regex": "npm:ansi-regex@2.0.0"
},
"npm:hash.js@1.0.3": {
"inherits": "npm:inherits@2.0.1"
},
"npm:hawk@3.1.0": {
"boom": "npm:boom@2.9.0",
"cryptiles": "npm:cryptiles@2.0.5",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"hoek": "npm:hoek@2.16.3",
"process": "github:jspm/nodelibs-process@0.1.2",
"sntp": "npm:sntp@1.0.9",
"systemjs-json": "github:systemjs/plugin-json@0.1.0",
"url": "github:jspm/nodelibs-url@0.1.0"
},
"npm:hoek@2.16.3": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"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:http-signature@0.11.0": {
"asn1": "npm:asn1@0.1.11",
"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",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:https-browserify@0.0.0": {
"http": "github:jspm/nodelibs-http@1.7.1"
},
"npm:inherits@2.0.1": {
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:is-my-json-valid@2.12.2": {
"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"
},
"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": {
"argparse": "npm:argparse@1.0.3",
"esprima": "npm:esprima@2.7.0",
"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"
},
"npm:json-formatter-js@0.2.0": {
"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"
},
"npm:json-pointer@0.3.0": {
"foreach": "npm:foreach@2.0.5"
},
"npm:json-schema-view-js@0.2.0": {
"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"
},
"npm:jsonpointer@2.0.0": {
"assert": "github:jspm/nodelibs-assert@0.1.0"
},
"npm:lodash._baseget@3.7.2": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:lodash._topath@3.8.1": {
"lodash.isarray": "npm:lodash.isarray@3.0.4",
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:lodash.get@3.7.0": {
"lodash._baseget": "npm:lodash._baseget@3.7.2",
"lodash._topath": "npm:lodash._topath@3.8.1"
},
"npm:lodash@3.10.1": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:miller-rabin@4.0.0": {
"bn.js": "npm:bn.js@4.1.1",
"brorand": "npm:brorand@1.0.5"
},
"npm:mime-db@1.19.0": {
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
},
"npm:mime-types@2.1.7": {
"mime-db": "npm:mime-db@1.19.0",
"path": "github:jspm/nodelibs-path@0.1.0"
},
"npm:node-uuid@1.4.3": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0"
},
"npm:oauth-sign@0.8.0": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2",
"querystring": "github:jspm/nodelibs-querystring@0.1.0"
},
"npm:ono@1.0.22": {
"process": "github:jspm/nodelibs-process@0.1.2",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:os-browserify@0.1.2": {
"os": "github:jspm/nodelibs-os@0.1.0"
},
"npm:pako@0.2.8": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:parse-asn1@5.0.0": {
"asn1.js": "npm:asn1.js@4.0.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",
"evp_bytestokey": "npm:evp_bytestokey@1.0.0",
"pbkdf2": "npm:pbkdf2@3.0.4",
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
},
"npm:path-browserify@0.0.0": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:pbkdf2@3.0.4": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"child_process": "github:jspm/nodelibs-child_process@0.1.0",
"create-hmac": "npm:create-hmac@1.1.4",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"path": "github:jspm/nodelibs-path@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2",
"systemjs-json": "github:systemjs/plugin-json@0.1.0"
},
"npm:process-nextick-args@1.0.3": {
"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.1.1",
"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"
},
"npm:punycode@1.3.2": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:randombytes@2.0.1": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:readable-stream@1.1.13": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"core-util-is": "npm:core-util-is@1.0.1",
"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",
"stream-browserify": "npm:stream-browserify@1.0.0",
"string_decoder": "npm:string_decoder@0.10.31"
},
"npm:readable-stream@2.0.2": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"core-util-is": "npm:core-util-is@1.0.1",
"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",
"string_decoder": "npm:string_decoder@0.10.31",
"util-deprecate": "npm:util-deprecate@1.0.1"
},
"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",
"bl": "npm:bl@1.0.0",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"caseless": "npm:caseless@0.11.0",
"combined-stream": "npm:combined-stream@1.0.5",
"crypto": "github:jspm/nodelibs-crypto@0.1.0",
"extend": "npm:extend@3.0.0",
"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",
"http": "github:jspm/nodelibs-http@1.7.1",
"http-signature": "npm:http-signature@0.11.0",
"https": "github:jspm/nodelibs-https@0.1.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",
"oauth-sign": "npm:oauth-sign@0.8.0",
"process": "github:jspm/nodelibs-process@0.1.2",
"qs": "npm:qs@5.1.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",
"url": "github:jspm/nodelibs-url@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0",
"zlib": "github:jspm/nodelibs-zlib@0.1.0"
},
"npm:ripemd160@1.0.1": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:sha.js@2.4.4": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"fs": "github:jspm/nodelibs-fs@0.1.2",
"inherits": "npm:inherits@2.0.1",
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:sntp@1.0.9": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"dgram": "github:jspm/nodelibs-dgram@0.1.0",
"dns": "github:jspm/nodelibs-dns@0.1.0",
"hoek": "npm:hoek@2.16.3",
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:source-map@0.4.4": {
"amdefine": "npm:amdefine@1.0.0",
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:stream-browserify@1.0.0": {
"events": "github:jspm/nodelibs-events@0.1.1",
"inherits": "npm:inherits@2.0.1",
"readable-stream": "npm:readable-stream@1.1.13"
},
"npm:string_decoder@0.10.31": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0"
},
"npm:stringstream@0.0.4": {
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"fs": "github:jspm/nodelibs-fs@0.1.2",
"process": "github:jspm/nodelibs-process@0.1.2",
"stream": "github:jspm/nodelibs-stream@0.1.0",
"string_decoder": "github:jspm/nodelibs-string_decoder@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0",
"zlib": "github:jspm/nodelibs-zlib@0.1.0"
},
"npm:strip-ansi@3.0.0": {
"ansi-regex": "npm:ansi-regex@2.0.0"
},
"npm:supports-color@2.0.0": {
"process": "github:jspm/nodelibs-process@0.1.2"
},
"npm:swagger-parser@3.3.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",
"json-schema-ref-parser": "github:RomanGotsiy/json-schema-ref-parser@master",
"ono": "npm:ono@1.0.22",
"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",
"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"
},
"npm:timers-browserify@1.4.1": {
"process": "npm:process@0.11.2"
},
"npm:tough-cookie@2.1.0": {
"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": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
"buffer": "github:jspm/nodelibs-buffer@0.1.0",
"events": "github:jspm/nodelibs-events@0.1.1",
"http": "github:jspm/nodelibs-http@1.7.1",
"https": "github:jspm/nodelibs-https@0.1.0",
"net": "github:jspm/nodelibs-net@0.1.2",
"process": "github:jspm/nodelibs-process@0.1.2",
"tls": "github:jspm/nodelibs-tls@0.1.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:url@0.10.3": {
"assert": "github:jspm/nodelibs-assert@0.1.0",
"punycode": "npm:punycode@1.3.2",
"querystring": "npm:querystring@0.2.0",
"util": "github:jspm/nodelibs-util@0.1.0"
},
"npm:util-deprecate@1.0.1": {
"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": {
"systemjs-json": "github:systemjs/plugin-json@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",
"lodash.get": "npm:lodash.get@3.7.0",
"process": "github:jspm/nodelibs-process@0.1.2",
"request": "npm:request@2.64.0",
"systemjs-json": "github:systemjs/plugin-json@0.1.0",
"validator": "npm:validator@4.1.0"
},
"npm:zone.js@0.5.8": {
"es6-promise": "npm:es6-promise@3.0.2",
"process": "github:jspm/nodelibs-process@0.1.2"
}
}
});