From 63d1d3b4af4cbac3a5f43e9aa32cb88fc18539d0 Mon Sep 17 00:00:00 2001 From: Brendan Abbott Date: Tue, 27 Jun 2017 16:39:50 +1000 Subject: [PATCH 1/2] Support definitions that don't have tags. Closes #140 --- README.md | 10 +- docs/open-api-v3-support.md | 2 +- package.json | 6 +- src/components/Navigation/Navigation.js | 13 +- .../Navigation/Navigation.styles.js | 4 + src/parser/open-api/v3/navigationParser.js | 60 ++++++ src/parser/open-api/v3/open-api-v3-parser.js | 174 ++++++++++-------- .../data/inputs/api-with-examples.false.json | 159 ++++++++++++++++ .../data/outputs/api-with-examples.false.json | 62 +++++++ yarn.lock | 58 ++---- 10 files changed, 418 insertions(+), 130 deletions(-) create mode 100644 src/parser/open-api/v3/navigationParser.js create mode 100644 test/parser/open-api/v3/data/inputs/api-with-examples.false.json create mode 100644 test/parser/open-api/v3/data/outputs/api-with-examples.false.json diff --git a/README.md b/README.md index b79e6f9..e548d1d 100644 --- a/README.md +++ b/README.md @@ -53,11 +53,11 @@ You need to specify a url for the `Open API v3` file, e.g. {navigation && navigation.map((tag) => { - let shouldBeExpanded = false - if (expandedTags.includes(tag.title)) { - shouldBeExpanded = true + // Handle a navigation that doesn't require tags. + if (!tag.methods) { + const isActive = (`#${tag.link}` === location.hash) + return ( + + ) } + // Otherwise the navigation is grouped by tag. return ( diff --git a/src/components/Navigation/Navigation.styles.js b/src/components/Navigation/Navigation.styles.js index 415ed8f..f42ad22 100644 --- a/src/components/Navigation/Navigation.styles.js +++ b/src/components/Navigation/Navigation.styles.js @@ -19,6 +19,10 @@ export const styles = createSheet(({ backgrounds }) => ({ '& > div + div': { borderTop: '1px solid #444' + }, + + '& > a': { + padding: '.7rem 1rem' } } })) diff --git a/src/parser/open-api/v3/navigationParser.js b/src/parser/open-api/v3/navigationParser.js new file mode 100644 index 0000000..e7a960d --- /dev/null +++ b/src/parser/open-api/v3/navigationParser.js @@ -0,0 +1,60 @@ +/** + * Return the permalink for the given `path` and `methodType`. Note this is + * not the link to the actual path, but it's a unique identifier to help + * with deeplinking from UI applications. + * + * @todo Look at supporting `operationId` which does this purpose. + * @param {string} path + * @param {string} methodType + */ +function getPermalink (path, methodType) { + return `${path}/${methodType}` +} + +/** + * Given the `path`, `method` and optionally the `tag`, construct + * an object that represents the navigation method. + * + * @param {string} path + * @param {object} method + * @param {object} tag + * @return {object} + */ +export function getNavigationMethod (path, method, tag) { + return { + type: method.type, + title: method.summary, + link: getPermalink(path, method.type) + } +} + +/** + * Construct the object used to render the method in the body of the renderer. + * This should represent all the information to create a request and receive + * a response for the given `method`. + * + * @param {string} path + * @param {object} method + * @param {object} request + * @param {object} params + * @param {object} responses + */ +export function getServicesMethod ({ path, method, request, params, responses }) { + const servicesMethod = { + type: method.type, + title: method.summary, + link: getPermalink(path, method.type), + request, + responses + } + + if (method.description) { + servicesMethod.description = method.description + } + + if (params) { + servicesMethod.parameters = params + } + + return servicesMethod +} diff --git a/src/parser/open-api/v3/open-api-v3-parser.js b/src/parser/open-api/v3/open-api-v3-parser.js index a0eb1d3..9de5be5 100644 --- a/src/parser/open-api/v3/open-api-v3-parser.js +++ b/src/parser/open-api/v3/open-api-v3-parser.js @@ -1,10 +1,36 @@ import refParser from 'json-schema-ref-parser' import { getSecurityDefinitions, getUISecurity } from './securityParser' +import { getNavigationMethod, getServicesMethod } from './navigationParser' import getUIReadySchema from '../schemaParser' /** * Construct navigation and services ready to be consumed by the UI * + * @param {Object} paths + * @param {Array} apiSecurity + * @param {Object} securityDefinitions + * @return {{navigation: [], services: []}} + */ +function getUINavigationAndServices ({ paths, apiSecurity = [], securityDefinitions }) { + const { navigationMethods: navigation, servicesMethods } = + buildNavigationAndServices(paths, apiSecurity, securityDefinitions) + + // Need to wrap up the methods to be individual services blocks. + // This simplifies the component logic. + const services = servicesMethods.map(method => { + return { + title: method.title, + methods: [ method ] + } + }) + + return {navigation, services} +} + +/** + * Construct navigation and services ready to be consumed by the UI using tags. + * This will group the paths by the logical tags. + * * @param {Array} tags * @param {Object} paths * @param {Array} apiSecurity @@ -12,79 +38,86 @@ import getUIReadySchema from '../schemaParser' * @param {Function} sortFunc * @return {{navigation: [], services: []}} */ -function getUINavigationAndServices ({ tags, paths, apiSecurity = [], securityDefinitions, sortFunc }) { +function getUINavigationAndServicesByTags ({ tags, paths, apiSecurity = [], securityDefinitions, sortFunc }) { const navigation = [] const services = [] + const isFunc = typeof sortFunc === 'function' - for (let i = 0; i < tags.length; i++) { + for (let i = 0, tagLength = tags.length; i < tagLength; i++) { const tag = tags[i] - const navigationMethods = [] - const servicesMethods = [] - const pathIds = Object.keys(paths) - - for (let j = 0; j < pathIds.length; j++) { - const pathId = pathIds[j] - const path = paths[pathId] - const methodTypes = Object.keys(path) + const exclusionFunc = (method) => method.tags.includes(tag) === false + const { navigationMethods, servicesMethods } = + buildNavigationAndServices(paths, apiSecurity, securityDefinitions, exclusionFunc) - for (let k = 0; k < methodTypes.length; k++) { - const methodType = methodTypes[k] - const method = path[methodType] + navigation.push({ + title: tag, + methods: isFunc ? navigationMethods.sort(sortFunc) : navigationMethods + }) - if (!method.tags.includes(tag)) { - continue - } + services.push({ + title: tag, + methods: isFunc ? servicesMethods.sort(sortFunc) : servicesMethods + }) + } - const link = pathId + '/' + methodType - const navigationMethod = { - type: methodType, - title: method.summary, - link - } - navigationMethods.push(navigationMethod) - - const uiRequest = getUIRequest(method.description, method.requestBody) - const uiResponses = getUIResponses(method.responses) - const servicesMethod = { - type: methodType, - title: method.summary, - link, - request: uiRequest, - responses: uiResponses - } + return { navigation, services } +} - if (method.description) { - servicesMethod.description = method.description - } +/** + * Build the navigation and services from the given paths. + * Optionally run an `exclusionFunc` which if returns true, will skip + * the path from being included in the result. + * + * @param {Object} paths + * @param {Array} apiSecurity + * @param {Object} securityDefinitions + * @param {Function} exclusionFunc + * @return {{navigation: [], services: []}} + */ +function buildNavigationAndServices (paths, apiSecurity, securityDefinitions, exclusionFunc) { + const pathIds = Object.keys(paths) + const navigationMethods = [] + const servicesMethods = [] + const isFunc = typeof exclusionFunc === 'function' + + for (let j = 0, pathIdLength = pathIds.length; j < pathIdLength; j++) { + const pathId = pathIds[j] + const path = paths[pathId] + const methodTypes = Object.keys(path) + + for (let k = 0, methodLength = methodTypes.length; k < methodLength; k++) { + const methodType = methodTypes[k] + const method = Object.assign({ type: methodType }, path[methodType]) + + // Should this be included in the output? + if (isFunc && exclusionFunc(method)) { + continue + } - // Security can be declared per method, or globally for the entire API. - if (method.security) { - servicesMethod.security = getUISecurity(method.security, securityDefinitions) - } else if (apiSecurity.length) { - servicesMethod.security = getUISecurity(apiSecurity, securityDefinitions) - } + // Add the navigation item + navigationMethods.push(getNavigationMethod(pathId, method)) - const uiParameters = getUIParameters(method.parameters) - if (uiParameters) { - servicesMethod.parameters = uiParameters - } + // Construct the full method object + const servicesMethod = getServicesMethod({ + path: pathId, + method, + request: getUIRequest(method.description, method.requestBody), + params: getUIParameters(method.parameters), + responses: getUIResponses(method.responses) + }) - servicesMethods.push(servicesMethod) + // Security can be declared per method, or globally for the entire API. + if (method.security) { + servicesMethod.security = getUISecurity(method.security, securityDefinitions) + } else if (apiSecurity.length) { + servicesMethod.security = getUISecurity(apiSecurity, securityDefinitions) } - } - navigation.push({ - title: tag, - methods: typeof sortFunc === 'function' ? navigationMethods.sort(sortFunc) : navigationMethods - }) - - services.push({ - title: tag, - methods: typeof sortFunc === 'function' ? servicesMethods.sort(sortFunc) : servicesMethods - }) + servicesMethods.push(servicesMethod) + } } - return {navigation, services} + return { navigationMethods, servicesMethods } } /** @@ -277,6 +310,10 @@ function getTags (paths) { for (const methodKey in path) { const method = path[methodKey] + if (Array.isArray(method.tags) === false) { + continue + } + method.tags.forEach(tag => { if (!tagCollection.includes(tag)) { tagCollection.push(tag) @@ -334,23 +371,16 @@ export default async function getUIReadyDefinition (openApiV3, sortFunc) { const info = derefOpenApiV3.info const paths = derefOpenApiV3.paths const apiSecurity = derefOpenApiV3.security || [] - - // Get tags from the paths - const tags = getTags(paths) - - // Get security definitions const securityDefinitions = getSecurityDefinitions(derefOpenApiV3) - // Construction navigation and services - const {navigation, services} = getUINavigationAndServices({ - tags, - paths, - apiSecurity, - securityDefinitions, - sortFunc - }) + // Construct navigation and services, which differs depending on + // if the definition utilises tags or not. + const tags = getTags(paths) + const {navigation, services} = (tags.length) + ? getUINavigationAndServicesByTags({ tags, paths, apiSecurity, securityDefinitions, sortFunc }) + : getUINavigationAndServices({ paths, apiSecurity, securityDefinitions }) - // If we have tag information, let's add it to the navigation + // If we have top-level tag descriptions, add it to the navigation if (derefOpenApiV3.tags) { addTagDetailsToNavigation(navigation, derefOpenApiV3.tags) } diff --git a/test/parser/open-api/v3/data/inputs/api-with-examples.false.json b/test/parser/open-api/v3/data/inputs/api-with-examples.false.json new file mode 100644 index 0000000..9a5f2fa --- /dev/null +++ b/test/parser/open-api/v3/data/inputs/api-with-examples.false.json @@ -0,0 +1,159 @@ +{ + "info": { + "title": "Simple API overview", + "version": "v2" + }, + "openapi": "3.0.0", + "paths": { + "/": { + "get": { + "operationId": "listVersionsv2", + "responses": { + "200": { + "content": { + "application/json": { + "examples": [ + { + "versions": [ + { + "id": "v2.0", + "links": [ + { + "href": "http://127.0.0.1:8774/v2/", + "rel": "self" + } + ], + "status": "CURRENT", + "updated": "2011-01-21T11:33:21Z" + }, + { + "id": "v3.0", + "links": [ + { + "href": "http://127.0.0.1:8774/v3/", + "rel": "self" + } + ], + "status": "EXPERIMENTAL", + "updated": "2013-07-23T11:33:21Z" + } + ] + } + ] + } + }, + "description": "200 response" + }, + "300": { + "content": { + "application/json": { + "examples": [ + "{\n \"versions\": [\n {\n \"status\": \"CURRENT\",\n \"updated\": \"2011-01-21T11:33:21Z\",\n \"id\": \"v2.0\",\n \"links\": [\n {\n \"href\": \"http://127.0.0.1:8774/v2/\",\n \"rel\": \"self\"\n }\n ]\n },\n {\n \"status\": \"EXPERIMENTAL\",\n \"updated\": \"2013-07-23T11:33:21Z\",\n \"id\": \"v3.0\",\n \"links\": [\n {\n \"href\": \"http://127.0.0.1:8774/v3/\",\n \"rel\": \"self\"\n }\n ]\n }\n ]\n}\n" + ] + } + }, + "description": "300 response" + } + }, + "summary": "List API versions" + } + }, + "/v2": { + "get": { + "operationId": "getVersionDetailsv2", + "responses": { + "200": { + "content": { + "application/json": { + "examples": [ + { + "version": { + "id": "v2.0", + "links": [ + { + "href": "http://127.0.0.1:8774/v2/", + "rel": "self" + }, + { + "href": "http://docs.openstack.org/api/openstack-compute/2/os-compute-devguide-2.pdf", + "rel": "describedby", + "type": "application/pdf" + }, + { + "href": "http://docs.openstack.org/api/openstack-compute/2/wadl/os-compute-2.wadl", + "rel": "describedby", + "type": "application/vnd.sun.wadl+xml" + }, + { + "href": "http://docs.openstack.org/api/openstack-compute/2/wadl/os-compute-2.wadl", + "rel": "describedby", + "type": "application/vnd.sun.wadl+xml" + } + ], + "media-types": [ + { + "base": "application/xml", + "type": "application/vnd.openstack.compute+xml;version=2" + }, + { + "base": "application/json", + "type": "application/vnd.openstack.compute+json;version=2" + } + ], + "status": "CURRENT", + "updated": "2011-01-21T11:33:21Z" + } + } + ] + } + }, + "description": "200 response" + }, + "203": { + "content": { + "application/json": { + "examples": [ + { + "version": { + "id": "v2.0", + "links": [ + { + "href": "http://23.253.228.211:8774/v2/", + "rel": "self" + }, + { + "href": "http://docs.openstack.org/api/openstack-compute/2/os-compute-devguide-2.pdf", + "rel": "describedby", + "type": "application/pdf" + }, + { + "href": "http://docs.openstack.org/api/openstack-compute/2/wadl/os-compute-2.wadl", + "rel": "describedby", + "type": "application/vnd.sun.wadl+xml" + } + ], + "media-types": [ + { + "base": "application/xml", + "type": "application/vnd.openstack.compute+xml;version=2" + }, + { + "base": "application/json", + "type": "application/vnd.openstack.compute+json;version=2" + } + ], + "status": "CURRENT", + "updated": "2011-01-21T11:33:21Z" + } + } + ] + } + }, + "description": "203 response" + } + }, + "summary": "Show API version details" + } + } + } +} diff --git a/test/parser/open-api/v3/data/outputs/api-with-examples.false.json b/test/parser/open-api/v3/data/outputs/api-with-examples.false.json new file mode 100644 index 0000000..e736c94 --- /dev/null +++ b/test/parser/open-api/v3/data/outputs/api-with-examples.false.json @@ -0,0 +1,62 @@ +{ + "title": "Simple API overview", + "version": "v2", + "info": {}, + "navigation": [ + { + "type": "get", + "title": "List API versions", + "link": "//get" + }, + { + "type": "get", + "title": "Show API version details", + "link": "/v2/get" + } + ], + "services": [ + { + "title": "List API versions", + "methods": [ + { + "type": "get", + "title": "List API versions", + "link": "//get", + "request": {}, + "responses": [ + { + "code": "200", + "description": "200 response" + }, + { + "code": "300", + "description": "300 response" + } + ] + } + ] + }, + { + "title": "Show API version details", + "methods": [ + { + "type": "get", + "title": "Show API version details", + "link": "/v2/get", + "request": {}, + "responses": [ + { + "code": "200", + "description": "200 response" + }, + { + "code": "203", + "description": "203 response" + } + ] + } + ] + } + ], + "security": {} +} diff --git a/yarn.lock b/yarn.lock index 5e9e7bd..6f9442f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -106,10 +106,6 @@ ansi-escapes@^1.1.0, ansi-escapes@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" -ansi-escapes@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" - ansi-html@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" @@ -2121,13 +2117,13 @@ eslint-module-utils@^2.0.0: debug "2.2.0" pkg-dir "^1.0.0" -eslint-plugin-import@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.3.0.tgz#37c801e0ada0e296cbdf20c3f393acb5b52af36b" +eslint-plugin-import@^2.6.0: + version "2.6.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-import/-/eslint-plugin-import-2.6.0.tgz#2a4bbad36a078e052a3c830ce3dfbd6b8a12c6e5" dependencies: builtin-modules "^1.1.1" contains-path "^0.1.0" - debug "^2.2.0" + debug "^2.6.8" doctrine "1.5.0" eslint-import-resolver-node "^0.2.0" eslint-module-utils "^2.0.0" @@ -2136,9 +2132,9 @@ eslint-plugin-import@^2.3.0: minimatch "^3.0.3" read-pkg-up "^2.0.0" -eslint-plugin-node@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-5.0.0.tgz#948b1fb82e3f0a744e86fad19aa4f49537d246cc" +eslint-plugin-node@^5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-node/-/eslint-plugin-node-5.1.0.tgz#bc8cdb85180d0b4d946a2531640e2a4dd7a4e6d4" dependencies: ignore "^3.3.3" minimatch "^3.0.4" @@ -2168,9 +2164,9 @@ eslint-scope@^3.7.1: esrecurse "^4.1.0" estraverse "^4.1.1" -eslint@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.0.0.tgz#7277c01437fdf41dccd168d5aa0e49b75ca1f260" +eslint@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/eslint/-/eslint-4.1.1.tgz#facbdfcfe3e0facd3a8b80dc98c4e6c13ae582df" dependencies: babel-code-frame "^6.22.0" chalk "^1.1.3" @@ -2194,6 +2190,7 @@ eslint@^4.0.0: json-stable-stringify "^1.0.1" levn "^0.3.0" lodash "^4.17.4" + minimatch "^3.0.2" mkdirp "^0.5.1" natural-compare "^1.4.0" optionator "^0.8.2" @@ -2328,7 +2325,7 @@ extend@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" -external-editor@^2.0.1, external-editor@^2.0.4: +external-editor@^2.0.1: version "2.0.4" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.4.tgz#1ed9199da9cbfe2ef2f7a31b2fde8b0d12368972" dependencies: @@ -2958,7 +2955,7 @@ ini@~1.3.0: version "1.3.4" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" -inquirer@3.0.6: +inquirer@3.0.6, inquirer@^3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347" dependencies: @@ -2976,25 +2973,6 @@ inquirer@3.0.6: strip-ansi "^3.0.0" through "^2.3.6" -inquirer@^3.0.6: - version "3.1.1" - resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.1.1.tgz#87621c4fba4072f48a8dd71c9f9df6f100b2d534" - dependencies: - ansi-escapes "^2.0.0" - chalk "^1.0.0" - cli-cursor "^2.1.0" - cli-width "^2.0.0" - external-editor "^2.0.4" - figures "^2.0.0" - lodash "^4.3.0" - mute-stream "0.0.7" - run-async "^2.2.0" - rx-lite "^4.0.8" - rx-lite-aggregates "^4.0.8" - string-width "^2.0.0" - strip-ansi "^3.0.0" - through "^2.3.6" - internal-ip@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-1.2.0.tgz#ae9fbf93b984878785d50a8de1b356956058cf5c" @@ -5236,16 +5214,6 @@ run-async@^2.2.0: dependencies: is-promise "^2.1.0" -rx-lite-aggregates@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" - dependencies: - rx-lite "*" - -rx-lite@*, rx-lite@^4.0.8: - version "4.0.8" - resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" - rx@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" From 4ec9eb7ce9dbcf650e5a947287a9556f3d3b76e6 Mon Sep 17 00:00:00 2001 From: Brendan Abbott Date: Tue, 27 Jun 2017 16:51:17 +1000 Subject: [PATCH 2/2] Update yarn.lock file --- yarn.lock | 175 ++++++++++++++++++++++++++++++++++++------------------ 1 file changed, 117 insertions(+), 58 deletions(-) diff --git a/yarn.lock b/yarn.lock index 6f9442f..ce1583a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -106,6 +106,10 @@ ansi-escapes@^1.1.0, ansi-escapes@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-1.4.0.tgz#d3a8a83b319aa67793662b13e761c7911422306e" +ansi-escapes@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/ansi-escapes/-/ansi-escapes-2.0.0.tgz#5bae52be424878dd9783e8910e3fc2922e83c81b" + ansi-html@0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" @@ -114,6 +118,10 @@ ansi-regex@^2.0.0, ansi-regex@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" +ansi-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998" + ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" @@ -260,8 +268,8 @@ async@^1.4.0, async@^1.5.2: resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" async@^2.1.2, async@^2.1.4: - version "2.4.1" - resolved "https://registry.yarnpkg.com/async/-/async-2.4.1.tgz#62a56b279c98a11d0987096a01cc3eeb8eb7bbd7" + version "2.5.0" + resolved "https://registry.yarnpkg.com/async/-/async-2.5.0.tgz#843190fd6b7357a0b9e1c956edddd5ec8462b54d" dependencies: lodash "^4.14.0" @@ -477,8 +485,8 @@ babel-jest@^20.0.3: babel-preset-jest "^20.0.3" babel-loader@^7.0.0: - version "7.1.0" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.0.tgz#3fbf2581f085774bd9642dca9990e6d6c1491144" + version "7.1.1" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-7.1.1.tgz#b87134c8b12e3e4c2a94e0546085bc680a2b8488" dependencies: find-cache-dir "^1.0.0" loader-utils "^1.0.2" @@ -990,7 +998,7 @@ babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.23.0, babel-types@^6.24 lodash "^4.2.0" to-fast-properties "^1.0.1" -babylon@^6.13.0, babylon@^6.17.0, babylon@^6.17.2: +babylon@^6.17.0, babylon@^6.17.2, babylon@^6.17.4: version "6.17.4" resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.17.4.tgz#3e8b7402b88d22c3423e137a1577883b15ff869a" @@ -1277,12 +1285,12 @@ caniuse-api@^1.5.2: lodash.uniq "^4.5.0" caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: - version "1.0.30000693" - resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000693.tgz#8510e7a9ab04adcca23a5dcefa34df9d28c1ce20" + version "1.0.30000696" + resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000696.tgz#e71f5c61e1f96c7a3af4e791ac5db55e11737604" caniuse-lite@^1.0.30000684: - version "1.0.30000693" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000693.tgz#c9c6298697c71fdf6cb13eefe8aa93926f2f8613" + version "1.0.30000696" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000696.tgz#30f2695d2a01a0dfd779a26ab83f4d134b3da5cc" cartesian-product@^2.1.2: version "2.1.2" @@ -1454,12 +1462,18 @@ combined-stream@^1.0.5, combined-stream@~1.0.5: dependencies: delayed-stream "~1.0.0" -commander@2.9.x, commander@^2.7.1, commander@^2.9.0, commander@~2.9.0: +commander@2.9.x, commander@~2.9.0: version "2.9.0" resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" dependencies: graceful-readlink ">= 1.0.0" +commander@^2.7.1, commander@^2.9.0: + version "2.10.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.10.0.tgz#e1f5d3245de246d1a5ca04702fa1ad1bd7e405fe" + dependencies: + graceful-readlink ">= 1.0.0" + commondir@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" @@ -2111,10 +2125,10 @@ eslint-import-resolver-node@^0.2.0: resolve "^1.1.6" eslint-module-utils@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.0.0.tgz#a6f8c21d901358759cdc35dbac1982ae1ee58bce" + version "2.1.1" + resolved "https://registry.yarnpkg.com/eslint-module-utils/-/eslint-module-utils-2.1.1.tgz#abaec824177613b8a95b299639e1b6facf473449" dependencies: - debug "2.2.0" + debug "^2.6.8" pkg-dir "^1.0.0" eslint-plugin-import@^2.6.0: @@ -2325,7 +2339,7 @@ extend@~3.0.0: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" -external-editor@^2.0.1: +external-editor@^2.0.1, external-editor@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.0.4.tgz#1ed9199da9cbfe2ef2f7a31b2fde8b0d12368972" dependencies: @@ -2716,6 +2730,10 @@ has-flag@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" +has-flag@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-2.0.0.tgz#e8207af1cc7b30d446cc70b734b5e8be18f88d51" + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -2733,8 +2751,8 @@ hash-base@^2.0.0: inherits "^2.0.1" hash.js@^1.0.0, hash.js@^1.0.3: - version "1.1.1" - resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.1.tgz#5cb2e796499224e69fd0b00ed01d2d4a16e7a323" + version "1.1.2" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.2.tgz#bf5c887825cfe40b9efde7bf11bd2db26e6bf01b" dependencies: inherits "^2.0.3" minimalistic-assert "^1.0.0" @@ -2786,8 +2804,8 @@ home-or-tmp@^2.0.0: os-tmpdir "^1.0.1" hosted-git-info@^2.1.4: - version "2.4.2" - resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.4.2.tgz#0076b9f46a270506ddbaaea56496897460612a67" + version "2.5.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.5.0.tgz#6d60e34b3abbc8313062c3b798ef8d901a07af3c" hpack.js@^2.1.6: version "2.1.6" @@ -2826,8 +2844,8 @@ html-minifier@^3.2.3: uglify-js "3.0.x" html-webpack-plugin@^2.28.0: - version "2.28.0" - resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-2.28.0.tgz#2e7863b57e5fd48fe263303e2ffc934c3064d009" + version "2.29.0" + resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-2.29.0.tgz#e987f421853d3b6938c8c4c8171842e5fd17af23" dependencies: bluebird "^3.4.7" html-minifier "^3.2.3" @@ -2955,7 +2973,7 @@ ini@~1.3.0: version "1.3.4" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" -inquirer@3.0.6, inquirer@^3.0.6: +inquirer@3.0.6: version "3.0.6" resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.0.6.tgz#e04aaa9d05b7a3cb9b0f407d04375f0447190347" dependencies: @@ -2973,6 +2991,25 @@ inquirer@3.0.6, inquirer@^3.0.6: strip-ansi "^3.0.0" through "^2.3.6" +inquirer@^3.0.6: + version "3.1.1" + resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-3.1.1.tgz#87621c4fba4072f48a8dd71c9f9df6f100b2d534" + dependencies: + ansi-escapes "^2.0.0" + chalk "^1.0.0" + cli-cursor "^2.1.0" + cli-width "^2.0.0" + external-editor "^2.0.4" + figures "^2.0.0" + lodash "^4.3.0" + mute-stream "0.0.7" + run-async "^2.2.0" + rx-lite "^4.0.8" + rx-lite-aggregates "^4.0.8" + string-width "^2.0.0" + strip-ansi "^3.0.0" + through "^2.3.6" + internal-ip@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/internal-ip/-/internal-ip-1.2.0.tgz#ae9fbf93b984878785d50a8de1b356956058cf5c" @@ -3204,14 +3241,14 @@ isstream@~0.1.2: resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" istanbul-api@^1.1.1: - version "1.1.9" - resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.1.9.tgz#2827920d380d4286d857d57a2968a841db8a7ec8" + version "1.1.10" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.1.10.tgz#f27e5e7125c8de13f6a80661af78f512e5439b2b" dependencies: async "^2.1.4" fileset "^2.0.2" istanbul-lib-coverage "^1.1.1" istanbul-lib-hook "^1.0.7" - istanbul-lib-instrument "^1.7.2" + istanbul-lib-instrument "^1.7.3" istanbul-lib-report "^1.1.1" istanbul-lib-source-maps "^1.2.1" istanbul-reports "^1.1.1" @@ -3229,15 +3266,15 @@ istanbul-lib-hook@^1.0.7: dependencies: append-transform "^0.4.0" -istanbul-lib-instrument@^1.4.2, istanbul-lib-instrument@^1.7.2: - version "1.7.2" - resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.2.tgz#6014b03d3470fb77638d5802508c255c06312e56" +istanbul-lib-instrument@^1.4.2, istanbul-lib-instrument@^1.7.2, istanbul-lib-instrument@^1.7.3: + version "1.7.3" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.7.3.tgz#925b239163eabdd68cc4048f52c2fa4f899ecfa7" dependencies: babel-generator "^6.18.0" babel-template "^6.16.0" babel-traverse "^6.18.0" babel-types "^6.18.0" - babylon "^6.13.0" + babylon "^6.17.4" istanbul-lib-coverage "^1.1.1" semver "^5.3.0" @@ -3555,8 +3592,8 @@ json-schema-ref-parser@^3.1.2: z-schema "^3.17.0" json-schema-traverse@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.0.tgz#0016c0b1ca1efe46d44d37541bcdfc19dcfae0db" + version "0.3.1" + resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340" json-schema@0.2.3: version "0.2.3" @@ -3927,7 +3964,11 @@ miller-rabin@^4.0.0: bn.js "^4.0.0" brorand "^1.0.1" -"mime-db@>= 1.27.0 < 2", mime-db@~1.27.0: +"mime-db@>= 1.27.0 < 2": + version "1.28.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.28.0.tgz#fedd349be06d2865b7fc57d837c6de4f17d7ac3c" + +mime-db@~1.27.0: version "1.27.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.27.0.tgz#820f572296bbd20ec25ed55e5b5de869e5436eb1" @@ -4108,8 +4149,8 @@ nopt@^4.0.1: osenv "^0.1.4" normalize-package-data@^2.3.2, normalize-package-data@^2.3.4: - version "2.3.8" - resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.8.tgz#d819eda2a9dedbd1ffa563ea4071d936782295bb" + version "2.4.0" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.4.0.tgz#12f95a307d58352075a04907b84ac8be98ac012f" dependencies: hosted-git-info "^2.1.4" is-builtin-module "^1.0.0" @@ -4136,8 +4177,8 @@ normalize-url@^1.4.0: sort-keys "^1.0.0" npmlog@^4.0.2: - version "4.1.0" - resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.0.tgz#dc59bee85f64f00ed424efb2af0783df25d1c0b5" + version "4.1.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.1.2.tgz#08a7f2a8bf734604779a9efa4ad5cc717abb954b" dependencies: are-we-there-yet "~1.1.2" console-control-strings "~1.1.0" @@ -4702,12 +4743,12 @@ postcss@^5.0.10, postcss@^5.0.11, postcss@^5.0.12, postcss@^5.0.13, postcss@^5.0 supports-color "^3.2.3" postcss@^6.0.1: - version "6.0.2" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.2.tgz#5c4fea589f0ac3b00caa75b1cbc3a284195b7e5d" + version "6.0.3" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-6.0.3.tgz#b7f565b3d956fbb8565ca7c1e239d0506e427d8b" dependencies: chalk "^1.1.3" source-map "^0.5.6" - supports-color "^3.2.3" + supports-color "^4.0.0" prelude-ls@~1.1.2: version "1.1.2" @@ -4908,8 +4949,8 @@ react-dom@^15.5.4: prop-types "^15.5.10" react-json-view@^1.8.4: - version "1.9.5" - resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.9.5.tgz#ef6994489ff30f3ae4f4bd14010c92dd5230e6f4" + version "1.10.2" + resolved "https://registry.yarnpkg.com/react-json-view/-/react-json-view-1.10.2.tgz#6da81133a8bfdb7edb11dc3f9590b311460836fb" react-jss@^6.1.1: version "6.1.1" @@ -4990,8 +5031,8 @@ readable-stream@1.0: string_decoder "~0.10.x" readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.4, readable-stream@^2.2.2, readable-stream@^2.2.6, readable-stream@^2.2.9: - version "2.3.1" - resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.1.tgz#84e26965bb9e785535ed256e8d38e92c69f09d10" + version "2.3.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.2.tgz#5a04df05e4f57fe3f0dc68fdd11dc5c97c7e6f4d" dependencies: core-util-is "~1.0.0" inherits "~2.0.3" @@ -5214,6 +5255,16 @@ run-async@^2.2.0: dependencies: is-promise "^2.1.0" +rx-lite-aggregates@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite-aggregates/-/rx-lite-aggregates-4.0.8.tgz#753b87a89a11c95467c4ac1626c4efc4e05c67be" + dependencies: + rx-lite "*" + +rx-lite@*, rx-lite@^4.0.8: + version "4.0.8" + resolved "https://registry.yarnpkg.com/rx-lite/-/rx-lite-4.0.8.tgz#0b1e11af8bc44836f04a6407e92da42467b79444" + rx@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/rx/-/rx-4.1.0.tgz#a5f13ff79ef3b740fe30aa803fb09f98805d4782" @@ -5222,10 +5273,6 @@ safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@~5.1.0: version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" -safe-buffer@~5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" - sane@~1.6.0: version "1.6.0" resolved "https://registry.yarnpkg.com/sane/-/sane-1.6.0.tgz#9610c452307a135d29c1fdfe2547034180c46775" @@ -5239,8 +5286,8 @@ sane@~1.6.0: watch "~0.10.0" sax@^1.2.1, sax@~1.2.1: - version "1.2.2" - resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.2.tgz#fd8631a23bc7826bef5d871bdb87378c95647828" + version "1.2.4" + resolved "https://registry.yarnpkg.com/sax/-/sax-1.2.4.tgz#2816234e2378bddc4e5354fab5caa895df7100d9" schema-utils@^0.3.0: version "0.3.0" @@ -5568,21 +5615,21 @@ string-width@^1.0.1, string-width@^1.0.2: strip-ansi "^3.0.0" string-width@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.0.0.tgz#635c5436cc72a6e0c387ceca278d4e2eec52687e" + version "2.1.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.0.tgz#030664561fc146c9423ec7d978fe2457437fe6d0" dependencies: is-fullwidth-code-point "^2.0.0" - strip-ansi "^3.0.0" + strip-ansi "^4.0.0" string_decoder@^0.10.25, string_decoder@~0.10.x: version "0.10.31" resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" string_decoder@~1.0.0: - version "1.0.2" - resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.2.tgz#b29e1f4e1125fa97a10382b8a533737b7491e179" + version "1.0.3" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab" dependencies: - safe-buffer "~5.0.1" + safe-buffer "~5.1.0" stringstream@~0.0.4: version "0.0.5" @@ -5594,6 +5641,12 @@ strip-ansi@3.0.1, strip-ansi@^3.0.0, strip-ansi@^3.0.1: dependencies: ansi-regex "^2.0.0" +strip-ansi@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f" + dependencies: + ansi-regex "^3.0.0" + strip-bom@3.0.0, strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -5631,6 +5684,12 @@ supports-color@^3.1.0, supports-color@^3.1.1, supports-color@^3.1.2, supports-co dependencies: has-flag "^1.0.0" +supports-color@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-4.0.0.tgz#33a7c680aa512c9d03ef929cacbb974d203d2790" + dependencies: + has-flag "^2.0.0" + svg2ttf@^2.0.0: version "2.1.1" resolved "https://registry.yarnpkg.com/svg2ttf/-/svg2ttf-2.1.1.tgz#103d3a236f6596c47a2490ec22b67c051ee4692e" @@ -5831,16 +5890,16 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" ua-parser-js@^0.7.9: - version "0.7.12" - resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.12.tgz#04c81a99bdd5dc52263ea29d24c6bf8d4818a4bb" + version "0.7.13" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.13.tgz#cd9dd2f86493b3f44dbeeef3780fda74c5ee14be" uc.micro@^1.0.1, uc.micro@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192" uglify-js@3.0.x: - version "3.0.19" - resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.0.19.tgz#ab1dfe2a171361b81fa9ffb3383461ea384557ed" + version "3.0.20" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.0.20.tgz#cb35b2bcfe478051b6f3282be8db4e4add49a1e5" dependencies: commander "~2.9.0" source-map "~0.5.1"