diff --git a/.codeclimate.yml b/.codeclimate.yml deleted file mode 100644 index 6ed0167a..00000000 --- a/.codeclimate.yml +++ /dev/null @@ -1,12 +0,0 @@ -engines: - eslint: - enabled: true - scss-lint: - enabled: true - fixme: - enabled: true -ratings: - paths: - - "lib/**" -exclude_paths: - - "**.spec.js" diff --git a/.travis.yml b/.travis.yml index 0cd1a4d7..c720646e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -32,7 +32,7 @@ before_script: after_script: - kill %1 # kill e2e server before_deploy: -- npm run build:prod-module +- if [[ ! -z "$TRAVIS_TAG" ]]; then npm run build:prod-module; fi deploy: - provider: npm skip_cleanup: true diff --git a/README.md b/README.md index 533d86d6..11f2cf99 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # ReDoc **OpenAPI/Swagger-generated API Reference Documentation** -[![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) [![Tested on APIs.guru](http://api.apis.guru/badges/tested_on.svg)](https://APIs.guru) [![Code Climate](https://codeclimate.com/github/Rebilly/ReDoc/badges/gpa.svg)](https://codeclimate.com/github/Rebilly/ReDoc) [![dependencies Status](https://david-dm.org/Rebilly/ReDoc/status.svg)](https://david-dm.org/Rebilly/ReDoc) [![devDependencies Status](https://david-dm.org/Rebilly/ReDoc/dev-status.svg)](https://david-dm.org/Rebilly/ReDoc#info=devDependencies) [![Stories in Ready](https://badge.waffle.io/Rebilly/ReDoc.png?label=ready&title=Ready)](https://waffle.io/Rebilly/ReDoc) +[![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) [![Tested on APIs.guru](http://api.apis.guru/badges/tested_on.svg)](https://APIs.guru) [![dependencies Status](https://david-dm.org/Rebilly/ReDoc/status.svg)](https://david-dm.org/Rebilly/ReDoc) [![devDependencies Status](https://david-dm.org/Rebilly/ReDoc/dev-status.svg)](https://david-dm.org/Rebilly/ReDoc#info=devDependencies) [![Stories in Ready](https://badge.waffle.io/Rebilly/ReDoc.png?label=ready&title=Ready)](https://waffle.io/Rebilly/ReDoc) [![npm](http://img.shields.io/npm/v/redoc.svg)](https://www.npmjs.com/package/redoc) [![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) @@ -112,6 +112,7 @@ ReDoc makes use of the following [vendor extensions](http://swagger.io/specifica * **selector**: selector of the element to be used for specifying the offset. The distance from the top of the page to the element's bottom will be used as offset; * **function**: A getter function. Must return a number representing the offset (in pixels); * `suppress-warnings` - if set, warnings are not rendered at the top of documentation (they still are logged to the console). +* `hide-hostname` - if set, the protocol and hostname is not shown in the method definition. ## Advanced usage Instead of adding `spec-url` attribute to the `` element you can initialize ReDoc via globally exposed `Redoc` object: @@ -139,3 +140,5 @@ Redoc.init('http://petstore.swagger.io/v2/swagger.json', { - Start the server `npm start` - Open `http://localhost:9000` + +Alternatively, Docker can be used by just running `docker-compose up`. diff --git a/build/webpack.dev.js b/build/webpack.dev.js index 449f6d50..3235c5fe 100644 --- a/build/webpack.dev.js +++ b/build/webpack.dev.js @@ -8,8 +8,7 @@ const IS_PRODUCTION = process.env.NODE_ENV === "production"; // TODO Refactor common parts of config module.exports = { - context: root(), - devtool: 'source-map', + devtool: '#inline-source-map', resolve: { extensions: ['.ts', '.js', '.json', '.css'], @@ -51,7 +50,9 @@ module.exports = { path: root('dist'), filename: '[name].js', sourceMapFilename: '[name].[id].map', - chunkFilename: '[id].chunk.js' + chunkFilename: '[id].chunk.js', + // devtoolModuleFilenameTemplate: "[resource-path]", + // devtoolFallbackModuleFilenameTemplate: "[resource-path]?[hash]", }, module: { diff --git a/build/webpack.prod.js b/build/webpack.prod.js index 8fc8ef45..5fc59973 100644 --- a/build/webpack.prod.js +++ b/build/webpack.prod.js @@ -3,7 +3,6 @@ const webpack = require('webpack'); const VERSION = JSON.stringify(require('../package.json').version); const root = require('./helpers').root; -const CopyWebpackPlugin = require('copy-webpack-plugin'); const BANNER = `ReDoc - OpenAPI/Swagger-generated API Reference Documentation ------------------------------------------------------------- diff --git a/demo/swagger.yaml b/demo/swagger.yaml index ac84c381..17d45c4c 100644 --- a/demo/swagger.yaml +++ b/demo/swagger.yaml @@ -26,6 +26,14 @@ info: This API features Cross-Origin Resource Sharing (CORS) implemented in compliance with [W3C spec](https://www.w3.org/TR/cors/). And that allows cross-domain communication from the browser. All responses have a wildcard same-origin which makes them completely public and accessible to everyone, including any code on any site. + # Authentication + Petstore offers two forms of authentication: + - API Key + - OAuth2 + + OAuth2 - an open protocol to allow secure authorization in a simple + and standard method from web, mobile and desktop applications. + version: 1.0.0 title: Swagger Petstore termsOfService: 'http://swagger.io/terms/' @@ -48,6 +56,9 @@ tags: description: Operations about user securityDefinitions: petstore_auth: + description: | + Get access to data while protecting your account credentials. + OAuth2 is also a safer and more secure way to give you access. type: oauth2 authorizationUrl: 'http://petstore.swagger.io/api/oauth/dialog' flow: implicit @@ -55,6 +66,8 @@ securityDefinitions: 'write:pets': modify pets in your account 'read:pets': read your pets api_key: + description: | + For this sample, you can use the api key `special-key` to test the authorization filters. type: apiKey name: api_key in: header diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..f61847b9 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,8 @@ +dev: + image: node:7 + command: sh -c "npm install; npm start -- --host=0.0.0.0" + ports: + - "9000:9000" + volumes: + - "./:/code" + working_dir: /code diff --git a/lib/components/ApiInfo/api-info.html b/lib/components/ApiInfo/api-info.html index b8a8428c..19d5924b 100644 --- a/lib/components/ApiInfo/api-info.html +++ b/lib/components/ApiInfo/api-info.html @@ -1,5 +1,5 @@ -
-

{{info.title}} ({{info.version}})

+
+

{{info.title}} ({{info.version}})

Download OpenAPI (fka Swagger) specification: Download @@ -17,5 +17,7 @@ {{info.license.name}}

- + + +
diff --git a/lib/components/ApiInfo/api-info.scss b/lib/components/ApiInfo/api-info.scss index 0c7c1a81..b029683a 100644 --- a/lib/components/ApiInfo/api-info.scss +++ b/lib/components/ApiInfo/api-info.scss @@ -1,28 +1,24 @@ @import '../../shared/styles/variables'; -.api-info-header { - font-weight: normal; -} - -:host > div { - width: 60%; - padding: 40px; +:host > .api-info-wrapper { box-sizing: border-box; + padding: $section-spacing; + width: 60%; + @media (max-width: $right-panel-squash-breakpoint) { width: 100%; } } -a.openapi-button { - padding: 3px 8px 4px 8px; - color: $primary-color; +.openapi-button { border: 1px solid $primary-color; - margin-left: 0.5em; + color: $primary-color; font-weight: normal; + margin-left: 0.5em; + padding: 3px 8px 4px; } :host /deep/ [section] { - padding-top: 60px; - margin-top: 20px; + padding-top: 2 * $section-spacing; } diff --git a/lib/components/ApiLogo/api-logo.scss b/lib/components/ApiLogo/api-logo.scss index 7f78e62b..cf1cc7f6 100644 --- a/lib/components/ApiLogo/api-logo.scss +++ b/lib/components/ApiLogo/api-logo.scss @@ -1,5 +1,14 @@ @import '../../shared/styles/variables'; +:host { + display: block; + text-align: center; + + @media (max-width: $side-menu-mobile-breakpoint) { + display: none; + } +} + img { max-height: 150px; width: auto; diff --git a/lib/components/JsonSchema/_json-schema-common.scss b/lib/components/JsonSchema/_json-schema-common.scss index d50ad788..bc4d44d3 100644 --- a/lib/components/JsonSchema/_json-schema-common.scss +++ b/lib/components/JsonSchema/_json-schema-common.scss @@ -5,26 +5,16 @@ $cell-spacing: 25px; $cell-padding: 10px; $bullet-margin: 10px; $line-border: $lines-width solid $tree-lines-color; -$line-border-erase: ($lines-width + 1px) solid #fff; +$line-border-erase: ($lines-width + 1px) solid $background-color; + +$border-color: lighten($secondary-color, 50%); +$nullable-color: #3195a6; +$hint-border: 1px dotted rgba(38, 50, 56, 0.4); $param-name-height: 20px; $sub-schema-offset: ($bullet-size / 2) + $bullet-margin; -.param-name { - position: relative; - border-left: $line-border; - padding: $cell-padding 0; - vertical-align: top; - line-height: $param-name-height; - - white-space: nowrap; - font-size: 0.929em; - font-weight: $regular; - - box-sizing: border-box; -} - .param-name-wrap { display: inline-block; padding-right: $cell-spacing; @@ -32,10 +22,9 @@ $sub-schema-offset: ($bullet-size / 2) + $bullet-margin; } .param-info { - border-bottom: 1px solid #ccc; + border-bottom: 1px solid $border-color; padding: $cell-padding 0; width: 75%; - line-height: 1em; box-sizing: border-box; } @@ -46,7 +35,7 @@ $sub-schema-offset: ($bullet-size / 2) + $bullet-margin; margin-right: 6px; margin-left: 6px; border-radius: $border-radius; - background-color: rgba($primary-color, .1); + background-color: rgba($primary-color, 0.1); padding: 0 4px; color: rgba($primary-color, 0.7); } @@ -58,7 +47,7 @@ $sub-schema-offset: ($bullet-size / 2) + $bullet-margin; .param-required { vertical-align: middle; line-height: $param-name-height; - color: #f00; + color: $red; font-size: 12px; font-weight: bold; } @@ -66,7 +55,7 @@ $sub-schema-offset: ($bullet-size / 2) + $bullet-margin; .param-nullable { vertical-align: middle; line-height: $param-name-height; - color: #3195a6; + color: $nullable-color; font-size: 12px; font-weight: bold; } @@ -77,82 +66,103 @@ $sub-schema-offset: ($bullet-size / 2) + $bullet-margin; color: rgba($black, 0.4); font-size: 0.929em; font-weight: normal; + + &.array::before { + content: $array-text; + color: $black; + font-weight: $base-font-weight; + } + + &.tuple::before { + content: $tuple-text; + color: $black; + font-weight: $base-font-weight; + } + + &.with-hint { + display: inline-block; + margin-bottom: 0.4em; + border-bottom: $hint-border; + padding: 0; + cursor: help; + } + + &-trivial { + display: inline-block; + } + + &-file { + font-weight: bold; + text-transform: capitalize; + } } -.param-type.array:before { - content: "Array of "; - color: $black; - font-weight: $base-font-weight; -} - -.param-type.tuple:before { - content: "Tuple"; - color: $black; - font-weight: $base-font-weight; -} - -.param-type.with-hint { - display: inline-block; - margin-bottom: 0.4em; - border-bottom: 1px dotted rgba(38,50,56,0.4); - padding: 0; - cursor: help; -} - -.param-type-trivial { - display: inline-block; -} - -.param-type-file { - font-weight: bold; - text-transform: capitalize; -} - -/* tree */ +// tree // Bullet -.param-name > span:before { - content: ""; - display: inline-block; - width: $bullet-size; - height: $bullet-size + 6; - background-color: $primary-color; - margin: 0 $bullet-margin; - vertical-align: middle; -} - -.param-name > span:after { - content: ""; - position: absolute; - border-top: $line-border; - width: $bullet-margin; - left: 0; - top: ($param-name-height/2) + $cell-padding + 1; -} - - .param:first-of-type > .param-name:before { - content: ""; - display: block; - position: absolute; - left: -$lines-width; - top: 0; - border-left: $line-border-erase; - height: ($param-name-height/2) + $cell-padding + 1; -} - -.param:last-of-type > .param-name, .param.last > .param-name { +.param-name { + border-left: $line-border; + box-sizing: border-box; position: relative; - &:after { - content: ""; + padding: $cell-padding 0; + vertical-align: top; + line-height: $param-name-height; + + white-space: nowrap; + font-size: 0.929em; + font-weight: $regular; + + > span::before { + content: ''; + display: inline-block; + width: $bullet-size; + height: $bullet-size + 6; + background-color: $primary-color; + margin: 0 $bullet-margin; + vertical-align: middle; + } + + > span::after { + content: ''; + position: absolute; + border-top: $line-border; + width: $bullet-margin; + left: 0; + top: ($param-name-height / 2) + $cell-padding + 1; + } +} + +.param:first-of-type { + + > .param-name::before { + content: ''; display: block; position: absolute; - left: -$lines-width - 1px; + left: -$lines-width; + top: 0; border-left: $line-border-erase; - top: ($param-name-height/2) + $cell-padding + $lines-width + 1; - background-color: white; - bottom: 0; + height: ($param-name-height / 2) + $cell-padding + 1; + } +} + +.param:last-of-type, +.param.last { + + > .param-name { + position: relative; + + &::after { + content: ''; + display: block; + position: absolute; + left: -$lines-width - 1px; + border-left: $line-border-erase; + top: ($param-name-height / 2) + $cell-padding + $lines-width + 1; + background-color: $background-color; + bottom: 0; + } } } @@ -160,33 +170,60 @@ $sub-schema-offset: ($bullet-size / 2) + $bullet-margin; border-left-color: transparent; } -.param-schema .param-wrap:first-of-type .param-name:before { - display: none !important; +.param-schema { + .param-wrap:first-of-type { + .param-name::before { + display: none; + } + } } -.param-schema.last > td { - border-left: 0; +.param-schema.last { + > td { + border-left: 0; + } } .param-enum { color: $text-color; - font-size: 13px; + font-size: 0.95em; - &:before { - content: 'Values: {'; - } - - &:after { - content: '}'; - } - - > .enum-value { - &:after { - content: ", "; - } - - &:last-of-type:after { - content: none; - } + &::before { + content: 'Valid values: '; } } + +.param-pattern { + color: $nullable-color; + white-space: nowrap; + + &::before, + &::after { + content: '/'; + margin: 0 3px; + font-size: 1.2em; + font-weight: bold; + vertical-align: bottom; + } +} + +.param-default { + font-size: 0.95em; + + &::before { + content: 'Default: '; + } +} + +.param-enum-value, +.param-default-value { + background-color: $background-color; + border: 1px solid rgba($secondary-color, 0.2); + margin: 2px 3px; + padding: 0 5px; + border-radius: 2px; + color: $secondary-color; + display: inline-block; + min-width: 20px; + text-align: center; +} diff --git a/lib/components/JsonSchema/json-schema.html b/lib/components/JsonSchema/json-schema.html index 67d70ff8..295f2d1a 100644 --- a/lib/components/JsonSchema/json-schema.html +++ b/lib/components/JsonSchema/json-schema.html @@ -23,8 +23,9 @@ Nullable
- {{enumItem.val | json}} + {{enumItem.val | json}}
+ {{schema.pattern}}