From 7d7bfd09c1bdbe753899265ef15212b0e4682c32 Mon Sep 17 00:00:00 2001 From: Pascal Mugnier Date: Wed, 19 Sep 2018 14:03:27 +0200 Subject: [PATCH] MMF-1420 Ease management of Embedded Docs navigation (#699) --- server/sonar-docs/README.md | 55 +- server/sonar-docs/gatsby-node.js | 20 +- server/sonar-docs/package.json | 18 +- .../sonar-docs/src/EmbedDocsSuggestions.json | 58 +- .../src/__tests__/BrokenLinkSafetyNet.test.js | 178 +++ .../src/layouts/components/CategoryLink.js | 84 +- .../src/layouts/components/ExternalLink.js | 34 + .../src/layouts/components/Footer.js | 8 +- .../src/layouts/components/HeadingAnchor.js | 35 + .../src/layouts/components/HeadingsLink.js | 30 +- .../src/layouts/components/Search.js | 25 +- .../layouts/components/SearchEntryResult.js | 2 +- .../src/layouts/components/Sidebar.js | 101 +- .../layouts/components/icons/DetachIcon.js | 32 + server/sonar-docs/src/layouts/index.js | 11 +- server/sonar-docs/src/layouts/utils.js | 30 +- server/sonar-docs/src/pages/404.md | 8 + .../src/pages/analysis/background-tasks.md | 1 + .../{generic_issue.md => generic-issue.md} | 4 +- .../{generic_test.md => generic-test.md} | 1 + .../pages/analysis/{index.md => overview.md} | 3 +- .../src/pages/analysis/pull-request.md | 3 +- ...{scm_integration.md => scm-integration.md} | 3 +- .../src/pages/branches/branches-faq.md | 38 +- .../src/pages/branches/long-lived-branches.md | 1 + .../pages/branches/{index.md => overview.md} | 13 +- .../pages/branches/short-lived-branches.md | 1 + server/sonar-docs/src/pages/index.md | 15 +- .../custom-measures.md | 2 +- .../housekeeping.md | 1 + .../look-and-feel.md | 2 +- .../quality-profiles.md | 1 + .../src/pages/integrations/index.md | 10 - .../{ => project-administration}/webhooks.md | 1 + .../{ => sonarcloud}/analyze-a-project.md | 12 +- .../integrations/bitbucketcloud.md | 2 +- .../{ => sonarcloud}/integrations/github.md | 2 +- .../{ => sonarcloud}/integrations/vsts.md | 2 +- .../{ => sonarcloud}/organizations/index.md | 8 +- .../organizations/manage-team.md | 2 +- .../organizations/organization-visibility.md | 2 +- .../src/pages/{ => sonarcloud}/privacy.md | 2 +- .../src/pages/{ => sonarcloud}/security.md | 2 +- .../{ => sonarcloud}/sonarcloud-pricing.md | 2 +- .../{ => user-guide}/fixing-the-water-leak.md | 7 +- .../{ => user-guide}/keyboard-shortcuts.md | 2 +- .../{ => user-guide}/metric-definitions.md | 1 + .../pages/{ => user-guide}/quality-gates.md | 3 +- .../{ => user-guide}/security-reports.md | 1 + .../pages/{ => user-guide}/user-account.md | 7 +- server/sonar-docs/src/templates/page.js | 13 +- server/sonar-docs/static/README.md | 24 + .../static/SonarCloudNavigationTree.json | 53 + .../static/SonarQubeNavigationTree.json | 46 + .../static/StaticNavigationTree.json | 54 + server/sonar-docs/yarn.lock | 1352 ++++++++++++++++- .../js/apps/documentation/components/App.tsx | 14 +- .../js/apps/documentation/components/Menu.tsx | 98 +- .../documentation/components/MenuBlock.tsx | 58 + .../components/MenuExternalLink.tsx | 37 + .../documentation/components/MenuItem.tsx | 46 + .../components/SearchResultEntry.tsx | 2 +- .../components/SearchResults.tsx | 7 +- .../apps/documentation/components/Sidebar.tsx | 10 +- .../components/__tests__/Menu-test.tsx | 12 +- .../components/__tests__/MenuBlock-test.tsx | 74 + .../__tests__/SearchResultEntry-test.tsx | 2 +- .../__tests__/SearchResults-test.tsx | 11 +- .../components/__tests__/Sidebar-test.tsx | 20 +- .../__snapshots__/Menu-test.tsx.snap | 110 +- .../__snapshots__/MenuBlock-test.tsx.snap | 69 + .../SearchResultEntry-test.tsx.snap | 4 +- .../__snapshots__/SearchResults-test.tsx.snap | 4 +- .../__snapshots__/Sidebar-test.tsx.snap | 30 +- .../components/__tests__/pages-test.ts | 86 -- .../src/main/js/apps/documentation/pages.ts | 7 +- .../src/main/js/apps/documentation/utils.ts | 55 +- .../docs/__tests__/DocMarkdownBlock-test.tsx | 5 +- .../sonar-web/src/main/js/helpers/markdown.js | 5 +- 79 files changed, 2632 insertions(+), 562 deletions(-) create mode 100644 server/sonar-docs/src/__tests__/BrokenLinkSafetyNet.test.js create mode 100644 server/sonar-docs/src/layouts/components/ExternalLink.js create mode 100644 server/sonar-docs/src/layouts/components/HeadingAnchor.js create mode 100644 server/sonar-docs/src/layouts/components/icons/DetachIcon.js create mode 100644 server/sonar-docs/src/pages/404.md rename server/sonar-docs/src/pages/analysis/{generic_issue.md => generic-issue.md} (97%) rename server/sonar-docs/src/pages/analysis/{generic_test.md => generic-test.md} (99%) rename server/sonar-docs/src/pages/analysis/{index.md => overview.md} (99%) rename server/sonar-docs/src/pages/analysis/{scm_integration.md => scm-integration.md} (75%) rename server/sonar-docs/src/pages/branches/{index.md => overview.md} (94%) rename server/sonar-docs/src/pages/{ => instance-administration}/custom-measures.md (96%) rename server/sonar-docs/src/pages/{ => instance-administration}/housekeeping.md (97%) rename server/sonar-docs/src/pages/{ => instance-administration}/look-and-feel.md (94%) rename server/sonar-docs/src/pages/{ => instance-administration}/quality-profiles.md (99%) delete mode 100644 server/sonar-docs/src/pages/integrations/index.md rename server/sonar-docs/src/pages/{ => project-administration}/webhooks.md (99%) rename server/sonar-docs/src/pages/{ => sonarcloud}/analyze-a-project.md (74%) rename server/sonar-docs/src/pages/{ => sonarcloud}/integrations/bitbucketcloud.md (99%) rename server/sonar-docs/src/pages/{ => sonarcloud}/integrations/github.md (98%) rename server/sonar-docs/src/pages/{ => sonarcloud}/integrations/vsts.md (98%) rename server/sonar-docs/src/pages/{ => sonarcloud}/organizations/index.md (75%) rename server/sonar-docs/src/pages/{ => sonarcloud}/organizations/manage-team.md (97%) rename server/sonar-docs/src/pages/{ => sonarcloud}/organizations/organization-visibility.md (96%) rename server/sonar-docs/src/pages/{ => sonarcloud}/privacy.md (99%) rename server/sonar-docs/src/pages/{ => sonarcloud}/security.md (99%) rename server/sonar-docs/src/pages/{ => sonarcloud}/sonarcloud-pricing.md (99%) rename server/sonar-docs/src/pages/{ => user-guide}/fixing-the-water-leak.md (87%) rename server/sonar-docs/src/pages/{ => user-guide}/keyboard-shortcuts.md (98%) rename server/sonar-docs/src/pages/{ => user-guide}/metric-definitions.md (99%) rename server/sonar-docs/src/pages/{ => user-guide}/quality-gates.md (94%) rename server/sonar-docs/src/pages/{ => user-guide}/security-reports.md (99%) rename server/sonar-docs/src/pages/{ => user-guide}/user-account.md (59%) create mode 100644 server/sonar-docs/static/README.md create mode 100644 server/sonar-docs/static/SonarCloudNavigationTree.json create mode 100644 server/sonar-docs/static/SonarQubeNavigationTree.json create mode 100644 server/sonar-docs/static/StaticNavigationTree.json create mode 100644 server/sonar-web/src/main/js/apps/documentation/components/MenuBlock.tsx create mode 100644 server/sonar-web/src/main/js/apps/documentation/components/MenuExternalLink.tsx create mode 100644 server/sonar-web/src/main/js/apps/documentation/components/MenuItem.tsx create mode 100644 server/sonar-web/src/main/js/apps/documentation/components/__tests__/MenuBlock-test.tsx create mode 100644 server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/MenuBlock-test.tsx.snap delete mode 100644 server/sonar-web/src/main/js/apps/documentation/components/__tests__/pages-test.ts diff --git a/server/sonar-docs/README.md b/server/sonar-docs/README.md index 05af399cff8..aca7bd3b15d 100644 --- a/server/sonar-docs/README.md +++ b/server/sonar-docs/README.md @@ -62,30 +62,56 @@ cd sonar-enterprise/server/sonar-docs yarn develop ``` +## Testing +As documentation writers there are two ways it is possible for us to break the SonarQube build +* malformed markup +* broken links + +Even without spinning up servers, you can double-check that your changes won't break the build. +**Test everything** +You can run all the tests, and make sure that both your markup is well-formed and your links are correct by running the build script: +``` +cd sonar-enterprise/ +./build.sh -x test -x obfuscate +``` +**Test links only** +If you only want to double-check your links changes, you can +``` +cd sonar-enterprise/server/sonar-docs +yarn jest +``` + +This will run the broken link test and stop at the first broken link it finds. Continue running this iteratively until it passes. + +## Navigation trees +Controlling the navigation trees of the tree instances is covered in [static/README.md](static) + + ## Writing docs +### URLs +All urls _must_ end with a trailing slash (`/`). + ### Header Each documentation file should contain a header at the top of the file delimited by "---" top and bottom. The header holds file metadata: * The `title` tag defines the title of the page for the index -* The `order` tag defines the order of the page for the index. (Floats are interpreted correctly) -* The `scope` tag defines to which product the doc applies. Omit `scope` to have a file show up everywhere: - * “sonarqube” - visible only for SonarQube and the static website - * “sonarcloud” - visible only for SonarCloud - * "static" - visible only on the static website +* The `url` tag is required and defines the path at which to publish the page. Reminder: end this with a trailing slash. Ex.: ``` --- title: Demo page -order: 0 -scope: static +url: /sonarcloud-pricing --- ``` -Metadata tags can appear in any order, but by convention, `title` should come first. +** Metadata conventions** +* Metadata tags can appear in any order, but by convention, `title` should come first. +* The `url` tag is optional, but by convention, should be specified to both make the publish path explicit and avoid problems potentially caused by moving or renaming files. + ### Includes @@ -98,15 +124,12 @@ Basic syntax: `@include tooltips/quality-gates/quality-gate` With special comments you can mark a page or a part of the content to be displayed only on SonarCloud, SonarQube or the static documentation website. -To display a page only in a certain context use the frontmatter option: - -```md ---- -scope: sonarcloud (or sonarqube, or static) ---- +To drop in "SonarQube" or "SonarCloud" as appropriate, use: +``` +{instance} ``` -To display/hide a part of the content use special comments: +To display/hide some other part of the content, use special comments: ```md @@ -128,7 +151,7 @@ this content is displayed only in the static website ``` -You can also use inline comments: +You can also use these comments inline: ```md this content is displayed on SonarCloudSonarQube diff --git a/server/sonar-docs/gatsby-node.js b/server/sonar-docs/gatsby-node.js index 0c39ec3c7ba..4564fe52491 100644 --- a/server/sonar-docs/gatsby-node.js +++ b/server/sonar-docs/gatsby-node.js @@ -42,7 +42,7 @@ exports.createPages = ({ graphql, boundActionCreators }) => { edges { node { frontmatter { - scope + url } headings { depth @@ -57,16 +57,14 @@ exports.createPages = ({ graphql, boundActionCreators }) => { } `).then(result => { result.data.allMarkdownRemark.edges.forEach(({ node }) => { - if (node.frontmatter.scope !== 'sonarcloud') { - createPage({ - path: node.fields.slug, - component: path.resolve('./src/templates/page.js'), - context: { - // Data passed to context is available in page queries as GraphQL variables. - slug: node.fields.slug - } - }); - } + createPage({ + path: node.frontmatter.url || node.fields.slug, + component: path.resolve('./src/templates/page.js'), + context: { + // Data passed to context is available in page queries as GraphQL variables. + slug: node.fields.slug + } + }); }); resolve(); }); diff --git a/server/sonar-docs/package.json b/server/sonar-docs/package.json index b94d672d5f2..15091a0dc94 100644 --- a/server/sonar-docs/package.json +++ b/server/sonar-docs/package.json @@ -22,17 +22,31 @@ "typography": "^0.16.16" }, "scripts": { - "build": "gatsby build --prefix-paths", + "build": "yarn jest && gatsby build --prefix-paths", "develop": "gatsby develop", "start": "serve public/", "format": "prettier --write 'src/**/*.{md,js}'" }, "devDependencies": { - "prettier": "^1.12.0" + "glob-promise": "3.4.0", + "jest": "23.6.0", + "prettier": "^1.12.0", + "remark": "9.0.0", + "unist-util-visit": "1.4.0" }, "prettier": { "jsxBracketSameLine": true, "printWidth": 100, "singleQuote": true + }, + "jest": { + "moduleFileExtensions": [ + "js" + ], + "testPathIgnorePatterns": [ + "/node_modules", + "/.cache" + ], + "testRegex": "(/__tests__/.*|\\-test)\\.(ts|tsx|js)$" } } diff --git a/server/sonar-docs/src/EmbedDocsSuggestions.json b/server/sonar-docs/src/EmbedDocsSuggestions.json index 996ecb4c49b..45beba34d09 100644 --- a/server/sonar-docs/src/EmbedDocsSuggestions.json +++ b/server/sonar-docs/src/EmbedDocsSuggestions.json @@ -3,152 +3,152 @@ "api_documentation": [], "background_tasks": [ { - "link": "/documentation/analysis/background-tasks", + "link": "/documentation/analysis/background-tasks/", "text": "About Background Tasks" } ], "code": [], "coding_rules": [ { - "link": "/documentation/quality-profiles", + "link": "/documentation/quality-profiles/", "text": "Quality Profiles" }, { - "link": "/documentation/keyboard-shortcuts", + "link": "/documentation/keyboard-shortcuts/", "text": "Keyboard Shortcuts" } ], "component_measures": [ { - "link": "/documentation/fixing-the-water-leak", + "link": "/documentation/fixing-the-water-leak/", "text": "Fixing the Water Leak" }, { - "link":"/documentation/metric-definitions", - "text":"Metric Definitions" + "link": "/documentation/metric-definitions/", + "text": "Metric Definitions" }, { - "link": "/documentation/keyboard-shortcuts", + "link": "/documentation/keyboard-shortcuts/", "text": "Keyboard Shortcuts" } ], "custom_measures": [ { - "link": "/documentation/custom-measures", + "link": "/documentation/custom-measures/", "text": "About Custom Measures" } ], "custom_metrics": [ { - "link": "/documentation/custom-measures", + "link": "/documentation/custom-measures/", "text": "Custom Measures" } ], "extension_billing": [ { - "link": "/documentation/sonarcloud-pricing", + "link": "/documentation/sonarcloud-pricing/", "text": "Pricing", "scope": "sonarcloud" } ], "global_permissions": [ { - "link": "/documentation/organizations/manage-team", + "link": "/documentation/organizations/manage-team/", "text": "Manage a Team", "scope": "sonarcloud" } ], "issues": [ { - "link": "/documentation/keyboard-shortcuts", + "link": "/documentation/keyboard-shortcuts/", "text": "Keyboard Shortcuts" } ], "marketplace": [], "organization_members": [ { - "link": "/documentation/organizations/manage-team", + "link": "/documentation/organizations/manage-team/", "text": "Manage a Team", "scope": "sonarcloud" } ], "organization_projects": [ { - "link": "/documentation/organizations/manage-team", + "link": "/documentation/organizations/manage-team/", "text": "Manage a Team", "scope": "sonarcloud" } ], "organization_space": [ { - "link": "/documentation/organizations/index", + "link": "/documentation/organizations/index/", "text": "Organizations", "scope": "sonarcloud" } ], "overview": [ { - "link": "/documentation/fixing-the-water-leak", + "link": "/documentation/fixing-the-water-leak/", "text": "Fixing the Water Leak" }, { - "link": "/documentation/branches/index", + "link": "/documentation/branches/index/", "text": "Branches Overview" }, { - "link": "/documentation/analysis/pull-request", + "link": "/documentation/analysis/pull-request/", "text": "Analyzing Pull Requests" } ], "permission_templates": [], - "profiles": [ + "profiles": [ { - "link": "/documentation/quality-profiles", + "link": "/documentation/quality-profiles/", "text": "Quality Profiles" } ], "project_activity": [], "project_quality_gate": [ { - "link": "/documentation/fixing-the-water-leak", + "link": "/documentation/fixing-the-water-leak/", "text": "Fixing the Water Leak" } ], "project_quality_profiles": [ { - "link": "/documentation/quality-profiles", + "link": "/documentation/quality-profiles/", "text": "About Quality Profiles" } ], "projects_management": [ { - "link": "/documentation/analyze-a-project", + "link": "/documentation/analyze-a-project/", "text": "Analyze a Project", "scope": "sonarcloud" } ], "projects": [ { - "link": "/documentation/analyze-a-project", + "link": "/documentation/analyze-a-project/", "text": "Analyze a Project", "scope": "sonarcloud" } ], "quality_gates": [ { - "link": "/documentation/fixing-the-water-leak", + "link": "/documentation/fixing-the-water-leak/", "text": "Fixing the Water Leak" } ], "quality_profiles": [ { - "link": "/documentation/quality-profiles", + "link": "/documentation/quality-profiles/", "text": "Quality Profiles" } ], "security_reports": [ { - "link": "/documentation/security-reports", + "link": "/documentation/security-reports/", "text": "About Security Reports" } ], @@ -156,7 +156,7 @@ "system_info": [], "user_groups": [ { - "link": "/documentation/organizations/manage-team", + "link": "/documentation/organizations/manage-team/", "text": "Manage a Team", "scope": "sonarcloud" } @@ -164,7 +164,7 @@ "users": [], "webhooks": [ { - "link": "/documentation/webhooks", + "link": "/documentation/webhooks/", "text": "About Webhooks" } ] diff --git a/server/sonar-docs/src/__tests__/BrokenLinkSafetyNet.test.js b/server/sonar-docs/src/__tests__/BrokenLinkSafetyNet.test.js new file mode 100644 index 00000000000..5eafbfa7178 --- /dev/null +++ b/server/sonar-docs/src/__tests__/BrokenLinkSafetyNet.test.js @@ -0,0 +1,178 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +const remark = require('remark'); +const fs = require('fs'); +const path = require('path'); +const glob = require('glob-promise'); +const visit = require('unist-util-visit'); + +it('should not have any broken link', async () => { + const root = path.resolve(__dirname + '/..'); + const files = await glob(root + '/pages/**/*.md') + .then(files => files.map(file => file.substr(root.length + 1))) + .then(files => + files.map(file => ({ + path: file.slice(0, -3), + content: handleIncludes(fs.readFileSync(root + '/' + file, 'utf8'), root) + })) + ); + + const parsedFiles = files.map(file => { + return { ...separateFrontMatter(file.content), path: file.path }; + }); + + const trees = [ + 'SonarCloudNavigationTree.json', + 'SonarQubeNavigationTree.json', + 'StaticNavigationTree.json' + ]; + trees.forEach(file => { + const tree = JSON.parse(fs.readFileSync(root + '/../static/' + file, 'utf8')); + tree.forEach(leaf => { + if (typeof leaf === 'object') { + if (leaf.children) { + leaf.children.forEach(child => { + // Check children markdown file path validity + const result = urlExists(parsedFiles, child); + if (!result) { + // Display custom error message + console.log('[', child, '] is not a valid link, in ', file); + } + expect(result).toBeTruthy(); + }); + } + } else { + // Check markdown file path validity + const result = urlExists(parsedFiles, leaf); + if (!result) { + console.log('[', leaf, '] is not a valid link, in ', file); + } + expect(result).toBeTruthy(); + } + }); + }); + + // Check if all url tag in frontmatter are valid and uniques + let urlLists = []; + parsedFiles.map(file => { + let result = file.frontmatter.url; + if (!result) { + console.log('[', file.path, '] has no url metadata'); + } + expect(result).toBeTruthy(); + + result = file.frontmatter.url.startsWith('/'); + if (!result) { + console.log('[', file.path, '] should starts with a slash ', file.frontmatter.url); + } + expect(result).toBeTruthy(); + + result = file.frontmatter.url.endsWith('/'); + if (!result) { + console.log('[', file.path, '] should ends with a slash ', file.frontmatter.url); + } + expect(result).toBeTruthy(); + + result = !urlLists.includes(file.frontmatter.url); + if (!result) { + console.log('[', file.path, '] has an url that is not unique ', file.frontmatter.url); + } + expect(result).toBeTruthy(); + + urlLists = [...urlLists, file.frontmatter.url]; + }); + + parsedFiles.map(file => { + const ast = remark().parse(file.content); + visit(ast, node => { + if (node.type === 'image' && !node.url.startsWith('http')) { + // Check image path validity + const result = fs.existsSync(root + '/' + node.url); + if (!result) { + console.log('[', node.url, '] is not a valid image path, in ', file.path + '.md'); + } + expect(result).toBeTruthy(); + } else if ( + node.type === 'link' && + !node.url.startsWith('http') && + !node.url.startsWith('/#') + ) { + // Check markdown file path validity + const result = urlExists(parsedFiles, node.url); + if (!result) { + console.log('[', node.url, '] is not a valid link, in ', file.path + '.md'); + } + expect(result).toBeTruthy(); + } + }); + }); + expect(true).toBeTruthy(); +}); + +function urlExists(files, url) { + return files.find(f => f.frontmatter.url === url) !== undefined; +} + +function handleIncludes(content, root) { + return content.replace(/@include (.+)/, (match, p) => { + const filePath = path.join(root, '..', `${p}.md`); + return fs.readFileSync(filePath, 'utf8'); + }); +} + +function getFrontMatterPosition(lines) { + let firstLine; + let lastLine; + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + if (line.trim() === '---') { + if (firstLine === undefined) { + firstLine = i; + } else { + lastLine = i; + break; + } + } + } + return lastLine !== undefined ? { firstLine, lastLine } : undefined; +} + +function parseFrontMatter(lines) { + const data = {}; + for (let i = 0; i < lines.length; i++) { + const tokens = lines[i].split(':').map(x => x.trim()); + if (tokens.length === 2) { + data[tokens[0]] = tokens[1]; + } + } + return data; +} + +function separateFrontMatter(content) { + const lines = content.split('\n'); + const position = getFrontMatterPosition(lines); + if (position) { + const frontmatter = parseFrontMatter(lines.slice(position.firstLine + 1, position.lastLine)); + const content = lines.slice(position.lastLine + 1).join('\n'); + return { frontmatter, content }; + } else { + return { frontmatter: {}, content }; + } +} diff --git a/server/sonar-docs/src/layouts/components/CategoryLink.js b/server/sonar-docs/src/layouts/components/CategoryLink.js index 2cfc743b1ec..12e51b570ae 100644 --- a/server/sonar-docs/src/layouts/components/CategoryLink.js +++ b/server/sonar-docs/src/layouts/components/CategoryLink.js @@ -21,39 +21,59 @@ import * as React from 'react'; import Link from 'gatsby-link'; import SubpageLink from './SubpageLink'; import HeadingsLink from './HeadingsLink'; -import { sortNodes } from '../utils'; import ChevronDownIcon from './icons/ChevronDownIcon'; import ChevronUpIcon from './icons/ChevronUpIcon'; -export default function CategoryLink({ node, location, headers, onToggle }) { - const hasChild = node.pages && node.pages.length > 0; - const prefix = process.env.GATSBY_USE_PREFIX === '1' ? '/' + process.env.GATSBY_DOCS_VERSION : ''; - const { slug } = node.fields; - const isCurrentPage = location.pathname === prefix + slug; - const open = location.pathname.startsWith(prefix + slug); - return ( -
-

- - {hasChild && open && } - {hasChild && !open && } - {node.frontmatter.title} - -

- {isCurrentPage && } - {hasChild && - open && ( -
- {sortNodes(node.pages).map(page => ( - - ))} -
- )} -
- ); +export default class CategoryLink extends React.PureComponent { + constructor(props) { + super(props); + this.state = { open: props.open }; + } + + toggle = event => { + event.preventDefault(); + event.stopPropagation(); + this.props.onToggle(this.props.title); + }; + + render() { + const { node, location, headers, children, title, open } = this.props; + const prefix = + process.env.GATSBY_USE_PREFIX === '1' ? '/' + process.env.GATSBY_DOCS_VERSION : ''; + const url = node ? node.frontmatter.url || node.fields.slug : ''; + const isCurrentPage = location.pathname === prefix + url; + return ( +
+

+ {node ? ( + + {node.frontmatter.title} + + ) : ( + + {open ? : } + {title} + + )} +

+ {isCurrentPage && } + {children && + open && ( +
+ {children.map(page => { + const url = page.frontmatter.url || page.fields.slug; + return ( + + ); + })} +
+ )} +
+ ); + } } diff --git a/server/sonar-docs/src/layouts/components/ExternalLink.js b/server/sonar-docs/src/layouts/components/ExternalLink.js new file mode 100644 index 00000000000..516f1d05951 --- /dev/null +++ b/server/sonar-docs/src/layouts/components/ExternalLink.js @@ -0,0 +1,34 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import DetachIcon from './icons/DetachIcon'; + +export function ExternalLink({ external, title }) { + return ( +
+

+ + + {title} + +

+
+ ); +} diff --git a/server/sonar-docs/src/layouts/components/Footer.js b/server/sonar-docs/src/layouts/components/Footer.js index e807022e79b..83e72f5c56f 100644 --- a/server/sonar-docs/src/layouts/components/Footer.js +++ b/server/sonar-docs/src/layouts/components/Footer.js @@ -23,10 +23,10 @@ export default function Footer() { return (
+ title="Creative Commons License"> Creative Commons License + target="_blank"> Creative Commons Attribution-NonCommercial 3.0 United States License. {' '} SONARQUBE is a trademark of SonarSource SA. All other trademarks and copyrights are the diff --git a/server/sonar-docs/src/layouts/components/HeadingAnchor.js b/server/sonar-docs/src/layouts/components/HeadingAnchor.js new file mode 100644 index 00000000000..a831007fa0a --- /dev/null +++ b/server/sonar-docs/src/layouts/components/HeadingAnchor.js @@ -0,0 +1,35 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; + +export default function HeadingAnchor(props) { + const onClick = event => { + event.stopPropagation(); + event.preventDefault(); + props.clickHandler(props.index); + }; + return ( +
  • + + {props.value} + +
  • + ); +} diff --git a/server/sonar-docs/src/layouts/components/HeadingsLink.js b/server/sonar-docs/src/layouts/components/HeadingsLink.js index 6abd72ceee3..a012a04a78f 100644 --- a/server/sonar-docs/src/layouts/components/HeadingsLink.js +++ b/server/sonar-docs/src/layouts/components/HeadingsLink.js @@ -18,6 +18,7 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; +import HeadingAnchor from './HeadingAnchor'; export default class HeadingsLink extends React.Component { skipScrollingHandler = false; @@ -51,7 +52,7 @@ export default class HeadingsLink extends React.Component { highlightHeading = scrollTop => { let headingIndex = 0; for (let i = 0; i < this.state.headers.length; i++) { - if (document.querySelector('#header-' + (i + 1)).offsetTop > scrollTop + 40) { + if (document.querySelector('#header-' + (i + 1)).offsetTop > scrollTop + 200) { break; } headingIndex = i; @@ -71,8 +72,8 @@ export default class HeadingsLink extends React.Component { node.classList.add('targetted-heading'); if (scrollTo) { this.skipScrollingHandler = true; - window.scrollTo(0, node.offsetTop - 30); - this.highlightHeading(node.offsetTop - 30); + window.scrollTo(0, node.offsetTop - 200); + this.highlightHeading(node.offsetTop - 200); } } }; @@ -87,12 +88,8 @@ export default class HeadingsLink extends React.Component { this.highlightHeading(scrollTop); }; - clickHandler = target => { - return event => { - event.stopPropagation(); - event.preventDefault(); - this.markH2(target, true); - }; + clickHandler = index => { + this.markH2(index, true); }; render() { @@ -106,14 +103,13 @@ export default class HeadingsLink extends React.Component { diff --git a/server/sonar-docs/src/layouts/components/Search.js b/server/sonar-docs/src/layouts/components/Search.js index 05b31278f4e..1562ff0484e 100644 --- a/server/sonar-docs/src/layouts/components/Search.js +++ b/server/sonar-docs/src/layouts/components/Search.js @@ -18,8 +18,9 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import React, { Component } from 'react'; -import lunr, { LunrIndex } from 'lunr'; +import lunr from 'lunr'; import ClearIcon from './icons/ClearIcon'; +import { getUrlsList } from '../utils'; // Search component export default class Search extends Component { @@ -36,13 +37,17 @@ export default class Search extends Component { this.metadataWhitelist = ['position']; - props.pages.forEach(page => - this.add({ - id: page.id, - title: page.frontmatter.title, - text: page.html.replace(/<(?:.|\n)*?>/gm, '').replace(/<(?:.|\n)*?>/gm, '') - }) - ); + props.pages + .filter(page => + getUrlsList(props.navigation).includes(page.frontmatter.url || page.fields.slug) + ) + .forEach(page => + this.add({ + id: page.id, + text: page.html.replace(/<(?:.|\n)*?>/gm, '').replace(/<(?:.|\n)*?>/gm, ''), + title: page.frontmatter.title + }) + ); }); } @@ -67,9 +72,9 @@ export default class Search extends Component { return { page: { id: page.id, - slug: page.fields.slug, + text: page.html.replace(/<(?:.|\n)*?>/gm, '').replace(/<(?:.|\n)*?>/gm, ''), title: page.frontmatter.title, - text: page.html.replace(/<(?:.|\n)*?>/gm, '').replace(/<(?:.|\n)*?>/gm, '') + url: page.frontmatter.url || page.fields.slug }, highlights, longestTerm diff --git a/server/sonar-docs/src/layouts/components/SearchEntryResult.js b/server/sonar-docs/src/layouts/components/SearchEntryResult.js index bfd0daba0ca..c1456691674 100644 --- a/server/sonar-docs/src/layouts/components/SearchEntryResult.js +++ b/server/sonar-docs/src/layouts/components/SearchEntryResult.js @@ -23,7 +23,7 @@ import { highlightMarks, cutWords } from '../utils'; export default function SearchResultEntry({ active, result }) { return ( - + diff --git a/server/sonar-docs/src/layouts/components/Sidebar.js b/server/sonar-docs/src/layouts/components/Sidebar.js index a9cf8668d29..e6a7fa1408e 100644 --- a/server/sonar-docs/src/layouts/components/Sidebar.js +++ b/server/sonar-docs/src/layouts/components/Sidebar.js @@ -19,20 +19,46 @@ */ import React from 'react'; import Link from 'gatsby-link'; -import { fromPairs } from 'lodash'; -import { sortNodes } from '../utils'; import CategoryLink from './CategoryLink'; import VersionSelect from './VersionSelect'; import Search from './Search'; import SearchEntryResult from './SearchEntryResult'; +import NavigationTree from '../../../static/StaticNavigationTree.json'; +import { ExternalLink } from './ExternalLink'; export default class Sidebar extends React.PureComponent { - state = { loaded: false, query: '', results: [], versions: [] }; + constructor(props) { + super(props); + this.state = { + loaded: false, + openBlockTitle: this.getOpenBlockFromLocation(this.props.location), + query: '', + results: [], + versions: [] + }; + } componentDidMount() { this.loadVersions(); } + componentDidUpdate(prevProps) { + if (this.props.location.pathname !== prevProps.location.pathname) { + this.setState({ openBlockTitle: this.getOpenBlockFromLocation(this.props.location) }); + } + } + + // A block is opened if the current page is set to one of his children + getOpenBlockFromLocation({ pathname }) { + const element = NavigationTree.find( + item => + typeof item === 'object' && + item.children && + item.children.some(child => pathname.endsWith(child)) + ); + return element ? element.title : ''; + } + loadVersions() { fetch('/DocsVersions.json').then(response => response.json().then(json => { @@ -41,21 +67,43 @@ export default class Sidebar extends React.PureComponent { ); } - getPagesHierarchy() { - const categories = sortNodes( - this.props.pages.filter(p => p.fields.slug.split('/').length === 3) - ); - const pages = this.props.pages.filter(p => p.fields.slug.split('/').length > 3); - const categoriesObject = fromPairs(categories.map(c => [c.fields.slug, { ...c, pages: [] }])); - pages.forEach(page => { - const parentSlug = page.fields.slug - .split('/') - .slice(0, 2) - .join('/'); - categoriesObject[parentSlug + '/'].pages.push(page); + getNodeFromUrl = url => { + return this.props.pages.find(p => p.fields.slug === url + '/' || p.frontmatter.url === url); + }; + + handleToggle = title => { + this.setState(state => ({ openBlockTitle: state.openBlockTitle === title ? '' : title })); + }; + + renderCategories = tree => { + return tree.map(item => { + if (typeof item === 'object') { + if (item.children) { + return ( + this.getNodeFromUrl(child))} + headers={this.props.headers} + key={item.title} + location={this.props.location} + onToggle={this.handleToggle} + open={item.title === this.state.openBlockTitle} + title={item.title} + /> + ); + } else { + return ; + } + } + return ( + + ); }); - return categoriesObject; - } + }; renderResults = () => { return ( @@ -79,7 +127,6 @@ export default class Sidebar extends React.PureComponent { }; render() { - const nodes = this.getPagesHierarchy(); const isOnCurrentVersion = this.state.versions.find(v => v.value === this.props.version) !== undefined; return ( @@ -89,9 +136,9 @@ export default class Sidebar extends React.PureComponent { Continuous Code Quality
    - + {this.state.query !== '' && this.renderResults()} - {this.state.query === '' && - Object.keys(nodes).map(key => ( - - ))} + {this.state.query === '' && this.renderCategories(NavigationTree)}
    ); diff --git a/server/sonar-docs/src/layouts/components/icons/DetachIcon.js b/server/sonar-docs/src/layouts/components/icons/DetachIcon.js new file mode 100644 index 00000000000..a48571957a4 --- /dev/null +++ b/server/sonar-docs/src/layouts/components/icons/DetachIcon.js @@ -0,0 +1,32 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import Icon from './Icon'; + +export default function DetachIcon({ className, fill = 'currentColor', size }) { + return ( + + + + ); +} diff --git a/server/sonar-docs/src/layouts/index.js b/server/sonar-docs/src/layouts/index.js index 2fc755141ce..824955d0ae5 100644 --- a/server/sonar-docs/src/layouts/index.js +++ b/server/sonar-docs/src/layouts/index.js @@ -38,13 +38,7 @@ export default function Layout(props) { location={props.location} pages={props.data.allMarkdownRemark.edges .map(e => e.node) - .filter(n => !n.fields.slug.startsWith('/tooltips')) - .filter( - n => - !n.frontmatter.scope || - n.frontmatter.scope === 'sonarqube' || - n.frontmatter.scope === 'static' - )} + .filter(n => !n.fields.slug.startsWith('/tooltips'))} searchIndex={props.data.siteSearchIndex} version={version} /> @@ -95,8 +89,7 @@ export const query = graphql` } frontmatter { title - order - scope + url } fields { slug diff --git a/server/sonar-docs/src/layouts/utils.js b/server/sonar-docs/src/layouts/utils.js index 9fdae25b2fd..40c2c59da23 100644 --- a/server/sonar-docs/src/layouts/utils.js +++ b/server/sonar-docs/src/layouts/utils.js @@ -1,12 +1,26 @@ -import { sortBy } from 'lodash'; +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { sortBy, flatten } from 'lodash'; -export function sortNodes(nodes) { - return nodes.sort((a, b) => { - if (a.frontmatter.order) { - return b.frontmatter.order ? a.frontmatter.order - b.frontmatter.order : 1; - } - return a.frontmatter.title < b.frontmatter.title ? -1 : 1; - }); +export function getUrlsList(navigation) { + return flatten(navigation.map(item => item.children || [item])); } const WORDS = 6; diff --git a/server/sonar-docs/src/pages/404.md b/server/sonar-docs/src/pages/404.md new file mode 100644 index 00000000000..d6a0f85fd7e --- /dev/null +++ b/server/sonar-docs/src/pages/404.md @@ -0,0 +1,8 @@ +--- +title: Page not found +url: /404/ +--- + +# Error + +This page does not exist diff --git a/server/sonar-docs/src/pages/analysis/background-tasks.md b/server/sonar-docs/src/pages/analysis/background-tasks.md index 62157db41da..c12fcfde131 100644 --- a/server/sonar-docs/src/pages/analysis/background-tasks.md +++ b/server/sonar-docs/src/pages/analysis/background-tasks.md @@ -1,5 +1,6 @@ --- title: Background Tasks +url: /analysis/background-tasks/ --- A Background Task can be: diff --git a/server/sonar-docs/src/pages/analysis/generic_issue.md b/server/sonar-docs/src/pages/analysis/generic-issue.md similarity index 97% rename from server/sonar-docs/src/pages/analysis/generic_issue.md rename to server/sonar-docs/src/pages/analysis/generic-issue.md index 33c3ff456f6..27ef5577131 100644 --- a/server/sonar-docs/src/pages/analysis/generic_issue.md +++ b/server/sonar-docs/src/pages/analysis/generic-issue.md @@ -1,5 +1,6 @@ --- title: Generic Issue Data +url: /analysis/generic-issue/ --- SonarQube supports a generic import format for raising "external" issues in code. It is intended to allow you to import the issues from your favorite linter even if no plugin exists for it. @@ -11,7 +12,7 @@ External issues suffer from two important limitations: External issues and the rules that raise them must be managed in the configuration of your linter. -## Import +## Import The analysis parameter `sonar.externalIssuesReportPaths` accepts a comma-delimited list of paths to reports. Each report must contain, at top-level, an array of `Issue` objects named `issues`. @@ -39,6 +40,7 @@ Each report must contain, at top-level, an array of `Issue` objects named `issue * `startColumn` - integer, optional. 0-indexed * `endColumn` - integer, optional. 0-indexed +## Example Here is an example of the expected format: { "issues": [ diff --git a/server/sonar-docs/src/pages/analysis/generic_test.md b/server/sonar-docs/src/pages/analysis/generic-test.md similarity index 99% rename from server/sonar-docs/src/pages/analysis/generic_test.md rename to server/sonar-docs/src/pages/analysis/generic-test.md index 47a5850076e..d7fa694f7d9 100644 --- a/server/sonar-docs/src/pages/analysis/generic_test.md +++ b/server/sonar-docs/src/pages/analysis/generic-test.md @@ -1,5 +1,6 @@ --- title: Generic Test Data +url: /analysis/generic-test/ --- Out of the box, SonarQube supports generic formats for test coverage and test execution import. If your coverage engines' native output formats aren't supported by your language plugins, simply covert them to these formats. diff --git a/server/sonar-docs/src/pages/analysis/index.md b/server/sonar-docs/src/pages/analysis/overview.md similarity index 99% rename from server/sonar-docs/src/pages/analysis/index.md rename to server/sonar-docs/src/pages/analysis/overview.md index e6603fe0a8c..1dc4166abed 100644 --- a/server/sonar-docs/src/pages/analysis/index.md +++ b/server/sonar-docs/src/pages/analysis/overview.md @@ -1,5 +1,6 @@ --- -title: Analyzing Source Code +title: Overview +url: /analysis/overview/ --- Once the SonarQube platform has been installed, you're ready to install an analyzer and begin creating projects. To do that, you must install and configure the scanner that is most appropriate for your needs. Do you build with: diff --git a/server/sonar-docs/src/pages/analysis/pull-request.md b/server/sonar-docs/src/pages/analysis/pull-request.md index 497b5ffb830..4e17d90c01d 100644 --- a/server/sonar-docs/src/pages/analysis/pull-request.md +++ b/server/sonar-docs/src/pages/analysis/pull-request.md @@ -1,5 +1,6 @@ --- title: Pull Request Analysis +url: /analysis/pull-request/ --- @@ -24,7 +25,7 @@ PR analyses on SonarQube are deleted automatically after 30 days with no analysi ## Integrations for GitHub, Bitbucket Cloud and VSTS -If your repositories are hosted on GitHub, Bitbucket Cloud or VSTS, check out first the dedicated ["Integrations" pages](/integrations/index). Chances are that you do not need to read this page further since those integrations handle the configuration and analysis parameters for you. +If your repositories are hosted on GitHub, Bitbucket Cloud or VSTS, check out first the dedicated Integrations for: [BitBucketCloud](/integrations/bitbucketcloud/), [GitHub](/integrations/github/), and [VSTS](/integrations/vsts/). Chances are that you do not need to read this page further since those integrations handle the configuration and analysis parameters for you. ## Analysis Parameters diff --git a/server/sonar-docs/src/pages/analysis/scm_integration.md b/server/sonar-docs/src/pages/analysis/scm-integration.md similarity index 75% rename from server/sonar-docs/src/pages/analysis/scm_integration.md rename to server/sonar-docs/src/pages/analysis/scm-integration.md index 8771b78b2f1..78a498f9c81 100644 --- a/server/sonar-docs/src/pages/analysis/scm_integration.md +++ b/server/sonar-docs/src/pages/analysis/scm-integration.md @@ -1,12 +1,13 @@ --- title: SCM Integration +url: /analysis/scm-integration/ --- Collecting SCM data during code analysis can unlock a number of SonarQube features: * Automatic Issue Assignment * code annotation (blame data) in the Code Viewer -* SCM-driven detection of new code (to help with [Fixing the Water Leak](/fixing-the-water-leak)). Without SCM data, SonarQube determines new code using analysis dates (to timestamp modification of lines). +* SCM-driven detection of new code (to help with [Fixing the Water Leak](/user-guide/fixing-the-water-leak/)). Without SCM data, SonarQube determines new code using analysis dates (to timestamp modification of lines). ### Turning it on/off SCM integration requires support for your individual SCM provider. Git and SVN are supported by default. For other SCM providers, see the Marketplace. diff --git a/server/sonar-docs/src/pages/branches/branches-faq.md b/server/sonar-docs/src/pages/branches/branches-faq.md index e5925192786..304db0a2fdd 100644 --- a/server/sonar-docs/src/pages/branches/branches-faq.md +++ b/server/sonar-docs/src/pages/branches/branches-faq.md @@ -1,6 +1,6 @@ --- title: Frequently Asked Branches Questions -order: 99 +url: /branches/branches-faq/ --- @@ -10,32 +10,32 @@ _Branch analysis is available as part of [Developer Edition](https://redirect.so -**Q:** How long are branches retained? -**A:** Long-lived branches are retained until you delete them manually (**Administration > Branches**). +## How long are branches retained? +Long-lived branches are retained until you delete them manually (**Administration > Branches**). Short-lived branches are deleted automatically after 30 days with no analysis. This can be updated in **Configuration > General > Number of days before purging inactive short living branches**. -**Q:** Do I need to have my project stored in an SCM such as Git or SVN to use this feature? -**A:** No, you don't need to be connected to a SCM. But if you use Git or SVN we can better track the new files on short-lived branches and so better report new issues on the files that really changed during the life of the short-lived branch. +## Does my project need to be stored in an SCM like Git or SVN? +No, you don't need to be connected to a SCM. But if you use Git or SVN we can better track the new files on short-lived branches and so better report new issues on the files that really changed during the life of the short-lived branch. -**Q:** If I flag an Issue as "Won't Fix" or "False-Positive", will it be replicated as such when merging my short-lived branch into the Master? -**A:** Yes. Each time there is an analysis of a long-lived branch, we look at the issues on the short-lived branches and try to synchronize them with the newly raised issues on the long-lived branch. In case you made some changes on the issues (false-positive, won't fix), these changes will be reported on the long-lived branch. +## What if I mark an Issue "Won't Fix" or "False-Positive" in a branch? +It be replicated as such when merging my short-lived branch into the Master. Each time there is an analysis of a long-lived branch, we look at the issues on the short-lived branches and try to synchronize them with the newly raised issues on the long-lived branch. In case you made some changes on the issues (false-positive, won't fix), these changes will be reported on the long-lived branch. -**Q:** Can I still use `sonar.branch`? -**A:** `sonar.branch` is deprecated. You can still use it but it will behave the same way it always has: a separate project will be created. We encourage you to smoothly migrate your users to the new parameter `sonar.branch.name`. +## Can I still use 'sonar.branch'? +`sonar.branch` is deprecated. You can still use it but it will behave the same way it always has: a separate project will be created. We encourage you to smoothly migrate your users to the new parameter `sonar.branch.name`. Please note you cannot use `sonar.branch` together with `sonar.branch.name`. -**Q:** Can I manually delete a branch? -**A:** This can be achieved by going into the Administration menu at Project's level, then Branches. +## Can I manually delete a branch? +This can be achieved by going into the Administration menu at Project's level, then Branches. -**Q:** How do I control the lifespan of a short-lived branch? -**A:** As a global admin, you can set the parameter sonar.dbcleaner.daysBeforeDeletingInactiveShortLivingBranches to control how many days you want to keep an inactive short-lived branch. +## How do I control the lifespan of a short-lived branch? +As a global admin, you can set the parameter `sonar.dbcleaner.daysBeforeDeletingInactiveShortLivingBranches` to control how many days you want to keep an inactive short-lived branch. -**Q:** Does the payload of the Webhook contain extra information related to Branches? -**A:** Yes, an extra node called "branch" is added to the payload. +## Does the payload of the Webhook include branch information? +Yes, an extra node called "branch" is added to the payload. -**Q:** When are Webhooks called? -**A:** When the computation of the background task is done for a given branch but also when an issue is updated on a short-lived branch. +## When are Webhooks called? +When the computation of the background task is done for a given branch but also when an issue is updated on a short-lived branch. -**Q:** What is the impact on my LOCs consumption vs my license? -**A:** The LOC of your largest branch are counted toward your license limit. All other branches are ignored. +## What is the impact on my LOCs consumption vs my license? +The LOC of your largest branch are counted toward your license limit. All other branches are ignored. diff --git a/server/sonar-docs/src/pages/branches/long-lived-branches.md b/server/sonar-docs/src/pages/branches/long-lived-branches.md index b806d2b6a21..1d0aae67c47 100644 --- a/server/sonar-docs/src/pages/branches/long-lived-branches.md +++ b/server/sonar-docs/src/pages/branches/long-lived-branches.md @@ -1,5 +1,6 @@ --- title: Long-lived Branches +url: /branches/long-lived-branches/ --- diff --git a/server/sonar-docs/src/pages/branches/index.md b/server/sonar-docs/src/pages/branches/overview.md similarity index 94% rename from server/sonar-docs/src/pages/branches/index.md rename to server/sonar-docs/src/pages/branches/overview.md index ffe24b02b98..c73cb5fc3c8 100644 --- a/server/sonar-docs/src/pages/branches/index.md +++ b/server/sonar-docs/src/pages/branches/overview.md @@ -1,5 +1,6 @@ --- -title: Branches +title: Overview +url: /branches/overview/ --- @@ -30,7 +31,7 @@ This corresponds to Pull/Merge Requests or Feature Branches. This kind of branch ![conceptual illustration of short-lived branches.](/images/short-lived-branch-concept.png) -For more, see [Short-lived Branches](/branches/short-lived-branches) +For more, see [Short-lived Branches](/branches/short-lived-branches/) ### Long-lived @@ -44,7 +45,7 @@ This kind of branch will: ![conceptual illustration of long-lived branches.](/images/long-lived-branch-concept.png) -For more, see [Long-lived Branches](/branches/long-lived-branches) +For more, see [Long-lived Branches](/branches/long-lived-branches/) ### Master / Main Branch @@ -76,6 +77,6 @@ This can be updated globally in **Configuration > General > Detection** of long- Once a branch type has been set, it cannot be changed. Explicitly, you cannot transform a long-lived to short-lived branch, or vice-versa. ## See also -* [Short-lived Branches](short-lived-branches) -* [Long-lived Branches](long-lived-branches) -* [Frequently Asked Questions](branches-faq) +* [Short-lived Branches](/branches/short-lived-branches/) +* [Long-lived Branches](/branches/long-lived-branches/) +* [Frequently Asked Questions](/branches/branches-faq/) diff --git a/server/sonar-docs/src/pages/branches/short-lived-branches.md b/server/sonar-docs/src/pages/branches/short-lived-branches.md index 8a937009f64..53e27a263b6 100644 --- a/server/sonar-docs/src/pages/branches/short-lived-branches.md +++ b/server/sonar-docs/src/pages/branches/short-lived-branches.md @@ -1,5 +1,6 @@ --- title: Short-lived Branches +url: /branches/short-lived-branches/ --- diff --git a/server/sonar-docs/src/pages/index.md b/server/sonar-docs/src/pages/index.md index cfaf315e74d..240e76889da 100644 --- a/server/sonar-docs/src/pages/index.md +++ b/server/sonar-docs/src/pages/index.md @@ -1,18 +1,23 @@ --- title: Documentation +url: / --- + + [SonarQube](http://www.sonarqube.org/)® software (previously called Sonar) is an open source quality management platform, dedicated to continuously analyze and measure technical quality, from project portfolio to method. If you wish to extend the SonarQube platform with open source plugins, have a look at our [plugin library](https://docs.sonarqube.org/display/PLUG/Plugin+Library). ## I write code -* [Fixing the Water Leak](/fixing-the-water-leak) -* [Quality Gates](/quality-gates) -* [Quality Profiles](/quality-profiles) - +* [Fixing the Water Leak](/user-guide/fixing-the-water-leak/) +* [Quality Gates](/user-guide/quality-gates/) +* [Quality Profiles](/instance-administration/quality-profiles/) + + SonarCloud is the leading product for Continuous Code Quality online, totally free for open-source projects. It supports all major programming languages, including Java, C#, JavaScript, TypeScript, C/C++ and many more. If your code is closed source, SonarCloud also offers a paid plan to run private analyses. -SonarCloud offers end-to-end integrations for teams leveraging [GitHub](/integrations/github), [VSTS](/integrations/vsts), or [Bitbucket Cloud](/integrations/bitbucketcloud) in their development processes. +SonarCloud offers end-to-end integrations for teams leveraging [GitHub](/integrations/github/), [VSTS](/integrations/vsts/), or [Bitbucket Cloud](/integrations/bitbucketcloud/) in their development processes. + diff --git a/server/sonar-docs/src/pages/custom-measures.md b/server/sonar-docs/src/pages/instance-administration/custom-measures.md similarity index 96% rename from server/sonar-docs/src/pages/custom-measures.md rename to server/sonar-docs/src/pages/instance-administration/custom-measures.md index 2c3979b283f..8867f060670 100644 --- a/server/sonar-docs/src/pages/custom-measures.md +++ b/server/sonar-docs/src/pages/instance-administration/custom-measures.md @@ -1,6 +1,6 @@ --- title: Custom Measures -scope: sonarqube +url: /instance-administration/custom-measures/ --- SonarQube collects a maximum of measures in an automated manner but there are some measures for which this is not possible, such as when: the information is not available for collection, the measure is computed by a human, and so on. Whatever the reason, SonarQube provides a service to inject those measures manually and allow you to benefit from other services: the Manual Measures service. The manual measures entered will be picked during the next analysis of the project and thereafter treated as "normal" measures. diff --git a/server/sonar-docs/src/pages/housekeeping.md b/server/sonar-docs/src/pages/instance-administration/housekeeping.md similarity index 97% rename from server/sonar-docs/src/pages/housekeeping.md rename to server/sonar-docs/src/pages/instance-administration/housekeeping.md index e2b333382d5..bd11f3fd403 100644 --- a/server/sonar-docs/src/pages/housekeeping.md +++ b/server/sonar-docs/src/pages/instance-administration/housekeeping.md @@ -1,5 +1,6 @@ --- title: Housekeeping +url: /instance-administration/housekeeping/ --- When you run a new analysis of your project, some data that was previously available is cleaned out of the database. For example the source code of the previous analysis, measures at directory and file levels, and so on are automatically removed at the end of a new analysis. Additionally, some old analysis snapshots are also removed. diff --git a/server/sonar-docs/src/pages/look-and-feel.md b/server/sonar-docs/src/pages/instance-administration/look-and-feel.md similarity index 94% rename from server/sonar-docs/src/pages/look-and-feel.md rename to server/sonar-docs/src/pages/instance-administration/look-and-feel.md index d74542fd730..1008e54d7ec 100644 --- a/server/sonar-docs/src/pages/look-and-feel.md +++ b/server/sonar-docs/src/pages/instance-administration/look-and-feel.md @@ -1,6 +1,6 @@ --- title: Look and Feel -scope: sonarqube +url: /instance-administration/look-and-feel/ --- ## Home logo diff --git a/server/sonar-docs/src/pages/quality-profiles.md b/server/sonar-docs/src/pages/instance-administration/quality-profiles.md similarity index 99% rename from server/sonar-docs/src/pages/quality-profiles.md rename to server/sonar-docs/src/pages/instance-administration/quality-profiles.md index 1e9c03e95e6..db513e758ac 100644 --- a/server/sonar-docs/src/pages/quality-profiles.md +++ b/server/sonar-docs/src/pages/instance-administration/quality-profiles.md @@ -1,5 +1,6 @@ --- title: Quality Profiles +url: /instance-administration/quality-profiles/ --- ## Overview diff --git a/server/sonar-docs/src/pages/integrations/index.md b/server/sonar-docs/src/pages/integrations/index.md deleted file mode 100644 index 01fcb49fe8f..00000000000 --- a/server/sonar-docs/src/pages/integrations/index.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -title: Integrations -scope: sonarcloud ---- - -SonarCloud integrates with the following cloud services to help developers get the most out of their code: - -* [Integration with GitHub](/integrations/github) -* [Integration with Bitbucket Cloud](/integrations/bitbucketcloud) -* [Integration with VSTS](/integrations/vsts) diff --git a/server/sonar-docs/src/pages/webhooks.md b/server/sonar-docs/src/pages/project-administration/webhooks.md similarity index 99% rename from server/sonar-docs/src/pages/webhooks.md rename to server/sonar-docs/src/pages/project-administration/webhooks.md index 2c09225141f..96050491720 100644 --- a/server/sonar-docs/src/pages/webhooks.md +++ b/server/sonar-docs/src/pages/project-administration/webhooks.md @@ -1,5 +1,6 @@ --- title: Webhooks +url: /project-administration/webhooks/ --- Webhooks notify external services when a project analysis is complete. An HTTP POST request including a JSON payload is sent to each URL. URLs may be specified at both the project and global levels. Project-level specification does not replace global-level webhooks. All hooks at both levels are called. diff --git a/server/sonar-docs/src/pages/analyze-a-project.md b/server/sonar-docs/src/pages/sonarcloud/analyze-a-project.md similarity index 74% rename from server/sonar-docs/src/pages/analyze-a-project.md rename to server/sonar-docs/src/pages/sonarcloud/analyze-a-project.md index 07f425a9740..113f8d502e8 100644 --- a/server/sonar-docs/src/pages/analyze-a-project.md +++ b/server/sonar-docs/src/pages/sonarcloud/analyze-a-project.md @@ -1,14 +1,14 @@ --- title: Analyze a Project -scope: sonarcloud +url: /analyze-a-project/ --- ## Prepare your organization -A project must belong to an [organization](/organizations/index). Create one if you intend to collaborate with your team mates, or use your personal organization for test purposes. +A project must belong to an [organization](/organizations/overview/). Create one if you intend to collaborate with your team mates, or use your personal organization for test purposes. [[info]] -| ** Important note for private code:** Newly created organizations and personal organizations are under a free plan by default. This means projects analyzed on these organizations are public by default: the code will be browsable by anyone. If you want private projects, you should [upgrade your organization to a paid plan](/sonarcloud-pricing) in the "Administration > Billing" page of your organization. +| ** Important note for private code:** Newly created organizations and personal organizations are under a free plan by default. This means projects analyzed on these organizations are public by default: the code will be browsable by anyone. If you want private projects, you should [upgrade your organization to a paid plan](/sonarcloud-pricing/) in the "Administration > Billing" page of your organization. Find the key of your organization, you will need it at later stages. It can be found on the top right corner of your organization's header. @@ -19,8 +19,8 @@ existing CI scripts. Depending on which cloud solution you are using for your developments, you can rely on dedicated integrations to help you: -* VSTS: [read our dedicated documentation](/integrations/vsts) -* Bitbucket Cloud: [read our dedicated documentation](/integrations/bitbucketcloud) -* GitHub: [read our dedicated documentation](/integrations/github) +* VSTS: [read our dedicated documentation](/integrations/vsts/) +* Bitbucket Cloud: [read our dedicated documentation](/integrations/bitbucketcloud/) +* GitHub: [read our dedicated documentation](/integrations/github/) If you are not using those solutions, you will have to find out what command to execute to run the analysis. Our [tutorial](/#sonarcloud#/onboarding) will help you on this. diff --git a/server/sonar-docs/src/pages/integrations/bitbucketcloud.md b/server/sonar-docs/src/pages/sonarcloud/integrations/bitbucketcloud.md similarity index 99% rename from server/sonar-docs/src/pages/integrations/bitbucketcloud.md rename to server/sonar-docs/src/pages/sonarcloud/integrations/bitbucketcloud.md index d547c0db84a..6006edcf435 100644 --- a/server/sonar-docs/src/pages/integrations/bitbucketcloud.md +++ b/server/sonar-docs/src/pages/sonarcloud/integrations/bitbucketcloud.md @@ -1,6 +1,6 @@ --- title: Integration with Bitbucket Cloud -scope: sonarcloud +url: /integrations/bitbucketcloud/ --- ## Authentication diff --git a/server/sonar-docs/src/pages/integrations/github.md b/server/sonar-docs/src/pages/sonarcloud/integrations/github.md similarity index 98% rename from server/sonar-docs/src/pages/integrations/github.md rename to server/sonar-docs/src/pages/sonarcloud/integrations/github.md index 12034296f7e..c283c9689c6 100644 --- a/server/sonar-docs/src/pages/integrations/github.md +++ b/server/sonar-docs/src/pages/sonarcloud/integrations/github.md @@ -1,6 +1,6 @@ --- title: Integration with GitHub -scope: sonarcloud +url: /integrations/github/ --- ## Authentication diff --git a/server/sonar-docs/src/pages/integrations/vsts.md b/server/sonar-docs/src/pages/sonarcloud/integrations/vsts.md similarity index 98% rename from server/sonar-docs/src/pages/integrations/vsts.md rename to server/sonar-docs/src/pages/sonarcloud/integrations/vsts.md index de94cd73ad1..448affcd709 100644 --- a/server/sonar-docs/src/pages/integrations/vsts.md +++ b/server/sonar-docs/src/pages/sonarcloud/integrations/vsts.md @@ -1,6 +1,6 @@ --- title: Integration with VSTS -scope: sonarcloud +url: /integrations/vsts/ --- diff --git a/server/sonar-docs/src/pages/organizations/index.md b/server/sonar-docs/src/pages/sonarcloud/organizations/index.md similarity index 75% rename from server/sonar-docs/src/pages/organizations/index.md rename to server/sonar-docs/src/pages/sonarcloud/organizations/index.md index 7ddec3f8abe..b872a83ac19 100644 --- a/server/sonar-docs/src/pages/organizations/index.md +++ b/server/sonar-docs/src/pages/sonarcloud/organizations/index.md @@ -1,6 +1,6 @@ --- title: Organizations -scope: sonarcloud +url: /organizations/overview/ --- ## Overview @@ -9,8 +9,8 @@ An organization is a space where a team or a whole company can collaborate acros An organization consists of: * Projects, on which users collaborate -* [Members](/organizations/manage-team), who can have different persmissions on the projects -* [Quality Profiles](/quality-profiles) and [Quality Gates](/quality-gates), which can be customized and shared accross projects +* [Members](/organizations/manage-team/), who can have different persmissions on the projects +* [Quality Profiles](/instance-administration/quality-profiles/) and [Quality Gates](/user-guide/quality-gates/), which can be customized and shared accross projects There are 2 kind of organizations: * **Personal organizations**. Each account has a personal organization linked to it. This is typically where open-source developers host their personal projects. It is not possible to delete this kind of organization. @@ -20,4 +20,4 @@ Organizations can be on: * **Free plan**. This is the default plan. Every project in an organization on the free plan is public. * **Paid plan**. This plan unlocks the ability to have private projects. Go to the "Billing" page of your organization to upgrade it to the paid plan. -Depending on which plan the organization is in, its [visibility](/organizations/organization-visibility) will change. +Depending on which plan the organization is in, its [visibility](/organizations/organization-visibility/) will change. diff --git a/server/sonar-docs/src/pages/organizations/manage-team.md b/server/sonar-docs/src/pages/sonarcloud/organizations/manage-team.md similarity index 97% rename from server/sonar-docs/src/pages/organizations/manage-team.md rename to server/sonar-docs/src/pages/sonarcloud/organizations/manage-team.md index 53d650f3746..8cbb162bcc1 100644 --- a/server/sonar-docs/src/pages/organizations/manage-team.md +++ b/server/sonar-docs/src/pages/sonarcloud/organizations/manage-team.md @@ -1,6 +1,6 @@ --- title: Manage a Team -scope: sonarcloud +url: /organizations/manage-team/ --- Members can collaborate on the projects in the organizations to which they belong. Depending on their permisssions within the organization, members can: diff --git a/server/sonar-docs/src/pages/organizations/organization-visibility.md b/server/sonar-docs/src/pages/sonarcloud/organizations/organization-visibility.md similarity index 96% rename from server/sonar-docs/src/pages/organizations/organization-visibility.md rename to server/sonar-docs/src/pages/sonarcloud/organizations/organization-visibility.md index c9e746dfa51..94c560580a4 100644 --- a/server/sonar-docs/src/pages/organizations/organization-visibility.md +++ b/server/sonar-docs/src/pages/sonarcloud/organizations/organization-visibility.md @@ -1,6 +1,6 @@ --- title: Organization Visibility -scope: sonarcloud +url: /organizations/organization-visibility/ --- ## Free plan organization diff --git a/server/sonar-docs/src/pages/privacy.md b/server/sonar-docs/src/pages/sonarcloud/privacy.md similarity index 99% rename from server/sonar-docs/src/pages/privacy.md rename to server/sonar-docs/src/pages/sonarcloud/privacy.md index 3e122cf5c6a..a92e13c100a 100644 --- a/server/sonar-docs/src/pages/privacy.md +++ b/server/sonar-docs/src/pages/sonarcloud/privacy.md @@ -1,6 +1,6 @@ --- title: Privacy -scope: sonarcloud +url: /privacy/ --- The privacy policy specifies how data collected on this website is used. Thank you for visiting our website and your interest in our services and products. As the protection of your personal data is an important concern for us, we will explain below what information we collect during your visit to our website, as they are processed and whether or how these may be used. diff --git a/server/sonar-docs/src/pages/security.md b/server/sonar-docs/src/pages/sonarcloud/security.md similarity index 99% rename from server/sonar-docs/src/pages/security.md rename to server/sonar-docs/src/pages/sonarcloud/security.md index 1ec4590eb9c..89315038c6b 100644 --- a/server/sonar-docs/src/pages/security.md +++ b/server/sonar-docs/src/pages/sonarcloud/security.md @@ -1,6 +1,6 @@ --- title: SonarCloud Security -scope: sonarcloud +url: /security/ --- We know that your code is very important to you and your business. We also know that no one wants proven bugs or vulnerabilities found on their source code to be unveiled to third-parties. This is why we take security extremely seriously. diff --git a/server/sonar-docs/src/pages/sonarcloud-pricing.md b/server/sonar-docs/src/pages/sonarcloud/sonarcloud-pricing.md similarity index 99% rename from server/sonar-docs/src/pages/sonarcloud-pricing.md rename to server/sonar-docs/src/pages/sonarcloud/sonarcloud-pricing.md index e38c41a713a..fd0567412f4 100644 --- a/server/sonar-docs/src/pages/sonarcloud-pricing.md +++ b/server/sonar-docs/src/pages/sonarcloud/sonarcloud-pricing.md @@ -1,6 +1,6 @@ --- title: Pricing -scope: sonarcloud +url: /sonarcloud-pricing/ --- Subscribing to a paid plan on SonarCloud allows you to analyze unlimited private projects. You can make your code visible by members of your organization only. diff --git a/server/sonar-docs/src/pages/fixing-the-water-leak.md b/server/sonar-docs/src/pages/user-guide/fixing-the-water-leak.md similarity index 87% rename from server/sonar-docs/src/pages/fixing-the-water-leak.md rename to server/sonar-docs/src/pages/user-guide/fixing-the-water-leak.md index 6158b2ff23c..be0a6b446fd 100644 --- a/server/sonar-docs/src/pages/fixing-the-water-leak.md +++ b/server/sonar-docs/src/pages/user-guide/fixing-the-water-leak.md @@ -1,5 +1,6 @@ --- title: Fixing the Water Leak +url: /user-guide/fixing-the-water-leak/ --- ## What is the Water Leak @@ -19,7 +20,7 @@ Typically in this traditional approach, just before release a periodic code qual Instead, why not apply the same simple logic you use at home to the way you manage code quality? Fixing the leak means putting the focus on the “new” code, i.e. the code that was added or changed since the last release. Then things get much easier: -* The [Quality Gate](/quality-gates) can be run every day, and passing it is achievable. There are no surprises at release time. +* The [Quality Gate](/user-guide/quality-gates/) can be run every day, and passing it is achievable. There are no surprises at release time. * It's pretty difficult for developers to push back on problems they introduced the previous day. Instead, they're generally happy to fix the problems while the code is still fresh. * There is a clear ownership of code quality * The criteria for go/no-go are consistent across applications, and are shared among teams. Indeed new code is new code, regardless of which application it is done in @@ -32,5 +33,5 @@ As a bonus, the code that gets changed the most has the highest maintainability, SonarQubeSonarCloud offers two main tools to help you find your leaks: * New Code metrics show the variance in your measures between the current code and a specific point you choose in its history, typically the `previous_version` -* New Code is primarily detected based on SCM "blame" data starting from the first analysis within your New Code Period (formerly the "Leak Period"), with fallback mechanisms when needed. See [SCM integration](/analysis/scm-integration) for more details. -* [Quality Gates](/quality-gates) allow you to set boolean thresholds against which your code is measured. Use them with differential metrics to ensure that your code quality moves in the right direction over time. +* New Code is primarily detected based on SCM "blame" data starting from the first analysis within your New Code Period (formerly the "Leak Period"), with fallback mechanisms when needed. See [SCM integration](/analysis/scm-integration/) for more details. +* [Quality Gates](/user-guide/quality-gates/) allow you to set boolean thresholds against which your code is measured. Use them with differential metrics to ensure that your code quality moves in the right direction over time. diff --git a/server/sonar-docs/src/pages/keyboard-shortcuts.md b/server/sonar-docs/src/pages/user-guide/keyboard-shortcuts.md similarity index 98% rename from server/sonar-docs/src/pages/keyboard-shortcuts.md rename to server/sonar-docs/src/pages/user-guide/keyboard-shortcuts.md index 178ccff0999..e6fa54758c4 100644 --- a/server/sonar-docs/src/pages/keyboard-shortcuts.md +++ b/server/sonar-docs/src/pages/user-guide/keyboard-shortcuts.md @@ -1,6 +1,6 @@ --- title: Keyboard Shortcuts -order: 99 +url: /user-guide/keyboard-shortcuts/ --- ## Global diff --git a/server/sonar-docs/src/pages/metric-definitions.md b/server/sonar-docs/src/pages/user-guide/metric-definitions.md similarity index 99% rename from server/sonar-docs/src/pages/metric-definitions.md rename to server/sonar-docs/src/pages/user-guide/metric-definitions.md index 737b3e656db..9507636dfe4 100644 --- a/server/sonar-docs/src/pages/metric-definitions.md +++ b/server/sonar-docs/src/pages/user-guide/metric-definitions.md @@ -1,5 +1,6 @@ --- title: Metric Definitions +url: /user-guide/metric-definitions/ --- ## Table of Contents diff --git a/server/sonar-docs/src/pages/quality-gates.md b/server/sonar-docs/src/pages/user-guide/quality-gates.md similarity index 94% rename from server/sonar-docs/src/pages/quality-gates.md rename to server/sonar-docs/src/pages/user-guide/quality-gates.md index 9d1cdda2dc2..8d422fbc151 100644 --- a/server/sonar-docs/src/pages/quality-gates.md +++ b/server/sonar-docs/src/pages/user-guide/quality-gates.md @@ -1,5 +1,6 @@ --- title: Quality Gates +url: /user-guide/quality-gates/ --- ## Overview @@ -23,7 +24,7 @@ Which is why you can define as many quality gates as you wish. Quality Gates are ## Use the Best Quality Gate Configuration -The quality gate "Sonar way" is provided by SonarSource, activated by default and considered as built-in and so read-only. It represents our view of the best way to implement the [Fixing the Water Leak](/fixing-the-water-leak) concept. At each SonarQube release, we adjust automatically this default quality gate according to SonarQube's capabilities. +The quality gate "Sonar way" is provided by SonarSource, activated by default and considered as built-in and so read-only. It represents our view of the best way to implement the [Fixing the Water Leak](/user-guide/fixing-the-water-leak/) concept. At each SonarQube release, we adjust automatically this default quality gate according to SonarQube's capabilities. Three metrics allow you to enforce a given Rating of Reliability, Security and Maintainability, not just overall but also on new code. These metrics are recommended and come as part of the default quality gate. We strongly advise you to adjust your own quality gates to use them to make feedback more clear to your developers looking at their quality gate on their project page. diff --git a/server/sonar-docs/src/pages/security-reports.md b/server/sonar-docs/src/pages/user-guide/security-reports.md similarity index 99% rename from server/sonar-docs/src/pages/security-reports.md rename to server/sonar-docs/src/pages/user-guide/security-reports.md index 79d6372e5a4..f25d69c2aa1 100644 --- a/server/sonar-docs/src/pages/security-reports.md +++ b/server/sonar-docs/src/pages/user-guide/security-reports.md @@ -1,5 +1,6 @@ --- title: Security Reports +url: /user-guide/security-reports/ --- ## What do the Security Reports show? diff --git a/server/sonar-docs/src/pages/user-account.md b/server/sonar-docs/src/pages/user-guide/user-account.md similarity index 59% rename from server/sonar-docs/src/pages/user-account.md rename to server/sonar-docs/src/pages/user-guide/user-account.md index 43feacfed3f..935823eda08 100644 --- a/server/sonar-docs/src/pages/user-account.md +++ b/server/sonar-docs/src/pages/user-guide/user-account.md @@ -1,8 +1,9 @@ --- title: User Account +url: /user-guide/user-account/ --- -As a SonarQubeSonarCloud user you have your own space where you can see the things that are relevant to you: +As a {instance} user you have your own space where you can see the things that are relevant to you: ## Home Page @@ -13,7 +14,7 @@ It gives you a summary of: ## Security -In addition to being able to change your password, if your instance is not using a 3rd party authentication mechanism such as LDAP or any OAuth provider (GitHub, Google Account, ...), you can manage your own [authentication tokens](/user-token). +In addition to being able to change your password, if your instance is not using a 3rd party authentication mechanism such as LDAP or any OAuth provider (GitHub, Google Account, ...), you can manage your own authentication tokens. -You can create as many Token as you want. Once a Token is created, you can use it to publish analysis to a project where you have the [execute analysis](/security/authorization) permission. +You can create as many Token as you want. Once a Token is created, you can use it to publish analysis to a project where you have the execute analysis permission. diff --git a/server/sonar-docs/src/templates/page.js b/server/sonar-docs/src/templates/page.js index 75b02494ed3..ad61a0fb70c 100644 --- a/server/sonar-docs/src/templates/page.js +++ b/server/sonar-docs/src/templates/page.js @@ -51,10 +51,11 @@ export default class Page extends React.PureComponent { htmlWithInclusions = removeTableOfContents(htmlWithInclusions); htmlWithInclusions = createAnchorForHeadings(htmlWithInclusions, realHeadingsList); htmlWithInclusions = replaceDynamicLinks(htmlWithInclusions); + htmlWithInclusions = replaceInstanceTag(htmlWithInclusions); return (
    - + @@ -99,6 +100,10 @@ export const query = graphql` } `; +function replaceInstanceTag(content) { + return content.replace('{instance}', 'SonarQube'); +} + function replaceDynamicLinks(content) { const version = process.env.GATSBY_DOCS_VERSION || ''; const usePrefix = process.env.GATSBY_USE_PREFIX === '1'; @@ -115,12 +120,6 @@ function replaceDynamicLinks(content) { '$2' ); - // Add trailing slash to local link - content = content.replace( - /\(.*)\<\/a\>/gim, - '$2' - ); - return content.replace( /\(.*)\<\/a\>/gim, '$2' diff --git a/server/sonar-docs/static/README.md b/server/sonar-docs/static/README.md new file mode 100644 index 00000000000..4e3c36aa6a7 --- /dev/null +++ b/server/sonar-docs/static/README.md @@ -0,0 +1,24 @@ +These three `*.NavigationTree.json` files control the navigation trees of the three versions of the documentation. + +Each one contains a JSON array. Array elements may either be: + +* a path string +* a node + +**Nodes contain two elements:** +* title - string. This is the "parent" node name to be used in the navigation tree +* children - array of path strings + +**Paths** +* begin with '/' +* end with '/' +* match the `url:` value of a page. +* **do not** include the trailing `.md` in the file name + +**What is the URL value of a page?** +The url value can be implicitly defined by the document's path under the `pages` directory, or explicitly overridden by in the page metadata by setting `url: [path here]`. + +Paths must always start and end with '/'. That includes: +* page metadata +* navigation tree files +* links between pages diff --git a/server/sonar-docs/static/SonarCloudNavigationTree.json b/server/sonar-docs/static/SonarCloudNavigationTree.json new file mode 100644 index 00000000000..77f9677e168 --- /dev/null +++ b/server/sonar-docs/static/SonarCloudNavigationTree.json @@ -0,0 +1,53 @@ +[ + "/privacy/", + "/security/", + "/sonarcloud-pricing/", + "/analyze-a-project/", + { + "title": "Analyzing Source Code", + "children": [ + "/analysis/overview/", + "/analysis/background-tasks/", + "/analysis/generic-issue/", + "/analysis/generic-test/", + "/analysis/pull-request/", + "/analysis/scm-integration/" + ] + }, + { + "title": "Integrations", + "children": ["/integrations/bitbucketcloud/", "/integrations/github/", "/integrations/vsts/"] + }, + { + "title": "Branches", + "children": [ + "/branches/overview/", + "/branches/short-lived-branches/", + "/branches/long-lived-branches/", + "/branches/branches-faq/" + ] + }, + { + "title": "User Guide", + "children": [ + "/user-guide/fixing-the-water-leak/", + "/user-guide/keyboard-shortcuts/", + "/user-guide/quality-gates/", + "/user-guide/metric-definitions/", + "/user-guide/security-reports/", + "/user-guide/user-account/" + ] + }, + { + "title": "Project Administration", + "children": ["/project-administration/webhooks/"] + }, + { + "title": "Organizations", + "children": [ + "/organizations/overview/", + "/organizations/manage-team/", + "/organizations/organization-visibility/" + ] + } +] diff --git a/server/sonar-docs/static/SonarQubeNavigationTree.json b/server/sonar-docs/static/SonarQubeNavigationTree.json new file mode 100644 index 00000000000..1d047f5936c --- /dev/null +++ b/server/sonar-docs/static/SonarQubeNavigationTree.json @@ -0,0 +1,46 @@ +[ + { + "title": "Analyzing Source Code", + "children": [ + "/analysis/overview/", + "/analysis/background-tasks/", + "/analysis/generic-issue/", + "/analysis/generic-test/", + "/analysis/pull-request/", + "/analysis/scm-integration/" + ] + }, + { + "title": "Branches", + "children": [ + "/branches/overview/", + "/branches/short-lived-branches/", + "/branches/long-lived-branches/", + "/branches/branches-faq/" + ] + }, + { + "title": "User Guide", + "children": [ + "/user-guide/fixing-the-water-leak/", + "/user-guide/keyboard-shortcuts/", + "/user-guide/quality-gates/", + "/user-guide/metric-definitions/", + "/user-guide/security-reports/", + "/user-guide/user-account/" + ] + }, + { + "title": "Project Administration", + "children": ["/project-administration/webhooks/"] + }, + { + "title": "Instance Administration", + "children": [ + "/instance-administration/custom-measures/", + "/instance-administration/housekeeping/", + "/instance-administration/look-and-feel/", + "/instance-administration/quality-profiles/" + ] + } +] diff --git a/server/sonar-docs/static/StaticNavigationTree.json b/server/sonar-docs/static/StaticNavigationTree.json new file mode 100644 index 00000000000..ffbac954d82 --- /dev/null +++ b/server/sonar-docs/static/StaticNavigationTree.json @@ -0,0 +1,54 @@ +[ + { + "title": "Requirements", + "children": [] + }, + { + "title": "Setup and Upgrade", + "children": [] + }, + { + "title": "Analyzing Source Code", + "children": [ + "/analysis/overview/", + "/analysis/background-tasks/", + "/analysis/generic-issue/", + "/analysis/generic-test/", + "/analysis/pull-request/", + "/analysis/scm-integration/" + ] + }, + { + "title": "Branches", + "children": [ + "/branches/overview/", + "/branches/short-lived-branches/", + "/branches/long-lived-branches/", + "/branches/branches-faq/" + ] + }, + { + "title": "User Guide", + "children": [ + "/user-guide/fixing-the-water-leak/", + "/user-guide/keyboard-shortcuts/", + "/user-guide/quality-gates/", + "/user-guide/metric-definitions/", + "/user-guide/security-reports/", + "/user-guide/user-account/" + ] + }, + { + "title": "Project Administration", + "children": ["/project-administration/webhooks/"] + }, + { + "title": "Instance Administration", + "children": [ + "/instance-administration/custom-measures/", + "/instance-administration/housekeeping/", + "/instance-administration/look-and-feel/", + "/instance-administration/quality-profiles/" + ] + } +] diff --git a/server/sonar-docs/yarn.lock b/server/sonar-docs/yarn.lock index 25a3cdbb78d..e665dd4a216 100644 --- a/server/sonar-docs/yarn.lock +++ b/server/sonar-docs/yarn.lock @@ -9,6 +9,20 @@ elasticlunr "^0.9.5" graphql "^0.11.7" +"@babel/code-frame@^7.0.0-beta.35": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.0.0.tgz#06e2ab19bdb535385559aabb5ba59729482800f8" + dependencies: + "@babel/highlight" "^7.0.0" + +"@babel/highlight@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.0.0.tgz#f710c38c8d458e6dd9a201afb637fcb781ce99e4" + dependencies: + chalk "^2.0.0" + esutils "^2.0.2" + js-tokens "^4.0.0" + "@types/configstore@^2.1.1": version "2.1.1" resolved "https://registry.yarnpkg.com/@types/configstore/-/configstore-2.1.1.tgz#cd1e8553633ad3185c3f2f239ecff5d2643e92b6" @@ -25,7 +39,7 @@ version "0.0.4" resolved "https://registry.yarnpkg.com/@types/get-port/-/get-port-0.0.4.tgz#eb6bb7423d9f888b632660dc7d2fd3e69a35643e" -"@types/glob@^5.0.30": +"@types/glob@*", "@types/glob@^5.0.30": version "5.0.35" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-5.0.35.tgz#1ae151c802cece940443b5ac246925c85189f32a" dependencies: @@ -78,6 +92,10 @@ version "0.0.32" resolved "https://registry.yarnpkg.com/@types/tmp/-/tmp-0.0.32.tgz#0d3cb31022f8427ea58c008af32b80da126ca4e3" +abab@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/abab/-/abab-2.0.0.tgz#aba0ab4c5eee2d4c79d3487d85450fb2376ebb0f" + abbrev@1: version "1.1.1" resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.1.tgz#f8f2c887ad10bf67f634f005b6987fed3179aac8" @@ -89,10 +107,20 @@ accepts@^1.3.0, accepts@~1.3.4, accepts@~1.3.5: mime-types "~2.1.18" negotiator "0.6.1" +acorn-globals@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/acorn-globals/-/acorn-globals-4.1.0.tgz#ab716025dbe17c54d3ef81d32ece2b2d99fe2538" + dependencies: + acorn "^5.0.0" + acorn@^3.0.0: version "3.3.0" resolved "https://registry.yarnpkg.com/acorn/-/acorn-3.3.0.tgz#45e37fb39e8da3f25baee3ff5369e2bb5f22017a" +acorn@^5.0.0, acorn@^5.5.3: + version "5.7.3" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-5.7.3.tgz#67aa231bf8812974b85235a96771eb6bd07ea279" + address@1.0.3, address@^1.0.1: version "1.0.3" resolved "https://registry.yarnpkg.com/address/-/address-1.0.3.tgz#b5f50631f8d6cec8bd20c963963afb55e06cbce9" @@ -101,7 +129,7 @@ after@0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/after/-/after-0.8.2.tgz#fedb394f9f0e02aa9768e702bda23b505fae7e1f" -ajv@^5.1.0: +ajv@^5.1.0, ajv@^5.3.0: version "5.5.2" resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965" dependencies: @@ -152,7 +180,7 @@ ansi-styles@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" -ansi-styles@^3.2.1: +ansi-styles@^3.2.0, ansi-styles@^3.2.1: version "3.2.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d" dependencies: @@ -173,6 +201,19 @@ anymatch@^1.3.0: micromatch "^2.1.5" normalize-path "^2.0.0" +anymatch@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-2.0.0.tgz#bcb24b4f37934d9aa7ac17b4adaf89e7c76ef2eb" + dependencies: + micromatch "^3.1.4" + normalize-path "^2.1.1" + +append-transform@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/append-transform/-/append-transform-0.4.0.tgz#d76ebf8ca94d276e247a36bad44a4b74ab611991" + dependencies: + default-require-extensions "^1.0.0" + aproba@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.2.0.tgz#6802e6264efd18c790a1b0d517f0f2627bf2c94a" @@ -225,6 +266,10 @@ array-each@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/array-each/-/array-each-1.0.1.tgz#a794af0c05ab1752846ee753a1f211a05ba0c44f" +array-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/array-equal/-/array-equal-1.0.0.tgz#8c2a5ef2472fd9ea742b04c77a75093ba2757c93" + array-filter@~0.0.0: version "0.0.1" resolved "https://registry.yarnpkg.com/array-filter/-/array-filter-0.0.1.tgz#7da8cf2e26628ed732803581fd21f67cacd2eeec" @@ -275,6 +320,10 @@ arraybuffer.slice@~0.0.7: version "0.0.7" resolved "https://registry.yarnpkg.com/arraybuffer.slice/-/arraybuffer.slice-0.0.7.tgz#3bbc4275dd584cc1b10809b89d4e8b63a69e7675" +arrify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + asap@~2.0.3: version "2.0.6" resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46" @@ -305,6 +354,10 @@ assign-symbols@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" +astral-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" + async-each@^1.0.0, async-each@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" @@ -327,6 +380,12 @@ async@^2.1.2: dependencies: lodash "^4.14.0" +async@^2.1.4, async@^2.5.0: + version "2.6.1" + resolved "https://registry.yarnpkg.com/async/-/async-2.6.1.tgz#b245a23ca71930044ec53fa46aa00a3e87c6a610" + dependencies: + lodash "^4.17.10" + async@~0.2.6: version "0.2.10" resolved "https://registry.yarnpkg.com/async/-/async-0.2.10.tgz#b6bbe0b0674b9d719708ca38de8c237cb526c3d1" @@ -358,6 +417,10 @@ aws4@^1.6.0: version "1.7.0" resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.7.0.tgz#d4d0e9b9dbfca77bf08eeb0a8a471550fe39e289" +aws4@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" + babel-cli@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-cli/-/babel-cli-6.26.0.tgz#502ab54874d7db88ad00b887a06383ce03d002f1" @@ -387,6 +450,30 @@ babel-code-frame@6.26.0, babel-code-frame@^6.11.0, babel-code-frame@^6.22.0, bab esutils "^2.0.2" js-tokens "^3.0.2" +babel-core@^6.0.0: + version "6.26.3" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.3.tgz#b2e2f09e342d0f0c88e2f02e067794125e75c207" + dependencies: + babel-code-frame "^6.26.0" + babel-generator "^6.26.0" + babel-helpers "^6.24.1" + babel-messages "^6.23.0" + babel-register "^6.26.0" + babel-runtime "^6.26.0" + babel-template "^6.26.0" + babel-traverse "^6.26.0" + babel-types "^6.26.0" + babylon "^6.18.0" + convert-source-map "^1.5.1" + debug "^2.6.9" + json5 "^0.5.1" + lodash "^4.17.4" + minimatch "^3.0.4" + path-is-absolute "^1.0.1" + private "^0.1.8" + slash "^1.0.0" + source-map "^0.5.7" + babel-core@^6.24.1, babel-core@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.26.0.tgz#af32f78b31a6fcef119c87b0fd8d9753f03a0bb8" @@ -411,7 +498,7 @@ babel-core@^6.24.1, babel-core@^6.26.0: slash "^1.0.0" source-map "^0.5.6" -babel-generator@^6.24.1, babel-generator@^6.26.0: +babel-generator@^6.18.0, babel-generator@^6.24.1, babel-generator@^6.26.0: version "6.26.1" resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.26.1.tgz#1844408d3b8f0d35a404ea7ac180f087a601bd90" dependencies: @@ -550,6 +637,13 @@ babel-helpers@^6.24.1: babel-runtime "^6.22.0" babel-template "^6.24.1" +babel-jest@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-23.6.0.tgz#a644232366557a2240a0c083da6b25786185a2f1" + dependencies: + babel-plugin-istanbul "^4.1.6" + babel-preset-jest "^23.2.0" + babel-loader@^6.0.0: version "6.4.1" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-6.4.1.tgz#0b34112d5b0748a8dcdbf51acf6f9bd42d50b8ca" @@ -575,6 +669,19 @@ babel-plugin-check-es2015-constants@^6.22.0, babel-plugin-check-es2015-constants dependencies: babel-runtime "^6.22.0" +babel-plugin-istanbul@^4.1.6: + version "4.1.6" + resolved "http://registry.npmjs.org/babel-plugin-istanbul/-/babel-plugin-istanbul-4.1.6.tgz#36c59b2192efce81c5b378321b74175add1c9a45" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.13.0" + find-up "^2.1.0" + istanbul-lib-instrument "^1.10.1" + test-exclude "^4.2.1" + +babel-plugin-jest-hoist@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/babel-plugin-jest-hoist/-/babel-plugin-jest-hoist-23.2.0.tgz#e61fae05a1ca8801aadee57a6d66b8cefaf44167" + babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" @@ -623,7 +730,7 @@ babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: version "6.18.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" -babel-plugin-syntax-object-rest-spread@^6.8.0: +babel-plugin-syntax-object-rest-spread@^6.13.0, babel-plugin-syntax-object-rest-spread@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" @@ -1077,6 +1184,13 @@ babel-preset-flow@^6.23.0: dependencies: babel-plugin-transform-flow-strip-types "^6.22.0" +babel-preset-jest@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/babel-preset-jest/-/babel-preset-jest-23.2.0.tgz#8ec7a03a138f001a1a8fb1e8113652bf1a55da46" + dependencies: + babel-plugin-jest-hoist "^23.2.0" + babel-plugin-syntax-object-rest-spread "^6.13.0" + babel-preset-react@^6.24.1: version "6.24.1" resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.24.1.tgz#ba69dfaea45fc3ec639b6a4ecea6e17702c91380" @@ -1142,7 +1256,7 @@ babel-runtime@^6.18.0, babel-runtime@^6.22.0, babel-runtime@^6.23.0, babel-runti core-js "^2.4.0" regenerator-runtime "^0.11.0" -babel-template@^6.24.1, babel-template@^6.26.0, babel-template@^6.9.0: +babel-template@^6.16.0, babel-template@^6.24.1, babel-template@^6.26.0, babel-template@^6.9.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.26.0.tgz#de03e2d16396b069f46dd9fff8521fb1a0e35e02" dependencies: @@ -1152,7 +1266,7 @@ babel-template@^6.24.1, babel-template@^6.26.0, babel-template@^6.9.0: babylon "^6.18.0" lodash "^4.17.4" -babel-traverse@^6.24.1, babel-traverse@^6.26.0: +babel-traverse@^6.0.0, babel-traverse@^6.18.0, babel-traverse@^6.24.1, babel-traverse@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.26.0.tgz#46a9cbd7edcc62c8e5c064e2d2d8d0f4035766ee" dependencies: @@ -1166,7 +1280,7 @@ babel-traverse@^6.24.1, babel-traverse@^6.26.0: invariant "^2.2.2" lodash "^4.17.4" -babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: +babel-types@^6.0.0, babel-types@^6.18.0, babel-types@^6.19.0, babel-types@^6.24.1, babel-types@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.26.0.tgz#a3b073f94ab49eb6fa55cd65227a334380632497" dependencies: @@ -1396,6 +1510,16 @@ brorand@^1.0.1: version "1.1.0" resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" +browser-process-hrtime@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/browser-process-hrtime/-/browser-process-hrtime-0.1.2.tgz#425d68a58d3447f02a04aa894187fce8af8b7b8e" + +browser-resolve@^1.11.3: + version "1.11.3" + resolved "https://registry.yarnpkg.com/browser-resolve/-/browser-resolve-1.11.3.tgz#9b7cbb3d0f510e4cb86bdbd796124d28b5890af6" + dependencies: + resolve "1.1.7" + browserify-aes@0.4.0: version "0.4.0" resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-0.4.0.tgz#067149b668df31c4b58533e02d01e806d8608e2c" @@ -1495,6 +1619,10 @@ buffer-fill@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-0.1.1.tgz#76d825c4d6e50e06b7a31eb520c04d08cc235071" +buffer-from@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" + buffer-peek-stream@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/buffer-peek-stream/-/buffer-peek-stream-1.0.1.tgz#53b47570a1347787c5bad4ca2ca3021f9d8b3cfd" @@ -1545,6 +1673,10 @@ callsite@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/callsite/-/callsite-1.0.0.tgz#280398e5d664bd74038b6f0905153e6e8af1bc20" +callsites@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/callsites/-/callsites-2.0.0.tgz#06eb84f00eea413da86affefacbffb36093b3c50" + camelcase@5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-5.0.0.tgz#03295527d58bd3cd4aa75363f35b2e8d97be2f42" @@ -1578,6 +1710,12 @@ caniuse-lite@^1.0.30000792: version "1.0.30000830" resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000830.tgz#cb96b8a2dd3cbfe04acea2af3c4e894249095328" +capture-exit@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/capture-exit/-/capture-exit-1.2.0.tgz#1c5fcc489fd0ab00d4f1ac7ae1072e3173fbab6f" + dependencies: + rsvp "^3.3.3" + capture-stack-trace@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/capture-stack-trace/-/capture-stack-trace-1.0.0.tgz#4a6fa07399c26bba47f0b2496b4d0fb408c5550d" @@ -1756,6 +1894,14 @@ cliui@^3.2.0: strip-ansi "^3.0.1" wrap-ansi "^2.0.0" +cliui@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-4.1.0.tgz#348422dbe82d800b3022eef4f6ac10bf2e4d1b49" + dependencies: + string-width "^2.1.1" + strip-ansi "^4.0.0" + wrap-ansi "^2.0.0" + clone@2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.1.tgz#d217d1e961118e3ac9a4b8bba3285553bf647cdb" @@ -1836,7 +1982,7 @@ colors@~1.1.2: version "1.1.2" resolved "https://registry.yarnpkg.com/colors/-/colors-1.1.2.tgz#168a4701756b6a7f51a12ce0c97bfa28c084ed63" -combined-stream@1.0.6, combined-stream@~1.0.5: +combined-stream@1.0.6, combined-stream@~1.0.5, combined-stream@~1.0.6: version "1.0.6" resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.6.tgz#723e7df6e801ac5613113a7e445a9b69cb632818" dependencies: @@ -1862,6 +2008,10 @@ commander@^2.11.0: version "2.15.1" resolved "https://registry.yarnpkg.com/commander/-/commander-2.15.1.tgz#df46e867d0fc2aec66a34662b406a9ccafff5b0f" +commander@~2.17.1: + version "2.17.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.17.1.tgz#bd77ab7de6de94205ceacc72f1716d29f20a77bf" + common-tags@0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-0.1.1.tgz#d893486ecc6df22cffe6c393c88c12f71e7e8871" @@ -1976,6 +2126,12 @@ convert-hrtime@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/convert-hrtime/-/convert-hrtime-2.0.0.tgz#19bfb2c9162f9e11c2f04c2c79de2b7e8095c627" +convert-source-map@^1.4.0, convert-source-map@^1.5.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + dependencies: + safe-buffer "~5.1.1" + convert-source-map@^1.5.0: version "1.5.1" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.5.1.tgz#b8278097b9bc229365de5c62cf5fcaed8b5599e5" @@ -2221,6 +2377,16 @@ csso@~2.3.1: clap "^1.0.9" source-map "^0.5.3" +cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": + version "0.3.4" + resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.4.tgz#8cd52e8a3acfd68d3aed38ee0a640177d2f9d797" + +cssstyle@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/cssstyle/-/cssstyle-1.1.1.tgz#18b038a9c44d65f7a8e428a653b9f6fe42faf5fb" + dependencies: + cssom "0.3.x" + csstype@^2.2.0: version "2.4.0" resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.4.0.tgz#6c7d711cc135dcd90c812a80213eab006fc1acff" @@ -2251,6 +2417,14 @@ data-uri-to-buffer@0.0.4: version "0.0.4" resolved "https://registry.yarnpkg.com/data-uri-to-buffer/-/data-uri-to-buffer-0.0.4.tgz#46e13ab9da8e309745c8d01ce547213ebdb2fe3f" +data-urls@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/data-urls/-/data-urls-1.0.1.tgz#d416ac3896918f29ca84d81085bc3705834da579" + dependencies: + abab "^2.0.0" + whatwg-mimetype "^2.1.0" + whatwg-url "^7.0.0" + date-now@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" @@ -2259,7 +2433,7 @@ death@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/death/-/death-1.1.0.tgz#01aa9c401edd92750514470b8266390c66c67318" -debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.3, debug@^2.6.6, debug@^2.6.8: +debug@2.6.9, debug@^2.1.2, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.3, debug@^2.6.6, debug@^2.6.8, debug@^2.6.9: version "2.6.9" resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f" dependencies: @@ -2289,10 +2463,24 @@ deep-equal@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" +deep-extend@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac" + deep-extend@~0.4.0: version "0.4.2" resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.2.tgz#48b699c27e334bf89f10892be432f6e4c7d34a7f" +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +default-require-extensions@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/default-require-extensions/-/default-require-extensions-1.0.0.tgz#f37ea15d3e13ffd9b437d33e1a75b5fb97874cb8" + dependencies: + strip-bom "^2.0.0" + define-properties@^1.1.1: version "1.1.2" resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.2.tgz#83a73f2fea569898fb737193c8f873caf6d45c94" @@ -2300,6 +2488,12 @@ define-properties@^1.1.1: foreach "^2.0.5" object-keys "^1.0.8" +define-properties@^1.1.2: + version "1.1.3" + resolved "https://registry.yarnpkg.com/define-properties/-/define-properties-1.1.3.tgz#cf88da6cbee26fe6db7094f61d870cbd84cee9f1" + dependencies: + object-keys "^1.0.12" + define-property@^0.2.5: version "0.2.5" resolved "https://registry.yarnpkg.com/define-property/-/define-property-0.2.5.tgz#c35b1ef918ec3c990f9a5bc57be04aacec5c8116" @@ -2391,6 +2585,10 @@ detect-libc@^1.0.2: version "1.0.3" resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b" +detect-newline@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/detect-newline/-/detect-newline-2.1.0.tgz#f41f1c10be4b00e87b5f13da680759f2c5bfd3e2" + detect-port-alt@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/detect-port-alt/-/detect-port-alt-1.1.3.tgz#a4d2f061d757a034ecf37c514260a98750f2b131" @@ -2426,6 +2624,10 @@ devcert-san@^0.3.3: tmp "^0.0.31" tslib "^1.6.0" +diff@^3.2.0: + version "3.5.0" + resolved "https://registry.yarnpkg.com/diff/-/diff-3.5.0.tgz#800c0dd1e0a8bfbc95835c202ad220fe317e5a12" + diffie-hellman@^5.0.0: version "5.0.3" resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.3.tgz#40e8ee98f55a2149607146921c63e1ae5f3d2875" @@ -2467,6 +2669,12 @@ domelementtype@~1.1.1: version "1.1.3" resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-1.1.3.tgz#bd28773e2642881aec51544924299c5cd822185b" +domexception@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/domexception/-/domexception-1.0.1.tgz#937442644ca6a31261ef36e3ec677fe805582c90" + dependencies: + webidl-conversions "^4.0.2" + domhandler@2.1: version "2.1.0" resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-2.1.0.tgz#d2646f5e57f6c3bab11cf6cb05d3c0acf7412594" @@ -2656,6 +2864,24 @@ error-stack-parser@^2.0.0: dependencies: stackframe "^1.0.3" +es-abstract@^1.5.1: + version "1.12.0" + resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.12.0.tgz#9dbbdd27c6856f0001421ca18782d786bf8a6165" + dependencies: + es-to-primitive "^1.1.1" + function-bind "^1.1.1" + has "^1.0.1" + is-callable "^1.1.3" + is-regex "^1.0.4" + +es-to-primitive@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/es-to-primitive/-/es-to-primitive-1.1.1.tgz#45355248a88979034b6792e19bb81f2b7975dd0d" + dependencies: + is-callable "^1.1.1" + is-date-object "^1.0.1" + is-symbol "^1.0.1" + es5-ext@^0.10.12, es5-ext@^0.10.35, es5-ext@^0.10.9, es5-ext@~0.10.14: version "0.10.42" resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.42.tgz#8c07dd33af04d5dcd1310b5cef13bea63a89ba8d" @@ -2698,6 +2924,17 @@ escape-string-regexp@1.0.5, escape-string-regexp@^1.0.2, escape-string-regexp@^1 version "1.0.5" resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" +escodegen@^1.9.1: + version "1.11.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.11.0.tgz#b27a9389481d5bfd5bec76f7bb1eb3f8f4556589" + dependencies: + esprima "^3.1.3" + estraverse "^4.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + esniff@^1.1: version "1.1.0" resolved "https://registry.yarnpkg.com/esniff/-/esniff-1.1.0.tgz#c66849229f91464dede2e0d40201ed6abf65f2ac" @@ -2709,10 +2946,18 @@ esprima@^2.6.0: version "2.7.3" resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" +esprima@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-3.1.3.tgz#fdca51cee6133895e3c88d535ce49dbff62a4633" + esprima@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/esprima/-/esprima-4.0.0.tgz#4499eddcd1110e0b218bacf2fa7f7f59f55ca804" +estraverse@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + esutils@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" @@ -2782,6 +3027,10 @@ exenv@^1.2.1: version "1.2.2" resolved "https://registry.yarnpkg.com/exenv/-/exenv-1.2.2.tgz#2ae78e85d9894158670b03d47bec1f03bd91bb9d" +exit@^0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/exit/-/exit-0.1.2.tgz#0632638f8d877cc82107d30a0fff1a17cba1cd0c" + expand-brackets@^0.1.4: version "0.1.5" resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" @@ -2818,6 +3067,17 @@ expand-tilde@^2.0.0, expand-tilde@^2.0.2: dependencies: homedir-polyfill "^1.0.1" +expect@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/expect/-/expect-23.6.0.tgz#1e0c8d3ba9a581c87bd71fb9bc8862d443425f98" + dependencies: + ansi-styles "^3.2.0" + jest-diff "^23.6.0" + jest-get-type "^22.1.0" + jest-matcher-utils "^23.6.0" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + express-graphql@^0.6.6: version "0.6.12" resolved "https://registry.yarnpkg.com/express-graphql/-/express-graphql-0.6.12.tgz#dfcb2058ca72ed5190b140830ad8cdbf76a9128a" @@ -2879,6 +3139,10 @@ extend@^3.0.0, extend@~3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444" +extend@~3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.2.tgz#f8b1136b4071fbd8eb140aff858b1019ec2915fa" + external-editor@^2.0.4: version "2.2.0" resolved "https://registry.yarnpkg.com/external-editor/-/external-editor-2.2.0.tgz#045511cfd8d133f3846673d1047c154e214ad3d5" @@ -2993,6 +3257,13 @@ filename-regex@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.1.tgz#c1c4b9bee3e09725ddb106b75c1e301fe2f18b26" +fileset@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/fileset/-/fileset-2.0.3.tgz#8e7548a96d3cc2327ee5e674168723a333bba2a0" + dependencies: + glob "^7.0.3" + minimatch "^3.0.3" + filesize@3.5.11: version "3.5.11" resolved "https://registry.yarnpkg.com/filesize/-/filesize-3.5.11.tgz#1919326749433bb3cf77368bd158caabcc19e9ee" @@ -3054,7 +3325,7 @@ find-up@^1.0.0: path-exists "^2.0.0" pinkie-promise "^2.0.0" -find-up@^2.0.0: +find-up@^2.0.0, find-up@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/find-up/-/find-up-2.1.0.tgz#45d1b7e506c717ddd482775a2b77920a3c0c57a7" dependencies: @@ -3132,7 +3403,7 @@ forever-agent@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" -form-data@~2.3.1: +form-data@~2.3.1, form-data@~2.3.2: version "2.3.2" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.2.tgz#4970498be604c20c005d4f5c23aecd21d6b49099" dependencies: @@ -3209,7 +3480,14 @@ fsevents@^1.0.0: nan "^2.9.2" node-pre-gyp "^0.9.0" -function-bind@^1.0.2: +fsevents@^1.2.3: + version "1.2.4" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.2.4.tgz#f41dcb1af2582af3692da36fc55cbd8e1041c426" + dependencies: + nan "^2.9.2" + node-pre-gyp "^0.10.0" + +function-bind@^1.0.2, function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -3542,6 +3820,12 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" +glob-promise@3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/glob-promise/-/glob-promise-3.4.0.tgz#b6b8f084504216f702dc2ce8c9bc9ac8866fdb20" + dependencies: + "@types/glob" "*" + glob-to-regexp@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/glob-to-regexp/-/glob-to-regexp-0.3.0.tgz#8c5a1494d2066c570cc3bfe4496175acc4d502ab" @@ -3715,6 +3999,10 @@ gray-percentage@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/gray-percentage/-/gray-percentage-2.0.0.tgz#b72a274d1b1379104a0050b63b207dc53fe56f99" +growly@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/growly/-/growly-1.3.0.tgz#f10748cbe76af964b7c96c93c6bcc28af120c081" + gzip-size@3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/gzip-size/-/gzip-size-3.0.0.tgz#546188e9bdc337f673772f81660464b389dce520" @@ -3731,6 +4019,16 @@ handlebars@4.0.11: optionalDependencies: uglify-js "^2.6" +handlebars@^4.0.3: + version "4.0.12" + resolved "https://registry.yarnpkg.com/handlebars/-/handlebars-4.0.12.tgz#2c15c8a96d46da5e266700518ba8cb8d919d5bc5" + dependencies: + async "^2.5.0" + optimist "^0.6.1" + source-map "^0.6.1" + optionalDependencies: + uglify-js "^3.1.4" + har-schema@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92" @@ -3742,6 +4040,13 @@ har-validator@~5.0.3: ajv "^5.1.0" har-schema "^2.0.0" +har-validator@~5.1.0: + version "5.1.0" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.1.0.tgz#44657f5688a22cfd4b72486e81b3a3fb11742c29" + dependencies: + ajv "^5.3.0" + har-schema "^2.0.0" + has-ansi@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" @@ -3964,6 +4269,12 @@ html-comment-regex@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/html-comment-regex/-/html-comment-regex-1.1.1.tgz#668b93776eaae55ebde8f3ad464b307a4963625e" +html-encoding-sniffer@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/html-encoding-sniffer/-/html-encoding-sniffer-1.0.2.tgz#e70d84b94da53aa375e11fe3a351be6642ca46f8" + dependencies: + whatwg-encoding "^1.0.1" + html-entities@^1.2.0: version "1.2.1" resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.1.tgz#0df29351f0721163515dfb9e5543e5f6eed5162f" @@ -4055,6 +4366,12 @@ iconv-lite@0.4.19: version "0.4.19" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b" +iconv-lite@0.4.23: + version "0.4.23" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.23.tgz#297871f63be507adcfbfca715d0cd0eed84e9a63" + dependencies: + safer-buffer ">= 2.1.2 < 3" + iconv-lite@^0.4.17, iconv-lite@^0.4.4, iconv-lite@~0.4.13: version "0.4.21" resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.21.tgz#c47f8733d02171189ebc4a400f3218d348094798" @@ -4083,6 +4400,13 @@ import-lazy@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/import-lazy/-/import-lazy-2.1.0.tgz#05698e3d45c88e8d7e9d92cb0584e77f096f3e43" +import-local@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/import-local/-/import-local-1.0.0.tgz#5e4ffdc03f4fe6c009c6729beb29631c2f8227bc" + dependencies: + pkg-dir "^2.0.0" + resolve-cwd "^2.0.0" + imurmurhash@^0.1.4: version "0.1.4" resolved "https://registry.yarnpkg.com/imurmurhash/-/imurmurhash-0.1.4.tgz#9218b9b2b928a238b13dc4fb6b6d576f231453ea" @@ -4148,7 +4472,7 @@ interpret@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.1.0.tgz#7ed1b1410c6a0e0f78cf95d3b8440c63f78b8614" -invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2: +invariant@^2.2.0, invariant@^2.2.1, invariant@^2.2.2, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" dependencies: @@ -4224,6 +4548,10 @@ is-builtin-module@^1.0.0: dependencies: builtin-modules "^1.0.0" +is-callable@^1.1.1, is-callable@^1.1.3: + version "1.1.4" + resolved "https://registry.yarnpkg.com/is-callable/-/is-callable-1.1.4.tgz#1e1adf219e1eeb684d691f9d6a05ff0d30a24d75" + is-ci@^1.0.10: version "1.1.0" resolved "https://registry.yarnpkg.com/is-ci/-/is-ci-1.1.0.tgz#247e4162e7860cebbdaf30b774d6b0ac7dcfe7a5" @@ -4242,6 +4570,10 @@ is-data-descriptor@^1.0.0: dependencies: kind-of "^6.0.0" +is-date-object@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-date-object/-/is-date-object-1.0.1.tgz#9aa20eb6aeebbff77fbd33e74ca01b33581d3a16" + is-decimal@^1.0.0: version "1.0.2" resolved "https://registry.yarnpkg.com/is-decimal/-/is-decimal-1.0.2.tgz#894662d6a8709d307f3a276ca4339c8fa5dff0ff" @@ -4306,6 +4638,10 @@ is-fullwidth-code-point@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz#a3b30a5c4f199183167aaab93beefae3ddfb654f" +is-generator-fn@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-generator-fn/-/is-generator-fn-1.0.0.tgz#969d49e1bb3329f6bb7f09089be26578b2ddd46a" + is-glob@^2.0.0, is-glob@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" @@ -4417,6 +4753,12 @@ is-redirect@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" +is-regex@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491" + dependencies: + has "^1.0.1" + is-relative-url@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/is-relative-url/-/is-relative-url-2.0.0.tgz#72902d7fe04b3d4792e7db15f9db84b7204c9cef" @@ -4453,6 +4795,10 @@ is-svg@^2.0.0: dependencies: html-comment-regex "^1.1.0" +is-symbol@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-symbol/-/is-symbol-1.0.1.tgz#3cc59f00025194b6ab2e38dbae6689256b660572" + is-typedarray@~1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" @@ -4544,6 +4890,69 @@ isstream@~0.1.2: version "0.1.2" resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" +istanbul-api@^1.3.1: + version "1.3.7" + resolved "https://registry.yarnpkg.com/istanbul-api/-/istanbul-api-1.3.7.tgz#a86c770d2b03e11e3f778cd7aedd82d2722092aa" + dependencies: + async "^2.1.4" + fileset "^2.0.2" + istanbul-lib-coverage "^1.2.1" + istanbul-lib-hook "^1.2.2" + istanbul-lib-instrument "^1.10.2" + istanbul-lib-report "^1.1.5" + istanbul-lib-source-maps "^1.2.6" + istanbul-reports "^1.5.1" + js-yaml "^3.7.0" + mkdirp "^0.5.1" + once "^1.4.0" + +istanbul-lib-coverage@^1.2.0, istanbul-lib-coverage@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/istanbul-lib-coverage/-/istanbul-lib-coverage-1.2.1.tgz#ccf7edcd0a0bb9b8f729feeb0930470f9af664f0" + +istanbul-lib-hook@^1.2.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-hook/-/istanbul-lib-hook-1.2.2.tgz#bc6bf07f12a641fbf1c85391d0daa8f0aea6bf86" + dependencies: + append-transform "^0.4.0" + +istanbul-lib-instrument@^1.10.1, istanbul-lib-instrument@^1.10.2: + version "1.10.2" + resolved "https://registry.yarnpkg.com/istanbul-lib-instrument/-/istanbul-lib-instrument-1.10.2.tgz#1f55ed10ac3c47f2bdddd5307935126754d0a9ca" + dependencies: + babel-generator "^6.18.0" + babel-template "^6.16.0" + babel-traverse "^6.18.0" + babel-types "^6.18.0" + babylon "^6.18.0" + istanbul-lib-coverage "^1.2.1" + semver "^5.3.0" + +istanbul-lib-report@^1.1.5: + version "1.1.5" + resolved "https://registry.yarnpkg.com/istanbul-lib-report/-/istanbul-lib-report-1.1.5.tgz#f2a657fc6282f96170aaf281eb30a458f7f4170c" + dependencies: + istanbul-lib-coverage "^1.2.1" + mkdirp "^0.5.1" + path-parse "^1.0.5" + supports-color "^3.1.2" + +istanbul-lib-source-maps@^1.2.4, istanbul-lib-source-maps@^1.2.6: + version "1.2.6" + resolved "https://registry.yarnpkg.com/istanbul-lib-source-maps/-/istanbul-lib-source-maps-1.2.6.tgz#37b9ff661580f8fca11232752ee42e08c6675d8f" + dependencies: + debug "^3.1.0" + istanbul-lib-coverage "^1.2.1" + mkdirp "^0.5.1" + rimraf "^2.6.1" + source-map "^0.5.3" + +istanbul-reports@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/istanbul-reports/-/istanbul-reports-1.5.1.tgz#97e4dbf3b515e8c484caea15d6524eebd3ff4e1a" + dependencies: + handlebars "^4.0.3" + isurl@^1.0.0-alpha5: version "1.0.0" resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" @@ -4559,61 +4968,393 @@ iterall@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/iterall/-/iterall-1.1.3.tgz#1cbbff96204056dde6656e2ed2e2226d0e6d72c9" -joi@12.x.x: - version "12.0.0" - resolved "https://registry.yarnpkg.com/joi/-/joi-12.0.0.tgz#46f55e68f4d9628f01bbb695902c8b307ad8d33a" +jest-changed-files@^23.4.2: + version "23.4.2" + resolved "https://registry.yarnpkg.com/jest-changed-files/-/jest-changed-files-23.4.2.tgz#1eed688370cd5eebafe4ae93d34bb3b64968fe83" dependencies: - hoek "4.x.x" - isemail "3.x.x" - topo "2.x.x" + throat "^4.0.0" -joi@9.0.0-0: - version "9.0.0-0" - resolved "https://registry.yarnpkg.com/joi/-/joi-9.0.0-0.tgz#a7ca4219602149ae0da7a7c5ca1d63d3c79e096b" +jest-cli@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-cli/-/jest-cli-23.6.0.tgz#61ab917744338f443ef2baa282ddffdd658a5da4" dependencies: - hoek "4.x.x" - isemail "2.x.x" - items "2.x.x" - moment "2.x.x" - topo "2.x.x" - -js-base64@^2.1.9: - version "2.4.3" - resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.3.tgz#2e545ec2b0f2957f41356510205214e98fad6582" + ansi-escapes "^3.0.0" + chalk "^2.0.1" + exit "^0.1.2" + glob "^7.1.2" + graceful-fs "^4.1.11" + import-local "^1.0.0" + is-ci "^1.0.10" + istanbul-api "^1.3.1" + istanbul-lib-coverage "^1.2.0" + istanbul-lib-instrument "^1.10.1" + istanbul-lib-source-maps "^1.2.4" + jest-changed-files "^23.4.2" + jest-config "^23.6.0" + jest-environment-jsdom "^23.4.0" + jest-get-type "^22.1.0" + jest-haste-map "^23.6.0" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + jest-resolve-dependencies "^23.6.0" + jest-runner "^23.6.0" + jest-runtime "^23.6.0" + jest-snapshot "^23.6.0" + jest-util "^23.4.0" + jest-validate "^23.6.0" + jest-watcher "^23.4.0" + jest-worker "^23.2.0" + micromatch "^2.3.11" + node-notifier "^5.2.1" + prompts "^0.1.9" + realpath-native "^1.0.0" + rimraf "^2.5.4" + slash "^1.0.0" + string-length "^2.0.0" + strip-ansi "^4.0.0" + which "^1.2.12" + yargs "^11.0.0" -js-tokens@^3.0.0, js-tokens@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" +jest-config@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-config/-/jest-config-23.6.0.tgz#f82546a90ade2d8c7026fbf6ac5207fc22f8eb1d" + dependencies: + babel-core "^6.0.0" + babel-jest "^23.6.0" + chalk "^2.0.1" + glob "^7.1.1" + jest-environment-jsdom "^23.4.0" + jest-environment-node "^23.4.0" + jest-get-type "^22.1.0" + jest-jasmine2 "^23.6.0" + jest-regex-util "^23.3.0" + jest-resolve "^23.6.0" + jest-util "^23.4.0" + jest-validate "^23.6.0" + micromatch "^2.3.11" + pretty-format "^23.6.0" -js-yaml@^3.10.0, js-yaml@^3.5.2: - version "3.11.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" +jest-diff@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-23.6.0.tgz#1500f3f16e850bb3d71233408089be099f610c7d" dependencies: - argparse "^1.0.7" - esprima "^4.0.0" + chalk "^2.0.1" + diff "^3.2.0" + jest-get-type "^22.1.0" + pretty-format "^23.6.0" -js-yaml@~3.7.0: - version "3.7.0" - resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80" +jest-docblock@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-docblock/-/jest-docblock-23.2.0.tgz#f085e1f18548d99fdd69b20207e6fd55d91383a7" dependencies: - argparse "^1.0.7" - esprima "^2.6.0" + detect-newline "^2.1.0" -jsan@^3.1.5, jsan@^3.1.9: - version "3.1.9" - resolved "https://registry.yarnpkg.com/jsan/-/jsan-3.1.9.tgz#2705676c1058f0a7d9ac266ad036a5769cfa7c96" +jest-each@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-each/-/jest-each-23.6.0.tgz#ba0c3a82a8054387016139c733a05242d3d71575" + dependencies: + chalk "^2.0.1" + pretty-format "^23.6.0" -jsbn@~0.1.0: - version "0.1.1" - resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" +jest-environment-jsdom@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-environment-jsdom/-/jest-environment-jsdom-23.4.0.tgz#056a7952b3fea513ac62a140a2c368c79d9e6023" + dependencies: + jest-mock "^23.2.0" + jest-util "^23.4.0" + jsdom "^11.5.1" -jsesc@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" +jest-environment-node@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-environment-node/-/jest-environment-node-23.4.0.tgz#57e80ed0841dea303167cce8cd79521debafde10" + dependencies: + jest-mock "^23.2.0" + jest-util "^23.4.0" -jsesc@~0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" +jest-get-type@^22.1.0: + version "22.4.3" + resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-22.4.3.tgz#e3a8504d8479342dd4420236b322869f18900ce4" + +jest-haste-map@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-haste-map/-/jest-haste-map-23.6.0.tgz#2e3eb997814ca696d62afdb3f2529f5bbc935e16" + dependencies: + fb-watchman "^2.0.0" + graceful-fs "^4.1.11" + invariant "^2.2.4" + jest-docblock "^23.2.0" + jest-serializer "^23.0.1" + jest-worker "^23.2.0" + micromatch "^2.3.11" + sane "^2.0.0" + +jest-jasmine2@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-jasmine2/-/jest-jasmine2-23.6.0.tgz#840e937f848a6c8638df24360ab869cc718592e0" + dependencies: + babel-traverse "^6.0.0" + chalk "^2.0.1" + co "^4.6.0" + expect "^23.6.0" + is-generator-fn "^1.0.0" + jest-diff "^23.6.0" + jest-each "^23.6.0" + jest-matcher-utils "^23.6.0" + jest-message-util "^23.4.0" + jest-snapshot "^23.6.0" + jest-util "^23.4.0" + pretty-format "^23.6.0" + +jest-leak-detector@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-leak-detector/-/jest-leak-detector-23.6.0.tgz#e4230fd42cf381a1a1971237ad56897de7e171de" + dependencies: + pretty-format "^23.6.0" + +jest-matcher-utils@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-23.6.0.tgz#726bcea0c5294261a7417afb6da3186b4b8cac80" + dependencies: + chalk "^2.0.1" + jest-get-type "^22.1.0" + pretty-format "^23.6.0" + +jest-message-util@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-message-util/-/jest-message-util-23.4.0.tgz#17610c50942349508d01a3d1e0bda2c079086a9f" + dependencies: + "@babel/code-frame" "^7.0.0-beta.35" + chalk "^2.0.1" + micromatch "^2.3.11" + slash "^1.0.0" + stack-utils "^1.0.1" + +jest-mock@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-mock/-/jest-mock-23.2.0.tgz#ad1c60f29e8719d47c26e1138098b6d18b261134" + +jest-regex-util@^23.3.0: + version "23.3.0" + resolved "https://registry.yarnpkg.com/jest-regex-util/-/jest-regex-util-23.3.0.tgz#5f86729547c2785c4002ceaa8f849fe8ca471bc5" + +jest-resolve-dependencies@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-resolve-dependencies/-/jest-resolve-dependencies-23.6.0.tgz#b4526af24c8540d9a3fab102c15081cf509b723d" + dependencies: + jest-regex-util "^23.3.0" + jest-snapshot "^23.6.0" + +jest-resolve@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-resolve/-/jest-resolve-23.6.0.tgz#cf1d1a24ce7ee7b23d661c33ba2150f3aebfa0ae" + dependencies: + browser-resolve "^1.11.3" + chalk "^2.0.1" + realpath-native "^1.0.0" + +jest-runner@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-runner/-/jest-runner-23.6.0.tgz#3894bd219ffc3f3cb94dc48a4170a2e6f23a5a38" + dependencies: + exit "^0.1.2" + graceful-fs "^4.1.11" + jest-config "^23.6.0" + jest-docblock "^23.2.0" + jest-haste-map "^23.6.0" + jest-jasmine2 "^23.6.0" + jest-leak-detector "^23.6.0" + jest-message-util "^23.4.0" + jest-runtime "^23.6.0" + jest-util "^23.4.0" + jest-worker "^23.2.0" + source-map-support "^0.5.6" + throat "^4.0.0" + +jest-runtime@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-runtime/-/jest-runtime-23.6.0.tgz#059e58c8ab445917cd0e0d84ac2ba68de8f23082" + dependencies: + babel-core "^6.0.0" + babel-plugin-istanbul "^4.1.6" + chalk "^2.0.1" + convert-source-map "^1.4.0" + exit "^0.1.2" + fast-json-stable-stringify "^2.0.0" + graceful-fs "^4.1.11" + jest-config "^23.6.0" + jest-haste-map "^23.6.0" + jest-message-util "^23.4.0" + jest-regex-util "^23.3.0" + jest-resolve "^23.6.0" + jest-snapshot "^23.6.0" + jest-util "^23.4.0" + jest-validate "^23.6.0" + micromatch "^2.3.11" + realpath-native "^1.0.0" + slash "^1.0.0" + strip-bom "3.0.0" + write-file-atomic "^2.1.0" + yargs "^11.0.0" + +jest-serializer@^23.0.1: + version "23.0.1" + resolved "https://registry.yarnpkg.com/jest-serializer/-/jest-serializer-23.0.1.tgz#a3776aeb311e90fe83fab9e533e85102bd164165" + +jest-snapshot@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-snapshot/-/jest-snapshot-23.6.0.tgz#f9c2625d1b18acda01ec2d2b826c0ce58a5aa17a" + dependencies: + babel-types "^6.0.0" + chalk "^2.0.1" + jest-diff "^23.6.0" + jest-matcher-utils "^23.6.0" + jest-message-util "^23.4.0" + jest-resolve "^23.6.0" + mkdirp "^0.5.1" + natural-compare "^1.4.0" + pretty-format "^23.6.0" + semver "^5.5.0" + +jest-util@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-util/-/jest-util-23.4.0.tgz#4d063cb927baf0a23831ff61bec2cbbf49793561" + dependencies: + callsites "^2.0.0" + chalk "^2.0.1" + graceful-fs "^4.1.11" + is-ci "^1.0.10" + jest-message-util "^23.4.0" + mkdirp "^0.5.1" + slash "^1.0.0" + source-map "^0.6.0" + +jest-validate@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest-validate/-/jest-validate-23.6.0.tgz#36761f99d1ed33fcd425b4e4c5595d62b6597474" + dependencies: + chalk "^2.0.1" + jest-get-type "^22.1.0" + leven "^2.1.0" + pretty-format "^23.6.0" + +jest-watcher@^23.4.0: + version "23.4.0" + resolved "https://registry.yarnpkg.com/jest-watcher/-/jest-watcher-23.4.0.tgz#d2e28ce74f8dad6c6afc922b92cabef6ed05c91c" + dependencies: + ansi-escapes "^3.0.0" + chalk "^2.0.1" + string-length "^2.0.0" + +jest-worker@^23.2.0: + version "23.2.0" + resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-23.2.0.tgz#faf706a8da36fae60eb26957257fa7b5d8ea02b9" + dependencies: + merge-stream "^1.0.1" + +jest@23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/jest/-/jest-23.6.0.tgz#ad5835e923ebf6e19e7a1d7529a432edfee7813d" + dependencies: + import-local "^1.0.0" + jest-cli "^23.6.0" + +joi@12.x.x: + version "12.0.0" + resolved "https://registry.yarnpkg.com/joi/-/joi-12.0.0.tgz#46f55e68f4d9628f01bbb695902c8b307ad8d33a" + dependencies: + hoek "4.x.x" + isemail "3.x.x" + topo "2.x.x" + +joi@9.0.0-0: + version "9.0.0-0" + resolved "https://registry.yarnpkg.com/joi/-/joi-9.0.0-0.tgz#a7ca4219602149ae0da7a7c5ca1d63d3c79e096b" + dependencies: + hoek "4.x.x" + isemail "2.x.x" + items "2.x.x" + moment "2.x.x" + topo "2.x.x" + +js-base64@^2.1.9: + version "2.4.3" + resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.3.tgz#2e545ec2b0f2957f41356510205214e98fad6582" + +js-tokens@^3.0.0, js-tokens@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.2.tgz#9866df395102130e38f7f996bceb65443209c25b" + +js-tokens@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499" + +js-yaml@^3.10.0, js-yaml@^3.5.2: + version "3.11.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.11.0.tgz#597c1a8bd57152f26d622ce4117851a51f5ebaef" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@^3.7.0: + version "3.12.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.12.0.tgz#eaed656ec8344f10f527c6bfa1b6e2244de167d1" + dependencies: + argparse "^1.0.7" + esprima "^4.0.0" + +js-yaml@~3.7.0: + version "3.7.0" + resolved "https://registry.yarnpkg.com/js-yaml/-/js-yaml-3.7.0.tgz#5c967ddd837a9bfdca5f2de84253abe8a1c03b80" + dependencies: + argparse "^1.0.7" + esprima "^2.6.0" + +jsan@^3.1.5, jsan@^3.1.9: + version "3.1.9" + resolved "https://registry.yarnpkg.com/jsan/-/jsan-3.1.9.tgz#2705676c1058f0a7d9ac266ad036a5769cfa7c96" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +jsdom@^11.5.1: + version "11.12.0" + resolved "https://registry.yarnpkg.com/jsdom/-/jsdom-11.12.0.tgz#1a80d40ddd378a1de59656e9e6dc5a3ba8657bc8" + dependencies: + abab "^2.0.0" + acorn "^5.5.3" + acorn-globals "^4.1.0" + array-equal "^1.0.0" + cssom ">= 0.3.2 < 0.4.0" + cssstyle "^1.0.0" + data-urls "^1.0.0" + domexception "^1.0.1" + escodegen "^1.9.1" + html-encoding-sniffer "^1.0.2" + left-pad "^1.3.0" + nwsapi "^2.0.7" + parse5 "4.0.0" + pn "^1.1.0" + request "^2.87.0" + request-promise-native "^1.0.5" + sax "^1.2.4" + symbol-tree "^3.2.2" + tough-cookie "^2.3.4" + w3c-hr-time "^1.0.1" + webidl-conversions "^4.0.2" + whatwg-encoding "^1.0.3" + whatwg-mimetype "^2.1.0" + whatwg-url "^6.4.1" + ws "^5.2.0" + xml-name-validator "^3.0.0" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" json-loader@^0.5.2: version "0.5.7" @@ -4747,6 +5488,10 @@ kind-of@^6.0.0, kind-of@^6.0.2: version "6.0.2" resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-6.0.2.tgz#01146b36a6218e64e58f3a8d66de5d7fc6f6d051" +kleur@^2.0.1: + version "2.0.2" + resolved "https://registry.yarnpkg.com/kleur/-/kleur-2.0.2.tgz#b704f4944d95e255d038f0cb05fb8a602c55a300" + latest-version@^3.0.0: version "3.1.0" resolved "https://registry.yarnpkg.com/latest-version/-/latest-version-3.1.0.tgz#a205383fea322b33b5ae3b18abee0dc2f356ee15" @@ -4763,10 +5508,21 @@ lcid@^1.0.0: dependencies: invert-kv "^1.0.0" -leven@2.1.0, leven@^2.0.0: +left-pad@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/left-pad/-/left-pad-1.3.0.tgz#5b8a3a7765dfe001261dde915589e782f8c94d1e" + +leven@2.1.0, leven@^2.0.0, leven@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + liftoff@^2.2.0: version "2.5.0" resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec" @@ -4935,6 +5691,10 @@ lodash.some@^4.4.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" +lodash.sortby@^4.7.0: + version "4.7.0" + resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" + lodash.template@^4.2.4: version "4.4.0" resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.4.0.tgz#e73a0385c8355591746e020b99679c690e68fba0" @@ -4960,7 +5720,7 @@ lodash@3.10.1: version "3.10.1" resolved "https://registry.yarnpkg.com/lodash/-/lodash-3.10.1.tgz#5bf45e8e49ba4189e17d482789dfd15bd140b7b6" -lodash@4, lodash@4.17.10, lodash@^4.0.0, lodash@^4.1.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.6.1: +lodash@4, lodash@4.17.10, lodash@^4.0.0, lodash@^4.1.0, lodash@^4.13.1, lodash@^4.14.0, lodash@^4.17.10, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.6.1: version "4.17.10" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.10.tgz#1b7793cf7259ea38fb3661d4d38b3260af8ae4e7" @@ -5180,6 +5940,12 @@ merge-descriptors@1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" +merge-stream@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-1.0.1.tgz#4041202d508a342ba00174008df0c251b8c135e1" + dependencies: + readable-stream "^2.0.1" + merge@^1.1.3, merge@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/merge/-/merge-1.2.0.tgz#7531e39d4949c281a66b8c5a6e0265e8b05894da" @@ -5221,7 +5987,7 @@ micromatch@^2.1.5, micromatch@^2.3.11, micromatch@^2.3.7: parse-glob "^3.0.4" regex-cache "^0.4.2" -micromatch@^3.0.3, micromatch@^3.0.4: +micromatch@^3.0.3, micromatch@^3.0.4, micromatch@^3.1.4: version "3.1.10" resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-3.1.10.tgz#70859bc95c9840952f359a068a3fc49f9ecfac23" dependencies: @@ -5250,12 +6016,22 @@ miller-rabin@^4.0.0: version "1.33.0" resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.33.0.tgz#a3492050a5cb9b63450541e39d9788d2272783db" +mime-db@~1.36.0: + version "1.36.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.36.0.tgz#5020478db3c7fe93aad7bbcc4dcf869c43363397" + mime-types@2.1.18, mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.18: version "2.1.18" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.18.tgz#6f323f60a83d11146f831ff11fd66e2fe5503bb8" dependencies: mime-db "~1.33.0" +mime-types@~2.1.19: + version "2.1.20" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.20.tgz#930cb719d571e903738520f8470911548ca2cc19" + dependencies: + mime-db "~1.36.0" + mime@1.3.x: version "1.3.6" resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.6.tgz#591d84d3653a6b0b4a3b9df8de5aa8108e72e5e0" @@ -5387,6 +6163,10 @@ nanomatch@^1.2.9: snapdragon "^0.8.1" to-regex "^3.0.1" +natural-compare@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" + ncp@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/ncp/-/ncp-2.0.0.tgz#195a21d6c46e361d2fb1281ba38b91e9df7bdbb3" @@ -5399,6 +6179,14 @@ needle@^2.2.0: iconv-lite "^0.4.4" sax "^1.2.4" +needle@^2.2.1: + version "2.2.3" + resolved "https://registry.yarnpkg.com/needle/-/needle-2.2.3.tgz#c1b04da378cd634d8befe2de965dc2cfb0fd65ca" + dependencies: + debug "^2.1.2" + iconv-lite "^0.4.4" + sax "^1.2.4" + negotiator@0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" @@ -5492,6 +6280,30 @@ node-libs-browser@^2.0.0: util "^0.10.3" vm-browserify "0.0.4" +node-notifier@^5.2.1: + version "5.2.1" + resolved "https://registry.yarnpkg.com/node-notifier/-/node-notifier-5.2.1.tgz#fa313dd08f5517db0e2502e5758d664ac69f9dea" + dependencies: + growly "^1.3.0" + semver "^5.4.1" + shellwords "^0.1.1" + which "^1.3.0" + +node-pre-gyp@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.10.3.tgz#3070040716afdc778747b61b6887bf78880b80fc" + dependencies: + detect-libc "^1.0.2" + mkdirp "^0.5.1" + needle "^2.2.1" + nopt "^4.0.1" + npm-packlist "^1.1.6" + npmlog "^4.0.2" + rc "^1.2.7" + rimraf "^2.6.1" + semver "^5.3.0" + tar "^4" + node-pre-gyp@^0.9.0: version "0.9.1" resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.9.1.tgz#f11c07516dd92f87199dbc7e1838eab7cd56c9e0" @@ -5605,10 +6417,18 @@ number-is-nan@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" +nwsapi@^2.0.7: + version "2.0.9" + resolved "https://registry.yarnpkg.com/nwsapi/-/nwsapi-2.0.9.tgz#77ac0cdfdcad52b6a1151a84e73254edc33ed016" + oauth-sign@~0.8.2: version "0.8.2" resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.9.0.tgz#47a7b016baa68b5fa0ecf3dee08a85c679ac6455" + object-assign@^4.0.1, object-assign@^4.1.0, object-assign@^4.1.1: version "4.1.1" resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" @@ -5625,6 +6445,10 @@ object-copy@^0.1.0: define-property "^0.2.5" kind-of "^3.0.3" +object-keys@^1.0.12: + version "1.0.12" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.12.tgz#09c53855377575310cca62f55bb334abff7b3ed2" + object-keys@^1.0.8: version "1.0.11" resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" @@ -5648,6 +6472,13 @@ object.defaults@^1.1.0: for-own "^1.0.0" isobject "^3.0.0" +object.getownpropertydescriptors@^2.0.3: + version "2.0.3" + resolved "https://registry.yarnpkg.com/object.getownpropertydescriptors/-/object.getownpropertydescriptors-2.0.3.tgz#8758c846f5b407adab0f236e0986f14b051caa16" + dependencies: + define-properties "^1.1.2" + es-abstract "^1.5.1" + object.map@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/object.map/-/object.map-1.0.1.tgz#cf83e59dc8fcc0ad5f4250e1f78b3b81bd801d37" @@ -5721,6 +6552,17 @@ optimist@^0.6.1, optimist@~0.6.0, optimist@~0.6.1: minimist "~0.0.1" wordwrap "~0.0.2" +optionator@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + original@>=0.0.5: version "1.0.0" resolved "https://registry.yarnpkg.com/original/-/original-1.0.0.tgz#9147f93fa1696d04be61e01bd50baeaca656bd3b" @@ -5853,6 +6695,17 @@ parse-entities@^1.0.2: is-decimal "^1.0.0" is-hexadecimal "^1.0.0" +parse-entities@^1.1.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/parse-entities/-/parse-entities-1.1.2.tgz#9eaf719b29dc3bd62246b4332009072e01527777" + dependencies: + character-entities "^1.0.0" + character-entities-legacy "^1.0.0" + character-reference-invalid "^1.0.0" + is-alphanumerical "^1.0.0" + is-decimal "^1.0.0" + is-hexadecimal "^1.0.0" + parse-filepath@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/parse-filepath/-/parse-filepath-1.0.2.tgz#a632127f53aaf3d15876f5872f3ffac763d6c891" @@ -5892,6 +6745,10 @@ parse-unit@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/parse-unit/-/parse-unit-1.0.1.tgz#7e1bb6d5bef3874c28e392526a2541170291eecf" +parse5@4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/parse5/-/parse5-4.0.0.tgz#6d78656e3da8d78b4ec0b906f7c08ef1dfe3f608" + parse5@^3.0.3: version "3.0.3" resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.3.tgz#042f792ffdd36851551cf4e9e066b3874ab45b5c" @@ -6051,6 +6908,12 @@ pkg-dir@^1.0.0: dependencies: find-up "^1.0.0" +pkg-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-2.0.0.tgz#f6d5d1109e19d63edf428e0bd57e12777615334b" + dependencies: + find-up "^2.1.0" + pkg-resolve@^0.1.7: version "0.1.14" resolved "https://registry.yarnpkg.com/pkg-resolve/-/pkg-resolve-0.1.14.tgz#329b2e76ccbb372e22e6a3a41cb30ab0457836ba" @@ -6065,6 +6928,10 @@ pleeease-filters@^3.0.0: onecolor "~2.4.0" postcss "^5.0.4" +pn@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/pn/-/pn-1.1.0.tgz#e2f4cef0e219f463c179ab37463e4e1ecdccbafb" + posix-character-classes@^0.1.0: version "0.1.1" resolved "https://registry.yarnpkg.com/posix-character-classes/-/posix-character-classes-0.1.1.tgz#01eac0fe3b5af71a2a6c02feabb8c1fef7e00eab" @@ -6571,6 +7438,10 @@ postcss@^6.0.1, postcss@^6.0.14: source-map "^0.6.1" supports-color "^5.3.0" +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + prepend-http@^1.0.0, prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" @@ -6594,7 +7465,14 @@ pretty-error@^2.1.1: renderkid "^2.0.1" utila "~0.4" -private@^0.1.6, private@^0.1.7: +pretty-format@^23.6.0: + version "23.6.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-23.6.0.tgz#5eaac8eeb6b33b987b7fe6097ea6a8a146ab5760" + dependencies: + ansi-regex "^3.0.0" + ansi-styles "^3.2.0" + +private@^0.1.6, private@^0.1.7, private@^0.1.8: version "0.1.8" resolved "https://registry.yarnpkg.com/private/-/private-0.1.8.tgz#2381edb3689f7a53d653190060fcf822d2f368ff" @@ -6622,6 +7500,13 @@ promise@^7.1.1: dependencies: asap "~2.0.3" +prompts@^0.1.9: + version "0.1.14" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-0.1.14.tgz#a8e15c612c5c9ec8f8111847df3337c9cbd443b2" + dependencies: + kleur "^2.0.1" + sisteransi "^0.1.1" + prop-types@^15.5.10, prop-types@^15.5.4, prop-types@^15.5.8: version "15.6.1" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.6.1.tgz#36644453564255ddda391191fb3a125cbdf654ca" @@ -6658,6 +7543,10 @@ pseudomap@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" +psl@^1.1.24: + version "1.1.29" + resolved "https://registry.yarnpkg.com/psl/-/psl-1.1.29.tgz#60f580d360170bb722a797cc704411e6da850c67" + public-encrypt@^4.0.0: version "4.0.2" resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.2.tgz#46eb9107206bf73489f8b85b69d91334c6610994" @@ -6687,6 +7576,10 @@ punycode@^1.2.4, punycode@^1.4.1: version "1.4.1" resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" +punycode@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-2.1.1.tgz#b58b010ac40c22c5657616c8d2c2c02c7bf479ec" + q@^1.1.2: version "1.5.1" resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" @@ -6695,6 +7588,10 @@ qs@6.5.1, qs@~6.5.1: version "6.5.1" resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8" +qs@~6.5.2: + version "6.5.2" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" + query-string@^4.1.0: version "4.3.4" resolved "https://registry.yarnpkg.com/query-string/-/query-string-4.3.4.tgz#bbb693b9ca915c232515b228b1a02b609043dbeb" @@ -6764,6 +7661,15 @@ rc@^1.0.1, rc@^1.1.6, rc@^1.1.7: minimist "^1.2.0" strip-json-comments "~2.0.1" +rc@^1.2.7: + version "1.2.8" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed" + dependencies: + deep-extend "^0.6.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + react-deep-force-update@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/react-deep-force-update/-/react-deep-force-update-2.1.1.tgz#8ea4263cd6455a050b37445b3f08fd839d86e909" @@ -6953,6 +7859,12 @@ readdirp@^2.0.0: readable-stream "^2.0.2" set-immediate-shim "^1.0.1" +realpath-native@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.0.2.tgz#cd51ce089b513b45cf9b1516c82989b51ccc6560" + dependencies: + util.promisify "^1.0.0" + rechoir@^0.6.2: version "0.6.2" resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.6.2.tgz#85204b54dba82d5742e28c96756ef43af50e3384" @@ -7162,6 +8074,26 @@ remark-parse@^4.0.0: vfile-location "^2.0.0" xtend "^4.0.1" +remark-parse@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/remark-parse/-/remark-parse-5.0.0.tgz#4c077f9e499044d1d5c13f80d7a98cf7b9285d95" + dependencies: + collapse-white-space "^1.0.2" + is-alphabetical "^1.0.0" + is-decimal "^1.0.0" + is-whitespace-character "^1.0.0" + is-word-character "^1.0.0" + markdown-escapes "^1.0.0" + parse-entities "^1.1.0" + repeat-string "^1.5.4" + state-toggle "^1.0.0" + trim "0.0.1" + trim-trailing-lines "^1.0.0" + unherit "^1.0.4" + unist-util-remove-position "^1.0.0" + vfile-location "^2.0.0" + xtend "^4.0.1" + remark-retext@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/remark-retext/-/remark-retext-3.1.0.tgz#1b3df2d49469c0d3596cad86e91503a8b600fdcc" @@ -7206,6 +8138,33 @@ remark-stringify@^4.0.0: unherit "^1.0.4" xtend "^4.0.1" +remark-stringify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/remark-stringify/-/remark-stringify-5.0.0.tgz#336d3a4d4a6a3390d933eeba62e8de4bd280afba" + dependencies: + ccount "^1.0.0" + is-alphanumeric "^1.0.0" + is-decimal "^1.0.0" + is-whitespace-character "^1.0.0" + longest-streak "^2.0.1" + markdown-escapes "^1.0.0" + markdown-table "^1.1.0" + mdast-util-compact "^1.0.0" + parse-entities "^1.0.2" + repeat-string "^1.5.4" + state-toggle "^1.0.0" + stringify-entities "^1.0.1" + unherit "^1.0.4" + xtend "^4.0.1" + +remark@9.0.0: + version "9.0.0" + resolved "https://registry.yarnpkg.com/remark/-/remark-9.0.0.tgz#c5cfa8ec535c73a67c4b0f12bfdbd3a67d8b2f60" + dependencies: + remark-parse "^5.0.0" + remark-stringify "^5.0.0" + unified "^6.0.0" + remark@^7.0.1: version "7.0.1" resolved "https://registry.yarnpkg.com/remark/-/remark-7.0.1.tgz#a5de4dacfabf0f60a49826ef24c479807f904bfb" @@ -7273,6 +8232,20 @@ replace-ext@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/replace-ext/-/replace-ext-1.0.0.tgz#de63128373fcbf7c3ccfa4de5a480c45a67958eb" +request-promise-core@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/request-promise-core/-/request-promise-core-1.1.1.tgz#3eee00b2c5aa83239cfb04c5700da36f81cd08b6" + dependencies: + lodash "^4.13.1" + +request-promise-native@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/request-promise-native/-/request-promise-native-1.0.5.tgz#5281770f68e0c9719e5163fd3fab482215f4fda5" + dependencies: + request-promise-core "1.1.1" + stealthy-require "^1.1.0" + tough-cookie ">=2.3.3" + request@^2.58.0, request@^2.67.0, request@^2.74.0: version "2.85.0" resolved "https://registry.yarnpkg.com/request/-/request-2.85.0.tgz#5a03615a47c61420b3eb99b7dba204f83603e1fa" @@ -7300,6 +8273,31 @@ request@^2.58.0, request@^2.67.0, request@^2.74.0: tunnel-agent "^0.6.0" uuid "^3.1.0" +request@^2.87.0: + version "2.88.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.88.0.tgz#9c2fca4f7d35b592efe57c7f0a55e81052124fef" + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.0" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.4.3" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" @@ -7348,6 +8346,10 @@ resolve-url@^0.2.1: version "0.2.1" resolved "https://registry.yarnpkg.com/resolve-url/-/resolve-url-0.2.1.tgz#2c637fe77c893afd2a663fe21aa9080068e2052a" +resolve@1.1.7: + version "1.1.7" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" + resolve@^1.1.6, resolve@^1.1.7: version "1.7.1" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.7.1.tgz#aadd656374fd298aee895bc026b8297418677fd3" @@ -7421,7 +8423,7 @@ rollup@^0.36.3: dependencies: source-map-support "^0.4.0" -rsvp@^3.0.13, rsvp@^3.0.18: +rsvp@^3.0.13, rsvp@^3.0.18, rsvp@^3.3.3: version "3.6.2" resolved "https://registry.yarnpkg.com/rsvp/-/rsvp-3.6.2.tgz#2e96491599a96cde1b515d5674a8f7a91452926a" @@ -7445,6 +8447,10 @@ safe-buffer@5.1.1, safe-buffer@^5.0.1, safe-buffer@^5.1.0, safe-buffer@^5.1.1, s version "5.1.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853" +safe-buffer@^5.1.2: + version "5.1.2" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.2.tgz#991ec69d296e0313747d59bdfd2b745c35f8828d" + safe-buffer@~5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" @@ -7455,7 +8461,7 @@ safe-regex@^1.1.0: dependencies: ret "~0.1.10" -safer-buffer@^2.1.0: +"safer-buffer@>= 2.1.2 < 3", safer-buffer@^2.1.0: version "2.1.2" resolved "https://registry.yarnpkg.com/safer-buffer/-/safer-buffer-2.1.2.tgz#44fa161b0187b9549dd84bb91802f9bd8385cd6a" @@ -7471,6 +8477,21 @@ sane@^1.3.3: walker "~1.0.5" watch "~0.10.0" +sane@^2.0.0: + version "2.5.2" + resolved "https://registry.yarnpkg.com/sane/-/sane-2.5.2.tgz#b4dc1861c21b427e929507a3e751e2a2cb8ab3fa" + dependencies: + anymatch "^2.0.0" + capture-exit "^1.2.0" + exec-sh "^0.2.0" + fb-watchman "^2.0.0" + micromatch "^3.1.4" + minimist "^1.1.1" + walker "~1.0.5" + watch "~0.18.0" + optionalDependencies: + fsevents "^1.2.3" + sanitize-html@^1.14.1: version "1.18.2" resolved "https://registry.yarnpkg.com/sanitize-html/-/sanitize-html-1.18.2.tgz#61877ba5a910327e42880a28803c2fbafa8e4642" @@ -7531,6 +8552,10 @@ semver@^4.3.3: version "4.3.6" resolved "https://registry.yarnpkg.com/semver/-/semver-4.3.6.tgz#300bc6e0e86374f7ba61068b5b1ecd57fc6532da" +semver@^5.4.1, semver@^5.5.0: + version "5.5.1" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" + send@0.16.2: version "0.16.2" resolved "https://registry.yarnpkg.com/send/-/send-0.16.2.tgz#6ecca1e0f8c156d141597559848df64730a6bbc1" @@ -7685,6 +8710,10 @@ shelljs@0.7.0: interpret "^1.0.0" rechoir "^0.6.2" +shellwords@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/shellwords/-/shellwords-0.1.1.tgz#d6b9181c1a48d397324c84871efbcfc73fc0654b" + shortid@^2.2.6: version "2.2.8" resolved "https://registry.yarnpkg.com/shortid/-/shortid-2.2.8.tgz#033b117d6a2e975804f6f0969dbe7d3d0b355131" @@ -7701,6 +8730,10 @@ signedsource@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/signedsource/-/signedsource-1.0.0.tgz#1ddace4981798f93bd833973803d80d52e93ad6a" +sisteransi@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/sisteransi/-/sisteransi-0.1.1.tgz#5431447d5f7d1675aac667ccd0b865a4994cb3ce" + slash@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" @@ -7842,6 +8875,13 @@ source-map-support@^0.4.0, source-map-support@^0.4.15: dependencies: source-map "^0.5.6" +source-map-support@^0.5.6: + version "0.5.9" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.9.tgz#41bc953b2534267ea2d605bccfa7bfa3111ced5f" + dependencies: + buffer-from "^1.0.0" + source-map "^0.6.0" + source-map-support@~0.2.8: version "0.2.10" resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.2.10.tgz#ea5a3900a1c1cb25096a0ae8cc5c2b4b10ded3dc" @@ -7872,7 +8912,7 @@ source-map@^0.5.3, source-map@^0.5.6, source-map@^0.5.7, source-map@~0.5.1, sour version "0.5.7" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc" -source-map@^0.6.1: +source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263" @@ -7955,6 +8995,10 @@ stack-trace@^0.0.10: version "0.0.10" resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0" +stack-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/stack-utils/-/stack-utils-1.0.1.tgz#d4f33ab54e8e38778b0ca5cfd3b3afb12db68620" + stackframe@^0.3.1: version "0.3.1" resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-0.3.1.tgz#33aa84f1177a5548c8935533cbfeb3420975f5a4" @@ -7992,6 +9036,10 @@ statuses@~1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.4.0.tgz#bb73d446da2796106efcc1b601a253d6c46bd087" +stealthy-require@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/stealthy-require/-/stealthy-require-1.1.1.tgz#35b09875b4ff49f26a777e509b3090a3226bf24b" + steno@^0.4.1: version "0.4.4" resolved "https://registry.yarnpkg.com/steno/-/steno-0.4.4.tgz#071105bdfc286e6615c0403c27e9d7b5dcb855cb" @@ -8023,6 +9071,13 @@ strict-uri-encode@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" +string-length@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" + dependencies: + astral-regex "^1.0.0" + strip-ansi "^4.0.0" + string-similarity@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/string-similarity/-/string-similarity-1.2.0.tgz#d75153cb383846318b7a39a8d9292bb4db4e9c30" @@ -8083,16 +9138,16 @@ strip-bom-string@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-bom-string/-/strip-bom-string-1.0.0.tgz#e5211e9224369fbb81d633a2f00044dc8cedad92" +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" + strip-bom@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" dependencies: is-utf8 "^0.2.0" -strip-bom@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" - strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" @@ -8111,7 +9166,7 @@ supports-color@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" -supports-color@^3.1.0, supports-color@^3.1.1, supports-color@^3.2.3: +supports-color@^3.1.0, supports-color@^3.1.1, supports-color@^3.1.2, supports-color@^3.2.3: version "3.2.3" resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" dependencies: @@ -8139,6 +9194,10 @@ symbol-observable@^1.0.2, symbol-observable@^1.0.3: version "1.2.0" resolved "https://registry.yarnpkg.com/symbol-observable/-/symbol-observable-1.2.0.tgz#c22688aed4eab3cdc2dfeacbb561660560a00804" +symbol-tree@^3.2.2: + version "3.2.2" + resolved "https://registry.yarnpkg.com/symbol-tree/-/symbol-tree-3.2.2.tgz#ae27db38f660a7ae2e1c3b7d1bc290819b8519e6" + symbol@^0.2.1: version "0.2.3" resolved "https://registry.yarnpkg.com/symbol/-/symbol-0.2.3.tgz#3b9873b8a901e47c6efe21526a3ac372ef28bbc7" @@ -8215,10 +9274,24 @@ term-size@^1.2.0: dependencies: execa "^0.7.0" +test-exclude@^4.2.1: + version "4.2.3" + resolved "https://registry.yarnpkg.com/test-exclude/-/test-exclude-4.2.3.tgz#a9a5e64474e4398339245a0a769ad7c2f4a97c20" + dependencies: + arrify "^1.0.1" + micromatch "^2.3.11" + object-assign "^4.1.0" + read-pkg-up "^1.0.1" + require-main-filename "^1.0.1" + text-table@0.2.0: version "0.2.0" resolved "https://registry.yarnpkg.com/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" +throat@^4.0.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/throat/-/throat-4.1.0.tgz#89037cbc92c56ab18926e6ba4cbb200e15672a6a" + through2@^2.0.1: version "2.0.3" resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" @@ -8300,12 +9373,25 @@ topo@2.x.x: dependencies: hoek "4.x.x" +tough-cookie@>=2.3.3, tough-cookie@^2.3.4, tough-cookie@~2.4.3: + version "2.4.3" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.4.3.tgz#53f36da3f47783b0925afa06ff9f3b165280f781" + dependencies: + psl "^1.1.24" + punycode "^1.4.1" + tough-cookie@~2.3.3: version "2.3.4" resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.4.tgz#ec60cee38ac675063ffc97a5c18970578ee83655" dependencies: punycode "^1.4.1" +tr46@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/tr46/-/tr46-1.0.1.tgz#a8b13fd6bfd2489519674ccde55ba3693b706d09" + dependencies: + punycode "^2.1.0" + traceur@0.0.105: version "0.0.105" resolved "https://registry.yarnpkg.com/traceur/-/traceur-0.0.105.tgz#5cf9dee83d6b77861c3d6c44d53859aed7ab0479" @@ -8354,6 +9440,12 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: version "0.14.5" resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + type-is@~1.6.15, type-is@~1.6.16: version "1.6.16" resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.16.tgz#f89ce341541c672b25ee7ae3c73dee3b2be50194" @@ -8394,6 +9486,13 @@ uglify-js@^2.6, uglify-js@^2.6.1: optionalDependencies: uglify-to-browserify "~1.0.0" +uglify-js@^3.1.4: + version "3.4.9" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-3.4.9.tgz#af02f180c1207d76432e473ed24a28f4a782bae3" + dependencies: + commander "~2.17.1" + source-map "~0.6.1" + uglify-js@~2.7.3: version "2.7.5" resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.7.5.tgz#4612c0c7baaee2ba7c487de4904ae122079f2ca8" @@ -8484,6 +9583,10 @@ unist-util-is@^2.0.0, unist-util-is@^2.1.1: version "2.1.1" resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.1.1.tgz#0c312629e3f960c66e931e812d3d80e77010947b" +unist-util-is@^2.1.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/unist-util-is/-/unist-util-is-2.1.2.tgz#1193fa8f2bfbbb82150633f3a8d2eb9a1c1d55db" + unist-util-modify-children@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/unist-util-modify-children/-/unist-util-modify-children-1.1.1.tgz#66d7e6a449e6f67220b976ab3cb8b5ebac39e51d" @@ -8516,6 +9619,18 @@ unist-util-visit-children@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/unist-util-visit-children/-/unist-util-visit-children-1.1.1.tgz#eba63b371116231181068837118b6e6e10ec8844" +unist-util-visit-parents@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/unist-util-visit-parents/-/unist-util-visit-parents-2.0.1.tgz#63fffc8929027bee04bfef7d2cce474f71cb6217" + dependencies: + unist-util-is "^2.1.2" + +unist-util-visit@1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.4.0.tgz#1cb763647186dc26f5e1df5db6bd1e48b3cc2fb1" + dependencies: + unist-util-visit-parents "^2.0.0" + unist-util-visit@^1.0.0, unist-util-visit@^1.1.0, unist-util-visit@^1.1.1: version "1.3.0" resolved "https://registry.yarnpkg.com/unist-util-visit/-/unist-util-visit-1.3.0.tgz#41ca7c82981fd1ce6c762aac397fc24e35711444" @@ -8626,6 +9741,13 @@ util-deprecate@^1.0.2, util-deprecate@~1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" +util.promisify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/util.promisify/-/util.promisify-1.0.0.tgz#440f7165a459c9a16dc145eb8e72f35687097030" + dependencies: + define-properties "^1.1.2" + object.getownpropertydescriptors "^2.0.3" + util@0.10.3, util@^0.10.3: version "0.10.3" resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" @@ -8648,6 +9770,10 @@ uuid@^3.0.0, uuid@^3.0.1, uuid@^3.1.0: version "3.2.1" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14" +uuid@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" + v8-compile-cache@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-1.1.2.tgz#8d32e4f16974654657e676e0e467a348e89b0dc4" @@ -8718,6 +9844,12 @@ vm-browserify@0.0.4: dependencies: indexof "0.0.1" +w3c-hr-time@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/w3c-hr-time/-/w3c-hr-time-1.0.1.tgz#82ac2bff63d950ea9e3189a58a65625fedf19045" + dependencies: + browser-process-hrtime "^0.1.2" + walker@~1.0.5: version "1.0.7" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" @@ -8734,6 +9866,13 @@ watch@~0.10.0: version "0.10.0" resolved "https://registry.yarnpkg.com/watch/-/watch-0.10.0.tgz#77798b2da0f9910d595f1ace5b0c2258521f21dc" +watch@~0.18.0: + version "0.18.0" + resolved "https://registry.yarnpkg.com/watch/-/watch-0.18.0.tgz#28095476c6df7c90c963138990c0a5423eb4b986" + dependencies: + exec-sh "^0.2.0" + minimist "^1.2.0" + watchpack@^0.2.1: version "0.2.9" resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-0.2.9.tgz#62eaa4ab5e5ba35fdfc018275626e3c0f5e3fb0b" @@ -8746,6 +9885,10 @@ web-namespaces@^1.0.0: version "1.1.2" resolved "https://registry.yarnpkg.com/web-namespaces/-/web-namespaces-1.1.2.tgz#c8dc267ab639505276bae19e129dbd6ae72b22b4" +webidl-conversions@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/webidl-conversions/-/webidl-conversions-4.0.2.tgz#a855980b1f0b6b359ba1d5d9fb39ae941faa63ad" + webpack-configurator@^0.3.0: version "0.3.1" resolved "https://registry.yarnpkg.com/webpack-configurator/-/webpack-configurator-0.3.1.tgz#d16802afa674101a0cbfa6fc344d415c9649540b" @@ -8873,10 +10016,36 @@ websocket-extensions@>=0.1.1: version "0.1.3" resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.3.tgz#5d2ff22977003ec687a4b87073dfbbac146ccf29" +whatwg-encoding@^1.0.1, whatwg-encoding@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/whatwg-encoding/-/whatwg-encoding-1.0.4.tgz#63fb016b7435b795d9025632c086a5209dbd2621" + dependencies: + iconv-lite "0.4.23" + whatwg-fetch@>=0.10.0: version "2.0.4" resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz#dde6a5df315f9d39991aa17621853d720b85566f" +whatwg-mimetype@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/whatwg-mimetype/-/whatwg-mimetype-2.1.0.tgz#f0f21d76cbba72362eb609dbed2a30cd17fcc7d4" + +whatwg-url@^6.4.1: + version "6.5.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-6.5.0.tgz#f2df02bff176fd65070df74ad5ccbb5a199965a8" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + +whatwg-url@^7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/whatwg-url/-/whatwg-url-7.0.0.tgz#fde926fa54a599f3adf82dff25a9f7be02dc6edd" + dependencies: + lodash.sortby "^4.7.0" + tr46 "^1.0.1" + webidl-conversions "^4.0.2" + when@^3.7.5: version "3.7.8" resolved "https://registry.yarnpkg.com/when/-/when-3.7.8.tgz#c7130b6a7ea04693e842cdc9e7a1f2aa39a39f82" @@ -8895,6 +10064,12 @@ which@^1.0.9, which@^1.1.1, which@^1.2.12, which@^1.2.14, which@^1.2.9: dependencies: isexe "^2.0.0" +which@^1.3.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" + dependencies: + isexe "^2.0.0" + wide-align@^1.1.0: version "1.1.2" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.2.tgz#571e0f1b0604636ebc0dfc21b0339bbe31341710" @@ -8923,6 +10098,10 @@ wordwrap@~0.0.2: version "0.0.3" resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.3.tgz#a3d5da6cd5c0bc0008d37234bbaf1bed63059107" +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + wrap-ansi@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" @@ -8934,7 +10113,7 @@ wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" -write-file-atomic@^2.0.0: +write-file-atomic@^2.0.0, write-file-atomic@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/write-file-atomic/-/write-file-atomic-2.3.0.tgz#1ff61575c2e2a4e8e510d6fa4e243cce183999ab" dependencies: @@ -8949,6 +10128,12 @@ ws@3.0.0: safe-buffer "~5.0.1" ultron "~1.1.0" +ws@^5.2.0: + version "5.2.2" + resolved "https://registry.yarnpkg.com/ws/-/ws-5.2.2.tgz#dffef14866b8e8dc9133582514d1befaf96e980f" + dependencies: + async-limiter "~1.0.0" + ws@~3.3.1: version "3.3.3" resolved "https://registry.yarnpkg.com/ws/-/ws-3.3.3.tgz#f1cf84fe2d5e901ebce94efaece785f187a228f2" @@ -8973,6 +10158,10 @@ xdg-basedir@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/xdg-basedir/-/xdg-basedir-3.0.0.tgz#496b2cc109eca8dbacfe2dc72b603c17c5870ad4" +xml-name-validator@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/xml-name-validator/-/xml-name-validator-3.0.0.tgz#6ae73e06de4d8c6e47f9fb181f78d648ad457c6a" + xmlhttprequest-ssl@~1.5.4: version "1.5.5" resolved "https://registry.yarnpkg.com/xmlhttprequest-ssl/-/xmlhttprequest-ssl-1.5.5.tgz#c2876b06168aadc40e57d97e81191ac8f4398b3e" @@ -9012,6 +10201,12 @@ yargs-parser@^7.0.0: dependencies: camelcase "^4.1.0" +yargs-parser@^9.0.2: + version "9.0.2" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-9.0.2.tgz#9ccf6a43460fe4ed40a9bb68f48d43b8a68cc077" + dependencies: + camelcase "^4.1.0" + yargs@4.7.1: version "4.7.1" resolved "https://registry.yarnpkg.com/yargs/-/yargs-4.7.1.tgz#e60432658a3387ff269c028eacde4a512e438dff" @@ -9030,6 +10225,23 @@ yargs@4.7.1: y18n "^3.2.1" yargs-parser "^2.4.0" +yargs@^11.0.0: + version "11.1.0" + resolved "http://registry.npmjs.org/yargs/-/yargs-11.1.0.tgz#90b869934ed6e871115ea2ff58b03f4724ed2d77" + dependencies: + cliui "^4.0.0" + decamelize "^1.1.1" + find-up "^2.1.0" + get-caller-file "^1.0.1" + os-locale "^2.0.0" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^2.0.0" + which-module "^2.0.0" + y18n "^3.2.1" + yargs-parser "^9.0.2" + yargs@^8.0.2: version "8.0.2" resolved "https://registry.yarnpkg.com/yargs/-/yargs-8.0.2.tgz#6299a9055b1cefc969ff7e79c1d918dceb22c360" diff --git a/server/sonar-web/src/main/js/apps/documentation/components/App.tsx b/server/sonar-web/src/main/js/apps/documentation/components/App.tsx index 848d860851c..55fa10d84c7 100644 --- a/server/sonar-web/src/main/js/apps/documentation/components/App.tsx +++ b/server/sonar-web/src/main/js/apps/documentation/components/App.tsx @@ -20,6 +20,8 @@ import * as React from 'react'; import Helmet from 'react-helmet'; import { Link } from 'react-router'; +import * as navigationTreeSonarQube from 'Docs/../static/SonarQubeNavigationTree.json'; +import * as navigationTreeSonarCloud from 'Docs/../static/SonarCloudNavigationTree.json'; import Sidebar from './Sidebar'; import getPages from '../pages'; import NotFound from '../../../app/components/NotFound'; @@ -27,6 +29,7 @@ import ScreenPositionHelper from '../../../components/common/ScreenPositionHelpe import DocMarkdownBlock from '../../../components/docs/DocMarkdownBlock'; import { translate } from '../../../helpers/l10n'; import { isSonarCloud } from '../../../helpers/system'; +import { DocsNavigationItem } from '../utils'; import '../styles.css'; interface Props { @@ -52,8 +55,11 @@ export default class App extends React.PureComponent { } render() { - const { splat = 'index' } = this.props.params; - const page = this.pages.find(p => p.relativeName === splat); + const tree = isSonarCloud() + ? ((navigationTreeSonarCloud as any).default as DocsNavigationItem[]) + : ((navigationTreeSonarQube as any).default as DocsNavigationItem[]); + const { splat = '' } = this.props.params; + const page = this.pages.find(p => p.url === '/' + splat); const mainTitle = translate('documentation.page'); if (!page) { @@ -71,7 +77,7 @@ export default class App extends React.PureComponent { return (
    - + {!isSonarCloud() && } @@ -85,7 +91,7 @@ export default class App extends React.PureComponent {

    {translate('documentation.page')}

    - +
    diff --git a/server/sonar-web/src/main/js/apps/documentation/components/Menu.tsx b/server/sonar-web/src/main/js/apps/documentation/components/Menu.tsx index e4763bf53d8..4db8919d7fb 100644 --- a/server/sonar-web/src/main/js/apps/documentation/components/Menu.tsx +++ b/server/sonar-web/src/main/js/apps/documentation/components/Menu.tsx @@ -18,59 +18,79 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import * as React from 'react'; -import { Link } from 'react-router'; -import * as classNames from 'classnames'; -import { sortBy } from 'lodash'; +import MenuBlock from './MenuBlock'; +import { MenuItem } from './MenuItem'; +import { MenuExternalLink } from './MenuExternalLink'; import { - getEntryChildren, DocumentationEntry, - activeOrChildrenActive, - getEntryRoot + DocsNavigationBlock, + getNodeFromUrl, + isDocsNavigationBlock, + isDocsNavigationExternalLink, + DocsNavigationItem } from '../utils'; -import OpenCloseIcon from '../../../components/icons-components/OpenCloseIcon'; interface Props { + navigation: DocsNavigationItem[]; pages: DocumentationEntry[]; splat: string; } -type EntryWithChildren = DocumentationEntry & { children?: DocumentationEntry[] }; +interface State { + openBlockTitle: string; +} -export default class Menu extends React.PureComponent { - getMenuEntriesHierarchy = (root?: string): EntryWithChildren[] => { - const topLevelEntries = getEntryChildren(this.props.pages, root); - return sortBy( - topLevelEntries.map(entry => { - const entryRoot = getEntryRoot(entry.relativeName); - const children = entryRoot !== '' ? this.getMenuEntriesHierarchy(entryRoot) : []; - return { ...entry, children }; - }), - entry => entry.order - ); - }; +export default class Menu extends React.PureComponent { + constructor(props: Props) { + super(props); + this.state = { + openBlockTitle: this.getOpenBlockFromLocation(this.props.splat) + }; + } - renderEntry = (entry: EntryWithChildren, depth: number): React.ReactNode => { - const active = entry.relativeName === this.props.splat; - const opened = activeOrChildrenActive(this.props.splat || '', entry); - const offset = 10 + 25 * depth; - const { children = [] } = entry; - return ( - - -

    - {children.length > 0 && } - {entry.title} -

    - - {opened && children.map(entry => this.renderEntry(entry, depth + 1))} -
    + componentWillReceiveProps(nextProps: Props) { + if (this.props.splat !== nextProps.splat) { + this.setState({ openBlockTitle: this.getOpenBlockFromLocation(nextProps.splat) }); + } + } + + getOpenBlockFromLocation(splat: string) { + const element = this.props.navigation.find( + item => isDocsNavigationBlock(item) && item.children.some(child => '/' + splat === child) ); + return element ? (element as DocsNavigationBlock).title : ''; + } + + toggleBlock = (title: string) => { + this.setState(state => ({ openBlockTitle: state.openBlockTitle === title ? '' : title })); }; render() { - return <>{this.getMenuEntriesHierarchy().map(entry => this.renderEntry(entry, 0))}; + return this.props.navigation.map(item => { + if (isDocsNavigationBlock(item)) { + return ( + + ); + } + if (isDocsNavigationExternalLink(item)) { + return ; + } + return ( + + ); + }); } } diff --git a/server/sonar-web/src/main/js/apps/documentation/components/MenuBlock.tsx b/server/sonar-web/src/main/js/apps/documentation/components/MenuBlock.tsx new file mode 100644 index 00000000000..fe48972206f --- /dev/null +++ b/server/sonar-web/src/main/js/apps/documentation/components/MenuBlock.tsx @@ -0,0 +1,58 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import { MenuItem } from './MenuItem'; +import { DocumentationEntry, DocsNavigationBlock, getNodeFromUrl } from '../utils'; +import OpenCloseIcon from '../../../components/icons-components/OpenCloseIcon'; + +interface Props { + block: DocsNavigationBlock; + onToggle: (title: string) => void; + open: boolean; + pages: DocumentationEntry[]; + splat: string; + title: string; +} + +export default class MenuBlock extends React.PureComponent { + handleClick = (event: React.MouseEvent) => { + event.stopPropagation(); + event.preventDefault(); + this.props.onToggle(this.props.title); + }; + + render() { + const { open, block, pages, title, splat } = this.props; + return ( + <> +
    +

    + + {title} +

    +
    + {open && + block.children.map(item => ( + + ))} + + ); + } +} diff --git a/server/sonar-web/src/main/js/apps/documentation/components/MenuExternalLink.tsx b/server/sonar-web/src/main/js/apps/documentation/components/MenuExternalLink.tsx new file mode 100644 index 00000000000..f15066598ec --- /dev/null +++ b/server/sonar-web/src/main/js/apps/documentation/components/MenuExternalLink.tsx @@ -0,0 +1,37 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import DetachIcon from '../../../components/icons-components/DetachIcon'; + +interface Props { + title: string; + url: string; +} + +export function MenuExternalLink({ title, url }: Props) { + return ( + +

    + + {title} +

    +
    + ); +} diff --git a/server/sonar-web/src/main/js/apps/documentation/components/MenuItem.tsx b/server/sonar-web/src/main/js/apps/documentation/components/MenuItem.tsx new file mode 100644 index 00000000000..0b67f4d7045 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/documentation/components/MenuItem.tsx @@ -0,0 +1,46 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import * as classNames from 'classnames'; +import { Link } from 'react-router'; +import { DocumentationEntry } from '../utils'; + +interface Props { + indent: boolean; + node: DocumentationEntry | undefined; + splat: string; +} + +export function MenuItem({ indent, node, splat }: Props) { + if (!node) { + return null; + } + + const active = node.url === '/' + splat; + return ( + +

    {node.title}

    + + ); +} diff --git a/server/sonar-web/src/main/js/apps/documentation/components/SearchResultEntry.tsx b/server/sonar-web/src/main/js/apps/documentation/components/SearchResultEntry.tsx index 436dfb56e95..094b45410a9 100644 --- a/server/sonar-web/src/main/js/apps/documentation/components/SearchResultEntry.tsx +++ b/server/sonar-web/src/main/js/apps/documentation/components/SearchResultEntry.tsx @@ -37,7 +37,7 @@ export default function SearchResultEntry({ active, result }: Props) { return ( + to={'/documentation' + result.page.url}> diff --git a/server/sonar-web/src/main/js/apps/documentation/components/SearchResults.tsx b/server/sonar-web/src/main/js/apps/documentation/components/SearchResults.tsx index b42ba425fd9..2beeb11b9f9 100644 --- a/server/sonar-web/src/main/js/apps/documentation/components/SearchResults.tsx +++ b/server/sonar-web/src/main/js/apps/documentation/components/SearchResults.tsx @@ -21,9 +21,10 @@ import * as React from 'react'; import lunr, { LunrIndex } from 'lunr'; import { sortBy } from 'lodash'; import SearchResultEntry, { SearchResult } from './SearchResultEntry'; -import { DocumentationEntry } from '../utils'; +import { DocumentationEntry, getUrlsList, DocsNavigationItem } from '../utils'; interface Props { + navigation: DocsNavigationItem[]; pages: DocumentationEntry[]; query: string; splat: string; @@ -41,7 +42,9 @@ export default class SearchResults extends React.PureComponent { this.metadataWhitelist = ['position']; - props.pages.forEach(page => this.add(page)); + props.pages + .filter(page => getUrlsList(props.navigation).includes(page.url)) + .forEach(page => this.add(page)); }); } diff --git a/server/sonar-web/src/main/js/apps/documentation/components/Sidebar.tsx b/server/sonar-web/src/main/js/apps/documentation/components/Sidebar.tsx index 43c3802a680..9374eee9943 100644 --- a/server/sonar-web/src/main/js/apps/documentation/components/Sidebar.tsx +++ b/server/sonar-web/src/main/js/apps/documentation/components/Sidebar.tsx @@ -20,10 +20,11 @@ import * as React from 'react'; import Menu from './Menu'; import SearchResults from './SearchResults'; -import { DocumentationEntry } from '../utils'; +import { DocumentationEntry, DocsNavigationItem } from '../utils'; import SearchBox from '../../../components/controls/SearchBox'; interface Props { + navigation: DocsNavigationItem[]; pages: DocumentationEntry[]; splat: string; } @@ -53,12 +54,17 @@ export default class Sidebar extends React.PureComponent {
    {this.state.query ? ( ) : ( - + )}
    diff --git a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/Menu-test.tsx b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/Menu-test.tsx index 2f71253a2d3..1985bc439f6 100644 --- a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/Menu-test.tsx +++ b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/Menu-test.tsx @@ -22,7 +22,7 @@ import { shallow } from 'enzyme'; import Menu from '../Menu'; function createPage(title: string, relativeName: string, text = '') { - return { relativeName, title, order: -1, text, content: text }; + return { relativeName, url: '/' + relativeName, title, text, content: text }; } const pages = [ @@ -44,5 +44,13 @@ const pages = [ ]; it('should render hierarchical menu', () => { - expect(shallow()).toMatchSnapshot(); + expect( + shallow( + + ) + ).toMatchSnapshot(); }); diff --git a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/MenuBlock-test.tsx b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/MenuBlock-test.tsx new file mode 100644 index 00000000000..9dcfe468335 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/MenuBlock-test.tsx @@ -0,0 +1,74 @@ +/* + * SonarQube + * Copyright (C) 2009-2018 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as React from 'react'; +import { shallow } from 'enzyme'; +import MenuBlock from '../MenuBlock'; + +const block = { + title: 'Foo', + children: ['/bar/', '/baz/'] +}; + +const pages = [ + { + content: 'bar', + relativeName: '/bar/', + text: 'bar', + title: 'Bar', + url: '/bar/' + }, + { + content: 'baz', + relativeName: '/baz/', + text: 'baz', + title: 'baz', + url: '/baz/' + } +]; + +it('should render a closed menu block', () => { + expect( + shallow( + + ) + ).toMatchSnapshot(); +}); + +it('should render an opened menu block', () => { + expect( + shallow( + + ) + ).toMatchSnapshot(); +}); diff --git a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/SearchResultEntry-test.tsx b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/SearchResultEntry-test.tsx index 6785fd66bf8..f38330cb585 100644 --- a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/SearchResultEntry-test.tsx +++ b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/SearchResultEntry-test.tsx @@ -27,8 +27,8 @@ import SearchResultEntry, { const page = { content: '', - order: -1, relativeName: 'foo/bar', + url: '/foo/bar', text: 'Foobar is a universal variable understood to represent whatever is being discussed.', title: 'Foobar' }; diff --git a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/SearchResults-test.tsx b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/SearchResults-test.tsx index d4151e45220..be38eb5a2f6 100644 --- a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/SearchResults-test.tsx +++ b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/SearchResults-test.tsx @@ -37,7 +37,7 @@ jest.mock('lunr', () => ({ })); function createPage(title: string, relativeName: string, text = '') { - return { relativeName, title, order: -1, text, content: text }; + return { relativeName, url: '/' + relativeName, title, text, content: text }; } const pages = [ @@ -59,7 +59,14 @@ const pages = [ ]; it('should search', () => { - const wrapper = shallow(); + const wrapper = shallow( + + ); expect(wrapper).toMatchSnapshot(); expect(lunr).toBeCalled(); expect((wrapper.instance() as SearchResults).index.search).toBeCalledWith('from~1 from*'); diff --git a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/Sidebar-test.tsx b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/Sidebar-test.tsx index 6fc596b466f..ab41a1a9afe 100644 --- a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/Sidebar-test.tsx +++ b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/Sidebar-test.tsx @@ -22,7 +22,7 @@ import { shallow } from 'enzyme'; import Sidebar from '../Sidebar'; function createPage(title: string, relativeName: string, text = '') { - return { relativeName, title, order: -1, text, content: text }; + return { relativeName, url: '/' + relativeName, title, text, content: text }; } const pages = [ @@ -31,11 +31,25 @@ const pages = [ ]; it('should render menu', () => { - expect(shallow()).toMatchSnapshot(); + expect( + shallow( + + ) + ).toMatchSnapshot(); }); it('should search', () => { - const wrapper = shallow(); + const wrapper = shallow( + + ); wrapper.find('SearchBox').prop('onChange')('foo'); wrapper.update(); expect(wrapper).toMatchSnapshot(); diff --git a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/Menu-test.tsx.snap b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/Menu-test.tsx.snap index dbc7ad1e5a0..469a3f41a6d 100644 --- a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/Menu-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/Menu-test.tsx.snap @@ -1,70 +1,52 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[`should render hierarchical menu 1`] = ` - - - -

    - - Lorem Ipsum -

    - - - -

    - Where does it come from? -

    - -
    -
    - - -

    - Where does Foobar come from? -

    - -
    -
    + "content": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.", + "relativeName": "lorem/index", + "text": "Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book.", + "title": "Lorem Ipsum", + "url": "/lorem/index", + }, + Object { + "content": "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words.", + "relativeName": "lorem/origin", + "text": "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words.", + "title": "Where does it come from?", + "url": "/lorem/origin", + }, + Object { + "content": "Foobar is a universal variable understood to represent whatever is being discussed.", + "relativeName": "foobar", + "text": "Foobar is a universal variable understood to represent whatever is being discussed.", + "title": "Where does Foobar come from?", + "url": "/foobar", + }, + ] + } + splat="lorem/origin" + title="Block" + />, + , +] `; diff --git a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/MenuBlock-test.tsx.snap b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/MenuBlock-test.tsx.snap new file mode 100644 index 00000000000..bdf2bad1314 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/MenuBlock-test.tsx.snap @@ -0,0 +1,69 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`should render a closed menu block 1`] = ` + + +

    + + Foobarbaz +

    +
    +
    +`; + +exports[`should render an opened menu block 1`] = ` + + +

    + + Foo +

    +
    + + +
    +`; diff --git a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/SearchResultEntry-test.tsx.snap b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/SearchResultEntry-test.tsx.snap index 3be4c54be97..6dd40778630 100644 --- a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/SearchResultEntry-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/SearchResultEntry-test.tsx.snap @@ -14,10 +14,10 @@ exports[`SearchResultEntry should render 1`] = ` "longestTerm": "", "page": Object { "content": "", - "order": -1, "relativeName": "foo/bar", "text": "Foobar is a universal variable understood to represent whatever is being discussed.", "title": "Foobar", + "url": "/foo/bar", }, } } @@ -29,10 +29,10 @@ exports[`SearchResultEntry should render 1`] = ` "longestTerm": "", "page": Object { "content": "", - "order": -1, "relativeName": "foo/bar", "text": "Foobar is a universal variable understood to represent whatever is being discussed.", "title": "Foobar", + "url": "/foo/bar", }, } } diff --git a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/SearchResults-test.tsx.snap b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/SearchResults-test.tsx.snap index cc6081342c8..d9e4c0dd961 100644 --- a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/SearchResults-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/SearchResults-test.tsx.snap @@ -24,10 +24,10 @@ exports[`should search 1`] = ` "longestTerm": "from", "page": Object { "content": "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words.", - "order": -1, "relativeName": "lorem/origin", "text": "Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words.", "title": "Where does it come from?", + "url": "/lorem/origin", }, } } @@ -48,10 +48,10 @@ exports[`should search 1`] = ` "longestTerm": "from", "page": Object { "content": "Foobar is a universal variable understood to represent whatever is being discussed.", - "order": -1, "relativeName": "foobar", "text": "Foobar is a universal variable understood to represent whatever is being discussed.", "title": "Where does Foobar come from?", + "url": "/foobar", }, } } diff --git a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/Sidebar-test.tsx.snap b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/Sidebar-test.tsx.snap index c03a4b3469c..422bf65f9c0 100644 --- a/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/Sidebar-test.tsx.snap +++ b/server/sonar-web/src/main/js/apps/documentation/components/__tests__/__snapshots__/Sidebar-test.tsx.snap @@ -16,21 +16,32 @@ exports[`should render menu 1`] = ` className="list-group" > { - const remark = require.requireActual('remark'); - return { default: remark }; -}); - -jest.mock('unist-util-visit', () => { - const exp = require.requireActual('unist-util-visit'); - return { default: exp }; -}); - -jest.mock('../../documentation.directory-loader', () => [ - { - path: 'all', - content: ` - --- - title: All - --- - - all all all` - }, - { - path: 'sonarqube-foo', - content: ` - --- - title: Foo - scope: sonarqube - --- - - foo foo foo` - }, - { - path: 'sonarcloud-bar', - content: ` - --- - title: Bar - scope: sonarcloud - --- - - bar bar bar` - }, - { - path: 'static-baz', - content: ` - --- - title: Baz - scope: static - --- - - baz baz baz` - } -]); - -jest.mock('../../../../helpers/system', () => ({ isSonarCloud: jest.fn() })); - -it('should filter pages for SonarQube', () => { - (isSonarCloud as jest.Mock).mockReturnValue(false); - expect(getPages().map(page => page.title)).toEqual(['All', 'Foo']); -}); - -it('should filter pages for SonarCloud', () => { - (isSonarCloud as jest.Mock).mockReturnValue(true); - expect(getPages().map(page => page.title)).toEqual(['All', 'Bar']); -}); diff --git a/server/sonar-web/src/main/js/apps/documentation/pages.ts b/server/sonar-web/src/main/js/apps/documentation/pages.ts index e377c21151c..898f70b1bef 100644 --- a/server/sonar-web/src/main/js/apps/documentation/pages.ts +++ b/server/sonar-web/src/main/js/apps/documentation/pages.ts @@ -22,7 +22,6 @@ import visit from 'unist-util-visit'; import { DocumentationEntry, DocumentationEntryScope } from './utils'; import * as Docs from './documentation.directory-loader'; import { separateFrontMatter, filterContent } from '../../helpers/markdown'; -import { isSonarCloud } from '../../helpers/system'; export default function getPages(): DocumentationEntry[] { return Docs.map((file: any) => { @@ -32,6 +31,7 @@ export default function getPages(): DocumentationEntry[] { return { relativeName: file.path, + url: parsed.frontmatter.url || `/${file.path}`, title: parsed.frontmatter.title, order: Number(parsed.frontmatter.order || -1), scope: parsed.frontmatter.scope @@ -40,11 +40,6 @@ export default function getPages(): DocumentationEntry[] { text, content: file.content }; - }).filter((page: DocumentationEntry) => { - if (!page.scope) { - return true; - } - return isSonarCloud() ? page.scope === 'sonarcloud' : page.scope === 'sonarqube'; }); } diff --git a/server/sonar-web/src/main/js/apps/documentation/utils.ts b/server/sonar-web/src/main/js/apps/documentation/utils.ts index 64ed6457367..3c08b6a26b4 100644 --- a/server/sonar-web/src/main/js/apps/documentation/utils.ts +++ b/server/sonar-web/src/main/js/apps/documentation/utils.ts @@ -17,42 +17,53 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ -import { sortBy } from 'lodash'; +import { sortBy, flatten } from 'lodash'; export type DocumentationEntryScope = 'sonarqube' | 'sonarcloud' | 'static'; +export interface DocsNavigationBlock { + title: string; + children: string[]; +} + +export interface DocsNavigationExternalLink { + title: string; + url: string; +} + export interface DocumentationEntry { content: string; - order: number; relativeName: string; - scope?: DocumentationEntryScope; text: string; title: string; + url: string; } -export function activeOrChildrenActive(root: string, entry: DocumentationEntry) { - return root.indexOf(getEntryRoot(entry.relativeName)) === 0; +export type DocsNavigationItem = string | DocsNavigationBlock | DocsNavigationExternalLink; + +export function isDocsNavigationBlock(item: DocsNavigationItem): item is DocsNavigationBlock { + return typeof item === 'object' && !(item as any).url; } -export function getEntryRoot(name: string) { - if (name.endsWith('index')) { - return name - .split('/') - .slice(0, -1) - .join('/'); - } - return name; +export function isDocsNavigationExternalLink( + item: DocsNavigationItem +): item is DocsNavigationExternalLink { + return typeof item === 'object' && (item as any).url; +} + +export function getUrlsList(navigation: DocsNavigationItem[]): string[] { + return flatten( + navigation + .filter(item => !isDocsNavigationExternalLink(item)) + .map( + (item: string | DocsNavigationBlock) => + isDocsNavigationBlock(item) ? item.children : [item] + ) + ); } -export function getEntryChildren(entries: DocumentationEntry[], root?: string) { - return entries.filter(entry => { - const parts = entry.relativeName.split('/'); - const depth = root ? root.split('/').length : 0; - return ( - (!root || entry.relativeName.indexOf(root) === 0) && - ((parts.length === depth + 1 && parts[depth] !== 'index') || parts[depth + 1] === 'index') - ); - }); +export function getNodeFromUrl(pages: DocumentationEntry[], url: string) { + return pages.find(p => p.url === url); } const WORDS = 6; diff --git a/server/sonar-web/src/main/js/components/docs/__tests__/DocMarkdownBlock-test.tsx b/server/sonar-web/src/main/js/components/docs/__tests__/DocMarkdownBlock-test.tsx index 64944d0496a..303e048e85b 100644 --- a/server/sonar-web/src/main/js/components/docs/__tests__/DocMarkdownBlock-test.tsx +++ b/server/sonar-web/src/main/js/components/docs/__tests__/DocMarkdownBlock-test.tsx @@ -33,7 +33,10 @@ jest.mock('remark-react', () => { return { default: remarkReact }; }); -jest.mock('../../../helpers/system', () => ({ isSonarCloud: jest.fn() })); +jest.mock('../../../helpers/system', () => ({ + getInstance: jest.fn(), + isSonarCloud: jest.fn() +})); it('should render simple markdown', () => { expect(shallow()).toMatchSnapshot(); diff --git a/server/sonar-web/src/main/js/helpers/markdown.js b/server/sonar-web/src/main/js/helpers/markdown.js index 633c3450289..b41e590fcad 100644 --- a/server/sonar-web/src/main/js/helpers/markdown.js +++ b/server/sonar-web/src/main/js/helpers/markdown.js @@ -72,8 +72,9 @@ function parseFrontMatter(lines) { * @returns {string} */ function filterContent(content) { - const { isSonarCloud } = require('./system'); - const contentWithoutStatic = cutConditionalContent(content, 'static'); + const { isSonarCloud, getInstance } = require('./system'); + const contentWithInstance = content.replace('{instance}', getInstance()); + const contentWithoutStatic = cutConditionalContent(contentWithInstance, 'static'); return isSonarCloud() ? cutConditionalContent(contentWithoutStatic, 'sonarqube') : cutConditionalContent(contentWithoutStatic, 'sonarcloud'); -- 2.39.5