From 59eb8ea29908eba3d5b43489c59fb6af0aaea9cb Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Wed, 24 Nov 2021 18:35:15 +0000 Subject: [PATCH 01/46] chore(NA): bump chromedriver to v96 (#119625) --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index c33ca8e8db385..a5667f7203ba2 100644 --- a/package.json +++ b/package.json @@ -668,7 +668,7 @@ "callsites": "^3.1.0", "chai": "3.5.0", "chance": "1.0.18", - "chromedriver": "^95.0.0", + "chromedriver": "^96.0.0", "clean-webpack-plugin": "^3.0.0", "cmd-shim": "^2.1.0", "compression-webpack-plugin": "^4.0.0", diff --git a/yarn.lock b/yarn.lock index 6c8ccfdd42e97..618664c9c9523 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9779,10 +9779,10 @@ chrome-trace-event@^1.0.2: dependencies: tslib "^1.9.0" -chromedriver@^95.0.0: - version "95.0.0" - resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-95.0.0.tgz#ecf854cac6df5137a651dcc132edf55612d3db7f" - integrity sha512-HwSg7S0ZZYsHTjULwxFHrrUqEpz1+ljDudJM3eOquvqD5QKnR5pSe/GlBTY9UU2tVFRYz8bEHYC4Y8qxciQiLQ== +chromedriver@^96.0.0: + version "96.0.0" + resolved "https://registry.yarnpkg.com/chromedriver/-/chromedriver-96.0.0.tgz#c8473498e4c94950fa168187b112019cce9e5c6c" + integrity sha512-4g6Hn5RHGsbaBmOrJbDlz/hdVPOc22eRsbvoAAMqkZxR2NJCcddHzCw2FAQeW8lX/C7xWVz3nyDsKX3fE9lIIw== dependencies: "@testim/chrome-version" "^1.0.7" axios "^0.21.2" From ac23dce29f07f0539eb8d3f0968ac36441729207 Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 24 Nov 2021 11:46:32 -0800 Subject: [PATCH 02/46] [storybook] upgrade to 6.3.x (#119498) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- package.json | 34 +- .../basic_optimization.test.ts.snap | 2 +- packages/kbn-storybook/BUILD.bazel | 3 + .../kbn-storybook/src/lib/default_config.ts | 5 +- .../kbn-storybook/src/lib/theme_switcher.tsx | 29 +- packages/kbn-storybook/src/typings.ts | 24 + packages/kbn-storybook/templates/index.ejs | 28 +- .../kbn-ui-shared-deps-npm/webpack.config.js | 1 + .../public/__stories__/wait_for.tsx | 3 +- typings/index.d.ts | 24 + x-pack/plugins/fleet/storybook/preview.tsx | 2 +- yarn.lock | 2356 ++++++++--------- 12 files changed, 1192 insertions(+), 1319 deletions(-) diff --git a/package.json b/package.json index a5667f7203ba2..81c6696b019f9 100644 --- a/package.json +++ b/package.json @@ -74,6 +74,7 @@ "yarn": "^1.21.1" }, "resolutions": { + "**/@babel/runtime": "^7.16.3", "**/@types/node": "16.10.2", "**/chokidar": "^3.4.3", "**/deepmerge": "^4.2.2", @@ -469,21 +470,22 @@ "@microsoft/api-extractor": "7.18.19", "@octokit/rest": "^16.35.0", "@percy/agent": "^0.28.6", - "@storybook/addon-a11y": "^6.1.20", - "@storybook/addon-actions": "^6.1.20", - "@storybook/addon-docs": "^6.1.20", - "@storybook/addon-essentials": "^6.1.20", - "@storybook/addon-knobs": "^6.1.20", - "@storybook/addon-storyshots": "^6.1.20", - "@storybook/addons": "^6.1.20", - "@storybook/api": "^6.1.20", - "@storybook/components": "^6.1.20", - "@storybook/core": "^6.1.20", - "@storybook/core-events": "^6.1.20", - "@storybook/node-logger": "^6.1.20", - "@storybook/react": "^6.1.20", - "@storybook/testing-react": "^0.0.17", - "@storybook/theming": "^6.1.20", + "@storybook/addon-a11y": "^6.3.12", + "@storybook/addon-actions": "^6.3.12", + "@storybook/addon-docs": "^6.3.12", + "@storybook/addon-essentials": "^6.3.12", + "@storybook/addon-knobs": "^6.3.1", + "@storybook/addon-storyshots": "^6.3.12", + "@storybook/addons": "^6.3.12", + "@storybook/api": "^6.3.12", + "@storybook/components": "^6.3.12", + "@storybook/core": "^6.3.12", + "@storybook/core-common": "^6.3.12", + "@storybook/core-events": "^6.3.12", + "@storybook/node-logger": "^6.3.12", + "@storybook/react": "^6.3.12", + "@storybook/testing-react": "^0.0.22", + "@storybook/theming": "^6.3.12", "@testing-library/dom": "^7.30.3", "@testing-library/jest-dom": "^5.11.10", "@testing-library/react": "^11.2.6", @@ -518,6 +520,7 @@ "@types/elasticsearch": "^5.0.33", "@types/enzyme": "^3.10.8", "@types/eslint": "^7.28.0", + "@types/express": "^4.17.13", "@types/extract-zip": "^1.6.2", "@types/faker": "^5.1.5", "@types/fancy-log": "^1.3.1", @@ -643,6 +646,7 @@ "@types/write-pkg": "^3.1.0", "@types/xml-crypto": "^1.4.2", "@types/xml2js": "^0.4.5", + "@types/yargs": "^15.0.0", "@types/yauzl": "^2.9.1", "@types/zen-observable": "^0.8.0", "@typescript-eslint/eslint-plugin": "^5.2.0", diff --git a/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap b/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap index cc42c71a55186..ddcdd980153fb 100644 --- a/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap +++ b/packages/kbn-optimizer/src/integration_tests/__snapshots__/basic_optimization.test.ts.snap @@ -316,7 +316,7 @@ exports[`prepares assets for distribution: bar bundle 1`] = ` if ( (o ? e.setAttribute(\\"media\\", o) : e.removeAttribute(\\"media\\"), i && - btoa && + \\"undefined\\" != typeof btoa && (r += \\"\\\\n/*# sourceMappingURL=data:application/json;base64,\\".concat( btoa(unescape(encodeURIComponent(JSON.stringify(i)))), \\" */\\" diff --git a/packages/kbn-storybook/BUILD.bazel b/packages/kbn-storybook/BUILD.bazel index b98f2d055a91a..f2a7bf25fb407 100644 --- a/packages/kbn-storybook/BUILD.bazel +++ b/packages/kbn-storybook/BUILD.bazel @@ -36,6 +36,7 @@ RUNTIME_DEPS = [ "@npm//@storybook/api", "@npm//@storybook/components", "@npm//@storybook/core", + "@npm//@storybook/core-common", "@npm//@storybook/node-logger", "@npm//@storybook/react", "@npm//@storybook/theming", @@ -53,9 +54,11 @@ TYPES_DEPS = [ "@npm//@storybook/api", "@npm//@storybook/components", "@npm//@storybook/core", + "@npm//@storybook/core-common", "@npm//@storybook/node-logger", "@npm//@storybook/react", "@npm//@storybook/theming", + "@npm//@types/express", # necessary for storybook which is missing the types "@npm//@types/loader-utils", "@npm//@types/node", "@npm//@types/react", diff --git a/packages/kbn-storybook/src/lib/default_config.ts b/packages/kbn-storybook/src/lib/default_config.ts index 5326be5912ca5..85e206ce01141 100644 --- a/packages/kbn-storybook/src/lib/default_config.ts +++ b/packages/kbn-storybook/src/lib/default_config.ts @@ -7,7 +7,7 @@ */ import * as path from 'path'; -import { StorybookConfig } from '@storybook/core/types'; +import { StorybookConfig } from '@storybook/core-common'; import { Configuration } from 'webpack'; import webpackMerge from 'webpack-merge'; import { REPO_ROOT } from './constants'; @@ -20,6 +20,9 @@ export const defaultConfig: StorybookConfig = { typescript: { reactDocgen: false, }, + features: { + postcss: false, + }, webpackFinal: (config, options) => { if (process.env.CI) { config.parallelism = 4; diff --git a/packages/kbn-storybook/src/lib/theme_switcher.tsx b/packages/kbn-storybook/src/lib/theme_switcher.tsx index fd3e36b4cc306..c06e57035819f 100644 --- a/packages/kbn-storybook/src/lib/theme_switcher.tsx +++ b/packages/kbn-storybook/src/lib/theme_switcher.tsx @@ -9,7 +9,10 @@ import React from 'react'; import { Icons, IconButton, TooltipLinkList, WithTooltip } from '@storybook/components'; import { useGlobals } from '@storybook/api'; -import { Link } from '@storybook/components/dist/tooltip/TooltipLinkList'; + +type PropsOf> = T extends React.FC ? P : never; +type ArrayItem = T extends Array ? I : never; +type Link = ArrayItem['links']>; const defaultTheme = 'v8.light'; @@ -22,7 +25,7 @@ export function ThemeSwitcher() { } function Menu({ onHide }: { onHide: () => void }) { - const links: Link[] = [ + const links = [ { id: 'v8.light', title: 'Light', @@ -31,16 +34,18 @@ export function ThemeSwitcher() { id: 'v8.dark', title: 'Dark', }, - ].map((link) => ({ - ...link, - onClick: (_event, item) => { - if (item.id !== selectedTheme) { - updateGlobals({ euiTheme: item.id }); - } - onHide(); - }, - active: selectedTheme === link.id, - })); + ].map( + (link): Link => ({ + ...link, + onClick: (_event, item) => { + if (item.id !== selectedTheme) { + updateGlobals({ euiTheme: item.id }); + } + onHide(); + }, + active: selectedTheme === link.id, + }) + ); return ; } diff --git a/packages/kbn-storybook/src/typings.ts b/packages/kbn-storybook/src/typings.ts index 6c5d8f4da5709..a4a091a46d190 100644 --- a/packages/kbn-storybook/src/typings.ts +++ b/packages/kbn-storybook/src/typings.ts @@ -16,3 +16,27 @@ declare module '@storybook/react/standalone'; // See https://github.com/storybookjs/storybook/issues/11684 declare module 'react-syntax-highlighter/dist/cjs/create-element'; declare module 'react-syntax-highlighter/dist/cjs/prism-light'; + +// Storybook uses this module and its types are defined in the source but not in the type output +declare module 'file-system-cache' { + interface Options { + basePath?: string; + ns?: string | string[]; + extension?: string; + } + + class FileSystemCache { + constructor(options: Options); + path(key: string): string; + fileExists(key: string): Promise; + ensureBasePath(): Promise; + get(key: string, defaultValue?: any): Promise; + getSync(key: string, defaultValue?: any): any | typeof defaultValue; + set(key: string, value: any): Promise<{ path: string }>; + setSync(key: string, value: any): this; + remove(key: string): Promise; + clear(): Promise; + save(): Promise<{ paths: string[] }>; + load(): Promise<{ files: Array<{ path: string; value: any }> }>; + } +} diff --git a/packages/kbn-storybook/templates/index.ejs b/packages/kbn-storybook/templates/index.ejs index 3473f73ca131f..13fb54c8442c1 100644 --- a/packages/kbn-storybook/templates/index.ejs +++ b/packages/kbn-storybook/templates/index.ejs @@ -1,6 +1,6 @@ @@ -37,23 +37,25 @@ - <% if (typeof bodyHtmlSnippet !== 'undefined') { %> <%= bodyHtmlSnippet %> <% } %> + <% if (typeof bodyHtmlSnippet !== 'undefined') { %> + <%= bodyHtmlSnippet %> + <% } %>
<% if (typeof globals !== 'undefined' && Object.keys(globals).length) { %> - - <% } %> <% dlls.forEach(file => { %> - - <% }); %> <% files.js.forEach(file => { %> - + + <% } %> + + <% files.js.forEach(file => { %> + <% }); %> diff --git a/packages/kbn-ui-shared-deps-npm/webpack.config.js b/packages/kbn-ui-shared-deps-npm/webpack.config.js index a6e7180e88123..197ec5e63ad7c 100644 --- a/packages/kbn-ui-shared-deps-npm/webpack.config.js +++ b/packages/kbn-ui-shared-deps-npm/webpack.config.js @@ -56,6 +56,7 @@ module.exports = (_, argv) => { '@babel/runtime/helpers/interopRequireDefault', '@babel/runtime/helpers/interopRequireWildcard', '@babel/runtime/helpers/objectSpread2', + '@babel/runtime/helpers/objectWithoutProperties', '@babel/runtime/helpers/objectWithoutPropertiesLoose', '@babel/runtime/helpers/slicedToArray', '@babel/runtime/helpers/toArray', diff --git a/src/plugins/presentation_util/public/__stories__/wait_for.tsx b/src/plugins/presentation_util/public/__stories__/wait_for.tsx index 7dd8d8514b840..8799a0f566dca 100644 --- a/src/plugins/presentation_util/public/__stories__/wait_for.tsx +++ b/src/plugins/presentation_util/public/__stories__/wait_for.tsx @@ -9,13 +9,12 @@ import React, { useState, useEffect, useRef, ReactElement } from 'react'; import { act } from 'react-test-renderer'; import { Story } from '@storybook/react'; -import { StoryFnReactReturnType } from '@storybook/react/dist/client/preview/types'; import { EuiLoadingSpinner } from '@elastic/eui'; export const waitFor = (waitTarget: Promise, spinner: ReactElement | null = ) => (CurrentStory: Story) => { - const [storyComponent, setStory] = useState(); + const [storyComponent, setStory] = useState(); const componentIsMounted = useRef(false); useEffect(() => { diff --git a/typings/index.d.ts b/typings/index.d.ts index 85c001b26031b..cd2dc0a989c83 100644 --- a/typings/index.d.ts +++ b/typings/index.d.ts @@ -38,3 +38,27 @@ declare module 'react-syntax-highlighter/dist/cjs/prism-light'; declare module 'monaco-editor/esm/vs/basic-languages/markdown/markdown'; declare module 'monaco-editor/esm/vs/basic-languages/css/css'; declare module 'monaco-editor/esm/vs/basic-languages/yaml/yaml'; + +// Storybook uses this module and its types are defined in the source but not in the type output +declare module 'file-system-cache' { + interface Options { + basePath?: string; + ns?: string | string[]; + extension?: string; + } + + class FileSystemCache { + constructor(options: Options); + path(key: string): string; + fileExists(key: string): Promise; + ensureBasePath(): Promise; + get(key: string, defaultValue?: any): Promise; + getSync(key: string, defaultValue?: any): any | typeof defaultValue; + set(key: string, value: any): Promise<{ path: string }>; + setSync(key: string, value: any): this; + remove(key: string): Promise; + clear(): Promise; + save(): Promise<{ paths: string[] }>; + load(): Promise<{ files: Array<{ path: string; value: any }> }>; + } +} diff --git a/x-pack/plugins/fleet/storybook/preview.tsx b/x-pack/plugins/fleet/storybook/preview.tsx index 353342a2572b0..7d8ac74f2fa80 100644 --- a/x-pack/plugins/fleet/storybook/preview.tsx +++ b/x-pack/plugins/fleet/storybook/preview.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { addDecorator } from '@storybook/react'; -import { Title, Subtitle, Description, Primary, Stories } from '@storybook/addon-docs/blocks'; +import { Title, Subtitle, Description, Primary, Stories } from '@storybook/addon-docs'; import { decorator } from './decorator'; diff --git a/yarn.lock b/yarn.lock index 618664c9c9523..16797a015882a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -32,7 +32,7 @@ dependencies: "@babel/highlight" "^7.10.4" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.5.5": +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.12.13", "@babel/code-frame@^7.16.0", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.0.tgz#0dfc80309beec8411e65e706461c408b0bb9b431" integrity sha512-IF4EOMEV+bfYwOmNxGzSnjR2EmQod7f1UXOpZM3l4i4o4QNwzjtJAu/HxdjHq0aYBvdqMuQEY1eg0nqW9ZPORA== @@ -91,7 +91,7 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/core@>=7.9.0", "@babel/core@^7.1.0", "@babel/core@^7.12.1", "@babel/core@^7.12.3", "@babel/core@^7.16.0", "@babel/core@^7.7.5": +"@babel/core@>=7.9.0", "@babel/core@^7.1.0", "@babel/core@^7.12.10", "@babel/core@^7.12.3", "@babel/core@^7.16.0", "@babel/core@^7.7.5": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.16.0.tgz#c4ff44046f5fe310525cc9eb4ef5147f0c5374d4" integrity sha512-mYZEvshBRHGsIAiyH5PzCFTCfbWfoYbO/jcSdXQSUQu1/pW0xDZAUP7KEc32heqWTAfAHhV9j1vH8Sav7l+JNQ== @@ -128,7 +128,7 @@ dependencies: eslint-rule-composer "^0.3.0" -"@babel/generator@^7.12.1", "@babel/generator@^7.12.5", "@babel/generator@^7.16.0", "@babel/generator@^7.4.4": +"@babel/generator@^7.12.11", "@babel/generator@^7.12.5", "@babel/generator@^7.16.0", "@babel/generator@^7.4.4": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.16.0.tgz#d40f3d1d5075e62d3500bccb67f3daa8a95265b2" integrity sha512-RR8hUCfRQn9j9RPKEVXo9LiwoxLPYn6hNZlvUOR8tSnaxlD0p0+la00ZP9/SnRt6HchKr+X0fO2r8vrETiJGew== @@ -182,10 +182,10 @@ "@babel/helper-annotate-as-pure" "^7.16.0" regexpu-core "^4.7.1" -"@babel/helper-define-polyfill-provider@^0.2.4": - version "0.2.4" - resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.2.4.tgz#8867aed79d3ea6cade40f801efb7ac5c66916b10" - integrity sha512-OrpPZ97s+aPi6h2n1OXzdhVis1SGSsMU2aMHgLcOKfsp4/v1NWpx3CWT3lBj5eeBq9cDkPkh+YCfdF7O12uNDQ== +"@babel/helper-define-polyfill-provider@^0.1.5": + version "0.1.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-polyfill-provider/-/helper-define-polyfill-provider-0.1.5.tgz#3c2f91b7971b9fc11fe779c945c014065dea340e" + integrity sha512-nXuzCSwlJ/WKr8qxzW816gwyT6VZgiJG17zR40fou70yfAcqjoNyTLl/DQ+FExw5Hx5KNqshmN8Ldl/r2N7cTg== dependencies: "@babel/helper-compilation-targets" "^7.13.0" "@babel/helper-module-imports" "^7.12.13" @@ -372,17 +372,12 @@ chalk "^2.0.0" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.12.3", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.16.0", "@babel/parser@^7.16.3", "@babel/parser@^7.4.5": - version "7.16.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.3.tgz#271bafcb811080905a119222edbc17909c82261d" - integrity sha512-dcNwU1O4sx57ClvLBVFbEgx0UZWfd0JQX5X6fxFRCLHelFBGXFfSz6Y0FAq2PEwUqlqLkdVjVr4VASEOuUnLJw== - -"@babel/parser@^7.16.4": +"@babel/parser@^7.1.0", "@babel/parser@^7.12.11", "@babel/parser@^7.12.7", "@babel/parser@^7.14.7", "@babel/parser@^7.16.0", "@babel/parser@^7.16.3", "@babel/parser@^7.16.4", "@babel/parser@^7.4.5": version "7.16.4" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.16.4.tgz#d5f92f57cf2c74ffe9b37981c0e72fee7311372e" integrity sha512-6V0qdPUaiVHH3RtZeLIsc+6pDhbYzHR8ogA8w+f+Wc77DuXto19g2QUwveINoS34Uw+W8/hQDGJCx+i4n7xcng== -"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.0", "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.2": +"@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression@^7.16.2": version "7.16.2" resolved "https://registry.yarnpkg.com/@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression/-/plugin-bugfix-safari-id-destructuring-collision-in-function-expression-7.16.2.tgz#2977fca9b212db153c195674e57cfab807733183" integrity sha512-h37CvpLSf8gb2lIJ2CgC3t+EjFbi0t8qS7LCS1xcJIlEXE4czlofwaW7W1HA8zpgOCzI9C1nmoqNR1zWkk0pQg== @@ -398,16 +393,7 @@ "@babel/helper-skip-transparent-expression-wrappers" "^7.16.0" "@babel/plugin-proposal-optional-chaining" "^7.16.0" -"@babel/plugin-proposal-async-generator-functions@^7.16.0", "@babel/plugin-proposal-async-generator-functions@^7.2.0": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.0.tgz#11425d47a60364352f668ad5fbc1d6596b2c5caf" - integrity sha512-nyYmIo7ZqKsY6P4lnVmBlxp9B3a96CscbLotlsNuktMHahkDwoPYEjXrZHU0Tj844Z9f1IthVxQln57mhkcExw== - dependencies: - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-remap-async-to-generator" "^7.16.0" - "@babel/plugin-syntax-async-generators" "^7.8.4" - -"@babel/plugin-proposal-async-generator-functions@^7.16.4": +"@babel/plugin-proposal-async-generator-functions@^7.16.4", "@babel/plugin-proposal-async-generator-functions@^7.2.0": version "7.16.4" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.16.4.tgz#e606eb6015fec6fa5978c940f315eae4e300b081" integrity sha512-/CUekqaAaZCQHleSK/9HajvcD/zdnJiKRiuUFq8ITE+0HsPzquf53cpFiqAwl/UfmJbR6n5uGPQSPdrmKOvHHg== @@ -441,7 +427,7 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-class-static-block" "^7.14.5" -"@babel/plugin-proposal-decorators@^7.12.1": +"@babel/plugin-proposal-decorators@^7.12.12": version "7.13.5" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.13.5.tgz#d28071457a5ba8ee1394b23e38d5dcf32ea20ef7" integrity sha512-i0GDfVNuoapwiheevUOuSW67mInqJ8qw7uWfpjNVeHMn143kXblEy/bmL9AdZ/0yf/4BMQeWXezK0tQIvNPqag== @@ -542,7 +528,7 @@ "@babel/helper-plugin-utils" "^7.14.5" "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" -"@babel/plugin-proposal-optional-chaining@^7.12.1", "@babel/plugin-proposal-optional-chaining@^7.16.0": +"@babel/plugin-proposal-optional-chaining@^7.12.7", "@babel/plugin-proposal-optional-chaining@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.16.0.tgz#56dbc3970825683608e9efb55ea82c2a2d6c8dc0" integrity sha512-Y4rFpkZODfHrVo70Uaj6cC1JJOt3Pp0MdWSwIKtb8z1/lsjl9AmnB7ErRFV+QNGIfcY1Eruc2UMx5KaRnXjMyg== @@ -754,7 +740,7 @@ dependencies: "@babel/helper-plugin-utils" "^7.14.5" -"@babel/plugin-transform-block-scoping@^7.12.1", "@babel/plugin-transform-block-scoping@^7.16.0", "@babel/plugin-transform-block-scoping@^7.4.4": +"@babel/plugin-transform-block-scoping@^7.12.12", "@babel/plugin-transform-block-scoping@^7.16.0", "@babel/plugin-transform-block-scoping@^7.4.4": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.16.0.tgz#bcf433fb482fe8c3d3b4e8a66b1c4a8e77d37c16" integrity sha512-27n3l67/R3UrXfizlvHGuTwsRIFyce3D/6a37GRxn28iyTPvNXaW4XvznexRh1zUNLPjbLL22Id0XQElV94ruw== @@ -952,7 +938,7 @@ "@babel/helper-plugin-utils" "^7.10.4" "@babel/plugin-syntax-jsx" "^7.10.4" -"@babel/plugin-transform-react-jsx@^7.0.0", "@babel/plugin-transform-react-jsx@^7.12.1", "@babel/plugin-transform-react-jsx@^7.16.0": +"@babel/plugin-transform-react-jsx@^7.0.0", "@babel/plugin-transform-react-jsx@^7.12.1", "@babel/plugin-transform-react-jsx@^7.12.12", "@babel/plugin-transform-react-jsx@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.16.0.tgz#55b797d4960c3de04e07ad1c0476e2bc6a4889f1" integrity sha512-rqDgIbukZ44pqq7NIRPGPGNklshPkvlmvqjdx3OZcGPk4zGIenYkxDTvl3LsSL8gqcc3ZzGmXPE6hR/u/voNOw== @@ -1121,87 +1107,7 @@ js-levenshtein "^1.1.3" semver "^5.5.0" -"@babel/preset-env@^7.12.1": - version "7.16.0" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.0.tgz#97228393d217560d6a1c6c56f0adb9d12bca67f5" - integrity sha512-cdTu/W0IrviamtnZiTfixPfIncr2M1VqRrkjzZWlr1B4TVYimCFK5jkyOdP4qw2MrlKHi+b3ORj6x8GoCew8Dg== - dependencies: - "@babel/compat-data" "^7.16.0" - "@babel/helper-compilation-targets" "^7.16.0" - "@babel/helper-plugin-utils" "^7.14.5" - "@babel/helper-validator-option" "^7.14.5" - "@babel/plugin-bugfix-safari-id-destructuring-collision-in-function-expression" "^7.16.0" - "@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining" "^7.16.0" - "@babel/plugin-proposal-async-generator-functions" "^7.16.0" - "@babel/plugin-proposal-class-properties" "^7.16.0" - "@babel/plugin-proposal-class-static-block" "^7.16.0" - "@babel/plugin-proposal-dynamic-import" "^7.16.0" - "@babel/plugin-proposal-export-namespace-from" "^7.16.0" - "@babel/plugin-proposal-json-strings" "^7.16.0" - "@babel/plugin-proposal-logical-assignment-operators" "^7.16.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.16.0" - "@babel/plugin-proposal-numeric-separator" "^7.16.0" - "@babel/plugin-proposal-object-rest-spread" "^7.16.0" - "@babel/plugin-proposal-optional-catch-binding" "^7.16.0" - "@babel/plugin-proposal-optional-chaining" "^7.16.0" - "@babel/plugin-proposal-private-methods" "^7.16.0" - "@babel/plugin-proposal-private-property-in-object" "^7.16.0" - "@babel/plugin-proposal-unicode-property-regex" "^7.16.0" - "@babel/plugin-syntax-async-generators" "^7.8.4" - "@babel/plugin-syntax-class-properties" "^7.12.13" - "@babel/plugin-syntax-class-static-block" "^7.14.5" - "@babel/plugin-syntax-dynamic-import" "^7.8.3" - "@babel/plugin-syntax-export-namespace-from" "^7.8.3" - "@babel/plugin-syntax-json-strings" "^7.8.3" - "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.3" - "@babel/plugin-syntax-numeric-separator" "^7.10.4" - "@babel/plugin-syntax-object-rest-spread" "^7.8.3" - "@babel/plugin-syntax-optional-catch-binding" "^7.8.3" - "@babel/plugin-syntax-optional-chaining" "^7.8.3" - "@babel/plugin-syntax-private-property-in-object" "^7.14.5" - "@babel/plugin-syntax-top-level-await" "^7.14.5" - "@babel/plugin-transform-arrow-functions" "^7.16.0" - "@babel/plugin-transform-async-to-generator" "^7.16.0" - "@babel/plugin-transform-block-scoped-functions" "^7.16.0" - "@babel/plugin-transform-block-scoping" "^7.16.0" - "@babel/plugin-transform-classes" "^7.16.0" - "@babel/plugin-transform-computed-properties" "^7.16.0" - "@babel/plugin-transform-destructuring" "^7.16.0" - "@babel/plugin-transform-dotall-regex" "^7.16.0" - "@babel/plugin-transform-duplicate-keys" "^7.16.0" - "@babel/plugin-transform-exponentiation-operator" "^7.16.0" - "@babel/plugin-transform-for-of" "^7.16.0" - "@babel/plugin-transform-function-name" "^7.16.0" - "@babel/plugin-transform-literals" "^7.16.0" - "@babel/plugin-transform-member-expression-literals" "^7.16.0" - "@babel/plugin-transform-modules-amd" "^7.16.0" - "@babel/plugin-transform-modules-commonjs" "^7.16.0" - "@babel/plugin-transform-modules-systemjs" "^7.16.0" - "@babel/plugin-transform-modules-umd" "^7.16.0" - "@babel/plugin-transform-named-capturing-groups-regex" "^7.16.0" - "@babel/plugin-transform-new-target" "^7.16.0" - "@babel/plugin-transform-object-super" "^7.16.0" - "@babel/plugin-transform-parameters" "^7.16.0" - "@babel/plugin-transform-property-literals" "^7.16.0" - "@babel/plugin-transform-regenerator" "^7.16.0" - "@babel/plugin-transform-reserved-words" "^7.16.0" - "@babel/plugin-transform-shorthand-properties" "^7.16.0" - "@babel/plugin-transform-spread" "^7.16.0" - "@babel/plugin-transform-sticky-regex" "^7.16.0" - "@babel/plugin-transform-template-literals" "^7.16.0" - "@babel/plugin-transform-typeof-symbol" "^7.16.0" - "@babel/plugin-transform-unicode-escapes" "^7.16.0" - "@babel/plugin-transform-unicode-regex" "^7.16.0" - "@babel/preset-modules" "^0.1.5" - "@babel/types" "^7.16.0" - babel-plugin-polyfill-corejs2 "^0.2.3" - babel-plugin-polyfill-corejs3 "^0.3.0" - babel-plugin-polyfill-regenerator "^0.2.3" - core-js-compat "^3.19.0" - semver "^6.3.0" - -"@babel/preset-env@^7.16.4": +"@babel/preset-env@^7.12.11", "@babel/preset-env@^7.16.4": version "7.16.4" resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.16.4.tgz#4f6ec33b2a3fe72d6bfdcdf3859500232563a2e3" integrity sha512-v0QtNd81v/xKj4gNKeuAerQ/azeNn/G1B1qMLeXOcV8+4TWlD2j3NV1u8q29SDFBXx/NBq5kyEAO+0mpRgacjA== @@ -1311,7 +1217,7 @@ "@babel/plugin-transform-react-jsx-self" "^7.0.0" "@babel/plugin-transform-react-jsx-source" "^7.0.0" -"@babel/preset-react@^7.12.1", "@babel/preset-react@^7.16.0": +"@babel/preset-react@^7.12.10", "@babel/preset-react@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.16.0.tgz#f71d3e8dff5218478011df037fad52660ee6d82a" integrity sha512-d31IFW2bLRB28uL1WoElyro8RH5l6531XfxMtCeCmp6RVAF1uTfxxUA0LH1tXl+psZdwfmIbwoG4U5VwgbhtLw== @@ -1323,7 +1229,7 @@ "@babel/plugin-transform-react-jsx-development" "^7.16.0" "@babel/plugin-transform-react-pure-annotations" "^7.16.0" -"@babel/preset-typescript@^7.12.1", "@babel/preset-typescript@^7.16.0": +"@babel/preset-typescript@^7.12.7", "@babel/preset-typescript@^7.16.0": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/preset-typescript/-/preset-typescript-7.16.0.tgz#b0b4f105b855fb3d631ec036cdc9d1ffd1fa5eac" integrity sha512-txegdrZYgO9DlPbv+9QOVpMnKbOtezsLHWsnsRF4AjbSIsVaujrq1qg8HK0mxQpWv0jnejt0yEoW1uWpvbrDTg== @@ -1362,21 +1268,7 @@ core-js-pure "^3.0.0" regenerator-runtime "^0.13.4" -"@babel/runtime@7.3.1": - version "7.3.1" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.3.1.tgz#574b03e8e8a9898eaf4a872a92ea20b7846f6f2a" - integrity sha512-7jGW8ppV0ant637pIqAcFfQDDH1orEPGJb8aXfUozuCU3QqX7rX4DA8iwrbPrR1hcH0FTTHz47yQnk+bl5xHQA== - dependencies: - regenerator-runtime "^0.12.0" - -"@babel/runtime@7.3.4": - version "7.3.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.3.4.tgz#73d12ba819e365fcf7fd152aed56d6df97d21c83" - integrity sha512-IvfvnMdSaLBateu0jfsYIpZTxAc2cKEXEMiezGGN75QcBcecDUKd3PgLAncT0oOgxKy8dd8hrJKj9MfzgfZd6g== - dependencies: - regenerator-runtime "^0.12.0" - -"@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.14.0", "@babel/runtime@^7.16.0", "@babel/runtime@^7.16.3", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": +"@babel/runtime@7.3.1", "@babel/runtime@^7.0.0", "@babel/runtime@^7.1.2", "@babel/runtime@^7.10.2", "@babel/runtime@^7.11.2", "@babel/runtime@^7.12.5", "@babel/runtime@^7.13.10", "@babel/runtime@^7.14.0", "@babel/runtime@^7.16.0", "@babel/runtime@^7.16.3", "@babel/runtime@^7.3.1", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.0", "@babel/runtime@^7.5.5", "@babel/runtime@^7.6.2", "@babel/runtime@^7.6.3", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": version "7.16.3" resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.16.3.tgz#b86f0db02a04187a3c17caa77de69840165d42d5" integrity sha512-WBwekcqacdY2e9AF/Q7WLFUWmdJGJTkbjqTjoMDgXkVZ3ZRUvOPsLb5KdwISoQVsbP+DQzVZW4Zhci0DvpbNTQ== @@ -1392,7 +1284,7 @@ "@babel/parser" "^7.16.0" "@babel/types" "^7.16.0" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.0", "@babel/traverse@^7.16.3", "@babel/traverse@^7.4.5": +"@babel/traverse@^7.1.0", "@babel/traverse@^7.12.11", "@babel/traverse@^7.12.9", "@babel/traverse@^7.13.0", "@babel/traverse@^7.16.0", "@babel/traverse@^7.16.3", "@babel/traverse@^7.4.5": version "7.16.3" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.16.3.tgz#f63e8a938cc1b780f66d9ed3c54f532ca2d14787" integrity sha512-eolumr1vVMjqevCpwVO99yN/LoGL0EyHiLO5I043aYQvwOJ9eR5UsZSClHVCzfhBduMAsSzgA/6AyqPjNayJag== @@ -1407,7 +1299,7 @@ debug "^4.1.0" globals "^11.1.0" -"@babel/types@^7.0.0", "@babel/types@^7.12.7", "@babel/types@^7.16.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": +"@babel/types@^7.0.0", "@babel/types@^7.12.11", "@babel/types@^7.12.7", "@babel/types@^7.16.0", "@babel/types@^7.3.0", "@babel/types@^7.3.3", "@babel/types@^7.4.4": version "7.16.0" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.16.0.tgz#db3b313804f96aadd0b776c4823e127ad67289ba" integrity sha512-PJgg/k3SdLsGb3hhisFvtLOw5ts113klrpLuIPtCJIU+BB24fqq6lf8RWqKJEjzqXR9AEH1rIb5XTqwBHB+kQg== @@ -1415,10 +1307,10 @@ "@babel/helper-validator-identifier" "^7.15.7" to-fast-properties "^2.0.0" -"@base2/pretty-print-object@1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.0.tgz#860ce718b0b73f4009e153541faff2cb6b85d047" - integrity sha512-4Th98KlMHr5+JkxfcoDT//6vY8vM+iSPrLNpHhRyLx2CFYi8e2RfqPLdpbnpo0Q5lQC5hNB79yes07zb02fvCw== +"@base2/pretty-print-object@1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@base2/pretty-print-object/-/pretty-print-object-1.0.1.tgz#371ba8be66d556812dc7fb169ebc3c08378f69d4" + integrity sha512-4iri8i1AqYHJE2DstZYkyEprg6Pq6sKx3xn5FpySk9sNhH7qN2LLlHJCfDTZRILNwQNPD7mATWM0TBui7uC1pA== "@bazel/ibazel@^0.15.10": version "0.15.10" @@ -1549,6 +1441,11 @@ enabled "2.0.x" kuler "^2.0.0" +"@discoveryjs/json-ext@^0.5.3": + version "0.5.5" + resolved "https://registry.yarnpkg.com/@discoveryjs/json-ext/-/json-ext-0.5.5.tgz#9283c9ce5b289a3c4f61c12757469e59377f81f3" + integrity sha512-6nFkfkmSeV/rqSaS4oWHgmpnYw194f6hmWF5is6b0J1naJZoiD0NTc9AiUwPHvWsowkjuHErCZT1wa0jg+BLIA== + "@dnd-kit/accessibility@^3.0.0": version "3.0.0" resolved "https://registry.yarnpkg.com/@dnd-kit/accessibility/-/accessibility-3.0.0.tgz#b56e3750414fd907b7d6972b3116aa8f96d07fde" @@ -2102,7 +1999,7 @@ "@emotion/serialize" "^0.11.15" "@emotion/utils" "0.11.3" -"@emotion/styled@^10.0.23", "@emotion/styled@^10.0.27": +"@emotion/styled@^10.0.27": version "10.0.27" resolved "https://registry.yarnpkg.com/@emotion/styled/-/styled-10.0.27.tgz#12cb67e91f7ad7431e1875b1d83a94b814133eaf" integrity sha512-iK/8Sh7+NLJzyp9a5+vIQIXTYxfT4yB/OJbjzQanB2RZpvmzBQOHZWhpAMZWYEKRNNbsD6WfBw5sVWkb6WzS/Q== @@ -2680,7 +2577,7 @@ jest-runner "^26.6.3" jest-runtime "^26.6.3" -"@jest/transform@^26.0.0", "@jest/transform@^26.6.2": +"@jest/transform@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/transform/-/transform-26.6.2.tgz#5ac57c5fa1ad17b2aae83e73e45813894dcf2e4b" integrity sha512-E9JjhUgNzvuQ+vVAL21vlyfy12gP0GhazGgJC4h6qUt1jSdUXGWJ1wfu/X7Sd8etSgxV4ovT1pb9v5D6QW4XgA== @@ -2710,16 +2607,6 @@ "@types/istanbul-reports" "^1.1.1" "@types/yargs" "^13.0.0" -"@jest/types@^25.5.0": - version "25.5.0" - resolved "https://registry.yarnpkg.com/@jest/types/-/types-25.5.0.tgz#4d6a4793f7b9599fc3680877b856a97dbccf2a9d" - integrity sha512-OXD0RgQ86Tu3MazKo8bnrkDRaDXXMGUqd+kTtLtK1Zb7CRzQcaSRPPPV37SvYTdevXEBVxe0HXylEjs8ibkmCw== - dependencies: - "@types/istanbul-lib-coverage" "^2.0.0" - "@types/istanbul-reports" "^1.1.1" - "@types/yargs" "^15.0.0" - chalk "^3.0.0" - "@jest/types@^26.6.2": version "26.6.2" resolved "https://registry.yarnpkg.com/@jest/types/-/types-26.6.2.tgz#bef5a532030e1d88a2f5a6d933f84e97226ed48e" @@ -3449,7 +3336,7 @@ resolved "https://registry.yarnpkg.com/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz#497c67a1cef50d1a2459ba60f315e448d2ad87fe" integrity sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q== -"@mdx-js/loader@^1.6.19": +"@mdx-js/loader@^1.6.22": version "1.6.22" resolved "https://registry.yarnpkg.com/@mdx-js/loader/-/loader-1.6.22.tgz#d9e8fe7f8185ff13c9c8639c048b123e30d322c4" integrity sha512-9CjGwy595NaxAYp0hF9B/A0lH6C8Rms97e2JS9d3jVUtILn6pT5i5IV965ra3lIWc7Rs1GG1tBdVF7dCowYe6Q== @@ -3458,7 +3345,7 @@ "@mdx-js/react" "1.6.22" loader-utils "2.0.0" -"@mdx-js/mdx@1.6.22", "@mdx-js/mdx@^1.6.19": +"@mdx-js/mdx@1.6.22", "@mdx-js/mdx@^1.6.22": version "1.6.22" resolved "https://registry.yarnpkg.com/@mdx-js/mdx/-/mdx-1.6.22.tgz#8a723157bf90e78f17dc0f27995398e6c731f1ba" integrity sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA== @@ -3483,7 +3370,7 @@ unist-builder "2.0.3" unist-util-visit "2.0.3" -"@mdx-js/react@1.6.22", "@mdx-js/react@^1.6.19": +"@mdx-js/react@1.6.22", "@mdx-js/react@^1.6.22": version "1.6.22" resolved "https://registry.yarnpkg.com/@mdx-js/react/-/react-1.6.22.tgz#ae09b4744fddc74714ee9f9d6f17a66e77c43573" integrity sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg== @@ -3926,7 +3813,7 @@ which "^2.0.1" winston "^3.0.0" -"@pmmmwh/react-refresh-webpack-plugin@^0.4.2": +"@pmmmwh/react-refresh-webpack-plugin@^0.4.3": version "0.4.3" resolved "https://registry.yarnpkg.com/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.4.3.tgz#1eec460596d200c0236bf195b078a5d1df89b766" integrity sha512-br5Qwvh8D2OQqSXpd1g/xqXKnK0r+Jz6qVKBbWmpUcrbGOxUrf39V5oZ1876084CGn18uMdR5uvPqBv9UqtBjQ== @@ -3938,10 +3825,10 @@ schema-utils "^2.6.5" source-map "^0.7.3" -"@popperjs/core@^2.4.0", "@popperjs/core@^2.5.4": - version "2.9.0" - resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.9.0.tgz#32e63212293dd3efbb521cd35a5020ab66eaa546" - integrity sha512-wjtKehFAIARq2OxK8j3JrggNlEslJfNuSm2ArteIbKyRMts2g0a7KzTxfRVNUM+O0gnBJ2hNV8nWPOYBgI1sew== +"@popperjs/core@^2.4.0", "@popperjs/core@^2.5.4", "@popperjs/core@^2.6.0": + version "2.10.2" + resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.10.2.tgz#0798c03351f0dea1a5a4cabddf26a55a7cbee590" + integrity sha512-IXf3XA7+XyN7CP9gGh/XB0UxVMlvARGEgGXLubFICsUMGz6Q+DU+i4gGlpOxTjKvXjkJDJC8YdqdKkDj9qZHEQ== "@probe.gl/stats@^3.3.0": version "3.3.0" @@ -4003,7 +3890,7 @@ resolved "https://registry.yarnpkg.com/@protobufjs/utf8/-/utf8-1.1.0.tgz#a777360b5b39a1a2e5106f8e858f2fd2d060c570" integrity sha1-p3c2C1s5oaLlEG+OhY8v0tBgxXA= -"@reach/router@^1.3.3", "@reach/router@^1.3.4": +"@reach/router@^1.3.4": version "1.3.4" resolved "https://registry.yarnpkg.com/@reach/router/-/router-1.3.4.tgz#d2574b19370a70c80480ed91f3da840136d10f8c" integrity sha512-+mtn9wjlB9NN2CNnnC/BRYtwdKBfSyyasPYraNAyvaV1occr/5NnB4CVzjEZipNHwYebQwcndGUmpFzxAUoqSA== @@ -4184,276 +4071,258 @@ "@types/node" ">=8.9.0" axios "^0.21.1" -"@storybook/addon-a11y@^6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/addon-a11y/-/addon-a11y-6.1.20.tgz#71102a84ebaf37948e19a6d28fb58de5adadd1b6" - integrity sha512-ytktgT4XyXtbqpYt76R2PWlRTku7NjoZHLCF6Gv+OSEYfys8e0twZ+BJ+Cojch6WLwHYXVcSfcmhgY+DedI0BA== - dependencies: - "@storybook/addons" "6.1.20" - "@storybook/api" "6.1.20" - "@storybook/channels" "6.1.20" - "@storybook/client-api" "6.1.20" - "@storybook/client-logger" "6.1.20" - "@storybook/components" "6.1.20" - "@storybook/core-events" "6.1.20" - "@storybook/theming" "6.1.20" - axe-core "^4.0.1" - core-js "^3.0.1" - global "^4.3.2" - lodash "^4.17.15" - react-sizeme "^2.5.2" +"@storybook/addon-a11y@^6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/addon-a11y/-/addon-a11y-6.3.12.tgz#2f930fc84fc275a4ed43a716fc09cc12caf4e110" + integrity sha512-q1NdRHFJV6sLEEJw0hatCc5ZIthELqM/AWdrEWDyhcJNyiq7Tq4nKqQBMTQSYwHiUAmxVgw7i4oa1vM2M51/3g== + dependencies: + "@storybook/addons" "6.3.12" + "@storybook/api" "6.3.12" + "@storybook/channels" "6.3.12" + "@storybook/client-api" "6.3.12" + "@storybook/client-logger" "6.3.12" + "@storybook/components" "6.3.12" + "@storybook/core-events" "6.3.12" + "@storybook/theming" "6.3.12" + axe-core "^4.2.0" + core-js "^3.8.2" + global "^4.4.0" + lodash "^4.17.20" + react-sizeme "^3.0.1" regenerator-runtime "^0.13.7" ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/addon-actions@6.1.20", "@storybook/addon-actions@^6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-6.1.20.tgz#a7c5f8d079d309f89b38ac8fb89b0838e63afc43" - integrity sha512-94KH/+Y+Do9k9XgVGup2XgRnzaz/6fSR41nKW4x8oUbnmke8FeZEAurBzjsK+0EGZhVilEpVvabZXc7t9tRZyg== - dependencies: - "@storybook/addons" "6.1.20" - "@storybook/api" "6.1.20" - "@storybook/client-api" "6.1.20" - "@storybook/components" "6.1.20" - "@storybook/core-events" "6.1.20" - "@storybook/theming" "6.1.20" - core-js "^3.0.1" - fast-deep-equal "^3.1.1" - global "^4.3.2" - lodash "^4.17.15" - polished "^3.4.4" +"@storybook/addon-actions@6.3.12", "@storybook/addon-actions@^6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/addon-actions/-/addon-actions-6.3.12.tgz#69eb5f8f780f1b00456051da6290d4b959ba24a0" + integrity sha512-mzuN4Ano4eyicwycM2PueGzzUCAEzt9/6vyptWEIVJu0sjK0J9KtBRlqFi1xGQxmCfimDR/n/vWBBkc7fp2uJA== + dependencies: + "@storybook/addons" "6.3.12" + "@storybook/api" "6.3.12" + "@storybook/client-api" "6.3.12" + "@storybook/components" "6.3.12" + "@storybook/core-events" "6.3.12" + "@storybook/theming" "6.3.12" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.20" + polished "^4.0.5" prop-types "^15.7.2" - react-inspector "^5.0.1" + react-inspector "^5.1.0" regenerator-runtime "^0.13.7" ts-dedent "^2.0.0" util-deprecate "^1.0.2" - uuid "^8.0.0" - -"@storybook/addon-backgrounds@6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-6.1.20.tgz#317cf6e123b8bc42f401cff1c0531aaa33d9d1ac" - integrity sha512-7YF+18DaekpiN1zyyLYOT6iqCPr8kGt6PFdAtMa/HtIalGryDwlRNHaUfylWAsaRWrOAz2tBzrX16olMuE+i3g== - dependencies: - "@storybook/addons" "6.1.20" - "@storybook/api" "6.1.20" - "@storybook/client-logger" "6.1.20" - "@storybook/components" "6.1.20" - "@storybook/core-events" "6.1.20" - "@storybook/theming" "6.1.20" - core-js "^3.0.1" - global "^4.3.2" + uuid-browser "^3.1.0" + +"@storybook/addon-backgrounds@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/addon-backgrounds/-/addon-backgrounds-6.3.12.tgz#5feecd461f48178aa976ba2694418e9ea1d621b3" + integrity sha512-51cHBx0HV7K/oRofJ/1pE05qti6sciIo8m4iPred1OezXIrJ/ckzP+gApdaUdzgcLAr6/MXQWLk0sJuImClQ6w== + dependencies: + "@storybook/addons" "6.3.12" + "@storybook/api" "6.3.12" + "@storybook/client-logger" "6.3.12" + "@storybook/components" "6.3.12" + "@storybook/core-events" "6.3.12" + "@storybook/theming" "6.3.12" + core-js "^3.8.2" + global "^4.4.0" memoizerific "^1.11.3" regenerator-runtime "^0.13.7" ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/addon-controls@6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-6.1.20.tgz#28fdbde325d55f910caad5f4694feee242c146ef" - integrity sha512-UZMZipa0B5IjKuZfOAa2xLYckzKuOtXbMTcTiT97ygyDSxMTkaCyfmuBdoUyoCv/+0PwQl2dN6EUqI+7I0ZZYA== - dependencies: - "@storybook/addons" "6.1.20" - "@storybook/api" "6.1.20" - "@storybook/client-api" "6.1.20" - "@storybook/components" "6.1.20" - "@storybook/node-logger" "6.1.20" - "@storybook/theming" "6.1.20" - core-js "^3.0.1" +"@storybook/addon-controls@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/addon-controls/-/addon-controls-6.3.12.tgz#dbb732c62cf06fb7ccaf87d6ab11c876d14456fc" + integrity sha512-WO/PbygE4sDg3BbstJ49q0uM3Xu5Nw4lnHR5N4hXSvRAulZt1d1nhphRTHjfX+CW+uBcfzkq9bksm6nKuwmOyw== + dependencies: + "@storybook/addons" "6.3.12" + "@storybook/api" "6.3.12" + "@storybook/client-api" "6.3.12" + "@storybook/components" "6.3.12" + "@storybook/node-logger" "6.3.12" + "@storybook/theming" "6.3.12" + core-js "^3.8.2" ts-dedent "^2.0.0" -"@storybook/addon-docs@6.1.20", "@storybook/addon-docs@^6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-6.1.20.tgz#390ea245686cfc464cfb94d441e494f1dbaf1b89" - integrity sha512-dc51UHcgMe/sa68+GFaJALJnkxoU8HNmNJmjwJoxZ1boTMC9D6CjVZl3tGqoLwoStlGB98lM7s+esONz+RAXtA== +"@storybook/addon-docs@6.3.12", "@storybook/addon-docs@^6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/addon-docs/-/addon-docs-6.3.12.tgz#2ec73b4f231d9f190d5c89295bc47bea6a95c6d1" + integrity sha512-iUrqJBMTOn2PgN8AWNQkfxfIPkh8pEg27t8UndMgfOpeGK/VWGw2UEifnA82flvntcilT4McxmVbRHkeBY9K5A== dependencies: - "@babel/core" "^7.12.1" - "@babel/generator" "^7.12.1" - "@babel/parser" "^7.12.3" - "@babel/plugin-transform-react-jsx" "^7.12.1" - "@babel/preset-env" "^7.12.1" - "@jest/transform" "^26.0.0" - "@mdx-js/loader" "^1.6.19" - "@mdx-js/mdx" "^1.6.19" - "@mdx-js/react" "^1.6.19" - "@storybook/addons" "6.1.20" - "@storybook/api" "6.1.20" - "@storybook/client-api" "6.1.20" - "@storybook/client-logger" "6.1.20" - "@storybook/components" "6.1.20" - "@storybook/core" "6.1.20" - "@storybook/core-events" "6.1.20" + "@babel/core" "^7.12.10" + "@babel/generator" "^7.12.11" + "@babel/parser" "^7.12.11" + "@babel/plugin-transform-react-jsx" "^7.12.12" + "@babel/preset-env" "^7.12.11" + "@jest/transform" "^26.6.2" + "@mdx-js/loader" "^1.6.22" + "@mdx-js/mdx" "^1.6.22" + "@mdx-js/react" "^1.6.22" + "@storybook/addons" "6.3.12" + "@storybook/api" "6.3.12" + "@storybook/builder-webpack4" "6.3.12" + "@storybook/client-api" "6.3.12" + "@storybook/client-logger" "6.3.12" + "@storybook/components" "6.3.12" + "@storybook/core" "6.3.12" + "@storybook/core-events" "6.3.12" "@storybook/csf" "0.0.1" - "@storybook/node-logger" "6.1.20" - "@storybook/postinstall" "6.1.20" - "@storybook/source-loader" "6.1.20" - "@storybook/theming" "6.1.20" - acorn "^7.1.0" - acorn-jsx "^5.1.0" - acorn-walk "^7.0.0" - core-js "^3.0.1" + "@storybook/csf-tools" "6.3.12" + "@storybook/node-logger" "6.3.12" + "@storybook/postinstall" "6.3.12" + "@storybook/source-loader" "6.3.12" + "@storybook/theming" "6.3.12" + acorn "^7.4.1" + acorn-jsx "^5.3.1" + acorn-walk "^7.2.0" + core-js "^3.8.2" doctrine "^3.0.0" - escodegen "^1.12.0" - fast-deep-equal "^3.1.1" - global "^4.3.2" + escodegen "^2.0.0" + fast-deep-equal "^3.1.3" + global "^4.4.0" html-tags "^3.1.0" js-string-escape "^1.0.1" - lodash "^4.17.15" - prettier "~2.0.5" + loader-utils "^2.0.0" + lodash "^4.17.20" + p-limit "^3.1.0" + prettier "~2.2.1" prop-types "^15.7.2" - react-element-to-jsx-string "^14.3.1" + react-element-to-jsx-string "^14.3.2" regenerator-runtime "^0.13.7" - remark-external-links "^6.0.0" + remark-external-links "^8.0.0" remark-slug "^6.0.0" ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/addon-essentials@^6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-6.1.20.tgz#4cd38e61e6a763c3ff291d0d8da04f2968395265" - integrity sha512-8ne21UO3mE8nxUq8Nk8rF3zSJiLVjQdBv9aimwXUgOBeQTBRyY/H0nswjbIas8WrEk4D0pK+ylel4CdmMXJxxw== - dependencies: - "@storybook/addon-actions" "6.1.20" - "@storybook/addon-backgrounds" "6.1.20" - "@storybook/addon-controls" "6.1.20" - "@storybook/addon-docs" "6.1.20" - "@storybook/addon-toolbars" "6.1.20" - "@storybook/addon-viewport" "6.1.20" - "@storybook/addons" "6.1.20" - "@storybook/api" "6.1.20" - "@storybook/node-logger" "6.1.20" - core-js "^3.0.1" +"@storybook/addon-essentials@^6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/addon-essentials/-/addon-essentials-6.3.12.tgz#445cc4bc2eb9168a9e5de1fdfb5ef3b92974e74b" + integrity sha512-PK0pPE0xkq00kcbBcFwu/5JGHQTu4GvLIHfwwlEGx6GWNQ05l6Q+1Z4nE7xJGv2PSseSx3CKcjn8qykNLe6O6g== + dependencies: + "@storybook/addon-actions" "6.3.12" + "@storybook/addon-backgrounds" "6.3.12" + "@storybook/addon-controls" "6.3.12" + "@storybook/addon-docs" "6.3.12" + "@storybook/addon-measure" "^2.0.0" + "@storybook/addon-toolbars" "6.3.12" + "@storybook/addon-viewport" "6.3.12" + "@storybook/addons" "6.3.12" + "@storybook/api" "6.3.12" + "@storybook/node-logger" "6.3.12" + core-js "^3.8.2" regenerator-runtime "^0.13.7" + storybook-addon-outline "^1.4.1" ts-dedent "^2.0.0" -"@storybook/addon-knobs@^6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/addon-knobs/-/addon-knobs-6.1.20.tgz#50e2a6e277fc44df9d50a04dad51f574e4f76f60" - integrity sha512-4G39Od9oRGUgiMqd8ukkNj5TmD54ZPUiw7u53J0gxIJFhgeInhzIE7w754LfaeBaaQ62OIqtc43r5BAKS0uPgQ== - dependencies: - "@storybook/addons" "6.1.20" - "@storybook/api" "6.1.20" - "@storybook/channels" "6.1.20" - "@storybook/client-api" "6.1.20" - "@storybook/components" "6.1.20" - "@storybook/core-events" "6.1.20" - "@storybook/theming" "6.1.20" - copy-to-clipboard "^3.0.8" - core-js "^3.0.1" +"@storybook/addon-knobs@^6.3.1": + version "6.3.1" + resolved "https://registry.yarnpkg.com/@storybook/addon-knobs/-/addon-knobs-6.3.1.tgz#2115c6f0d5759e4fe73d5f25710f4a94ebd6f0db" + integrity sha512-2GGGnQSPXXUhHHYv4IW6pkyQlCPYXKYiyGzfhV7Zhs95M2Ban08OA6KLmliMptWCt7U9tqTO8dB5u0C2cWmCTw== + dependencies: + copy-to-clipboard "^3.3.1" + core-js "^3.8.2" escape-html "^1.0.3" - fast-deep-equal "^3.1.1" - global "^4.3.2" - lodash "^4.17.15" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.20" prop-types "^15.7.2" - qs "^6.6.0" - react-color "^2.17.0" + qs "^6.10.0" + react-colorful "^5.1.2" react-lifecycles-compat "^3.0.4" - react-select "^3.0.8" - regenerator-runtime "^0.13.7" + react-select "^3.2.0" -"@storybook/addon-storyshots@^6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/addon-storyshots/-/addon-storyshots-6.1.20.tgz#2cedd14159fd40227bcdc364c6c73c2e3b1e6b47" - integrity sha512-DwaiKd0sUut9x1M1mVWbpal6DPZnIYGMpm7QxtGP+2Bmv23/n/FmFZoHVzIC3/KwjOlButKAiY9gB45B5HFrqg== +"@storybook/addon-measure@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@storybook/addon-measure/-/addon-measure-2.0.0.tgz#c40bbe91bacd3f795963dc1ee6ff86be87deeda9" + integrity sha512-ZhdT++cX+L9LwjhGYggvYUUVQH/MGn2rwbrAwCMzA/f2QTFvkjxzX8nDgMxIhaLCDC+gHIxfJG2wrWN0jkBr3g== + +"@storybook/addon-storyshots@^6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/addon-storyshots/-/addon-storyshots-6.3.12.tgz#542bba23a6ad65a4a0b77427169f177e24f5c5f1" + integrity sha512-plpy/q3pPpXtK9DyofE0trTeCZIyU0Z+baybbxltsM/tKFuQxbHSxTwgluq/7LOMkaRPgbddGyHForHoRLjsWg== dependencies: - "@jest/transform" "^26.0.0" - "@storybook/addons" "6.1.20" - "@storybook/client-api" "6.1.20" - "@storybook/core" "6.1.20" - "@types/glob" "^7.1.1" - "@types/jest" "^25.1.1" + "@jest/transform" "^26.6.2" + "@storybook/addons" "6.3.12" + "@storybook/client-api" "6.3.12" + "@storybook/core" "6.3.12" + "@storybook/core-common" "6.3.12" + "@types/glob" "^7.1.3" + "@types/jest" "^26.0.16" "@types/jest-specific-snapshot" "^0.5.3" babel-plugin-require-context-hook "^1.0.0" - core-js "^3.0.1" - glob "^7.1.3" - global "^4.3.2" + core-js "^3.8.2" + glob "^7.1.6" + global "^4.4.0" jest-specific-snapshot "^4.0.0" - pretty-format "^26.4.0" + preact-render-to-string "^5.1.19" + pretty-format "^26.6.2" react-test-renderer "^16.8.0 || ^17.0.0" - read-pkg-up "^7.0.0" + read-pkg-up "^7.0.1" regenerator-runtime "^0.13.7" ts-dedent "^2.0.0" -"@storybook/addon-toolbars@6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-6.1.20.tgz#a748cdf255607eba229809ab1e4ce51f811204e3" - integrity sha512-r+MGlY9MyGnlJQ6149GZOFnJ6rUZgrnX9RcpcuwOBmfZNUM0andnOlaV3L1s2LY+oEETDi/rqQkQcrr7jbO/wA== - dependencies: - "@storybook/addons" "6.1.20" - "@storybook/api" "6.1.20" - "@storybook/client-api" "6.1.20" - "@storybook/components" "6.1.20" - core-js "^3.0.1" - -"@storybook/addon-viewport@6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-6.1.20.tgz#42173010cecd5f762534b00c614deaa3a4d42381" - integrity sha512-Xh75q3eh29QYkgYUF7ZEc8/R4HcQjTPazsxxknYZKu+S5TZ1OhoToH74YOL7bDuMAMAco95zv4zHpW02/oYT0g== - dependencies: - "@storybook/addons" "6.1.20" - "@storybook/api" "6.1.20" - "@storybook/client-logger" "6.1.20" - "@storybook/components" "6.1.20" - "@storybook/core-events" "6.1.20" - "@storybook/theming" "6.1.20" - core-js "^3.0.1" - global "^4.3.2" - memoizerific "^1.11.3" - prop-types "^15.7.2" +"@storybook/addon-toolbars@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/addon-toolbars/-/addon-toolbars-6.3.12.tgz#bc0d420b3476c891c42f7b0ab3b457e9e5ef7ca5" + integrity sha512-8GvP6zmAfLPRnYRARSaIwLkQClLIRbflRh4HZoFk6IMjQLXZb4NL3JS5OLFKG+HRMMU2UQzfoSDqjI7k7ptyRw== + dependencies: + "@storybook/addons" "6.3.12" + "@storybook/api" "6.3.12" + "@storybook/client-api" "6.3.12" + "@storybook/components" "6.3.12" + "@storybook/theming" "6.3.12" + core-js "^3.8.2" regenerator-runtime "^0.13.7" -"@storybook/addons@6.1.20", "@storybook/addons@^6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-6.1.20.tgz#da01dabd6692919b719fcb30519d53ea80887097" - integrity sha512-kIhXYgF+ARNpYxO3qhz8yThDvKpaq+HDst8odPU9sCNEI66PSH6hrILhTmnffNnqdtY3LnKkU9rGVfZn+3TOTA== - dependencies: - "@storybook/api" "6.1.20" - "@storybook/channels" "6.1.20" - "@storybook/client-logger" "6.1.20" - "@storybook/core-events" "6.1.20" - "@storybook/router" "6.1.20" - "@storybook/theming" "6.1.20" - core-js "^3.0.1" - global "^4.3.2" +"@storybook/addon-viewport@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/addon-viewport/-/addon-viewport-6.3.12.tgz#2fd61e60644fb07185a662f75b3e9dad8ad14f01" + integrity sha512-TRjyfm85xouOPmXxeLdEIzXLfJZZ1ePQ7p/5yphDGBHdxMU4m4qiZr8wYpUaxHsRu/UB3dKfaOyGT+ivogbnbw== + dependencies: + "@storybook/addons" "6.3.12" + "@storybook/api" "6.3.12" + "@storybook/client-logger" "6.3.12" + "@storybook/components" "6.3.12" + "@storybook/core-events" "6.3.12" + "@storybook/theming" "6.3.12" + core-js "^3.8.2" + global "^4.4.0" + memoizerific "^1.11.3" + prop-types "^15.7.2" regenerator-runtime "^0.13.7" -"@storybook/api@6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/api/-/api-6.1.20.tgz#3738b0c859ead820b378ee94e936abcf0e2f7436" - integrity sha512-+Uvvj7B+0oGb83mOzNjFuxju3ColjJpgyDjNzD5jI2xCtGyau+c8Lr4rhI9xNc2Dw9b8gpfPmhkvEnBPmd/ecQ== - dependencies: - "@reach/router" "^1.3.3" - "@storybook/channels" "6.1.20" - "@storybook/client-logger" "6.1.20" - "@storybook/core-events" "6.1.20" - "@storybook/csf" "0.0.1" - "@storybook/router" "6.1.20" - "@storybook/semver" "^7.3.2" - "@storybook/theming" "6.1.20" - "@types/reach__router" "^1.3.7" - core-js "^3.0.1" - fast-deep-equal "^3.1.1" - global "^4.3.2" - lodash "^4.17.15" - memoizerific "^1.11.3" +"@storybook/addons@6.3.12", "@storybook/addons@^6.3.0", "@storybook/addons@^6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/addons/-/addons-6.3.12.tgz#8773dcc113c5086dfff722388b7b65580e43b65b" + integrity sha512-UgoMyr7Qr0FS3ezt8u6hMEcHgyynQS9ucr5mAwZky3wpXRPFyUTmMto9r4BBUdqyUvTUj/LRKIcmLBfj+/l0Fg== + dependencies: + "@storybook/api" "6.3.12" + "@storybook/channels" "6.3.12" + "@storybook/client-logger" "6.3.12" + "@storybook/core-events" "6.3.12" + "@storybook/router" "6.3.12" + "@storybook/theming" "6.3.12" + core-js "^3.8.2" + global "^4.4.0" regenerator-runtime "^0.13.7" - store2 "^2.7.1" - telejson "^5.0.2" - ts-dedent "^2.0.0" - util-deprecate "^1.0.2" -"@storybook/api@^6.1.20": - version "6.2.9" - resolved "https://registry.yarnpkg.com/@storybook/api/-/api-6.2.9.tgz#a9b46569192ad5d8da6435c9d63dc4b0c8463b51" - integrity sha512-okkA3HAScE9tGnYBrjTOcgzT+L1lRHNoEh3ZfGgh1u/XNEyHGNkj4grvkd6nX7BzRcYQ/l2VkcKCqmOjUnSkVQ== +"@storybook/api@6.3.12", "@storybook/api@^6.3.0", "@storybook/api@^6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/api/-/api-6.3.12.tgz#2845c20464d5348d676d09665e8ab527825ed7b5" + integrity sha512-LScRXUeCWEW/OP+jiooNMQICVdusv7azTmULxtm72fhkXFRiQs2CdRNTiqNg46JLLC9z95f1W+pGK66X6HiiQA== dependencies: "@reach/router" "^1.3.4" - "@storybook/channels" "6.2.9" - "@storybook/client-logger" "6.2.9" - "@storybook/core-events" "6.2.9" + "@storybook/channels" "6.3.12" + "@storybook/client-logger" "6.3.12" + "@storybook/core-events" "6.3.12" "@storybook/csf" "0.0.1" - "@storybook/router" "6.2.9" + "@storybook/router" "6.3.12" "@storybook/semver" "^7.3.2" - "@storybook/theming" "6.2.9" + "@storybook/theming" "6.3.12" "@types/reach__router" "^1.3.7" core-js "^3.8.2" fast-deep-equal "^3.1.3" @@ -4463,300 +4332,439 @@ qs "^6.10.0" regenerator-runtime "^0.13.7" store2 "^2.12.0" - telejson "^5.1.0" + telejson "^5.3.2" ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/channel-postmessage@6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-6.1.20.tgz#d23956e553ff7e5f022bd8496ee7a26defa57440" - integrity sha512-4/zUd48qBnhoD96M4yBK+RlMQmZid0FSUzc6w7mXXjDE7vmRrXgP5ppIwYlzo4mcNSA5wCJsEp4YKRgAfZAUxw== - dependencies: - "@storybook/channels" "6.1.20" - "@storybook/client-logger" "6.1.20" - "@storybook/core-events" "6.1.20" - core-js "^3.0.1" - global "^4.3.2" - qs "^6.6.0" - telejson "^5.0.2" - -"@storybook/channels@6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-6.1.20.tgz#8dc2763ffda301f3bda811cdcb19f8e88ff4ec80" - integrity sha512-UBvVf07LAUD6JTrk77f4qydS4v5hzjAHJWOfWO6b82oO5bu4hTXt/Rjj/TSz85Rl/NmM4GYAAPIfxJHg53TRTg== - dependencies: - core-js "^3.0.1" +"@storybook/builder-webpack4@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/builder-webpack4/-/builder-webpack4-6.3.12.tgz#288d541e2801892721c975259476022da695dbfe" + integrity sha512-Dlm5Fc1svqpFDnVPZdAaEBiM/IDZHMV3RfEGbUTY/ZC0q8b/Ug1czzp/w0aTIjOFRuBDcG6IcplikaqHL8CJLg== + dependencies: + "@babel/core" "^7.12.10" + "@babel/plugin-proposal-class-properties" "^7.12.1" + "@babel/plugin-proposal-decorators" "^7.12.12" + "@babel/plugin-proposal-export-default-from" "^7.12.1" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" + "@babel/plugin-proposal-object-rest-spread" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.12.7" + "@babel/plugin-proposal-private-methods" "^7.12.1" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-transform-arrow-functions" "^7.12.1" + "@babel/plugin-transform-block-scoping" "^7.12.12" + "@babel/plugin-transform-classes" "^7.12.1" + "@babel/plugin-transform-destructuring" "^7.12.1" + "@babel/plugin-transform-for-of" "^7.12.1" + "@babel/plugin-transform-parameters" "^7.12.1" + "@babel/plugin-transform-shorthand-properties" "^7.12.1" + "@babel/plugin-transform-spread" "^7.12.1" + "@babel/plugin-transform-template-literals" "^7.12.1" + "@babel/preset-env" "^7.12.11" + "@babel/preset-react" "^7.12.10" + "@babel/preset-typescript" "^7.12.7" + "@storybook/addons" "6.3.12" + "@storybook/api" "6.3.12" + "@storybook/channel-postmessage" "6.3.12" + "@storybook/channels" "6.3.12" + "@storybook/client-api" "6.3.12" + "@storybook/client-logger" "6.3.12" + "@storybook/components" "6.3.12" + "@storybook/core-common" "6.3.12" + "@storybook/core-events" "6.3.12" + "@storybook/node-logger" "6.3.12" + "@storybook/router" "6.3.12" + "@storybook/semver" "^7.3.2" + "@storybook/theming" "6.3.12" + "@storybook/ui" "6.3.12" + "@types/node" "^14.0.10" + "@types/webpack" "^4.41.26" + autoprefixer "^9.8.6" + babel-loader "^8.2.2" + babel-plugin-macros "^2.8.0" + babel-plugin-polyfill-corejs3 "^0.1.0" + case-sensitive-paths-webpack-plugin "^2.3.0" + core-js "^3.8.2" + css-loader "^3.6.0" + dotenv-webpack "^1.8.0" + file-loader "^6.2.0" + find-up "^5.0.0" + fork-ts-checker-webpack-plugin "^4.1.6" + fs-extra "^9.0.1" + glob "^7.1.6" + glob-promise "^3.4.0" + global "^4.4.0" + html-webpack-plugin "^4.0.0" + pnp-webpack-plugin "1.6.4" + postcss "^7.0.36" + postcss-flexbugs-fixes "^4.2.1" + postcss-loader "^4.2.0" + raw-loader "^4.0.2" + react-dev-utils "^11.0.3" + stable "^0.1.8" + style-loader "^1.3.0" + terser-webpack-plugin "^4.2.3" ts-dedent "^2.0.0" + url-loader "^4.1.1" util-deprecate "^1.0.2" + webpack "4" + webpack-dev-middleware "^3.7.3" + webpack-filter-warnings-plugin "^1.2.1" + webpack-hot-middleware "^2.25.0" + webpack-virtual-modules "^0.2.2" + +"@storybook/channel-postmessage@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/channel-postmessage/-/channel-postmessage-6.3.12.tgz#3ff9412ac0f445e3b8b44dd414e783a5a47ff7c1" + integrity sha512-Ou/2Ga3JRTZ/4sSv7ikMgUgLTeZMsXXWLXuscz4oaYhmOqAU9CrJw0G1NitwBgK/+qC83lEFSLujHkWcoQDOKg== + dependencies: + "@storybook/channels" "6.3.12" + "@storybook/client-logger" "6.3.12" + "@storybook/core-events" "6.3.12" + core-js "^3.8.2" + global "^4.4.0" + qs "^6.10.0" + telejson "^5.3.2" -"@storybook/channels@6.2.9": - version "6.2.9" - resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-6.2.9.tgz#a9fd7f25102cbec15fb56f76abf891b7b214e9de" - integrity sha512-6dC8Fb2ipNyOQXnUZMDeEUaJGH5DMLzyHlGLhVyDtrO5WR6bO8mQdkzf4+5dSKXgCBNX0BSkssXth4pDjn18rg== +"@storybook/channels@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/channels/-/channels-6.3.12.tgz#aa0d793895a8b211f0ad3459c61c1bcafd0093c7" + integrity sha512-l4sA+g1PdUV8YCbgs47fIKREdEQAKNdQIZw0b7BfTvY9t0x5yfBywgQhYON/lIeiNGz2OlIuD+VUtqYfCtNSyw== dependencies: core-js "^3.8.2" ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/client-api@6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-6.1.20.tgz#bf6fb3e247a599d2d6c7502898f336ff79e4df4c" - integrity sha512-QLM8h0h8HWkHRh3GYoO6PdwYX4No4/J7oYg6cNVhNbhA9l4a3HDLEyfBGojU4ZUDd2feJ8Sgml92UoP4Vrj0kg== +"@storybook/client-api@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/client-api/-/client-api-6.3.12.tgz#a0c6d72a871d1cb02b4b98675472839061e39b5b" + integrity sha512-xnW+lKKK2T774z+rOr9Wopt1aYTStfb86PSs9p3Fpnc2Btcftln+C3NtiHZl8Ccqft8Mz/chLGgewRui6tNI8g== dependencies: - "@storybook/addons" "6.1.20" - "@storybook/channel-postmessage" "6.1.20" - "@storybook/channels" "6.1.20" - "@storybook/client-logger" "6.1.20" - "@storybook/core-events" "6.1.20" + "@storybook/addons" "6.3.12" + "@storybook/channel-postmessage" "6.3.12" + "@storybook/channels" "6.3.12" + "@storybook/client-logger" "6.3.12" + "@storybook/core-events" "6.3.12" "@storybook/csf" "0.0.1" - "@types/qs" "^6.9.0" - "@types/webpack-env" "^1.15.3" - core-js "^3.0.1" - global "^4.3.2" - lodash "^4.17.15" + "@types/qs" "^6.9.5" + "@types/webpack-env" "^1.16.0" + core-js "^3.8.2" + global "^4.4.0" + lodash "^4.17.20" memoizerific "^1.11.3" - qs "^6.6.0" + qs "^6.10.0" regenerator-runtime "^0.13.7" stable "^0.1.8" - store2 "^2.7.1" + store2 "^2.12.0" ts-dedent "^2.0.0" util-deprecate "^1.0.2" -"@storybook/client-logger@6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-6.1.20.tgz#f78102bbf4d169c45c5202c1b01cb1e58140be30" - integrity sha512-UKq+5vRXZXcwLgjXEK/NoL61JXar51aSDwnPa4jEFXRpXvIbHZzr6U3TO6r2J2LkTEJO54V2k8F2wnZgUvm3QA== - dependencies: - core-js "^3.0.1" - global "^4.3.2" - -"@storybook/client-logger@6.2.9": - version "6.2.9" - resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-6.2.9.tgz#77c1ea39684ad2a2cf6836051b381fc5b354e132" - integrity sha512-IfOQZuvpjh66qBInQCJOb9S0dTGpzZ/Cxlcvokp+PYt95KztaWN3mPm+HaDQCeRsrWNe0Bpm1zuickcJ6dBOXg== +"@storybook/client-logger@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/client-logger/-/client-logger-6.3.12.tgz#6585c98923b49fcb25dbceeeb96ef2a83e28e0f4" + integrity sha512-zNDsamZvHnuqLznDdP9dUeGgQ9TyFh4ray3t1VGO7ZqWVZ2xtVCCXjDvMnOXI2ifMpX5UsrOvshIPeE9fMBmiQ== dependencies: core-js "^3.8.2" global "^4.4.0" -"@storybook/components@6.1.20", "@storybook/components@^6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/components/-/components-6.1.20.tgz#90834d76d50a17172f8c480e0f366ebade31e108" - integrity sha512-X4k2PF3Q60p3rgRkGtjWh0DWP9tqdwMRwDjA6TGj8WyRM2FdROlmH/hwRy9Op/cs2Yj8ApkUJk8AMUm3hBhYvQ== +"@storybook/components@6.3.12", "@storybook/components@^6.3.0", "@storybook/components@^6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/components/-/components-6.3.12.tgz#0c7967c60354c84afa20dfab4753105e49b1927d" + integrity sha512-kdQt8toUjynYAxDLrJzuG7YSNL6as1wJoyzNUaCfG06YPhvIAlKo7le9tS2mThVFN5e9nbKrW3N1V1sp6ypZXQ== dependencies: - "@popperjs/core" "^2.5.4" - "@storybook/client-logger" "6.1.20" + "@popperjs/core" "^2.6.0" + "@storybook/client-logger" "6.3.12" "@storybook/csf" "0.0.1" - "@storybook/theming" "6.1.20" - "@types/overlayscrollbars" "^1.9.0" - "@types/react-color" "^3.0.1" - "@types/react-syntax-highlighter" "11.0.4" - core-js "^3.0.1" - fast-deep-equal "^3.1.1" - global "^4.3.2" - lodash "^4.17.15" - markdown-to-jsx "^6.11.4" + "@storybook/theming" "6.3.12" + "@types/color-convert" "^2.0.0" + "@types/overlayscrollbars" "^1.12.0" + "@types/react-syntax-highlighter" "11.0.5" + color-convert "^2.0.1" + core-js "^3.8.2" + fast-deep-equal "^3.1.3" + global "^4.4.0" + lodash "^4.17.20" + markdown-to-jsx "^7.1.3" memoizerific "^1.11.3" - overlayscrollbars "^1.10.2" - polished "^3.4.4" - react-color "^2.17.0" + overlayscrollbars "^1.13.1" + polished "^4.0.5" + prop-types "^15.7.2" + react-colorful "^5.1.2" react-popper-tooltip "^3.1.1" - react-syntax-highlighter "^13.5.0" - react-textarea-autosize "^8.1.1" + react-syntax-highlighter "^13.5.3" + react-textarea-autosize "^8.3.0" regenerator-runtime "^0.13.7" ts-dedent "^2.0.0" + util-deprecate "^1.0.2" -"@storybook/core-events@6.1.20", "@storybook/core-events@^6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-6.1.20.tgz#a23fe6ff858c0a4c48f89beaca1e50be5ba0b598" - integrity sha512-OPKNCbETTrGGypxFzDtsE2cGdHDNolVSJv1mZ17fr9lquc5eyJJCAJ4HbPk+OocRuHBKEnc1/pcA+wWKBM+vnA== - dependencies: - core-js "^3.0.1" - -"@storybook/core-events@6.2.9": - version "6.2.9" - resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-6.2.9.tgz#4f12947cd15d1eb3c4109923657c012feef521cd" - integrity sha512-xQmbX/oYQK1QsAGN8hriXX5SUKOoTUe3L4dVaVHxJqy7MReRWJpprJmCpbAPJzWS6WCbDFfCM5kVEexHLOzJlQ== +"@storybook/core-client@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/core-client/-/core-client-6.3.12.tgz#fd01bfbc69c331f4451973a4e7597624dc3737e5" + integrity sha512-8Smd9BgZHJpAdevLKQYinwtjSyCZAuBMoetP4P5hnn53mWl0NFbrHFaAdT+yNchDLZQUbf7Y18VmIqEH+RCR5w== dependencies: + "@storybook/addons" "6.3.12" + "@storybook/channel-postmessage" "6.3.12" + "@storybook/client-api" "6.3.12" + "@storybook/client-logger" "6.3.12" + "@storybook/core-events" "6.3.12" + "@storybook/csf" "0.0.1" + "@storybook/ui" "6.3.12" + airbnb-js-shims "^2.2.1" + ansi-to-html "^0.6.11" core-js "^3.8.2" + global "^4.4.0" + lodash "^4.17.20" + qs "^6.10.0" + regenerator-runtime "^0.13.7" + ts-dedent "^2.0.0" + unfetch "^4.2.0" + util-deprecate "^1.0.2" -"@storybook/core@6.1.20", "@storybook/core@^6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/core/-/core-6.1.20.tgz#57e8a86305f7da6cdc13185299c4c5f4b90b7308" - integrity sha512-cXca0s+ixoouXwPXeUoE9sB5OEkOUpkGAA78W8MLP4IHlI09ZBFCmLP989JdcCT2EjFBQ1V/UudNkQHMlyIl2A== +"@storybook/core-common@6.3.12", "@storybook/core-common@^6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/core-common/-/core-common-6.3.12.tgz#95ce953d7efda44394b159322d6a2280c202f21c" + integrity sha512-xlHs2QXELq/moB4MuXjYOczaxU64BIseHsnFBLyboJYN6Yso3qihW5RB7cuJlGohkjb4JwY74dvfT4Ww66rkBA== dependencies: - "@babel/core" "^7.12.3" + "@babel/core" "^7.12.10" "@babel/plugin-proposal-class-properties" "^7.12.1" - "@babel/plugin-proposal-decorators" "^7.12.1" + "@babel/plugin-proposal-decorators" "^7.12.12" "@babel/plugin-proposal-export-default-from" "^7.12.1" "@babel/plugin-proposal-nullish-coalescing-operator" "^7.12.1" "@babel/plugin-proposal-object-rest-spread" "^7.12.1" - "@babel/plugin-proposal-optional-chaining" "^7.12.1" + "@babel/plugin-proposal-optional-chaining" "^7.12.7" "@babel/plugin-proposal-private-methods" "^7.12.1" "@babel/plugin-syntax-dynamic-import" "^7.8.3" "@babel/plugin-transform-arrow-functions" "^7.12.1" - "@babel/plugin-transform-block-scoping" "^7.12.1" + "@babel/plugin-transform-block-scoping" "^7.12.12" "@babel/plugin-transform-classes" "^7.12.1" "@babel/plugin-transform-destructuring" "^7.12.1" "@babel/plugin-transform-for-of" "^7.12.1" "@babel/plugin-transform-parameters" "^7.12.1" "@babel/plugin-transform-shorthand-properties" "^7.12.1" "@babel/plugin-transform-spread" "^7.12.1" - "@babel/plugin-transform-template-literals" "^7.12.1" - "@babel/preset-env" "^7.12.1" - "@babel/preset-react" "^7.12.1" - "@babel/preset-typescript" "^7.12.1" + "@babel/preset-env" "^7.12.11" + "@babel/preset-react" "^7.12.10" + "@babel/preset-typescript" "^7.12.7" "@babel/register" "^7.12.1" - "@storybook/addons" "6.1.20" - "@storybook/api" "6.1.20" - "@storybook/channel-postmessage" "6.1.20" - "@storybook/channels" "6.1.20" - "@storybook/client-api" "6.1.20" - "@storybook/client-logger" "6.1.20" - "@storybook/components" "6.1.20" - "@storybook/core-events" "6.1.20" - "@storybook/csf" "0.0.1" - "@storybook/node-logger" "6.1.20" - "@storybook/router" "6.1.20" + "@storybook/node-logger" "6.3.12" "@storybook/semver" "^7.3.2" - "@storybook/theming" "6.1.20" - "@storybook/ui" "6.1.20" "@types/glob-base" "^0.3.0" "@types/micromatch" "^4.0.1" - "@types/node-fetch" "^2.5.4" - airbnb-js-shims "^2.2.1" - ansi-to-html "^0.6.11" - autoprefixer "^9.7.2" - babel-loader "^8.0.6" - babel-plugin-emotion "^10.0.20" - babel-plugin-macros "^2.8.0" - babel-preset-minify "^0.5.0 || 0.6.0-alpha.5" - better-opn "^2.0.0" - boxen "^4.1.0" - case-sensitive-paths-webpack-plugin "^2.2.0" - chalk "^4.0.0" - cli-table3 "0.6.0" - commander "^5.0.0" - core-js "^3.0.1" - cpy "^8.1.1" - css-loader "^3.5.3" - detect-port "^1.3.0" - dotenv-webpack "^1.7.0" - ejs "^3.1.2" - express "^4.17.0" - file-loader "^6.0.0" + "@types/node" "^14.0.10" + "@types/pretty-hrtime" "^1.0.0" + babel-loader "^8.2.2" + babel-plugin-macros "^3.0.1" + babel-plugin-polyfill-corejs3 "^0.1.0" + chalk "^4.1.0" + core-js "^3.8.2" + express "^4.17.1" file-system-cache "^1.0.5" - find-up "^4.1.0" - fork-ts-checker-webpack-plugin "^4.1.4" - fs-extra "^9.0.0" + find-up "^5.0.0" + fork-ts-checker-webpack-plugin "^6.0.4" glob "^7.1.6" glob-base "^0.3.0" - glob-promise "^3.4.0" - global "^4.3.2" - html-webpack-plugin "^4.2.1" - inquirer "^7.0.0" - interpret "^2.0.0" - ip "^1.1.5" - json5 "^2.1.1" + interpret "^2.2.0" + json5 "^2.1.3" lazy-universal-dotenv "^3.0.1" micromatch "^4.0.2" - node-fetch "^2.6.0" - pkg-dir "^4.2.0" - pnp-webpack-plugin "1.6.4" - postcss-flexbugs-fixes "^4.1.0" - postcss-loader "^3.0.0" + pkg-dir "^5.0.0" pretty-hrtime "^1.0.3" - qs "^6.6.0" - raw-loader "^4.0.1" - react-dev-utils "^11.0.3" - regenerator-runtime "^0.13.7" resolve-from "^5.0.0" + ts-dedent "^2.0.0" + util-deprecate "^1.0.2" + webpack "4" + +"@storybook/core-events@6.3.12", "@storybook/core-events@^6.3.0", "@storybook/core-events@^6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/core-events/-/core-events-6.3.12.tgz#73f6271d485ef2576234e578bb07705b92805290" + integrity sha512-SXfD7xUUMazaeFkB92qOTUV8Y/RghE4SkEYe5slAdjeocSaH7Nz2WV0rqNEgChg0AQc+JUI66no8L9g0+lw4Gw== + dependencies: + core-js "^3.8.2" + +"@storybook/core-server@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/core-server/-/core-server-6.3.12.tgz#d906f823b263d78a4b087be98810b74191d263cd" + integrity sha512-T/Mdyi1FVkUycdyOnhXvoo3d9nYXLQFkmaJkltxBFLzAePAJUSgAsPL9odNC3+p8Nr2/UDsDzvu/Ow0IF0mzLQ== + dependencies: + "@discoveryjs/json-ext" "^0.5.3" + "@storybook/builder-webpack4" "6.3.12" + "@storybook/core-client" "6.3.12" + "@storybook/core-common" "6.3.12" + "@storybook/csf-tools" "6.3.12" + "@storybook/manager-webpack4" "6.3.12" + "@storybook/node-logger" "6.3.12" + "@storybook/semver" "^7.3.2" + "@types/node" "^14.0.10" + "@types/node-fetch" "^2.5.7" + "@types/pretty-hrtime" "^1.0.0" + "@types/webpack" "^4.41.26" + better-opn "^2.1.1" + boxen "^4.2.0" + chalk "^4.1.0" + cli-table3 "0.6.0" + commander "^6.2.1" + compression "^1.7.4" + core-js "^3.8.2" + cpy "^8.1.1" + detect-port "^1.3.0" + express "^4.17.1" + file-system-cache "^1.0.5" + fs-extra "^9.0.1" + globby "^11.0.2" + ip "^1.1.5" + node-fetch "^2.6.1" + pretty-hrtime "^1.0.3" + prompts "^2.4.0" + regenerator-runtime "^0.13.7" serve-favicon "^2.5.0" - shelljs "^0.8.4" - stable "^0.1.8" - style-loader "^1.2.1" - telejson "^5.0.2" - terser-webpack-plugin "^3.0.0" ts-dedent "^2.0.0" - unfetch "^4.1.0" - url-loader "^4.0.0" util-deprecate "^1.0.2" - webpack "^4.44.2" - webpack-dev-middleware "^3.7.0" - webpack-filter-warnings-plugin "^1.2.1" - webpack-hot-middleware "^2.25.0" - webpack-virtual-modules "^0.2.2" + webpack "4" + +"@storybook/core@6.3.12", "@storybook/core@^6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/core/-/core-6.3.12.tgz#eb945f7ed5c9039493318bcd2bb5a3a897b91cfd" + integrity sha512-FJm2ns8wk85hXWKslLWiUWRWwS9KWRq7jlkN6M9p57ghFseSGr4W71Orcoab4P3M7jI97l5yqBfppbscinE74g== + dependencies: + "@storybook/core-client" "6.3.12" + "@storybook/core-server" "6.3.12" + +"@storybook/csf-tools@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/csf-tools/-/csf-tools-6.3.12.tgz#d979c6a79d1e9d6c8b5a5e8834d07fcf5b793844" + integrity sha512-wNrX+99ajAXxLo0iRwrqw65MLvCV6SFC0XoPLYrtBvyKr+hXOOnzIhO2f5BNEii8velpC2gl2gcLKeacpVYLqA== + dependencies: + "@babel/generator" "^7.12.11" + "@babel/parser" "^7.12.11" + "@babel/plugin-transform-react-jsx" "^7.12.12" + "@babel/preset-env" "^7.12.11" + "@babel/traverse" "^7.12.11" + "@babel/types" "^7.12.11" + "@mdx-js/mdx" "^1.6.22" + "@storybook/csf" "^0.0.1" + core-js "^3.8.2" + fs-extra "^9.0.1" + js-string-escape "^1.0.1" + lodash "^4.17.20" + prettier "~2.2.1" + regenerator-runtime "^0.13.7" -"@storybook/csf@0.0.1": +"@storybook/csf@0.0.1", "@storybook/csf@^0.0.1": version "0.0.1" resolved "https://registry.yarnpkg.com/@storybook/csf/-/csf-0.0.1.tgz#95901507dc02f0bc6f9ac8ee1983e2fc5bb98ce6" integrity sha512-USTLkZze5gkel8MYCujSRBVIrUQ3YPBrLOx7GNk/0wttvVtlzWXAq9eLbQ4p/NicGxP+3T7KPEMVV//g+yubpw== dependencies: lodash "^4.17.15" -"@storybook/node-logger@6.1.20", "@storybook/node-logger@^6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-6.1.20.tgz#40ec44bfd36e799089c831ecb86588c730023e6c" - integrity sha512-Z6337htb1mxIccvCx2Ai0v9LPDlBlmXzeWhap3q2Y6hg8g1p4+0W5Y6bG9RmXqJoXLaT1trO8uAXgGO7AN92yg== +"@storybook/manager-webpack4@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/manager-webpack4/-/manager-webpack4-6.3.12.tgz#1c10a60b0acec3f9136dd8b7f22a25469d8b91e5" + integrity sha512-OkPYNrHXg2yZfKmEfTokP6iKx4OLTr0gdI5yehi/bLEuQCSHeruxBc70Dxm1GBk1Mrf821wD9WqMXNDjY5Qtug== + dependencies: + "@babel/core" "^7.12.10" + "@babel/plugin-transform-template-literals" "^7.12.1" + "@babel/preset-react" "^7.12.10" + "@storybook/addons" "6.3.12" + "@storybook/core-client" "6.3.12" + "@storybook/core-common" "6.3.12" + "@storybook/node-logger" "6.3.12" + "@storybook/theming" "6.3.12" + "@storybook/ui" "6.3.12" + "@types/node" "^14.0.10" + "@types/webpack" "^4.41.26" + babel-loader "^8.2.2" + case-sensitive-paths-webpack-plugin "^2.3.0" + chalk "^4.1.0" + core-js "^3.8.2" + css-loader "^3.6.0" + dotenv-webpack "^1.8.0" + express "^4.17.1" + file-loader "^6.2.0" + file-system-cache "^1.0.5" + find-up "^5.0.0" + fs-extra "^9.0.1" + html-webpack-plugin "^4.0.0" + node-fetch "^2.6.1" + pnp-webpack-plugin "1.6.4" + read-pkg-up "^7.0.1" + regenerator-runtime "^0.13.7" + resolve-from "^5.0.0" + style-loader "^1.3.0" + telejson "^5.3.2" + terser-webpack-plugin "^4.2.3" + ts-dedent "^2.0.0" + url-loader "^4.1.1" + util-deprecate "^1.0.2" + webpack "4" + webpack-dev-middleware "^3.7.3" + webpack-virtual-modules "^0.2.2" + +"@storybook/node-logger@6.3.12", "@storybook/node-logger@^6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/node-logger/-/node-logger-6.3.12.tgz#a67cfbe266d2692f317914ef583721627498df19" + integrity sha512-iktOem/Ls2+dsZY9PhPeC6T1QhX/y7OInP88neLsqEPEbB2UXca3Ydv7OZBhBVbvN25W45b05MRzbtNUxYLNRw== dependencies: "@types/npmlog" "^4.1.2" - chalk "^4.0.0" - core-js "^3.0.1" + chalk "^4.1.0" + core-js "^3.8.2" npmlog "^4.1.2" pretty-hrtime "^1.0.3" -"@storybook/postinstall@6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/postinstall/-/postinstall-6.1.20.tgz#3e31f061f3f07f9a4955b970b963796734a45799" - integrity sha512-k9yLNN4T6KrvzWntU504NMesUQEg5YcsqKfNGjpTfKKRJjMR3+k74pbUZFC+XJEfMkCvSkWsJ2NRcE65bAMm3w== +"@storybook/postinstall@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/postinstall/-/postinstall-6.3.12.tgz#ed98caff76d8c1a1733ec630565ef4162b274614" + integrity sha512-HkZ+abtZ3W6JbGPS6K7OSnNXbwaTwNNd5R02kRs4gV9B29XsBPDtFT6vIwzM3tmVQC7ihL5a8ceWp2OvzaNOuw== dependencies: - core-js "^3.0.1" + core-js "^3.8.2" + +"@storybook/react-docgen-typescript-plugin@1.0.2-canary.253f8c1.0": + version "1.0.2-canary.253f8c1.0" + resolved "https://registry.yarnpkg.com/@storybook/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-1.0.2-canary.253f8c1.0.tgz#f2da40e6aae4aa586c2fb284a4a1744602c3c7fa" + integrity sha512-mmoRG/rNzAiTbh+vGP8d57dfcR2aP+5/Ll03KKFyfy5FqWFm/Gh7u27ikx1I3LmVMI8n6jh5SdWMkMKon7/tDw== + dependencies: + debug "^4.1.1" + endent "^2.0.1" + find-cache-dir "^3.3.1" + flat-cache "^3.0.4" + micromatch "^4.0.2" + react-docgen-typescript "^2.0.0" + tslib "^2.0.0" -"@storybook/react@^6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/react/-/react-6.1.20.tgz#0e2b858107fc139aa01a1d0fb2dca0611dd2224b" - integrity sha512-9NCWxLXJSjEy/DP9fC8Uj7zUljPA6eREjZuNElHGRI/Tg5R/QBuQnBJX9EagLic1lzpcUbsfWJ/+Bpa2qLXAEw== +"@storybook/react@^6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/react/-/react-6.3.12.tgz#2e172cbfc06f656d2890743dcf49741a10fa1629" + integrity sha512-c1Y/3/eNzye+ZRwQ3BXJux6pUMVt3lhv1/M9Qagl9JItP3jDSj5Ed3JHCgwEqpprP8mvNNXwEJ8+M7vEQyDuHg== dependencies: "@babel/preset-flow" "^7.12.1" - "@babel/preset-react" "^7.12.1" - "@pmmmwh/react-refresh-webpack-plugin" "^0.4.2" - "@storybook/addons" "6.1.20" - "@storybook/core" "6.1.20" - "@storybook/node-logger" "6.1.20" + "@babel/preset-react" "^7.12.10" + "@pmmmwh/react-refresh-webpack-plugin" "^0.4.3" + "@storybook/addons" "6.3.12" + "@storybook/core" "6.3.12" + "@storybook/core-common" "6.3.12" + "@storybook/node-logger" "6.3.12" + "@storybook/react-docgen-typescript-plugin" "1.0.2-canary.253f8c1.0" "@storybook/semver" "^7.3.2" - "@types/webpack-env" "^1.15.3" + "@types/webpack-env" "^1.16.0" babel-plugin-add-react-displayname "^0.0.5" babel-plugin-named-asset-import "^0.3.1" babel-plugin-react-docgen "^4.2.1" - core-js "^3.0.1" - global "^4.3.2" - lodash "^4.17.15" + core-js "^3.8.2" + global "^4.4.0" + lodash "^4.17.20" prop-types "^15.7.2" react-dev-utils "^11.0.3" - react-docgen-typescript-plugin "^0.6.2" react-refresh "^0.8.3" + read-pkg-up "^7.0.1" regenerator-runtime "^0.13.7" ts-dedent "^2.0.0" - webpack "^4.44.2" + webpack "4" -"@storybook/router@6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/router/-/router-6.1.20.tgz#8d27379f53439762f503d77ce4ec2e9ac80644b4" - integrity sha512-hIJiy60znxu9fJgnFP3n5C9YdWr/bHk77vowf0nO0v+dd59EKlgh7ibiDi48Fe2PMU95pYGb6mCDouNS+boN0w== - dependencies: - "@reach/router" "^1.3.3" - "@types/reach__router" "^1.3.7" - core-js "^3.0.1" - global "^4.3.2" - memoizerific "^1.11.3" - qs "^6.6.0" - -"@storybook/router@6.2.9": - version "6.2.9" - resolved "https://registry.yarnpkg.com/@storybook/router/-/router-6.2.9.tgz#547543031dd8330870bb6b473dcf7e51982e841c" - integrity sha512-7Bn1OFoItCl8whXRT8N1qp1Lky7kzXJ3aslWp5E8HcM8rxh4OYXfbaeiyJEJxBTGC5zxgY+tAEXHFjsAviFROg== +"@storybook/router@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/router/-/router-6.3.12.tgz#0d572ec795f588ca886f39cb9b27b94ff3683f84" + integrity sha512-G/pNGCnrJRetCwyEZulHPT+YOcqEj/vkPVDTUfii2qgqukup6K0cjwgd7IukAURnAnnzTi1gmgFuEKUi8GE/KA== dependencies: "@reach/router" "^1.3.4" - "@storybook/client-logger" "6.2.9" + "@storybook/client-logger" "6.3.12" "@types/reach__router" "^1.3.7" core-js "^3.8.2" fast-deep-equal "^3.1.3" @@ -4774,55 +4782,36 @@ core-js "^3.6.5" find-up "^4.1.0" -"@storybook/source-loader@6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/source-loader/-/source-loader-6.1.20.tgz#884f982430a422063a8a0edee0af1d72dabc75d2" - integrity sha512-rxfh+6JoPrw9RIB+yQ81VpRt586rlLC6mNeGthuwq1KLrw6j4B6Uk3VK0zE1mWdqVfVZZH3SuzM/KEGK86XlTg== +"@storybook/source-loader@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/source-loader/-/source-loader-6.3.12.tgz#86e72824c04ad0eaa89b807857bd845db97e57bd" + integrity sha512-Lfe0LOJGqAJYkZsCL8fhuQOeFSCgv8xwQCt4dkcBd0Rw5zT2xv0IXDOiIOXGaWBMDtrJUZt/qOXPEPlL81Oaqg== dependencies: - "@storybook/addons" "6.1.20" - "@storybook/client-logger" "6.1.20" + "@storybook/addons" "6.3.12" + "@storybook/client-logger" "6.3.12" "@storybook/csf" "0.0.1" - core-js "^3.0.1" - estraverse "^4.2.0" - global "^4.3.2" + core-js "^3.8.2" + estraverse "^5.2.0" + global "^4.4.0" loader-utils "^2.0.0" - lodash "^4.17.15" - prettier "~2.0.5" + lodash "^4.17.20" + prettier "~2.2.1" regenerator-runtime "^0.13.7" - source-map "^0.7.3" - -"@storybook/testing-react@^0.0.17": - version "0.0.17" - resolved "https://registry.yarnpkg.com/@storybook/testing-react/-/testing-react-0.0.17.tgz#632dd22f8815743f78c182b126f444cf51d92d71" - integrity sha512-93nbA/JSWDEys1msd438+wzETRFDEgT2aFqJL2y46++zsyv8g2mCYKZkf9E36KQHMQbO1uJBHT8CmrLQa8VmZw== -"@storybook/theming@6.1.20", "@storybook/theming@^6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.1.20.tgz#ed0b330a5c08bbe998e9df95e615f0e84a8d663f" - integrity sha512-yg56fa4uhXs+oNmwSHw/jAt1sWpAfq2k6aP1FOtWiEI372g7ZYddP/0ENoj07R+8jZxkvafLNhMI20aIxXpvTQ== - dependencies: - "@emotion/core" "^10.1.1" - "@emotion/is-prop-valid" "^0.8.6" - "@emotion/styled" "^10.0.23" - "@storybook/client-logger" "6.1.20" - core-js "^3.0.1" - deep-object-diff "^1.1.0" - emotion-theming "^10.0.19" - global "^4.3.2" - memoizerific "^1.11.3" - polished "^3.4.4" - resolve-from "^5.0.0" - ts-dedent "^2.0.0" +"@storybook/testing-react@^0.0.22": + version "0.0.22" + resolved "https://registry.yarnpkg.com/@storybook/testing-react/-/testing-react-0.0.22.tgz#65d3defefbac0183eded0dafb601241d8f135c66" + integrity sha512-XBJpH1cROXkwwKwD89kIcyhyMPEN5zfSyOUanrN+/Tx4nB5IwzVc/Om+7mtSFvh4UTSNOk5G42Y12KE/HbH7VA== -"@storybook/theming@6.2.9": - version "6.2.9" - resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.2.9.tgz#16bf40180861f222c7ed1d80abd5d1e3cb315660" - integrity sha512-183oJW7AD7Fhqg5NT4ct3GJntwteAb9jZnQ6yhf9JSdY+fk8OhxRbPf7ov0au2gYACcGrWDd9K5pYQsvWlP5gA== +"@storybook/theming@6.3.12", "@storybook/theming@^6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/theming/-/theming-6.3.12.tgz#5bddf9bd90a60709b5ab238ecdb7d9055dd7862e" + integrity sha512-wOJdTEa/VFyFB2UyoqyYGaZdym6EN7RALuQOAMT6zHA282FBmKw8nL5DETHEbctpnHdcrMC/391teK4nNSrdOA== dependencies: "@emotion/core" "^10.1.1" "@emotion/is-prop-valid" "^0.8.6" "@emotion/styled" "^10.0.27" - "@storybook/client-logger" "6.2.9" + "@storybook/client-logger" "6.3.12" core-js "^3.8.2" deep-object-diff "^1.1.0" emotion-theming "^10.0.27" @@ -4832,41 +4821,40 @@ resolve-from "^5.0.0" ts-dedent "^2.0.0" -"@storybook/ui@6.1.20": - version "6.1.20" - resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-6.1.20.tgz#ba585e2f600257e9168e8e5cb704c63593daeb69" - integrity sha512-XKsSgPjoThIzyxltJercXWRFErF99qOVJWYYCZ6/K0WuYHR4wncRPwN9/ur7BboWFJGWlCJll7fredFAmidP+g== +"@storybook/ui@6.3.12": + version "6.3.12" + resolved "https://registry.yarnpkg.com/@storybook/ui/-/ui-6.3.12.tgz#349e1a4c58c4fd18ea65b2ab56269a7c3a164ee7" + integrity sha512-PC2yEz4JMfarq7rUFbeA3hCA+31p5es7YPEtxLRvRwIZhtL0P4zQUfHpotb3KgWdoAIfZesAuoIQwMPQmEFYrw== dependencies: "@emotion/core" "^10.1.1" - "@storybook/addons" "6.1.20" - "@storybook/api" "6.1.20" - "@storybook/channels" "6.1.20" - "@storybook/client-logger" "6.1.20" - "@storybook/components" "6.1.20" - "@storybook/core-events" "6.1.20" - "@storybook/router" "6.1.20" + "@storybook/addons" "6.3.12" + "@storybook/api" "6.3.12" + "@storybook/channels" "6.3.12" + "@storybook/client-logger" "6.3.12" + "@storybook/components" "6.3.12" + "@storybook/core-events" "6.3.12" + "@storybook/router" "6.3.12" "@storybook/semver" "^7.3.2" - "@storybook/theming" "6.1.20" - "@types/markdown-to-jsx" "^6.11.0" - copy-to-clipboard "^3.0.8" - core-js "^3.0.1" - core-js-pure "^3.0.1" - downshift "^6.0.6" - emotion-theming "^10.0.19" + "@storybook/theming" "6.3.12" + "@types/markdown-to-jsx" "^6.11.3" + copy-to-clipboard "^3.3.1" + core-js "^3.8.2" + core-js-pure "^3.8.2" + downshift "^6.0.15" + emotion-theming "^10.0.27" fuse.js "^3.6.1" - global "^4.3.2" - lodash "^4.17.15" + global "^4.4.0" + lodash "^4.17.20" markdown-to-jsx "^6.11.4" memoizerific "^1.11.3" - polished "^3.4.4" - qs "^6.6.0" - react-draggable "^4.0.3" - react-helmet-async "^1.0.2" - react-hotkeys "2.0.0" - react-sizeme "^2.6.7" + polished "^4.0.5" + qs "^6.10.0" + react-draggable "^4.4.3" + react-helmet-async "^1.0.7" + react-sizeme "^3.0.1" regenerator-runtime "^0.13.7" resolve-from "^5.0.0" - store2 "^2.7.1" + store2 "^2.12.0" "@stylelint/postcss-css-in-js@^0.37.2": version "0.37.2" @@ -5143,11 +5131,6 @@ dependencies: "@turf/helpers" "6.x" -"@types/anymatch@*": - version "1.3.1" - resolved "https://registry.yarnpkg.com/@types/anymatch/-/anymatch-1.3.1.tgz#336badc1beecb9dacc38bea2cf32adf627a8421a" - integrity sha512-/+CRPXpBDpo2RK9C68N3b2cOvO0Cf5B9aPijHsoDQTHivnGSObdOF2BRQOYjojWTDy6nQvMjmqRXIxH55VjxxA== - "@types/apidoc@^0.22.3": version "0.22.3" resolved "https://registry.yarnpkg.com/@types/apidoc/-/apidoc-0.22.3.tgz#0227f4b8189b5cde42d23ed81a858526959fc2b7" @@ -5219,6 +5202,14 @@ resolved "https://registry.yarnpkg.com/@types/base64-js/-/base64-js-1.2.5.tgz#582b2476169a6cba460a214d476c744441d873d5" integrity sha1-WCskdhaabLpGCiFNR2x0REHYc9U= +"@types/body-parser@*": + version "1.19.2" + resolved "https://registry.yarnpkg.com/@types/body-parser/-/body-parser-1.19.2.tgz#aea2059e28b7658639081347ac4fab3de166e6f0" + integrity sha512-ALYone6pm6QmwZoAgeyNksccT9Q4AWZQ6PvfwR37GT6r6FWUPguq6sUmNGSMV2Wr761oQoBxwGGa6DR5o1DC9g== + dependencies: + "@types/connect" "*" + "@types/node" "*" + "@types/braces@*": version "3.0.0" resolved "https://registry.yarnpkg.com/@types/braces/-/braces-3.0.0.tgz#7da1c0d44ff1c7eb660a36ec078ea61ba7eb42cb" @@ -5285,6 +5276,13 @@ dependencies: "@types/color-name" "*" +"@types/color-convert@^2.0.0": + version "2.0.0" + resolved "https://registry.yarnpkg.com/@types/color-convert/-/color-convert-2.0.0.tgz#8f5ee6b9e863dcbee5703f5a517ffb13d3ea4e22" + integrity sha512-m7GG7IKKGuJUXvkZ1qqG3ChccdIM/qBBo913z+Xft0nKCX4hAU/IxKwZBU4cpRZ7GS5kV4vOblUkILtSShCPXQ== + dependencies: + "@types/color-name" "*" + "@types/color-name@*", "@types/color-name@^1.1.1": version "1.1.1" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" @@ -5304,6 +5302,13 @@ dependencies: "@types/webpack" "*" +"@types/connect@*": + version "3.4.35" + resolved "https://registry.yarnpkg.com/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1" + integrity sha512-cdeYyv4KWoEgpBISTxWvqYsVy444DOqehiF3fM3ne10AmJ62RSyNkUnxMJXHQWRQQX2eR94m5y1IZyDwBjV9FQ== + dependencies: + "@types/node" "*" + "@types/cookiejar@*": version "2.1.0" resolved "https://registry.yarnpkg.com/@types/cookiejar/-/cookiejar-2.1.0.tgz#4b7daf2c51696cfc70b942c11690528229d1a1ce" @@ -5429,6 +5434,25 @@ resolved "https://registry.yarnpkg.com/@types/expect/-/expect-1.20.4.tgz#8288e51737bf7e3ab5d7c77bfa695883745264e5" integrity sha512-Q5Vn3yjTDyCMV50TB6VRIbQNxSE4OmZR86VSbGaNpfUolm0iePBB4KdEEHmxoY5sT2+2DIvXW0rvMDP2nHZ4Mg== +"@types/express-serve-static-core@^4.17.18": + version "4.17.25" + resolved "https://registry.yarnpkg.com/@types/express-serve-static-core/-/express-serve-static-core-4.17.25.tgz#e42f7046adc65ece2eb6059b77aecfbe9e9f82e0" + integrity sha512-OUJIVfRMFijZukGGwTpKNFprqCCXk5WjNGvUgB/CxxBR40QWSjsNK86+yvGKlCOGc7sbwfHLaXhkG+NsytwBaQ== + dependencies: + "@types/node" "*" + "@types/qs" "*" + "@types/range-parser" "*" + +"@types/express@^4.17.13": + version "4.17.13" + resolved "https://registry.yarnpkg.com/@types/express/-/express-4.17.13.tgz#a76e2995728999bab51a33fabce1d705a3709034" + integrity sha512-6bSZTPaTIACxn48l50SR+axgrqm6qXFIxrdAKaG6PaJk3+zuUr35hBlgT7vOmJcum+OEaIBLtHV/qloEAFITeA== + dependencies: + "@types/body-parser" "*" + "@types/express-serve-static-core" "^4.17.18" + "@types/qs" "*" + "@types/serve-static" "*" + "@types/extract-zip@^1.6.2": version "1.6.2" resolved "https://registry.yarnpkg.com/@types/extract-zip/-/extract-zip-1.6.2.tgz#5c7eb441c41136167a42b88b64051e6260c29e86" @@ -5501,7 +5525,7 @@ "@types/glob" "*" "@types/node" "*" -"@types/glob@*", "@types/glob@^7.1.1", "@types/glob@^7.1.2": +"@types/glob@*", "@types/glob@^7.1.1", "@types/glob@^7.1.2", "@types/glob@^7.1.3": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/glob/-/glob-7.1.3.tgz#e6ba80f36b7daad2c685acd9266382e68985c183" integrity sha512-SEYeGAIQIQX8NN6LDKprLjbrd5dARM5EXsd8GI/A5l0apYI1fGMWgPHSe4ZKL4eozlAyI+doUE9XbYS4xCkQ1w== @@ -5708,7 +5732,7 @@ dependencies: "@types/jest" "*" -"@types/jest@*", "@types/jest@^26.0.22": +"@types/jest@*", "@types/jest@^26.0.16", "@types/jest@^26.0.22": version "26.0.22" resolved "https://registry.yarnpkg.com/@types/jest/-/jest-26.0.22.tgz#8308a1debdf1b807aa47be2838acdcd91e88fbe6" integrity sha512-eeWwWjlqxvBxc4oQdkueW5OF/gtfSceKk4OnOAGlUSwS/liBRtZppbJuz1YkgbrbfGOoeBHun9fOvXnjNwrSOw== @@ -5716,14 +5740,6 @@ jest-diff "^26.0.0" pretty-format "^26.0.0" -"@types/jest@^25.1.1": - version "25.2.3" - resolved "https://registry.yarnpkg.com/@types/jest/-/jest-25.2.3.tgz#33d27e4c4716caae4eced355097a47ad363fdcaf" - integrity sha512-JXc1nK/tXHiDhV55dvfzqtmP4S3sy3T3ouV2tkViZgxY/zeUkcpQcQPGRlgF4KmWzWW5oiWYSZwtCB+2RsE4Fw== - dependencies: - jest-diff "^25.2.1" - pretty-format "^25.2.1" - "@types/joi@^17.2.3": version "17.2.3" resolved "https://registry.yarnpkg.com/@types/joi/-/joi-17.2.3.tgz#b7768ed9d84f1ebd393328b9f97c1cf3d2b94798" @@ -5767,7 +5783,7 @@ "@types/parse5" "*" "@types/tough-cookie" "*" -"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.6", "@types/json-schema@^7.0.7", "@types/json-schema@^7.0.9": +"@types/json-schema@*", "@types/json-schema@^7.0.4", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6", "@types/json-schema@^7.0.7", "@types/json-schema@^7.0.9": version "7.0.9" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.9.tgz#97edc9037ea0c38585320b28964dde3b39e4660d" integrity sha512-qcUXuemtEu+E5wZSJHNxUXeCZhAfXKQ41D+duX+VYPde7xyEVZci+/oXKJL13tnRs9lR2pr4fod59GT6/X1/yQ== @@ -5885,10 +5901,10 @@ dependencies: "@types/linkify-it" "*" -"@types/markdown-to-jsx@^6.11.0": - version "6.11.1" - resolved "https://registry.yarnpkg.com/@types/markdown-to-jsx/-/markdown-to-jsx-6.11.1.tgz#4d9464aa76337d798b874dd3f2d6b4c86ddd98ad" - integrity sha512-fm/II24OzSx7J7CzXnHjEIf0d+s82bmdcokbyzY7PFMUnhyhnuGJgedt8R+yZgDn1mqhCLHmMjBPMsL8K4Xp9g== +"@types/markdown-to-jsx@^6.11.3": + version "6.11.3" + resolved "https://registry.yarnpkg.com/@types/markdown-to-jsx/-/markdown-to-jsx-6.11.3.tgz#cdd1619308fecbc8be7e6a26f3751260249b020e" + integrity sha512-30nFYpceM/ZEvhGiqWjm5quLUxNeld0HCzJEXMZZDpq53FPkS85mTwkWtCXzCqq8s5JYLgM5W392a02xn8Bdaw== dependencies: "@types/react" "*" @@ -5928,6 +5944,11 @@ resolved "https://registry.yarnpkg.com/@types/mime-types/-/mime-types-2.1.0.tgz#9ca52cda363f699c69466c2a6ccdaad913ea7a73" integrity sha1-nKUs2jY/aZxpRmwqbM2q2RPqenM= +"@types/mime@^1": + version "1.3.2" + resolved "https://registry.yarnpkg.com/@types/mime/-/mime-1.3.2.tgz#93e25bf9ee75fe0fd80b594bc4feb0e862111b5a" + integrity sha512-YATxVxgRqNH6nHEIsvg6k2Boc1JHI9ZbH5iWFFv/MTkchz3b1ieGDa5T0a9RznNdI0KhVbdbWSN+KWWrQZRxTw== + "@types/mime@^2.0.1": version "2.0.1" resolved "https://registry.yarnpkg.com/@types/mime/-/mime-2.0.1.tgz#dc488842312a7f075149312905b5e3c0b054c79d" @@ -5993,7 +6014,7 @@ dependencies: "@types/node" "*" -"@types/node-fetch@^2.5.4", "@types/node-fetch@^2.5.7": +"@types/node-fetch@^2.5.7": version "2.5.7" resolved "https://registry.yarnpkg.com/@types/node-fetch/-/node-fetch-2.5.7.tgz#20a2afffa882ab04d44ca786449a276f9f6bbf3c" integrity sha512-o2WVNf5UhWRkxlf6eq+jMZDu7kjgpgJfl4xVNlvryc95O/6F2ld8ztKX+qu+Rjyet93WAWm5LjeX9H5FGkODvw== @@ -6015,7 +6036,7 @@ dependencies: "@types/node" "*" -"@types/node@*", "@types/node@12.20.24", "@types/node@16.10.2", "@types/node@>= 8", "@types/node@>=8.9.0", "@types/node@^10.1.0", "@types/node@^14.14.31": +"@types/node@*", "@types/node@12.20.24", "@types/node@16.10.2", "@types/node@>= 8", "@types/node@>=8.9.0", "@types/node@^10.1.0", "@types/node@^14.0.10", "@types/node@^14.14.31": version "16.10.2" resolved "https://registry.yarnpkg.com/@types/node/-/node-16.10.2.tgz#5764ca9aa94470adb4e1185fe2e9f19458992b2e" integrity sha512-zCclL4/rx+W5SQTzFs9wyvvyCwoK9QtBpratqz2IYJ3O8Umrn0m3nsTv0wQBk9sRGpvUe9CwPDrQFB10f1FIjQ== @@ -6068,7 +6089,7 @@ dependencies: "@types/node" "*" -"@types/overlayscrollbars@^1.9.0": +"@types/overlayscrollbars@^1.12.0": version "1.12.0" resolved "https://registry.yarnpkg.com/@types/overlayscrollbars/-/overlayscrollbars-1.12.0.tgz#98456caceca8ad73bd5bb572632a585074e70764" integrity sha512-h/pScHNKi4mb+TrJGDon8Yb06ujFG0mSg12wIO0sWMUF3dQIe2ExRRdNRviaNt9IjxIiOfnRr7FsQAdHwK4sMg== @@ -6127,6 +6148,11 @@ resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-2.3.2.tgz#fc8c2825e4ed2142473b4a81064e6e081463d1b3" integrity sha512-eI5Yrz3Qv4KPUa/nSIAi0h+qX0XyewOliug5F2QAtuRg6Kjg6jfmxe1GIwoIRhZspD1A0RP8ANrPwvEXXtRFog== +"@types/pretty-hrtime@^1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@types/pretty-hrtime/-/pretty-hrtime-1.0.1.tgz#72a26101dc567b0d68fd956cf42314556e42d601" + integrity sha512-VjID5MJb1eGKthz2qUerWT8+R4b9N+CHvGCzg9fn4kWZgaF9AhdYikQio3R7wV8YY1NsQKPaCwKz1Yff+aHNUQ== + "@types/pretty-ms@^5.0.0": version "5.0.1" resolved "https://registry.yarnpkg.com/@types/pretty-ms/-/pretty-ms-5.0.1.tgz#f2f0d7be58caf8613d149053d446e0282ae11ff3" @@ -6154,10 +6180,15 @@ resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.4.tgz#15925414e0ad2cd765bfef58842f7e26a7accb24" integrity sha512-1HcDas8SEj4z1Wc696tH56G8OlRaH/sqZOynNNB+HF0WOeXPaxTtbYzJY2oEfiUxjSKjhCKr+MvR7dCHcEelug== -"@types/qs@^6.9.0": - version "6.9.4" - resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.4.tgz#a59e851c1ba16c0513ea123830dd639a0a15cb6a" - integrity sha512-+wYo+L6ZF6BMoEjtf8zB2esQsqdV6WsjRK/GP9WOgLPrq87PbNWgIxS76dS5uvl/QXtHGakZmwTznIfcPXcKlQ== +"@types/qs@*", "@types/qs@^6.9.5": + version "6.9.7" + resolved "https://registry.yarnpkg.com/@types/qs/-/qs-6.9.7.tgz#63bb7d067db107cc1e457c303bc25d511febf6cb" + integrity sha512-FGa1F62FT09qcrueBA6qYTrJPVDzah9a+493+o2PCXsesWHIn27G98TsSMs3WPNbZIEj4+VJf6saSFpvD+3Zsw== + +"@types/range-parser@*": + version "1.2.4" + resolved "https://registry.yarnpkg.com/@types/range-parser/-/range-parser-1.2.4.tgz#cd667bcfdd025213aafb7ca5915a932590acdcdc" + integrity sha512-EEhsLsD6UsDM1yFhAvy0Cjr6VwmpMWqFBCb9w07wVugF7w9nfajxLuVmngTIpgS6svCnm6Vaw+MZhoDCKnOfsw== "@types/rbush@^3.0.0": version "3.0.0" @@ -6178,13 +6209,6 @@ dependencies: "@types/react" "*" -"@types/react-color@^3.0.1": - version "3.0.1" - resolved "https://registry.yarnpkg.com/@types/react-color/-/react-color-3.0.1.tgz#5433e2f503ea0e0831cbc6fd0c20f8157d93add0" - integrity sha512-J6mYm43Sid9y+OjZ7NDfJ2VVkeeuTPNVImNFITgQNXodHteKfl/t/5pAR5Z9buodZ2tCctsZjgiMlQOpfntakw== - dependencies: - "@types/react" "*" - "@types/react-dom@>=16.9.0", "@types/react-dom@^16.9.8": version "16.9.8" resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-16.9.8.tgz#fe4c1e11dfc67155733dfa6aa65108b4971cb423" @@ -6262,10 +6286,10 @@ "@types/history" "*" "@types/react" "*" -"@types/react-syntax-highlighter@11.0.4": - version "11.0.4" - resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.4.tgz#d86d17697db62f98046874f62fdb3e53a0bbc4cd" - integrity sha512-9GfTo3a0PHwQeTVoqs0g5bS28KkSY48pp5659wA+Dp4MqceDEa8EHBqrllJvvtyusszyJhViUEap0FDvlk/9Zg== +"@types/react-syntax-highlighter@11.0.5": + version "11.0.5" + resolved "https://registry.yarnpkg.com/@types/react-syntax-highlighter/-/react-syntax-highlighter-11.0.5.tgz#0d546261b4021e1f9d85b50401c0a42acb106087" + integrity sha512-VIOi9i2Oj5XsmWWoB72p3KlZoEbdRAcechJa8Ztebw7bDl2YmR+odxIqhtJGp1q2EozHs02US+gzxJ9nuf56qg== dependencies: "@types/react" "*" @@ -6385,6 +6409,14 @@ resolved "https://registry.yarnpkg.com/@types/semver/-/semver-7.3.4.tgz#43d7168fec6fa0988bb1a513a697b29296721afb" integrity sha512-+nVsLKlcUCeMzD2ufHEYuJ9a2ovstb6Dp52A5VsoKxDXgvE051XgHI/33I1EymwkRGQkwnA0LkhnUzituGs4EQ== +"@types/serve-static@*": + version "1.13.10" + resolved "https://registry.yarnpkg.com/@types/serve-static/-/serve-static-1.13.10.tgz#f5e0ce8797d2d7cc5ebeda48a52c96c4fa47a8d9" + integrity sha512-nCkHGI4w7ZgAdNkrEu0bv+4xNV/XDqW+DydknebMOQwkpDGx8G+HTlj7R7ABI8i8nKxVw0wtKPi1D+lPOkh4YQ== + dependencies: + "@types/mime" "^1" + "@types/node" "*" + "@types/set-value@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/set-value/-/set-value-2.0.0.tgz#63d386b103926dcf49b50e16e0f6dd49983046be" @@ -6471,7 +6503,7 @@ dependencies: "@types/superagent" "*" -"@types/tapable@*", "@types/tapable@^1.0.5", "@types/tapable@^1.0.6": +"@types/tapable@^1", "@types/tapable@^1.0.5", "@types/tapable@^1.0.6": version "1.0.6" resolved "https://registry.yarnpkg.com/@types/tapable/-/tapable-1.0.6.tgz#a9ca4b70a18b270ccb2bc0aaafefd1d486b7ea74" integrity sha512-W+bw9ds02rAQaMvaLYxAbJ6cvguW/iJXNT6lTssS1ps6QdrMKttqEAMEG/b5CR8TZl3/L7/lH0ZV5nNR1LXikA== @@ -6618,10 +6650,10 @@ "@types/node" "*" chokidar "^2.1.2" -"@types/webpack-env@^1.15.3": - version "1.15.3" - resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.15.3.tgz#fb602cd4c2f0b7c0fb857e922075fdf677d25d84" - integrity sha512-5oiXqR7kwDGZ6+gmzIO2lTC+QsriNuQXZDWNYRV3l2XRN/zmPgnC21DLSx2D05zvD8vnXW6qUg7JnXZ4I6qLVQ== +"@types/webpack-env@^1.15.3", "@types/webpack-env@^1.16.0": + version "1.16.3" + resolved "https://registry.yarnpkg.com/@types/webpack-env/-/webpack-env-1.16.3.tgz#b776327a73e561b71e7881d0cd6d34a1424db86a" + integrity sha512-9gtOPPkfyNoEqCQgx4qJKkuNm/x0R2hKR7fdl7zvTJyHnIisuE/LfvXOsYWL0o3qq6uiBnKZNNNzi3l0y/X+xw== "@types/webpack-merge@^4.1.5": version "4.1.5" @@ -6639,16 +6671,16 @@ "@types/source-list-map" "*" source-map "^0.6.1" -"@types/webpack@*", "@types/webpack@^4.4.31", "@types/webpack@^4.41.3", "@types/webpack@^4.41.8": - version "4.41.21" - resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.21.tgz#cc685b332c33f153bb2f5fc1fa3ac8adeb592dee" - integrity sha512-2j9WVnNrr/8PLAB5csW44xzQSJwS26aOnICsP3pSGCEdsu6KYtfQ6QJsVUKHWRnm1bL7HziJsfh5fHqth87yKA== +"@types/webpack@*", "@types/webpack@^4.4.31", "@types/webpack@^4.41.26", "@types/webpack@^4.41.3", "@types/webpack@^4.41.8": + version "4.41.32" + resolved "https://registry.yarnpkg.com/@types/webpack/-/webpack-4.41.32.tgz#a7bab03b72904070162b2f169415492209e94212" + integrity sha512-cb+0ioil/7oz5//7tZUSwbrSAN/NWHrQylz5cW8G0dWTcF/g+/dSdMlKVZspBYuMAN1+WnwHrkxiRrLcwd0Heg== dependencies: - "@types/anymatch" "*" "@types/node" "*" - "@types/tapable" "*" + "@types/tapable" "^1" "@types/uglify-js" "*" "@types/webpack-sources" "*" + anymatch "^3.0.0" source-map "^0.6.0" "@types/write-pkg@^3.1.0": @@ -7059,11 +7091,6 @@ acorn-globals@^6.0.0: acorn "^7.1.1" acorn-walk "^7.1.1" -acorn-jsx@^5.1.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.1.0.tgz#294adb71b57398b0680015f0a38c563ee1db5384" - integrity sha512-tMUqwBWfLFbJbizRmEcWSLw6HnFzfdJs2sOJEOwwtVPMoH/0Ay+E703oZz78VSXZiiDcZrQ5XKjPIUQixhmgVw== - acorn-jsx@^5.3.1: version "5.3.1" resolved "https://registry.yarnpkg.com/acorn-jsx/-/acorn-jsx-5.3.1.tgz#fc8661e11b7ac1539c47dbfea2e72b3af34d267b" @@ -7083,7 +7110,7 @@ acorn-walk@^6.0.1: resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-6.1.1.tgz#d363b66f5fac5f018ff9c3a1e7b6f8e310cc3913" integrity sha512-OtUw6JUTgxA2QoqqmrmQ7F2NYqiBPi/L2jqHyFtllhOUvXYQXf0Z1CYUinIfyT4bTCGmrA7gX9FvHA81uzCoVw== -acorn-walk@^7.0.0, acorn-walk@^7.1.1: +acorn-walk@^7.0.0, acorn-walk@^7.1.1, acorn-walk@^7.2.0: version "7.2.0" resolved "https://registry.yarnpkg.com/acorn-walk/-/acorn-walk-7.2.0.tgz#0de889a601203909b0fbe07b8938dc21d2e967bc" integrity sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA== @@ -7103,10 +7130,10 @@ acorn@^6.0.1, acorn@^6.0.4, acorn@^6.4.1: resolved "https://registry.yarnpkg.com/acorn/-/acorn-6.4.1.tgz#531e58ba3f51b9dacb9a6646ca4debf5b14ca474" integrity sha512-ZVA9k326Nwrj3Cj9jlh3wGFutC2ZornPNARZwsNYqQYgN0EsV2d53w5RN/co65Ohn4sUAUtb1rSUAOD6XN9idA== -acorn@^7.0.0, acorn@^7.1.0, acorn@^7.1.1, acorn@^7.4.0: - version "7.4.0" - resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.0.tgz#e1ad486e6c54501634c6c397c5c121daa383607c" - integrity sha512-+G7P8jJmCHr+S+cLfQxygbWhXy+8YTVGzAkpEbcLo2mLoL7tij/VG41QSHACSf5QgYRhMZYHuNc6drJaO0Da+w== +acorn@^7.0.0, acorn@^7.1.1, acorn@^7.4.0, acorn@^7.4.1: + version "7.4.1" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-7.4.1.tgz#feaed255973d2e77555b83dbc08851a6c63520fa" + integrity sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A== acorn@^8.4.1: version "8.5.0" @@ -7453,10 +7480,10 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" -anymatch@^3.0.3, anymatch@~3.1.1: - version "3.1.1" - resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" - integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== +anymatch@^3.0.0, anymatch@^3.0.3, anymatch@~3.1.1: + version "3.1.2" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.2.tgz#c0557c096af32f106198f4f4e2a383537e378716" + integrity sha512-P43ePfOAIupkguHUycrc4qJ9kz8ZiuOUijaETwX7THt0Y/GNK7v0aa8rY816xWjZ7rJdA5XdMcpVFTKMq+RvWg== dependencies: normalize-path "^3.0.0" picomatch "^2.0.4" @@ -7996,7 +8023,7 @@ attr-accept@^2.0.0: resolved "https://registry.yarnpkg.com/attr-accept/-/attr-accept-2.2.1.tgz#89b48de019ed4342f1865626b4389c666b3ed231" integrity sha512-GpefLMsbH5ojNgfTW+OBin2xKzuHfyeNA+qCktzZojBhbA/lPZdCFMWdwk5ajb989Ok7ZT+EADqvW3TAFNMjhA== -autoprefixer@^9.7.2, autoprefixer@^9.7.4: +autoprefixer@^9.7.4: version "9.8.5" resolved "https://registry.yarnpkg.com/autoprefixer/-/autoprefixer-9.8.5.tgz#2c225de229ddafe1d1424c02791d0c3e10ccccaa" integrity sha512-C2p5KkumJlsTHoNv9w31NrBRgXhf6eCMteJuHZi2xhkgC+5Vm40MEtCKPhc0qdgAOhox0YPy1SQHTAky05UoKg== @@ -8039,11 +8066,16 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.8.0.tgz#f0e003d9ca9e7f59c7a508945d7b2ef9a04a542f" integrity sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ== -axe-core@^4.0.1, axe-core@^4.0.2: +axe-core@^4.0.2: version "4.0.2" resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.0.2.tgz#c7cf7378378a51fcd272d3c09668002a4990b1cb" integrity sha512-arU1h31OGFu+LPrOLGZ7nB45v940NMDMEJeNmbutu57P+UFDVnkZg3e+J1I2HJRZ9hT7gO8J91dn/PMrAiKakA== +axe-core@^4.2.0: + version "4.3.5" + resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.5.tgz#78d6911ba317a8262bfee292aeafcc1e04b49cc5" + integrity sha512-WKTW1+xAzhMS5dJsxWkliixlO/PqC4VhmO9T4juNYcaTg9jzWiJsou6m5pxWYGfigWbwzJWeFY6z47a+4neRXA== + axios@^0.21.1: version "0.21.1" resolved "https://registry.yarnpkg.com/axios/-/axios-0.21.1.tgz#22563481962f4d6bde9a76d516ef0e5d3c09b2b8" @@ -8086,41 +8118,6 @@ babel-generator@^6.18.0: source-map "^0.5.7" trim-right "^1.0.1" -babel-helper-evaluate-path@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/babel-helper-evaluate-path/-/babel-helper-evaluate-path-0.5.0.tgz#a62fa9c4e64ff7ea5cea9353174ef023a900a67c" - integrity sha512-mUh0UhS607bGh5wUMAQfOpt2JX2ThXMtppHRdRU1kL7ZLRWIXxoV2UIV1r2cAeeNeU1M5SB5/RSUgUxrK8yOkA== - -babel-helper-flip-expressions@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/babel-helper-flip-expressions/-/babel-helper-flip-expressions-0.4.3.tgz#3696736a128ac18bc25254b5f40a22ceb3c1d3fd" - integrity sha1-NpZzahKKwYvCUlS19AoizrPB0/0= - -babel-helper-is-nodes-equiv@^0.0.1: - version "0.0.1" - resolved "https://registry.yarnpkg.com/babel-helper-is-nodes-equiv/-/babel-helper-is-nodes-equiv-0.0.1.tgz#34e9b300b1479ddd98ec77ea0bbe9342dfe39684" - integrity sha1-NOmzALFHnd2Y7HfqC76TQt/jloQ= - -babel-helper-is-void-0@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/babel-helper-is-void-0/-/babel-helper-is-void-0-0.4.3.tgz#7d9c01b4561e7b95dbda0f6eee48f5b60e67313e" - integrity sha1-fZwBtFYee5Xb2g9u7kj1tg5nMT4= - -babel-helper-mark-eval-scopes@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/babel-helper-mark-eval-scopes/-/babel-helper-mark-eval-scopes-0.4.3.tgz#d244a3bef9844872603ffb46e22ce8acdf551562" - integrity sha1-0kSjvvmESHJgP/tG4izorN9VFWI= - -babel-helper-remove-or-void@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/babel-helper-remove-or-void/-/babel-helper-remove-or-void-0.4.3.tgz#a4f03b40077a0ffe88e45d07010dee241ff5ae60" - integrity sha1-pPA7QAd6D/6I5F0HAQ3uJB/1rmA= - -babel-helper-to-multiple-sequence-expressions@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/babel-helper-to-multiple-sequence-expressions/-/babel-helper-to-multiple-sequence-expressions-0.5.0.tgz#a3f924e3561882d42fcf48907aa98f7979a4588d" - integrity sha512-m2CvfDW4+1qfDdsrtf4dwOslQC3yhbgyBFptncp4wvtdrDHqueW7slsYv4gArie056phvQFhT2nRcGS4bnm6mA== - babel-jest@^26.6.3: version "26.6.3" resolved "https://registry.yarnpkg.com/babel-jest/-/babel-jest-26.6.3.tgz#d87d25cb0037577a0c89f82e5755c5d293c01056" @@ -8135,16 +8132,6 @@ babel-jest@^26.6.3: graceful-fs "^4.2.4" slash "^3.0.0" -babel-loader@^8.0.6: - version "8.0.6" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.0.6.tgz#e33bdb6f362b03f4bb141a0c21ab87c501b70dfb" - integrity sha512-4BmWKtBOBm13uoUwd08UwjZlaw3O9GWf456R9j+5YykFZ6LUIjIKLc0zEZf+hauxPOJs96C8k6FvYD09vWzhYw== - dependencies: - find-cache-dir "^2.0.0" - loader-utils "^1.0.2" - mkdirp "^0.5.1" - pify "^4.0.1" - babel-loader@^8.2.2: version "8.2.2" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.2.tgz#9363ce84c10c9a40e6c753748e1441b60c8a0b81" @@ -8194,7 +8181,7 @@ babel-plugin-dynamic-import-node@^2.3.3: dependencies: object.assign "^4.1.0" -babel-plugin-emotion@^10.0.20, babel-plugin-emotion@^10.0.27: +babel-plugin-emotion@^10.0.27: version "10.0.33" resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz#ce1155dcd1783bbb9286051efee53f4e2be63e03" integrity sha512-bxZbTTGz0AJQDHm8k6Rf3RQJ8tX2scsfsRyKVgAbiUPUNIRtlK+7JxP+TAd1kRLABFxe0CFm2VdK4ePkoA9FxQ== @@ -8276,94 +8263,20 @@ babel-plugin-macros@^2.0.0, babel-plugin-macros@^2.6.1, babel-plugin-macros@^2.8 cosmiconfig "^6.0.0" resolve "^1.12.0" -babel-plugin-minify-builtins@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-builtins/-/babel-plugin-minify-builtins-0.5.0.tgz#31eb82ed1a0d0efdc31312f93b6e4741ce82c36b" - integrity sha512-wpqbN7Ov5hsNwGdzuzvFcjgRlzbIeVv1gMIlICbPj0xkexnfoIDe7q+AZHMkQmAE/F9R5jkrB6TLfTegImlXag== - -babel-plugin-minify-constant-folding@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-constant-folding/-/babel-plugin-minify-constant-folding-0.5.0.tgz#f84bc8dbf6a561e5e350ff95ae216b0ad5515b6e" - integrity sha512-Vj97CTn/lE9hR1D+jKUeHfNy+m1baNiJ1wJvoGyOBUx7F7kJqDZxr9nCHjO/Ad+irbR3HzR6jABpSSA29QsrXQ== - dependencies: - babel-helper-evaluate-path "^0.5.0" - -babel-plugin-minify-dead-code-elimination@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-dead-code-elimination/-/babel-plugin-minify-dead-code-elimination-0.5.0.tgz#d23ef5445238ad06e8addf5c1cf6aec835bcda87" - integrity sha512-XQteBGXlgEoAKc/BhO6oafUdT4LBa7ARi55mxoyhLHNuA+RlzRmeMAfc31pb/UqU01wBzRc36YqHQzopnkd/6Q== - dependencies: - babel-helper-evaluate-path "^0.5.0" - babel-helper-mark-eval-scopes "^0.4.3" - babel-helper-remove-or-void "^0.4.3" - lodash.some "^4.6.0" - -babel-plugin-minify-flip-comparisons@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-flip-comparisons/-/babel-plugin-minify-flip-comparisons-0.4.3.tgz#00ca870cb8f13b45c038b3c1ebc0f227293c965a" - integrity sha1-AMqHDLjxO0XAOLPB68DyJyk8llo= - dependencies: - babel-helper-is-void-0 "^0.4.3" - -babel-plugin-minify-guarded-expressions@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-guarded-expressions/-/babel-plugin-minify-guarded-expressions-0.4.3.tgz#cc709b4453fd21b1f302877444c89f88427ce397" - integrity sha1-zHCbRFP9IbHzAod0RMifiEJ845c= - dependencies: - babel-helper-flip-expressions "^0.4.3" - -babel-plugin-minify-infinity@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-infinity/-/babel-plugin-minify-infinity-0.4.3.tgz#dfb876a1b08a06576384ef3f92e653ba607b39ca" - integrity sha1-37h2obCKBldjhO8/kuZTumB7Oco= - -babel-plugin-minify-mangle-names@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-mangle-names/-/babel-plugin-minify-mangle-names-0.5.0.tgz#bcddb507c91d2c99e138bd6b17a19c3c271e3fd3" - integrity sha512-3jdNv6hCAw6fsX1p2wBGPfWuK69sfOjfd3zjUXkbq8McbohWy23tpXfy5RnToYWggvqzuMOwlId1PhyHOfgnGw== - dependencies: - babel-helper-mark-eval-scopes "^0.4.3" - -babel-plugin-minify-numeric-literals@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-numeric-literals/-/babel-plugin-minify-numeric-literals-0.4.3.tgz#8e4fd561c79f7801286ff60e8c5fd9deee93c0bc" - integrity sha1-jk/VYcefeAEob/YOjF/Z3u6TwLw= - -babel-plugin-minify-replace@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-replace/-/babel-plugin-minify-replace-0.5.0.tgz#d3e2c9946c9096c070efc96761ce288ec5c3f71c" - integrity sha512-aXZiaqWDNUbyNNNpWs/8NyST+oU7QTpK7J9zFEFSA0eOmtUNMU3fczlTTTlnCxHmq/jYNFEmkkSG3DDBtW3Y4Q== - -babel-plugin-minify-simplify@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-simplify/-/babel-plugin-minify-simplify-0.5.0.tgz#1f090018afb90d8b54d3d027fd8a4927f243da6f" - integrity sha512-TM01J/YcKZ8XIQd1Z3nF2AdWHoDsarjtZ5fWPDksYZNsoOjQ2UO2EWm824Ym6sp127m44gPlLFiO5KFxU8pA5Q== - dependencies: - babel-helper-flip-expressions "^0.4.3" - babel-helper-is-nodes-equiv "^0.0.1" - babel-helper-to-multiple-sequence-expressions "^0.5.0" - -babel-plugin-minify-type-constructors@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/babel-plugin-minify-type-constructors/-/babel-plugin-minify-type-constructors-0.4.3.tgz#1bc6f15b87f7ab1085d42b330b717657a2156500" - integrity sha1-G8bxW4f3qxCF1CszC3F2V6IVZQA= +babel-plugin-macros@^3.0.1: + version "3.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz#9ef6dc74deb934b4db344dc973ee851d148c50c1" + integrity sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg== dependencies: - babel-helper-is-void-0 "^0.4.3" + "@babel/runtime" "^7.12.5" + cosmiconfig "^7.0.0" + resolve "^1.19.0" babel-plugin-named-asset-import@^0.3.1: version "0.3.3" resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.3.tgz#9ba2f3ac4dc78b042651654f07e847adfe50667c" integrity sha512-1XDRysF4894BUdMChT+2HHbtJYiO7zx5Be7U6bT8dISy7OdyETMGIAQBMPQCsY1YRf0xcubwnKKaDr5bk15JTA== -babel-plugin-polyfill-corejs2@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.3.tgz#6ed8e30981b062f8fe6aca8873a37ebcc8cc1c0f" - integrity sha512-NDZ0auNRzmAfE1oDDPW2JhzIMXUk+FFe2ICejmt5T4ocKgiQx3e0VCRx9NCAidcMtL2RUZaWtXnmjTCkx0tcbA== - dependencies: - "@babel/compat-data" "^7.13.11" - "@babel/helper-define-polyfill-provider" "^0.2.4" - semver "^6.1.1" - babel-plugin-polyfill-corejs2@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.3.0.tgz#407082d0d355ba565af24126fb6cb8e9115251fd" @@ -8373,13 +8286,13 @@ babel-plugin-polyfill-corejs2@^0.3.0: "@babel/helper-define-polyfill-provider" "^0.3.0" semver "^6.1.1" -babel-plugin-polyfill-corejs3@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.3.0.tgz#fa7ca3d1ee9ddc6193600ffb632c9785d54918af" - integrity sha512-JLwi9vloVdXLjzACL80j24bG6/T1gYxwowG44dg6HN/7aTPdyPbJJidf6ajoA3RPHHtW0j9KMrSOLpIZpAnPpg== +babel-plugin-polyfill-corejs3@^0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.1.7.tgz#80449d9d6f2274912e05d9e182b54816904befd0" + integrity sha512-u+gbS9bbPhZWEeyy1oR/YaaSpod/KDT07arZHb80aTpl8H5ZBq+uN1nN9/xtX7jQyfLdPfoqI4Rue/MQSWJquw== dependencies: - "@babel/helper-define-polyfill-provider" "^0.2.4" - core-js-compat "^3.18.0" + "@babel/helper-define-polyfill-provider" "^0.1.5" + core-js-compat "^3.8.1" babel-plugin-polyfill-corejs3@^0.4.0: version "0.4.0" @@ -8389,13 +8302,6 @@ babel-plugin-polyfill-corejs3@^0.4.0: "@babel/helper-define-polyfill-provider" "^0.3.0" core-js-compat "^3.18.0" -babel-plugin-polyfill-regenerator@^0.2.3: - version "0.2.3" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.3.tgz#2e9808f5027c4336c994992b48a4262580cb8d6d" - integrity sha512-JVE78oRZPKFIeUqFGrSORNzQnrDwZR16oiWeGM8ZyjBn2XAT5OjP+wXx5ESuo33nUsFUEJYjtklnsKbxW5L+7g== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.2.4" - babel-plugin-polyfill-regenerator@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.3.0.tgz#9ebbcd7186e1a33e21c5e20cae4e7983949533be" @@ -8442,70 +8348,11 @@ babel-plugin-syntax-jsx@^6.18.0: resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" integrity sha1-CvMqmm4Tyno/1QaeYtew9Y0NiUY= -babel-plugin-transform-inline-consecutive-adds@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-inline-consecutive-adds/-/babel-plugin-transform-inline-consecutive-adds-0.4.3.tgz#323d47a3ea63a83a7ac3c811ae8e6941faf2b0d1" - integrity sha1-Mj1Ho+pjqDp6w8gRro5pQfrysNE= - -babel-plugin-transform-member-expression-literals@^6.9.4: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-member-expression-literals/-/babel-plugin-transform-member-expression-literals-6.9.4.tgz#37039c9a0c3313a39495faac2ff3a6b5b9d038bf" - integrity sha1-NwOcmgwzE6OUlfqsL/OmtbnQOL8= - -babel-plugin-transform-merge-sibling-variables@^6.9.4: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-merge-sibling-variables/-/babel-plugin-transform-merge-sibling-variables-6.9.4.tgz#85b422fc3377b449c9d1cde44087203532401dae" - integrity sha1-hbQi/DN3tEnJ0c3kQIcgNTJAHa4= - -babel-plugin-transform-minify-booleans@^6.9.4: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-minify-booleans/-/babel-plugin-transform-minify-booleans-6.9.4.tgz#acbb3e56a3555dd23928e4b582d285162dd2b198" - integrity sha1-rLs+VqNVXdI5KOS1gtKFFi3SsZg= - -babel-plugin-transform-property-literals@^6.9.4: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-property-literals/-/babel-plugin-transform-property-literals-6.9.4.tgz#98c1d21e255736573f93ece54459f6ce24985d39" - integrity sha1-mMHSHiVXNlc/k+zlRFn2ziSYXTk= - dependencies: - esutils "^2.0.2" - babel-plugin-transform-react-remove-prop-types@^0.4.24: version "0.4.24" resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-remove-prop-types/-/babel-plugin-transform-react-remove-prop-types-0.4.24.tgz#f2edaf9b4c6a5fbe5c1d678bfb531078c1555f3a" integrity sha512-eqj0hVcJUR57/Ug2zE1Yswsw4LhuqqHhD+8v120T1cl3kjg76QwtyBrdIk4WVwK+lAhBJVYCd/v+4nc4y+8JsA== -babel-plugin-transform-regexp-constructors@^0.4.3: - version "0.4.3" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-regexp-constructors/-/babel-plugin-transform-regexp-constructors-0.4.3.tgz#58b7775b63afcf33328fae9a5f88fbd4fb0b4965" - integrity sha1-WLd3W2OvzzMyj66aX4j71PsLSWU= - -babel-plugin-transform-remove-console@^6.9.4: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-console/-/babel-plugin-transform-remove-console-6.9.4.tgz#b980360c067384e24b357a588d807d3c83527780" - integrity sha1-uYA2DAZzhOJLNXpYjYB9PINSd4A= - -babel-plugin-transform-remove-debugger@^6.9.4: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-debugger/-/babel-plugin-transform-remove-debugger-6.9.4.tgz#42b727631c97978e1eb2d199a7aec84a18339ef2" - integrity sha1-QrcnYxyXl44estGZp67IShgznvI= - -babel-plugin-transform-remove-undefined@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-remove-undefined/-/babel-plugin-transform-remove-undefined-0.5.0.tgz#80208b31225766c630c97fa2d288952056ea22dd" - integrity sha512-+M7fJYFaEE/M9CXa0/IRkDbiV3wRELzA1kKQFCJ4ifhrzLKn/9VCCgj9OFmYWwBd8IB48YdgPkHYtbYq+4vtHQ== - dependencies: - babel-helper-evaluate-path "^0.5.0" - -babel-plugin-transform-simplify-comparison-operators@^6.9.4: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-simplify-comparison-operators/-/babel-plugin-transform-simplify-comparison-operators-6.9.4.tgz#f62afe096cab0e1f68a2d753fdf283888471ceb9" - integrity sha1-9ir+CWyrDh9ootdT/fKDiIRxzrk= - -babel-plugin-transform-undefined-to-void@^6.9.4: - version "6.9.4" - resolved "https://registry.yarnpkg.com/babel-plugin-transform-undefined-to-void/-/babel-plugin-transform-undefined-to-void-6.9.4.tgz#be241ca81404030678b748717322b89d0c8fe280" - integrity sha1-viQcqBQEAwZ4t0hxcyK4nQyP4oA= - babel-polyfill@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.26.0.tgz#379937abc67d7895970adc621f284cd966cf2153" @@ -8541,35 +8388,6 @@ babel-preset-jest@^26.6.2: babel-plugin-jest-hoist "^26.6.2" babel-preset-current-node-syntax "^1.0.0" -"babel-preset-minify@^0.5.0 || 0.6.0-alpha.5": - version "0.5.0" - resolved "https://registry.yarnpkg.com/babel-preset-minify/-/babel-preset-minify-0.5.0.tgz#e25bb8d3590087af02b650967159a77c19bfb96b" - integrity sha512-xj1s9Mon+RFubH569vrGCayA9Fm2GMsCgDRm1Jb8SgctOB7KFcrVc2o8K3YHUyMz+SWP8aea75BoS8YfsXXuiA== - dependencies: - babel-plugin-minify-builtins "^0.5.0" - babel-plugin-minify-constant-folding "^0.5.0" - babel-plugin-minify-dead-code-elimination "^0.5.0" - babel-plugin-minify-flip-comparisons "^0.4.3" - babel-plugin-minify-guarded-expressions "^0.4.3" - babel-plugin-minify-infinity "^0.4.3" - babel-plugin-minify-mangle-names "^0.5.0" - babel-plugin-minify-numeric-literals "^0.4.3" - babel-plugin-minify-replace "^0.5.0" - babel-plugin-minify-simplify "^0.5.0" - babel-plugin-minify-type-constructors "^0.4.3" - babel-plugin-transform-inline-consecutive-adds "^0.4.3" - babel-plugin-transform-member-expression-literals "^6.9.4" - babel-plugin-transform-merge-sibling-variables "^6.9.4" - babel-plugin-transform-minify-booleans "^6.9.4" - babel-plugin-transform-property-literals "^6.9.4" - babel-plugin-transform-regexp-constructors "^0.4.3" - babel-plugin-transform-remove-console "^6.9.4" - babel-plugin-transform-remove-debugger "^6.9.4" - babel-plugin-transform-remove-undefined "^0.5.0" - babel-plugin-transform-simplify-comparison-operators "^6.9.4" - babel-plugin-transform-undefined-to-void "^6.9.4" - lodash.isplainobject "^4.0.6" - babel-runtime@6.x, babel-runtime@^6.11.6, babel-runtime@^6.22.0, babel-runtime@^6.26.0: version "6.26.0" resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.26.0.tgz#965c7058668e82b55d7bfe04ff2337bc8b5647fe" @@ -8710,7 +8528,7 @@ basic-auth@^2.0.1: dependencies: safe-buffer "5.1.2" -batch-processor@1.0.0, batch-processor@^1.0.0: +batch-processor@1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/batch-processor/-/batch-processor-1.0.0.tgz#75c95c32b748e0850d10c2b168f6bdbe9891ace8" integrity sha1-dclcMrdI4IUNEMKxaPa9vpiRrOg= @@ -8742,10 +8560,10 @@ before-after-hook@^2.0.0, before-after-hook@^2.1.0: resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635" integrity sha512-IWIbu7pMqyw3EAJHzzHbWa85b6oud/yfKYg5rqB5hNE8CeMi3nX+2C2sj0HswfblST86hpVEOAb9x34NZd6P7A== -better-opn@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-2.0.0.tgz#c70d198e51164bdc220306a28a885d9ac7a14c44" - integrity sha512-PPbGRgO/K0LowMHbH/JNvaV3qY3Vt+A2nH28fzJxy16h/DfR5OsVti6ldGl6S9SMsyUqT13sltikiAVtI6tKLA== +better-opn@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/better-opn/-/better-opn-2.1.1.tgz#94a55b4695dc79288f31d7d0e5f658320759f7c6" + integrity sha512-kIPXZS5qwyKiX/HcRvDYfmBQUa8XP17I0mYZZ0y4UhpYOSvtsLHDYqmomS+Mj20aDvD3knEiQ0ecQy2nhio3yA== dependencies: open "^7.0.3" @@ -8851,7 +8669,7 @@ bowser@^1.7.3: resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.9.4.tgz#890c58a2813a9d3243704334fa81b96a5c150c9a" integrity sha512-9IdMmj2KjigRq6oWhmwv1W36pDuA4STQZ8q6YO9um+x07xgYNCD3Oou+WP/3L1HNz7iqythGet3/p4wvc8AAwQ== -boxen@^4.1.0, boxen@^4.2.0: +boxen@^4.2.0: version "4.2.0" resolved "https://registry.yarnpkg.com/boxen/-/boxen-4.2.0.tgz#e411b62357d6d6d36587c8ac3d5d974daa070e64" integrity sha512-eB4uT9RGzg2odpER62bBwSLvUeGC+WbRjjyyFhGsKnc8wp/m0+hQsMUvUe3H2V0D5vw0nBdO1hCJoZo5mKeuIQ== @@ -9191,7 +9009,7 @@ browserslist@4.14.2: escalade "^3.0.2" node-releases "^1.1.61" -browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.17.1, browserslist@^4.6.0, browserslist@^4.8.5: +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.6.0: version "4.17.1" resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.17.1.tgz#a98d104f54af441290b7d592626dd541fa642eb9" integrity sha512-aLD0ZMDSnF4lUt4ZDNgqi5BUn9BZ7YdQdI/cYlILrhdSSZJLU9aNZoD5/NBmM4SK34APB2e83MOsRt1EnkuyaQ== @@ -9565,10 +9383,10 @@ cardinal@^2.1.1: ansicolors "~0.3.2" redeyed "~2.1.0" -case-sensitive-paths-webpack-plugin@^2.2.0: - version "2.2.0" - resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.2.0.tgz#3371ef6365ef9c25fa4b81c16ace0e9c7dc58c3e" - integrity sha512-u5ElzokS8A1pm9vM3/iDgTcI3xqHxuCao94Oz8etI3cf0Tio0p8izkDYbTIn09uP3yUUr6+veaE6IkjnTYS46g== +case-sensitive-paths-webpack-plugin@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/case-sensitive-paths-webpack-plugin/-/case-sensitive-paths-webpack-plugin-2.3.0.tgz#23ac613cc9a856e4f88ff8bb73bbb5e989825cf7" + integrity sha512-/4YgnZS8y1UXXmC02xD5rRrBEu6T5ub+mQHLNRj0fzTRbgdBYhsNo2V5EqwgqrExjxsjtF/OpAKAMkKsxbD5XQ== caseless@~0.12.0: version "0.12.0" @@ -9735,7 +9553,7 @@ cheerio@^1.0.0-rc.10, cheerio@^1.0.0-rc.3: parse5-htmlparser2-tree-adapter "^6.0.1" tslib "^2.2.0" -chokidar@3.4.3, chokidar@^2.0.0, chokidar@^2.0.4, chokidar@^2.1.1, chokidar@^2.1.2, chokidar@^2.1.8, chokidar@^3.2.2, chokidar@^3.4.0, chokidar@^3.4.1, chokidar@^3.4.3: +chokidar@3.4.3, chokidar@^2.0.0, chokidar@^2.0.4, chokidar@^2.1.1, chokidar@^2.1.2, chokidar@^2.1.8, chokidar@^3.2.2, chokidar@^3.4.0, chokidar@^3.4.1, chokidar@^3.4.2, chokidar@^3.4.3: version "3.5.1" resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.5.1.tgz#ee9ce7bbebd2b79f49f304799d5468e31e14e68a" integrity sha512-9+s+Od+W0VJJzawDma/gvBNQqkTiqYTWLuZoyAsivsI4AaWTCzHG06/TMjsf1cYe9Cb97UCEhjz7HvnPk2p/tw== @@ -10047,10 +9865,10 @@ cloneable-readable@^1.0.0: process-nextick-args "^2.0.0" readable-stream "^2.3.5" -clsx@^1.0.1: - version "1.0.4" - resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.0.4.tgz#0c0171f6d5cb2fe83848463c15fcc26b4df8c2ec" - integrity sha512-1mQ557MIZTrL/140j+JVdRM6e31/OA4vTYxXgqIIZlndyfjHpyawKZia1Im05Vp9BWmImkcNrNtFYQMyFcgJDg== +clsx@^1.0.1, clsx@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/clsx/-/clsx-1.1.1.tgz#98b3134f9abbdf23b2663491ace13c5c03a73188" + integrity sha512-6/bPho624p3S2pMyvP5kKBPXnI3ufHLObBFCfgx+LkeR5lg2XYy2hqZqUf45ypD8COn2bhgGJSUE+l5dhNBieA== cmd-shim@^2.1.0: version "2.1.0" @@ -10286,7 +10104,7 @@ commander@^5.1.0: resolved "https://registry.yarnpkg.com/commander/-/commander-5.1.0.tgz#46abbd1652f8e059bddaef99bbdcb2ad9cf179ae" integrity sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg== -commander@^6.1.0: +commander@^6.1.0, commander@^6.2.1: version "6.2.1" resolved "https://registry.yarnpkg.com/commander/-/commander-6.2.1.tgz#0792eb682dfbc325999bb2b84fddddba110ac73c" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== @@ -10563,10 +10381,10 @@ copy-props@^2.0.1: each-props "^1.3.0" is-plain-object "^2.0.1" -copy-to-clipboard@^3.0.8, copy-to-clipboard@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.2.0.tgz#d2724a3ccbfed89706fac8a894872c979ac74467" - integrity sha512-eOZERzvCmxS8HWzugj4Uxl8OJxa7T2k1Gi0X5qavwydHIfuSHq2dTD09LOg/XyGq4Zpb5IsR/2OJ5lbOegz78w== +copy-to-clipboard@^3.0.8, copy-to-clipboard@^3.2.0, copy-to-clipboard@^3.3.1: + version "3.3.1" + resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz#115aa1a9998ffab6196f93076ad6da3b913662ae" + integrity sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw== dependencies: toggle-selection "^1.0.6" @@ -10587,23 +10405,7 @@ copy-webpack-plugin@^6.0.2: serialize-javascript "^3.1.0" webpack-sources "^1.4.3" -core-js-compat@^3.1.1: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c" - integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng== - dependencies: - browserslist "^4.8.5" - semver "7.0.0" - -core-js-compat@^3.18.0: - version "3.18.1" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.18.1.tgz#01942a0877caf9c6e5007c027183cf0bdae6a191" - integrity sha512-XJMYx58zo4W0kLPmIingVZA10+7TuKrMLPt83+EzDmxFJQUMcTVVmQ+n5JP4r6Z14qSzhQBRi3NSWoeVyKKXUg== - dependencies: - browserslist "^4.17.1" - semver "7.0.0" - -core-js-compat@^3.19.0, core-js-compat@^3.19.1: +core-js-compat@^3.1.1, core-js-compat@^3.18.0, core-js-compat@^3.19.1, core-js-compat@^3.8.1: version "3.19.1" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.19.1.tgz#fe598f1a9bf37310d77c3813968e9f7c7bb99476" integrity sha512-Q/VJ7jAF/y68+aUsQJ/afPOewdsGkDtcMb40J8MbuWKlK3Y+wtHq8bTHKPj2WKWLIqmS5JhHs4CzHtz6pT2W6g== @@ -10611,10 +10413,10 @@ core-js-compat@^3.19.0, core-js-compat@^3.19.1: browserslist "^4.17.6" semver "7.0.0" -core-js-pure@^3.0.0, core-js-pure@^3.0.1: - version "3.6.5" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.6.5.tgz#c79e75f5e38dbc85a662d91eea52b8256d53b813" - integrity sha512-lacdXOimsiD0QyNf9BC/mxivNJ/ybBGJXQFKzRekp1WTHoVUWsUHEn+2T8GJAzzIhyOuXA+gOxCVN3l+5PLPUA== +core-js-pure@^3.0.0, core-js-pure@^3.8.2: + version "3.19.1" + resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.19.1.tgz#edffc1fc7634000a55ba05e95b3f0fe9587a5aa4" + integrity sha512-Q0Knr8Es84vtv62ei6/6jXH/7izKmOrtrxH9WJTHLCMAVeU+8TF8z8Nr08CsH4Ot0oJKzBzJJL9SJBYIv7WlfQ== core-js@^1.0.0: version "1.2.7" @@ -10626,7 +10428,7 @@ core-js@^2.4.0, core-js@^2.5.0, core-js@^2.6.9: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.9.tgz#6b4b214620c834152e179323727fc19741b084f2" integrity sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A== -core-js@^3.0.1, core-js@^3.0.4, core-js@^3.19.1, core-js@^3.6.5, core-js@^3.8.2: +core-js@^3.0.4, core-js@^3.19.1, core-js@^3.6.5, core-js@^3.8.2: version "3.19.1" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.19.1.tgz#f6f173cae23e73a7d88fa23b6e9da329276c6641" integrity sha512-Tnc7E9iKd/b/ff7GFbhwPVzJzPztGrChB8X8GLqoYGdEOG8IpLnK1xPyo3ZoO3HsK6TodJS58VGPOxA+hLHQMg== @@ -10894,7 +10696,7 @@ css-in-js-utils@^2.0.0: hyphenate-style-name "^1.0.2" isobject "^3.0.1" -css-loader@^3.4.2, css-loader@^3.5.3: +css-loader@^3.4.2, css-loader@^3.6.0: version "3.6.0" resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-3.6.0.tgz#2e4b2c7e6e2d27f8c8f28f61bffcd2e6c91ef645" integrity sha512-M5lSukoWi1If8dhQAUCvj4H8vUt3vOnwbQBH9DdTm/s4Ym2B/3dPMtYZeJmq7Q3S3Pa+I94DcZ7pc9bP14cWIQ== @@ -12191,11 +11993,6 @@ diff-sequences@^24.9.0: resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-24.9.0.tgz#5715d6244e2aa65f48bba0bc972db0b0b11e95b5" integrity sha512-Dj6Wk3tWyTE+Fo1rW8v0Xhwk80um6yFYKbuAxc9c3EZxIHFDYwbi34Uk42u1CdnIiVorvt4RmlSDjIPyzGC2ew== -diff-sequences@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-25.2.6.tgz#5f467c00edd35352b7bca46d7927d60e687a76dd" - integrity sha512-Hq8o7+6GaZeoFjtpgvRBUknSXNeJiCx7V9Fr94ZMljNiCr9n9L8H8aJqgWOQiDDGdyn29fRNcDdRVJ5fdyihfg== - diff-sequences@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/diff-sequences/-/diff-sequences-26.6.2.tgz#48ba99157de1923412eed41db6b6d4aa9ca7c0b1" @@ -12449,10 +12246,10 @@ dotenv-expand@^5.1.0: resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0" integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA== -dotenv-webpack@^1.7.0: - version "1.7.0" - resolved "https://registry.yarnpkg.com/dotenv-webpack/-/dotenv-webpack-1.7.0.tgz#4384d8c57ee6f405c296278c14a9f9167856d3a1" - integrity sha512-wwNtOBW/6gLQSkb8p43y0Wts970A3xtNiG/mpwj9MLUhtPCQG6i+/DSXXoNN7fbPCU/vQ7JjwGmgOeGZSSZnsw== +dotenv-webpack@^1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/dotenv-webpack/-/dotenv-webpack-1.8.0.tgz#7ca79cef2497dd4079d43e81e0796bc9d0f68a5e" + integrity sha512-o8pq6NLBehtrqA8Jv8jFQNtG9nhRtVqmoD4yWbgUyoU3+9WBlPe+c2EAiaJok9RB28QvrWvdWLZGeTT5aATDMg== dependencies: dotenv-defaults "^1.0.2" @@ -12483,7 +12280,7 @@ downshift@^3.2.10: prop-types "^15.7.2" react-is "^16.9.0" -downshift@^6.0.6: +downshift@^6.0.15: version "6.1.0" resolved "https://registry.yarnpkg.com/downshift/-/downshift-6.1.0.tgz#f008063d9b63935910d9db12ead07979ab51ce66" integrity sha512-MnEJERij+1pTVAsOPsH3q9MJGNIZuu2sT90uxOCEOZYH6sEzkVGtUcTBVDRQkE8y96zpB7uEbRn24aE9VpHnZg== @@ -12594,7 +12391,7 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -ejs@^3.1.2, ejs@^3.1.6: +ejs@^3.1.6: version "3.1.6" resolved "https://registry.yarnpkg.com/ejs/-/ejs-3.1.6.tgz#5bfd0a0689743bb5268b3550cceeebbc1702822a" integrity sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw== @@ -12683,20 +12480,13 @@ elegant-spinner@^1.0.1: resolved "https://registry.yarnpkg.com/elegant-spinner/-/elegant-spinner-1.0.1.tgz#db043521c95d7e303fd8f345bedc3349cfb0729e" integrity sha1-2wQ1IcldfjA/2PNFvtwzSc+wcp4= -element-resize-detector@^1.1.12, element-resize-detector@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/element-resize-detector/-/element-resize-detector-1.2.1.tgz#b0305194447a4863155e58f13323a0aef30851d1" - integrity sha512-BdFsPepnQr9fznNPF9nF4vQ457U/ZJXQDSNF1zBe7yaga8v9AdZf3/NElYxFdUh7SitSGt040QygiTo6dtatIw== +element-resize-detector@^1.1.12, element-resize-detector@^1.2.2: + version "1.2.3" + resolved "https://registry.yarnpkg.com/element-resize-detector/-/element-resize-detector-1.2.3.tgz#5078d9b99398fe4c589f8c8df94ff99e5d413ff3" + integrity sha512-+dhNzUgLpq9ol5tyhoG7YLoXL3ssjfFW+0gpszXPwRU6NjGr1fVHMEAF8fVzIiRJq57Nre0RFeIjJwI8Nh2NmQ== dependencies: batch-processor "1.0.0" -element-resize-detector@^1.1.15: - version "1.1.15" - resolved "https://registry.yarnpkg.com/element-resize-detector/-/element-resize-detector-1.1.15.tgz#48eba1a2eaa26969a4c998d972171128c971d8d2" - integrity sha512-16/5avDegXlUxytGgaumhjyQoM6hpp5j3+L79sYq5hlXfTNRy5WMMuTVWkZU3egp/CokCmTmvf18P3KeB57Iog== - dependencies: - batch-processor "^1.0.0" - elliptic@^6.0.0: version "6.5.4" resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.5.4.tgz#da37cebd31e79a1367e941b592ed1fbebd58abbb" @@ -12745,7 +12535,7 @@ emoticon@^3.2.0: resolved "https://registry.yarnpkg.com/emoticon/-/emoticon-3.2.0.tgz#c008ca7d7620fac742fe1bf4af8ff8fed154ae7f" integrity sha512-SNujglcLTTg+lDAcApPNgEdudaqQFiAbJCqzjNxJkvN9vAwCGi0uu8IUVvx+f16h+V44KCY6Y2yboroc9pilHg== -emotion-theming@^10.0.19, emotion-theming@^10.0.27: +emotion-theming@^10.0.27: version "10.0.27" resolved "https://registry.yarnpkg.com/emotion-theming/-/emotion-theming-10.0.27.tgz#1887baaec15199862c89b1b984b79806f2b9ab10" integrity sha512-MlF1yu/gYh8u+sLUqA0YuA9JX0P4Hb69WlKc/9OLo+WCXuX6sy/KoIa+qJimgmr2dWqnypYKYPX37esjDBbhdw== @@ -13131,7 +12921,7 @@ escape-string-regexp@^1.0.0, escape-string-regexp@^1.0.2, escape-string-regexp@^ resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ= -escodegen@^1.11.0, escodegen@^1.11.1, escodegen@^1.12.0, escodegen@^1.14.1: +escodegen@^1.11.0, escodegen@^1.11.1, escodegen@^1.14.1: version "1.14.3" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.14.3.tgz#4e7b81fba61581dc97582ed78cab7f0e8d63f503" integrity sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw== @@ -13143,6 +12933,18 @@ escodegen@^1.11.0, escodegen@^1.11.1, escodegen@^1.12.0, escodegen@^1.14.1: optionalDependencies: source-map "~0.6.1" +escodegen@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-2.0.0.tgz#5e32b12833e8aa8fa35e1bf0befa89380484c7dd" + integrity sha512-mmHKys/C8BFUGI+MAWNcSYoORYLMdPzjrknd2Vc+bUsjN5bXcr8EhrNB+UTqfL1y3I9c4fw2ihgtMPQLBRiQxw== + dependencies: + esprima "^4.0.1" + estraverse "^5.2.0" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.6.1" + escodegen@~1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.2.0.tgz#09de7967791cc958b7f89a2ddb6d23451af327e1" @@ -13746,7 +13548,7 @@ expose-loader@^0.7.5: resolved "https://registry.yarnpkg.com/expose-loader/-/expose-loader-0.7.5.tgz#e29ea2d9aeeed3254a3faa1b35f502db9f9c3f6f" integrity sha512-iPowgKUZkTPX5PznYsmifVj9Bob0w2wTHVkt/eYNPSzyebkUgIedmskf/kcfEIWpiWjg3JRjnW+a17XypySMuw== -express@^4.16.3, express@^4.17.0, express@^4.17.1: +express@^4.16.3, express@^4.17.1: version "4.17.1" resolved "https://registry.yarnpkg.com/express/-/express-4.17.1.tgz#4491fc38605cf51f8629d39c2b5d026f98a4c134" integrity sha512-mHJ9O79RqluphRrcw2X/GTh3k9tVv8YcoyY4Kkh4WDMUYKRZUq0h1o0w2rrrxBqM7VoeUVqgb27xlEMXTnYt4g== @@ -14098,13 +13900,13 @@ file-loader@^4.2.0: loader-utils "^1.2.3" schema-utils "^2.0.0" -file-loader@^6.0.0: - version "6.0.0" - resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.0.0.tgz#97bbfaab7a2460c07bcbd72d3a6922407f67649f" - integrity sha512-/aMOAYEFXDdjG0wytpTL5YQLfZnnTmLNjn+AIrJ/6HVnTfDqLsVKUUwkDf4I4kgex36BvjuXEn/TX9B/1ESyqQ== +file-loader@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-loader/-/file-loader-6.2.0.tgz#baef7cf8e1840df325e4390b4484879480eebe4d" + integrity sha512-qo3glqyTa61Ytg4u73GultjHGjdRyig3tG6lPtyX/jOEJvHif9uB0/OCI2Kif6ctF3caQTW2G5gym21oAsI4pw== dependencies: loader-utils "^2.0.0" - schema-utils "^2.6.5" + schema-utils "^3.0.0" file-saver@^1.3.8: version "1.3.8" @@ -14422,7 +14224,7 @@ forever-agent@~0.6.1: resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" integrity sha1-+8cfDEGt6zf5bFd60e1C2P2sypE= -fork-ts-checker-webpack-plugin@4.1.6, fork-ts-checker-webpack-plugin@^4.1.4: +fork-ts-checker-webpack-plugin@4.1.6, fork-ts-checker-webpack-plugin@^4.1.6: version "4.1.6" resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-4.1.6.tgz#5055c703febcf37fa06405d400c122b905167fc5" integrity sha512-DUxuQaKoqfNne8iikd14SAkh5uw4+8vNifp6gmA73yYNS6ywLIWSLD/n/mBzHQRpW3J7rbATEakmiA8JvkTyZw== @@ -14435,6 +14237,25 @@ fork-ts-checker-webpack-plugin@4.1.6, fork-ts-checker-webpack-plugin@^4.1.4: tapable "^1.0.0" worker-rpc "^0.1.0" +fork-ts-checker-webpack-plugin@^6.0.4: + version "6.4.0" + resolved "https://registry.yarnpkg.com/fork-ts-checker-webpack-plugin/-/fork-ts-checker-webpack-plugin-6.4.0.tgz#057e477cf1d8b013b2ed2669437f818680289c4c" + integrity sha512-3I3wFkc4DbzaUDPWEi96wdYGu4EKtxBafhZYm0o4mX51d9bphAY4P3mBl8K5mFXFJqVzHfmdbm9kLGnm7vwwBg== + dependencies: + "@babel/code-frame" "^7.8.3" + "@types/json-schema" "^7.0.5" + chalk "^4.1.0" + chokidar "^3.4.2" + cosmiconfig "^6.0.0" + deepmerge "^4.2.2" + fs-extra "^9.0.0" + glob "^7.1.6" + memfs "^3.1.2" + minimatch "^3.0.4" + schema-utils "2.7.0" + semver "^7.3.2" + tapable "^1.0.0" + form-data@^2.3.1: version "2.5.0" resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.5.0.tgz#094ec359dc4b55e7d62e0db4acd76e89fe874d37" @@ -14605,6 +14426,11 @@ fs-mkdirp-stream@^1.0.0: graceful-fs "^4.1.11" through2 "^2.0.3" +fs-monkey@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/fs-monkey/-/fs-monkey-1.0.3.tgz#ae3ac92d53bb328efe0e9a1d9541f6ad8d48e2d3" + integrity sha512-cybjIfiiE+pTWicSCLFHSrXZ6EilF30oh91FDP9S2B051prEa7QWfrVTQm10/dDpswBDXZugPa1Ogu8Yh+HV0Q== + fs-readdir-recursive@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz#e32fc030a2ccee44a6b5371308da54be0b397d27" @@ -15040,7 +14866,7 @@ global-prefix@^3.0.0: kind-of "^6.0.2" which "^1.3.1" -global@^4.3.1, global@^4.3.2, global@^4.4.0: +global@^4.3.1, global@^4.4.0: version "4.4.0" resolved "https://registry.yarnpkg.com/global/-/global-4.4.0.tgz#3e7b105179006a323ed71aafca3e9c57a5cc6406" integrity sha512-wv/LAoHdRE3BeTGz53FAamhGlPLhlssK45usmGFThIi4XqnBmjKQ16u+RNbP7WvigRZDxUsM0J3gcQ5yicaL0w== @@ -15120,7 +14946,7 @@ globby@^10.0.1: merge2 "^1.2.3" slash "^3.0.0" -globby@^11.0.1, globby@^11.0.3, globby@^11.0.4: +globby@^11.0.1, globby@^11.0.2, globby@^11.0.3, globby@^11.0.4: version "11.0.4" resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== @@ -15887,7 +15713,7 @@ html-void-elements@^1.0.0: resolved "https://registry.yarnpkg.com/html-void-elements/-/html-void-elements-1.0.5.tgz#ce9159494e86d95e45795b166c2021c2cfca4483" integrity sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w== -html-webpack-plugin@^4.2.1: +html-webpack-plugin@^4.0.0: version "4.3.0" resolved "https://registry.yarnpkg.com/html-webpack-plugin/-/html-webpack-plugin-4.3.0.tgz#53bf8f6d696c4637d5b656d3d9863d89ce8174fd" integrity sha512-C0fzKN8yQoVLTelcJxZfJCE+aAvQiY2VUf3UuKrR4a9k5UMWYOtpDLsaXwATbcVCnI05hUS7L9ULQHWLZhyi3w== @@ -16400,7 +16226,7 @@ interpret@^1.0.0, interpret@^1.1.0, interpret@^1.4.0: resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.4.0.tgz#665ab8bc4da27a774a40584e812e3e0fa45b1a1e" integrity sha512-agE4QfB2Lkp9uICn7BAqoscw4SZP9kTE2hxiFI3jBPmXJfdqiahTbUuKGsMoN2GtqL9AxhYioAcVvgsb1HvRbA== -interpret@^2.0.0: +interpret@^2.2.0: version "2.2.0" resolved "https://registry.yarnpkg.com/interpret/-/interpret-2.2.0.tgz#1a78a0b5965c40a5416d007ad6f50ad27c417df9" integrity sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw== @@ -16434,7 +16260,7 @@ intl@^1.2.5: resolved "https://registry.yarnpkg.com/intl/-/intl-1.2.5.tgz#82244a2190c4e419f8371f5aa34daa3420e2abde" integrity sha1-giRKIZDE5Bn4Nx9ao02qNCDiq94= -invariant@2.2.4, invariant@^2.1.0, invariant@^2.1.1, invariant@^2.2.2, invariant@^2.2.3, invariant@^2.2.4: +invariant@^2.1.0, invariant@^2.1.1, invariant@^2.2.2, invariant@^2.2.3, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" integrity sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA== @@ -16667,7 +16493,7 @@ is-docker@^2.0.0: resolved "https://registry.yarnpkg.com/is-docker/-/is-docker-2.0.0.tgz#2cb0df0e75e2d064fe1864c37cdeacb7b2dcf25b" integrity sha512-pJEdRugimx4fBMra5z2/5iRdZ63OhYV0vr0Dwm5+xtW4D1FvRkB8hamMIhnWfyJeDdyr/aa7BDyNbtG38VxgoQ== -is-dom@^1.1.0: +is-dom@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/is-dom/-/is-dom-1.1.0.tgz#af1fced292742443bb59ca3f76ab5e80907b4e8a" integrity sha512-u82f6mvhYxRPKpw8V1N0W8ce1xXwOrQtgGcxl6UCL5zBmZu3is/18K0rR7uFCnMDuAsS/3W54mGL4vsaFUQlEQ== @@ -16925,6 +16751,11 @@ is-plain-object@3.0.0: dependencies: isobject "^4.0.0" +is-plain-object@5.0.0, is-plain-object@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" + integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== + is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-2.0.4.tgz#2c163b3fafb1b606d9d17928f05c2a1c38e07677" @@ -16932,11 +16763,6 @@ is-plain-object@^2.0.1, is-plain-object@^2.0.3, is-plain-object@^2.0.4: dependencies: isobject "^3.0.1" -is-plain-object@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/is-plain-object/-/is-plain-object-5.0.0.tgz#4427f50ab3429e9025ea7d52e9043a9ef4159344" - integrity sha512-VRSzKkbMm5jMDoKLbltAkFQ5Qr7VDiTFGXxYFXXowVj387GeGNOCsOH6Msy00SGZ3Fp84b1Naa1psqgcCIEP5Q== - is-potential-custom-element-name@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.0.tgz#0c52e54bcca391bb2c494b21e8626d7336c6e397" @@ -16957,7 +16783,7 @@ is-redirect@^1.0.0: resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24" integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ= -is-regex@^1.0.4, is-regex@^1.0.5, is-regex@^1.1.0, is-regex@^1.1.1, is-regex@^1.1.2, is-regex@^1.1.3, is-regex@^1.1.4: +is-regex@^1.0.4, is-regex@^1.0.5, is-regex@^1.1.0, is-regex@^1.1.2, is-regex@^1.1.3, is-regex@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.1.4.tgz#eef5663cd59fa4c0ae339505323df6854bb15958" integrity sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg== @@ -17404,16 +17230,6 @@ jest-diff@^24.9.0: jest-get-type "^24.9.0" pretty-format "^24.9.0" -jest-diff@^25.2.1: - version "25.5.0" - resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-25.5.0.tgz#1dd26ed64f96667c068cef026b677dfa01afcfa9" - integrity sha512-z1kygetuPiREYdNIumRpAHY6RXiGmp70YHptjdaxTWGmA085W3iCnXNx0DhflK3vwrKmrRWyY1wUpkPMVxMK7A== - dependencies: - chalk "^3.0.0" - diff-sequences "^25.2.6" - jest-get-type "^25.2.6" - pretty-format "^25.5.0" - jest-diff@^26.0.0, jest-diff@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-26.6.2.tgz#1aa7468b52c3a68d7d5c5fdcdfcd5e49bd164394" @@ -17491,11 +17307,6 @@ jest-get-type@^24.9.0: resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-24.9.0.tgz#1684a0c8a50f2e4901b6644ae861f579eed2ef0e" integrity sha512-lUseMzAley4LhIcpSP9Jf+fTrQ4a1yHQwLNeeVa2cEmbCGeoZAtYPOIv8JaxLD/sUpKxetKGP+gsHl8f8TSj8Q== -jest-get-type@^25.2.6: - version "25.2.6" - resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-25.2.6.tgz#0b0a32fab8908b44d508be81681487dbabb8d877" - integrity sha512-DxjtyzOHjObRM+sM1knti6or+eOgcGU4xVSb2HNP1TqO4ahsT+rqZg+nyqHWJSvWgKC5cG3QjGFBqxLghiF/Ig== - jest-get-type@^26.3.0: version "26.3.0" resolved "https://registry.yarnpkg.com/jest-get-type/-/jest-get-type-26.3.0.tgz#e97dc3c3f53c2b406ca7afaed4493b1d099199e0" @@ -17907,7 +17718,7 @@ jest-when@^3.2.1: bunyan "^1.8.12" expect "^24.8.0" -jest-worker@^26.2.1, jest-worker@^26.5.0, jest-worker@^26.6.2: +jest-worker@^26.5.0, jest-worker@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/jest-worker/-/jest-worker-26.6.2.tgz#7f72cbc4d643c365e27b9fd775f9d0eaa9c7a8ed" integrity sha512-KWYVV1c4i+jbMpaBC+U++4Va0cp8OisU185o73T1vo99hqi7w8tSJfUXYswwqqrjzwxa6KpRK54WhPvwf5w6PQ== @@ -18221,10 +18032,10 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.1.0, json5@^2.1.1, json5@^2.1.2: - version "2.1.3" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" - integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== +json5@^2.1.0, json5@^2.1.2, json5@^2.1.3: + version "2.2.0" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.0.tgz#2dfefe720c6ba525d9ebd909950f0515316c89a3" + integrity sha512-f+8cldu7X/y7RAJurMEJmdoKXGB/X550w2Nr3tTbezL6RwEE/iMcm+tZnXeoZtKuOq6ft8+CqzEkrIgx1fPoQA== dependencies: minimist "^1.2.5" @@ -18985,11 +18796,6 @@ lodash.set@^4.3.2: resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM= -lodash.some@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" - integrity sha1-G7nzFO9ri63tE7VJFpsqlF62jk0= - lodash.sortby@^4.7.0: version "4.7.0" resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" @@ -19382,6 +19188,11 @@ markdown-to-jsx@^6.11.4: prop-types "^15.6.2" unquote "^1.1.0" +markdown-to-jsx@^7.1.3: + version "7.1.3" + resolved "https://registry.yarnpkg.com/markdown-to-jsx/-/markdown-to-jsx-7.1.3.tgz#f00bae66c0abe7dd2d274123f84cb6bd2a2c7c6a" + integrity sha512-jtQ6VyT7rMT5tPV0g2EJakEnXLiPksnvlYtwQsVVZ611JsWGN8bQ1tVSDX4s6JllfEH6wmsYxNjTUAMrPmNA8w== + match-sorter@^6.0.2: version "6.1.0" resolved "https://registry.yarnpkg.com/match-sorter/-/match-sorter-6.1.0.tgz#7fec6808d94311a35fef7fd842a11634f2361bd7" @@ -19441,13 +19252,6 @@ mdast-squeeze-paragraphs@^4.0.0: dependencies: unist-util-remove "^2.0.0" -mdast-util-definitions@^2.0.0: - version "2.0.1" - resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-2.0.1.tgz#2c931d8665a96670639f17f98e32c3afcfee25f3" - integrity sha512-Co+DQ6oZlUzvUR7JCpP249PcexxygiaKk9axJh+eRzHDZJk2julbIdKB4PXHVxdBuLzvJ1Izb+YDpj2deGMOuA== - dependencies: - unist-util-visit "^2.0.0" - mdast-util-definitions@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz#c5c1a84db799173b4dcf7643cda999e440c24db2" @@ -19540,6 +19344,13 @@ media-typer@0.3.0: resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" integrity sha1-hxDXrwqmJvj/+hzgAWhUUmMlV0g= +memfs@^3.1.2: + version "3.3.0" + resolved "https://registry.yarnpkg.com/memfs/-/memfs-3.3.0.tgz#4da2d1fc40a04b170a56622c7164c6be2c4cbef2" + integrity sha512-BEE62uMfKOavX3iG7GYX43QJ+hAeeWnwIAuJ/R6q96jaMtiLzhsxHJC8B1L7fK7Pt/vXDRwb3SG/yBpNGDPqzg== + dependencies: + fs-monkey "1.0.3" + "memoize-one@>=3.1.1 <6", memoize-one@^5.0.0, memoize-one@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0" @@ -19726,7 +19537,7 @@ mime-db@1.44.0, mime-db@1.x.x, "mime-db@>= 1.40.0 < 2": resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.44.0.tgz#fa11c5eb0aca1334b4233cb4d52f10c5a6272f92" integrity sha512-/NOTfLrsPBVeH7YtFPgsVWveuL+4SjjYxaQ1xtM1KMFj7HdxlBlxeyNLzhyJVx7r4rZGJAZ/6lkKCitSc/Nmpg== -mime-types@^2.0.1, mime-types@^2.1.12, mime-types@^2.1.26, mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: +mime-types@^2.0.1, mime-types@^2.1.12, mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: version "2.1.27" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" integrity sha512-JIhqnCasI9yD+SsmkquHBxTSEuZdQX5BuQnS2Vc7puQQQ+8yiP5AY5uWhpdv4YL4VM5c6iliiYWPgJ/nJQLp7w== @@ -20489,7 +20300,7 @@ node-emoji@^1.10.0: dependencies: lodash.toarray "^4.4.0" -node-fetch@2.6.1, node-fetch@^1.0.1, node-fetch@^2.3.0, node-fetch@^2.6.0, node-fetch@^2.6.1: +node-fetch@2.6.1, node-fetch@^1.0.1, node-fetch@^2.3.0, node-fetch@^2.6.1: version "2.6.1" resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-2.6.1.tgz#045bd323631f76ed2e2b55573394416b639a0052" integrity sha512-V4aYg89jEoVRxRb2fJdAg8FHvI7cEyYdVAh94HH0UIK8oJxUfkjlDQN9RbMx+bEjP7+ggMiFRprSti032Oipxw== @@ -21263,10 +21074,10 @@ outpipe@^1.1.0: dependencies: shell-quote "^1.4.2" -overlayscrollbars@^1.10.2: - version "1.13.0" - resolved "https://registry.yarnpkg.com/overlayscrollbars/-/overlayscrollbars-1.13.0.tgz#1edb436328133b94877b558f77966d5497ca36a7" - integrity sha512-p8oHrMeRAKxXDMPI/EBNITj/zTVHKNnAnM59Im+xnoZUlV07FyTg46wom2286jJlXGGfcPFG/ba5NUiCwWNd4w== +overlayscrollbars@^1.13.1: + version "1.13.1" + resolved "https://registry.yarnpkg.com/overlayscrollbars/-/overlayscrollbars-1.13.1.tgz#0b840a88737f43a946b9d87875a2f9e421d0338a" + integrity sha512-gIQfzgGgu1wy80EB4/6DaJGHMEGmizq27xHIESrzXq0Y/J0Ay1P3DWk6tuVmEPIZH15zaBlxeEJOqdJKmowHCQ== p-all@^2.1.0: version "2.1.0" @@ -21323,12 +21134,12 @@ p-limit@^2.0.0, p-limit@^2.2.0, p-limit@^2.3.0: dependencies: p-try "^2.0.0" -p-limit@^3.0.1, p-limit@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.0.2.tgz#1664e010af3cadc681baafd3e2a437be7b0fb5fe" - integrity sha512-iwqZSOoWIW+Ew4kAGUlN16J4M7OB3ysMLSZtnhmqx7njIHFPlxWBX8xo3lVTyFVq6mI/lL9qt2IsN1sHwaxJkg== +p-limit@^3.0.1, p-limit@^3.0.2, p-limit@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-3.1.0.tgz#e1daccbe78d0d1388ca18c64fea38e3e57e3706b" + integrity sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ== dependencies: - p-try "^2.0.0" + yocto-queue "^0.1.0" p-locate@^2.0.0: version "2.0.0" @@ -21860,6 +21671,11 @@ phin@^2.9.1: resolved "https://registry.yarnpkg.com/phin/-/phin-2.9.3.tgz#f9b6ac10a035636fb65dfc576aaaa17b8743125c" integrity sha512-CzFr90qM24ju5f88quFC/6qohjC144rehe5n6DH900lgXmUe86+xCKc10ev56gRKC4/BkHUoG4uSiQgBiIXwDA== +picocolors@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-0.2.1.tgz#570670f793646851d1ba135996962abad587859f" + integrity sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA== + picocolors@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c" @@ -21961,6 +21777,13 @@ pkg-dir@^3.0.0: dependencies: find-up "^3.0.0" +pkg-dir@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" + integrity sha512-NPE8TDbzl/3YQYY7CSS228s3g2ollTFnc+Qi3tqmqJp9Vg2ovUpixcJEo2HJScN2Ez+kEaal6y70c0ehqJBJeA== + dependencies: + find-up "^5.0.0" + pkg-up@3.1.0, pkg-up@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/pkg-up/-/pkg-up-3.1.0.tgz#100ec235cc150e4fd42519412596a28512a0def5" @@ -22059,7 +21882,7 @@ point-in-polygon@^1.0.1: resolved "https://registry.yarnpkg.com/point-in-polygon/-/point-in-polygon-1.0.1.tgz#d59b64e8fee41c49458aac82b56718c5957b2af7" integrity sha1-1Ztk6P7kHElFiqyCtWcYxZV7Kvc= -polished@^3.4.4, polished@^3.7.2: +polished@^3.7.2: version "3.7.2" resolved "https://registry.yarnpkg.com/polished/-/polished-3.7.2.tgz#ec5ddc17a7d322a574d5e10ddd2a6f01d3e767d1" integrity sha512-pQKtpZGmsZrW8UUpQMAnR7s3ppHeMQVNyMDKtUyKwuvDmklzcEyM5Kllb3JyE/sE/x7arDmyd35i+4vp99H6sQ== @@ -22148,12 +21971,12 @@ postcss-discard-overridden@^4.0.1: dependencies: postcss "^7.0.0" -postcss-flexbugs-fixes@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.1.0.tgz#e094a9df1783e2200b7b19f875dcad3b3aff8b20" - integrity sha512-jr1LHxQvStNNAHlgco6PzY308zvLklh7SJVYuWUwyUQncofaAlD2l+P/gxKHOdqWKe7xJSkVLFF/2Tp+JqMSZA== +postcss-flexbugs-fixes@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/postcss-flexbugs-fixes/-/postcss-flexbugs-fixes-4.2.1.tgz#9218a65249f30897deab1033aced8578562a6690" + integrity sha512-9SiofaZ9CWpQWxOwRh1b/r85KD5y7GgvsNt1056k6OYLvWUun0czCvogfJgylC22uJTwW1KzY3Gz65NZRlvoiQ== dependencies: - postcss "^7.0.0" + postcss "^7.0.26" postcss-html@^0.36.0: version "0.36.0" @@ -22187,6 +22010,17 @@ postcss-loader@^3.0.0: postcss-load-config "^2.0.0" schema-utils "^1.0.0" +postcss-loader@^4.2.0: + version "4.3.0" + resolved "https://registry.yarnpkg.com/postcss-loader/-/postcss-loader-4.3.0.tgz#2c4de9657cd4f07af5ab42bd60a673004da1b8cc" + integrity sha512-M/dSoIiNDOo8Rk0mUqoj4kpGq91gcxCfb9PoyZVdZ76/AuhxylHDYZblNE8o+EQ9AMSASeMFEKxZf5aU6wlx1Q== + dependencies: + cosmiconfig "^7.0.0" + klona "^2.0.4" + loader-utils "^2.0.0" + schema-utils "^3.0.0" + semver "^7.3.4" + postcss-media-query-parser@^0.2.3: version "0.2.3" resolved "https://registry.yarnpkg.com/postcss-media-query-parser/-/postcss-media-query-parser-0.2.3.tgz#27b39c6f4d94f81b1a73b8f76351c609e5cef244" @@ -22501,20 +22335,26 @@ postcss@^7.0.0, postcss@^7.0.14, postcss@^7.0.16, postcss@^7.0.2, postcss@^7.0.2 source-map "^0.6.1" supports-color "^6.1.0" -postcss@^7.0.1, postcss@^7.0.27, postcss@^7.0.35: - version "7.0.35" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.35.tgz#d2be00b998f7f211d8a276974079f2e92b970e24" - integrity sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg== +postcss@^7.0.1, postcss@^7.0.27, postcss@^7.0.35, postcss@^7.0.36: + version "7.0.39" + resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.39.tgz#9624375d965630e2e1f2c02a935c82a59cb48309" + integrity sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA== dependencies: - chalk "^2.4.2" + picocolors "^0.2.1" source-map "^0.6.1" - supports-color "^6.1.0" potpack@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/potpack/-/potpack-1.0.1.tgz#d1b1afd89e4c8f7762865ec30bd112ab767e2ebf" integrity sha512-15vItUAbViaYrmaB/Pbw7z6qX2xENbFSTA7Ii4tgbPtasxm5v6ryKhKtL91tpWovDJzTiZqdwzhcFBCwiMVdVw== +preact-render-to-string@^5.1.19: + version "5.1.19" + resolved "https://registry.yarnpkg.com/preact-render-to-string/-/preact-render-to-string-5.1.19.tgz#ffae7c3bd1680be5ecf5991d41fe3023b3051e0e" + integrity sha512-bj8sn/oytIKO6RtOGSS/1+5CrQyRSC99eLUnEVbqUa6MzJX5dYh7wu9bmT0d6lm/Vea21k9KhCQwvr2sYN3rrQ== + dependencies: + pretty-format "^3.8.0" + prebuild-install@^6.1.2: version "6.1.4" resolved "https://registry.yarnpkg.com/prebuild-install/-/prebuild-install-6.1.4.tgz#ae3c0142ad611d58570b89af4986088a4937e00f" @@ -22566,10 +22406,10 @@ prettier@^2.4.0: resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.4.0.tgz#85bdfe0f70c3e777cf13a4ffff39713ca6f64cba" integrity sha512-DsEPLY1dE5HF3BxCRBmD4uYZ+5DCbvatnolqTqcxEgKVZnL2kUfyu7b8pPQ5+hTBkdhU9SLUmK0/pHb07RE4WQ== -prettier@~2.0.5: - version "2.0.5" - resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.0.5.tgz#d6d56282455243f2f92cc1716692c08aa31522d4" - integrity sha512-7PtVymN48hGcO4fGjybyBSIWDsLU4H4XlvOHfq91pz9kkGlonzwTfYkaIEwiRg/dAJF9YlbsduBAgtYLi+8cFg== +prettier@~2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/prettier/-/prettier-2.2.1.tgz#795a1a78dd52f073da0cd42b21f9c91381923ff5" + integrity sha512-PqyhM2yCjg/oKkFPtTGUojv7gnZAoG80ttl45O6x2Ug/rMJw4wcc9k6aaf2hibP7BGVCCM33gZoGjyvt9mm16Q== pretty-bytes@^5.6.0: version "5.6.0" @@ -22594,17 +22434,7 @@ pretty-format@^24.9.0: ansi-styles "^3.2.0" react-is "^16.8.4" -pretty-format@^25.2.1, pretty-format@^25.5.0: - version "25.5.0" - resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-25.5.0.tgz#7873c1d774f682c34b8d48b6743a2bf2ac55791a" - integrity sha512-kbo/kq2LQ/A/is0PQwsEHM7Ca6//bGPPvU6UnsdDRSKTWxT/ru/xb88v4BJf6a69H+uTytOEsTusT9ksd/1iWQ== - dependencies: - "@jest/types" "^25.5.0" - ansi-regex "^5.0.0" - ansi-styles "^4.0.0" - react-is "^16.12.0" - -pretty-format@^26.0.0, pretty-format@^26.4.0, pretty-format@^26.6.2: +pretty-format@^26.0.0, pretty-format@^26.6.2: version "26.6.2" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-26.6.2.tgz#e35c2705f14cb7fe2fe94fa078345b444120fc93" integrity sha512-7AeGuCYNGmycyQbCqd/3PWH4eOoX/OiCa0uphp57NVTeAGdJGaAliecxwBDHYQCIvrW7aDBZCYeNTP/WX69mkg== @@ -22624,6 +22454,11 @@ pretty-format@^27.2.0: ansi-styles "^5.0.0" react-is "^17.0.1" +pretty-format@^3.8.0: + version "3.8.0" + resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-3.8.0.tgz#bfbed56d5e9a776645f4b1ff7aa1a3ac4fa3c385" + integrity sha1-v77VbV6ad2ZF9LH/eqGjrE+jw4U= + pretty-hrtime@^1.0.0, pretty-hrtime@^1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz#b7e3ea42435a4c9b2759d99e0f201eb195802ee1" @@ -22753,6 +22588,14 @@ prompts@2.4.0, prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" +prompts@^2.4.0: + version "2.4.2" + resolved "https://registry.yarnpkg.com/prompts/-/prompts-2.4.2.tgz#7b57e73b3a48029ad10ebd44f74b01722a4cb069" + integrity sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q== + dependencies: + kleur "^3.0.3" + sisteransi "^1.0.5" + prop-types-exact@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/prop-types-exact/-/prop-types-exact-1.2.0.tgz#825d6be46094663848237e3925a98c6e944e9869" @@ -22762,7 +22605,7 @@ prop-types-exact@^1.2.0: object.assign "^4.1.0" reflect.ownkeys "^0.2.0" -prop-types@15.7.2, prop-types@15.x, prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: +prop-types@15.x, prop-types@^15.0.0, prop-types@^15.5.10, prop-types@^15.5.7, prop-types@^15.5.8, prop-types@^15.6.0, prop-types@^15.6.1, prop-types@^15.6.2, prop-types@^15.7.2: version "15.7.2" resolved "https://registry.yarnpkg.com/prop-types/-/prop-types-15.7.2.tgz#52c41e75b8c87e72b9d9360e0206b99dcbffa6c5" integrity sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ== @@ -22970,7 +22813,7 @@ q@^1.1.2, q@^1.5.1: resolved "https://registry.yarnpkg.com/q/-/q-1.5.1.tgz#7e32f75b41381291d04611f1bf14109ac00651d7" integrity sha1-fjL3W0E4EpHQRhHxvxQQmsAGUdc= -qs@6.7.0, qs@^6.5.1, qs@^6.6.0: +qs@6.7.0, qs@^6.5.1: version "6.7.0" resolved "https://registry.yarnpkg.com/qs/-/qs-6.7.0.tgz#41dc1a015e3d581f1621776be31afb2876a9b1bc" integrity sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ== @@ -23150,13 +22993,13 @@ raw-loader@^3.1.0: loader-utils "^1.1.0" schema-utils "^2.0.1" -raw-loader@^4.0.1: - version "4.0.1" - resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.1.tgz#14e1f726a359b68437e183d5a5b7d33a3eba6933" - integrity sha512-baolhQBSi3iNh1cglJjA0mYzga+wePk7vdEX//1dTFd+v4TsQlQE0jitJSNF1OIP82rdYulH7otaVmdlDaJ64A== +raw-loader@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/raw-loader/-/raw-loader-4.0.2.tgz#1aac6b7d1ad1501e66efdac1522c73e59a584eb6" + integrity sha512-ZnScIV3ag9A4wPX/ZayxL/jZH+euYb6FcUinPcgiQW0+UBtEv0O6Q3lGd3cqJ+GHH+rksEv3Pj99oxJ3u3VIKA== dependencies: loader-utils "^2.0.0" - schema-utils "^2.6.5" + schema-utils "^3.0.0" rbush@^3.0.0, rbush@^3.0.1: version "3.0.1" @@ -23237,7 +23080,7 @@ react-clientside-effect@^1.2.2: dependencies: "@babel/runtime" "^7.0.0" -react-color@^2.13.8, react-color@^2.17.0: +react-color@^2.13.8: version "2.17.0" resolved "https://registry.yarnpkg.com/react-color/-/react-color-2.17.0.tgz#e14b8a11f4e89163f65a34c8b43faf93f7f02aaa" integrity sha512-kJfE5tSaFe6GzalXOHksVjqwCPAsTl+nzS9/BWfP7j3EXbQ4IiLAF9sZGNzk3uq7HfofGYgjmcUgh0JP7xAQ0w== @@ -23249,6 +23092,11 @@ react-color@^2.13.8, react-color@^2.17.0: reactcss "^1.2.0" tinycolor2 "^1.4.1" +react-colorful@^5.1.2: + version "5.5.1" + resolved "https://registry.yarnpkg.com/react-colorful/-/react-colorful-5.5.1.tgz#29d9c4e496f2ca784dd2bb5053a3a4340cfaf784" + integrity sha512-M1TJH2X3RXEt12sWkpa6hLc/bbYS0H6F4rIqjQZ+RxNBstpY67d9TrFXtqdZwhpmBXcCwEi7stKqFue3ZRkiOg== + react-dev-utils@^11.0.3: version "11.0.4" resolved "https://registry.yarnpkg.com/react-dev-utils/-/react-dev-utils-11.0.4.tgz#a7ccb60257a1ca2e0efe7a83e38e6700d17aa37a" @@ -23279,21 +23127,10 @@ react-dev-utils@^11.0.3: strip-ansi "6.0.0" text-table "0.2.0" -react-docgen-typescript-plugin@^0.6.2: - version "0.6.3" - resolved "https://registry.yarnpkg.com/react-docgen-typescript-plugin/-/react-docgen-typescript-plugin-0.6.3.tgz#664b22601df083597ecb1e60bd21beca60125fdf" - integrity sha512-av1S/fmWBNFGgNa4qtkidFjjOz23eEi6EdCtwSWo9WNhGzUMyMygbD/DosMWoeFlZpk9R3MXPkRE7PDH6j5GMQ== - dependencies: - debug "^4.1.1" - endent "^2.0.1" - micromatch "^4.0.2" - react-docgen-typescript "^1.20.5" - tslib "^2.0.0" - -react-docgen-typescript@^1.20.5: - version "1.21.0" - resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-1.21.0.tgz#3385dde81b63eb1d54f86a935bd4f65f96c821f6" - integrity sha512-E4y/OcXwHukgiVafCGlxwoNHr4BDmM70Ww7oimL/QkMo5dmGALhceewe/xmVjdMxxI7E5syOGOc9/tbHL742rg== +react-docgen-typescript@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/react-docgen-typescript/-/react-docgen-typescript-2.1.1.tgz#c9f9ccb1fa67e0f4caf3b12f2a07512a201c2dcf" + integrity sha512-XWe8bsYqVjxciKdpNoufaHiB7FgUHIOnVQgxUolRL3Zlof2zkdTzuQH6SU2n3Ek9kfy3O1c63ojMtNfpiuNeZQ== react-docgen@^5.0.0: version "5.3.0" @@ -23327,12 +23164,12 @@ react-draggable@3.x, "react-draggable@^2.2.6 || ^3.0.3": classnames "^2.2.5" prop-types "^15.6.0" -react-draggable@^4.0.3: - version "4.1.0" - resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.1.0.tgz#e1c5b774001e32f0bff397254e1e9d5448ac92a4" - integrity sha512-Or/qe70cfymshqoC8Lsp0ukTzijJObehb7Vfl7tb5JRxoV+b6PDkOGoqYaWBzZ59k9dH/bwraLGsnlW78/3vrA== +react-draggable@^4.0.3, react-draggable@^4.4.3: + version "4.4.4" + resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.4.tgz#5b26d9996be63d32d285a426f41055de87e59b2f" + integrity sha512-6e0WdcNLwpBx/YIDpoyd2Xb04PB0elrDrulKUgdrIlwuYvxh5Ok9M+F8cljm8kPXXs43PmMzek9RrB1b7mLMqA== dependencies: - classnames "^2.2.5" + clsx "^1.1.1" prop-types "^15.6.0" react-dropzone@^11.2.0: @@ -23352,13 +23189,14 @@ react-dropzone@^4.2.9: attr-accept "^1.1.3" prop-types "^15.5.7" -react-element-to-jsx-string@^14.3.1: - version "14.3.1" - resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-14.3.1.tgz#a08fa6e46eb76061aca7eabc2e70f433583cb203" - integrity sha512-LRdQWRB+xcVPOL4PU4RYuTg6dUJ/FNmaQ8ls6w38YbzkbV6Yr5tFNESroub9GiSghtnMq8dQg2LcNN5aMIDzVg== +react-element-to-jsx-string@^14.3.2: + version "14.3.4" + resolved "https://registry.yarnpkg.com/react-element-to-jsx-string/-/react-element-to-jsx-string-14.3.4.tgz#709125bc72f06800b68f9f4db485f2c7d31218a8" + integrity sha512-t4ZwvV6vwNxzujDQ+37bspnLwA4JlgUPWhLjBJWsNIDceAf6ZKUTCjdm08cN6WeZ5pTMKiCJkmAYnpmR4Bm+dg== dependencies: - "@base2/pretty-print-object" "1.0.0" - is-plain-object "3.0.0" + "@base2/pretty-print-object" "1.0.1" + is-plain-object "5.0.0" + react-is "17.0.2" react-error-boundary@^3.1.0: version "3.1.1" @@ -23372,12 +23210,12 @@ react-error-overlay@^6.0.9: resolved "https://registry.yarnpkg.com/react-error-overlay/-/react-error-overlay-6.0.9.tgz#3c743010c9359608c375ecd6bc76f35d93995b0a" integrity sha512-nQTTcUu+ATDbrSD1BZHr5kgSD4oF8OFjxun8uAaL8RwPBacGBNPf/yAuVVdx17N8XNzRDMrZ9XcKZHCjPW+9ew== -react-fast-compare@2.0.4, react-fast-compare@^2.0.4: +react-fast-compare@^2.0.4: version "2.0.4" resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9" integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw== -react-fast-compare@^3.0.1: +react-fast-compare@^3.0.1, react-fast-compare@^3.2.0: version "3.2.0" resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb" integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA== @@ -23417,23 +23255,16 @@ react-grid-layout@^0.16.2: react-draggable "3.x" react-resizable "1.x" -react-helmet-async@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-1.0.2.tgz#bb55dd8268f7b15aac69c6b22e2f950abda8cc44" - integrity sha512-qzzchrM/ibHuPS/60ief8jaibPunuRdeta4iBDQV+ri2SFKwOV+X2NlEpvevZOauhmHrH/I6dI4E90EPVfJBBg== - dependencies: - "@babel/runtime" "7.3.4" - invariant "2.2.4" - prop-types "15.7.2" - react-fast-compare "2.0.4" - shallowequal "1.1.0" - -react-hotkeys@2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/react-hotkeys/-/react-hotkeys-2.0.0.tgz#a7719c7340cbba888b0e9184f806a9ec0ac2c53f" - integrity sha512-3n3OU8vLX/pfcJrR3xJ1zlww6KS1kEJt0Whxc4FiGV+MJrQ1mYSYI3qS/11d2MJDFm8IhOXMTFQirfu6AVOF6Q== +react-helmet-async@^1.0.7: + version "1.1.2" + resolved "https://registry.yarnpkg.com/react-helmet-async/-/react-helmet-async-1.1.2.tgz#653b7e6bbfdd239c5dcd6b8df2811c7a363b8334" + integrity sha512-LTTzDDkyIleT/JJ6T/uqx7Y8qi1EuPPSiJawQY/nHHz0h7SPDT6HxP1YDDQx/fzcVxCqpWEEMS3QdrSrNkJYhg== dependencies: - prop-types "^15.6.1" + "@babel/runtime" "^7.12.5" + invariant "^2.2.4" + prop-types "^15.7.2" + react-fast-compare "^3.2.0" + shallowequal "^1.1.0" react-input-autosize@^2.2.1, react-input-autosize@^2.2.2: version "2.2.2" @@ -23442,14 +23273,21 @@ react-input-autosize@^2.2.1, react-input-autosize@^2.2.2: dependencies: prop-types "^15.5.8" -react-inspector@^5.0.1: - version "5.0.1" - resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-5.0.1.tgz#8a30f3d488c4f40203624bbe24800f508ae05d3a" - integrity sha512-qRIENuAIcRaytrmg/TL5nN5igYZMzyQqIKlWA8zoYRDltULsZC1bWy2Ua5wYJuwEYnC3gK4FCjcIQnb+5OyLsQ== +react-input-autosize@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-3.0.0.tgz#6b5898c790d4478d69420b55441fcc31d5c50a85" + integrity sha512-nL9uS7jEs/zu8sqwFE5MAPx6pPkNAriACQ2rGLlqmKr2sPGtN7TXTyDdQt4lbNXVx7Uzadb40x8qotIuru6Rhg== dependencies: - "@babel/runtime" "^7.8.7" - is-dom "^1.1.0" - prop-types "^15.6.1" + prop-types "^15.5.8" + +react-inspector@^5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/react-inspector/-/react-inspector-5.1.1.tgz#58476c78fde05d5055646ed8ec02030af42953c8" + integrity sha512-GURDaYzoLbW8pMGXwYPDBIv6nqei4kK7LPRZ9q9HCZF54wqXz/dnylBp/kfE9XmekBhHvLDdcYeyIwSrvtOiWg== + dependencies: + "@babel/runtime" "^7.0.0" + is-dom "^1.0.0" + prop-types "^15.0.0" react-intl@^2.8.0: version "2.8.0" @@ -23462,6 +23300,11 @@ react-intl@^2.8.0: intl-relativeformat "^2.1.0" invariant "^2.1.1" +react-is@17.0.2: + version "17.0.2" + resolved "https://registry.yarnpkg.com/react-is/-/react-is-17.0.2.tgz#e691d4a8e9c789365655539ab372762b0efb54f0" + integrity sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w== + react-is@^16.12.0, react-is@^16.13.1, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0: version "16.13.1" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4" @@ -23694,10 +23537,10 @@ react-select@^2.4.4: react-input-autosize "^2.2.1" react-transition-group "^2.2.1" -react-select@^3.0.8: - version "3.1.0" - resolved "https://registry.yarnpkg.com/react-select/-/react-select-3.1.0.tgz#ab098720b2e9fe275047c993f0d0caf5ded17c27" - integrity sha512-wBFVblBH1iuCBprtpyGtd1dGMadsG36W5/t2Aj8OE6WbByDg5jIFyT7X5gT+l0qmT5TqWhxX+VsKJvCEl2uL9g== +react-select@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/react-select/-/react-select-3.2.0.tgz#de9284700196f5f9b5277c5d850a9ce85f5c72fe" + integrity sha512-B/q3TnCZXEKItO0fFN/I0tWOX3WJvi/X2wtdffmwSQVRwg5BpValScTO1vdic9AxlUgmeSzib2hAZAwIUQUZGQ== dependencies: "@babel/runtime" "^7.4.4" "@emotion/cache" "^10.0.9" @@ -23705,7 +23548,7 @@ react-select@^3.0.8: "@emotion/css" "^10.0.9" memoize-one "^5.0.0" prop-types "^15.6.0" - react-input-autosize "^2.2.2" + react-input-autosize "^3.0.0" react-transition-group "^4.3.0" react-shortcuts@^2.0.0: @@ -23729,25 +23572,15 @@ react-sizeme@^2.3.6: invariant "^2.2.2" lodash "^4.17.4" -react-sizeme@^2.5.2: - version "2.6.12" - resolved "https://registry.yarnpkg.com/react-sizeme/-/react-sizeme-2.6.12.tgz#ed207be5476f4a85bf364e92042520499455453e" - integrity sha512-tL4sCgfmvapYRZ1FO2VmBmjPVzzqgHA7kI8lSJ6JS6L78jXFNRdOZFpXyK6P1NBZvKPPCZxReNgzZNUajAerZw== - dependencies: - element-resize-detector "^1.2.1" - invariant "^2.2.4" - shallowequal "^1.1.0" - throttle-debounce "^2.1.0" - -react-sizeme@^2.6.7: - version "2.6.10" - resolved "https://registry.yarnpkg.com/react-sizeme/-/react-sizeme-2.6.10.tgz#9993dcb5e67fab94a8e5d078a0d3820609010f17" - integrity sha512-OJAPQxSqbcpbsXFD+fr5ARw4hNSAOimWcaTOLcRkIqnTp9+IFWY0w3Qdw1sMez6Ao378aimVL/sW6TTsgigdOA== +react-sizeme@^3.0.1: + version "3.0.2" + resolved "https://registry.yarnpkg.com/react-sizeme/-/react-sizeme-3.0.2.tgz#4a2f167905ba8f8b8d932a9e35164e459f9020e4" + integrity sha512-xOIAOqqSSmKlKFJLO3inBQBdymzDuXx4iuwkNcJmC96jeiOg5ojByvL+g3MW9LPEsojLbC6pf68zOfobK8IPlw== dependencies: - element-resize-detector "^1.1.15" + element-resize-detector "^1.2.2" invariant "^2.2.4" shallowequal "^1.1.0" - throttle-debounce "^2.1.0" + throttle-debounce "^3.0.1" react-style-singleton@^2.1.0: version "2.1.0" @@ -23758,7 +23591,7 @@ react-style-singleton@^2.1.0: invariant "^2.2.4" tslib "^1.0.0" -react-syntax-highlighter@^13.5.0, react-syntax-highlighter@^15.3.1: +react-syntax-highlighter@^13.5.3, react-syntax-highlighter@^15.3.1: version "15.3.1" resolved "https://registry.yarnpkg.com/react-syntax-highlighter/-/react-syntax-highlighter-15.3.1.tgz#ba16ae8705f191956b73d0e11ae938fd255f2579" integrity sha512-XVQuug7kQ4/cWxiYE0XfGXvbDqLLqRsMK/GpmD3v1WOLzb6REcgkL59cJo0m3Y2LB0eoRCNhV62jqQe9/Z0p9w== @@ -23779,10 +23612,10 @@ react-test-renderer@^16.0.0-0, react-test-renderer@^16.12.0, "react-test-rendere react-is "^16.8.6" scheduler "^0.18.0" -react-textarea-autosize@^8.1.1: - version "8.2.0" - resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.2.0.tgz#fae38653f5ec172a855fd5fffb39e466d56aebdb" - integrity sha512-grajUlVbkx6VdtSxCgzloUIphIZF5bKr21OYMceWPKkniy7H0mRAT/AXPrRtObAe+zUePnNlBwUc4ivVjUGIjw== +react-textarea-autosize@^8.3.0: + version "8.3.3" + resolved "https://registry.yarnpkg.com/react-textarea-autosize/-/react-textarea-autosize-8.3.3.tgz#f70913945369da453fd554c168f6baacd1fa04d8" + integrity sha512-2XlHXK2TDxS6vbQaoPbMOfQ8GK7+irc2fVK6QFIcC8GOnH3zI/v481n+j1L0WaPVvKxwesnY93fEfH++sus2rQ== dependencies: "@babel/runtime" "^7.10.2" use-composed-ref "^1.0.0" @@ -24246,11 +24079,6 @@ regenerator-runtime@^0.11.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.11.1.tgz#be05ad7f9bf7d22e056f9726cee5017fbf19e2e9" integrity sha512-MguG95oij0fC3QV3URf4V2SDYGJhJnJGqvIIgdECeODCT98wSWDAJ94SSuVpYQUoTcGUIL6L4yNB7j1DFFHSBg== -regenerator-runtime@^0.12.0: - version "0.12.1" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" - integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== - regenerator-runtime@^0.13.1, regenerator-runtime@^0.13.3, regenerator-runtime@^0.13.4, regenerator-runtime@^0.13.7: version "0.13.7" resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.7.tgz#cac2dacc8a1ea675feaabaeb8ae833898ae46f55" @@ -24392,14 +24220,14 @@ remark-emoji@^2.1.0: node-emoji "^1.10.0" unist-util-visit "^2.0.2" -remark-external-links@^6.0.0: - version "6.1.0" - resolved "https://registry.yarnpkg.com/remark-external-links/-/remark-external-links-6.1.0.tgz#1a545b3cf896eae00ec1732d90f595f75a329abe" - integrity sha512-dJr+vhe3wuh1+E9jltQ+efRMqtMDOOnfFkhtoArOmhnBcPQX6THttXMkc/H0kdnAvkXTk7f2QdOYm5qo/sGqdw== +remark-external-links@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/remark-external-links/-/remark-external-links-8.0.0.tgz#308de69482958b5d1cd3692bc9b725ce0240f345" + integrity sha512-5vPSX0kHoSsqtdftSHhIYofVINC8qmp0nctkeU9YoJwV3YfiBRiI6cbFRJ0oI/1F9xS+bopXG0m2KS8VFscuKA== dependencies: extend "^3.0.0" is-absolute-url "^3.0.0" - mdast-util-definitions "^2.0.0" + mdast-util-definitions "^4.0.0" space-separated-tokens "^1.0.0" unist-util-visit "^2.0.0" @@ -24778,7 +24606,7 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.1.10, resolve@^1.1.4, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.20.0, resolve@^1.3.2, resolve@^1.3.3, resolve@^1.4.0, resolve@^1.7.1, resolve@^1.8.1: +resolve@^1.1.10, resolve@^1.1.4, resolve@^1.1.5, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.17.0, resolve@^1.18.1, resolve@^1.19.0, resolve@^1.20.0, resolve@^1.3.2, resolve@^1.3.3, resolve@^1.4.0, resolve@^1.7.1, resolve@^1.8.1: version "1.20.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.20.0.tgz#629a013fb3f70755d6f0b7935cc1c2c5378b1975" integrity sha512-wENBPt4ySzg4ybFQW2TT1zMQucPK95HSh/nq2CFTZVOGut2+pQvSsgtda4d26YrYcr067wjbmzOG8byDPBX63A== @@ -25149,15 +24977,7 @@ schema-utils@1.0.0, schema-utils@^0.3.0, schema-utils@^1.0.0: ajv-errors "^1.0.0" ajv-keywords "^3.1.0" -schema-utils@^0.4.5: - version "0.4.7" - resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" - integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== - dependencies: - ajv "^6.1.0" - ajv-keywords "^3.1.0" - -schema-utils@^2.0.0, schema-utils@^2.0.1, schema-utils@^2.5.0, schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0: +schema-utils@2.7.0, schema-utils@^2.0.0, schema-utils@^2.0.1, schema-utils@^2.5.0, schema-utils@^2.6.5, schema-utils@^2.6.6, schema-utils@^2.7.0: version "2.7.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-2.7.0.tgz#17151f76d8eae67fbbf77960c33c676ad9f4efc7" integrity sha512-0ilKFI6QQF5nxDZLFn2dMjvc4hjg/Wkg7rHd3jK6/A4a1Hl9VFdQWvgB1UMGoU94pad1P/8N7fMcEnLnSiju8A== @@ -25166,6 +24986,14 @@ schema-utils@^2.0.0, schema-utils@^2.0.1, schema-utils@^2.5.0, schema-utils@^2.6 ajv "^6.12.2" ajv-keywords "^3.4.1" +schema-utils@^0.4.5: + version "0.4.7" + resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187" + integrity sha512-v/iwU6wvwGK8HbU9yi3/nhGzP0yGSuhQMzL6ySiec1FSrZZDkhm4noOSWzrNFo/jEc+SJY6jRTwuwbSXJPDUnQ== + dependencies: + ajv "^6.1.0" + ajv-keywords "^3.1.0" + schema-utils@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/schema-utils/-/schema-utils-3.0.0.tgz#67502f6aa2b66a2d4032b4279a2944978a0913ef" @@ -25329,13 +25157,6 @@ serialize-javascript@^3.0.0, serialize-javascript@^3.1.0: dependencies: randombytes "^2.1.0" -serialize-javascript@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/serialize-javascript/-/serialize-javascript-4.0.0.tgz#b525e1238489a5ecfc42afacc3fe99e666f4b1aa" - integrity sha512-GaNA54380uFefWghODBWEGisLZFj00nS5ACs6yHa9nLqlLpVLO8ChDGeKRjZnV4Nh4n0Qi7nhYZD/9fCPzEqkw== - dependencies: - randombytes "^2.1.0" - serve-favicon@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/serve-favicon/-/serve-favicon-2.5.0.tgz#935d240cdfe0f5805307fdfe967d88942a2cbcf0" @@ -25463,7 +25284,7 @@ shallow-copy@~0.0.1: resolved "https://registry.yarnpkg.com/shallow-copy/-/shallow-copy-0.0.1.tgz#415f42702d73d810330292cc5ee86eae1a11a170" integrity sha1-QV9CcC1z2BAzApLMXuhurhoRoXA= -shallowequal@1.1.0, shallowequal@^1.1.0: +shallowequal@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/shallowequal/-/shallowequal-1.1.0.tgz#188d521de95b9087404fd4dcb68b13df0ae4e7f8" integrity sha512-y0m1JoUZSlPAjXVtPPW70aZWfIL/dSP7AFkRnniLCrK/8MDKog3TySTBmckD+RObVxH0v4Tox67+F14PdED2oQ== @@ -26225,10 +26046,16 @@ store2@^2.12.0: resolved "https://registry.yarnpkg.com/store2/-/store2-2.12.0.tgz#e1f1b7e1a59b6083b2596a8d067f6ee88fd4d3cf" integrity sha512-7t+/wpKLanLzSnQPX8WAcuLCCeuSHoWdQuh9SB3xD0kNOM38DNf+0Oa+wmvxmYueRzkmh6IcdKFtvTa+ecgPDw== -store2@^2.7.1: - version "2.9.0" - resolved "https://registry.yarnpkg.com/store2/-/store2-2.9.0.tgz#9987e3cf491b8163fd6197c42bab7d71c58c179b" - integrity sha512-JmK+95jLX2zAP75DVAJ1HAziQ6f+f495h4P9ez2qbmxazN6fE7doWlitqx9hj2YohH3kOi6RVksJe1UH0sJfPw== +storybook-addon-outline@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/storybook-addon-outline/-/storybook-addon-outline-1.4.1.tgz#0a1b262b9c65df43fc63308a1fdbd4283c3d9458" + integrity sha512-Qvv9X86CoONbi+kYY78zQcTGmCgFaewYnOVR6WL7aOFJoW7TrLiIc/O4hH5X9PsEPZFqjfXEPUPENWVUQim6yw== + dependencies: + "@storybook/addons" "^6.3.0" + "@storybook/api" "^6.3.0" + "@storybook/components" "^6.3.0" + "@storybook/core-events" "^6.3.0" + ts-dedent "^2.1.1" stream-browserify@^2.0.0: version "2.0.2" @@ -26603,13 +26430,13 @@ style-it@^2.1.3: dependencies: react-lib-adler32 "^1.0.3" -style-loader@^1.1.3, style-loader@^1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.2.1.tgz#c5cbbfbf1170d076cfdd86e0109c5bba114baa1a" - integrity sha512-ByHSTQvHLkWE9Ir5+lGbVOXhxX10fbprhLvdg96wedFZb4NDekDPxVKv5Fwmio+QcMlkkNfuK+5W1peQ5CUhZg== +style-loader@^1.1.3, style-loader@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/style-loader/-/style-loader-1.3.0.tgz#828b4a3b3b7e7aa5847ce7bae9e874512114249e" + integrity sha512-V7TCORko8rs9rIqkSrlMfkqA63DfoGBBJmK1kKGCcSi+BWb4cqz0SRsnp4l6rU5iwOEd0/2ePv68SV22VXon4Q== dependencies: loader-utils "^2.0.0" - schema-utils "^2.6.6" + schema-utils "^2.7.0" style-search@^0.1.0: version "0.1.0" @@ -27105,24 +26932,10 @@ tcp-port-used@^1.0.1: debug "4.1.0" is2 "2.0.1" -telejson@^5.0.2: - version "5.0.2" - resolved "https://registry.yarnpkg.com/telejson/-/telejson-5.0.2.tgz#ed1e64be250cc1c757a53c19e1740b49832b3d51" - integrity sha512-XCrDHGbinczsscs8LXFr9jDhvy37yBk9piB7FJrCfxE8oP66WDkolNMpaBkWYgQqB9dQGBGtTDzGQPedc9KJmw== - dependencies: - "@types/is-function" "^1.0.0" - global "^4.4.0" - is-function "^1.0.2" - is-regex "^1.1.1" - is-symbol "^1.0.3" - isobject "^4.0.0" - lodash "^4.17.19" - memoizerific "^1.11.3" - -telejson@^5.1.0: - version "5.1.1" - resolved "https://registry.yarnpkg.com/telejson/-/telejson-5.1.1.tgz#fd83b594ebddfaeb9a5c4b9660c302fc07c9a65c" - integrity sha512-aU7x+nwodmODJPXhU9sC/REOcX/dx1tNbyeOFV1PCTh6e9Mj+bnyfQ7sr13zfJYya9BtpGwnUNn9Fd76Ybj2eg== +telejson@^5.3.2: + version "5.3.3" + resolved "https://registry.yarnpkg.com/telejson/-/telejson-5.3.3.tgz#fa8ca84543e336576d8734123876a9f02bf41d2e" + integrity sha512-PjqkJZpzEggA9TBpVtJi1LVptP7tYtXB6rEubwlHap76AMjzvOdKX41CxyaW7ahhzDU1aftXnMCx5kAPDZTQBA== dependencies: "@types/is-function" "^1.0.0" global "^4.4.0" @@ -27175,21 +26988,6 @@ terser-webpack-plugin@^1.4.3: webpack-sources "^1.4.0" worker-farm "^1.7.0" -terser-webpack-plugin@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-3.1.0.tgz#91e6d39571460ed240c0cf69d295bcf30ebf98cb" - integrity sha512-cjdZte66fYkZ65rQ2oJfrdCAkkhJA7YLYk5eGOcGCSGlq0ieZupRdjedSQXYknMPo2IveQL+tPdrxUkERENCFA== - dependencies: - cacache "^15.0.5" - find-cache-dir "^3.3.1" - jest-worker "^26.2.1" - p-limit "^3.0.2" - schema-utils "^2.6.6" - serialize-javascript "^4.0.0" - source-map "^0.6.1" - terser "^4.8.0" - webpack-sources "^1.4.3" - terser-webpack-plugin@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/terser-webpack-plugin/-/terser-webpack-plugin-4.2.3.tgz#28daef4a83bd17c1db0297070adc07fc8cfc6a9a" @@ -27214,7 +27012,7 @@ terser@5.4.0: source-map "~0.7.2" source-map-support "~0.5.19" -terser@^4.1.2, terser@^4.6.3, terser@^4.8.0: +terser@^4.1.2, terser@^4.6.3: version "4.8.0" resolved "https://registry.yarnpkg.com/terser/-/terser-4.8.0.tgz#63056343d7c70bb29f3af665865a46fe03a0df17" integrity sha512-EAPipTNeWsb/3wLPeup1tVPaXfIaU68xMnVdPafIL1TV05OhASArYyIfFvnvJCNrR2NIOvDVNNTFRa+Re2MWyw== @@ -27280,6 +27078,11 @@ throttle-debounce@^2.1.0: resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-2.1.0.tgz#257e648f0a56bd9e54fe0f132c4ab8611df4e1d5" integrity sha512-AOvyNahXQuU7NN+VVvOOX+uW6FPaWdAOdRP5HfwYxAfCzXTFKRMoIMk+n+po318+ktcChx+F1Dd91G3YHeMKyg== +throttle-debounce@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-3.0.1.tgz#32f94d84dfa894f786c9a1f290e7a645b6a19abb" + integrity sha512-dTEWWNu6JmeVXY0ZYoPuH5cRIwc0MeGbJwah9KUNYSJwommQpCzTySTpEe8Gs1J23aeWEuAobe4Ag7EHVt/LOg== + throttleit@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/throttleit/-/throttleit-1.0.0.tgz#9e785836daf46743145a5984b6268d828528ac6c" @@ -27670,10 +27473,10 @@ ts-debounce@^3.0.0: resolved "https://registry.yarnpkg.com/ts-debounce/-/ts-debounce-3.0.0.tgz#9beedf59c04de3b5bef8ff28bd6885624df357be" integrity sha512-7jiRWgN4/8IdvCxbIwnwg2W0bbYFBH6BxFqBjMKk442t7+liF2Z1H6AUCcl8e/pD93GjPru+axeiJwFmRww1WQ== -ts-dedent@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.0.0.tgz#47c5eb23d9096f3237cc413bc82d387d36dbe690" - integrity sha512-DfxKjSFQfw9+uf7N9Cy8Ebx9fv5fquK4hZ6SD3Rzr+1jKP6AVA6H8+B5457ZpUs0JKsGpGqIevbpZ9DMQJDp1A== +ts-dedent@^2.0.0, ts-dedent@^2.1.1: + version "2.2.0" + resolved "https://registry.yarnpkg.com/ts-dedent/-/ts-dedent-2.2.0.tgz#39e4bd297cd036292ae2394eb3412be63f563bb5" + integrity sha512-q5W7tVM71e2xjHZTlgfTDoPF/SmqKG5hddq9SzR49CH2hayqRKJtQ4mtRlSxKaJlR/+9rEM+mnBHf7I2/BQcpQ== ts-easing@^0.2.0: version "0.2.0" @@ -28058,10 +27861,10 @@ undici@^4.7.0: resolved "https://registry.yarnpkg.com/undici/-/undici-4.7.0.tgz#3bda286d67bf45d0ab1b94ca6c84e546dcb3b0d4" integrity sha512-O1q+/EIs4g0HnVMH8colei3qODGiYBLpavWYv3kI+JazBBsBIndnZfUqZ2MEfPJ12H9d56yVdwZG1/nV/xcoSQ== -unfetch@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.1.0.tgz#6ec2dd0de887e58a4dee83a050ded80ffc4137db" - integrity sha512-crP/n3eAPUJxZXM9T80/yv0YhkTEx2K1D3h7D1AJM6fzsWZrxdyRuLN0JH/dkZh1LNH8LxCnBzoPFCPbb2iGpg== +unfetch@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/unfetch/-/unfetch-4.2.0.tgz#7e21b0ef7d363d8d9af0fb929a5555f6ef97a3be" + integrity sha512-F9p7yYCn6cIW9El1zi0HI6vqpeIvBsr3dSuRO6Xuppb1u5rXpCPmMvLSyECLhybr9isec8Ohl0hPekMVrEinDA== unherit@^1.0.4: version "1.1.0" @@ -28491,14 +28294,14 @@ url-loader@^2.2.0: mime "^2.4.4" schema-utils "^2.5.0" -url-loader@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.0.tgz#c7d6b0d6b0fccd51ab3ffc58a78d32b8d89a7be2" - integrity sha512-IzgAAIC8wRrg6NYkFIJY09vtktQcsvU8V6HhtQj9PTefbYImzLB1hufqo4m+RyM5N3mLx5BqJKccgxJS+W3kqw== +url-loader@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/url-loader/-/url-loader-4.1.1.tgz#28505e905cae158cf07c92ca622d7f237e70a4e2" + integrity sha512-3BTV812+AVHHOJQO8O5MkWgZ5aosP7GnROJwvzLS9hWDj00lZ6Z0wNak423Lp9PBZN05N+Jk/N5Si8jRAlGyWA== dependencies: loader-utils "^2.0.0" - mime-types "^2.1.26" - schema-utils "^2.6.5" + mime-types "^2.1.27" + schema-utils "^3.0.0" url-parse-lax@^3.0.0: version "3.0.0" @@ -28662,6 +28465,11 @@ utils-merge@1.0.1: resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713" integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM= +uuid-browser@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/uuid-browser/-/uuid-browser-3.1.0.tgz#0f05a40aef74f9e5951e20efbf44b11871e56410" + integrity sha1-DwWkCu90+eWVHiDvv0SxGHHlZBA= + uuid@3.3.2: version "3.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.3.2.tgz#1b4af4955eb3077c501c23872fc6513811587131" @@ -28682,12 +28490,7 @@ uuid@^7.0.3: resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.3.tgz#c5c9f2c8cf25dc0a372c4df1441c41f5bd0c680b" integrity sha512-DPSke0pXhTZgoF/d+WSt2QaKMCFSfx7QegxEWT+JOuHF5aWrKEn0G+ztjuJg/gG8/ItK+rbPCD/yNv8yyih6Cg== -uuid@^8.0.0, uuid@^8.3.0: - version "8.3.0" - resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.0.tgz#ab738085ca22dc9a8c92725e459b1d507df5d6ea" - integrity sha512-fX6Z5o4m6XsXBdli9g7DtWgAx+osMsRRZFKma1mIUsLCz6vRvv+pz5VNbyu9UEDzpMWulZfvpgb/cmDXVulYFQ== - -uuid@^8.3.2: +uuid@^8.3.0, uuid@^8.3.2: version "8.3.2" resolved "https://registry.yarnpkg.com/uuid/-/uuid-8.3.2.tgz#80d5b5ced271bb9af6c445f21a1a04c606cefbe2" integrity sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg== @@ -29402,10 +29205,10 @@ webpack-cli@^3.3.12: v8-compile-cache "^2.1.1" yargs "^13.3.2" -webpack-dev-middleware@^3.7.0, webpack-dev-middleware@^3.7.2: - version "3.7.2" - resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.2.tgz#0019c3db716e3fa5cecbf64f2ab88a74bab331f3" - integrity sha512-1xC42LxbYoqLNAhV6YzTYacicgMZQTqRd27Sim9wn5hJrX3I5nxYy1SxSd4+gjUFsz1dQFj+yEe6zEVmSkeJjw== +webpack-dev-middleware@^3.7.2, webpack-dev-middleware@^3.7.3: + version "3.7.3" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-3.7.3.tgz#0639372b143262e2b84ab95d3b91a7597061c2c5" + integrity sha512-djelc/zGiz9nZj/U7PTBi2ViorGJXEWo/3ltkPbDyxCXhhEXkW0ce99falaok4TPj+AsxLiXJR0EBOb0zh9fKQ== dependencies: memory-fs "^0.4.1" mime "^2.4.4" @@ -29497,7 +29300,7 @@ webpack-virtual-modules@^0.2.2: dependencies: debug "^3.0.0" -webpack@^4.41.5, webpack@^4.44.2: +webpack@4, webpack@^4.41.5: version "4.46.0" resolved "https://registry.yarnpkg.com/webpack/-/webpack-4.46.0.tgz#bf9b4404ea20a073605e0a011d188d77cb6ad542" integrity sha512-6jJuJjg8znb/xRItk7bkT0+Q7AHCYjjFnvKIWQPkNIOyRqoCGvkOs0ipeQzrqz4l5FtN5ZI/ukEHroeX/o1/5Q== @@ -30171,6 +29974,11 @@ yn@3.1.1: resolved "https://registry.yarnpkg.com/yn/-/yn-3.1.1.tgz#1e87401a09d767c1d5eab26a6e4c185182d2eb50" integrity sha512-Ux4ygGWsu2c7isFWe8Yu1YluJmqVhxqK2cLXNQA5AcC3QfbGNpM7fu0Y8b/z16pXLnFxZYvWhd3fhBY9DLmC6Q== +yocto-queue@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b" + integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== + z-schema@~3.18.3: version "3.18.4" resolved "https://registry.yarnpkg.com/z-schema/-/z-schema-3.18.4.tgz#ea8132b279533ee60be2485a02f7e3e42541a9a2" From 595469e44a176a42224107a31136e54f996bdc68 Mon Sep 17 00:00:00 2001 From: spalger Date: Wed, 24 Nov 2021 12:55:43 -0700 Subject: [PATCH 03/46] skip flaky suite (#119258) --- .../test_suites/task_manager/health_route.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/plugin_api_integration/test_suites/task_manager/health_route.ts b/x-pack/test/plugin_api_integration/test_suites/task_manager/health_route.ts index b79583b8fe5d7..abed8ac85f0dd 100644 --- a/x-pack/test/plugin_api_integration/test_suites/task_manager/health_route.ts +++ b/x-pack/test/plugin_api_integration/test_suites/task_manager/health_route.ts @@ -109,7 +109,8 @@ export default function ({ getService }: FtrProviderContext) { const monitoredAggregatedStatsRefreshRate = 5000; - describe('health', () => { + // FLAKY: https://github.com/elastic/kibana/issues/119258 + describe.skip('health', () => { it('should return basic configuration of task manager', async () => { const health = await getHealth(); expect(health.status).to.eql('OK'); From 73dfb433a7f5b724be67e2279339f0a8f8531e7d Mon Sep 17 00:00:00 2001 From: DeDe Morton Date: Wed, 24 Nov 2021 12:03:15 -0800 Subject: [PATCH 04/46] Update link to docs about adding a Fleet Server (#119400) --- src/core/public/doc_links/doc_links_service.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts index 743d7a970551f..ec7802b68e7c5 100644 --- a/src/core/public/doc_links/doc_links_service.ts +++ b/src/core/public/doc_links/doc_links_service.ts @@ -488,7 +488,7 @@ export class DocLinksService { fleet: { guide: `${FLEET_DOCS}index.html`, fleetServer: `${FLEET_DOCS}fleet-server.html`, - fleetServerAddFleetServer: `${FLEET_DOCS}fleet-server.html#add-fleet-server`, + fleetServerAddFleetServer: `${FLEET_DOCS}add-a-fleet-server.html`, settings: `${FLEET_DOCS}fleet-settings.html#fleet-server-hosts-setting`, settingsFleetServerHostSettings: `${FLEET_DOCS}fleet-settings.html#fleet-server-hosts-setting`, settingsFleetServerProxySettings: `${KIBANA_DOCS}fleet-settings-kb.html#fleet-data-visualizer-settings`, From bbcbb3d8e11483ef743034ba5219a68a290a7f2c Mon Sep 17 00:00:00 2001 From: James Rodewig Date: Wed, 24 Nov 2021 15:42:18 -0500 Subject: [PATCH 05/46] [DOCS] Fix `future` typo on TSVB page (#119659) --- docs/user/dashboard/tsvb.asciidoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/user/dashboard/tsvb.asciidoc b/docs/user/dashboard/tsvb.asciidoc index 7efd8425e5611..1c90c28826f6e 100644 --- a/docs/user/dashboard/tsvb.asciidoc +++ b/docs/user/dashboard/tsvb.asciidoc @@ -31,7 +31,7 @@ When you use only {data-sources}, you are able to: * Improve performance -IMPORTANT: Creating *TSVB* visualizations with an {es} index string is deprecated and will be removed in a fytyre release. By default, you create *TSVB* visualizations with only {data-sources}. To use an {es} index string, contact your administrator, or go to <> and set `metrics:allowStringIndices` to `true`. +IMPORTANT: Creating *TSVB* visualizations with an {es} index string is deprecated and will be removed in a future release. By default, you create *TSVB* visualizations with only {data-sources}. To use an {es} index string, contact your administrator, or go to <> and set `metrics:allowStringIndices` to `true`. . On the dashboard, click *All types*, then select *TSVB*. From dbf47c685a9374535c9c9d2fd97157c58d2fd076 Mon Sep 17 00:00:00 2001 From: Nicolas Chaulet Date: Wed, 24 Nov 2021 16:03:53 -0500 Subject: [PATCH 06/46] [Fleet] Add missing package policies for managed preconfigured policies (#119488) --- .../fleet/server/services/agent_policy.ts | 8 +- .../fleet/server/services/package_policy.ts | 19 ++- .../server/services/preconfiguration.test.ts | 140 ++++++++++++++++-- .../fleet/server/services/preconfiguration.ts | 115 +++++++------- 4 files changed, 204 insertions(+), 78 deletions(-) diff --git a/x-pack/plugins/fleet/server/services/agent_policy.ts b/x-pack/plugins/fleet/server/services/agent_policy.ts index bb9360b834b37..69859855d74f0 100644 --- a/x-pack/plugins/fleet/server/services/agent_policy.ts +++ b/x-pack/plugins/fleet/server/services/agent_policy.ts @@ -781,7 +781,8 @@ export async function addPackageToAgentPolicy( defaultOutput: Output, packagePolicyName?: string, packagePolicyDescription?: string, - transformPackagePolicy?: (p: NewPackagePolicy) => NewPackagePolicy + transformPackagePolicy?: (p: NewPackagePolicy) => NewPackagePolicy, + bumpAgentPolicyRevison = false ) { const packageInfo = await getPackageInfo({ savedObjectsClient: soClient, @@ -803,7 +804,10 @@ export async function addPackageToAgentPolicy( : basePackagePolicy; await packagePolicyService.create(soClient, esClient, newPackagePolicy, { - bumpRevision: false, + bumpRevision: bumpAgentPolicyRevison, skipEnsureInstalled: true, + skipUniqueNameVerification: true, + overwrite: true, + force: true, // To add package to managed policy we need the force flag }); } diff --git a/x-pack/plugins/fleet/server/services/package_policy.ts b/x-pack/plugins/fleet/server/services/package_policy.ts index 9e84974211480..535d93cc3eceb 100644 --- a/x-pack/plugins/fleet/server/services/package_policy.ts +++ b/x-pack/plugins/fleet/server/services/package_policy.ts @@ -96,17 +96,22 @@ class PackagePolicyService { bumpRevision?: boolean; force?: boolean; skipEnsureInstalled?: boolean; + skipUniqueNameVerification?: boolean; + overwrite?: boolean; } ): Promise { - const existingPoliciesWithName = await this.list(soClient, { - perPage: 1, - kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.name: "${packagePolicy.name}"`, - }); + if (!options?.skipUniqueNameVerification) { + const existingPoliciesWithName = await this.list(soClient, { + perPage: 1, + kuery: `${PACKAGE_POLICY_SAVED_OBJECT_TYPE}.name: "${packagePolicy.name}"`, + }); - // Check that the name does not exist already - if (existingPoliciesWithName.items.length > 0) { - throw new IngestManagerError('There is already an integration policy with the same name'); + // Check that the name does not exist already + if (existingPoliciesWithName.items.length > 0) { + throw new IngestManagerError('There is already an integration policy with the same name'); + } } + let elasticsearch: PackagePolicy['elasticsearch']; // Add ids to stream const packagePolicyId = options?.id || uuid.v4(); diff --git a/x-pack/plugins/fleet/server/services/preconfiguration.test.ts b/x-pack/plugins/fleet/server/services/preconfiguration.test.ts index 6fefc4631239d..4b87c0957c961 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration.test.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration.test.ts @@ -5,12 +5,14 @@ * 2.0. */ +import uuid from 'uuid'; import { elasticsearchServiceMock, savedObjectsClientMock } from 'src/core/server/mocks'; import { SavedObjectsErrorHelpers } from '../../../../../src/core/server'; import type { InstallResult, + PackagePolicy, PreconfiguredAgentPolicy, PreconfiguredOutput, } from '../../common/types'; @@ -27,11 +29,13 @@ import { cleanPreconfiguredOutputs, } from './preconfiguration'; import { outputService } from './output'; +import { packagePolicyService } from './package_policy'; jest.mock('./agent_policy_update'); jest.mock('./output'); const mockedOutputService = outputService as jest.Mocked; +const mockedPackagePolicyService = packagePolicyService as jest.Mocked; const mockInstalledPackages = new Map(); const mockInstallPackageErrors = new Map(); @@ -57,7 +61,7 @@ function getPutPreconfiguredPackagesMock() { return { saved_objects: [ { - id: `mocked-${id}`, + id, attributes, type: type as string, score: 1, @@ -80,8 +84,9 @@ function getPutPreconfiguredPackagesMock() { soClient.get.mockImplementation(async (type, id) => { const attributes = mockConfiguredPolicies.get(id); if (!attributes) throw SavedObjectsErrorHelpers.createGenericNotFoundError(type, id); + return { - id: `mocked-${id}`, + id, attributes, type: type as string, references: [], @@ -92,7 +97,7 @@ function getPutPreconfiguredPackagesMock() { const { id } = options!; mockConfiguredPolicies.set(id, attributes); return { - id: `mocked-${id}`, + id: id || uuid.v4(), attributes, type, references: [], @@ -163,13 +168,15 @@ jest.mock('./package_policy', () => ({ packagePolicyService: { getByIDs: jest.fn().mockReturnValue([]), listIds: jest.fn().mockReturnValue({ items: [] }), - create(soClient: any, esClient: any, newPackagePolicy: NewPackagePolicy) { - return { - id: 'mocked', - version: 'mocked', - ...newPackagePolicy, - }; - }, + create: jest + .fn() + .mockImplementation((soClient: any, esClient: any, newPackagePolicy: NewPackagePolicy) => { + return { + id: 'mocked', + version: 'mocked', + ...newPackagePolicy, + }; + }), get(soClient: any, id: string) { return { id: 'mocked', @@ -201,6 +208,7 @@ const spyAgentPolicyServicBumpAllAgentPoliciesForOutput = jest.spyOn( describe('policy preconfiguration', () => { beforeEach(() => { + mockedPackagePolicyService.create.mockReset(); mockInstalledPackages.clear(); mockInstallPackageErrors.clear(); mockConfiguredPolicies.clear(); @@ -267,11 +275,116 @@ describe('policy preconfiguration', () => { ); expect(policies.length).toEqual(1); - expect(policies[0].id).toBe('mocked-test-id'); + expect(policies[0].id).toBe('test-id'); expect(packages).toEqual(expect.arrayContaining(['test_package-3.0.0'])); expect(nonFatalErrors.length).toBe(0); }); + it('should not add new package policy to existing non managed policies', async () => { + const soClient = getPutPreconfiguredPackagesMock(); + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + mockedPackagePolicyService.getByIDs.mockResolvedValue([ + { name: 'test_package1' } as PackagePolicy, + ]); + + mockConfiguredPolicies.set('test-id', { + name: 'Test policy', + description: 'Test policy description', + unenroll_timeout: 120, + namespace: 'default', + id: 'test-id', + package_policies: [ + { + name: 'test_package1', + }, + ], + } as PreconfiguredAgentPolicy); + + await ensurePreconfiguredPackagesAndPolicies( + soClient, + esClient, + [ + { + name: 'Test policy', + namespace: 'default', + id: 'test-id', + is_managed: false, + package_policies: [ + { + package: { name: 'test_package' }, + name: 'test_package1', + }, + { + package: { name: 'test_package' }, + name: 'test_package2', + }, + ], + }, + ] as PreconfiguredAgentPolicy[], + [{ name: 'test_package', version: '3.0.0' }], + mockDefaultOutput + ); + + expect(mockedPackagePolicyService.create).not.toBeCalled(); + }); + + it('should add new package policy to existing managed policies', async () => { + const soClient = getPutPreconfiguredPackagesMock(); + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + mockedPackagePolicyService.getByIDs.mockResolvedValue([ + { name: 'test_package1' } as PackagePolicy, + ]); + + mockConfiguredPolicies.set('test-id', { + name: 'Test policy', + description: 'Test policy description', + unenroll_timeout: 120, + namespace: 'default', + id: 'test-id', + package_policies: [ + { + name: 'test_package1', + }, + ], + is_managed: true, + } as PreconfiguredAgentPolicy); + + await ensurePreconfiguredPackagesAndPolicies( + soClient, + esClient, + [ + { + name: 'Test policy', + namespace: 'default', + id: 'test-id', + is_managed: true, + package_policies: [ + { + package: { name: 'test_package' }, + name: 'test_package1', + }, + { + package: { name: 'test_package' }, + name: 'test_package2', + }, + ], + }, + ] as PreconfiguredAgentPolicy[], + [{ name: 'test_package', version: '3.0.0' }], + mockDefaultOutput + ); + + expect(mockedPackagePolicyService.create).toBeCalledTimes(1); + expect(mockedPackagePolicyService.create).toBeCalledWith( + expect.anything(), // so client + expect.anything(), // es client + expect.objectContaining({ + name: 'test_package2', + }), + expect.anything() // options + ); + }); + it('should throw an error when trying to install duplicate packages', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; @@ -352,6 +465,7 @@ describe('policy preconfiguration', () => { '[Test policy] could not be added. [test_package] is not installed, add [test_package] to [xpack.fleet.packages] or remove it from [Test package].' ); }); + it('should not attempt to recreate or modify an agent policy if its ID is unchanged', async () => { const soClient = getPutPreconfiguredPackagesMock(); const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; @@ -373,7 +487,7 @@ describe('policy preconfiguration', () => { ); expect(policiesA.length).toEqual(1); - expect(policiesA[0].id).toBe('mocked-test-id'); + expect(policiesA[0].id).toBe('test-id'); expect(nonFatalErrorsA.length).toBe(0); const { policies: policiesB, nonFatalErrors: nonFatalErrorsB } = @@ -398,7 +512,7 @@ describe('policy preconfiguration', () => { ); expect(policiesB.length).toEqual(1); - expect(policiesB[0].id).toBe('mocked-test-id'); + expect(policiesB[0].id).toBe('test-id'); expect(policiesB[0].updated_at).toEqual(policiesA[0].updated_at); expect(nonFatalErrorsB.length).toBe(0); }); diff --git a/x-pack/plugins/fleet/server/services/preconfiguration.ts b/x-pack/plugins/fleet/server/services/preconfiguration.ts index b16eae266d28c..8b906b68556a4 100644 --- a/x-pack/plugins/fleet/server/services/preconfiguration.ts +++ b/x-pack/plugins/fleet/server/services/preconfiguration.ts @@ -19,12 +19,9 @@ import type { PreconfiguredPackage, PreconfigurationError, PreconfiguredOutput, + PackagePolicy, } from '../../common'; -import { - AGENT_POLICY_SAVED_OBJECT_TYPE, - SO_SEARCH_LIMIT, - normalizeHostsForAgents, -} from '../../common'; +import { SO_SEARCH_LIMIT, normalizeHostsForAgents } from '../../common'; import { PRECONFIGURATION_DELETION_RECORD_SAVED_OBJECT_TYPE, PRECONFIGURATION_LATEST_KEYWORD, @@ -284,65 +281,69 @@ export async function ensurePreconfiguredPackagesAndPolicies( } fulfilledPolicies.push(policyResult.value); const { created, policy, shouldAddIsManagedFlag } = policyResult.value; - if (created) { - try { - const preconfiguredAgentPolicy = policies[i]; - const { package_policies: packagePolicies } = preconfiguredAgentPolicy; - - const installedPackagePolicies = await Promise.all( - packagePolicies.map(async ({ package: pkg, name, ...newPackagePolicy }) => { - const installedPackage = await getInstallation({ - savedObjectsClient: soClient, - pkgName: pkg.name, - }); - if (!installedPackage) { - const rejectedPackage = rejectedPackages.find((rp) => rp.package?.name === pkg.name); - - if (rejectedPackage) { - throw new Error( - i18n.translate('xpack.fleet.preconfiguration.packageRejectedError', { - defaultMessage: `[{agentPolicyName}] could not be added. [{pkgName}] could not be installed due to error: [{errorMessage}]`, - values: { - agentPolicyName: preconfiguredAgentPolicy.name, - pkgName: pkg.name, - errorMessage: rejectedPackage.error.toString(), - }, - }) - ); - } + if (created || policies[i].is_managed) { + const preconfiguredAgentPolicy = policies[i]; + const { package_policies: packagePolicies } = preconfiguredAgentPolicy; + const agentPolicyWithPackagePolicies = await agentPolicyService.get( + soClient, + policy!.id, + true + ); + const installedPackagePolicies = await Promise.all( + packagePolicies.map(async ({ package: pkg, name, ...newPackagePolicy }) => { + const installedPackage = await getInstallation({ + savedObjectsClient: soClient, + pkgName: pkg.name, + }); + if (!installedPackage) { + const rejectedPackage = rejectedPackages.find((rp) => rp.package?.name === pkg.name); + + if (rejectedPackage) { throw new Error( - i18n.translate('xpack.fleet.preconfiguration.packageMissingError', { - defaultMessage: - '[{agentPolicyName}] could not be added. [{pkgName}] is not installed, add [{pkgName}] to [{packagesConfigValue}] or remove it from [{packagePolicyName}].', + i18n.translate('xpack.fleet.preconfiguration.packageRejectedError', { + defaultMessage: `[{agentPolicyName}] could not be added. [{pkgName}] could not be installed due to error: [{errorMessage}]`, values: { agentPolicyName: preconfiguredAgentPolicy.name, - packagePolicyName: name, pkgName: pkg.name, - packagesConfigValue: 'xpack.fleet.packages', + errorMessage: rejectedPackage.error.toString(), }, }) ); } - return { name, installedPackage, ...newPackagePolicy }; - }) - ); - await addPreconfiguredPolicyPackages( - soClient, - esClient, - policy!, - installedPackagePolicies!, - defaultOutput + + throw new Error( + i18n.translate('xpack.fleet.preconfiguration.packageMissingError', { + defaultMessage: + '[{agentPolicyName}] could not be added. [{pkgName}] is not installed, add [{pkgName}] to [{packagesConfigValue}] or remove it from [{packagePolicyName}].', + values: { + agentPolicyName: preconfiguredAgentPolicy.name, + packagePolicyName: name, + pkgName: pkg.name, + packagesConfigValue: 'xpack.fleet.packages', + }, + }) + ); + } + return { name, installedPackage, ...newPackagePolicy }; + }) + ); + + const packagePoliciesToAdd = installedPackagePolicies.filter((installablePackagePolicy) => { + return !(agentPolicyWithPackagePolicies?.package_policies as PackagePolicy[]).some( + (packagePolicy) => packagePolicy.name === installablePackagePolicy.name ); - // If ann error happens while adding a package to the policy we will delete the policy so the setup can be retried later - } catch (err) { - await soClient - .delete(AGENT_POLICY_SAVED_OBJECT_TYPE, policy!.id) - // swallow error - .catch((deleteErr) => logger.error(deleteErr)); - - throw err; - } + }); + + await addPreconfiguredPolicyPackages( + soClient, + esClient, + policy!, + packagePoliciesToAdd!, + defaultOutput, + !created + ); + // Add the is_managed flag after configuring package policies to avoid errors if (shouldAddIsManagedFlag) { await agentPolicyService.update(soClient, esClient, policy!.id, { is_managed: true }); @@ -408,7 +409,8 @@ async function addPreconfiguredPolicyPackages( inputs?: InputsOverride[]; } >, - defaultOutput: Output + defaultOutput: Output, + bumpAgentPolicyRevison = false ) { // Add packages synchronously to avoid overwriting for (const { installedPackage, name, description, inputs } of installedPackagePolicies) { @@ -426,7 +428,8 @@ async function addPreconfiguredPolicyPackages( defaultOutput, name, description, - (policy) => overridePackageInputs(policy, packageInfo, inputs) + (policy) => overridePackageInputs(policy, packageInfo, inputs), + bumpAgentPolicyRevison ); } } From 9189066b0ccbf0b7b8cdc45093049de43dc8c897 Mon Sep 17 00:00:00 2001 From: "Christiane (Tina) Heiligers" Date: Wed, 24 Nov 2021 14:42:28 -0700 Subject: [PATCH 07/46] [docs-logging]: move developer/architecture docs to user docs (#119125) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- docs/CHANGELOG.asciidoc | 2 +- .../logging-configuration-migration.asciidoc | 80 -- .../core/logging-service.asciidoc | 476 ------------ docs/developer/architecture/index.asciidoc | 2 - docs/migration/migrate_8_0.asciidoc | 8 +- docs/settings/logging-settings.asciidoc | 220 ++---- docs/setup/configuring-logging.asciidoc | 697 ++++++++++++++++++ docs/setup/settings.asciidoc | 62 +- docs/setup/upgrade.asciidoc | 4 + .../logging-configuration-changes.asciidoc | 45 ++ docs/user/setup.asciidoc | 2 + 11 files changed, 853 insertions(+), 745 deletions(-) delete mode 100644 docs/developer/architecture/core/logging-configuration-migration.asciidoc create mode 100644 docs/setup/configuring-logging.asciidoc create mode 100644 docs/setup/upgrade/logging-configuration-changes.asciidoc diff --git a/docs/CHANGELOG.asciidoc b/docs/CHANGELOG.asciidoc index 31cdcbca9d1f9..b63e6fbc94117 100644 --- a/docs/CHANGELOG.asciidoc +++ b/docs/CHANGELOG.asciidoc @@ -404,7 +404,7 @@ Use spaces, cross-cluster replication, or cross-cluster search. To migrate to << The logging configuration and log output format has changed. For more information, refer to {kibana-pull}112305[#112305]. *Impact* + -Use the new <>. +Use the new <>. ==== [float] diff --git a/docs/developer/architecture/core/logging-configuration-migration.asciidoc b/docs/developer/architecture/core/logging-configuration-migration.asciidoc deleted file mode 100644 index db02b4d4e507f..0000000000000 --- a/docs/developer/architecture/core/logging-configuration-migration.asciidoc +++ /dev/null @@ -1,80 +0,0 @@ -[[logging-configuration-migration]] -== Logging configuration migration - -Compatibility with the legacy logging system is assured until the end of the `v7` version. -All log messages handled by `root` context are forwarded to the legacy logging service. If you re-write -root appenders, make sure that it contains `default` appender to provide backward compatibility. - -NOTE: When you switch to the new logging configuration, you will start seeing duplicate log entries in both formats. -These will be removed when the `default` appender is no longer required. If you define an appender for a logger, -the log messages aren't handled by the `root` logger anymore and are not forwarded to the legacy logging service. - -[[logging-pattern-format-old-and-new-example]] -[options="header"] -|=== - -| Parameter | Platform log record in **pattern** format | Legacy Platform log record **text** format - -| @timestamp | ISO8601_TZ `2012-01-31T23:33:22.011-05:00` | Absolute `23:33:22.011` - -| logger | `parent.child` | `['parent', 'child']` - -| level | `DEBUG` | `['debug']` - -| meta | stringified JSON object `{"to": "v8"}`| N/A - -| pid | can be configured as `%pid` | N/A - -|=== - -[[logging-json-format-old-and-new-example]] -[options="header"] -|=== - -| Parameter | Platform log record in **json** format | Legacy Platform log record **json** format - -| @timestamp | ISO8601_TZ `2012-01-31T23:33:22.011-05:00` | ISO8601 `2012-01-31T23:33:22.011Z` - -| logger | `log.logger: parent.child` | `tags: ['parent', 'child']` - -| level | `log.level: DEBUG` | `tags: ['debug']` - -| meta | merged in log record `{... "to": "v8"}` | merged in log record `{... "to": "v8"}` - -| pid | `process.pid: 12345` | `pid: 12345` - -| type | N/A | `type: log` - -| error | `{ message, name, stack }` | `{ message, name, stack, code, signal }` - -|=== - -[[logging-cli-migration]] -=== Logging configuration via CLI - -As is the case for any of Kibana's config settings, you can specify your logging configuration via the CLI. For convenience, the `--verbose` and `--silent` flags exist as shortcuts and will continue to be supported beyond v7. - -If you wish to override these flags, you can always do so by passing your preferred logging configuration directly to the CLI. For example, with the following configuration: - -[source,yaml] ----- -logging: - appenders: - custom: - type: console - layout: - type: pattern - pattern: "[%date][%level] %message" ----- - -you can override the flags with: - -[options="header"] -|=== - -| legacy logging | {kib} Platform logging | cli shortcuts - -|--verbose| --logging.root.level=debug --logging.root.appenders[0]=default --logging.root.appenders[1]=custom | --verbose - -|--silent| --logging.root.level=off | --silent -|=== diff --git a/docs/developer/architecture/core/logging-service.asciidoc b/docs/developer/architecture/core/logging-service.asciidoc index 7dc2a4ca1f4ce..79d8c6d197e10 100644 --- a/docs/developer/architecture/core/logging-service.asciidoc +++ b/docs/developer/architecture/core/logging-service.asciidoc @@ -25,482 +25,6 @@ export class MyPlugin implements Plugin { } } ---- - -The way logging works in {kib} is inspired by the `log4j 2` logging framework used by {ref-bare}/current/logging.html[Elasticsearch]. -The main idea is to have consistent logging behavior (configuration, log format etc.) across the entire Elastic Stack where possible. - -=== Loggers, Appenders and Layouts - -The {kib} logging system has three main components: _loggers_, _appenders_ and _layouts_. These components allow us to log -messages according to message type and level, to control how these messages are formatted and where the final logs -will be displayed or stored. - -__Loggers__ define what logging settings should be applied to a particular logger. - -__<>__ define where log messages are displayed (eg. stdout or console) and stored (eg. file on the disk). - -__<>__ define how log messages are formatted and what type of information they include. - -[[log-level]] -=== Log level - -Currently we support the following log levels: _all_, _fatal_, _error_, _warn_, _info_, _debug_, _trace_, _off_. - -Levels are ordered, so _all_ > _fatal_ > _error_ > _warn_ > _info_ > _debug_ > _trace_ > _off_. - -A log record is being logged by the logger if its level is higher than or equal to the level of its logger. Otherwise, -the log record is ignored. - -The _all_ and _off_ levels can be used only in configuration and are just handy shortcuts that allow you to log every -log record or disable logging entirely or for a specific logger. These levels are also configurable as <>. - -[[logging-layouts]] -=== Layouts - -Every appender should know exactly how to format log messages before they are written to the console or file on the disk. -This behavior is controlled by the layouts and configured through `appender.layout` configuration property for every -custom appender. Currently we don't define any default layout for the -custom appenders, so one should always make the choice explicitly. - -There are two types of layout supported at the moment: <> and <>. - -[[pattern-layout]] -==== Pattern layout - -With `pattern` layout it's possible to define a string pattern with special placeholders `%conversion_pattern` that will be replaced with data from the actual log message. By default the following pattern is used: `[%date][%level][%logger] %message`. - -NOTE: The `pattern` layout uses a sub-set of https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout[log4j 2 pattern syntax] and **doesn't implement** all `log4j 2` capabilities. - -The conversions that are provided out of the box are: - -**level** -Outputs the <> of the logging event. -Example of `%level` output: `TRACE`, `DEBUG`, `INFO`. - -**logger** -Outputs the name of the logger that published the logging event. -Example of `%logger` output: `server`, `server.http`, `server.http.kibana`. - -**message** -Outputs the application supplied message associated with the logging event. - -**meta** -Outputs the entries of `meta` object data in **json** format, if one is present in the event. -Example of `%meta` output: -[source,bash] ----- -// Meta{from: 'v7', to: 'v8'} -'{"from":"v7","to":"v8"}' -// Meta empty object -'{}' -// no Meta provided -'' ----- - -[[date-format]] -**date** -Outputs the date of the logging event. The date conversion specifier may be followed by a set of braces containing a name of predefined date format and canonical timezone name. -Timezone name is expected to be one from https://en.wikipedia.org/wiki/List_of_tz_database_time_zones[TZ database name]. -Timezone defaults to the host timezone when not explicitly specified. -Example of `%date` output: - -[[date-conversion-pattern-examples]] -[options="header"] -|=== - -| Conversion pattern | Example - -| `%date` -| `2012-02-01T14:30:22.011Z` uses `ISO8601` format by default - -| `%date{ISO8601}` -| `2012-02-01T14:30:22.011Z` - -| `%date{ISO8601_TZ}` -| `2012-02-01T09:30:22.011-05:00` `ISO8601` with timezone - -| `%date{ISO8601_TZ}{America/Los_Angeles}` -| `2012-02-01T06:30:22.011-08:00` - -| `%date{ABSOLUTE}` -| `09:30:22.011` - -| `%date{ABSOLUTE}{America/Los_Angeles}` -| `06:30:22.011` - -| `%date{UNIX}` -| `1328106622` - -| `%date{UNIX_MILLIS}` -| `1328106622011` - -|=== - -**pid** -Outputs the process ID. - -The pattern layout also offers a `highlight` option that allows you to highlight -some parts of the log message with different colors. Highlighting is quite handy if log messages are forwarded -to a terminal with color support. - -[[json-layout]] -==== JSON layout -With `json` layout log messages will be formatted as JSON strings in https://www.elastic.co/guide/en/ecs/current/ecs-reference.html[ECS format] that includes a timestamp, log level, logger, message text and any other metadata that may be associated with the log message itself. - -[[logging-appenders]] -=== Appenders - -[[rolling-file-appender]] -==== Rolling File Appender - -Similar to Log4j's `RollingFileAppender`, this appender will log into a file, and rotate it following a rolling -strategy when the configured policy triggers. - -===== Triggering Policies - -The triggering policy determines when a rollover should occur. - -There are currently two policies supported: `size-limit` and `time-interval`. - -[[size-limit-triggering-policy]] -**SizeLimitTriggeringPolicy** - -This policy will rotate the file when it reaches a predetermined size. - -[source,yaml] ----- -logging: - appenders: - rolling-file: - type: rolling-file - fileName: /var/logs/kibana.log - policy: - type: size-limit - size: 50mb - strategy: - //... - layout: - type: pattern ----- - -The options are: - -- `size` - -The maximum size the log file should reach before a rollover should be performed. The default value is `100mb` - -[[time-interval-triggering-policy]] -**TimeIntervalTriggeringPolicy** - -This policy will rotate the file every given interval of time. - -[source,yaml] ----- -logging: - appenders: - rolling-file: - type: rolling-file - fileName: /var/logs/kibana.log - policy: - type: time-interval - interval: 10s - modulate: true - strategy: - //... - layout: - type: pattern ----- - -The options are: - -- `interval` - -How often a rollover should occur. The default value is `24h` - -- `modulate` - -Whether the interval should be adjusted to cause the next rollover to occur on the interval boundary. - -For example, if modulate is true and the interval is `4h`, if the current hour is 3 am then the first rollover will occur at 4 am -and then next ones will occur at 8 am, noon, 4pm, etc. The default value is `true`. - -===== Rolling strategies - -The rolling strategy determines how the rollover should occur: both the naming of the rolled files, -and their retention policy. - -There is currently one strategy supported: `numeric`. - -**NumericRollingStrategy** - -This strategy will suffix the file with a given pattern when rolling, -and will retains a fixed amount of rolled files. - -[source,yaml] ----- -logging: - appenders: - rolling-file: - type: rolling-file - fileName: /var/logs/kibana.log - policy: - // ... - strategy: - type: numeric - pattern: '-%i' - max: 2 - layout: - type: pattern ----- - -For example, with this configuration: - -- During the first rollover kibana.log is renamed to kibana-1.log. A new kibana.log file is created and starts - being written to. -- During the second rollover kibana-1.log is renamed to kibana-2.log and kibana.log is renamed to kibana-1.log. - A new kibana.log file is created and starts being written to. -- During the third and subsequent rollovers, kibana-2.log is deleted, kibana-1.log is renamed to kibana-2.log and - kibana.log is renamed to kibana-1.log. A new kibana.log file is created and starts being written to. - -The options are: - -- `pattern` - -The suffix to append to the file path when rolling. Must include `%i`, as this is the value -that will be converted to the file index. - -For example, with `fileName: /var/logs/kibana.log` and `pattern: '-%i'`, the rolling files created -will be `/var/logs/kibana-1.log`, `/var/logs/kibana-2.log`, and so on. The default value is `-%i` - -- `max` - -The maximum number of files to keep. Once this number is reached, oldest files will be deleted. The default value is `7` - -==== Rewrite Appender - -WARNING: This appender is currently considered experimental and is not intended -for public consumption. The API is subject to change at any time. - -Similar to log4j's `RewriteAppender`, this appender serves as a sort of middleware, -modifying the provided log events before passing them along to another -appender. - -[source,yaml] ----- -logging: - appenders: - my-rewrite-appender: - type: rewrite - appenders: [console, file] # name of "destination" appender(s) - policy: - # ... ----- - -The most common use case for the `RewriteAppender` is when you want to -filter or censor sensitive data that may be contained in a log entry. -In fact, with a default configuration, {kib} will automatically redact -any `authorization`, `cookie`, or `set-cookie` headers when logging http -requests & responses. - -To configure additional rewrite rules, you'll need to specify a <>. - -[[rewrite-policies]] -===== Rewrite Policies - -Rewrite policies exist to indicate which parts of a log record can be -modified within the rewrite appender. - -**Meta** - -The `meta` rewrite policy can read and modify any data contained in the -`LogMeta` before passing it along to a destination appender. - -Meta policies must specify one of three modes, which indicate which action -to perform on the configured properties: -- `update` updates an existing property at the provided `path`. -- `remove` removes an existing property at the provided `path`. - -The `properties` are listed as a `path` and `value` pair, where `path` is -the dot-delimited path to the target property in the `LogMeta` object, and -`value` is the value to add or update in that target property. When using -the `remove` mode, a `value` is not necessary. - -Here's an example of how you would replace any `cookie` header values with `[REDACTED]`: - -[source,yaml] ----- -logging: - appenders: - my-rewrite-appender: - type: rewrite - appenders: [console] - policy: - type: meta # indicates that we want to rewrite the LogMeta - mode: update # will update an existing property only - properties: - - path: "http.request.headers.cookie" # path to property - value: "[REDACTED]" # value to replace at path ----- - -Rewrite appenders can even be passed to other rewrite appenders to apply -multiple filter policies/modes, as long as it doesn't create a circular -reference. Each rewrite appender is applied sequentially (one after the other). - -[source,yaml] ----- -logging: - appenders: - remove-request-headers: - type: rewrite - appenders: [censor-response-headers] # redirect to the next rewrite appender - policy: - type: meta - mode: remove - properties: - - path: "http.request.headers" # remove all request headers - censor-response-headers: - type: rewrite - appenders: [console] # output to console - policy: - type: meta - mode: update - properties: - - path: "http.response.headers.set-cookie" - value: "[REDACTED]" ----- - -===== Complete Example For Rewrite Appender - -[source,yaml] ----- -logging: - appenders: - custom_console: - type: console - layout: - type: pattern - highlight: true - pattern: "[%date][%level][%logger] %message %meta" - file: - type: file - fileName: ./kibana.log - layout: - type: json - censor: - type: rewrite - appenders: [custom_console, file] - policy: - type: meta - mode: update - properties: - - path: "http.request.headers.cookie" - value: "[REDACTED]" - loggers: - - name: http.server.response - appenders: [censor] # pass these logs to our rewrite appender - level: debug ----- - -[[logger-hierarchy]] -=== Logger hierarchy - -Every logger has a unique name that follows a hierarchical naming rule. The logger is considered to be an -ancestor of another logger if its name followed by a `.` is a prefix of the descendant logger. For example, a logger -named `a.b` is an ancestor of logger `a.b.c`. All top-level loggers are descendants of a special `root` logger at the top of the logger hierarchy. The `root` logger always exists and -fully configured. - -You can configure _<>_ and _appenders_ for a specific logger. If a logger only has a _log level_ configured, then the _appenders_ configuration applied to the logger is inherited from the ancestor logger. - -NOTE: In the current implementation we __don't support__ so called _appender additivity_ when log messages are forwarded to _every_ distinct appender within the -ancestor chain including `root`. That means that log messages are only forwarded to appenders that are configured for a particular logger. If a logger doesn't have any appenders configured, the configuration of that particular logger will be inherited from its closest ancestor. - -[[dedicated-loggers]] -==== Dedicated loggers - -**Root** - -The `root` logger has a dedicated configuration node since this logger is special and should always exist. By default `root` is configured with `info` level and `default` appender that is also always available. This is the configuration that all custom loggers will use unless they're re-configured explicitly. - -For example to see _all_ log messages that fall back on the `root` logger configuration, just add one line to the configuration: - -[source,yaml] ----- -logging.root.level: all ----- - -Or disable logging entirely with `off`: - -[source,yaml] ----- -logging.root.level: off ----- - -**Metrics Logs** - -The `metrics.ops` logger is configured with `debug` level and will automatically output sample system and process information at a regular interval. -The metrics that are logged are a subset of the data collected and are formatted in the log message as follows: - -[options="header"] -|=== - -| Ops formatted log property | Location in metrics service | Log units - -| memory | process.memory.heap.used_in_bytes | http://numeraljs.com/#format[depends on the value], typically MB or GB - -| uptime | process.uptime_in_millis | HH:mm:ss - -| load | os.load | [ "load for the last 1 min" "load for the last 5 min" "load for the last 15 min"] - -| delay | process.event_loop_delay | ms -|=== - -The log interval is the same as the interval at which system and process information is refreshed and is configurable under `ops.interval`: - -[source,yaml] ----- -ops.interval: 5000 ----- - -The minimum interval is 100ms and defaults to 5000ms. - -[[request-response-logger]] -**Request and Response Logs** - -The `http.server.response` logger is configured with `debug` level and will automatically output -data about http requests and responses occurring on the {kib} server. -The message contains some high-level information, and the corresponding log meta contains the following: - -[options="header"] -|=== - -| Meta property | Description | Format - -| client.ip | IP address of the requesting client | ip - -| http.request.method | http verb for the request (uppercase) | string - -| http.request.mime_type | (optional) mime as specified in the headers | string - -| http.request.referrer | (optional) referrer | string - -| http.request.headers | request headers | object - -| http.response.body.bytes | (optional) Calculated response payload size in bytes | number - -| http.response.status_code | status code returned | number - -| http.response.headers | response headers | object - -| http.response.responseTime | (optional) Calculated response time in ms | number - -| url.path | request path | string - -| url.query | (optional) request query string | string - -| user_agent.original | raw user-agent string provided in request headers | string - -|=== - === Usage Usage is very straightforward, one should just get a logger for a specific context and use it to log messages with diff --git a/docs/developer/architecture/index.asciidoc b/docs/developer/architecture/index.asciidoc index 90a0972d65f2f..774292f513f03 100644 --- a/docs/developer/architecture/index.asciidoc +++ b/docs/developer/architecture/index.asciidoc @@ -40,8 +40,6 @@ include::core/http-service.asciidoc[leveloffset=+1] include::core/logging-service.asciidoc[leveloffset=+1] -include::core/logging-configuration-migration.asciidoc[leveloffset=+1] - include::core/saved-objects-service.asciidoc[leveloffset=+1] include::core/uisettings-service.asciidoc[leveloffset=+1] diff --git a/docs/migration/migrate_8_0.asciidoc b/docs/migration/migrate_8_0.asciidoc index f5f8a95ad24de..59dd36a4fa5ef 100644 --- a/docs/migration/migrate_8_0.asciidoc +++ b/docs/migration/migrate_8_0.asciidoc @@ -65,7 +65,7 @@ If you are currently using one of these settings in your Kibana config, please r ==== Default logging timezone is now the system's timezone *Details:* In prior releases the timezone used in logs defaulted to UTC. We now use the host machine's timezone by default. -*Impact:* To restore the previous behavior, in kibana.yml use the pattern layout, with a {kibana-ref}/logging-service.html#date-format[date modifier]: +*Impact:* To restore the previous behavior, in kibana.yml use the pattern layout, with a date modifier: [source,yaml] ------------------- logging: @@ -100,7 +100,7 @@ See https://github.com/elastic/kibana/pull/87939 for more details. [float] ==== Logging destination is specified by the appender -*Details:* Previously log destination would be `stdout` and could be changed to `file` using `logging.dest`. With the new logging configuration, you can specify the destination using {kibana-ref}/logging-service.html#logging-appenders[appenders]. +*Details:* Previously log destination would be `stdout` and could be changed to `file` using `logging.dest`. With the new logging configuration, you can specify the destination using appenders. *Impact:* To restore the previous behavior and log records to *stdout*, in `kibana.yml` use an appender with `type: console`. [source,yaml] @@ -131,7 +131,7 @@ logging: [float] ==== Set log verbosity with root -*Details:* Previously logging output would be specified by `logging.silent` (none), `logging.quiet` (error messages only) and `logging.verbose` (all). With the new logging configuration, set the minimum required {kibana-ref}/logging-service.html#log-level[log level]. +*Details:* Previously logging output would be specified by `logging.silent` (none), `logging.quiet` (error messages only) and `logging.verbose` (all). With the new logging configuration, set the minimum required log level. *Impact:* To restore the previous behavior, in `kibana.yml` specify `logging.root.level`: [source,yaml] @@ -188,7 +188,7 @@ logging: ==== Configure log rotation with the rolling-file appender *Details:* Previously log rotation would be enabled when `logging.rotate.enabled` was true. -*Impact:* To restore the previous behavior, in `kibana.yml` use the {kibana-ref}/logging-service.html#rolling-file-appender[`rolling-file`] appender. +*Impact:* To restore the previous behavior, in `kibana.yml` use the `rolling-file` appender. [source,yaml] ------------------- diff --git a/docs/settings/logging-settings.asciidoc b/docs/settings/logging-settings.asciidoc index f88ea665c0213..cb8237c5aa384 100644 --- a/docs/settings/logging-settings.asciidoc +++ b/docs/settings/logging-settings.asciidoc @@ -4,172 +4,86 @@ Logging settings ++++ -{kib} relies on three high-level entities to set the logging service: appenders, loggers, and root. +You do not need to configure any additional settings to use the logging features in {kib}. Logging is enabled by default and will log at `info` level using the `pattern` layout, which outputs logs to `stdout`. + +However, if you are planning to ingest your logs using Elasticsearch or another tool, we recommend using the `json` layout, which produces logs in ECS format. In general, `pattern` layout is recommended when raw logs will be read by a human, and `json` layout when logs will be read by a machine. + +NOTE: The logging configuration is validated against the predefined schema and if there are any issues with it, {kib} will fail to start with the detailed error message. + +{kib} relies on three high-level entities to set the logging service: appenders, loggers, and root. These can be configured in the `logging` namespace in `kibana.yml`. - Appenders define where log messages are displayed (stdout or console) and their layout (`pattern` or `json`). They also allow you to specify if you want the logs stored and, if so, where (file on the disk). - Loggers define what logging settings, such as the level of verbosity and the appenders, to apply to a particular context. Each log entry context provides information about the service or plugin that emits it and any of its sub-parts, for example, `metrics.ops` or `elasticsearch.query`. - Root is a logger that applies to all the log entries in {kib}. -Refer to the <> for common configuration use cases. To learn more about possible configuration values, go to {kibana-ref}/logging-service.html[{kib}'s Logging service]. - -[[log-settings-examples]] -==== Examples -Here are some configuration examples for the most common logging use cases: - -[[log-to-file-example]] -===== Log to a file - -Log the default log format to a file instead of to stdout (the default). - -[source,yaml] ----- -logging: - appenders: - file: - type: file - fileName: /var/log/kibana.log - layout: - type: pattern - root: - appenders: [file] ----- - -[[log-in-json-ECS-example]] -===== Log in JSON format - -Log the default log format to JSON layout instead of pattern (the default). -With `json` layout, log messages will be formatted as JSON strings in https://www.elastic.co/guide/en/ecs/current/ecs-reference.html[ECS format] that includes a timestamp, log level, logger, message text and any other metadata that may be associated with the log message itself. - -[source,yaml] ----- -logging: - appenders: - json-layout: - type: console - layout: - type: json - root: - appenders: [json-layout] ----- - -[[log-with-meta-to-stdout]] -===== Log with meta to stdout - -Include `%meta` in your pattern layout: - -[source,yaml] ----- -logging: - appenders: - console-meta: - type: console - layout: - type: pattern - pattern: "[%date] [%level] [%logger] [%meta] %message" - root: - appenders: [console-meta] ----- - -[[log-elasticsearch-queries]] -===== Log {es} queries - -[source,yaml] --- -logging: - appenders: - console_appender: - type: console - layout: - type: pattern - highlight: true - root: - appenders: [console_appender] - level: warn - loggers: - - name: elasticsearch.query - level: debug --- - -[[change-overall-log-level]] -===== Change overall log level - -[source,yaml] ----- -logging: - root: - level: debug ----- - -[[customize-specific-log-records]] -===== Customize specific log records -Here is a detailed configuration example that can be used to configure _loggers_, _appenders_ and _layouts_: - -[source,yaml] ----- -logging: - appenders: - console: - type: console - layout: - type: pattern - highlight: true - file: - type: file - fileName: /var/log/kibana.log - custom: - type: console - layout: - type: pattern - pattern: "[%date][%level] %message" - json-file-appender: - type: file - fileName: /var/log/kibana-json.log - layout: - type: json - - root: - appenders: [console, file] - level: error - - loggers: - - name: plugins - appenders: [custom] - level: warn - - name: plugins.myPlugin - level: info - - name: server - level: fatal - - name: optimize - appenders: [console] - - name: telemetry - appenders: [json-file-appender] - level: all - - name: metrics.ops - appenders: [console] - level: debug ----- - -Here is what we get with the config above: -[options="header"] +The following table serves as a quick reference for different logging configuration keys. Note that these are not stand-alone settings and may require additional logging configuration. See the <> guide and complete <> for common configuration use cases. + +[cols="2*<"] |=== +| `logging.appenders[].` +| Unique appender identifier. -| Context name | Appenders | Level +| `logging.appenders[].console:` +| Appender to use for logging records to *stdout*. By default, uses the `[%date][%level][%logger] %message` **pattern** layout. To use a **json**, set the <>. -| root | console, file | error +| `logging.appenders[].file:` +| Allows you to specify a fileName to write log records to disk. To write <>, add the file appender to `root.appenders`. If configured, you also need to specify <>. -| plugins | custom | warn +| `logging.appenders[].rolling-file:` +| Similar to Log4j's `RollingFileAppender`, this appender will log to a file and rotate if following a rolling strategy when the configured policy triggers. There are currently two policies supported: `size-limit` and `time-interval`. -| plugins.myPlugin | custom | info +| `logging.appenders[]..type` +| The appender type determines where the log messages are sent. Options are `console`, `file`, `rewrite`, `rolling-file`. Required. -| server | console, file | fatal +| `logging.appenders[]..fileName` +| Determines the filepath where the log messages are written to for file and rolling-file appender types. Required for appenders that write to file. -| optimize | console | error +| `logging.appenders[]..policy.type` +| Specify the triggering policy for when a rollover should occur for the `rolling-file` type appender. -| telemetry | json-file-appender | all +| `logging.appenders[]..policy.interval` +| Specify the time interval for rotating a log file for a `time-interval` type `rolling-file` appender. *Default 24h* -| metrics.ops | console | debug -|=== +| `logging.appenders[]..policy.size` +| Specify the size limit at which the policy should trigger a rollover for a `size-limit` type `rolling-file` appender. *Default 100mb*. + +| `logging.appenders[]..policy.interval` +| Specify the time interval at which the policy should trigger a rollover for a time-interval type `rolling-file` appender. + +| `logging.appenders[]..policy.modulate` +| Whether the interval should be adjusted to cause the next rollover to occur on the interval boundary. Boolean. Default `true`. + +| `logging.appenders[]..strategy.type` +| Rolling file strategy type. Only `numeric` is currently supported. + +| `logging.appenders[]..strategy.pattern` +| The suffix to append to the file path when rolling. Must include `%i`. -NOTE: If you modify `root.appenders`, make sure to include `default`. +| `logging.appenders[]..strategy.max` +| The maximum number of files to keep. Optional. Default is `7`. -// For more details about logging configuration, refer to the logging system documentation (update to include a link). +| `logging.appenders[]..layout.type` +| Determines how the log messages are displayed. Options are `pattern`, which provides human-readable output, or `json`, which provides ECS-compliant output. Required. + +| `logging.appenders[]..layout.highlight` +| Optional boolean to highlight log messages in color. Applies to `pattern` layout only. Default is `false`. + +| `logging.appenders[]..layout.pattern` +| Optional <> for placeholders that will be replaced with data from the actual log message. Applicable to pattern type layout only. + +| `logging.root.appenders[]` +| List of specific appenders to apply to `root`. Defaults to `console` with `pattern` layout. + +| `logging.root.level` +| Specify default verbosity for all log messages to fall back to if not specifically configured at the individual logger level. Options are `all`, `fatal`, `error`, `warn`, `info`, `debug`, `trace`, `off`. The `all` and `off` levels can be used only in configuration and are just handy shortcuts that allow you to log every log record or disable logging entirely or for a specific logger. Default is `info`. + +| `logging.loggers[]..name:` +| Specific logger instance. + +| `logging.loggers[]..level` +| Specify verbosity of log messages for context. Optional and inherits the verbosity of any ancestor logger, up to the `root` logger `level`. + +| `logging.loggers[]..appenders` +| Determines the appender to apply to a specific logger context as an array. Optional and falls back to the appender(s) of the `root` logger if not specified. + +|=== diff --git a/docs/setup/configuring-logging.asciidoc b/docs/setup/configuring-logging.asciidoc new file mode 100644 index 0000000000000..38c5594a8e78f --- /dev/null +++ b/docs/setup/configuring-logging.asciidoc @@ -0,0 +1,697 @@ +[[logging-configuration]] +== Configure logging + +The {kib} logging system has three main components: _loggers_, _appenders_ and _layouts_. These components allow us to log messages according to message type and level, to control how these messages are formatted and where the final logs will be displayed or stored. + +- <> +- <> +- <> +- <> + +[float] +[[loggers-appenders-layout]] +=== Loggers, Appenders and Layouts +__Loggers__ define what logging settings should be applied to a particular logger. + +__<>__ define where log messages are displayed (eg. stdout or console) and stored (eg. file on the disk). + +__<>__ define how log messages are formatted and what type of information they include. + +[float] +[[log-level]] +=== Log level + +Currently we support the following log levels: _all_, _fatal_, _error_, _warn_, _info_, _debug_, _trace_, _off_. + +Levels are ordered, so _all_ > _fatal_ > _error_ > _warn_ > _info_ > _debug_ > _trace_ > _off_. + +A log record will be logged by the logger if its level is higher than or equal to the level of its logger. Otherwise, the log record is ignored. + +The _all_ and _off_ levels can only be used in configuration and are handy shortcuts that allow you to log every log record or disable logging entirely for a specific logger. These levels can also be specified using <>. + +[float] +[[logging-layouts]] +=== Layouts + +Every appender should know exactly how to format log messages before they are written to the console or file on the disk. +This behavior is controlled by the layouts and configured through `appender.layout` configuration property for every +custom appender. Currently we don't define any default layout for the +custom appenders, so one should always make the choice explicitly. + +There are two types of layout supported at the moment: <> and <>. + +[float] +[[pattern-layout]] +==== Pattern layout + +With `pattern` layout it's possible to define a string pattern with special placeholders `%conversion_pattern` that will be replaced with data from the actual log message. By default the following pattern is used: `[%date][%level][%logger] %message`. + +NOTE: The `pattern` layout uses a sub-set of https://logging.apache.org/log4j/2.x/manual/layouts.html#PatternLayout[log4j 2 pattern syntax] and **doesn't implement** all `log4j 2` capabilities. + +The conversions that are provided out of the box are: + +**level** +Outputs the <> of the logging event. +Example of `%level` output: `TRACE`, `DEBUG`, `INFO`. + +**logger** +Outputs the name of the logger that published the logging event. +Example of `%logger` output: `server`, `server.http`, `server.http.kibana`. + +**message** +Outputs the application supplied message associated with the logging event. + +**meta** +Outputs the entries of `meta` object data in **json** format, if one is present in the event. +Example of `%meta` output: +[source,bash] +---- +// Meta{from: 'v7', to: 'v8'} +'{"from":"v7","to":"v8"}' +// Meta empty object +'{}' +// no Meta provided +'' +---- + +[float] +[[date-format]] +**date** +Outputs the date of the logging event. The date conversion specifier may be followed by a set of braces containing a name of predefined date format and canonical timezone name. +Timezone name is expected to be one from https://en.wikipedia.org/wiki/List_of_tz_database_time_zones[TZ database name]. +Timezone defaults to the host timezone when not explicitly specified. +Example of `%date` output: + +[float] +[[date-conversion-pattern-examples]] +[options="header"] +|=== + +| Conversion pattern | Example + +| `%date` +| `2012-02-01T14:30:22.011Z` uses `ISO8601` format by default + +| `%date{ISO8601}` +| `2012-02-01T14:30:22.011Z` + +| `%date{ISO8601_TZ}` +| `2012-02-01T09:30:22.011-05:00` `ISO8601` with timezone + +| `%date{ISO8601_TZ}{America/Los_Angeles}` +| `2012-02-01T06:30:22.011-08:00` + +| `%date{ABSOLUTE}` +| `09:30:22.011` + +| `%date{ABSOLUTE}{America/Los_Angeles}` +| `06:30:22.011` + +| `%date{UNIX}` +| `1328106622` + +| `%date{UNIX_MILLIS}` +| `1328106622011` + +|=== + +**pid** +Outputs the process ID. + +The pattern layout also offers a `highlight` option that allows you to highlight +some parts of the log message with different colors. Highlighting is quite handy if log messages are forwarded +to a terminal with color support. + +[float] +[[json-layout]] +==== JSON layout +With `json` layout log messages will be formatted as JSON strings in https://www.elastic.co/guide/en/ecs/current/ecs-reference.html[ECS format] that includes a timestamp, log level, logger, message text and any other metadata that may be associated with the log message itself. + +[float] +[[logger-hierarchy]] +=== Logger hierarchy + +Every logger has a unique name that follows a hierarchical naming rule. The logger is considered to be an +ancestor of another logger if its name followed by a `.` is a prefix of the descendant logger. For example, a logger +named `a.b` is an ancestor of logger `a.b.c`. All top-level loggers are descendants of a special `root` logger at the top of the logger hierarchy. The `root` logger always exists, is fully configured and logs to `info` level by default. The `root` logger must also be configured if any other logging configuration is specified in your `kibana.yml`. + +You can configure _<>_ and _appenders_ for a specific logger. If a logger only has a _log level_ configured, then the _appenders_ configuration applied to the logger is inherited from the ancestor logger, up to the `root` logger. + +NOTE: In the current implementation we __don't support__ so called _appender additivity_ when log messages are forwarded to _every_ distinct appender within the +ancestor chain including `root`. That means that log messages are only forwarded to appenders that are configured for a particular logger. If a logger doesn't have any appenders configured, the configuration of that particular logger will be inherited from its closest ancestor. + +[float] +[[dedicated-loggers]] +===== Dedicated loggers + +**Root** + +The `root` logger has a dedicated configuration node since this logger is special and should always exist. By default `root` is configured with `info` level and `default` appender that is also always available. This is the configuration that all custom loggers will use unless they're re-configured explicitly. + +For example to see _all_ log messages that fall back on the `root` logger configuration, just add one line to the configuration: + +[source,yaml] +---- +logging.root.level: all +---- + +Or disable logging entirely with `off`: + +[source,yaml] +---- +logging.root.level: off +---- + +**Metrics Logs** + +The `metrics.ops` logger is configured with `debug` level and will automatically output sample system and process information at a regular interval. +The metrics that are logged are a subset of the data collected and are formatted in the log message as follows: + +[options="header"] +|=== + +| Ops formatted log property | Location in metrics service | Log units + +| memory | process.memory.heap.used_in_bytes | http://numeraljs.com/#format[depends on the value], typically MB or GB + +| uptime | process.uptime_in_millis | HH:mm:ss + +| load | os.load | [ "load for the last 1 min" "load for the last 5 min" "load for the last 15 min"] + +| delay | process.event_loop_delay | ms +|=== + +The log interval is the same as the interval at which system and process information is refreshed and is configurable under `ops.interval`: + +[source,yaml] +---- +ops.interval: 5000 +---- + +The minimum interval is 100ms and defaults to 5000ms. + +[[request-response-logger]] +**Request and Response Logs** + +The `http.server.response` logger is configured with `debug` level and will automatically output +data about http requests and responses occurring on the {kib} server. +The message contains some high-level information, and the corresponding log meta contains the following: + +[options="header"] +|=== + +| Meta property | Description | Format + +| client.ip | IP address of the requesting client | ip + +| http.request.method | http verb for the request (uppercase) | string + +| http.request.mime_type | (optional) mime as specified in the headers | string + +| http.request.referrer | (optional) referrer | string + +| http.request.headers | request headers | object + +| http.response.body.bytes | (optional) Calculated response payload size in bytes | number + +| http.response.status_code | status code returned | number + +| http.response.headers | response headers | object + +| http.response.responseTime | (optional) Calculated response time in ms | number + +| url.path | request path | string + +| url.query | (optional) request query string | string + +| user_agent.original | raw user-agent string provided in request headers | string + +|=== + +[float] +[[logging-appenders]] +=== Appenders + +[float] +[[rolling-file-appender]] +==== Rolling File Appender + +Similar to Log4j's `RollingFileAppender`, this appender will log into a file, and rotate it following a rolling +strategy when the configured policy triggers. + +[float] +====== Triggering Policies + +The triggering policy determines when a rollover should occur. + +There are currently two policies supported: `size-limit` and `time-interval`. + +[float] +[[size-limit-triggering-policy]] +**Size-limit triggering policy** + +This policy will rotate the file when it reaches a predetermined size. + +[source,yaml] +---- +logging: + appenders: + rolling-file: + type: rolling-file + fileName: /var/logs/kibana.log + policy: + type: size-limit + size: 50mb + strategy: + //... + layout: + type: pattern +---- + +The options are: + +- `size` + +The maximum size the log file should reach before a rollover should be performed. The default value is `100mb` + +[[time-interval-triggering-policy]] +**Time-interval triggering policy** + +This policy will rotate the file every given interval of time. + +[source,yaml] +---- +logging: + appenders: + rolling-file: + type: rolling-file + fileName: /var/logs/kibana.log + policy: + type: time-interval + interval: 10s + modulate: true + strategy: + //... + layout: + type: pattern +---- + +The options are: + +- `interval` + +How often a rollover should occur. The default value is `24h` + +- `modulate` + +Whether the interval should be adjusted to cause the next rollover to occur on the interval boundary. + +For example, if modulate is true and the interval is `4h`, if the current hour is 3 am then the first rollover will occur at 4 am +and then next ones will occur at 8 am, noon, 4pm, etc. The default value is `true`. + +[float] +===== Rolling strategies + +The rolling strategy determines how the rollover should occur: both the naming of the rolled files, +and their retention policy. + +There is currently one strategy supported: `numeric`. + +**Numeric rolling strategy** + +This strategy will suffix the file with a given pattern when rolling, +and will retains a fixed amount of rolled files. + +[source,yaml] +---- +logging: + appenders: + rolling-file: + type: rolling-file + fileName: /var/logs/kibana.log + policy: + // ... + strategy: + type: numeric + pattern: '-%i' + max: 2 + layout: + type: pattern +---- + +For example, with this configuration: + +- During the first rollover kibana.log is renamed to kibana-1.log. A new kibana.log file is created and starts + being written to. +- During the second rollover kibana-1.log is renamed to kibana-2.log and kibana.log is renamed to kibana-1.log. + A new kibana.log file is created and starts being written to. +- During the third and subsequent rollovers, kibana-2.log is deleted, kibana-1.log is renamed to kibana-2.log and + kibana.log is renamed to kibana-1.log. A new kibana.log file is created and starts being written to. + +The options are: + +- `pattern` + +The suffix to append to the file path when rolling. Must include `%i`, as this is the value +that will be converted to the file index. + +For example, with `fileName: /var/logs/kibana.log` and `pattern: '-%i'`, the rolling files created +will be `/var/logs/kibana-1.log`, `/var/logs/kibana-2.log`, and so on. The default value is `-%i` + +- `max` + +The maximum number of files to keep. Once this number is reached, oldest files will be deleted. The default value is `7` + +[float] +[[rewrite-appender]] +==== Rewrite appender + +WARNING: This appender is currently considered experimental and is not intended +for public consumption. The API is subject to change at any time. + +Similar to log4j's `RewriteAppender`, this appender serves as a sort of middleware, +modifying the provided log events before passing them along to another +appender. + +[source,yaml] +---- +logging: + appenders: + my-rewrite-appender: + type: rewrite + appenders: [console, file] # name of "destination" appender(s) + policy: + # ... +---- + +The most common use case for the `RewriteAppender` is when you want to +filter or censor sensitive data that may be contained in a log entry. +In fact, with a default configuration, {kib} will automatically redact +any `authorization`, `cookie`, or `set-cookie` headers when logging http +requests & responses. + +To configure additional rewrite rules, you'll need to specify a <>. + +[float] +[[rewrite-policies]] +====== Rewrite policies + +Rewrite policies exist to indicate which parts of a log record can be +modified within the rewrite appender. + +**Meta** + +The `meta` rewrite policy can read and modify any data contained in the +`LogMeta` before passing it along to a destination appender. + +Meta policies must specify one of three modes, which indicate which action +to perform on the configured properties: +- `update` updates an existing property at the provided `path`. +- `remove` removes an existing property at the provided `path`. + +The `properties` are listed as a `path` and `value` pair, where `path` is +the dot-delimited path to the target property in the `LogMeta` object, and +`value` is the value to add or update in that target property. When using +the `remove` mode, a `value` is not necessary. + +Here's an example of how you would replace any `cookie` header values with `[REDACTED]`: + +[source,yaml] +---- +logging: + appenders: + my-rewrite-appender: + type: rewrite + appenders: [console] + policy: + type: meta # indicates that we want to rewrite the LogMeta + mode: update # will update an existing property only + properties: + - path: "http.request.headers.cookie" # path to property + value: "[REDACTED]" # value to replace at path +---- + +Rewrite appenders can even be passed to other rewrite appenders to apply +multiple filter policies/modes, as long as it doesn't create a circular +reference. Each rewrite appender is applied sequentially (one after the other). + +[source,yaml] +---- +logging: + appenders: + remove-request-headers: + type: rewrite + appenders: [censor-response-headers] # redirect to the next rewrite appender + policy: + type: meta + mode: remove + properties: + - path: "http.request.headers" # remove all request headers + censor-response-headers: + type: rewrite + appenders: [console] # output to console + policy: + type: meta + mode: update + properties: + - path: "http.response.headers.set-cookie" + value: "[REDACTED]" +---- + +[float] +====== Complete Example For Rewrite Appender + +[source,yaml] +---- +logging: + appenders: + custom_console: + type: console + layout: + type: pattern + highlight: true + pattern: "[%date][%level][%logger] %message %meta" + file: + type: file + fileName: ./kibana.log + layout: + type: json + censor: + type: rewrite + appenders: [custom_console, file] + policy: + type: meta + mode: update + properties: + - path: "http.request.headers.cookie" + value: "[REDACTED]" + loggers: + - name: http.server.response + appenders: [censor] # pass these logs to our rewrite appender + level: debug +---- + +[[log-settings-examples]] +=== Examples +Here are some configuration examples for the most common logging use cases: + +[float] +[[log-to-file-example]] +==== Log to a file + +Log the default log format to a file instead of to stdout (the default). + +[source,yaml] +---- +logging: + appenders: + file: + type: file + fileName: /var/log/kibana.log + layout: + type: pattern + root: + appenders: [file] +---- + +[float] +[[log-in-json-ECS-example]] +==== Log in JSON format + +Log the default log format to JSON layout instead of pattern (the default). +With `json` layout, log messages will be formatted as JSON strings in https://www.elastic.co/guide/en/ecs/current/ecs-reference.html[ECS format] that includes a timestamp, log level, logger, message text and any other metadata that may be associated with the log message itself. + +[source,yaml] +---- +logging: + appenders: + json-layout: + type: console + layout: + type: json + root: + appenders: [json-layout] +---- + +[float] +[[log-with-meta-to-stdout]] +==== Log with meta to stdout + +Include `%meta` in your pattern layout: + +[source,yaml] +---- +logging: + appenders: + console-meta: + type: console + layout: + type: pattern + pattern: "[%date] [%level] [%logger] [%meta] %message" + root: + appenders: [console-meta] +---- + +[float] +[[log-elasticsearch-queries]] +==== Log {es} queries + +[source,yaml] +-- +logging: + appenders: + console_appender: + type: console + layout: + type: pattern + highlight: true + root: + appenders: [console_appender] + level: warn + loggers: + - name: elasticsearch.query + level: debug +-- + +[float] +[[change-overall-log-level]] +==== Change overall log level + +[source,yaml] +---- +logging: + root: + level: debug +---- + +[float] +[[customize-specific-log-records]] +==== Customize specific log records +Here is a detailed configuration example that can be used to configure _loggers_, _appenders_ and _layouts_: + +[source,yaml] +---- +logging: + appenders: + console: + type: console + layout: + type: pattern + highlight: true + file: + type: file + fileName: /var/log/kibana.log + custom: + type: console + layout: + type: pattern + pattern: "[%date][%level] %message" + json-file-appender: + type: file + fileName: /var/log/kibana-json.log + layout: + type: json + + root: + appenders: [console, file] + level: error + + loggers: + - name: plugins + appenders: [custom] + level: warn + - name: plugins.myPlugin + level: info + - name: server + level: fatal + - name: optimize + appenders: [console] + - name: telemetry + appenders: [json-file-appender] + level: all + - name: metrics.ops + appenders: [console] + level: debug +---- + +Here is what we get with the config above: +[options="header"] +|=== + +| Context name | Appenders | Level + +| root | console, file | error + +| plugins | custom | warn + +| plugins.myPlugin | custom | info + +| server | console, file | fatal + +| optimize | console | error + +| telemetry | json-file-appender | all + +| metrics.ops | console | debug +|=== + +=== Cli configuration +[float] +[[logging-cli-migration]] +=== Logging configuration via CLI + +As is the case for any of Kibana's config settings, you can specify your logging configuration via the CLI. For convenience, the `--verbose` and `--silent` flags exist as shortcuts and will continue to be supported beyond v7. + +If you wish to override these flags, you can always do so by passing your preferred logging configuration directly to the CLI. For example, with the following configuration: + +[source,yaml] +---- +logging: + appenders: + custom: + type: console + layout: + type: pattern + pattern: "[%date][%level] %message" + root: + level: warn + appenders: [custom] +---- + +you can override the root logging level with: + +[options="header"] +[cols="1, 4, 1"] +|=== + +|legacy logging|{kib} Platform logging|cli shortcuts + +|--verbose +|--logging.root.level=debug +|--verbose + +|--silent +|--logging.root.level=off +|--silent + +|=== diff --git a/docs/setup/settings.asciidoc b/docs/setup/settings.asciidoc index c9a8210f82198..9e2f981e92f92 100644 --- a/docs/setup/settings.asciidoc +++ b/docs/setup/settings.asciidoc @@ -110,7 +110,7 @@ in this setting. currently do not have an inspector, for example Timelion and Monitoring. *Default: `false`* -The following example shows a valid `elasticsearch.query` logger configuration: +The following example shows a valid verbose `elasticsearch.query` logger configuration: |=== [source,text] @@ -123,7 +123,7 @@ logging: type: pattern highlight: true root: - appenders: [default, console_appender] + appenders: [console_appender] level: warn loggers: - name: elasticsearch.query @@ -298,50 +298,54 @@ suggestions. This value must be a whole number greater than zero. [NOTE] ============ -To reload the logging settings, send a SIGHUP signal to {kib}. +To reload the <>, send a SIGHUP signal to {kib}. +For more logging configuration options, see the <> guide. ============ [cols="2*<"] |=== |[[logging-root]] `logging.root:` -| The {kibana-ref}/logging-service.html#logging-service[`root` logger] has a dedicated configuration node since this context name is special and is pre-configured for logging by default. -// TODO: add link to the advanced logging documentation. +| The `root` logger has is a <> and is pre-configured. The `root` logger logs at `info` level by default. If any other logging configuration is specified, `root` _must_ also be explicitly configured. |[[logging-root-appenders]] `logging.root.appenders:` -| A list of logging appenders to forward the root level logger instance to. By default `root` is configured with the `default` appender that must be included in the list. This is the configuration that all custom loggers will use unless they're re-configured explicitly. Additional appenders, if configured, can be included in the list. +| A list of logging appenders to forward the root level logger instance to. By default `root` is configured with the `default` appender that logs to stdout with a `pattern` layout. This is the configuration that all custom loggers will use unless they're re-configured explicitly. You can override the default behavior by configuring a different <> to apply to `root`. |[[logging-root-level]] `logging.root.level:` {ess-icon} -| Level at which a log record should be logged. Supported levels are: _all_, _fatal_, _error_, _warn_, _info_, _debug_, _trace_, _off_. Levels are ordered from _all_ (highest) to _off_ and a log record will be logged it its level is higher than or equal to the level of its logger, otherwise the log record is ignored. Use this value to <>. Set to `all` to log all events, including system usage information and all requests. Set to `off` to silence all logs. *Default: `info`*. +| Level at which a log record should be logged. Supported levels are: _all_, _fatal_, _error_, _warn_, _info_, _debug_, _trace_, _off_. Levels are ordered from _all_ (highest) to _off_ and a log record will be logged it its level is higher than or equal to the level of its logger, otherwise the log record is ignored. Use this value to <>. *Default: `info`*. -|[[logging-loggers]] `logging.loggers:` - | Allows you to <>. - -| `logging.loggers.name:` -| Specific logger instance. - -| `logging.loggers.level:` -| Level at which a log record should be shown. Supported levels are: _all_, _fatal_, _error_, _warn_, _info_, _debug_, _trace_, _off_. - -| `logging.loggers.appenders:` -| Specific appender format to apply for a particular logger context. +2+a| +[TIP] +============ +Set to `all` to log all events, including system usage information and all requests. Set to `off` to silence all logs. You can also use the logging <> to set log level to `verbose` or silence all logs. +============ -| `logging.appenders:` -| {kibana-ref}/logging-service.html#logging-appenders[Appenders] define how and where log messages are displayed (eg. *stdout* or console) and stored (eg. file on the disk). -// TODO: add link to the advanced logging documentation. +The following example shows a valid verbose `logging.root` configuration: +|=== -| `logging.appenders.console:` -| Appender to use for logging records to *stdout*. By default, uses the `[%date][%level][%logger] %message` **pattern** layout. To use a **json**, set the <>. +[source,text] +-- +logging: + appenders: + console_appender: + type: console + layout: + type: pattern + highlight: true + root: + appenders: [console_appender] + level: all +-- -| `logging.appenders.file:` -| Allows you to specify a fileName to send log records to on disk. To send <>, add the file appender to `root.appenders`. +[cols="2*<"] +|=== -| `logging.appenders.rolling-file:` -| Similar to Log4j's `RollingFileAppender`, this appender will log into a file and rotate if following a rolling strategy when the configured policy triggers. There are currently two policies supported: `size-limit` and `time-interval`. +|[[logging-loggers]] `logging.loggers[]:` + | Allows you to <>. -The size limit policy will perform a rollover when the log file reaches a maximum `size`. *Default 100mb* +| `logging.appenders[]:` +| <> define how and where log messages are displayed (eg. *stdout* or console) and stored (eg. file on the disk). -The time interval policy will rotate the log file every given interval of time. *Default 24h* | `map.includeElasticMapsService:` {ess-icon} | Set to `false` to disable connections to Elastic Maps Service. diff --git a/docs/setup/upgrade.asciidoc b/docs/setup/upgrade.asciidoc index 9a949ffa01b65..a139b8a50ca4d 100644 --- a/docs/setup/upgrade.asciidoc +++ b/docs/setup/upgrade.asciidoc @@ -58,6 +58,8 @@ Before you upgrade {kib}: * Shut down all {kib} instances. Running more than one {kib} version against the same Elasticseach index is unsupported. Upgrading while older {kib} instances are running can cause data loss or upgrade failures. + +NOTE: {kib} logging system may have changed, depending on your target version. For details, see <>. To identify the changes you need to make to upgrade, and to enable you to perform an Elasticsearch rolling upgrade with no downtime, you must upgrade to @@ -101,3 +103,5 @@ Assistant, <>. include::upgrade/upgrade-standard.asciidoc[] include::upgrade/upgrade-migrations.asciidoc[] + +include::upgrade/logging-configuration-changes.asciidoc[] diff --git a/docs/setup/upgrade/logging-configuration-changes.asciidoc b/docs/setup/upgrade/logging-configuration-changes.asciidoc new file mode 100644 index 0000000000000..a7a86fcb45b14 --- /dev/null +++ b/docs/setup/upgrade/logging-configuration-changes.asciidoc @@ -0,0 +1,45 @@ +[[logging-configuration-changes]] +=== Logging configuration changes + +WARNING: {kib} 8.0 and later uses a new logging system. Be sure to read the documentation for your version of {kib} before proceeding. + +[[logging-pattern-format-old-and-new-example]] +[options="header"] +|=== + +| Parameter | Log record in **pattern** format | Legacy log record in **text** format + +| @timestamp | ISO8601_TZ `2012-01-31T23:33:22.011-05:00` | Absolute `23:33:22.011` + +| logger | `parent.child` | `['parent', 'child']` + +| level | `DEBUG` | `['debug']` + +| meta | stringified JSON object `{"to": "v8"}`| N/A + +| pid | can be configured as `%pid` | N/A + +|=== + +[[logging-json-format-old-and-new-example]] +[options="header"] +|=== + +| Parameter | Log record in **json** format | Legacy log record **json** format + +| @timestamp | ISO8601_TZ `2012-01-31T23:33:22.011-05:00` | ISO8601 `2012-01-31T23:33:22.011Z` + +| logger | `log.logger: parent.child` | `tags: ['parent', 'child']` + +| level | `log.level: DEBUG` | `tags: ['debug']` + +| meta | merged in log record `{... "to": "v8"}` | merged in log record `{... "to": "v8"}` + +| pid | `process.pid: 12345` | `pid: 12345` + +| type | N/A | `type: log` + +| error | `{ message, name, stack }` | `{ message, name, stack, code, signal }` + +|=== + diff --git a/docs/user/setup.asciidoc b/docs/user/setup.asciidoc index 7da0a969b53e8..546cc8f974865 100644 --- a/docs/user/setup.asciidoc +++ b/docs/user/setup.asciidoc @@ -64,6 +64,8 @@ include::security/securing-kibana.asciidoc[] include::{kib-repo-dir}/setup/configuring-reporting.asciidoc[] +include::{kib-repo-dir}/setup/configuring-logging.asciidoc[] + include::monitoring/configuring-monitoring.asciidoc[leveloffset=+1] include::monitoring/monitoring-metricbeat.asciidoc[leveloffset=+2] include::monitoring/viewing-metrics.asciidoc[leveloffset=+2] From 54da675bc66c7673e441f3965b22bbfacd57e1ae Mon Sep 17 00:00:00 2001 From: Byron Hulcher Date: Wed, 24 Nov 2021 17:58:55 -0500 Subject: [PATCH 08/46] [App Search] Add new type CrawlRequestWithDetails, and use that for CrawlDetailsLogic.values.crawlRequest (#119645) --- .../crawl_details_flyout.test.tsx | 4 +- .../crawl_details_flyout.tsx | 4 +- .../components/crawl_requests_table.test.tsx | 4 +- .../components/crawl_requests_table.tsx | 4 +- .../crawler/crawl_detail_logic.test.ts | 37 ++++--- .../components/crawler/crawl_detail_logic.ts | 38 +++---- .../app_search/components/crawler/types.ts | 17 +++- .../components/crawler/utils.test.ts | 98 +++++++++++++++++++ .../app_search/components/crawler/utils.ts | 46 ++++++++- 9 files changed, 200 insertions(+), 52 deletions(-) diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_details_flyout/crawl_details_flyout.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_details_flyout/crawl_details_flyout.test.tsx index ec63b41626230..1810b05a938da 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_details_flyout/crawl_details_flyout.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_details_flyout/crawl_details_flyout.test.tsx @@ -16,7 +16,7 @@ import { EuiCodeBlock, EuiFlyout, EuiTab, EuiTabs } from '@elastic/eui'; import { Loading } from '../../../../../shared/loading'; import { CrawlDetailActions, CrawlDetailValues } from '../../crawl_detail_logic'; -import { CrawlEventFromServer } from '../../types'; +import { CrawlRequestWithDetailsFromServer } from '../../types'; import { CrawlDetailsPreview } from './crawl_details_preview'; @@ -25,7 +25,7 @@ import { CrawlDetailsFlyout } from '.'; const MOCK_VALUES: Partial = { dataLoading: false, flyoutClosed: false, - crawlEventFromServer: {} as CrawlEventFromServer, + crawlRequestFromServer: {} as CrawlRequestWithDetailsFromServer, }; const MOCK_ACTIONS: Partial = { diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_details_flyout/crawl_details_flyout.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_details_flyout/crawl_details_flyout.tsx index 27dda25b09202..8ecd861304458 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_details_flyout/crawl_details_flyout.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_details_flyout/crawl_details_flyout.tsx @@ -27,7 +27,7 @@ import { CrawlDetailsPreview } from './crawl_details_preview'; export const CrawlDetailsFlyout: React.FC = () => { const { closeFlyout, setSelectedTab } = useActions(CrawlDetailLogic); - const { crawlEventFromServer, dataLoading, flyoutClosed, selectedTab } = + const { crawlRequestFromServer, dataLoading, flyoutClosed, selectedTab } = useValues(CrawlDetailLogic); if (flyoutClosed) { @@ -71,7 +71,7 @@ export const CrawlDetailsFlyout: React.FC = () => { {selectedTab === 'preview' && } {selectedTab === 'json' && ( - {JSON.stringify(crawlEventFromServer, null, 2)} + {JSON.stringify(crawlRequestFromServer, null, 2)} )} diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_requests_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_requests_table.test.tsx index c8b89153ed88c..bc5f8bf87e100 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_requests_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_requests_table.test.tsx @@ -51,7 +51,7 @@ const values: { events: CrawlEvent[] } = { }; const actions = { - fetchCrawlEvent: jest.fn(), + fetchCrawlRequest: jest.fn(), openFlyout: jest.fn(), }; @@ -83,7 +83,7 @@ describe('CrawlRequestsTable', () => { expect(crawlID.text()).toContain('618d0e66abe97bc688328900'); crawlID.simulate('click'); - expect(actions.fetchCrawlEvent).toHaveBeenCalledWith('618d0e66abe97bc688328900'); + expect(actions.fetchCrawlRequest).toHaveBeenCalledWith('618d0e66abe97bc688328900'); expect(actions.openFlyout).toHaveBeenCalled(); const processCrawlID = shallow(columns[0].render('54325423aef7890543', { stage: 'process' })); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_requests_table.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_requests_table.tsx index 9f2451136ba93..0949be0ced0a6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_requests_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/components/crawl_requests_table.tsx @@ -28,7 +28,7 @@ import { CustomFormattedTimestamp } from './custom_formatted_timestamp'; export const CrawlRequestsTable: React.FC = () => { const { events } = useValues(CrawlerLogic); - const { fetchCrawlEvent, openFlyout } = useActions(CrawlDetailLogic); + const { fetchCrawlRequest, openFlyout } = useActions(CrawlDetailLogic); const columns: Array> = [ { @@ -44,7 +44,7 @@ export const CrawlRequestsTable: React.FC = () => { return ( { - fetchCrawlEvent(id); + fetchCrawlRequest(id); openFlyout(); }} > diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawl_detail_logic.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawl_detail_logic.test.ts index 40674843ab730..57816db01b58c 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawl_detail_logic.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawl_detail_logic.test.ts @@ -13,31 +13,30 @@ import { nextTick } from '@kbn/test/jest'; import { itShowsServerErrorAsFlashMessage } from '../../../test_helpers'; import { CrawlDetailLogic, CrawlDetailValues } from './crawl_detail_logic'; -import { CrawlerStatus, CrawlEventFromServer, CrawlType } from './types'; -import { crawlEventServerToClient } from './utils'; +import { CrawlType, CrawlerStatus, CrawlRequestWithDetailsFromServer } from './types'; +import { crawlRequestWithDetailsServerToClient } from './utils'; const DEFAULT_VALUES: CrawlDetailValues = { dataLoading: true, flyoutClosed: true, - crawlEvent: null, - crawlEventFromServer: null, + crawlRequest: null, + crawlRequestFromServer: null, selectedTab: 'preview', }; -const crawlEventResponse: CrawlEventFromServer = { +const crawlRequestResponse: CrawlRequestWithDetailsFromServer = { id: '12345', status: CrawlerStatus.Pending, created_at: 'Mon, 31 Aug 2020 17:00:00 +0000', began_at: null, completed_at: null, - stage: 'crawl', type: CrawlType.Full, crawl_config: { domain_allowlist: [], }, }; -const clientCrawlEvent = crawlEventServerToClient(crawlEventResponse); +const clientCrawlRequest = crawlRequestWithDetailsServerToClient(crawlRequestResponse); describe('CrawlDetailLogic', () => { const { mount } = new LogicMounter(CrawlDetailLogic); @@ -66,20 +65,20 @@ describe('CrawlDetailLogic', () => { }); }); - describe('onRecieveCrawlEvent', () => { + describe('onRecieveCrawlRequest', () => { it('saves the crawl request and sets data loading to false', () => { mount({ dataLoading: true, request: null, }); - CrawlDetailLogic.actions.onRecieveCrawlEvent(crawlEventResponse); + CrawlDetailLogic.actions.onRecieveCrawlRequest(crawlRequestResponse); expect(CrawlDetailLogic.values).toEqual({ ...DEFAULT_VALUES, dataLoading: false, - crawlEventFromServer: crawlEventResponse, - crawlEvent: clientCrawlEvent, + crawlRequestFromServer: crawlRequestResponse, + crawlRequest: clientCrawlRequest, }); }); }); @@ -116,13 +115,13 @@ describe('CrawlDetailLogic', () => { }); }); - describe('fetchCrawlEvent', () => { + describe('fetchCrawlRequest', () => { it('sets loading to true', () => { mount({ dataLoading: false, }); - CrawlDetailLogic.actions.fetchCrawlEvent('12345'); + CrawlDetailLogic.actions.fetchCrawlRequest('12345'); expect(CrawlDetailLogic.values).toEqual({ ...DEFAULT_VALUES, @@ -132,24 +131,24 @@ describe('CrawlDetailLogic', () => { it('updates logic with data that has been converted from server to client', async () => { mount(); - jest.spyOn(CrawlDetailLogic.actions, 'onRecieveCrawlEvent'); + jest.spyOn(CrawlDetailLogic.actions, 'onRecieveCrawlRequest'); - http.get.mockReturnValueOnce(Promise.resolve(crawlEventResponse)); + http.get.mockReturnValueOnce(Promise.resolve(crawlRequestResponse)); - CrawlDetailLogic.actions.fetchCrawlEvent('12345'); + CrawlDetailLogic.actions.fetchCrawlRequest('12345'); await nextTick(); expect(http.get).toHaveBeenCalledWith( '/internal/app_search/engines/some-engine/crawler/crawl_requests/12345' ); - expect(CrawlDetailLogic.actions.onRecieveCrawlEvent).toHaveBeenCalledWith( - crawlEventResponse + expect(CrawlDetailLogic.actions.onRecieveCrawlRequest).toHaveBeenCalledWith( + crawlRequestResponse ); }); itShowsServerErrorAsFlashMessage(http.get, () => { mount(); - CrawlDetailLogic.actions.fetchCrawlEvent('12345'); + CrawlDetailLogic.actions.fetchCrawlRequest('12345'); }); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawl_detail_logic.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawl_detail_logic.ts index 801f643fb936b..46180ad7c3235 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawl_detail_logic.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/crawl_detail_logic.ts @@ -12,14 +12,14 @@ import { flashAPIErrors } from '../../../shared/flash_messages'; import { HttpLogic } from '../../../shared/http'; import { EngineLogic } from '../engine'; -import { CrawlEvent, CrawlEventFromServer } from './types'; -import { crawlEventServerToClient } from './utils'; +import { CrawlRequestWithDetails, CrawlRequestWithDetailsFromServer } from './types'; +import { crawlRequestWithDetailsServerToClient } from './utils'; type CrawlDetailFlyoutTabs = 'preview' | 'json'; export interface CrawlDetailValues { - crawlEvent: CrawlEvent | null; - crawlEventFromServer: CrawlEventFromServer | null; + crawlRequest: CrawlRequestWithDetails | null; + crawlRequestFromServer: CrawlRequestWithDetailsFromServer | null; dataLoading: boolean; flyoutClosed: boolean; selectedTab: CrawlDetailFlyoutTabs; @@ -27,9 +27,9 @@ export interface CrawlDetailValues { export interface CrawlDetailActions { closeFlyout(): void; - fetchCrawlEvent(requestId: string): { requestId: string }; - onRecieveCrawlEvent(crawlEventFromServer: CrawlEventFromServer): { - crawlEventFromServer: CrawlEventFromServer; + fetchCrawlRequest(requestId: string): { requestId: string }; + onRecieveCrawlRequest(crawlRequestFromServer: CrawlRequestWithDetailsFromServer): { + crawlRequestFromServer: CrawlRequestWithDetailsFromServer; }; openFlyout(): void; setSelectedTab(selectedTab: CrawlDetailFlyoutTabs): { selectedTab: CrawlDetailFlyoutTabs }; @@ -39,30 +39,30 @@ export const CrawlDetailLogic = kea ({ requestId }), - onRecieveCrawlEvent: (crawlEventFromServer) => ({ crawlEventFromServer }), + fetchCrawlRequest: (requestId) => ({ requestId }), + onRecieveCrawlRequest: (crawlRequestFromServer) => ({ crawlRequestFromServer }), openFlyout: true, setSelectedTab: (selectedTab) => ({ selectedTab }), }, reducers: { - crawlEvent: [ + crawlRequest: [ null, { - onRecieveCrawlEvent: (_, { crawlEventFromServer }) => - crawlEventServerToClient(crawlEventFromServer), + onRecieveCrawlRequest: (_, { crawlRequestFromServer }) => + crawlRequestWithDetailsServerToClient(crawlRequestFromServer), }, ], - crawlEventFromServer: [ + crawlRequestFromServer: [ null, { - onRecieveCrawlEvent: (_, { crawlEventFromServer }) => crawlEventFromServer, + onRecieveCrawlRequest: (_, { crawlRequestFromServer }) => crawlRequestFromServer, }, ], dataLoading: [ true, { - fetchCrawlEvent: () => true, - onRecieveCrawlEvent: () => false, + fetchCrawlRequest: () => true, + onRecieveCrawlRequest: () => false, }, ], flyoutClosed: [ @@ -81,16 +81,16 @@ export const CrawlDetailLogic = kea ({ - fetchCrawlEvent: async ({ requestId }) => { + fetchCrawlRequest: async ({ requestId }) => { const { http } = HttpLogic.values; const { engineName } = EngineLogic.values; try { - const response = await http.get( + const response = await http.get( `/internal/app_search/engines/${engineName}/crawler/crawl_requests/${requestId}` ); - actions.onRecieveCrawlEvent(response); + actions.onRecieveCrawlRequest(response); } catch (e) { flashAPIErrors(e); } diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/types.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/types.ts index ddf714c3e14f7..6cdccfdc78633 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/types.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/types.ts @@ -199,8 +199,6 @@ export interface CrawlRequest { completedAt: string | null; } -export type CrawlEventStage = 'crawl' | 'process'; - export interface CrawlConfig { domainAllowlist: string[]; } @@ -208,6 +206,21 @@ export interface CrawlConfig { export interface CrawlConfigFromServer { domain_allowlist: string[]; } + +export type CrawlRequestWithDetailsFromServer = CrawlRequestFromServer & { + type: CrawlType; + crawl_config: CrawlConfigFromServer; + // TODO add other properties like stats +}; + +export type CrawlRequestWithDetails = CrawlRequest & { + type: CrawlType; + crawlConfig: CrawlConfig; + // TODO add other properties like stats +}; + +export type CrawlEventStage = 'crawl' | 'process'; + export type CrawlEventFromServer = CrawlRequestFromServer & { stage: CrawlEventStage; type: CrawlType; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.test.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.test.ts index fa61a1a886be5..c104312f19edc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.test.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.test.ts @@ -18,13 +18,19 @@ import { CrawlRequest, CrawlerDomain, CrawlType, + CrawlRequestWithDetailsFromServer, + CrawlRequestWithDetails, + CrawlEvent, + CrawlEventFromServer, } from './types'; import { crawlerDomainServerToClient, crawlerDataServerToClient, crawlDomainValidationToResult, + crawlEventServerToClient, crawlRequestServerToClient, + crawlRequestWithDetailsServerToClient, getDeleteDomainConfirmationMessage, getDeleteDomainSuccessMessage, getCrawlRulePathPatternTooltip, @@ -120,6 +126,98 @@ describe('crawlRequestServerToClient', () => { }); }); +describe('crawlRequestWithDetailsServerToClient', () => { + it('converts the API payload into properties matching our code style', () => { + const id = '507f1f77bcf86cd799439011'; + + const defaultServerPayload: CrawlRequestWithDetailsFromServer = { + id, + status: CrawlerStatus.Pending, + created_at: 'Mon, 31 Aug 2020 17:00:00 +0000', + began_at: null, + completed_at: null, + type: CrawlType.Full, + crawl_config: { + domain_allowlist: [], + }, + }; + + const defaultClientPayload: CrawlRequestWithDetails = { + id, + status: CrawlerStatus.Pending, + createdAt: 'Mon, 31 Aug 2020 17:00:00 +0000', + beganAt: null, + completedAt: null, + type: CrawlType.Full, + crawlConfig: { + domainAllowlist: [], + }, + }; + + expect(crawlRequestWithDetailsServerToClient(defaultServerPayload)).toStrictEqual( + defaultClientPayload + ); + expect( + crawlRequestWithDetailsServerToClient({ + ...defaultServerPayload, + began_at: 'Mon, 31 Aug 2020 17:00:00 +0000', + }) + ).toStrictEqual({ ...defaultClientPayload, beganAt: 'Mon, 31 Aug 2020 17:00:00 +0000' }); + expect( + crawlRequestWithDetailsServerToClient({ + ...defaultServerPayload, + completed_at: 'Mon, 31 Aug 2020 17:00:00 +0000', + }) + ).toStrictEqual({ ...defaultClientPayload, completedAt: 'Mon, 31 Aug 2020 17:00:00 +0000' }); + }); +}); + +describe('crawlEventServerToClient', () => { + it('converts the API payload into properties matching our code style', () => { + const id = '507f1f77bcf86cd799439011'; + + const defaultServerPayload: CrawlEventFromServer = { + id, + status: CrawlerStatus.Pending, + created_at: 'Mon, 31 Aug 2020 17:00:00 +0000', + began_at: null, + completed_at: null, + type: CrawlType.Full, + crawl_config: { + domain_allowlist: [], + }, + stage: 'crawl', + }; + + const defaultClientPayload: CrawlEvent = { + id, + status: CrawlerStatus.Pending, + createdAt: 'Mon, 31 Aug 2020 17:00:00 +0000', + beganAt: null, + completedAt: null, + type: CrawlType.Full, + crawlConfig: { + domainAllowlist: [], + }, + stage: 'crawl', + }; + + expect(crawlEventServerToClient(defaultServerPayload)).toStrictEqual(defaultClientPayload); + expect( + crawlEventServerToClient({ + ...defaultServerPayload, + began_at: 'Mon, 31 Aug 2020 17:00:00 +0000', + }) + ).toStrictEqual({ ...defaultClientPayload, beganAt: 'Mon, 31 Aug 2020 17:00:00 +0000' }); + expect( + crawlEventServerToClient({ + ...defaultServerPayload, + completed_at: 'Mon, 31 Aug 2020 17:00:00 +0000', + }) + ).toStrictEqual({ ...defaultClientPayload, completedAt: 'Mon, 31 Aug 2020 17:00:00 +0000' }); + }); +}); + describe('crawlerDataServerToClient', () => { let output: CrawlerData; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.ts index a5065446b72a0..16e3dad5f46e9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/crawler/utils.ts @@ -22,6 +22,8 @@ import { CrawlEvent, CrawlConfigFromServer, CrawlConfig, + CrawlRequestWithDetailsFromServer, + CrawlRequestWithDetails, } from './types'; export function crawlerDomainServerToClient(payload: CrawlerDomainFromServer): CrawlerDomain { @@ -91,15 +93,51 @@ export function crawlConfigServerToClient(crawlConfig: CrawlConfigFromServer): C } export function crawlEventServerToClient(event: CrawlEventFromServer): CrawlEvent { - const clientCrawlRequest = crawlRequestServerToClient(event as CrawlRequestFromServer); - - const { stage, type, crawl_config: crawlConfig } = event; + const { + id, + stage, + status, + created_at: createdAt, + began_at: beganAt, + completed_at: completedAt, + type, + crawl_config: crawlConfig, + } = event; return { - ...clientCrawlRequest, + id, stage, + status, + createdAt, + beganAt, + completedAt, + type, + crawlConfig: crawlConfigServerToClient(crawlConfig), + }; +} + +export function crawlRequestWithDetailsServerToClient( + event: CrawlRequestWithDetailsFromServer +): CrawlRequestWithDetails { + const { + id, + status, + created_at: createdAt, + began_at: beganAt, + completed_at: completedAt, + type, + crawl_config: crawlConfig, + } = event; + + return { + id, + status, + createdAt, + beganAt, + completedAt, type, crawlConfig: crawlConfigServerToClient(crawlConfig), + // TODO add fields like stats }; } From 5041ab66d13d573516444215daee66b6a5faa22c Mon Sep 17 00:00:00 2001 From: Jonathan Budzenski Date: Wed, 24 Nov 2021 17:30:03 -0600 Subject: [PATCH 09/46] [build] Support pushing cloud images (#118071) * [build] Support pushing cloud images * read earlier * fix types * feedback * fix exit code when not pushing * suffix with pr number * Revert "suffix with pr number" This reverts commit 4a687d1d6e339e698ecc53b28455509e70e4264d. * default to null Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .buildkite/scripts/build_kibana.sh | 8 +++++- .buildkite/scripts/lifecycle/pre_command.sh | 6 ++++ src/dev/build/args.test.ts | 14 ++++++++++ src/dev/build/args.ts | 5 ++++ src/dev/build/build_distributables.ts | 2 ++ src/dev/build/lib/build.test.ts | 2 ++ src/dev/build/lib/config.test.ts | 2 ++ src/dev/build/lib/config.ts | 28 ++++++++++++++++++- src/dev/build/lib/runner.test.ts | 2 ++ .../nodejs/download_node_builds_task.test.ts | 2 ++ .../nodejs/extract_node_builds_task.test.ts | 2 ++ .../verify_existing_node_builds_task.test.ts | 2 ++ .../tasks/os_packages/docker_generator/run.ts | 5 ++++ .../docker_generator/template_context.ts | 2 ++ .../templates/build_docker_sh.template.ts | 10 +++++-- 15 files changed, 88 insertions(+), 4 deletions(-) diff --git a/.buildkite/scripts/build_kibana.sh b/.buildkite/scripts/build_kibana.sh index 84d66a30ea213..e811af224e9af 100755 --- a/.buildkite/scripts/build_kibana.sh +++ b/.buildkite/scripts/build_kibana.sh @@ -12,13 +12,19 @@ else fi if [[ "${GITHUB_PR_LABELS:-}" == *"ci:deploy-cloud"* ]]; then - echo "--- Build Kibana Cloud Distribution" + echo "--- Build and push Kibana Cloud Distribution" + + echo "$KIBANA_DOCKER_PASSWORD" | docker login -u "$KIBANA_DOCKER_USERNAME" --password-stdin docker.elastic.co + trap 'docker logout docker.elastic.co' EXIT + node scripts/build \ --skip-initialize \ --skip-generic-folders \ --skip-platform-folders \ --skip-archives \ --docker-images \ + --docker-tag-qualifier="$GIT_COMMIT" \ + --docker-push \ --skip-docker-ubi \ --skip-docker-centos \ --skip-docker-contexts diff --git a/.buildkite/scripts/lifecycle/pre_command.sh b/.buildkite/scripts/lifecycle/pre_command.sh index 7016cf41d79e9..1eeb47f3a2472 100755 --- a/.buildkite/scripts/lifecycle/pre_command.sh +++ b/.buildkite/scripts/lifecycle/pre_command.sh @@ -72,6 +72,12 @@ export GITHUB_TOKEN KIBANA_CI_REPORTER_KEY=$(retry 5 5 vault read -field=value secret/kibana-issues/dev/kibanamachine-reporter) export KIBANA_CI_REPORTER_KEY +KIBANA_DOCKER_USERNAME="$(retry 5 5 vault read -field=username secret/kibana-issues/dev/container-registry)" +export KIBANA_DOCKER_USERNAME + +KIBANA_DOCKER_PASSWORD="$(retry 5 5 vault read -field=password secret/kibana-issues/dev/container-registry)" +export KIBANA_DOCKER_PASSWORD + # Setup Failed Test Reporter Elasticsearch credentials { TEST_FAILURES_ES_CLOUD_ID=$(retry 5 5 vault read -field=cloud_id secret/kibana-issues/dev/failed_tests_reporter_es) diff --git a/src/dev/build/args.test.ts b/src/dev/build/args.test.ts index 9ac4c5ec3b236..354de9fee60d7 100644 --- a/src/dev/build/args.test.ts +++ b/src/dev/build/args.test.ts @@ -36,6 +36,8 @@ it('build default and oss dist for current platform, without packages, by defaul "createGenericFolders": true, "createPlatformFolders": true, "createRpmPackage": false, + "dockerPush": false, + "dockerTagQualifier": null, "downloadCloudDependencies": true, "downloadFreshNode": true, "initialize": true, @@ -64,6 +66,8 @@ it('builds packages if --all-platforms is passed', () => { "createGenericFolders": true, "createPlatformFolders": true, "createRpmPackage": true, + "dockerPush": false, + "dockerTagQualifier": null, "downloadCloudDependencies": true, "downloadFreshNode": true, "initialize": true, @@ -92,6 +96,8 @@ it('limits packages if --rpm passed with --all-platforms', () => { "createGenericFolders": true, "createPlatformFolders": true, "createRpmPackage": true, + "dockerPush": false, + "dockerTagQualifier": null, "downloadCloudDependencies": true, "downloadFreshNode": true, "initialize": true, @@ -120,6 +126,8 @@ it('limits packages if --deb passed with --all-platforms', () => { "createGenericFolders": true, "createPlatformFolders": true, "createRpmPackage": false, + "dockerPush": false, + "dockerTagQualifier": null, "downloadCloudDependencies": true, "downloadFreshNode": true, "initialize": true, @@ -149,6 +157,8 @@ it('limits packages if --docker passed with --all-platforms', () => { "createGenericFolders": true, "createPlatformFolders": true, "createRpmPackage": false, + "dockerPush": false, + "dockerTagQualifier": null, "downloadCloudDependencies": true, "downloadFreshNode": true, "initialize": true, @@ -185,6 +195,8 @@ it('limits packages if --docker passed with --skip-docker-ubi and --all-platform "createGenericFolders": true, "createPlatformFolders": true, "createRpmPackage": false, + "dockerPush": false, + "dockerTagQualifier": null, "downloadCloudDependencies": true, "downloadFreshNode": true, "initialize": true, @@ -214,6 +226,8 @@ it('limits packages if --all-platforms passed with --skip-docker-centos', () => "createGenericFolders": true, "createPlatformFolders": true, "createRpmPackage": true, + "dockerPush": false, + "dockerTagQualifier": null, "downloadCloudDependencies": true, "downloadFreshNode": true, "initialize": true, diff --git a/src/dev/build/args.ts b/src/dev/build/args.ts index e7fca2a2a3d7b..78f097b595c40 100644 --- a/src/dev/build/args.ts +++ b/src/dev/build/args.ts @@ -23,6 +23,7 @@ export function readCliArgs(argv: string[]) { 'rpm', 'deb', 'docker-images', + 'docker-push', 'skip-docker-contexts', 'skip-docker-ubi', 'skip-docker-centos', @@ -50,6 +51,8 @@ export function readCliArgs(argv: string[]) { rpm: null, deb: null, 'docker-images': null, + 'docker-push': false, + 'docker-tag-qualifier': null, 'version-qualifier': '', }, unknown: (flag) => { @@ -95,6 +98,8 @@ export function readCliArgs(argv: string[]) { const buildOptions: BuildOptions = { isRelease: Boolean(flags.release), versionQualifier: flags['version-qualifier'], + dockerPush: Boolean(flags['docker-push']), + dockerTagQualifier: flags['docker-tag-qualifier'], initialize: !Boolean(flags['skip-initialize']), downloadFreshNode: !Boolean(flags['skip-node-download']), downloadCloudDependencies: !Boolean(flags['skip-cloud-dependencies-download']), diff --git a/src/dev/build/build_distributables.ts b/src/dev/build/build_distributables.ts index 8912b05a16943..a5ed81c15c9b1 100644 --- a/src/dev/build/build_distributables.ts +++ b/src/dev/build/build_distributables.ts @@ -13,6 +13,8 @@ import * as Tasks from './tasks'; export interface BuildOptions { isRelease: boolean; + dockerPush: boolean; + dockerTagQualifier: string | null; downloadFreshNode: boolean; downloadCloudDependencies: boolean; initialize: boolean; diff --git a/src/dev/build/lib/build.test.ts b/src/dev/build/lib/build.test.ts index f92a91e2b7221..8ea2a20d83960 100644 --- a/src/dev/build/lib/build.test.ts +++ b/src/dev/build/lib/build.test.ts @@ -32,6 +32,8 @@ const config = new Config( buildSha: 'abcd1234', buildVersion: '8.0.0', }, + '', + false, true ); diff --git a/src/dev/build/lib/config.test.ts b/src/dev/build/lib/config.test.ts index b2afe3337230d..3f90c8738d8e2 100644 --- a/src/dev/build/lib/config.test.ts +++ b/src/dev/build/lib/config.test.ts @@ -29,6 +29,8 @@ const setup = async ({ targetAllPlatforms = true }: { targetAllPlatforms?: boole return await Config.create({ isRelease: true, targetAllPlatforms, + dockerPush: false, + dockerTagQualifier: '', }); }; diff --git a/src/dev/build/lib/config.ts b/src/dev/build/lib/config.ts index 33b98e1b94a04..650af04dfd54b 100644 --- a/src/dev/build/lib/config.ts +++ b/src/dev/build/lib/config.ts @@ -17,6 +17,8 @@ interface Options { isRelease: boolean; targetAllPlatforms: boolean; versionQualifier?: string; + dockerTagQualifier: string | null; + dockerPush: boolean; } interface Package { @@ -29,7 +31,13 @@ interface Package { } export class Config { - static async create({ isRelease, targetAllPlatforms, versionQualifier }: Options) { + static async create({ + isRelease, + targetAllPlatforms, + versionQualifier, + dockerTagQualifier, + dockerPush, + }: Options) { const pkgPath = resolve(__dirname, '../../../../package.json'); const pkg: Package = loadJsonFile.sync(pkgPath); @@ -43,6 +51,8 @@ export class Config { versionQualifier, pkg, }), + dockerTagQualifier, + dockerPush, isRelease ); } @@ -53,6 +63,8 @@ export class Config { private readonly nodeVersion: string, private readonly repoRoot: string, private readonly versionInfo: VersionInfo, + private readonly dockerTagQualifier: string | null, + private readonly dockerPush: boolean, public readonly isRelease: boolean ) {} @@ -70,6 +82,20 @@ export class Config { return this.nodeVersion; } + /** + * Get the docker tag qualifier + */ + getDockerTagQualfiier() { + return this.dockerTagQualifier; + } + + /** + * Get docker push + */ + getDockerPush() { + return this.dockerPush; + } + /** * Convert an absolute path to a relative path, based from the repo */ diff --git a/src/dev/build/lib/runner.test.ts b/src/dev/build/lib/runner.test.ts index 2a08da2797a9d..7c49c35446833 100644 --- a/src/dev/build/lib/runner.test.ts +++ b/src/dev/build/lib/runner.test.ts @@ -50,6 +50,8 @@ const setup = async () => { isRelease: true, targetAllPlatforms: true, versionQualifier: '-SNAPSHOT', + dockerPush: false, + dockerTagQualifier: '', }); const run = createRunner({ diff --git a/src/dev/build/tasks/nodejs/download_node_builds_task.test.ts b/src/dev/build/tasks/nodejs/download_node_builds_task.test.ts index ec82caac273cf..3410e3efafe6b 100644 --- a/src/dev/build/tasks/nodejs/download_node_builds_task.test.ts +++ b/src/dev/build/tasks/nodejs/download_node_builds_task.test.ts @@ -39,6 +39,8 @@ async function setup({ failOnUrl }: { failOnUrl?: string } = {}) { const config = await Config.create({ isRelease: true, targetAllPlatforms: true, + dockerPush: false, + dockerTagQualifier: '', }); getNodeDownloadInfo.mockImplementation((_: Config, platform: Platform) => { diff --git a/src/dev/build/tasks/nodejs/extract_node_builds_task.test.ts b/src/dev/build/tasks/nodejs/extract_node_builds_task.test.ts index 9f869b99c18ae..fb0891c24f3b0 100644 --- a/src/dev/build/tasks/nodejs/extract_node_builds_task.test.ts +++ b/src/dev/build/tasks/nodejs/extract_node_builds_task.test.ts @@ -43,6 +43,8 @@ async function setup() { const config = await Config.create({ isRelease: true, targetAllPlatforms: true, + dockerPush: false, + dockerTagQualifier: '', }); return { config }; diff --git a/src/dev/build/tasks/nodejs/verify_existing_node_builds_task.test.ts b/src/dev/build/tasks/nodejs/verify_existing_node_builds_task.test.ts index c636db145694c..3a71a2b06fe91 100644 --- a/src/dev/build/tasks/nodejs/verify_existing_node_builds_task.test.ts +++ b/src/dev/build/tasks/nodejs/verify_existing_node_builds_task.test.ts @@ -48,6 +48,8 @@ async function setup(actualShaSums?: Record) { const config = await Config.create({ isRelease: true, targetAllPlatforms: true, + dockerPush: false, + dockerTagQualifier: '', }); getNodeShasums.mockReturnValue( diff --git a/src/dev/build/tasks/os_packages/docker_generator/run.ts b/src/dev/build/tasks/os_packages/docker_generator/run.ts index 715516c3807ec..6a192baed3fa3 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/run.ts +++ b/src/dev/build/tasks/os_packages/docker_generator/run.ts @@ -71,6 +71,9 @@ export async function runDockerGenerator( : []), ]; + const dockerPush = config.getDockerPush(); + const dockerTagQualifier = config.getDockerTagQualfiier(); + const scope: TemplateContext = { artifactPrefix, artifactTarball, @@ -82,6 +85,8 @@ export async function runDockerGenerator( imageTag, dockerBuildDir, dockerTargetFilename, + dockerPush, + dockerTagQualifier, baseOSImage, dockerBuildDate, ubi: flags.ubi, diff --git a/src/dev/build/tasks/os_packages/docker_generator/template_context.ts b/src/dev/build/tasks/os_packages/docker_generator/template_context.ts index 075a3a8808e73..143fcf16ace56 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/template_context.ts +++ b/src/dev/build/tasks/os_packages/docker_generator/template_context.ts @@ -14,6 +14,8 @@ export interface TemplateContext { version: string; license: string; artifactsDir: string; + dockerPush: boolean; + dockerTagQualifier: string | null; imageTag: string; dockerBuildDir: string; dockerTargetFilename: string; diff --git a/src/dev/build/tasks/os_packages/docker_generator/templates/build_docker_sh.template.ts b/src/dev/build/tasks/os_packages/docker_generator/templates/build_docker_sh.template.ts index 05b9b4d100c53..de26705566585 100644 --- a/src/dev/build/tasks/os_packages/docker_generator/templates/build_docker_sh.template.ts +++ b/src/dev/build/tasks/os_packages/docker_generator/templates/build_docker_sh.template.ts @@ -13,11 +13,16 @@ import { TemplateContext } from '../template_context'; function generator({ imageTag, imageFlavor, + dockerPush, + dockerTagQualifier, version, dockerTargetFilename, baseOSImage, architecture, }: TemplateContext) { + const dockerTargetName = `${imageTag}${imageFlavor}:${version}${ + dockerTagQualifier ? '-' + dockerTagQualifier : '' + }`; return dedent(` #!/usr/bin/env bash # @@ -54,10 +59,11 @@ function generator({ retry_docker_pull ${baseOSImage} echo "Building: kibana${imageFlavor}-docker"; \\ - docker build -t ${imageTag}${imageFlavor}:${version} -f Dockerfile . || exit 1; + docker build -t ${dockerTargetName} -f Dockerfile . || exit 1; - docker save ${imageTag}${imageFlavor}:${version} | gzip -c > ${dockerTargetFilename} + docker save ${dockerTargetName} | gzip -c > ${dockerTargetFilename} + ${dockerPush} && docker image push ${dockerTargetName} exit 0 `); } From 3358874443fb984381ff760b7ae2003b62570724 Mon Sep 17 00:00:00 2001 From: Spencer Date: Wed, 24 Nov 2021 15:42:55 -0800 Subject: [PATCH 10/46] [build] automatically retry all downloads (#119642) --- src/dev/build/lib/download.ts | 179 +++++++--- .../lib/integration_tests/download.test.ts | 322 +++++++++++------- .../tasks/download_cloud_dependencies.ts | 14 +- .../nodejs/download_node_builds_task.test.ts | 16 +- .../tasks/nodejs/download_node_builds_task.ts | 6 +- .../build/tasks/nodejs/node_shasums.test.ts | 9 +- src/dev/build/tasks/nodejs/node_shasums.ts | 25 +- .../build/tasks/patch_native_modules_task.ts | 16 +- 8 files changed, 374 insertions(+), 213 deletions(-) diff --git a/src/dev/build/lib/download.ts b/src/dev/build/lib/download.ts index 9293854bfb2bd..c67407095b37e 100644 --- a/src/dev/build/lib/download.ts +++ b/src/dev/build/lib/download.ts @@ -8,11 +8,12 @@ import { openSync, writeSync, unlinkSync, closeSync } from 'fs'; import { dirname } from 'path'; +import { setTimeout } from 'timers/promises'; import chalk from 'chalk'; import { createHash } from 'crypto'; import Axios from 'axios'; -import { ToolingLog } from '@kbn/dev-utils'; +import { ToolingLog, isAxiosResponseError } from '@kbn/dev-utils'; // https://github.com/axios/axios/tree/ffea03453f77a8176c51554d5f6c3c6829294649/lib/adapters // @ts-expect-error untyped internal module used to prevent axios from using xhr adapter in tests @@ -30,81 +31,151 @@ function tryUnlink(path: string) { } } -interface DownloadOptions { +interface DownloadToDiskOptions { log: ToolingLog; url: string; destination: string; shaChecksum: string; shaAlgorithm: string; - retries?: number; + maxAttempts?: number; + retryDelaySecMultiplier?: number; } -export async function download(options: DownloadOptions): Promise { - const { log, url, destination, shaChecksum, shaAlgorithm, retries = 0 } = options; - +export async function downloadToDisk({ + log, + url, + destination, + shaChecksum, + shaAlgorithm, + maxAttempts = 1, + retryDelaySecMultiplier = 5, +}: DownloadToDiskOptions) { if (!shaChecksum) { throw new Error(`${shaAlgorithm} checksum of ${url} not provided, refusing to download.`); } - // mkdirp and open file outside of try/catch, we don't retry for those errors - await mkdirp(dirname(destination)); - const fileHandle = openSync(destination, 'w'); + if (maxAttempts < 1) { + throw new Error(`[maxAttempts=${maxAttempts}] must be >= 1`); + } - let error; - try { - log.debug(`Attempting download of ${url}`, chalk.dim(shaAlgorithm)); + let attempt = 0; + while (true) { + attempt += 1; - const response = await Axios.request({ - url, - responseType: 'stream', - adapter: AxiosHttpAdapter, - }); + // mkdirp and open file outside of try/catch, we don't retry for those errors + await mkdirp(dirname(destination)); + const fileHandle = openSync(destination, 'w'); - if (response.status !== 200) { - throw new Error(`Unexpected status code ${response.status} when downloading ${url}`); - } + let error; + try { + log.debug( + `[${attempt}/${maxAttempts}] Attempting download of ${url}`, + chalk.dim(shaAlgorithm) + ); - const hash = createHash(shaAlgorithm); - await new Promise((resolve, reject) => { - response.data.on('data', (chunk: Buffer) => { - hash.update(chunk); - writeSync(fileHandle, chunk); + const response = await Axios.request({ + url, + responseType: 'stream', + adapter: AxiosHttpAdapter, }); - response.data.on('error', reject); - response.data.on('end', resolve); - }); + if (response.status !== 200) { + throw new Error(`Unexpected status code ${response.status} when downloading ${url}`); + } - const downloadedSha = hash.digest('hex'); - if (downloadedSha !== shaChecksum) { - throw new Error( - `Downloaded checksum ${downloadedSha} does not match the expected ${shaAlgorithm} checksum.` - ); + const hash = createHash(shaAlgorithm); + await new Promise((resolve, reject) => { + response.data.on('data', (chunk: Buffer) => { + hash.update(chunk); + writeSync(fileHandle, chunk); + }); + + response.data.on('error', reject); + response.data.on('end', resolve); + }); + + const downloadedSha = hash.digest('hex'); + if (downloadedSha !== shaChecksum) { + throw new Error( + `Downloaded checksum ${downloadedSha} does not match the expected ${shaAlgorithm} checksum.` + ); + } + } catch (_error) { + error = _error; + } finally { + closeSync(fileHandle); } - } catch (_error) { - error = _error; - } finally { - closeSync(fileHandle); - } - if (!error) { - log.debug(`Downloaded ${url} and verified checksum`); - return; - } + if (!error) { + log.debug(`Downloaded ${url} and verified checksum`); + return; + } - log.debug(`Download failed: ${error.message}`); + log.debug(`Download failed: ${error.message}`); - // cleanup downloaded data and log error - log.debug(`Deleting downloaded data at ${destination}`); - tryUnlink(destination); + // cleanup downloaded data and log error + log.debug(`Deleting downloaded data at ${destination}`); + tryUnlink(destination); - // retry if we have retries left - if (retries > 0) { - log.debug(`Retrying - ${retries} attempt remaining`); - return await download({ - ...options, - retries: retries - 1, - }); + // retry if we have retries left + if (attempt < maxAttempts) { + const sec = attempt * retryDelaySecMultiplier; + log.info(`Retrying in ${sec} seconds`); + await setTimeout(sec * 1000); + continue; + } + + throw error; } +} + +interface DownloadToStringOptions { + log: ToolingLog; + url: string; + expectStatus?: number; + maxAttempts?: number; + retryDelaySecMultiplier?: number; +} +export async function downloadToString({ + log, + url, + expectStatus, + maxAttempts = 3, + retryDelaySecMultiplier = 5, +}: DownloadToStringOptions) { + let attempt = 0; + while (true) { + try { + attempt += 1; + log.debug(`[${attempt}/${maxAttempts}] Attempting download to string of [${url}]`); + + const resp = await Axios.request({ + url, + method: 'GET', + adapter: AxiosHttpAdapter, + responseType: 'text', + validateStatus: !expectStatus ? undefined : (status) => status === expectStatus, + }); + + log.success(`Downloaded [${url}]`); + return resp.data; + } catch (error) { + log.warning(`Download failed: ${error.message}`); + if (isAxiosResponseError(error)) { + log.debug( + `[${error.response.status}/${error.response.statusText}] response: ${error.response.data}` + ); + } else { + log.debug('received no response'); + } + + if ((maxAttempts ?? 3) > attempt) { + const sec = (retryDelaySecMultiplier ?? 5) * attempt; + log.info(`Retrying in ${sec} seconds`); + await setTimeout(sec * 1000); + continue; + } - throw error; + throw error; + } + } } diff --git a/src/dev/build/lib/integration_tests/download.test.ts b/src/dev/build/lib/integration_tests/download.test.ts index 173682ef05d71..7f885fdc02d28 100644 --- a/src/dev/build/lib/integration_tests/download.test.ts +++ b/src/dev/build/lib/integration_tests/download.test.ts @@ -13,14 +13,25 @@ import { readFileSync } from 'fs'; import del from 'del'; import { CI_PARALLEL_PROCESS_PREFIX } from '@kbn/test'; -import { ToolingLog } from '@kbn/dev-utils'; +import { + ToolingLog, + ToolingLogCollectingWriter, + createStripAnsiSerializer, + createReplaceSerializer, +} from '@kbn/dev-utils'; import { mkdirp } from '../fs'; -import { download } from '../download'; +import { downloadToDisk, downloadToString } from '../download'; const TMP_DIR = join(tmpdir(), CI_PARALLEL_PROCESS_PREFIX, 'download-js-test-tmp-dir'); const TMP_DESTINATION = join(TMP_DIR, '__tmp_download_js_test_file__'); +expect.addSnapshotSerializer(createStripAnsiSerializer()); +expect.addSnapshotSerializer(createReplaceSerializer(TMP_DIR, 'TMP_DIR')); +expect.addSnapshotSerializer( + createReplaceSerializer(/http:\/\/localhost:\d+\//g, 'TEST_SERVER_URL') +); + beforeEach(async () => { await del(TMP_DIR, { force: true }); await mkdirp(TMP_DIR); @@ -31,12 +42,11 @@ afterEach(async () => { await del(TMP_DIR, { force: true }); }); -const onLogLine = jest.fn(); -const log = new ToolingLog({ - level: 'verbose', - writeTo: { - write: onLogLine, - }, +const logWritter = new ToolingLogCollectingWriter('verbose'); +const log = new ToolingLog(); +log.setWriters([logWritter]); +afterEach(() => { + logWritter.messages.length = 0; }); type Handler = (req: IncomingMessage, res: ServerResponse) => void; @@ -54,18 +64,14 @@ const sendErrorHandler: Handler = (req, res) => { }; let serverUrl: string; -let nextHandler: Handler | null = null; +const handlers: Handler[] = []; const server = createServer((req, res) => { - if (!nextHandler) { - nextHandler = sendErrorHandler; - } - - const handler = nextHandler; - nextHandler = null; - handler(req, res); + (handlers.shift() ?? sendErrorHandler)(req, res); }); -afterEach(() => (nextHandler = null)); +afterEach(() => { + handlers.length = 0; +}); beforeAll(async () => { await Promise.race([ @@ -87,136 +93,224 @@ afterAll(async () => { server.close(); }); -it('downloads from URL and checks that content matches sha256', async () => { - nextHandler = createSendHandler('foo'); - await download({ - log, - url: serverUrl, - destination: TMP_DESTINATION, - shaChecksum: FOO_SHA256, - shaAlgorithm: 'sha256', - }); - expect(readFileSync(TMP_DESTINATION, 'utf8')).toBe('foo'); -}); - -it('rejects and deletes destination if sha256 does not match', async () => { - nextHandler = createSendHandler('foo'); - - try { - await download({ +describe('downloadToDisk', () => { + it('downloads from URL and checks that content matches sha256', async () => { + handlers.push(createSendHandler('foo')); + await downloadToDisk({ log, url: serverUrl, destination: TMP_DESTINATION, - shaChecksum: 'bar', + shaChecksum: FOO_SHA256, shaAlgorithm: 'sha256', }); - throw new Error('Expected download() to reject'); - } catch (error) { - expect(error).toHaveProperty( - 'message', - expect.stringContaining('does not match the expected sha256 checksum') - ); - } - - try { - readFileSync(TMP_DESTINATION); - throw new Error('Expected download to be deleted'); - } catch (error) { - expect(error).toHaveProperty('code', 'ENOENT'); - } -}); + expect(readFileSync(TMP_DESTINATION, 'utf8')).toBe('foo'); + }); -describe('reties download retries: number of times', () => { - it('resolves if retries = 1 and first attempt fails', async () => { - let reqCount = 0; - nextHandler = function sequenceHandler(req, res) { - switch (++reqCount) { - case 1: - nextHandler = sequenceHandler; - return sendErrorHandler(req, res); - default: - return createSendHandler('foo')(req, res); - } - }; + it('rejects and deletes destination if sha256 does not match', async () => { + handlers.push(createSendHandler('foo')); - await download({ + const promise = downloadToDisk({ log, url: serverUrl, destination: TMP_DESTINATION, - shaChecksum: FOO_SHA256, + shaChecksum: 'bar', shaAlgorithm: 'sha256', - retries: 2, }); + await expect(promise).rejects.toMatchInlineSnapshot( + `[Error: Downloaded checksum 2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae does not match the expected sha256 checksum.]` + ); - expect(readFileSync(TMP_DESTINATION, 'utf8')).toBe('foo'); + try { + readFileSync(TMP_DESTINATION); + throw new Error('Expected download to be deleted'); + } catch (error) { + expect(error).toHaveProperty('code', 'ENOENT'); + } }); - it('resolves if first fails, second is bad shasum, but third succeeds', async () => { - let reqCount = 0; - nextHandler = function sequenceHandler(req, res) { - switch (++reqCount) { - case 1: - nextHandler = sequenceHandler; - return sendErrorHandler(req, res); - case 2: - nextHandler = sequenceHandler; - return createSendHandler('bar')(req, res); - default: - return createSendHandler('foo')(req, res); - } - }; + describe('reties download retries: number of times', () => { + it('resolves if retries = 1 and first attempt fails', async () => { + handlers.push(sendErrorHandler, createSendHandler('foo')); - await download({ - log, - url: serverUrl, - destination: TMP_DESTINATION, - shaChecksum: FOO_SHA256, - shaAlgorithm: 'sha256', - retries: 2, + await downloadToDisk({ + log, + url: serverUrl, + destination: TMP_DESTINATION, + shaChecksum: FOO_SHA256, + shaAlgorithm: 'sha256', + maxAttempts: 2, + retryDelaySecMultiplier: 0.1, + }); + + expect(readFileSync(TMP_DESTINATION, 'utf8')).toBe('foo'); + expect(logWritter.messages).toMatchInlineSnapshot(` + Array [ + " debg [1/2] Attempting download of TEST_SERVER_URL sha256", + " debg Download failed: Request failed with status code 500", + " debg Deleting downloaded data at TMP_DIR/__tmp_download_js_test_file__", + " info Retrying in 0.1 seconds", + " debg [2/2] Attempting download of TEST_SERVER_URL sha256", + " debg Downloaded TEST_SERVER_URL and verified checksum", + ] + `); }); - }); - it('makes 6 requests if `retries: 5` and all failed', async () => { - let reqCount = 0; - nextHandler = function sequenceHandler(req, res) { - reqCount += 1; - nextHandler = sequenceHandler; - sendErrorHandler(req, res); - }; + it('resolves if first fails, second is bad shasum, but third succeeds', async () => { + handlers.push(sendErrorHandler, createSendHandler('bar'), createSendHandler('foo')); - try { - await download({ + await downloadToDisk({ log, url: serverUrl, destination: TMP_DESTINATION, shaChecksum: FOO_SHA256, shaAlgorithm: 'sha256', - retries: 5, + maxAttempts: 3, + retryDelaySecMultiplier: 0.1, }); - throw new Error('Expected download() to reject'); - } catch (error) { - expect(error).toHaveProperty( - 'message', - expect.stringContaining('Request failed with status code 500') + + expect(logWritter.messages).toMatchInlineSnapshot(` + Array [ + " debg [1/3] Attempting download of TEST_SERVER_URL sha256", + " debg Download failed: Request failed with status code 500", + " debg Deleting downloaded data at TMP_DIR/__tmp_download_js_test_file__", + " info Retrying in 0.1 seconds", + " debg [2/3] Attempting download of TEST_SERVER_URL sha256", + " debg Download failed: Downloaded checksum fcde2b2edba56bf408601fb721fe9b5c338d10ee429ea04fae5511b68fbf8fb9 does not match the expected sha256 checksum.", + " debg Deleting downloaded data at TMP_DIR/__tmp_download_js_test_file__", + " info Retrying in 0.2 seconds", + " debg [3/3] Attempting download of TEST_SERVER_URL sha256", + " debg Downloaded TEST_SERVER_URL and verified checksum", + ] + `); + }); + + it('makes 5 requests if `maxAttempts: 5` and all failed', async () => { + const promise = downloadToDisk({ + log, + url: serverUrl, + destination: TMP_DESTINATION, + shaChecksum: FOO_SHA256, + shaAlgorithm: 'sha256', + maxAttempts: 5, + retryDelaySecMultiplier: 0.1, + }); + await expect(promise).rejects.toMatchInlineSnapshot( + `[Error: Request failed with status code 500]` ); - expect(reqCount).toBe(6); - } + expect(logWritter.messages).toMatchInlineSnapshot(` + Array [ + " debg [1/5] Attempting download of TEST_SERVER_URL sha256", + " debg Download failed: Request failed with status code 500", + " debg Deleting downloaded data at TMP_DIR/__tmp_download_js_test_file__", + " info Retrying in 0.1 seconds", + " debg [2/5] Attempting download of TEST_SERVER_URL sha256", + " debg Download failed: Request failed with status code 500", + " debg Deleting downloaded data at TMP_DIR/__tmp_download_js_test_file__", + " info Retrying in 0.2 seconds", + " debg [3/5] Attempting download of TEST_SERVER_URL sha256", + " debg Download failed: Request failed with status code 500", + " debg Deleting downloaded data at TMP_DIR/__tmp_download_js_test_file__", + " info Retrying in 0.30000000000000004 seconds", + " debg [4/5] Attempting download of TEST_SERVER_URL sha256", + " debg Download failed: Request failed with status code 500", + " debg Deleting downloaded data at TMP_DIR/__tmp_download_js_test_file__", + " info Retrying in 0.4 seconds", + " debg [5/5] Attempting download of TEST_SERVER_URL sha256", + " debg Download failed: Request failed with status code 500", + " debg Deleting downloaded data at TMP_DIR/__tmp_download_js_test_file__", + ] + `); + }); }); -}); -describe('sha256 option not supplied', () => { - it('refuses to download', async () => { - try { + describe('sha256 option not supplied', () => { + it('refuses to download', async () => { // @ts-expect-error missing sha256 param is intentional - await download({ + const promise = downloadToDisk({ log, url: 'http://google.com', destination: TMP_DESTINATION, }); - throw new Error('expected download() to reject'); - } catch (error) { - expect(error).toHaveProperty('message', expect.stringContaining('refusing to download')); - } + await expect(promise).rejects.toMatchInlineSnapshot( + `[Error: undefined checksum of http://google.com not provided, refusing to download.]` + ); + }); + }); +}); + +describe('downloadToString', () => { + it('returns a string from the server', async () => { + handlers.push(createSendHandler('foo bar')); + + const result = await downloadToString({ log, url: serverUrl }); + expect(result).toBe('foo bar'); + expect(logWritter.messages).toMatchInlineSnapshot(` + Array [ + " debg [1/3] Attempting download to string of [TEST_SERVER_URL]", + " succ Downloaded [TEST_SERVER_URL]", + ] + `); + }); + + it(`throws when expectStatus doesn't match`, async () => { + handlers.push(createSendHandler('foo')); + + const promise = downloadToString({ + log, + url: serverUrl, + expectStatus: 201, + maxAttempts: 1, + }); + await expect(promise).rejects.toMatchInlineSnapshot( + `[Error: Request failed with status code 200]` + ); + expect(logWritter.messages).toMatchInlineSnapshot(` + Array [ + " debg [1/1] Attempting download to string of [TEST_SERVER_URL]", + " warn Download failed: Request failed with status code 200", + " debg [200/OK] response: foo", + ] + `); + }); + + it(`retries when expectStatus doesn't match`, async () => { + handlers.push( + (_, res) => { + res.statusCode = 500; + res.end('something went wrong'); + }, + (_, res) => { + res.statusCode = 404; + res.end('not found'); + }, + (_, res) => { + res.statusCode = 201; + res.end('bar'); + } + ); + + const result = await downloadToString({ + log, + url: serverUrl, + expectStatus: 201, + retryDelaySecMultiplier: 0.1, + }); + + expect(result).toBe('bar'); + expect(logWritter.messages).toMatchInlineSnapshot(` + Array [ + " debg [1/3] Attempting download to string of [TEST_SERVER_URL]", + " warn Download failed: Request failed with status code 500", + " debg [500/Internal Server Error] response: something went wrong", + " info Retrying in 0.1 seconds", + " debg [2/3] Attempting download to string of [TEST_SERVER_URL]", + " warn Download failed: Request failed with status code 404", + " debg [404/Not Found] response: not found", + " info Retrying in 0.2 seconds", + " debg [3/3] Attempting download to string of [TEST_SERVER_URL]", + " succ Downloaded [TEST_SERVER_URL]", + ] + `); }); }); diff --git a/src/dev/build/tasks/download_cloud_dependencies.ts b/src/dev/build/tasks/download_cloud_dependencies.ts index 5b5ba2a9ff625..be1767769cff0 100644 --- a/src/dev/build/tasks/download_cloud_dependencies.ts +++ b/src/dev/build/tasks/download_cloud_dependencies.ts @@ -6,10 +6,9 @@ * Side Public License, v 1. */ -import axios from 'axios'; import Path from 'path'; import del from 'del'; -import { Task, download } from '../lib'; +import { Task, downloadToDisk, downloadToString } from '../lib'; export const DownloadCloudDependencies: Task = { description: 'Downloading cloud dependencies', @@ -20,18 +19,15 @@ export const DownloadCloudDependencies: Task = { const version = config.getBuildVersion(); const architecture = process.arch === 'arm64' ? 'arm64' : 'x86_64'; const url = `https://${subdomain}-no-kpi.elastic.co/downloads/beats/${beat}/${beat}-${version}-linux-${architecture}.tar.gz`; - const checksumRes = await axios.get(url + '.sha512'); - if (checksumRes.status !== 200) { - throw new Error(`Unexpected status code ${checksumRes.status} when downloading ${url}`); - } + const checksum = await downloadToString({ log, url: url + '.sha512', expectStatus: 200 }); const destination = config.resolveFromRepo('.beats', Path.basename(url)); - return download({ + return downloadToDisk({ log, url, destination, - shaChecksum: checksumRes.data.split(' ')[0], + shaChecksum: checksum.split(' ')[0], shaAlgorithm: 'sha512', - retries: 3, + maxAttempts: 3, }); }; diff --git a/src/dev/build/tasks/nodejs/download_node_builds_task.test.ts b/src/dev/build/tasks/nodejs/download_node_builds_task.test.ts index 3410e3efafe6b..b1309bd05c603 100644 --- a/src/dev/build/tasks/nodejs/download_node_builds_task.test.ts +++ b/src/dev/build/tasks/nodejs/download_node_builds_task.test.ts @@ -24,7 +24,7 @@ expect.addSnapshotSerializer(createAnyInstanceSerializer(ToolingLog)); const { getNodeDownloadInfo } = jest.requireMock('./node_download_info'); const { getNodeShasums } = jest.requireMock('./node_shasums'); -const { download } = jest.requireMock('../../lib/download'); +const { downloadToDisk } = jest.requireMock('../../lib/download'); const log = new ToolingLog(); const testWriter = new ToolingLogCollectingWriter(); @@ -57,7 +57,7 @@ async function setup({ failOnUrl }: { failOnUrl?: string } = {}) { 'win32:downloadName': 'win32:sha256', }); - download.mockImplementation(({ url }: any) => { + downloadToDisk.mockImplementation(({ url }: any) => { if (url === failOnUrl) { throw new Error('Download failed for reasons'); } @@ -71,13 +71,13 @@ it('downloads node builds for each platform', async () => { await DownloadNodeBuilds.run(config, log, []); - expect(download.mock.calls).toMatchInlineSnapshot(` + expect(downloadToDisk.mock.calls).toMatchInlineSnapshot(` Array [ Array [ Object { "destination": "linux:downloadPath", "log": , - "retries": 3, + "maxAttempts": 3, "shaAlgorithm": "sha256", "shaChecksum": "linux:sha256", "url": "linux:url", @@ -87,7 +87,7 @@ it('downloads node builds for each platform', async () => { Object { "destination": "linux:downloadPath", "log": , - "retries": 3, + "maxAttempts": 3, "shaAlgorithm": "sha256", "shaChecksum": "linux:sha256", "url": "linux:url", @@ -97,7 +97,7 @@ it('downloads node builds for each platform', async () => { Object { "destination": "darwin:downloadPath", "log": , - "retries": 3, + "maxAttempts": 3, "shaAlgorithm": "sha256", "shaChecksum": "darwin:sha256", "url": "darwin:url", @@ -107,7 +107,7 @@ it('downloads node builds for each platform', async () => { Object { "destination": "darwin:downloadPath", "log": , - "retries": 3, + "maxAttempts": 3, "shaAlgorithm": "sha256", "shaChecksum": "darwin:sha256", "url": "darwin:url", @@ -117,7 +117,7 @@ it('downloads node builds for each platform', async () => { Object { "destination": "win32:downloadPath", "log": , - "retries": 3, + "maxAttempts": 3, "shaAlgorithm": "sha256", "shaChecksum": "win32:sha256", "url": "win32:url", diff --git a/src/dev/build/tasks/nodejs/download_node_builds_task.ts b/src/dev/build/tasks/nodejs/download_node_builds_task.ts index f19195092d964..9bc46def46964 100644 --- a/src/dev/build/tasks/nodejs/download_node_builds_task.ts +++ b/src/dev/build/tasks/nodejs/download_node_builds_task.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { download, GlobalTask } from '../../lib'; +import { downloadToDisk, GlobalTask } from '../../lib'; import { getNodeShasums } from './node_shasums'; import { getNodeDownloadInfo } from './node_download_info'; @@ -18,13 +18,13 @@ export const DownloadNodeBuilds: GlobalTask = { await Promise.all( config.getNodePlatforms().map(async (platform) => { const { url, downloadPath, downloadName } = getNodeDownloadInfo(config, platform); - await download({ + await downloadToDisk({ log, url, shaChecksum: shasums[downloadName], shaAlgorithm: 'sha256', destination: downloadPath, - retries: 3, + maxAttempts: 3, }); }) ); diff --git a/src/dev/build/tasks/nodejs/node_shasums.test.ts b/src/dev/build/tasks/nodejs/node_shasums.test.ts index 4b1482f9c0820..20d1f297b9ae0 100644 --- a/src/dev/build/tasks/nodejs/node_shasums.test.ts +++ b/src/dev/build/tasks/nodejs/node_shasums.test.ts @@ -47,15 +47,12 @@ c4edece2c0aa68e816c4e067f397eb12e9d0c81bb37b3d349dbaf47cf246b0b7 win-x86/node.l 6a2ee7a0b0074ece27d171418d82ce25a60b87750ec30c5c9fbeaaca8c206fa5 win-x86/node_pdb.7z 1b44176d888c1bc6a6b05fcc6234031b3b8a58da9de8b99661088f998ac5e269 win-x86/node_pdb.zip`; -jest.mock('axios', () => ({ - async get(url: string) { +jest.mock('../../lib/download', () => ({ + async downloadToString({ url }: { url: string }) { expect(url).toBe( 'https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/dist/v8.9.4/SHASUMS256.txt' ); - return { - status: 200, - data: mockResponse, - }; + return mockResponse; }, })); diff --git a/src/dev/build/tasks/nodejs/node_shasums.ts b/src/dev/build/tasks/nodejs/node_shasums.ts index 973dc86977a8e..ca588352ce7bb 100644 --- a/src/dev/build/tasks/nodejs/node_shasums.ts +++ b/src/dev/build/tasks/nodejs/node_shasums.ts @@ -6,29 +6,22 @@ * Side Public License, v 1. */ -import axios from 'axios'; import { ToolingLog } from '@kbn/dev-utils'; +import { downloadToString } from '../../lib/download'; export async function getNodeShasums(log: ToolingLog, nodeVersion: string) { const url = `https://us-central1-elastic-kibana-184716.cloudfunctions.net/kibana-ci-proxy-cache/dist/v${nodeVersion}/SHASUMS256.txt`; log.debug('Downloading shasum values for node version', nodeVersion, 'from', url); - const { status, data } = await axios.get(url); + const checksum = await downloadToString({ log, url, expectStatus: 200 }); - if (status !== 200) { - throw new Error(`${url} failed with a ${status} response`); - } + return checksum.split('\n').reduce((acc: Record, line: string) => { + const [sha, platform] = line.split(' '); - return data - .toString('utf8') - .split('\n') - .reduce((acc: Record, line: string) => { - const [sha, platform] = line.split(' '); - - return { - ...acc, - [platform]: sha, - }; - }, {}); + return { + ...acc, + [platform]: sha, + }; + }, {}); } diff --git a/src/dev/build/tasks/patch_native_modules_task.ts b/src/dev/build/tasks/patch_native_modules_task.ts index fe9743533b901..be7fa5b50a074 100644 --- a/src/dev/build/tasks/patch_native_modules_task.ts +++ b/src/dev/build/tasks/patch_native_modules_task.ts @@ -10,7 +10,17 @@ import path from 'path'; import { ToolingLog } from '@kbn/dev-utils'; -import { deleteAll, download, gunzip, untar, Task, Config, Build, Platform, read } from '../lib'; +import { + deleteAll, + downloadToDisk, + gunzip, + untar, + Task, + Config, + Build, + Platform, + read, +} from '../lib'; const DOWNLOAD_DIRECTORY = '.native_modules'; @@ -100,13 +110,13 @@ async function patchModule( log.debug(`Patching ${pkg.name} binaries from ${archive.url} to ${extractPath}`); await deleteAll([extractPath], log); - await download({ + await downloadToDisk({ log, url: archive.url, destination: downloadPath, shaChecksum: archive.sha256, shaAlgorithm: 'sha256', - retries: 3, + maxAttempts: 3, }); switch (pkg.extractMethod) { case 'gunzip': From 046bf5de6a95c0de031381ce6022a7509888d58d Mon Sep 17 00:00:00 2001 From: Scotty Bollinger Date: Wed, 24 Nov 2021 17:47:43 -0600 Subject: [PATCH 11/46] Add a stub for the custom GitHub App source (#119670) --- .../applications/workplace_search/routes.ts | 1 + .../components/add_source/github_app.tsx | 64 +++++++++++++++++++ .../components/add_source/index.ts | 1 + .../content_sources/sources_router.test.tsx | 2 +- .../views/content_sources/sources_router.tsx | 6 +- 5 files changed, 72 insertions(+), 2 deletions(-) create mode 100644 x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/github_app.tsx diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.ts index ec515eed91179..1be152ad5ca0b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/routes.ts @@ -73,6 +73,7 @@ export const ADD_CONFLUENCE_SERVER_PATH = `${SOURCES_PATH}/add/confluence_server export const ADD_DROPBOX_PATH = `${SOURCES_PATH}/add/dropbox`; export const ADD_GITHUB_ENTERPRISE_PATH = `${SOURCES_PATH}/add/github_enterprise_server`; export const ADD_GITHUB_PATH = `${SOURCES_PATH}/add/github`; +export const ADD_GITHUB_APP_PATH = `${SOURCES_PATH}/add/github_app`; export const ADD_GMAIL_PATH = `${SOURCES_PATH}/add/gmail`; export const ADD_GOOGLE_DRIVE_PATH = `${SOURCES_PATH}/add/google_drive`; export const ADD_JIRA_PATH = `${SOURCES_PATH}/add/jira_cloud`; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/github_app.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/github_app.tsx new file mode 100644 index 0000000000000..7f518d272d842 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/github_app.tsx @@ -0,0 +1,64 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { useValues } from 'kea'; + +import { EuiFlexGroup, EuiFlexItem, EuiHorizontalRule, EuiPanel, EuiSpacer } from '@elastic/eui'; + +import { AppLogic } from '../../../../app_logic'; +import { + WorkplaceSearchPageTemplate, + PersonalDashboardLayout, +} from '../../../../components/layout'; +import { NAV, SOURCE_NAMES } from '../../../../constants'; + +import { staticSourceData } from '../../source_data'; + +import { AddSourceHeader } from './add_source_header'; +import { SourceFeatures } from './source_features'; + +export const GitHubApp: React.FC = () => { + const { isOrganization } = useValues(AppLogic); + + const name = SOURCE_NAMES.GITHUB; + const data = staticSourceData.find((source) => (source.name = name)); + const Layout = isOrganization ? WorkplaceSearchPageTemplate : PersonalDashboardLayout; + + return ( + +
'TODO: use method from add_source_logic'}> + + + + + + + + + + + + + form goes here + + +
+
+ ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/index.ts b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/index.ts index f4920451e67c3..033cf9f356342 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/components/add_source/index.ts @@ -7,3 +7,4 @@ export { AddSource } from './add_source'; export { AddSourceList } from './add_source_list'; +export { GitHubApp } from './github_app'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.test.tsx index 00cf56001f73b..bcf2b2792c5d5 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.test.tsx @@ -34,7 +34,7 @@ describe('SourcesRouter', () => { }); it('renders sources routes', () => { - const TOTAL_ROUTES = 61; + const TOTAL_ROUTES = 62; const wrapper = shallow(); expect(wrapper.find(Switch)).toHaveLength(1); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.tsx index 2d47bab00810c..5142f5d6597ae 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/content_sources/sources_router.tsx @@ -14,6 +14,7 @@ import { useActions, useValues } from 'kea'; import { LicensingLogic } from '../../../shared/licensing'; import { AppLogic } from '../../app_logic'; import { + ADD_GITHUB_APP_PATH, ADD_SOURCE_PATH, SOURCE_DETAILS_PATH, PRIVATE_SOURCES_PATH, @@ -21,7 +22,7 @@ import { getSourcesPath, } from '../../routes'; -import { AddSource, AddSourceList } from './components/add_source'; +import { AddSource, AddSourceList, GitHubApp } from './components/add_source'; import { OrganizationSources } from './organization_sources'; import { PrivateSources } from './private_sources'; import { staticSourceData } from './source_data'; @@ -66,6 +67,9 @@ export const SourcesRouter: React.FC = () => { + + + {staticSourceData.map(({ addPath, accountContextOnly }, i) => ( {!hasPlatinumLicense && accountContextOnly ? ( From f0ad666a54b3e2116cee94e3acc2766804658e97 Mon Sep 17 00:00:00 2001 From: Catherine Liu Date: Wed, 24 Nov 2021 17:07:40 -0700 Subject: [PATCH 12/46] Preserves originating path when returning from editor (#115118) * Add originatingPath to edit_panel_action Support originatingPath in embeddable state transfer Fix ts error * Fixed jest tests * Parse originatingPath without using hash * provide static container context on embeddable panel * Fixed ts error Co-authored-by: Anton Dosov Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- src/plugins/embeddable/public/index.ts | 1 + .../lib/actions/edit_panel_action.test.tsx | 18 ++++++++++++++++-- .../public/lib/actions/edit_panel_action.ts | 9 ++++++++- .../public/lib/panel/embeddable_panel.tsx | 16 +++++++++++++++- src/plugins/embeddable/public/plugin.tsx | 18 ++++++++++++++++-- .../components/visualize_byvalue_editor.tsx | 7 ++++++- .../components/visualize_editor.tsx | 4 ++++ .../components/visualize_editor_common.tsx | 3 +++ .../components/visualize_top_nav.tsx | 4 ++++ .../application/utils/get_top_nav_config.tsx | 7 ++++++- .../application/utils/use/use_vis_byvalue.ts | 8 ++++++-- .../renderers/embeddable/embeddable.tsx | 10 +++++++++- x-pack/plugins/maps/public/render_app.tsx | 3 ++- .../maps/public/routes/map_page/map_page.tsx | 2 ++ .../routes/map_page/saved_map/saved_map.ts | 5 +++++ 15 files changed, 103 insertions(+), 12 deletions(-) diff --git a/src/plugins/embeddable/public/index.ts b/src/plugins/embeddable/public/index.ts index 6a6b5b2df2ddd..c6beccd5e3365 100644 --- a/src/plugins/embeddable/public/index.ts +++ b/src/plugins/embeddable/public/index.ts @@ -35,6 +35,7 @@ export type { EmbeddableEditorState, EmbeddablePackageState, EmbeddableRendererProps, + EmbeddableContainerContext, } from './lib'; export { ACTION_ADD_PANEL, diff --git a/src/plugins/embeddable/public/lib/actions/edit_panel_action.test.tsx b/src/plugins/embeddable/public/lib/actions/edit_panel_action.test.tsx index 1731907288460..a8c54ca8cdc33 100644 --- a/src/plugins/embeddable/public/lib/actions/edit_panel_action.test.tsx +++ b/src/plugins/embeddable/public/lib/actions/edit_panel_action.test.tsx @@ -44,7 +44,13 @@ test('is compatible when edit url is available, in edit mode and editable', asyn test('redirects to app using state transfer with by value mode', async () => { applicationMock.currentAppId$ = of('superCoolCurrentApp'); - const action = new EditPanelAction(getFactory, applicationMock, stateTransferMock); + const testPath = '/test-path'; + const action = new EditPanelAction( + getFactory, + applicationMock, + stateTransferMock, + () => testPath + ); const embeddable = new EditableEmbeddable( { id: '123', @@ -67,13 +73,20 @@ test('redirects to app using state transfer with by value mode', async () => { coolInput1: 1, coolInput2: 2, }, + originatingPath: testPath, }, }); }); test('redirects to app using state transfer without by value mode', async () => { applicationMock.currentAppId$ = of('superCoolCurrentApp'); - const action = new EditPanelAction(getFactory, applicationMock, stateTransferMock); + const testPath = '/test-path'; + const action = new EditPanelAction( + getFactory, + applicationMock, + stateTransferMock, + () => testPath + ); const embeddable = new EditableEmbeddable( { id: '123', viewMode: ViewMode.EDIT, savedObjectId: '1234' } as SavedObjectEmbeddableInput, true @@ -86,6 +99,7 @@ test('redirects to app using state transfer without by value mode', async () => originatingApp: 'superCoolCurrentApp', embeddableId: '123', valueInput: undefined, + originatingPath: testPath, }, }); }); diff --git a/src/plugins/embeddable/public/lib/actions/edit_panel_action.ts b/src/plugins/embeddable/public/lib/actions/edit_panel_action.ts index ea90307ef57a1..fde5c2ae62bc0 100644 --- a/src/plugins/embeddable/public/lib/actions/edit_panel_action.ts +++ b/src/plugins/embeddable/public/lib/actions/edit_panel_action.ts @@ -43,7 +43,8 @@ export class EditPanelAction implements Action { constructor( private readonly getEmbeddableFactory: EmbeddableStart['getEmbeddableFactory'], private readonly application: ApplicationStart, - private readonly stateTransfer?: EmbeddableStateTransfer + private readonly stateTransfer?: EmbeddableStateTransfer, + private readonly getOriginatingPath?: () => string ) { if (this.application?.currentAppId$) { this.application.currentAppId$ @@ -104,15 +105,21 @@ export class EditPanelAction implements Action { public getAppTarget({ embeddable }: ActionContext): NavigationContext | undefined { const app = embeddable ? embeddable.getOutput().editApp : undefined; const path = embeddable ? embeddable.getOutput().editPath : undefined; + if (app && path) { if (this.currentAppId) { const byValueMode = !(embeddable.getInput() as SavedObjectEmbeddableInput).savedObjectId; + + const originatingPath = this.getOriginatingPath?.(); + const state: EmbeddableEditorState = { originatingApp: this.currentAppId, valueInput: byValueMode ? this.getExplicitInput({ embeddable }) : undefined, embeddableId: embeddable.id, searchSessionId: embeddable.getInput().searchSessionId, + originatingPath, }; + return { app, path, state }; } return { app, path }; diff --git a/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx b/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx index cce286bfe73b4..9807a47698a50 100644 --- a/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx +++ b/src/plugins/embeddable/public/lib/panel/embeddable_panel.tsx @@ -53,6 +53,18 @@ const removeById = ({ id }: { id: string }) => disabledActions.indexOf(id) === -1; +/** + * Embeddable container may provide information about its environment, + * Use it for drilling down data that is static or doesn't have to be reactive, + * otherwise prefer passing data with input$ + * */ +export interface EmbeddableContainerContext { + /** + * Current app's path including query and hash starting from {appId} + */ + getCurrentPath?: () => string; +} + interface Props { embeddable: IEmbeddable; getActions: UiActionsService['getTriggerCompatibleActions']; @@ -70,6 +82,7 @@ interface Props { showShadow?: boolean; showBadges?: boolean; showNotifications?: boolean; + containerContext?: EmbeddableContainerContext; } interface State { @@ -373,7 +386,8 @@ export class EmbeddablePanel extends React.Component { editPanel: new EditPanelAction( this.props.getEmbeddableFactory, this.props.application, - this.props.stateTransfer + this.props.stateTransfer, + this.props.containerContext?.getCurrentPath ), }; }; diff --git a/src/plugins/embeddable/public/plugin.tsx b/src/plugins/embeddable/public/plugin.tsx index 7e393c6fc14e1..9043514fad317 100644 --- a/src/plugins/embeddable/public/plugin.tsx +++ b/src/plugins/embeddable/public/plugin.tsx @@ -36,6 +36,7 @@ import { IEmbeddable, EmbeddablePanel, SavedObjectEmbeddableInput, + EmbeddableContainerContext, } from './lib'; import { EmbeddableFactoryDefinition } from './lib/embeddables/embeddable_factory_definition'; import { EmbeddableStateTransfer } from './lib/state_transfer'; @@ -97,7 +98,11 @@ export interface EmbeddableStart extends PersistableStateService AttributeService; } -export type EmbeddablePanelHOC = React.FC<{ embeddable: IEmbeddable; hideHeader?: boolean }>; +export type EmbeddablePanelHOC = React.FC<{ + embeddable: IEmbeddable; + hideHeader?: boolean; + containerContext?: EmbeddableContainerContext; +}>; export class EmbeddablePublicPlugin implements Plugin { private readonly embeddableFactoryDefinitions: Map = @@ -155,7 +160,15 @@ export class EmbeddablePublicPlugin implements Plugin - ({ embeddable, hideHeader }: { embeddable: IEmbeddable; hideHeader?: boolean }) => + ({ + embeddable, + hideHeader, + containerContext, + }: { + embeddable: IEmbeddable; + hideHeader?: boolean; + containerContext?: EmbeddableContainerContext; + }) => ( ); diff --git a/src/plugins/visualize/public/application/components/visualize_byvalue_editor.tsx b/src/plugins/visualize/public/application/components/visualize_byvalue_editor.tsx index c32d15c336cfb..bab18c7263a73 100644 --- a/src/plugins/visualize/public/application/components/visualize_byvalue_editor.tsx +++ b/src/plugins/visualize/public/application/components/visualize_byvalue_editor.tsx @@ -26,6 +26,7 @@ import { VisualizeConstants } from '../..'; export const VisualizeByValueEditor = ({ onAppLeave }: VisualizeAppProps) => { const [originatingApp, setOriginatingApp] = useState(); + const [originatingPath, setOriginatingPath] = useState(); const { services } = useKibana(); const [eventEmitter] = useState(new EventEmitter()); const [hasUnsavedChanges, setHasUnsavedChanges] = useState(false); @@ -39,8 +40,10 @@ export const VisualizeByValueEditor = ({ onAppLeave }: VisualizeAppProps) => { embeddableId: embeddableIdValue, valueInput: valueInputValue, searchSessionId, + originatingPath: pathValue, } = stateTransferService.getIncomingEditorState(VisualizeConstants.APP_ID) || {}; + setOriginatingPath(pathValue); setOriginatingApp(value); setValueInput(valueInputValue); setEmbeddableId(embeddableIdValue); @@ -64,7 +67,8 @@ export const VisualizeByValueEditor = ({ onAppLeave }: VisualizeAppProps) => { eventEmitter, isChromeVisible, valueInput, - originatingApp + originatingApp, + originatingPath ); const { appState, hasUnappliedChanges } = useVisualizeAppState( services, @@ -99,6 +103,7 @@ export const VisualizeByValueEditor = ({ onAppLeave }: VisualizeAppProps) => { isEmbeddableRendered={isEmbeddableRendered} originatingApp={originatingApp} setOriginatingApp={setOriginatingApp} + originatingPath={originatingPath} setHasUnsavedChanges={setHasUnsavedChanges} visEditorRef={visEditorRef} embeddableId={embeddableId} diff --git a/src/plugins/visualize/public/application/components/visualize_editor.tsx b/src/plugins/visualize/public/application/components/visualize_editor.tsx index e81a886cee5a1..7688080df3e2c 100644 --- a/src/plugins/visualize/public/application/components/visualize_editor.tsx +++ b/src/plugins/visualize/public/application/components/visualize_editor.tsx @@ -27,6 +27,7 @@ import { VisualizeConstants } from '../..'; export const VisualizeEditor = ({ onAppLeave }: VisualizeAppProps) => { const { id: visualizationIdFromUrl } = useParams<{ id: string }>(); const [originatingApp, setOriginatingApp] = useState(); + const [originatingPath, setOriginatingPath] = useState(); const [embeddableIdValue, setEmbeddableId] = useState(); const { services } = useKibana(); const [eventEmitter] = useState(new EventEmitter()); @@ -61,6 +62,7 @@ export const VisualizeEditor = ({ onAppLeave }: VisualizeAppProps) => { originatingApp: value, searchSessionId, embeddableId, + originatingPath: pathValue, } = stateTransferService.getIncomingEditorState(VisualizeConstants.APP_ID) || {}; if (searchSessionId) { @@ -71,6 +73,7 @@ export const VisualizeEditor = ({ onAppLeave }: VisualizeAppProps) => { setEmbeddableId(embeddableId); setOriginatingApp(value); + setOriginatingPath(pathValue); }, [services]); useEffect(() => { @@ -91,6 +94,7 @@ export const VisualizeEditor = ({ onAppLeave }: VisualizeAppProps) => { isEmbeddableRendered={isEmbeddableRendered} originatingApp={originatingApp} setOriginatingApp={setOriginatingApp} + originatingPath={originatingPath} visualizationIdFromUrl={visualizationIdFromUrl} setHasUnsavedChanges={setHasUnsavedChanges} visEditorRef={visEditorRef} diff --git a/src/plugins/visualize/public/application/components/visualize_editor_common.tsx b/src/plugins/visualize/public/application/components/visualize_editor_common.tsx index 1ad7395557e30..4f017b56c534a 100644 --- a/src/plugins/visualize/public/application/components/visualize_editor_common.tsx +++ b/src/plugins/visualize/public/application/components/visualize_editor_common.tsx @@ -37,6 +37,7 @@ interface VisualizeEditorCommonProps { visEditorRef: RefObject; originatingApp?: string; setOriginatingApp?: (originatingApp: string | undefined) => void; + originatingPath?: string; visualizationIdFromUrl?: string; embeddableId?: string; } @@ -52,6 +53,7 @@ export const VisualizeEditorCommon = ({ isEmbeddableRendered, onAppLeave, originatingApp, + originatingPath, setOriginatingApp, visualizationIdFromUrl, embeddableId, @@ -117,6 +119,7 @@ export const VisualizeEditorCommon = ({ isEmbeddableRendered={isEmbeddableRendered} hasUnappliedChanges={hasUnappliedChanges} originatingApp={originatingApp} + originatingPath={originatingPath} setOriginatingApp={setOriginatingApp} visInstance={visInstance} stateContainer={appState} diff --git a/src/plugins/visualize/public/application/components/visualize_top_nav.tsx b/src/plugins/visualize/public/application/components/visualize_top_nav.tsx index ad933e597f0a7..c602b0193cf9c 100644 --- a/src/plugins/visualize/public/application/components/visualize_top_nav.tsx +++ b/src/plugins/visualize/public/application/components/visualize_top_nav.tsx @@ -29,6 +29,7 @@ interface VisualizeTopNavProps { setHasUnsavedChanges: (value: boolean) => void; hasUnappliedChanges: boolean; originatingApp?: string; + originatingPath?: string; visInstance: VisualizeEditorVisInstance; setOriginatingApp?: (originatingApp: string | undefined) => void; stateContainer: VisualizeAppStateContainer; @@ -46,6 +47,7 @@ const TopNav = ({ hasUnappliedChanges, originatingApp, setOriginatingApp, + originatingPath, visInstance, stateContainer, visualizationIdFromUrl, @@ -88,6 +90,7 @@ const TopNav = ({ openInspector, originatingApp, setOriginatingApp, + originatingPath, visInstance, stateContainer, visualizationIdFromUrl, @@ -104,6 +107,7 @@ const TopNav = ({ hasUnappliedChanges, openInspector, originatingApp, + originatingPath, visInstance, setOriginatingApp, stateContainer, diff --git a/src/plugins/visualize/public/application/utils/get_top_nav_config.tsx b/src/plugins/visualize/public/application/utils/get_top_nav_config.tsx index 772565734dac4..fd739a97e8cd0 100644 --- a/src/plugins/visualize/public/application/utils/get_top_nav_config.tsx +++ b/src/plugins/visualize/public/application/utils/get_top_nav_config.tsx @@ -54,6 +54,7 @@ export interface TopNavConfigParams { setHasUnsavedChanges: (value: boolean) => void; openInspector: () => void; originatingApp?: string; + originatingPath?: string; setOriginatingApp?: (originatingApp: string | undefined) => void; hasUnappliedChanges: boolean; visInstance: VisualizeEditorVisInstance; @@ -79,6 +80,7 @@ export const getTopNavConfig = ( setHasUnsavedChanges, openInspector, originatingApp, + originatingPath, setOriginatingApp, hasUnappliedChanges, visInstance, @@ -168,6 +170,8 @@ export const getTopNavConfig = ( if (saveOptions.dashboardId) { path = saveOptions.dashboardId === 'new' ? '#/create' : `#/view/${saveOptions.dashboardId}`; + } else if (originatingPath) { + path = originatingPath; } if (stateTransfer) { @@ -232,7 +236,8 @@ export const getTopNavConfig = ( type: VISUALIZE_EMBEDDABLE_TYPE, searchSessionId: data.search.session.getSessionId(), }; - stateTransfer.navigateToWithEmbeddablePackage(originatingApp, { state }); + + stateTransfer.navigateToWithEmbeddablePackage(originatingApp, { state, path: originatingPath }); }; const navigateToOriginatingApp = () => { diff --git a/src/plugins/visualize/public/application/utils/use/use_vis_byvalue.ts b/src/plugins/visualize/public/application/utils/use/use_vis_byvalue.ts index 27c9f77b98910..8e0b9692f8aab 100644 --- a/src/plugins/visualize/public/application/utils/use/use_vis_byvalue.ts +++ b/src/plugins/visualize/public/application/utils/use/use_vis_byvalue.ts @@ -19,7 +19,8 @@ export const useVisByValue = ( eventEmitter: EventEmitter, isChromeVisible: boolean | undefined, valueInput?: VisualizeInput, - originatingApp?: string + originatingApp?: string, + originatingPath?: string ) => { const [state, setState] = useState<{ byValueVisInstance?: ByValueVisInstance; @@ -55,7 +56,9 @@ export const useVisByValue = ( const originatingAppName = originatingApp ? stateTransferService.getAppNameFromId(originatingApp) : undefined; - const redirectToOrigin = originatingApp ? () => navigateToApp(originatingApp) : undefined; + const redirectToOrigin = originatingApp + ? () => navigateToApp(originatingApp, { path: originatingPath }) + : undefined; chrome?.setBreadcrumbs( getEditBreadcrumbs({ byValue: true, originatingAppName, redirectToOrigin }) ); @@ -76,6 +79,7 @@ export const useVisByValue = ( state.visEditorController, valueInput, originatingApp, + originatingPath, ]); useEffect(() => { diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx index 953746c280840..0b1adb9559e55 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/embeddable/embeddable.tsx @@ -20,6 +20,7 @@ import { RendererStrings } from '../../../i18n'; import { embeddableInputToExpression } from './embeddable_input_to_expression'; import { RendererFactory, EmbeddableInput } from '../../../types'; import { CANVAS_EMBEDDABLE_CLASSNAME } from '../../../common/lib'; +import type { EmbeddableContainerContext } from '../../../../../../src/plugins/embeddable/public/'; const { embeddable: strings } = RendererStrings; @@ -31,6 +32,10 @@ const embeddablesRegistry: { const renderEmbeddableFactory = (core: CoreStart, plugins: StartDeps) => { const I18nContext = core.i18n.Context; + const embeddableContainerContext: EmbeddableContainerContext = { + getCurrentPath: () => window.location.hash, + }; + return (embeddableObject: IEmbeddable) => { return (
{ style={{ width: '100%', height: '100%', cursor: 'auto' }} > - +
); diff --git a/x-pack/plugins/maps/public/render_app.tsx b/x-pack/plugins/maps/public/render_app.tsx index 3eefaeb6f7a9b..17c1dfdc98f2e 100644 --- a/x-pack/plugins/maps/public/render_app.tsx +++ b/x-pack/plugins/maps/public/render_app.tsx @@ -77,7 +77,7 @@ export async function renderApp( setAppChrome(); function renderMapApp(routeProps: RouteComponentProps<{ savedMapId?: string }>) { - const { embeddableId, originatingApp, valueInput } = + const { embeddableId, originatingApp, valueInput, originatingPath } = stateTransfer.getIncomingEditorState(APP_ID) || {}; let mapEmbeddableInput; @@ -98,6 +98,7 @@ export async function renderApp( setHeaderActionMenu={setHeaderActionMenu} stateTransfer={stateTransfer} originatingApp={originatingApp} + originatingPath={originatingPath} history={history} key={routeProps.match.params.savedMapId ? routeProps.match.params.savedMapId : 'new'} /> diff --git a/x-pack/plugins/maps/public/routes/map_page/map_page.tsx b/x-pack/plugins/maps/public/routes/map_page/map_page.tsx index 7e927115a5d06..b382be1d506bd 100644 --- a/x-pack/plugins/maps/public/routes/map_page/map_page.tsx +++ b/x-pack/plugins/maps/public/routes/map_page/map_page.tsx @@ -20,6 +20,7 @@ interface Props { setHeaderActionMenu: AppMountParameters['setHeaderActionMenu']; stateTransfer: EmbeddableStateTransfer; originatingApp?: string; + originatingPath?: string; history: AppMountParameters['history']; } @@ -43,6 +44,7 @@ export class MapPage extends Component { mapEmbeddableInput: props.mapEmbeddableInput, embeddableId: props.embeddableId, originatingApp: props.originatingApp, + originatingPath: props.originatingPath, stateTransfer: props.stateTransfer, onSaveCallback: this.updateSaveCounter, }), diff --git a/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts b/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts index 3cff8d9713830..a6f1eb8572ef1 100644 --- a/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts +++ b/x-pack/plugins/maps/public/routes/map_page/saved_map/saved_map.ts @@ -58,6 +58,7 @@ export class SavedMap { private _mapEmbeddableInput?: MapEmbeddableInput; private readonly _onSaveCallback?: () => void; private _originatingApp?: string; + private _originatingPath?: string; private readonly _stateTransfer?: EmbeddableStateTransfer; private readonly _store: MapStore; private _tags: string[] = []; @@ -69,6 +70,7 @@ export class SavedMap { onSaveCallback, originatingApp, stateTransfer, + originatingPath, }: { defaultLayers?: LayerDescriptor[]; mapEmbeddableInput?: MapEmbeddableInput; @@ -76,12 +78,14 @@ export class SavedMap { onSaveCallback?: () => void; originatingApp?: string; stateTransfer?: EmbeddableStateTransfer; + originatingPath?: string; }) { this._defaultLayers = defaultLayers; this._mapEmbeddableInput = mapEmbeddableInput; this._embeddableId = embeddableId; this._onSaveCallback = onSaveCallback; this._originatingApp = originatingApp; + this._originatingPath = originatingPath; this._stateTransfer = stateTransfer; this._store = createMapStore(); } @@ -379,6 +383,7 @@ export class SavedMap { type: MAP_SAVED_OBJECT_TYPE, input: updatedMapEmbeddableInput, }, + path: this._originatingPath, }); return; } else if (dashboardId) { From ce817118fc0e9bef0295d25116bfada5bd0fb355 Mon Sep 17 00:00:00 2001 From: Catherine Liu Date: Wed, 24 Nov 2021 17:09:22 -0700 Subject: [PATCH 13/46] Fix saved visualization time range error (#116347) * Fix saved visualization time range error * Fix ts error Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../functions/external/saved_visualization.test.ts | 11 +++++++++++ .../functions/external/saved_visualization.ts | 3 ++- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_visualization.test.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_visualization.test.ts index 52c452e61bd55..8b7c77e20f7d2 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_visualization.test.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_visualization.test.ts @@ -57,4 +57,15 @@ describe('savedVisualization', () => { const expression = fn(null, { ...args, title: '' }, {} as any); expect(expression.input.title).toEqual(''); }); + + it('accepts time range', () => { + const expression = fn( + null, + { ...args, timerange: { type: 'timerange', from: '15m-now', to: 'now' } }, + {} as any + ); + expect(expression.input.timeRange).toHaveProperty('from', '15m-now'); + expect(expression.input.timeRange).toHaveProperty('to', 'now'); + expect(expression.input.timeRange).not.toHaveProperty('type'); + }); }); diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_visualization.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_visualization.ts index 31e3fb2a8c564..4a0668740bb4b 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_visualization.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/external/saved_visualization.ts @@ -5,6 +5,7 @@ * 2.0. */ +import { omit } from 'lodash'; import { ExpressionFunctionDefinition } from 'src/plugins/expressions'; import { VisualizeInput } from 'src/plugins/visualizations/public'; import { @@ -96,7 +97,7 @@ export function savedVisualization(): ExpressionFunctionDefinition< id, savedObjectId: id, disableTriggers: true, - timeRange: timerange || defaultTimeRange, + timeRange: timerange ? omit(timerange, 'type') : defaultTimeRange, filters: getQueryFilters(filters), vis: visOptions, title: title === null ? undefined : title, From c56449a0bf409b68e37a0ec580ef824a9f50cf75 Mon Sep 17 00:00:00 2001 From: Dominique Clarke Date: Wed, 24 Nov 2021 19:22:25 -0500 Subject: [PATCH 14/46] [Uptime] hide UI Monitor Management features behind feature flag (#119559) * hide ui monitor management features behind feature flag * adjust tests * adjust content * adjust rtl_helpers --- .../uptime/{server => common}/config.ts | 19 ++ x-pack/plugins/uptime/common/constants/ui.ts | 4 + x-pack/plugins/uptime/public/apps/plugin.ts | 7 +- .../plugins/uptime/public/apps/render_app.tsx | 5 +- .../plugins/uptime/public/apps/uptime_app.tsx | 5 +- .../components/monitor/ml/ml_flyout.test.tsx | 2 + .../contexts/uptime_settings_context.tsx | 14 +- .../uptime/public/hooks/use_telemetry.ts | 2 + .../uptime/public/lib/helper/rtl_helpers.tsx | 7 + .../uptime/public/pages/add_monitor.tsx | 12 + .../uptime/public/pages/edit_monitor.tsx | 12 + x-pack/plugins/uptime/public/pages/index.ts | 2 + x-pack/plugins/uptime/public/routes.test.tsx | 47 ++++ x-pack/plugins/uptime/public/routes.tsx | 256 +++++++++++------- x-pack/plugins/uptime/server/index.ts | 2 +- .../lib/adapters/framework/adapter_types.ts | 2 +- .../server/lib/saved_objects/saved_objects.ts | 2 +- x-pack/plugins/uptime/server/plugin.ts | 4 +- 18 files changed, 295 insertions(+), 109 deletions(-) rename x-pack/plugins/uptime/{server => common}/config.ts (68%) create mode 100644 x-pack/plugins/uptime/public/pages/add_monitor.tsx create mode 100644 x-pack/plugins/uptime/public/pages/edit_monitor.tsx create mode 100644 x-pack/plugins/uptime/public/routes.test.tsx diff --git a/x-pack/plugins/uptime/server/config.ts b/x-pack/plugins/uptime/common/config.ts similarity index 68% rename from x-pack/plugins/uptime/server/config.ts rename to x-pack/plugins/uptime/common/config.ts index acaef68c95015..ccd5e7b5a2cc6 100644 --- a/x-pack/plugins/uptime/server/config.ts +++ b/x-pack/plugins/uptime/common/config.ts @@ -9,9 +9,25 @@ import { PluginConfigDescriptor } from 'kibana/server'; import { schema, TypeOf } from '@kbn/config-schema'; export const config: PluginConfigDescriptor = { + exposeToBrowser: { + ui: true, + }, schema: schema.maybe( schema.object({ index: schema.maybe(schema.string()), + ui: schema.maybe( + schema.object({ + unsafe: schema.maybe( + schema.object({ + monitorManagement: schema.maybe( + schema.object({ + enabled: schema.boolean(), + }) + ), + }) + ), + }) + ), unsafe: schema.maybe( schema.object({ service: schema.maybe( @@ -30,3 +46,6 @@ export const config: PluginConfigDescriptor = { }; export type UptimeConfig = TypeOf; +export interface UptimeUiConfig { + ui?: TypeOf['ui']; +} diff --git a/x-pack/plugins/uptime/common/constants/ui.ts b/x-pack/plugins/uptime/common/constants/ui.ts index 659d5727abc0c..b1d92db8eae12 100644 --- a/x-pack/plugins/uptime/common/constants/ui.ts +++ b/x-pack/plugins/uptime/common/constants/ui.ts @@ -7,6 +7,10 @@ export const MONITOR_ROUTE = '/monitor/:monitorId?'; +export const MONITOR_ADD_ROUTE = '/add-monitor'; + +export const MONITOR_EDIT_ROUTE = '/edit-monitor/:monitorId'; + export const OVERVIEW_ROUTE = '/'; export const SETTINGS_ROUTE = '/settings'; diff --git a/x-pack/plugins/uptime/public/apps/plugin.ts b/x-pack/plugins/uptime/public/apps/plugin.ts index 0cd0af6231c9c..ec6deef429ca9 100644 --- a/x-pack/plugins/uptime/public/apps/plugin.ts +++ b/x-pack/plugins/uptime/public/apps/plugin.ts @@ -15,6 +15,7 @@ import { from } from 'rxjs'; import { map } from 'rxjs/operators'; import { i18n } from '@kbn/i18n'; import { DEFAULT_APP_CATEGORIES } from '../../../../../src/core/public'; + import { FeatureCatalogueCategory, HomePublicPluginSetup, @@ -43,6 +44,7 @@ import { } from '../components/fleet_package'; import { LazySyntheticsCustomAssetsExtension } from '../components/fleet_package/lazy_synthetics_custom_assets_extension'; import { Start as InspectorPluginStart } from '../../../../../src/plugins/inspector/public'; +import { UptimeUiConfig } from '../../common/config'; export interface ClientPluginsSetup { data: DataPublicPluginSetup; @@ -73,9 +75,10 @@ export type ClientStart = void; export class UptimePlugin implements Plugin { - constructor(_context: PluginInitializerContext) {} + constructor(private readonly initContext: PluginInitializerContext) {} public setup(core: CoreSetup, plugins: ClientPluginsSetup): void { + const config = this.initContext.config.get(); if (plugins.home) { plugins.home.featureCatalogue.register({ id: PLUGIN.ID, @@ -203,7 +206,7 @@ export class UptimePlugin const [coreStart, corePlugins] = await core.getStartServices(); const { renderApp } = await import('./render_app'); - return renderApp(coreStart, plugins, corePlugins, params); + return renderApp(coreStart, plugins, corePlugins, params, config); }, }); } diff --git a/x-pack/plugins/uptime/public/apps/render_app.tsx b/x-pack/plugins/uptime/public/apps/render_app.tsx index 376fb4c8364c0..cc831680dbf09 100644 --- a/x-pack/plugins/uptime/public/apps/render_app.tsx +++ b/x-pack/plugins/uptime/public/apps/render_app.tsx @@ -17,12 +17,14 @@ import { } from '../../common/constants'; import { UptimeApp, UptimeAppProps } from './uptime_app'; import { ClientPluginsSetup, ClientPluginsStart } from './plugin'; +import { UptimeUiConfig } from '../../common/config'; export function renderApp( core: CoreStart, plugins: ClientPluginsSetup, startPlugins: ClientPluginsStart, - appMountParameters: AppMountParameters + appMountParameters: AppMountParameters, + config: UptimeUiConfig ) { const { application: { capabilities }, @@ -70,6 +72,7 @@ export function renderApp( setBadge, appMountParameters, setBreadcrumbs: core.chrome.setBreadcrumbs, + config, }; ReactDOM.render(, appMountParameters.element); diff --git a/x-pack/plugins/uptime/public/apps/uptime_app.tsx b/x-pack/plugins/uptime/public/apps/uptime_app.tsx index c5c379db71692..7eb2c9626e37f 100644 --- a/x-pack/plugins/uptime/public/apps/uptime_app.tsx +++ b/x-pack/plugins/uptime/public/apps/uptime_app.tsx @@ -35,6 +35,7 @@ import { EuiThemeProvider } from '../../../../../src/plugins/kibana_react/common import { Storage } from '../../../../../src/plugins/kibana_utils/public'; import { UptimeIndexPatternContextProvider } from '../contexts/uptime_index_pattern_context'; import { InspectorContextProvider } from '../../../observability/public'; +import { UptimeUiConfig } from '../../common/config'; export interface UptimeAppColors { danger: string; @@ -63,6 +64,7 @@ export interface UptimeAppProps { commonlyUsedRanges: CommonlyUsedRange[]; setBreadcrumbs: (crumbs: ChromeBreadcrumb[]) => void; appMountParameters: AppMountParameters; + config: UptimeUiConfig; } const Application = (props: UptimeAppProps) => { @@ -77,6 +79,7 @@ const Application = (props: UptimeAppProps) => { setBadge, startPlugins, appMountParameters, + config, } = props; useEffect(() => { @@ -133,7 +136,7 @@ const Application = (props: UptimeAppProps) => { > - + diff --git a/x-pack/plugins/uptime/public/components/monitor/ml/ml_flyout.test.tsx b/x-pack/plugins/uptime/public/components/monitor/ml/ml_flyout.test.tsx index 29c4a852e208b..c2c4baf0751c4 100644 --- a/x-pack/plugins/uptime/public/components/monitor/ml/ml_flyout.test.tsx +++ b/x-pack/plugins/uptime/public/components/monitor/ml/ml_flyout.test.tsx @@ -40,6 +40,7 @@ describe('ML Flyout component', () => { isApmAvailable: true, isInfraAvailable: true, isLogsAvailable: true, + config: {}, }; const { findByText, findAllByText } = render( @@ -66,6 +67,7 @@ describe('ML Flyout component', () => { isApmAvailable: true, isInfraAvailable: true, isLogsAvailable: true, + config: {}, }; const { queryByText } = render( diff --git a/x-pack/plugins/uptime/public/contexts/uptime_settings_context.tsx b/x-pack/plugins/uptime/public/contexts/uptime_settings_context.tsx index dacaeb89a5cc5..63f21a23e30d3 100644 --- a/x-pack/plugins/uptime/public/contexts/uptime_settings_context.tsx +++ b/x-pack/plugins/uptime/public/contexts/uptime_settings_context.tsx @@ -10,6 +10,7 @@ import { UptimeAppProps } from '../apps/uptime_app'; import { CLIENT_DEFAULTS, CONTEXT_DEFAULTS } from '../../common/constants'; import { CommonlyUsedRange } from '../components/common/uptime_date_picker'; import { useGetUrlParams } from '../hooks'; +import { UptimeUiConfig } from '../../common/config'; export interface UptimeSettingsContextValues { basePath: string; @@ -18,6 +19,7 @@ export interface UptimeSettingsContextValues { isApmAvailable: boolean; isInfraAvailable: boolean; isLogsAvailable: boolean; + config: UptimeUiConfig; commonlyUsedRanges?: CommonlyUsedRange[]; } @@ -36,11 +38,19 @@ const defaultContext: UptimeSettingsContextValues = { isApmAvailable: true, isInfraAvailable: true, isLogsAvailable: true, + config: {}, }; export const UptimeSettingsContext = createContext(defaultContext); export const UptimeSettingsContextProvider: React.FC = ({ children, ...props }) => { - const { basePath, isApmAvailable, isInfraAvailable, isLogsAvailable, commonlyUsedRanges } = props; + const { + basePath, + isApmAvailable, + isInfraAvailable, + isLogsAvailable, + commonlyUsedRanges, + config, + } = props; const { dateRangeStart, dateRangeEnd } = useGetUrlParams(); @@ -51,6 +61,7 @@ export const UptimeSettingsContextProvider: React.FC = ({ childr isInfraAvailable, isLogsAvailable, commonlyUsedRanges, + config, dateRangeStart: dateRangeStart ?? DATE_RANGE_START, dateRangeEnd: dateRangeEnd ?? DATE_RANGE_END, }; @@ -62,6 +73,7 @@ export const UptimeSettingsContextProvider: React.FC = ({ childr dateRangeStart, dateRangeEnd, commonlyUsedRanges, + config, ]); return ; diff --git a/x-pack/plugins/uptime/public/hooks/use_telemetry.ts b/x-pack/plugins/uptime/public/hooks/use_telemetry.ts index f5abdb473fb0d..0c97bf7ac972a 100644 --- a/x-pack/plugins/uptime/public/hooks/use_telemetry.ts +++ b/x-pack/plugins/uptime/public/hooks/use_telemetry.ts @@ -14,6 +14,8 @@ export enum UptimePage { Overview = 'Overview', MappingError = 'MappingError', Monitor = 'Monitor', + MonitorAdd = 'AddMonitor', + MonitorEdit = 'EditMonitor', Settings = 'Settings', Certificates = 'Certificates', StepDetail = 'StepDetail', diff --git a/x-pack/plugins/uptime/public/lib/helper/rtl_helpers.tsx b/x-pack/plugins/uptime/public/lib/helper/rtl_helpers.tsx index 47c2bd6e7331e..fe7fd0918450b 100644 --- a/x-pack/plugins/uptime/public/lib/helper/rtl_helpers.tsx +++ b/x-pack/plugins/uptime/public/lib/helper/rtl_helpers.tsx @@ -13,6 +13,7 @@ import { Router } from 'react-router-dom'; import { createMemoryHistory, History } from 'history'; import { CoreStart } from 'kibana/public'; import { I18nProvider } from '@kbn/i18n-react'; +import { EuiPageTemplate } from '@elastic/eui'; import { coreMock } from 'src/core/public/mocks'; // eslint-disable-next-line import/no-extraneous-dependencies import { configure } from '@testing-library/dom'; @@ -113,6 +114,12 @@ const mockCore: () => Partial = () => { triggersActionsUi: triggersActionsUiMock.createStart(), storage: createMockStore(), data: dataPluginMock.createStartContract(), + observability: { + navigation: { + // @ts-ignore + PageTemplate: EuiPageTemplate, + }, + }, }; return core; diff --git a/x-pack/plugins/uptime/public/pages/add_monitor.tsx b/x-pack/plugins/uptime/public/pages/add_monitor.tsx new file mode 100644 index 0000000000000..10e3d9d6ce29a --- /dev/null +++ b/x-pack/plugins/uptime/public/pages/add_monitor.tsx @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +export const AddMonitorPage: React.FC = () => { + return null; +}; diff --git a/x-pack/plugins/uptime/public/pages/edit_monitor.tsx b/x-pack/plugins/uptime/public/pages/edit_monitor.tsx new file mode 100644 index 0000000000000..3be1bc7b35d8d --- /dev/null +++ b/x-pack/plugins/uptime/public/pages/edit_monitor.tsx @@ -0,0 +1,12 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +export const EditMonitorPage: React.FC = () => { + return null; +}; diff --git a/x-pack/plugins/uptime/public/pages/index.ts b/x-pack/plugins/uptime/public/pages/index.ts index 352ceb39123e8..6833a90c8bd82 100644 --- a/x-pack/plugins/uptime/public/pages/index.ts +++ b/x-pack/plugins/uptime/public/pages/index.ts @@ -10,3 +10,5 @@ export { MonitorPage } from './monitor'; export { StepDetailPage } from './synthetics/step_detail_page'; export { SettingsPage } from './settings'; export { NotFoundPage } from './not_found'; +export { AddMonitorPage } from './add_monitor'; +export { EditMonitorPage } from './edit_monitor'; diff --git a/x-pack/plugins/uptime/public/routes.test.tsx b/x-pack/plugins/uptime/public/routes.test.tsx new file mode 100644 index 0000000000000..5b7815610fe62 --- /dev/null +++ b/x-pack/plugins/uptime/public/routes.test.tsx @@ -0,0 +1,47 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +// app.test.js +import { screen } from '@testing-library/react'; +import { render } from './lib/helper/rtl_helpers'; +import { createMemoryHistory } from 'history'; +import React from 'react'; +import * as telemetry from './hooks/use_telemetry'; +import { MONITOR_ADD_ROUTE, MONITOR_EDIT_ROUTE } from '../common/constants'; + +import '@testing-library/jest-dom'; + +import { PageRouter } from './routes'; + +describe('PageRouter', () => { + beforeEach(() => { + jest.spyOn(telemetry, 'useUptimeTelemetry').mockImplementation(() => {}); + }); + it.each([MONITOR_ADD_ROUTE, MONITOR_EDIT_ROUTE])( + 'hides ui monitor management pages when feature flag is not enabled', + (page) => { + const history = createMemoryHistory(); + history.push(page); + render(, { history }); + + expect(screen.getByText(/Page not found/i)).toBeInTheDocument(); + } + ); + + it.each([ + [MONITOR_ADD_ROUTE, 'Add Monitor'], + [MONITOR_EDIT_ROUTE, 'Edit Monitor'], + ])('hides ui monitor management pages when feature flag is not enabled', (page, heading) => { + const history = createMemoryHistory(); + history.push(page); + render(, { + history, + }); + + expect(screen.getByText(heading)).toBeInTheDocument(); + }); +}); diff --git a/x-pack/plugins/uptime/public/routes.tsx b/x-pack/plugins/uptime/public/routes.tsx index a911319d9a3fd..64d7411f1673d 100644 --- a/x-pack/plugins/uptime/public/routes.tsx +++ b/x-pack/plugins/uptime/public/routes.tsx @@ -13,12 +13,22 @@ import { CERTIFICATES_ROUTE, MAPPING_ERROR_ROUTE, MONITOR_ROUTE, + MONITOR_ADD_ROUTE, + MONITOR_EDIT_ROUTE, OVERVIEW_ROUTE, SETTINGS_ROUTE, STEP_DETAIL_ROUTE, SYNTHETIC_CHECK_STEPS_ROUTE, } from '../common/constants'; -import { MappingErrorPage, MonitorPage, StepDetailPage, NotFoundPage, SettingsPage } from './pages'; +import { + MappingErrorPage, + MonitorPage, + AddMonitorPage, + EditMonitorPage, + StepDetailPage, + NotFoundPage, + SettingsPage, +} from './pages'; import { CertificatesPage } from './pages/certificates'; import { UptimePage, useUptimeTelemetry } from './hooks'; import { OverviewPageComponent } from './pages/overview'; @@ -41,6 +51,11 @@ import { import { UptimePageTemplateComponent } from './apps/uptime_page_template'; import { apiService } from './state/api/utils'; import { useInspectorContext } from '../../observability/public'; +import { UptimeConfig } from '../common/config'; + +interface PageRouterProps { + config: UptimeConfig; +} interface RouteProps { path: string; @@ -63,109 +78,151 @@ export const MONITORING_OVERVIEW_LABEL = i18n.translate('xpack.uptime.overview.h defaultMessage: 'Monitors', }); -const Routes: RouteProps[] = [ - { - title: i18n.translate('xpack.uptime.monitorRoute.title', { - defaultMessage: 'Monitor | {baseTitle}', - values: { baseTitle }, - }), - path: MONITOR_ROUTE, - component: MonitorPage, - dataTestSubj: 'uptimeMonitorPage', - telemetryId: UptimePage.Monitor, - pageHeader: { - children: , - pageTitle: , - rightSideItems: [], +const getRoutes = (config: UptimeConfig): RouteProps[] => { + return [ + { + title: i18n.translate('xpack.uptime.monitorRoute.title', { + defaultMessage: 'Monitor | {baseTitle}', + values: { baseTitle }, + }), + path: MONITOR_ROUTE, + component: MonitorPage, + dataTestSubj: 'uptimeMonitorPage', + telemetryId: UptimePage.Monitor, + pageHeader: { + children: , + pageTitle: , + rightSideItems: [], + }, }, - }, - { - title: i18n.translate('xpack.uptime.settingsRoute.title', { - defaultMessage: `Settings | {baseTitle}`, - values: { baseTitle }, - }), - path: SETTINGS_ROUTE, - component: SettingsPage, - dataTestSubj: 'uptimeSettingsPage', - telemetryId: UptimePage.Settings, - pageHeader: { - pageTitle: ( - - ), + { + title: i18n.translate('xpack.uptime.settingsRoute.title', { + defaultMessage: `Settings | {baseTitle}`, + values: { baseTitle }, + }), + path: SETTINGS_ROUTE, + component: SettingsPage, + dataTestSubj: 'uptimeSettingsPage', + telemetryId: UptimePage.Settings, + pageHeader: { + pageTitle: ( + + ), + }, }, - }, - { - title: i18n.translate('xpack.uptime.certificatesRoute.title', { - defaultMessage: `Certificates | {baseTitle}`, - values: { baseTitle }, - }), - path: CERTIFICATES_ROUTE, - component: CertificatesPage, - dataTestSubj: 'uptimeCertificatesPage', - telemetryId: UptimePage.Certificates, - pageHeader: { - pageTitle: , - rightSideItems: [], + { + title: i18n.translate('xpack.uptime.certificatesRoute.title', { + defaultMessage: `Certificates | {baseTitle}`, + values: { baseTitle }, + }), + path: CERTIFICATES_ROUTE, + component: CertificatesPage, + dataTestSubj: 'uptimeCertificatesPage', + telemetryId: UptimePage.Certificates, + pageHeader: { + pageTitle: , + rightSideItems: [], + }, }, - }, - { - title: i18n.translate('xpack.uptime.stepDetailRoute.title', { - defaultMessage: 'Synthetics detail | {baseTitle}', - values: { baseTitle }, - }), - path: STEP_DETAIL_ROUTE, - component: StepDetailPage, - dataTestSubj: 'uptimeStepDetailPage', - telemetryId: UptimePage.StepDetail, - pageHeader: { - children: , - pageTitle: , - rightSideItems: [], + { + title: i18n.translate('xpack.uptime.stepDetailRoute.title', { + defaultMessage: 'Synthetics detail | {baseTitle}', + values: { baseTitle }, + }), + path: STEP_DETAIL_ROUTE, + component: StepDetailPage, + dataTestSubj: 'uptimeStepDetailPage', + telemetryId: UptimePage.StepDetail, + pageHeader: { + children: , + pageTitle: , + rightSideItems: [], + }, }, - }, - { - title: baseTitle, - path: SYNTHETIC_CHECK_STEPS_ROUTE, - component: SyntheticsCheckSteps, - dataTestSubj: 'uptimeSyntheticCheckStepsPage', - telemetryId: UptimePage.SyntheticCheckStepsPage, - pageHeader: { - pageTitle: , - rightSideItems: [], + { + title: baseTitle, + path: SYNTHETIC_CHECK_STEPS_ROUTE, + component: SyntheticsCheckSteps, + dataTestSubj: 'uptimeSyntheticCheckStepsPage', + telemetryId: UptimePage.SyntheticCheckStepsPage, + pageHeader: { + pageTitle: , + rightSideItems: [], + }, }, - }, - { - title: baseTitle, - path: OVERVIEW_ROUTE, - component: OverviewPageComponent, - dataTestSubj: 'uptimeOverviewPage', - telemetryId: UptimePage.Overview, - pageHeader: { - pageTitle: MONITORING_OVERVIEW_LABEL, - rightSideItems: [], + { + title: baseTitle, + path: OVERVIEW_ROUTE, + component: OverviewPageComponent, + dataTestSubj: 'uptimeOverviewPage', + telemetryId: UptimePage.Overview, + pageHeader: { + pageTitle: MONITORING_OVERVIEW_LABEL, + rightSideItems: [], + }, }, - }, - { - title: i18n.translate('xpack.uptime.mappingErrorRoute.title', { - defaultMessage: 'Synthetics | mapping error', - }), - path: MAPPING_ERROR_ROUTE, - component: MappingErrorPage, - dataTestSubj: 'uptimeMappingErrorPage', - telemetryId: UptimePage.MappingError, - pageHeader: { - pageTitle: ( -
- -
- ), - rightSideItems: [], + { + title: i18n.translate('xpack.uptime.mappingErrorRoute.title', { + defaultMessage: 'Synthetics | mapping error', + }), + path: MAPPING_ERROR_ROUTE, + component: MappingErrorPage, + dataTestSubj: 'uptimeMappingErrorPage', + telemetryId: UptimePage.MappingError, + pageHeader: { + pageTitle: ( +
+ +
+ ), + rightSideItems: [], + }, }, - }, -]; + ...(config.ui?.unsafe?.monitorManagement?.enabled + ? [ + { + title: i18n.translate('xpack.uptime.addMonitorRoute.title', { + defaultMessage: 'Add Monitor | {baseTitle}', + values: { baseTitle }, + }), + path: MONITOR_ADD_ROUTE, + component: AddMonitorPage, + dataTestSubj: 'uptimeMonitorAddPage', + telemetryId: UptimePage.MonitorAdd, + pageHeader: { + pageTitle: ( + + ), + }, + }, + { + title: i18n.translate('xpack.uptime.editMonitorRoute.title', { + defaultMessage: 'Edit Monitor | {baseTitle}', + values: { baseTitle }, + }), + path: MONITOR_EDIT_ROUTE, + component: EditMonitorPage, + dataTestSubj: 'uptimeMonitorEditPage', + telemetryId: UptimePage.MonitorEdit, + pageHeader: { + pageTitle: ( + + ), + }, + }, + ] + : []), + ]; +}; const RouteInit: React.FC> = ({ path, @@ -179,14 +236,15 @@ const RouteInit: React.FC> = return null; }; -export const PageRouter: FC = () => { +export const PageRouter: FC = ({ config = {} }) => { + const routes = getRoutes(config); const { addInspectorRequest } = useInspectorContext(); apiService.addInspectorRequest = addInspectorRequest; return ( - {Routes.map( + {routes.map( ({ title, path, component: RouteComponent, dataTestSubj, telemetryId, pageHeader }) => (
diff --git a/x-pack/plugins/uptime/server/index.ts b/x-pack/plugins/uptime/server/index.ts index a48ae37d077f9..7c3b2ec345bd6 100644 --- a/x-pack/plugins/uptime/server/index.ts +++ b/x-pack/plugins/uptime/server/index.ts @@ -11,4 +11,4 @@ import { Plugin } from './plugin'; export const plugin = (initializerContext: PluginInitializerContext) => new Plugin(initializerContext); -export { config } from './config'; +export { config } from '../common/config'; diff --git a/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts index 8f1d8ffefbb9f..d9648a8aae575 100644 --- a/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts @@ -18,7 +18,7 @@ import { MlPluginSetup as MlSetup } from '../../../../../ml/server'; import { RuleRegistryPluginSetupContract } from '../../../../../rule_registry/server'; import { UptimeESClient } from '../../lib'; import type { UptimeRouter } from '../../../types'; -import { UptimeConfig } from '../../../config'; +import { UptimeConfig } from '../../../../common/config'; export type UMElasticsearchQueryFn = ( params: { diff --git a/x-pack/plugins/uptime/server/lib/saved_objects/saved_objects.ts b/x-pack/plugins/uptime/server/lib/saved_objects/saved_objects.ts index b731d5d393cf6..7a53a37b804e9 100644 --- a/x-pack/plugins/uptime/server/lib/saved_objects/saved_objects.ts +++ b/x-pack/plugins/uptime/server/lib/saved_objects/saved_objects.ts @@ -12,7 +12,7 @@ import { import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../common/constants'; import { DynamicSettings } from '../../../common/runtime_types'; import { UMSavedObjectsQueryFn } from '../adapters'; -import { UptimeConfig } from '../../config'; +import { UptimeConfig } from '../../../common/config'; import { settingsObjectId, umDynamicSettings } from './uptime_settings'; import { syntheticsMonitor } from './synthetics_monitor'; diff --git a/x-pack/plugins/uptime/server/plugin.ts b/x-pack/plugins/uptime/server/plugin.ts index ed3b58a4cfb57..b1b85eb943c81 100644 --- a/x-pack/plugins/uptime/server/plugin.ts +++ b/x-pack/plugins/uptime/server/plugin.ts @@ -19,7 +19,7 @@ import { KibanaTelemetryAdapter, UptimeCorePlugins } from './lib/adapters'; import { registerUptimeSavedObjects, savedObjectsAdapter } from './lib/saved_objects/saved_objects'; import { mappingFromFieldMap } from '../../rule_registry/common/mapping_from_field_map'; import { Dataset } from '../../rule_registry/server'; -import { UptimeConfig } from './config'; +import { UptimeConfig } from '../common/config'; export type UptimeRuleRegistry = ReturnType['ruleRegistry']; @@ -28,7 +28,7 @@ export class Plugin implements PluginType { private initContext: PluginInitializerContext; private logger?: Logger; - constructor(_initializerContext: PluginInitializerContext) { + constructor(_initializerContext: PluginInitializerContext) { this.initContext = _initializerContext; } From 14ed0cb89952fd6ff904f723b2e0a435961a5aa2 Mon Sep 17 00:00:00 2001 From: Mat Schaffer Date: Thu, 25 Nov 2021 12:24:34 +0900 Subject: [PATCH 15/46] Switch monitoring alerts CCS to use remote glob (#118647) * Switch monitoring alerts CCS to use remote glob Rather than expanding all available remotes which can exceed netty buffers when many remotes are present. * Fix additional availableCcs as string[] references * Fix code warnings Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../plugins/monitoring/server/alerts/base_rule.ts | 14 ++++++-------- .../server/alerts/ccr_read_exceptions_rule.ts | 2 +- .../server/alerts/cluster_health_rule.ts | 2 +- .../monitoring/server/alerts/cpu_usage_rule.ts | 2 +- .../monitoring/server/alerts/disk_usage_rule.ts | 2 +- .../alerts/elasticsearch_version_mismatch_rule.ts | 2 +- .../server/alerts/kibana_version_mismatch_rule.ts | 2 +- .../server/alerts/large_shard_size_rule.ts | 2 +- .../server/alerts/license_expiration_rule.ts | 2 +- .../alerts/logstash_version_mismatch_rule.ts | 2 +- .../monitoring/server/alerts/memory_usage_rule.ts | 2 +- .../server/alerts/missing_monitoring_data_rule.ts | 2 +- .../server/alerts/nodes_changed_rule.ts | 2 +- .../alerts/thread_pool_rejections_rule_base.ts | 2 +- .../collectors/get_usage_collector.ts | 7 ++----- .../collectors/lib/fetch_license_type.test.ts | 2 +- .../collectors/lib/fetch_license_type.ts | 2 +- .../lib/get_stack_products_usage.test.ts | 2 +- .../collectors/lib/get_stack_products_usage.ts | 2 +- .../lib/alerts/get_ccs_index_pattern.test.ts | 15 ++++----------- .../server/lib/alerts/get_ccs_index_pattern.ts | 8 +++----- 21 files changed, 32 insertions(+), 46 deletions(-) diff --git a/x-pack/plugins/monitoring/server/alerts/base_rule.ts b/x-pack/plugins/monitoring/server/alerts/base_rule.ts index 4a7e78f535253..51b779083bf4b 100644 --- a/x-pack/plugins/monitoring/server/alerts/base_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/base_rule.ts @@ -27,13 +27,12 @@ import { CommonAlertFilter, CommonAlertParams, } from '../../common/types/alerts'; -import { fetchAvailableCcs } from '../lib/alerts/fetch_available_ccs'; import { fetchClusters } from '../lib/alerts/fetch_clusters'; import { getCcsIndexPattern } from '../lib/alerts/get_ccs_index_pattern'; import { INDEX_PATTERN_ELASTICSEARCH } from '../../common/constants'; import { AlertSeverity } from '../../common/enums'; import { appendMetricbeatIndex } from '../lib/alerts/append_mb_index'; -import { parseDuration } from '../../../alerting/common/parse_duration'; +import { parseDuration } from '../../../alerting/common'; import { Globals } from '../static_globals'; type ExecutedState = @@ -125,8 +124,7 @@ export class BaseRule { }); if (existingRuleData.total > 0) { - const existingRule = existingRuleData.data[0] as Alert; - return existingRule; + return existingRuleData.data[0] as Alert; } const ruleActions = []; @@ -228,7 +226,7 @@ export class BaseRule { ); const esClient = services.scopedClusterClient.asCurrentUser; - const availableCcs = Globals.app.config.ui.ccs.enabled ? await fetchAvailableCcs(esClient) : []; + const availableCcs = Globals.app.config.ui.ccs.enabled; const clusters = await this.fetchClusters(esClient, params as CommonAlertParams, availableCcs); const data = await this.fetchData(params, esClient, clusters, availableCcs); return await this.processData(data, clusters, services, state); @@ -237,10 +235,10 @@ export class BaseRule { protected async fetchClusters( esClient: ElasticsearchClient, params: CommonAlertParams, - ccs?: string[] + ccs?: boolean ) { let esIndexPattern = appendMetricbeatIndex(Globals.app.config, INDEX_PATTERN_ELASTICSEARCH); - if (ccs?.length) { + if (ccs) { esIndexPattern = getCcsIndexPattern(esIndexPattern, ccs); } if (!params.limit) { @@ -262,7 +260,7 @@ export class BaseRule { params: CommonAlertParams | unknown, esClient: ElasticsearchClient, clusters: AlertCluster[], - availableCcs: string[] + availableCcs: boolean ): Promise> { throw new Error('Child classes must implement `fetchData`'); } diff --git a/x-pack/plugins/monitoring/server/alerts/ccr_read_exceptions_rule.ts b/x-pack/plugins/monitoring/server/alerts/ccr_read_exceptions_rule.ts index e3a3537ea2eaf..9b2f9b9fb3ed7 100644 --- a/x-pack/plugins/monitoring/server/alerts/ccr_read_exceptions_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/ccr_read_exceptions_rule.ts @@ -73,7 +73,7 @@ export class CCRReadExceptionsRule extends BaseRule { params: CommonAlertParams, esClient: ElasticsearchClient, clusters: AlertCluster[], - availableCcs: string[] + availableCcs: boolean ): Promise { let esIndexPattern = appendMetricbeatIndex(Globals.app.config, INDEX_PATTERN_ELASTICSEARCH); if (availableCcs) { diff --git a/x-pack/plugins/monitoring/server/alerts/cluster_health_rule.ts b/x-pack/plugins/monitoring/server/alerts/cluster_health_rule.ts index b9b9b90845eea..e85fb33cd76bd 100644 --- a/x-pack/plugins/monitoring/server/alerts/cluster_health_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/cluster_health_rule.ts @@ -67,7 +67,7 @@ export class ClusterHealthRule extends BaseRule { params: CommonAlertParams, esClient: ElasticsearchClient, clusters: AlertCluster[], - availableCcs: string[] + availableCcs: boolean ): Promise { let esIndexPattern = appendMetricbeatIndex(Globals.app.config, INDEX_PATTERN_ELASTICSEARCH); if (availableCcs) { diff --git a/x-pack/plugins/monitoring/server/alerts/cpu_usage_rule.ts b/x-pack/plugins/monitoring/server/alerts/cpu_usage_rule.ts index 7e38efcb819ea..b41783d449c02 100644 --- a/x-pack/plugins/monitoring/server/alerts/cpu_usage_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/cpu_usage_rule.ts @@ -61,7 +61,7 @@ export class CpuUsageRule extends BaseRule { params: CommonAlertParams, esClient: ElasticsearchClient, clusters: AlertCluster[], - availableCcs: string[] + availableCcs: boolean ): Promise { let esIndexPattern = appendMetricbeatIndex(Globals.app.config, INDEX_PATTERN_ELASTICSEARCH); if (availableCcs) { diff --git a/x-pack/plugins/monitoring/server/alerts/disk_usage_rule.ts b/x-pack/plugins/monitoring/server/alerts/disk_usage_rule.ts index bac70baebb4e2..17dff8ea6a9dd 100644 --- a/x-pack/plugins/monitoring/server/alerts/disk_usage_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/disk_usage_rule.ts @@ -60,7 +60,7 @@ export class DiskUsageRule extends BaseRule { params: CommonAlertParams, esClient: ElasticsearchClient, clusters: AlertCluster[], - availableCcs: string[] + availableCcs: boolean ): Promise { let esIndexPattern = appendMetricbeatIndex(Globals.app.config, INDEX_PATTERN_ELASTICSEARCH); if (availableCcs) { diff --git a/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_rule.ts b/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_rule.ts index 352cac531f8e8..b873a20c874b5 100644 --- a/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/elasticsearch_version_mismatch_rule.ts @@ -56,7 +56,7 @@ export class ElasticsearchVersionMismatchRule extends BaseRule { params: CommonAlertParams, esClient: ElasticsearchClient, clusters: AlertCluster[], - availableCcs: string[] + availableCcs: boolean ): Promise { let esIndexPattern = appendMetricbeatIndex(Globals.app.config, INDEX_PATTERN_ELASTICSEARCH); if (availableCcs) { diff --git a/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_rule.ts b/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_rule.ts index 6d9410ed0e5a0..79f449f8e7ef7 100644 --- a/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/kibana_version_mismatch_rule.ts @@ -69,7 +69,7 @@ export class KibanaVersionMismatchRule extends BaseRule { params: CommonAlertParams, esClient: ElasticsearchClient, clusters: AlertCluster[], - availableCcs: string[] + availableCcs: boolean ): Promise { let kibanaIndexPattern = appendMetricbeatIndex(Globals.app.config, INDEX_PATTERN_KIBANA); if (availableCcs) { diff --git a/x-pack/plugins/monitoring/server/alerts/large_shard_size_rule.ts b/x-pack/plugins/monitoring/server/alerts/large_shard_size_rule.ts index b0370a23159d7..3009995e2f292 100644 --- a/x-pack/plugins/monitoring/server/alerts/large_shard_size_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/large_shard_size_rule.ts @@ -61,7 +61,7 @@ export class LargeShardSizeRule extends BaseRule { params: CommonAlertParams & { indexPattern: string }, esClient: ElasticsearchClient, clusters: AlertCluster[], - availableCcs: string[] + availableCcs: boolean ): Promise { let esIndexPattern = appendMetricbeatIndex(Globals.app.config, INDEX_PATTERN_ELASTICSEARCH); if (availableCcs) { diff --git a/x-pack/plugins/monitoring/server/alerts/license_expiration_rule.ts b/x-pack/plugins/monitoring/server/alerts/license_expiration_rule.ts index c26929b05ab26..fc050bd678012 100644 --- a/x-pack/plugins/monitoring/server/alerts/license_expiration_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/license_expiration_rule.ts @@ -81,7 +81,7 @@ export class LicenseExpirationRule extends BaseRule { params: CommonAlertParams, esClient: ElasticsearchClient, clusters: AlertCluster[], - availableCcs: string[] + availableCcs: boolean ): Promise { let esIndexPattern = appendMetricbeatIndex(Globals.app.config, INDEX_PATTERN_ELASTICSEARCH); if (availableCcs) { diff --git a/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_rule.ts b/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_rule.ts index e59ed9efbefb2..6d7c06c1c1e07 100644 --- a/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/logstash_version_mismatch_rule.ts @@ -56,7 +56,7 @@ export class LogstashVersionMismatchRule extends BaseRule { params: CommonAlertParams, esClient: ElasticsearchClient, clusters: AlertCluster[], - availableCcs: string[] + availableCcs: boolean ): Promise { let logstashIndexPattern = appendMetricbeatIndex(Globals.app.config, INDEX_PATTERN_LOGSTASH); if (availableCcs) { diff --git a/x-pack/plugins/monitoring/server/alerts/memory_usage_rule.ts b/x-pack/plugins/monitoring/server/alerts/memory_usage_rule.ts index d94e1234ce813..25b12379f8d3a 100644 --- a/x-pack/plugins/monitoring/server/alerts/memory_usage_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/memory_usage_rule.ts @@ -65,7 +65,7 @@ export class MemoryUsageRule extends BaseRule { params: CommonAlertParams, esClient: ElasticsearchClient, clusters: AlertCluster[], - availableCcs: string[] + availableCcs: boolean ): Promise { let esIndexPattern = appendMetricbeatIndex(Globals.app.config, INDEX_PATTERN_ELASTICSEARCH); if (availableCcs) { diff --git a/x-pack/plugins/monitoring/server/alerts/missing_monitoring_data_rule.ts b/x-pack/plugins/monitoring/server/alerts/missing_monitoring_data_rule.ts index 1b45b19fe89f8..50ba9fa9e3586 100644 --- a/x-pack/plugins/monitoring/server/alerts/missing_monitoring_data_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/missing_monitoring_data_rule.ts @@ -60,7 +60,7 @@ export class MissingMonitoringDataRule extends BaseRule { params: CommonAlertParams, esClient: ElasticsearchClient, clusters: AlertCluster[], - availableCcs: string[] + availableCcs: boolean ): Promise { let indexPattern = appendMetricbeatIndex(Globals.app.config, INDEX_PATTERN); if (availableCcs) { diff --git a/x-pack/plugins/monitoring/server/alerts/nodes_changed_rule.ts b/x-pack/plugins/monitoring/server/alerts/nodes_changed_rule.ts index 6645466f30c73..545d6331d225e 100644 --- a/x-pack/plugins/monitoring/server/alerts/nodes_changed_rule.ts +++ b/x-pack/plugins/monitoring/server/alerts/nodes_changed_rule.ts @@ -105,7 +105,7 @@ export class NodesChangedRule extends BaseRule { params: CommonAlertParams, esClient: ElasticsearchClient, clusters: AlertCluster[], - availableCcs: string[] + availableCcs: boolean ): Promise { let esIndexPattern = appendMetricbeatIndex(Globals.app.config, INDEX_PATTERN_ELASTICSEARCH); if (availableCcs) { diff --git a/x-pack/plugins/monitoring/server/alerts/thread_pool_rejections_rule_base.ts b/x-pack/plugins/monitoring/server/alerts/thread_pool_rejections_rule_base.ts index 678f8b429167f..e6c2002eaff87 100644 --- a/x-pack/plugins/monitoring/server/alerts/thread_pool_rejections_rule_base.ts +++ b/x-pack/plugins/monitoring/server/alerts/thread_pool_rejections_rule_base.ts @@ -71,7 +71,7 @@ export class ThreadPoolRejectionsRuleBase extends BaseRule { params: ThreadPoolRejectionsAlertParams, esClient: ElasticsearchClient, clusters: AlertCluster[], - availableCcs: string[] + availableCcs: boolean ): Promise { let esIndexPattern = appendMetricbeatIndex(Globals.app.config, INDEX_PATTERN_ELASTICSEARCH); if (availableCcs) { diff --git a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/get_usage_collector.ts b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/get_usage_collector.ts index 558a79e03dcb7..4c454637bf8bb 100644 --- a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/get_usage_collector.ts +++ b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/get_usage_collector.ts @@ -8,7 +8,6 @@ import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { IClusterClient } from 'src/core/server'; import { MonitoringConfig } from '../../config'; -import { fetchAvailableCcs } from '../../lib/alerts/fetch_available_ccs'; import { getStackProductsUsage } from './lib/get_stack_products_usage'; import { fetchLicenseType } from './lib/fetch_license_type'; import { MonitoringUsage, StackProductUsage, MonitoringClusterStackProductUsage } from './types'; @@ -106,7 +105,7 @@ export function getMonitoringUsageCollector( ? getClient().asScoped(kibanaRequest).asCurrentUser : getClient().asInternalUser; const usageClusters: MonitoringClusterStackProductUsage[] = []; - const availableCcs = config.ui.ccs.enabled ? await fetchAvailableCcs(callCluster) : []; + const availableCcs = config.ui.ccs.enabled; const elasticsearchIndex = getCcsIndexPattern(INDEX_PATTERN_ELASTICSEARCH, availableCcs); const clusters = await fetchClusters(callCluster, elasticsearchIndex); for (const cluster of clusters) { @@ -127,12 +126,10 @@ export function getMonitoringUsageCollector( }); } - const usage = { + return { hasMonitoringData: usageClusters.length > 0, clusters: usageClusters, }; - - return usage; }, }); } diff --git a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_license_type.test.ts b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_license_type.test.ts index 89050963c9201..93e21072d0e34 100644 --- a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_license_type.test.ts +++ b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_license_type.test.ts @@ -10,7 +10,7 @@ import { fetchLicenseType } from './fetch_license_type'; describe('fetchLicenseType', () => { const clusterUuid = '1abcde2'; - const availableCcs: string[] = []; + const availableCcs = false; const callCluster = { search: jest.fn().mockImplementation(() => ({ body: { diff --git a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_license_type.ts b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_license_type.ts index 0f0d75546d28d..5a0c714c8f1d3 100644 --- a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_license_type.ts +++ b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/fetch_license_type.ts @@ -13,7 +13,7 @@ import { getCcsIndexPattern } from '../../../lib/alerts/get_ccs_index_pattern'; export async function fetchLicenseType( client: ElasticsearchClient, - availableCcs: string[], + availableCcs: boolean, clusterUuid: string ) { let index = INDEX_PATTERN_ELASTICSEARCH; diff --git a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/get_stack_products_usage.test.ts b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/get_stack_products_usage.test.ts index 78e1e98def5a2..a9d7fa05883c5 100644 --- a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/get_stack_products_usage.test.ts +++ b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/get_stack_products_usage.test.ts @@ -15,7 +15,7 @@ describe('getStackProductsUsage', () => { }, }; const clusterUuid = '1abcde2'; - const availableCcs: string[] = []; + const availableCcs = false; const callCluster = { search: jest.fn().mockImplementation(() => ({ body: { diff --git a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/get_stack_products_usage.ts b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/get_stack_products_usage.ts index 25a1892a9f38d..abe69a9b637c0 100644 --- a/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/get_stack_products_usage.ts +++ b/x-pack/plugins/monitoring/server/kibana_monitoring/collectors/lib/get_stack_products_usage.ts @@ -25,7 +25,7 @@ import { getCcsIndexPattern } from '../../../lib/alerts/get_ccs_index_pattern'; export const getStackProductsUsage = async ( config: MonitoringConfig, callCluster: ElasticsearchClient, - availableCcs: string[], + availableCcs: boolean, clusterUuid: string ): Promise< Pick< diff --git a/x-pack/plugins/monitoring/server/lib/alerts/get_ccs_index_pattern.test.ts b/x-pack/plugins/monitoring/server/lib/alerts/get_ccs_index_pattern.test.ts index 7377f00c43d5b..a2b47440c2a97 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/get_ccs_index_pattern.test.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/get_ccs_index_pattern.test.ts @@ -8,19 +8,12 @@ import { getCcsIndexPattern } from './get_ccs_index_pattern'; describe('getCcsIndexPattern', () => { - it('should return an index pattern including remotes', () => { - const remotes = ['Remote1', 'Remote2']; - const index = '.monitoring-es-*'; - const result = getCcsIndexPattern(index, remotes); - expect(result).toBe('.monitoring-es-*,Remote1:.monitoring-es-*,Remote2:.monitoring-es-*'); - }); - - it('should return an index pattern from multiple index patterns including remotes', () => { - const remotes = ['Remote1', 'Remote2']; + it('should return an index pattern from multiple index patterns including CCS globs', () => { + const availableCcs = true; const index = '.monitoring-es-*,.monitoring-kibana-*'; - const result = getCcsIndexPattern(index, remotes); + const result = getCcsIndexPattern(index, availableCcs); expect(result).toBe( - '.monitoring-es-*,.monitoring-kibana-*,Remote1:.monitoring-es-*,Remote2:.monitoring-es-*,Remote1:.monitoring-kibana-*,Remote2:.monitoring-kibana-*' + '.monitoring-es-*,.monitoring-kibana-*,*:.monitoring-es-*,*:.monitoring-kibana-*' ); }); }); diff --git a/x-pack/plugins/monitoring/server/lib/alerts/get_ccs_index_pattern.ts b/x-pack/plugins/monitoring/server/lib/alerts/get_ccs_index_pattern.ts index df863e0f683fc..84dbb306d5ee0 100644 --- a/x-pack/plugins/monitoring/server/lib/alerts/get_ccs_index_pattern.ts +++ b/x-pack/plugins/monitoring/server/lib/alerts/get_ccs_index_pattern.ts @@ -5,15 +5,13 @@ * 2.0. */ -export function getCcsIndexPattern(indexPattern: string, remotes: string[]): string { - if (remotes.length === 0) { +export function getCcsIndexPattern(indexPattern: string, availableCcs: boolean): string { + if (!availableCcs) { return indexPattern; } const patternsToAdd = []; for (const index of indexPattern.split(',')) { - for (const remote of remotes) { - patternsToAdd.push(`${remote}:${index}`); - } + patternsToAdd.push(`*:${index}`); } return [...indexPattern.split(','), ...patternsToAdd].join(','); } From ba9dfeafa0c45c6ebd400e0f88e1f06ec47b2dc7 Mon Sep 17 00:00:00 2001 From: Miriam <31922082+MiriamAparicio@users.noreply.github.com> Date: Thu, 25 Nov 2021 08:21:04 +0000 Subject: [PATCH 16/46] [APM] Errors: Enhancements to the Errors list page (part II) (#118878) * refactor errors groups endpoints * Add sparkline and reorder columns * Fix i18n * Delete is_aggregation_accurate not used * fix rebase conflicts * rename endpoint path * fix api test * fix i18n conflict * fix e2e tests * PR review * rename variables for consistency * fix tests after rename endpoints * rename functions * fix conflict * fix i18n conflict * fix i18n conflict --- .../read_only_user/errors/errors_page.spec.ts | 12 +- .../service_overview/header_filters.spec.ts | 2 +- .../service_overview/time_comparison.spec.ts | 2 +- .../error_group_list.stories.tsx | 37 ++-- .../error_group_list/index.tsx | 88 +++++--- .../app/error_group_overview/index.tsx | 126 +++++++++-- .../get_columns.tsx | 14 +- .../service_overview_errors_table/index.tsx | 16 +- .../errors/__snapshots__/queries.test.ts.snap | 28 ++- .../server/routes/errors/get_error_groups.ts | 121 ----------- .../get_error_group_detailed_statistics.ts} | 8 +- .../get_error_group_main_statistics.ts} | 59 +++-- .../get_error_group_sample.ts | 14 +- .../apm/server/routes/errors/queries.test.ts | 14 +- .../plugins/apm/server/routes/errors/route.ts | 87 +++++++- .../get_service_error_groups/index.ts | 205 ------------------ .../apm/server/routes/services/route.ts | 98 +-------- .../translations/translations/ja-JP.json | 4 +- .../translations/translations/zh-CN.json | 5 +- .../tests/errors/error_group_list.spec.ts | 12 +- .../tests/feature_controls.spec.ts | 2 +- .../error_groups_detailed_statistics.spec.ts | 6 +- .../error_groups_main_statistics.spec.ts | 17 +- .../error_groups/get_error_group_ids.ts | 4 +- 24 files changed, 388 insertions(+), 593 deletions(-) delete mode 100644 x-pack/plugins/apm/server/routes/errors/get_error_groups.ts rename x-pack/plugins/apm/server/routes/{services/get_service_error_groups/get_service_error_group_detailed_statistics.ts => errors/get_error_groups/get_error_group_detailed_statistics.ts} (94%) rename x-pack/plugins/apm/server/routes/{services/get_service_error_groups/get_service_error_group_main_statistics.ts => errors/get_error_groups/get_error_group_main_statistics.ts} (60%) rename x-pack/plugins/apm/server/routes/errors/{ => get_error_groups}/get_error_group_sample.ts (79%) delete mode 100644 x-pack/plugins/apm/server/routes/services/get_service_error_groups/index.ts diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts index fd6890d3a7bed..d08e22092d592 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/errors/errors_page.spec.ts @@ -91,19 +91,13 @@ describe('Errors page', () => { it('sorts by ocurrences', () => { cy.visit(javaServiceErrorsPageHref); cy.contains('span', 'Occurrences').click(); - cy.url().should( - 'include', - '&sortField=occurrenceCount&sortDirection=asc' - ); + cy.url().should('include', '&sortField=occurrences&sortDirection=asc'); }); it('sorts by latest occurrences', () => { cy.visit(javaServiceErrorsPageHref); - cy.contains('span', 'Latest occurrence').click(); - cy.url().should( - 'include', - '&sortField=latestOccurrenceAt&sortDirection=asc' - ); + cy.contains('span', 'Last seen').click(); + cy.url().should('include', '&sortField=lastSeen&sortDirection=asc'); }); }); }); diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/header_filters.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/header_filters.spec.ts index a7667002d4ea9..49d7104f44a88 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/header_filters.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/header_filters.spec.ts @@ -48,7 +48,7 @@ const apisToIntercept = [ }, { endpoint: - '/internal/apm/services/opbeans-node/error_groups/main_statistics?*', + '/internal/apm/services/opbeans-node/errors/groups/main_statistics?*', name: 'errorGroupsMainStatisticsRequest', }, { diff --git a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/time_comparison.spec.ts b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/time_comparison.spec.ts index e905c86a5854c..d513dcaef6842 100644 --- a/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/time_comparison.spec.ts +++ b/x-pack/plugins/apm/ftr_e2e/cypress/integration/read_only_user/service_overview/time_comparison.spec.ts @@ -40,7 +40,7 @@ const apisToIntercept = [ }, { endpoint: - '/internal/apm/services/opbeans-java/error_groups/detailed_statistics?*', + '/internal/apm/services/opbeans-java/errors/groups/detailed_statistics?*', name: 'errorGroupsDetailedRequest', }, { diff --git a/x-pack/plugins/apm/public/components/app/error_group_overview/error_group_list/error_group_list.stories.tsx b/x-pack/plugins/apm/public/components/app/error_group_overview/error_group_list/error_group_list.stories.tsx index e61e43c8bb7ea..3d6a9af707955 100644 --- a/x-pack/plugins/apm/public/components/app/error_group_overview/error_group_list/error_group_list.stories.tsx +++ b/x-pack/plugins/apm/public/components/app/error_group_overview/error_group_list/error_group_list.stories.tsx @@ -38,52 +38,49 @@ export const Example: Story = (args) => { return ; }; Example.args = { - items: [ + mainStatistics: [ { - message: 'net/http: abort Handler', - occurrenceCount: 14, + name: 'net/http: abort Handler', + occurrences: 14, culprit: 'Main.func2', groupId: '83a653297ec29afed264d7b60d5cda7b', - latestOccurrenceAt: '2021-10-21T16:18:41.434Z', + lastSeen: 1634833121434, handled: false, type: 'errorString', }, { - message: 'POST /api/orders (500)', - occurrenceCount: 5, + name: 'POST /api/orders (500)', + occurrences: 5, culprit: 'logrusMiddleware', groupId: '7a640436a9be648fd708703d1ac84650', - latestOccurrenceAt: '2021-10-21T16:18:40.162Z', + lastSeen: 1634833121434, handled: false, type: 'OpError', }, { - message: - 'write tcp 10.36.2.24:3000->10.36.1.14:34232: write: connection reset by peer', - occurrenceCount: 4, + name: 'write tcp 10.36.2.24:3000->10.36.1.14:34232: write: connection reset by peer', + occurrences: 4, culprit: 'apiHandlers.getProductCustomers', groupId: '95ca0e312c109aa11e298bcf07f1445b', - latestOccurrenceAt: '2021-10-21T16:18:42.650Z', + lastSeen: 1634833121434, handled: false, type: 'OpError', }, { - message: - 'write tcp 10.36.0.21:3000->10.36.1.252:57070: write: connection reset by peer', - occurrenceCount: 3, + name: 'write tcp 10.36.0.21:3000->10.36.1.252:57070: write: connection reset by peer', + occurrences: 3, culprit: 'apiHandlers.getCustomers', groupId: '4053d7e33d2b716c819bd96d9d6121a2', - latestOccurrenceAt: '2021-10-21T16:07:44.078Z', + lastSeen: 1634833121434, handled: false, type: 'OpError', }, { - message: - 'write tcp 10.36.0.21:3000->10.36.0.88:33926: write: broken pipe', - occurrenceCount: 2, + name: 'write tcp 10.36.0.21:3000->10.36.0.88:33926: write: broken pipe', + occurrences: 2, culprit: 'apiHandlers.getOrders', groupId: '94f4ca8ec8c02e5318cf03f46ae4c1f3', - latestOccurrenceAt: '2021-10-21T16:13:45.742Z', + lastSeen: 1634833121434, handled: false, type: 'OpError', }, @@ -95,6 +92,6 @@ export const EmptyState: Story = (args) => { return ; }; EmptyState.args = { - items: [], + mainStatistics: [], serviceName: 'test service', }; diff --git a/x-pack/plugins/apm/public/components/app/error_group_overview/error_group_list/index.tsx b/x-pack/plugins/apm/public/components/app/error_group_overview/error_group_list/index.tsx index 7facc9a4ca376..e252eba15ade1 100644 --- a/x-pack/plugins/apm/public/components/app/error_group_overview/error_group_list/index.tsx +++ b/x-pack/plugins/apm/public/components/app/error_group_overview/error_group_list/index.tsx @@ -11,9 +11,9 @@ import { EuiToolTip, RIGHT_ALIGNMENT, } from '@elastic/eui'; -import numeral from '@elastic/numeral'; import { i18n } from '@kbn/i18n'; import React, { useMemo } from 'react'; +import { asInteger } from '../../../../../common/utils/formatters'; import { euiStyled } from '../../../../../../../../src/plugins/kibana_react/common'; import { NOT_AVAILABLE_LABEL } from '../../../../../common/i18n'; import { useLegacyUrlParams } from '../../../../context/url_params_context/use_url_params'; @@ -24,6 +24,7 @@ import { ErrorOverviewLink } from '../../../shared/Links/apm/ErrorOverviewLink'; import { APMQueryParams } from '../../../shared/Links/url_helpers'; import { ITableColumn, ManagedTable } from '../../../shared/managed_table'; import { TimestampTooltip } from '../../../shared/TimestampTooltip'; +import { SparkPlot } from '../../../shared/charts/spark_plot'; const GroupIdLink = euiStyled(ErrorDetailLink)` font-family: ${({ theme }) => theme.eui.euiCodeFontFamily}; @@ -48,14 +49,23 @@ const Culprit = euiStyled.div` `; type ErrorGroupItem = - APIReturnType<'GET /internal/apm/services/{serviceName}/errors'>['errorGroups'][0]; + APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/main_statistics'>['errorGroups'][0]; +type ErrorGroupDetailedStatistics = + APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>; interface Props { - items: ErrorGroupItem[]; + mainStatistics: ErrorGroupItem[]; serviceName: string; + detailedStatistics: ErrorGroupDetailedStatistics; + comparisonEnabled?: boolean; } -function ErrorGroupList({ items, serviceName }: Props) { +function ErrorGroupList({ + mainStatistics, + serviceName, + detailedStatistics, + comparisonEnabled, +}: Props) { const { urlParams } = useLegacyUrlParams(); const columns = useMemo(() => { @@ -132,13 +142,13 @@ function ErrorGroupList({ items, serviceName }: Props) { - {item.message || NOT_AVAILABLE_LABEL} + {item.name || NOT_AVAILABLE_LABEL}
@@ -167,46 +177,64 @@ function ErrorGroupList({ items, serviceName }: Props) { ), }, { + field: 'lastSeen', + sortable: true, + name: i18n.translate('xpack.apm.errorsTable.lastSeenColumnLabel', { + defaultMessage: 'Last seen', + }), + align: RIGHT_ALIGNMENT, + render: (_, { lastSeen }) => + lastSeen ? ( + + ) : ( + NOT_AVAILABLE_LABEL + ), + }, + { + field: 'occurrences', name: i18n.translate('xpack.apm.errorsTable.occurrencesColumnLabel', { defaultMessage: 'Occurrences', }), - field: 'occurrenceCount', sortable: true, dataType: 'number', - render: (_, { occurrenceCount }) => - occurrenceCount - ? numeral(occurrenceCount).format('0.[0]a') - : NOT_AVAILABLE_LABEL, - }, - { - field: 'latestOccurrenceAt', - sortable: true, - name: i18n.translate( - 'xpack.apm.errorsTable.latestOccurrenceColumnLabel', - { - defaultMessage: 'Latest occurrence', - } - ), align: RIGHT_ALIGNMENT, - render: (_, { latestOccurrenceAt }) => - latestOccurrenceAt ? ( - - ) : ( - NOT_AVAILABLE_LABEL - ), + render: (_, { occurrences, groupId }) => { + const currentPeriodTimeseries = + detailedStatistics?.currentPeriod?.[groupId]?.timeseries; + const previousPeriodTimeseries = + detailedStatistics?.previousPeriod?.[groupId]?.timeseries; + return ( + + ); + }, }, ] as Array>; - }, [serviceName, urlParams]); + }, [serviceName, urlParams, detailedStatistics, comparisonEnabled]); return ( diff --git a/x-pack/plugins/apm/public/components/app/error_group_overview/index.tsx b/x-pack/plugins/apm/public/components/app/error_group_overview/index.tsx index 9e113b37a1394..c836f5f7acd61 100644 --- a/x-pack/plugins/apm/public/components/app/error_group_overview/index.tsx +++ b/x-pack/plugins/apm/public/components/app/error_group_overview/index.tsx @@ -14,24 +14,60 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React from 'react'; +import uuid from 'uuid'; import { useApmServiceContext } from '../../../context/apm_service/use_apm_service_context'; import { ChartPointerEventContextProvider } from '../../../context/chart_pointer_event/chart_pointer_event_context'; import { useApmParams } from '../../../hooks/use_apm_params'; import { useErrorGroupDistributionFetcher } from '../../../hooks/use_error_group_distribution_fetcher'; import { useFetcher } from '../../../hooks/use_fetcher'; import { useTimeRange } from '../../../hooks/use_time_range'; +import { APIReturnType } from '../../../services/rest/createCallApmApi'; import { FailedTransactionRateChart } from '../../shared/charts/failed_transaction_rate_chart'; +import { getTimeRangeComparison } from '../../shared/time_comparison/get_time_range_comparison'; import { ErrorDistribution } from '../error_group_details/Distribution'; import { ErrorGroupList } from './error_group_list'; +type ErrorGroupMainStatistics = + APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/main_statistics'>; +type ErrorGroupDetailedStatistics = + APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>; + +const INITIAL_STATE_MAIN_STATISTICS: { + errorGroupMainStatistics: ErrorGroupMainStatistics['errorGroups']; + requestId?: string; +} = { + errorGroupMainStatistics: [], + requestId: undefined, +}; + +const INITIAL_STATE_DETAILED_STATISTICS: ErrorGroupDetailedStatistics = { + currentPeriod: {}, + previousPeriod: {}, +}; + export function ErrorGroupOverview() { - const { serviceName } = useApmServiceContext(); + const { serviceName, transactionType } = useApmServiceContext(); const { - query: { environment, kuery, sortField, sortDirection, rangeFrom, rangeTo }, + query: { + environment, + kuery, + sortField, + sortDirection, + rangeFrom, + rangeTo, + comparisonType, + comparisonEnabled, + }, } = useApmParams('/services/{serviceName}/errors'); const { start, end } = useTimeRange({ rangeFrom, rangeTo }); + const { comparisonStart, comparisonEnd } = getTimeRangeComparison({ + start, + end, + comparisonType, + comparisonEnabled, + }); const { errorDistributionData, status } = useErrorGroupDistributionFetcher({ serviceName, @@ -40,30 +76,90 @@ export function ErrorGroupOverview() { kuery, }); - const { data: errorGroupListData } = useFetcher( - (callApmApi) => { - const normalizedSortDirection = sortDirection === 'asc' ? 'asc' : 'desc'; + const { data: errorGroupListData = INITIAL_STATE_MAIN_STATISTICS } = + useFetcher( + (callApmApi) => { + const normalizedSortDirection = + sortDirection === 'asc' ? 'asc' : 'desc'; - if (start && end) { + if (start && end && transactionType) { + return callApmApi({ + endpoint: + 'GET /internal/apm/services/{serviceName}/errors/groups/main_statistics', + params: { + path: { + serviceName, + }, + query: { + environment, + transactionType, + kuery, + start, + end, + sortField, + sortDirection: normalizedSortDirection, + }, + }, + }).then((response) => { + return { + // Everytime the main statistics is refetched, updates the requestId making the comparison API to be refetched. + requestId: uuid(), + errorGroupMainStatistics: response.errorGroups, + }; + }); + } + }, + [ + environment, + kuery, + serviceName, + transactionType, + start, + end, + sortField, + sortDirection, + ] + ); + + const { requestId, errorGroupMainStatistics } = errorGroupListData; + + const { + data: errorGroupDetailedStatistics = INITIAL_STATE_DETAILED_STATISTICS, + } = useFetcher( + (callApmApi) => { + if ( + requestId && + errorGroupMainStatistics.length && + start && + end && + transactionType + ) { return callApmApi({ - endpoint: 'GET /internal/apm/services/{serviceName}/errors', + endpoint: + 'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics', params: { - path: { - serviceName, - }, + path: { serviceName }, query: { environment, kuery, start, end, - sortField, - sortDirection: normalizedSortDirection, + numBuckets: 20, + transactionType, + groupIds: JSON.stringify( + errorGroupMainStatistics.map(({ groupId }) => groupId).sort() + ), + comparisonStart, + comparisonEnd, }, }, }); } }, - [environment, kuery, serviceName, start, end, sortField, sortDirection] + // only fetches agg results when requestId changes + // eslint-disable-next-line react-hooks/exhaustive-deps + [requestId], + { preservePreviousData: false } ); if (!errorDistributionData || !errorGroupListData) { @@ -110,8 +206,10 @@ export function ErrorGroupOverview() { diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/get_columns.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/get_columns.tsx index 14a8b59cd7826..aba1073bfe9c2 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/get_columns.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/get_columns.tsx @@ -16,9 +16,9 @@ import { TimestampTooltip } from '../../../shared/TimestampTooltip'; import { TruncateWithTooltip } from '../../../shared/truncate_with_tooltip'; type ErrorGroupMainStatistics = - APIReturnType<'GET /internal/apm/services/{serviceName}/error_groups/main_statistics'>; + APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/main_statistics'>; type ErrorGroupDetailedStatistics = - APIReturnType<'GET /internal/apm/services/{serviceName}/error_groups/detailed_statistics'>; + APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>; export function getColumns({ serviceName, @@ -28,14 +28,14 @@ export function getColumns({ serviceName: string; errorGroupDetailedStatistics: ErrorGroupDetailedStatistics; comparisonEnabled?: boolean; -}): Array> { +}): Array> { return [ { field: 'name', name: i18n.translate('xpack.apm.serviceOverview.errorsTableColumnName', { defaultMessage: 'Name', }), - render: (_, { name, group_id: errorGroupId }) => { + render: (_, { name, groupId: errorGroupId }) => { return ( { + render: (_, { occurrences, groupId: errorGroupId }) => { const currentPeriodTimeseries = errorGroupDetailedStatistics?.currentPeriod?.[errorGroupId] ?.timeseries; @@ -92,9 +92,9 @@ export function getColumns({ valueLabel={i18n.translate( 'xpack.apm.serviceOveriew.errorsTableOccurrences', { - defaultMessage: `{occurrencesCount} occ.`, + defaultMessage: `{occurrences} occ.`, values: { - occurrencesCount: asInteger(occurrences), + occurrences: asInteger(occurrences), }, } )} diff --git a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx index ce4ba85b233e2..28824b3b8a399 100644 --- a/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx +++ b/x-pack/plugins/apm/public/components/app/service_overview/service_overview_errors_table/index.tsx @@ -30,9 +30,9 @@ interface Props { serviceName: string; } type ErrorGroupMainStatistics = - APIReturnType<'GET /internal/apm/services/{serviceName}/error_groups/main_statistics'>; + APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/main_statistics'>; type ErrorGroupDetailedStatistics = - APIReturnType<'GET /internal/apm/services/{serviceName}/error_groups/detailed_statistics'>; + APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>; type SortDirection = 'asc' | 'desc'; type SortField = 'name' | 'lastSeen' | 'occurrences'; @@ -44,7 +44,7 @@ const DEFAULT_SORT = { }; const INITIAL_STATE_MAIN_STATISTICS: { - items: ErrorGroupMainStatistics['error_groups']; + items: ErrorGroupMainStatistics['errorGroups']; totalItems: number; requestId?: string; } = { @@ -97,7 +97,7 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) { } return callApmApi({ endpoint: - 'GET /internal/apm/services/{serviceName}/error_groups/main_statistics', + 'GET /internal/apm/services/{serviceName}/errors/groups/main_statistics', params: { path: { serviceName }, query: { @@ -110,7 +110,7 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) { }, }).then((response) => { const currentPageErrorGroups = orderBy( - response.error_groups, + response.errorGroups, field, direction ).slice(pageIndex * PAGE_SIZE, (pageIndex + 1) * PAGE_SIZE); @@ -119,7 +119,7 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) { // Everytime the main statistics is refetched, updates the requestId making the comparison API to be refetched. requestId: uuid(), items: currentPageErrorGroups, - totalItems: response.error_groups.length, + totalItems: response.errorGroups.length, }; }); }, @@ -150,7 +150,7 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) { if (requestId && items.length && start && end && transactionType) { return callApmApi({ endpoint: - 'GET /internal/apm/services/{serviceName}/error_groups/detailed_statistics', + 'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics', params: { path: { serviceName }, query: { @@ -161,7 +161,7 @@ export function ServiceOverviewErrorsTable({ serviceName }: Props) { numBuckets: 20, transactionType, groupIds: JSON.stringify( - items.map(({ group_id: groupId }) => groupId).sort() + items.map(({ groupId: groupId }) => groupId).sort() ), comparisonStart, comparisonEnd, diff --git a/x-pack/plugins/apm/server/routes/errors/__snapshots__/queries.test.ts.snap b/x-pack/plugins/apm/server/routes/errors/__snapshots__/queries.test.ts.snap index c0134170606d2..5602798c51ea4 100644 --- a/x-pack/plugins/apm/server/routes/errors/__snapshots__/queries.test.ts.snap +++ b/x-pack/plugins/apm/server/routes/errors/__snapshots__/queries.test.ts.snap @@ -78,11 +78,9 @@ Object { "@timestamp", ], "size": 1, - "sort": Array [ - Object { - "@timestamp": "desc", - }, - ], + "sort": Object { + "@timestamp": "desc", + }, }, }, }, @@ -103,6 +101,11 @@ Object { "service.name": "serviceName", }, }, + Object { + "term": Object { + "transaction.type": "request", + }, + }, Object { "range": Object { "@timestamp": Object { @@ -120,7 +123,7 @@ Object { } `; -exports[`error queries fetches multiple error groups when sortField = latestOccurrenceAt 1`] = ` +exports[`error queries fetches multiple error groups when sortField = lastSeen 1`] = ` Object { "apm": Object { "events": Array [ @@ -148,11 +151,9 @@ Object { "@timestamp", ], "size": 1, - "sort": Array [ - Object { - "@timestamp": "desc", - }, - ], + "sort": Object { + "@timestamp": "desc", + }, }, }, }, @@ -173,6 +174,11 @@ Object { "service.name": "serviceName", }, }, + Object { + "term": Object { + "transaction.type": "request", + }, + }, Object { "range": Object { "@timestamp": Object { diff --git a/x-pack/plugins/apm/server/routes/errors/get_error_groups.ts b/x-pack/plugins/apm/server/routes/errors/get_error_groups.ts deleted file mode 100644 index b26f3f4e7b4fe..0000000000000 --- a/x-pack/plugins/apm/server/routes/errors/get_error_groups.ts +++ /dev/null @@ -1,121 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { AggregationsTermsAggregationOrder } from '@elastic/elasticsearch/lib/api/types'; -import { ProcessorEvent } from '../../../common/processor_event'; -import { environmentQuery } from '../../../common/utils/environment_query'; -import { kqlQuery, rangeQuery } from '../../../../observability/server'; -import { - ERROR_CULPRIT, - ERROR_EXC_HANDLED, - ERROR_EXC_MESSAGE, - ERROR_EXC_TYPE, - ERROR_GROUP_ID, - ERROR_LOG_MESSAGE, - SERVICE_NAME, -} from '../../../common/elasticsearch_fieldnames'; -import { getErrorName } from '../../lib/helpers/get_error_name'; -import { Setup } from '../../lib/helpers/setup_request'; - -export async function getErrorGroups({ - environment, - kuery, - serviceName, - sortField, - sortDirection = 'desc', - setup, - start, - end, -}: { - environment: string; - kuery: string; - serviceName: string; - sortField?: string; - sortDirection?: 'asc' | 'desc'; - setup: Setup; - start: number; - end: number; -}) { - const { apmEventClient } = setup; - - // sort buckets by last occurrence of error - const sortByLatestOccurrence = sortField === 'latestOccurrenceAt'; - - const maxTimestampAggKey = 'max_timestamp'; - const order: AggregationsTermsAggregationOrder = sortByLatestOccurrence - ? { [maxTimestampAggKey]: sortDirection } - : { _count: sortDirection }; - - const params = { - apm: { - events: [ProcessorEvent.error as const], - }, - body: { - size: 0, - query: { - bool: { - filter: [ - { term: { [SERVICE_NAME]: serviceName } }, - ...rangeQuery(start, end), - ...environmentQuery(environment), - ...kqlQuery(kuery), - ], - }, - }, - aggs: { - error_groups: { - terms: { - field: ERROR_GROUP_ID, - size: 500, - order, - }, - aggs: { - sample: { - top_hits: { - _source: [ - ERROR_LOG_MESSAGE, - ERROR_EXC_MESSAGE, - ERROR_EXC_HANDLED, - ERROR_EXC_TYPE, - ERROR_CULPRIT, - ERROR_GROUP_ID, - '@timestamp', - ], - sort: [{ '@timestamp': 'desc' as const }], - size: 1, - }, - }, - ...(sortByLatestOccurrence - ? { [maxTimestampAggKey]: { max: { field: '@timestamp' } } } - : {}), - }, - }, - }, - }, - }; - - const resp = await apmEventClient.search('get_error_groups', params); - - // aggregations can be undefined when no matching indices are found. - // this is an exception rather than the rule so the ES type does not account for this. - const hits = (resp.aggregations?.error_groups.buckets || []).map((bucket) => { - const source = bucket.sample.hits.hits[0]._source; - const message = getErrorName(source); - - return { - message, - occurrenceCount: bucket.doc_count, - culprit: source.error.culprit, - groupId: source.error.grouping_key, - latestOccurrenceAt: source['@timestamp'], - handled: source.error.exception?.[0].handled, - type: source.error.exception?.[0].type, - }; - }); - - return hits; -} diff --git a/x-pack/plugins/apm/server/routes/services/get_service_error_groups/get_service_error_group_detailed_statistics.ts b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_detailed_statistics.ts similarity index 94% rename from x-pack/plugins/apm/server/routes/services/get_service_error_groups/get_service_error_group_detailed_statistics.ts rename to x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_detailed_statistics.ts index 17c538d0fd7ea..870c307a3f769 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_error_groups/get_service_error_group_detailed_statistics.ts +++ b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_detailed_statistics.ts @@ -18,7 +18,7 @@ import { environmentQuery } from '../../../../common/utils/environment_query'; import { getBucketSize } from '../../../lib/helpers/get_bucket_size'; import { Setup } from '../../../lib/helpers/setup_request'; -export async function getServiceErrorGroupDetailedStatistics({ +export async function getErrorGroupDetailedStatistics({ kuery, serviceName, setup, @@ -106,7 +106,7 @@ export async function getServiceErrorGroupDetailedStatistics({ }); } -export async function getServiceErrorGroupPeriods({ +export async function getErrorGroupPeriods({ kuery, serviceName, setup, @@ -141,7 +141,7 @@ export async function getServiceErrorGroupPeriods({ groupIds, }; - const currentPeriodPromise = getServiceErrorGroupDetailedStatistics({ + const currentPeriodPromise = getErrorGroupDetailedStatistics({ ...commonProps, start, end, @@ -149,7 +149,7 @@ export async function getServiceErrorGroupPeriods({ const previousPeriodPromise = comparisonStart && comparisonEnd - ? getServiceErrorGroupDetailedStatistics({ + ? getErrorGroupDetailedStatistics({ ...commonProps, start: comparisonStart, end: comparisonEnd, diff --git a/x-pack/plugins/apm/server/routes/services/get_service_error_groups/get_service_error_group_main_statistics.ts b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_main_statistics.ts similarity index 60% rename from x-pack/plugins/apm/server/routes/services/get_service_error_groups/get_service_error_group_main_statistics.ts rename to x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_main_statistics.ts index 8d174abb1bed5..e460991029915 100644 --- a/x-pack/plugins/apm/server/routes/services/get_service_error_groups/get_service_error_group_main_statistics.ts +++ b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_main_statistics.ts @@ -5,9 +5,13 @@ * 2.0. */ +import { AggregationsTermsAggregationOrder } from '@elastic/elasticsearch/lib/api/types'; import { kqlQuery, rangeQuery } from '../../../../../observability/server'; import { + ERROR_CULPRIT, + ERROR_EXC_HANDLED, ERROR_EXC_MESSAGE, + ERROR_EXC_TYPE, ERROR_GROUP_ID, ERROR_LOG_MESSAGE, SERVICE_NAME, @@ -18,27 +22,40 @@ import { environmentQuery } from '../../../../common/utils/environment_query'; import { getErrorName } from '../../../lib/helpers/get_error_name'; import { Setup } from '../../../lib/helpers/setup_request'; -export async function getServiceErrorGroupMainStatistics({ +export async function getErrorGroupMainStatistics({ kuery, serviceName, setup, - transactionType, environment, + transactionType, + sortField, + sortDirection = 'desc', start, end, }: { kuery: string; serviceName: string; setup: Setup; - transactionType: string; environment: string; + transactionType: string; + sortField?: string; + sortDirection?: 'asc' | 'desc'; start: number; end: number; }) { const { apmEventClient } = setup; + // sort buckets by last occurrence of error + const sortByLatestOccurrence = sortField === 'lastSeen'; + + const maxTimestampAggKey = 'max_timestamp'; + + const order: AggregationsTermsAggregationOrder = sortByLatestOccurrence + ? { [maxTimestampAggKey]: sortDirection } + : { _count: sortDirection }; + const response = await apmEventClient.search( - 'get_service_error_group_main_statistics', + 'get_error_group_main_statistics', { apm: { events: [ProcessorEvent.error], @@ -61,20 +78,30 @@ export async function getServiceErrorGroupMainStatistics({ terms: { field: ERROR_GROUP_ID, size: 500, - order: { - _count: 'desc', - }, + order, }, aggs: { sample: { + // change to top_metrics top_hits: { size: 1, - _source: [ERROR_LOG_MESSAGE, ERROR_EXC_MESSAGE, '@timestamp'], + _source: [ + ERROR_LOG_MESSAGE, + ERROR_EXC_MESSAGE, + ERROR_EXC_HANDLED, + ERROR_EXC_TYPE, + ERROR_CULPRIT, + ERROR_GROUP_ID, + '@timestamp', + ], sort: { '@timestamp': 'desc', }, }, }, + ...(sortByLatestOccurrence + ? { [maxTimestampAggKey]: { max: { field: '@timestamp' } } } + : {}), }, }, }, @@ -82,19 +109,17 @@ export async function getServiceErrorGroupMainStatistics({ } ); - const errorGroups = + return ( response.aggregations?.error_groups.buckets.map((bucket) => ({ - group_id: bucket.key as string, + groupId: bucket.key as string, name: getErrorName(bucket.sample.hits.hits[0]._source), lastSeen: new Date( bucket.sample.hits.hits[0]?._source['@timestamp'] ).getTime(), occurrences: bucket.doc_count, - })) ?? []; - - return { - is_aggregation_accurate: - (response.aggregations?.error_groups.sum_other_doc_count ?? 0) === 0, - error_groups: errorGroups, - }; + culprit: bucket.sample.hits.hits[0]?._source.error.culprit, + handled: bucket.sample.hits.hits[0]?._source.error.exception?.[0].handled, + type: bucket.sample.hits.hits[0]?._source.error.exception?.[0].type, + })) ?? [] + ); } diff --git a/x-pack/plugins/apm/server/routes/errors/get_error_group_sample.ts b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_sample.ts similarity index 79% rename from x-pack/plugins/apm/server/routes/errors/get_error_group_sample.ts rename to x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_sample.ts index 2c5073fb5dc66..d5a6e65417ac2 100644 --- a/x-pack/plugins/apm/server/routes/errors/get_error_group_sample.ts +++ b/x-pack/plugins/apm/server/routes/errors/get_error_groups/get_error_group_sample.ts @@ -5,17 +5,17 @@ * 2.0. */ -import { asMutableArray } from '../../../common/utils/as_mutable_array'; +import { asMutableArray } from '../../../../common/utils/as_mutable_array'; import { ERROR_GROUP_ID, SERVICE_NAME, TRANSACTION_SAMPLED, -} from '../../../common/elasticsearch_fieldnames'; -import { ProcessorEvent } from '../../../common/processor_event'; -import { rangeQuery, kqlQuery } from '../../../../observability/server'; -import { environmentQuery } from '../../../common/utils/environment_query'; -import { Setup } from '../../lib/helpers/setup_request'; -import { getTransaction } from '../transactions/get_transaction'; +} from '../../../../common/elasticsearch_fieldnames'; +import { ProcessorEvent } from '../../../../common/processor_event'; +import { rangeQuery, kqlQuery } from '../../../../../observability/server'; +import { environmentQuery } from '../../../../common/utils/environment_query'; +import { getTransaction } from '../../transactions/get_transaction'; +import { Setup } from '../../../lib/helpers/setup_request'; export async function getErrorGroupSample({ environment, diff --git a/x-pack/plugins/apm/server/routes/errors/queries.test.ts b/x-pack/plugins/apm/server/routes/errors/queries.test.ts index 529ed08b7e860..af4a4aef694fc 100644 --- a/x-pack/plugins/apm/server/routes/errors/queries.test.ts +++ b/x-pack/plugins/apm/server/routes/errors/queries.test.ts @@ -5,13 +5,13 @@ * 2.0. */ -import { getErrorGroupSample } from './get_error_group_sample'; -import { getErrorGroups } from './get_error_groups'; import { SearchParamsMock, inspectSearchParams, } from '../../utils/test_helpers'; import { ENVIRONMENT_ALL } from '../../../common/environment_filter_values'; +import { getErrorGroupMainStatistics } from './get_error_groups/get_error_group_main_statistics'; +import { getErrorGroupSample } from './get_error_groups/get_error_group_sample'; describe('error queries', () => { let mock: SearchParamsMock; @@ -38,10 +38,11 @@ describe('error queries', () => { it('fetches multiple error groups', async () => { mock = await inspectSearchParams((setup) => - getErrorGroups({ + getErrorGroupMainStatistics({ sortDirection: 'asc', sortField: 'foo', serviceName: 'serviceName', + transactionType: 'request', setup, environment: ENVIRONMENT_ALL.value, kuery: '', @@ -53,12 +54,13 @@ describe('error queries', () => { expect(mock.params).toMatchSnapshot(); }); - it('fetches multiple error groups when sortField = latestOccurrenceAt', async () => { + it('fetches multiple error groups when sortField = lastSeen', async () => { mock = await inspectSearchParams((setup) => - getErrorGroups({ + getErrorGroupMainStatistics({ sortDirection: 'asc', - sortField: 'latestOccurrenceAt', + sortField: 'lastSeen', serviceName: 'serviceName', + transactionType: 'request', setup, environment: ENVIRONMENT_ALL.value, kuery: '', diff --git a/x-pack/plugins/apm/server/routes/errors/route.ts b/x-pack/plugins/apm/server/routes/errors/route.ts index 602fed89be93c..f4e5ac172d5b0 100644 --- a/x-pack/plugins/apm/server/routes/errors/route.ts +++ b/x-pack/plugins/apm/server/routes/errors/route.ts @@ -5,11 +5,11 @@ * 2.0. */ +import { toNumberRt } from '@kbn/io-ts-utils/to_number_rt'; +import { jsonRt } from '@kbn/io-ts-utils/json_rt'; import * as t from 'io-ts'; import { createApmServerRoute } from '../apm_routes/create_apm_server_route'; import { getErrorDistribution } from './distribution/get_distribution'; -import { getErrorGroupSample } from './get_error_group_sample'; -import { getErrorGroups } from './get_error_groups'; import { setupRequest } from '../../lib/helpers/setup_request'; import { environmentRt, @@ -18,9 +18,13 @@ import { comparisonRangeRt, } from '../default_api_types'; import { createApmServerRouteRepository } from '../apm_routes/create_apm_server_route_repository'; +import { getErrorGroupMainStatistics } from './get_error_groups/get_error_group_main_statistics'; +import { getErrorGroupPeriods } from './get_error_groups/get_error_group_detailed_statistics'; +import { getErrorGroupSample } from './get_error_groups/get_error_group_sample'; -const errorsRoute = createApmServerRoute({ - endpoint: 'GET /internal/apm/services/{serviceName}/errors', +const errorsMainStatisticsRoute = createApmServerRoute({ + endpoint: + 'GET /internal/apm/services/{serviceName}/errors/groups/main_statistics', params: t.type({ path: t.type({ serviceName: t.string, @@ -33,6 +37,9 @@ const errorsRoute = createApmServerRoute({ environmentRt, kueryRt, rangeRt, + t.type({ + transactionType: t.string, + }), ]), }), options: { tags: ['access:apm'] }, @@ -40,13 +47,21 @@ const errorsRoute = createApmServerRoute({ const { params } = resources; const setup = await setupRequest(resources); const { serviceName } = params.path; - const { environment, kuery, sortField, sortDirection, start, end } = - params.query; + const { + environment, + transactionType, + kuery, + sortField, + sortDirection, + start, + end, + } = params.query; - const errorGroups = await getErrorGroups({ + const errorGroups = await getErrorGroupMainStatistics({ environment, kuery, serviceName, + transactionType, sortField, sortDirection, setup, @@ -58,6 +73,61 @@ const errorsRoute = createApmServerRoute({ }, }); +const errorsDetailedStatisticsRoute = createApmServerRoute({ + endpoint: + 'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics', + params: t.type({ + path: t.type({ + serviceName: t.string, + }), + query: t.intersection([ + environmentRt, + kueryRt, + rangeRt, + comparisonRangeRt, + t.type({ + numBuckets: toNumberRt, + transactionType: t.string, + groupIds: jsonRt.pipe(t.array(t.string)), + }), + ]), + }), + options: { tags: ['access:apm'] }, + handler: async (resources) => { + const setup = await setupRequest(resources); + const { params } = resources; + + const { + path: { serviceName }, + query: { + environment, + kuery, + numBuckets, + transactionType, + groupIds, + comparisonStart, + comparisonEnd, + start, + end, + }, + } = params; + + return getErrorGroupPeriods({ + environment, + kuery, + serviceName, + setup, + numBuckets, + transactionType, + groupIds, + comparisonStart, + comparisonEnd, + start, + end, + }); + }, +}); + const errorGroupsRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/services/{serviceName}/errors/{groupId}', params: t.type({ @@ -131,6 +201,7 @@ const errorDistributionRoute = createApmServerRoute({ }); export const errorsRouteRepository = createApmServerRouteRepository() - .add(errorsRoute) + .add(errorsMainStatisticsRoute) + .add(errorsDetailedStatisticsRoute) .add(errorGroupsRoute) .add(errorDistributionRoute); diff --git a/x-pack/plugins/apm/server/routes/services/get_service_error_groups/index.ts b/x-pack/plugins/apm/server/routes/services/get_service_error_groups/index.ts deleted file mode 100644 index 1a853231bb09a..0000000000000 --- a/x-pack/plugins/apm/server/routes/services/get_service_error_groups/index.ts +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one - * or more contributor license agreements. Licensed under the Elastic License - * 2.0; you may not use this file except in compliance with the Elastic License - * 2.0. - */ - -import { orderBy } from 'lodash'; -import { ValuesType } from 'utility-types'; -import { kqlQuery, rangeQuery } from '../../../../../observability/server'; -import { PromiseReturnType } from '../../../../../observability/typings/common'; -import { - ERROR_EXC_MESSAGE, - ERROR_GROUP_ID, - ERROR_LOG_MESSAGE, - SERVICE_NAME, - TRANSACTION_TYPE, -} from '../../../../common/elasticsearch_fieldnames'; -import { ProcessorEvent } from '../../../../common/processor_event'; -import { environmentQuery } from '../../../../common/utils/environment_query'; -import { withApmSpan } from '../../../utils/with_apm_span'; -import { getBucketSize } from '../../../lib/helpers/get_bucket_size'; -import { getErrorName } from '../../../lib/helpers/get_error_name'; -import { Setup } from '../../../lib/helpers/setup_request'; - -export type ServiceErrorGroupItem = ValuesType< - PromiseReturnType ->; - -export async function getServiceErrorGroups({ - environment, - kuery, - serviceName, - setup, - size, - numBuckets, - pageIndex, - sortDirection, - sortField, - transactionType, - start, - end, -}: { - environment: string; - kuery: string; - serviceName: string; - setup: Setup; - size: number; - pageIndex: number; - numBuckets: number; - sortDirection: 'asc' | 'desc'; - sortField: 'name' | 'lastSeen' | 'occurrences'; - transactionType: string; - start: number; - end: number; -}) { - return withApmSpan('get_service_error_groups', async () => { - const { apmEventClient } = setup; - - const { intervalString } = getBucketSize({ start, end, numBuckets }); - - const response = await apmEventClient.search( - 'get_top_service_error_groups', - { - apm: { - events: [ProcessorEvent.error], - }, - body: { - size: 0, - query: { - bool: { - filter: [ - { term: { [SERVICE_NAME]: serviceName } }, - { term: { [TRANSACTION_TYPE]: transactionType } }, - ...rangeQuery(start, end), - ...environmentQuery(environment), - ...kqlQuery(kuery), - ], - }, - }, - aggs: { - error_groups: { - terms: { - field: ERROR_GROUP_ID, - size: 500, - order: { - _count: 'desc', - }, - }, - aggs: { - sample: { - top_hits: { - size: 1, - _source: [ - ERROR_LOG_MESSAGE, - ERROR_EXC_MESSAGE, - '@timestamp', - ] as any as string, - sort: { - '@timestamp': 'desc', - }, - }, - }, - }, - }, - }, - }, - } - ); - - const errorGroups = - response.aggregations?.error_groups.buckets.map((bucket) => ({ - group_id: bucket.key as string, - name: getErrorName(bucket.sample.hits.hits[0]._source), - lastSeen: new Date( - bucket.sample.hits.hits[0]?._source['@timestamp'] - ).getTime(), - occurrences: { - value: bucket.doc_count, - }, - })) ?? []; - - // Sort error groups first, and only get timeseries for data in view. - // This is to limit the possibility of creating too many buckets. - - const sortedAndSlicedErrorGroups = orderBy( - errorGroups, - (group) => { - if (sortField === 'occurrences') { - return group.occurrences.value; - } - return group[sortField]; - }, - [sortDirection] - ).slice(pageIndex * size, pageIndex * size + size); - - const sortedErrorGroupIds = sortedAndSlicedErrorGroups.map( - (group) => group.group_id - ); - - const timeseriesResponse = await apmEventClient.search( - 'get_service_error_groups_timeseries', - { - apm: { - events: [ProcessorEvent.error], - }, - body: { - size: 0, - query: { - bool: { - filter: [ - { terms: { [ERROR_GROUP_ID]: sortedErrorGroupIds } }, - { term: { [SERVICE_NAME]: serviceName } }, - { term: { [TRANSACTION_TYPE]: transactionType } }, - ...rangeQuery(start, end), - ...environmentQuery(environment), - ...kqlQuery(kuery), - ], - }, - }, - aggs: { - error_groups: { - terms: { - field: ERROR_GROUP_ID, - size, - }, - aggs: { - timeseries: { - date_histogram: { - field: '@timestamp', - fixed_interval: intervalString, - min_doc_count: 0, - extended_bounds: { - min: start, - max: end, - }, - }, - }, - }, - }, - }, - }, - } - ); - - return { - total_error_groups: errorGroups.length, - is_aggregation_accurate: - (response.aggregations?.error_groups.sum_other_doc_count ?? 0) === 0, - error_groups: sortedAndSlicedErrorGroups.map((errorGroup) => ({ - ...errorGroup, - occurrences: { - ...errorGroup.occurrences, - timeseries: - timeseriesResponse.aggregations?.error_groups.buckets - .find((bucket) => bucket.key === errorGroup.group_id) - ?.timeseries.buckets.map((dateBucket) => ({ - x: dateBucket.key, - y: dateBucket.doc_count, - })) ?? null, - }, - })), - }; - }); -} diff --git a/x-pack/plugins/apm/server/routes/services/route.ts b/x-pack/plugins/apm/server/routes/services/route.ts index d395be4c6adce..6df0af26ad8d6 100644 --- a/x-pack/plugins/apm/server/routes/services/route.ts +++ b/x-pack/plugins/apm/server/routes/services/route.ts @@ -21,9 +21,6 @@ import { getServiceAgent } from './get_service_agent'; import { getServiceAlerts } from './get_service_alerts'; import { getServiceDependencies } from './get_service_dependencies'; import { getServiceInstanceMetadataDetails } from './get_service_instance_metadata_details'; -import { getServiceErrorGroupPeriods } from './get_service_error_groups/get_service_error_group_detailed_statistics'; -import { getServiceErrorGroupMainStatistics } from './get_service_error_groups/get_service_error_group_main_statistics'; -import { getServiceInstancesDetailedStatisticsPeriods } from './get_service_instances/detailed_statistics'; import { getServiceInstancesMainStatistics } from './get_service_instances/main_statistics'; import { getServiceMetadataDetails } from './get_service_metadata_details'; import { getServiceMetadataIcons } from './get_service_metadata_icons'; @@ -47,6 +44,7 @@ import { offsetPreviousPeriodCoordinates } from '../../../common/utils/offset_pr import { getServicesDetailedStatistics } from './get_services_detailed_statistics'; import { getServiceDependenciesBreakdown } from './get_service_dependencies_breakdown'; import { getBucketSizeForAggregatedTransactions } from '../../lib/helpers/get_bucket_size_for_aggregated_transactions'; +import { getServiceInstancesDetailedStatisticsPeriods } from './get_service_instances/detailed_statistics'; const servicesRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/services', @@ -374,98 +372,6 @@ const serviceAnnotationsCreateRoute = createApmServerRoute({ }, }); -const serviceErrorGroupsMainStatisticsRoute = createApmServerRoute({ - endpoint: - 'GET /internal/apm/services/{serviceName}/error_groups/main_statistics', - params: t.type({ - path: t.type({ - serviceName: t.string, - }), - query: t.intersection([ - environmentRt, - kueryRt, - rangeRt, - t.type({ - transactionType: t.string, - }), - ]), - }), - options: { tags: ['access:apm'] }, - handler: async (resources) => { - const setup = await setupRequest(resources); - const { params } = resources; - const { - path: { serviceName }, - query: { kuery, transactionType, environment, start, end }, - } = params; - - return getServiceErrorGroupMainStatistics({ - kuery, - serviceName, - setup, - transactionType, - environment, - start, - end, - }); - }, -}); - -const serviceErrorGroupsDetailedStatisticsRoute = createApmServerRoute({ - endpoint: - 'GET /internal/apm/services/{serviceName}/error_groups/detailed_statistics', - params: t.type({ - path: t.type({ - serviceName: t.string, - }), - query: t.intersection([ - environmentRt, - kueryRt, - rangeRt, - comparisonRangeRt, - t.type({ - numBuckets: toNumberRt, - transactionType: t.string, - groupIds: jsonRt.pipe(t.array(t.string)), - }), - ]), - }), - options: { tags: ['access:apm'] }, - handler: async (resources) => { - const setup = await setupRequest(resources); - const { params } = resources; - - const { - path: { serviceName }, - query: { - environment, - kuery, - numBuckets, - transactionType, - groupIds, - comparisonStart, - comparisonEnd, - start, - end, - }, - } = params; - - return getServiceErrorGroupPeriods({ - environment, - kuery, - serviceName, - setup, - numBuckets, - transactionType, - groupIds, - comparisonStart, - comparisonEnd, - start, - end, - }); - }, -}); - const serviceThroughputRoute = createApmServerRoute({ endpoint: 'GET /internal/apm/services/{serviceName}/throughput', params: t.type({ @@ -952,8 +858,6 @@ export const serviceRouteRepository = createApmServerRouteRepository() .add(serviceNodeMetadataRoute) .add(serviceAnnotationsRoute) .add(serviceAnnotationsCreateRoute) - .add(serviceErrorGroupsMainStatisticsRoute) - .add(serviceErrorGroupsDetailedStatisticsRoute) .add(serviceInstancesMetadataDetails) .add(serviceThroughputRoute) .add(serviceInstancesMainStatisticsRoute) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 1dd7127e56623..229a61d88e590 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -5662,7 +5662,6 @@ "xpack.apm.errorsTable.errorMessageAndCulpritColumnLabel": "エラーメッセージと原因", "xpack.apm.errorsTable.groupIdColumnDescription": "スタックトレースのハッシュ。動的パラメータのため、エラーメッセージが異なる場合でも、類似したエラーをグループ化します。", "xpack.apm.errorsTable.groupIdColumnLabel": "グループ ID", - "xpack.apm.errorsTable.latestOccurrenceColumnLabel": "最近のオカレンス", "xpack.apm.errorsTable.noErrorsLabel": "エラーが見つかりません", "xpack.apm.errorsTable.occurrencesColumnLabel": "オカレンス", "xpack.apm.errorsTable.typeColumnLabel": "型", @@ -5971,7 +5970,6 @@ "xpack.apm.serviceNodeMetrics.unidentifiedServiceNodesWarningText": "これらのメトリックが所属する JVM を特定できませんでした。7.5 よりも古い APM Server を実行していることが原因である可能性が高いです。この問題は APM Server 7.5 以降にアップグレードすることで解決されます。アップグレードに関する詳細は、{link} をご覧ください。代わりに Kibana クエリバーを使ってホスト名、コンテナー ID、またはその他フィールドでフィルタリングすることもできます。", "xpack.apm.serviceNodeMetrics.unidentifiedServiceNodesWarningTitle": "JVM を特定できませんでした", "xpack.apm.serviceNodeNameMissing": "(空)", - "xpack.apm.serviceOveriew.errorsTableOccurrences": "{occurrencesCount} occ.", "xpack.apm.serviceOverview.dependenciesTableColumn": "依存関係", "xpack.apm.serviceOverview.dependenciesTableTabLink": "依存関係を表示", "xpack.apm.serviceOverview.dependenciesTableTitle": "依存関係", @@ -27665,4 +27663,4 @@ "xpack.watcher.watchEdit.thresholdWatchExpression.aggType.fieldIsRequiredValidationMessage": "フィールドを選択してください。", "xpack.watcher.watcherDescription": "アラートの作成、管理、監視によりデータへの変更を検知します。" } -} \ No newline at end of file +} diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 6bab22bd1dd4b..b17c984ac2474 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -5700,8 +5700,7 @@ "xpack.apm.errorsTable.errorMessageAndCulpritColumnLabel": "错误消息和原因", "xpack.apm.errorsTable.groupIdColumnDescription": "堆栈跟踪的哈希。将类似错误分组在一起,即使因动态参数造成错误消息不同。", "xpack.apm.errorsTable.groupIdColumnLabel": "组 ID", - "xpack.apm.errorsTable.latestOccurrenceColumnLabel": "最新一次发生", - "xpack.apm.errorsTable.noErrorsLabel": "未找到错误", + "xpack.apm.errorsTable.noErrorsLabel": "未找到任何错误", "xpack.apm.errorsTable.occurrencesColumnLabel": "发生次数", "xpack.apm.errorsTable.typeColumnLabel": "类型", "xpack.apm.errorsTable.unhandledLabel": "未处理", @@ -6012,8 +6011,6 @@ "xpack.apm.serviceNodeMetrics.unidentifiedServiceNodesWarningText": "无法识别这些指标属于哪些 JVM。这可能因为运行的 APM Server 版本低于 7.5。如果升级到 APM Server 7.5 或更高版本,应可解决此问题。有关升级的详细信息,请参阅 {link}。或者,也可以使用 Kibana 查询栏按主机名、容器 ID 或其他字段筛选。", "xpack.apm.serviceNodeMetrics.unidentifiedServiceNodesWarningTitle": "找不到 JVM", "xpack.apm.serviceNodeNameMissing": "(空)", - "xpack.apm.serviceOveriew.errorsTableOccurrences": "{occurrencesCount} 次", - "xpack.apm.serviceOverview.dependenciesTableColumn": "依赖项", "xpack.apm.serviceOverview.dependenciesTableTabLink": "查看依赖项", "xpack.apm.serviceOverview.dependenciesTableTitle": "依赖项", "xpack.apm.serviceOverview.errorsTable.errorMessage": "无法提取", diff --git a/x-pack/test/apm_api_integration/tests/errors/error_group_list.spec.ts b/x-pack/test/apm_api_integration/tests/errors/error_group_list.spec.ts index 5fc3f70d0d023..ce27183e84ca1 100644 --- a/x-pack/test/apm_api_integration/tests/errors/error_group_list.spec.ts +++ b/x-pack/test/apm_api_integration/tests/errors/error_group_list.spec.ts @@ -13,7 +13,8 @@ import { import { RecursivePartial } from '../../../../plugins/apm/typings/common'; import { FtrProviderContext } from '../../common/ftr_provider_context'; -type ErrorGroups = APIReturnType<'GET /internal/apm/services/{serviceName}/errors'>['errorGroups']; +type ErrorGroups = + APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/main_statistics'>['errorGroups']; export default function ApiTest({ getService }: FtrProviderContext) { const registry = getService('registry'); @@ -26,17 +27,18 @@ export default function ApiTest({ getService }: FtrProviderContext) { async function callApi( overrides?: RecursivePartial< - APIClientRequestParamsOf<'GET /internal/apm/services/{serviceName}/errors'>['params'] + APIClientRequestParamsOf<'GET /internal/apm/services/{serviceName}/errors/groups/main_statistics'>['params'] > ) { return await apmApiClient.readUser({ - endpoint: `GET /internal/apm/services/{serviceName}/errors`, + endpoint: 'GET /internal/apm/services/{serviceName}/errors/groups/main_statistics', params: { path: { serviceName, ...overrides?.path }, query: { start: new Date(start).toISOString(), end: new Date(end).toISOString(), environment: 'ENVIRONMENT_ALL', + transactionType: 'request', kuery: '', ...overrides?.query, }, @@ -133,12 +135,12 @@ export default function ApiTest({ getService }: FtrProviderContext) { it('returns correct number of errors', () => { expect(errorGroups.length).to.equal(2); - expect(errorGroups.map((error) => error.message).sort()).to.eql(['error 1', 'error 2']); + expect(errorGroups.map((error) => error.name).sort()).to.eql(['error 1', 'error 2']); }); it('returns correct occurences', () => { const numberOfBuckets = 15; - expect(errorGroups.map((error) => error.occurrenceCount).sort()).to.eql([ + expect(errorGroups.map((error) => error.occurrences).sort()).to.eql([ appleTransaction.failureRate * numberOfBuckets, bananaTransaction.failureRate * numberOfBuckets, ]); diff --git a/x-pack/test/apm_api_integration/tests/feature_controls.spec.ts b/x-pack/test/apm_api_integration/tests/feature_controls.spec.ts index f20aaaff2b23d..64e9ce248b455 100644 --- a/x-pack/test/apm_api_integration/tests/feature_controls.spec.ts +++ b/x-pack/test/apm_api_integration/tests/feature_controls.spec.ts @@ -44,7 +44,7 @@ export default function featureControlsTests({ getService }: FtrProviderContext) { // this doubles as a smoke test for the _inspect query parameter req: { - url: `/internal/apm/services/foo/errors?start=${start}&end=${end}&_inspect=true&environment=ENVIRONMENT_ALL&kuery=`, + url: `/internal/apm/services/foo/errors/groups/main_statistics?start=${start}&end=${end}&_inspect=true&environment=ENVIRONMENT_ALL&transactionType=bar&kuery=`, }, expectForbidden: expect403, expectResponse: expect200, diff --git a/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.spec.ts b/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.spec.ts index e94de1d5410f1..164a613cd2a14 100644 --- a/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.spec.ts +++ b/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_detailed_statistics.spec.ts @@ -19,7 +19,7 @@ import { config, generateData } from './generate_data'; import { getErrorGroupIds } from './get_error_group_ids'; type ErrorGroupsDetailedStatistics = - APIReturnType<'GET /internal/apm/services/{serviceName}/error_groups/detailed_statistics'>; + APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>; export default function ApiTest({ getService }: FtrProviderContext) { const registry = getService('registry'); @@ -32,11 +32,11 @@ export default function ApiTest({ getService }: FtrProviderContext) { async function callApi( overrides?: RecursivePartial< - APIClientRequestParamsOf<'GET /internal/apm/services/{serviceName}/error_groups/detailed_statistics'>['params'] + APIClientRequestParamsOf<'GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics'>['params'] > ) { return await apmApiClient.readUser({ - endpoint: `GET /internal/apm/services/{serviceName}/error_groups/detailed_statistics`, + endpoint: `GET /internal/apm/services/{serviceName}/errors/groups/detailed_statistics`, params: { path: { serviceName, ...overrides?.path }, query: { diff --git a/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_main_statistics.spec.ts b/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_main_statistics.spec.ts index 5774ce4225f5a..cf2a0865b1cbc 100644 --- a/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_main_statistics.spec.ts +++ b/x-pack/test/apm_api_integration/tests/services/error_groups/error_groups_main_statistics.spec.ts @@ -15,7 +15,7 @@ import { FtrProviderContext } from '../../../common/ftr_provider_context'; import { generateData, config } from './generate_data'; type ErrorGroupsMainStatistics = - APIReturnType<'GET /internal/apm/services/{serviceName}/error_groups/main_statistics'>; + APIReturnType<'GET /internal/apm/services/{serviceName}/errors/groups/main_statistics'>; export default function ApiTest({ getService }: FtrProviderContext) { const registry = getService('registry'); @@ -28,11 +28,11 @@ export default function ApiTest({ getService }: FtrProviderContext) { async function callApi( overrides?: RecursivePartial< - APIClientRequestParamsOf<'GET /internal/apm/services/{serviceName}/error_groups/main_statistics'>['params'] + APIClientRequestParamsOf<'GET /internal/apm/services/{serviceName}/errors/groups/main_statistics'>['params'] > ) { return await apmApiClient.readUser({ - endpoint: `GET /internal/apm/services/{serviceName}/error_groups/main_statistics`, + endpoint: `GET /internal/apm/services/{serviceName}/errors/groups/main_statistics`, params: { path: { serviceName, ...overrides?.path }, query: { @@ -54,8 +54,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { it('handles empty state', async () => { const response = await callApi(); expect(response.status).to.be(200); - expect(response.body.error_groups).to.empty(); - expect(response.body.is_aggregation_accurate).to.eql(true); + expect(response.body.errorGroups).to.empty(); }); } ); @@ -81,8 +80,8 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('returns correct number of occurrences', () => { - expect(errorGroupMainStatistics.error_groups.length).to.equal(2); - expect(errorGroupMainStatistics.error_groups.map((error) => error.name).sort()).to.eql([ + expect(errorGroupMainStatistics.errorGroups.length).to.equal(2); + expect(errorGroupMainStatistics.errorGroups.map((error) => error.name).sort()).to.eql([ ERROR_NAME_1, ERROR_NAME_2, ]); @@ -91,7 +90,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { it('returns correct occurences', () => { const numberOfBuckets = 15; expect( - errorGroupMainStatistics.error_groups.map((error) => error.occurrences).sort() + errorGroupMainStatistics.errorGroups.map((error) => error.occurrences).sort() ).to.eql([ PROD_LIST_ERROR_RATE * numberOfBuckets, PROD_ID_ERROR_RATE * numberOfBuckets, @@ -99,7 +98,7 @@ export default function ApiTest({ getService }: FtrProviderContext) { }); it('has same last seen value as end date', () => { - errorGroupMainStatistics.error_groups.map((error) => { + errorGroupMainStatistics.errorGroups.map((error) => { expect(error.lastSeen).to.equal(moment(end).startOf('minute').valueOf()); }); }); diff --git a/x-pack/test/apm_api_integration/tests/services/error_groups/get_error_group_ids.ts b/x-pack/test/apm_api_integration/tests/services/error_groups/get_error_group_ids.ts index cfc0867fdcfb9..a5b7d1a095767 100644 --- a/x-pack/test/apm_api_integration/tests/services/error_groups/get_error_group_ids.ts +++ b/x-pack/test/apm_api_integration/tests/services/error_groups/get_error_group_ids.ts @@ -22,7 +22,7 @@ export async function getErrorGroupIds({ count?: number; }) { const { body } = await apmApiClient.readUser({ - endpoint: `GET /internal/apm/services/{serviceName}/error_groups/main_statistics`, + endpoint: `GET /internal/apm/services/{serviceName}/errors/groups/main_statistics`, params: { path: { serviceName }, query: { @@ -35,5 +35,5 @@ export async function getErrorGroupIds({ }, }); - return take(body.error_groups.map((group) => group.group_id).sort(), count); + return take(body.errorGroups.map((group) => group.groupId).sort(), count); } From d2d5432c051c9aba445facdccbc3fdeafaf29349 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Thu, 25 Nov 2021 10:15:52 +0100 Subject: [PATCH 17/46] =?UTF-8?q?remove=20=E2=80=9Cabortcontroller-polyfil?= =?UTF-8?q?l=E2=80=9D=20(#119308)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- package.json | 1 - packages/kbn-ui-shared-deps-npm/BUILD.bazel | 2 -- .../server/lib/get_request_aborted_signal.ts | 2 -- .../expressions/common/execution/execution.ts | 19 +------------------ yarn.lock | 5 ----- 5 files changed, 1 insertion(+), 28 deletions(-) diff --git a/package.json b/package.json index 81c6696b019f9..df39dd8c65d7e 100644 --- a/package.json +++ b/package.json @@ -189,7 +189,6 @@ "@types/jsonwebtoken": "^8.5.6", "JSONStream": "1.3.5", "abort-controller": "^3.0.0", - "abortcontroller-polyfill": "^1.7.3", "antlr4ts": "^0.5.0-alpha.3", "archiver": "^5.2.0", "axios": "^0.21.1", diff --git a/packages/kbn-ui-shared-deps-npm/BUILD.bazel b/packages/kbn-ui-shared-deps-npm/BUILD.bazel index 490aa91f30680..b75315120e90d 100644 --- a/packages/kbn-ui-shared-deps-npm/BUILD.bazel +++ b/packages/kbn-ui-shared-deps-npm/BUILD.bazel @@ -34,7 +34,6 @@ RUNTIME_DEPS = [ "@npm//@elastic/eui", "@npm//@elastic/numeral", "@npm//@emotion/react", - "@npm//abortcontroller-polyfill", "@npm//babel-loader", "@npm//babel-plugin-transform-react-remove-prop-types", "@npm//core-js", @@ -74,7 +73,6 @@ TYPES_DEPS = [ "@npm//@elastic/eui", "@npm//@elastic/numeral", "@npm//@emotion/react", - "@npm//abortcontroller-polyfill", "@npm//babel-loader", "@npm//core-js", "@npm//css-loader", diff --git a/src/plugins/data/server/lib/get_request_aborted_signal.ts b/src/plugins/data/server/lib/get_request_aborted_signal.ts index 7d1ed1fd89024..1d2849745da26 100644 --- a/src/plugins/data/server/lib/get_request_aborted_signal.ts +++ b/src/plugins/data/server/lib/get_request_aborted_signal.ts @@ -7,8 +7,6 @@ */ import { Observable } from 'rxjs'; -// @ts-ignore not typed -import { AbortController } from 'abortcontroller-polyfill/dist/cjs-ponyfill'; /** * A simple utility function that returns an `AbortSignal` corresponding to an `AbortController` diff --git a/src/plugins/expressions/common/execution/execution.ts b/src/plugins/expressions/common/execution/execution.ts index 65dcc2502f9ea..c81e398dbc9e8 100644 --- a/src/plugins/expressions/common/execution/execution.ts +++ b/src/plugins/expressions/common/execution/execution.ts @@ -64,23 +64,6 @@ export interface ExecutionResult { result: Output; } -/** - * AbortController is not available in Node until v15, so we - * need to temporarily mock it for plugins using expressions - * on the server. - * - * TODO: Remove this once Kibana is upgraded to Node 15. - */ -const getNewAbortController = (): AbortController => { - try { - return new AbortController(); - } catch (error) { - // eslint-disable-next-line @typescript-eslint/no-var-requires - const polyfill = require('abortcontroller-polyfill/dist/cjs-ponyfill'); - return new polyfill.AbortController(); - } -}; - const createAbortErrorValue = () => createError({ message: 'The expression was aborted.', @@ -173,7 +156,7 @@ export class Execution< /** * AbortController to cancel this Execution. */ - private readonly abortController = getNewAbortController(); + private readonly abortController = new AbortController(); /** * Whether .start() method has been called. diff --git a/yarn.lock b/yarn.lock index 16797a015882a..3d1ab34b02f85 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7062,11 +7062,6 @@ abort-controller@^3.0.0: dependencies: event-target-shim "^5.0.0" -abortcontroller-polyfill@^1.7.3: - version "1.7.3" - resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz#1b5b487bd6436b5b764fd52a612509702c3144b5" - integrity sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q== - accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.7: version "1.3.7" resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.7.tgz#531bc726517a3b2b41f850021c6cc15eaab507cd" From 84680619084497a6691df2c35e38e08a1fb7e4ff Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Thu, 25 Nov 2021 10:16:32 +0100 Subject: [PATCH 18/46] [Search] unskip tests of example plugin (#119604) --- examples/search_examples/public/search_sessions/app.tsx | 2 ++ x-pack/test/examples/search_examples/search_example.ts | 4 ++-- .../test/examples/search_examples/search_session_example.ts | 6 ++++-- .../test/examples/search_examples/search_sessions_cache.ts | 5 ++--- 4 files changed, 10 insertions(+), 7 deletions(-) diff --git a/examples/search_examples/public/search_sessions/app.tsx b/examples/search_examples/public/search_sessions/app.tsx index c953da0895ccd..b5b38df7a548e 100644 --- a/examples/search_examples/public/search_sessions/app.tsx +++ b/examples/search_examples/public/search_sessions/app.tsx @@ -299,6 +299,7 @@ export const SearchSessionsExampleApp = ({ setIndexPattern(id); }} isClearable={false} + data-test-subj="indexPatternSelector" /> @@ -313,6 +314,7 @@ export const SearchSessionsExampleApp = ({ setNumericFieldName(fld?.name); }} sortMatchesBy="startsWith" + data-test-subj="searchMetricField" /> diff --git a/x-pack/test/examples/search_examples/search_example.ts b/x-pack/test/examples/search_examples/search_example.ts index fb3cef4055e33..949e13ca3b750 100644 --- a/x-pack/test/examples/search_examples/search_example.ts +++ b/x-pack/test/examples/search_examples/search_example.ts @@ -16,12 +16,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const comboBox = getService('comboBox'); const toasts = getService('toasts'); - describe('Search session example', () => { + describe('Search example', () => { const appId = 'searchExamples'; before(async function () { await PageObjects.common.navigateToApp(appId, { insertTimestamp: false }); - await comboBox.set('indexPatternSelector', 'logstash-*'); + await comboBox.setCustom('indexPatternSelector', 'logstash-*'); await comboBox.set('searchBucketField', 'geo.src'); await comboBox.set('searchMetricField', 'memory'); await PageObjects.timePicker.setAbsoluteRange( diff --git a/x-pack/test/examples/search_examples/search_session_example.ts b/x-pack/test/examples/search_examples/search_session_example.ts index e6261f69e14f6..ae191c16da14a 100644 --- a/x-pack/test/examples/search_examples/search_session_example.ts +++ b/x-pack/test/examples/search_examples/search_session_example.ts @@ -14,9 +14,9 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { const log = getService('log'); const es = getService('es'); const searchSessions = getService('searchSessions'); + const comboBox = getService('comboBox'); - // FLAKY: https://github.com/elastic/kibana/issues/118921 - describe.skip('Search session example', () => { + describe('Search session example', () => { const appId = 'searchExamples'; before(async function () { @@ -36,6 +36,8 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { }); it('should start search, save session, restore session using "restore" button', async () => { + await comboBox.setCustom('indexPatternSelector', 'logstash-*'); + await comboBox.setCustom('searchMetricField', 'bytes'); await testSubjects.clickWhenNotDisabled('startSearch'); await testSubjects.find('searchResults-1'); await searchSessions.expectState('completed'); diff --git a/x-pack/test/examples/search_examples/search_sessions_cache.ts b/x-pack/test/examples/search_examples/search_sessions_cache.ts index 0da2de46a1f62..4e5374a8c32a3 100644 --- a/x-pack/test/examples/search_examples/search_sessions_cache.ts +++ b/x-pack/test/examples/search_examples/search_sessions_cache.ts @@ -27,13 +27,12 @@ export default function ({ getService, getPageObjects }: FtrProviderContext) { return text; } - // FLAKY: https://github.com/elastic/kibana/issues/116537 - describe.skip('Search session client side cache', () => { + describe('Search session client side cache', () => { const appId = 'searchExamples'; before(async function () { await PageObjects.common.navigateToApp(appId, { insertTimestamp: false }); - await comboBox.set('indexPatternSelector', 'logstash-*'); + await comboBox.setCustom('indexPatternSelector', 'logstash-*'); await comboBox.set('searchBucketField', 'extension.raw'); await comboBox.set('searchMetricField', 'phpmemory'); }); From f993b04f8c0c51858e74b98379132e89c29c8aea Mon Sep 17 00:00:00 2001 From: Pete Harverson Date: Thu, 25 Nov 2021 09:32:40 +0000 Subject: [PATCH 19/46] [ML] Fix anomaly detection module manifest queries to ignore frozen and cold tiers (#119635) --- .../data_recognizer/modules/apache_ecs/manifest.json | 3 ++- .../data_recognizer/modules/apm_transaction/manifest.json | 3 ++- .../modules/auditbeat_process_docker_ecs/manifest.json | 3 ++- .../modules/auditbeat_process_hosts_ecs/manifest.json | 7 ++++--- .../modules/metricbeat_system_ecs/manifest.json | 3 ++- .../models/data_recognizer/modules/nginx_ecs/manifest.json | 3 ++- .../data_recognizer/modules/security_auth/manifest.json | 3 ++- .../data_recognizer/modules/security_linux/manifest.json | 3 ++- .../data_recognizer/modules/security_network/manifest.json | 3 ++- .../data_recognizer/modules/security_windows/manifest.json | 3 ++- .../data_recognizer/modules/siem_auditbeat/manifest.json | 3 ++- .../modules/siem_auditbeat_auth/manifest.json | 3 ++- .../data_recognizer/modules/siem_cloudtrail/manifest.json | 3 ++- .../data_recognizer/modules/siem_packetbeat/manifest.json | 3 ++- .../data_recognizer/modules/siem_winlogbeat/manifest.json | 3 ++- .../modules/siem_winlogbeat_auth/manifest.json | 3 ++- .../data_recognizer/modules/uptime_heartbeat/manifest.json | 3 ++- 17 files changed, 36 insertions(+), 19 deletions(-) diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/manifest.json index e9cd932ce264c..c4c8a2c167a3c 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apache_ecs/manifest.json @@ -12,7 +12,8 @@ { "exists": { "field": "source.address" } }, { "exists": { "field": "url.original" } }, { "exists": { "field": "http.response.status_code" } } - ] + ], + "must_not": { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/manifest.json index 3332fad66b3e2..721d4693e61aa 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/apm_transaction/manifest.json @@ -10,7 +10,8 @@ "filter": [ { "term": { "processor.event": "metric" } }, { "term": { "metricset.name": "transaction" } } - ] + ], + "must_not": { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/manifest.json index 7f407c4f5f713..b106130da8c32 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_docker_ecs/manifest.json @@ -13,7 +13,8 @@ ], "must": { "exists": { "field": "auditd.data.syscall" } - } + }, + "must_not": { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/manifest.json index 3f883e0198817..96d0eb2a43866 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/auditbeat_process_hosts_ecs/manifest.json @@ -13,9 +13,10 @@ "must": { "exists": { "field": "auditd.data.syscall" } }, - "must_not": { - "exists": { "field": "container.runtime" } - } + "must_not": [ + { "exists": { "field": "container.runtime" } }, + { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } + ] } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/metricbeat_system_ecs/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/metricbeat_system_ecs/manifest.json index 6482fab429ecb..23504b4088d53 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/metricbeat_system_ecs/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/metricbeat_system_ecs/manifest.json @@ -14,7 +14,8 @@ "system.filesystem" ] } - } + }, + "must_not": { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/manifest.json index e219035178941..80ef655acb1f4 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/nginx_ecs/manifest.json @@ -12,7 +12,8 @@ { "exists": { "field": "source.address" } }, { "exists": { "field": "url.original" } }, { "exists": { "field": "http.response.status_code" } } - ] + ], + "must_not": { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/security_auth/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/security_auth/manifest.json index 480f49f3f2b19..7bb54bd126e77 100755 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/security_auth/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/security_auth/manifest.json @@ -13,7 +13,8 @@ "event.category": "authentication" } } - ] + ], + "must_not": { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/security_linux/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/security_linux/manifest.json index c627e5a6f6253..281343975500b 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/security_linux/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/security_linux/manifest.json @@ -40,7 +40,8 @@ } } } - ] + ], + "must_not": { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/security_network/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/security_network/manifest.json index 384ea006b5b42..bed522d4e954a 100755 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/security_network/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/security_network/manifest.json @@ -13,7 +13,8 @@ "event.category": "network" } } - ] + ], + "must_not": { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/security_windows/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/security_windows/manifest.json index e1bd6eacc6882..7325fa76b2eb0 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/security_windows/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/security_windows/manifest.json @@ -30,7 +30,8 @@ ] } } - ] + ], + "must_not": { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_auditbeat/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_auditbeat/manifest.json index 36d1df6db4c99..efb7947ed34f5 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_auditbeat/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_auditbeat/manifest.json @@ -9,7 +9,8 @@ "bool": { "filter": [ {"term": {"agent.type": "auditbeat"}} - ] + ], + "must_not": { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_auditbeat_auth/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_auditbeat_auth/manifest.json index f6e878de8169b..2d43544522fef 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_auditbeat_auth/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_auditbeat_auth/manifest.json @@ -10,7 +10,8 @@ "filter": [ {"term": {"event.category": "authentication"}}, {"term": {"agent.type": "auditbeat"}} - ] + ], + "must_not": { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_cloudtrail/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_cloudtrail/manifest.json index 33940f20db903..1d9f778f17150 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_cloudtrail/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_cloudtrail/manifest.json @@ -9,7 +9,8 @@ "bool": { "filter": [ {"term": {"event.dataset": "aws.cloudtrail"}} - ] + ], + "must_not": { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_packetbeat/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_packetbeat/manifest.json index e11e1726076d9..61c3ce979154a 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_packetbeat/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_packetbeat/manifest.json @@ -9,7 +9,8 @@ "bool": { "filter": [ {"term": {"agent.type": "packetbeat"}} - ] + ], + "must_not": { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_winlogbeat/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_winlogbeat/manifest.json index 969873ead6d9c..7e4f20bce6d5a 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_winlogbeat/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_winlogbeat/manifest.json @@ -9,7 +9,8 @@ "bool": { "filter": [ {"term": {"agent.type": "winlogbeat"}} - ] + ], + "must_not": { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_winlogbeat_auth/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_winlogbeat_auth/manifest.json index f08f4da880118..45a3d25969812 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_winlogbeat_auth/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/siem_winlogbeat_auth/manifest.json @@ -10,7 +10,8 @@ "filter": [ {"term": {"agent.type": "winlogbeat"}}, {"term": {"event.category": "authentication"}} - ] + ], + "must_not": { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } } }, "jobs": [ diff --git a/x-pack/plugins/ml/server/models/data_recognizer/modules/uptime_heartbeat/manifest.json b/x-pack/plugins/ml/server/models/data_recognizer/modules/uptime_heartbeat/manifest.json index 52005a2629900..89a08f8a8207a 100644 --- a/x-pack/plugins/ml/server/models/data_recognizer/modules/uptime_heartbeat/manifest.json +++ b/x-pack/plugins/ml/server/models/data_recognizer/modules/uptime_heartbeat/manifest.json @@ -7,7 +7,8 @@ "defaultIndexPattern": "heartbeat-*", "query": { "bool": { - "filter": [{ "term": { "agent.type": "heartbeat" } }] + "filter": [{ "term": { "agent.type": "heartbeat" } }], + "must_not": { "terms": { "_tier": [ "data_frozen", "data_cold" ] } } } }, "jobs": [ From 8aec972f647aafbeb69a9f70b40f19d11ff62df0 Mon Sep 17 00:00:00 2001 From: Dima Arnautov Date: Thu, 25 Nov 2021 10:54:30 +0100 Subject: [PATCH 20/46] [ML] Support `force` stop deployment (#118563) * support force stop * fix i18n, revert tests * update text * remove "Force" from the confirmation modals --- .../close_job_confirm/close_job_confirm.tsx | 4 +- .../action_stop/stop_action_modal.tsx | 2 +- .../services/ml_api_service/trained_models.ts | 5 +- .../models_management/force_stop_dialog.tsx | 89 +++++++++++++++++++ .../models_management/models_list.tsx | 16 +++- .../ml/server/routes/trained_models.ts | 3 + 6 files changed, 113 insertions(+), 6 deletions(-) create mode 100644 x-pack/plugins/ml/public/application/trained_models/models_management/force_stop_dialog.tsx diff --git a/x-pack/plugins/ml/public/application/components/model_snapshots/close_job_confirm/close_job_confirm.tsx b/x-pack/plugins/ml/public/application/components/model_snapshots/close_job_confirm/close_job_confirm.tsx index 14c3dc3fc7a7a..da1bb825768e2 100644 --- a/x-pack/plugins/ml/public/application/components/model_snapshots/close_job_confirm/close_job_confirm.tsx +++ b/x-pack/plugins/ml/public/application/components/model_snapshots/close_job_confirm/close_job_confirm.tsx @@ -43,10 +43,10 @@ export const CloseJobConfirm: FC = ({ confirmButtonText={ combinedJobState === COMBINED_JOB_STATE.OPEN_AND_RUNNING ? i18n.translate('xpack.ml.modelSnapshotTable.closeJobConfirm.stopAndClose.button', { - defaultMessage: 'Force stop and close', + defaultMessage: 'Stop and close', }) : i18n.translate('xpack.ml.modelSnapshotTable.closeJobConfirm.close.button', { - defaultMessage: 'Force close', + defaultMessage: 'Close', }) } defaultFocusedButton="confirm" diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/stop_action_modal.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/stop_action_modal.tsx index e9939299d7ca0..6f0ee0afebe42 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/stop_action_modal.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_stop/stop_action_modal.tsx @@ -31,7 +31,7 @@ export const StopActionModal: FC = ({ closeModal, item, forceStopAnd confirmButtonText={i18n.translate( 'xpack.ml.dataframe.analyticsList.forceStopModalStartButton', { - defaultMessage: 'Force stop', + defaultMessage: 'Stop', } )} defaultFocusedButton={EUI_MODAL_CONFIRM_BUTTON} diff --git a/x-pack/plugins/ml/public/application/services/ml_api_service/trained_models.ts b/x-pack/plugins/ml/public/application/services/ml_api_service/trained_models.ts index 822c5059982e7..381528e1055d6 100644 --- a/x-pack/plugins/ml/public/application/services/ml_api_service/trained_models.ts +++ b/x-pack/plugins/ml/public/application/services/ml_api_service/trained_models.ts @@ -135,10 +135,13 @@ export function trainedModelsApiProvider(httpService: HttpService) { }); }, - stopModelAllocation(modelId: string) { + stopModelAllocation(modelId: string, options: { force: boolean } = { force: false }) { + const force = options?.force; + return httpService.http<{ acknowledge: boolean }>({ path: `${apiBasePath}/trained_models/${modelId}/deployment/_stop`, method: 'POST', + query: { force }, }); }, }; diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/force_stop_dialog.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/force_stop_dialog.tsx new file mode 100644 index 0000000000000..6d2a3880180eb --- /dev/null +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/force_stop_dialog.tsx @@ -0,0 +1,89 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { FC } from 'react'; +import { EuiConfirmModal } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n/react'; +import type { OverlayStart } from 'kibana/public'; +import type { ModelItem } from './models_list'; +import { toMountPoint } from '../../../../../../../src/plugins/kibana_react/public'; + +interface ForceStopModelConfirmDialogProps { + model: ModelItem; + onCancel: () => void; + onConfirm: () => void; +} + +export const ForceStopModelConfirmDialog: FC = ({ + model, + onConfirm, + onCancel, +}) => { + return ( + + } + onCancel={onCancel} + onConfirm={onConfirm} + cancelButtonText={ + + } + confirmButtonText={ + + } + buttonColor="danger" + > + +
    + {Object.keys(model.pipelines!) + .sort() + .map((pipelineName) => { + return
  • {pipelineName}
  • ; + })} +
+
+ ); +}; + +export const getUserConfirmationProvider = + (overlays: OverlayStart) => async (forceStopModel: ModelItem) => { + return new Promise(async (resolve, reject) => { + try { + const modalSession = overlays.openModal( + toMountPoint( + { + modalSession.close(); + resolve(false); + }} + onConfirm={() => { + modalSession.close(); + resolve(true); + }} + /> + ) + ); + } catch (e) { + resolve(false); + } + }); + }; diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/models_list.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/models_list.tsx index 0283e470bc383..c80ff808aa539 100644 --- a/x-pack/plugins/ml/public/application/trained_models/models_management/models_list.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/models_list.tsx @@ -53,6 +53,7 @@ import { useFieldFormatter } from '../../contexts/kibana/use_field_formatter'; import { FIELD_FORMAT_IDS } from '../../../../../../../src/plugins/field_formats/common'; import { useRefresh } from '../../routing/use_refresh'; import { DEPLOYMENT_STATE } from '../../../../common/constants/trained_models'; +import { getUserConfirmationProvider } from './force_stop_dialog'; type Stats = Omit; @@ -80,6 +81,7 @@ export const ModelsList: FC = () => { const { services: { application: { navigateToUrl, capabilities }, + overlays, }, } = useMlKibana(); const urlLocator = useMlLocator()!; @@ -110,6 +112,8 @@ export const ModelsList: FC = () => { {} ); + const getUserConfirmation = useMemo(() => getUserConfirmationProvider(overlays), []); + const navigateToPath = useNavigateToPath(); const isBuiltInModel = useCallback( @@ -418,13 +422,21 @@ export const ModelsList: FC = () => { available: (item) => item.model_type === 'pytorch', enabled: (item) => !isLoading && - !isPopulatedObject(item.pipelines) && isPopulatedObject(item.stats?.deployment_stats) && item.stats?.deployment_stats?.state !== DEPLOYMENT_STATE.STOPPING, onClick: async (item) => { + const requireForceStop = isPopulatedObject(item.pipelines); + + if (requireForceStop) { + const hasUserApproved = await getUserConfirmation(item); + if (!hasUserApproved) return; + } + try { setIsLoading(true); - await trainedModelsApiService.stopModelAllocation(item.model_id); + await trainedModelsApiService.stopModelAllocation(item.model_id, { + force: requireForceStop, + }); displaySuccessToast( i18n.translate('xpack.ml.trainedModels.modelsList.stopSuccess', { defaultMessage: 'Deployment for "{modelId}" has been stopped successfully.', diff --git a/x-pack/plugins/ml/server/routes/trained_models.ts b/x-pack/plugins/ml/server/routes/trained_models.ts index e7696861153ff..e213efc203704 100644 --- a/x-pack/plugins/ml/server/routes/trained_models.ts +++ b/x-pack/plugins/ml/server/routes/trained_models.ts @@ -16,6 +16,7 @@ import { modelsProvider } from '../models/data_frame_analytics'; import { TrainedModelConfigResponse } from '../../common/types/trained_models'; import { memoryOverviewServiceProvider } from '../models/memory_overview'; import { mlLog } from '../lib/log'; +import { forceQuerySchema } from './schemas/anomaly_detectors_schema'; export function trainedModelsRoutes({ router, routeGuard }: RouteInitialization) { /** @@ -266,6 +267,7 @@ export function trainedModelsRoutes({ router, routeGuard }: RouteInitialization) path: '/api/ml/trained_models/{modelId}/deployment/_stop', validate: { params: modelIdSchema, + query: forceQuerySchema, }, options: { tags: ['access:ml:canGetDataFrameAnalytics'], @@ -276,6 +278,7 @@ export function trainedModelsRoutes({ router, routeGuard }: RouteInitialization) const { modelId } = request.params; const { body } = await mlClient.stopTrainedModelDeployment({ model_id: modelId, + force: request.query.force ?? false, }); return response.ok({ body, From b0b1efd75dc28a14e54a11ea13877888908f7538 Mon Sep 17 00:00:00 2001 From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com> Date: Thu, 25 Nov 2021 11:04:06 +0100 Subject: [PATCH 21/46] [Fleet] fix upgradeable agents filter (#119338) * fix upgradeable * added unit tests * fix review comments Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../fleet/server/services/agents/crud.test.ts | 195 ++++++++++++++++++ .../fleet/server/services/agents/crud.ts | 46 +++-- 2 files changed, 226 insertions(+), 15 deletions(-) create mode 100644 x-pack/plugins/fleet/server/services/agents/crud.test.ts diff --git a/x-pack/plugins/fleet/server/services/agents/crud.test.ts b/x-pack/plugins/fleet/server/services/agents/crud.test.ts new file mode 100644 index 0000000000000..01b7d21ef2809 --- /dev/null +++ b/x-pack/plugins/fleet/server/services/agents/crud.test.ts @@ -0,0 +1,195 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { ElasticsearchClient } from 'kibana/server'; + +import type { Agent } from '../../types'; + +import { getAgentsByKuery } from './crud'; + +jest.mock('../../../common', () => ({ + ...jest.requireActual('../../../common'), + isAgentUpgradeable: jest.fn().mockImplementation((agent: Agent) => agent.id.includes('up')), +})); + +describe('Agents CRUD test', () => { + let esClientMock: ElasticsearchClient; + let searchMock: jest.Mock; + describe('getAgentsByKuery', () => { + beforeEach(() => { + searchMock = jest.fn(); + esClientMock = { + search: searchMock, + } as unknown as ElasticsearchClient; + }); + function getEsResponse(ids: string[], total: number) { + return { + body: { + hits: { + total: { value: total }, + hits: ids.map((id: string) => ({ + _id: id, + _source: {}, + })), + }, + }, + }; + } + it('should return upgradeable on first page', async () => { + searchMock + .mockImplementationOnce(() => Promise.resolve(getEsResponse(['1', '2', '3', '4', '5'], 7))) + .mockImplementationOnce(() => + Promise.resolve(getEsResponse(['1', '2', '3', '4', '5', 'up', '7'], 7)) + ); + const result = await getAgentsByKuery(esClientMock, { + showUpgradeable: true, + showInactive: false, + page: 1, + perPage: 5, + }); + + expect(result).toEqual({ + agents: [ + { + access_api_key: undefined, + id: 'up', + packages: [], + policy_revision: undefined, + status: 'inactive', + }, + ], + page: 1, + perPage: 5, + total: 1, + }); + }); + + it('should return upgradeable from all pages', async () => { + searchMock + .mockImplementationOnce(() => Promise.resolve(getEsResponse(['1', '2', '3', 'up', '5'], 7))) + .mockImplementationOnce(() => + Promise.resolve(getEsResponse(['1', '2', '3', 'up', '5', 'up2', '7'], 7)) + ); + const result = await getAgentsByKuery(esClientMock, { + showUpgradeable: true, + showInactive: false, + page: 1, + perPage: 5, + }); + + expect(result).toEqual({ + agents: [ + { + access_api_key: undefined, + id: 'up', + packages: [], + policy_revision: undefined, + status: 'inactive', + }, + { + access_api_key: undefined, + id: 'up2', + packages: [], + policy_revision: undefined, + status: 'inactive', + }, + ], + page: 1, + perPage: 5, + total: 2, + }); + }); + + it('should return upgradeable on second page', async () => { + searchMock + .mockImplementationOnce(() => Promise.resolve(getEsResponse(['up6', '7'], 7))) + .mockImplementationOnce(() => + Promise.resolve(getEsResponse(['up1', 'up2', 'up3', 'up4', 'up5', 'up6', '7'], 7)) + ); + const result = await getAgentsByKuery(esClientMock, { + showUpgradeable: true, + showInactive: false, + page: 2, + perPage: 5, + }); + + expect(result).toEqual({ + agents: [ + { + access_api_key: undefined, + id: 'up6', + packages: [], + policy_revision: undefined, + status: 'inactive', + }, + ], + page: 2, + perPage: 5, + total: 6, + }); + }); + + it('should return upgradeable from one page when total is more than limit', async () => { + searchMock.mockImplementationOnce(() => + Promise.resolve(getEsResponse(['1', '2', '3', 'up', '5'], 10001)) + ); + const result = await getAgentsByKuery(esClientMock, { + showUpgradeable: true, + showInactive: false, + page: 1, + perPage: 5, + }); + + expect(result).toEqual({ + agents: [ + { + access_api_key: undefined, + id: 'up', + packages: [], + policy_revision: undefined, + status: 'inactive', + }, + ], + page: 1, + perPage: 5, + total: 10001, + }); + }); + + it('should return second page', async () => { + searchMock.mockImplementationOnce(() => Promise.resolve(getEsResponse(['6', '7'], 7))); + const result = await getAgentsByKuery(esClientMock, { + showUpgradeable: false, + showInactive: false, + page: 2, + perPage: 5, + }); + + expect(result).toEqual({ + agents: [ + { + access_api_key: undefined, + id: '6', + packages: [], + policy_revision: undefined, + status: 'inactive', + }, + { + access_api_key: undefined, + id: '7', + packages: [], + policy_revision: undefined, + status: 'inactive', + }, + ], + page: 2, + perPage: 5, + total: 7, + }); + }); + }); +}); diff --git a/x-pack/plugins/fleet/server/services/agents/crud.ts b/x-pack/plugins/fleet/server/services/agents/crud.ts index 516acf5a120de..6a00e2d5a6e1d 100644 --- a/x-pack/plugins/fleet/server/services/agents/crud.ts +++ b/x-pack/plugins/fleet/server/services/agents/crud.ts @@ -122,30 +122,46 @@ export async function getAgentsByKuery( const kueryNode = _joinFilters(filters); const body = kueryNode ? { query: toElasticsearchQuery(kueryNode) } : {}; - const res = await esClient.search({ - index: AGENTS_INDEX, - from: (page - 1) * perPage, - size: perPage, - track_total_hits: true, - ignore_unavailable: true, - body: { - ...body, - sort: [{ [sortField]: { order: sortOrder } }], - }, - }); + const queryAgents = async (from: number, size: number) => + esClient.search({ + index: AGENTS_INDEX, + from, + size, + track_total_hits: true, + ignore_unavailable: true, + body: { + ...body, + sort: [{ [sortField]: { order: sortOrder } }], + }, + }); + const res = await queryAgents((page - 1) * perPage, perPage); let agents = res.body.hits.hits.map(searchHitToAgent); + let total = (res.body.hits.total as estypes.SearchTotalHits).value; // filtering for a range on the version string will not work, // nor does filtering on a flattened field (local_metadata), so filter here if (showUpgradeable) { - agents = agents.filter((agent) => - isAgentUpgradeable(agent, appContextService.getKibanaVersion()) - ); + // fixing a bug where upgradeable filter was not returning right results https://github.com/elastic/kibana/issues/117329 + // query all agents, then filter upgradeable, and return the requested page and correct total + // if there are more than SO_SEARCH_LIMIT agents, the logic falls back to same as before + if (total < SO_SEARCH_LIMIT) { + const response = await queryAgents(0, SO_SEARCH_LIMIT); + agents = response.body.hits.hits + .map(searchHitToAgent) + .filter((agent) => isAgentUpgradeable(agent, appContextService.getKibanaVersion())); + total = agents.length; + const start = (page - 1) * perPage; + agents = agents.slice(start, start + perPage); + } else { + agents = agents.filter((agent) => + isAgentUpgradeable(agent, appContextService.getKibanaVersion()) + ); + } } return { agents, - total: (res.body.hits.total as estypes.SearchTotalHits).value, + total, page, perPage, }; From 37b9fce07659cf68169305263e3191b7f2105448 Mon Sep 17 00:00:00 2001 From: Robert Oskamp Date: Thu, 25 Nov 2021 12:33:35 +0100 Subject: [PATCH 22/46] Functional tests - adjust userMenu timeout (#119607) This PR stabilizes the login during functional tests by adjusting the timeout for the opened user menu. --- x-pack/test/functional/services/user_menu.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/test/functional/services/user_menu.js b/x-pack/test/functional/services/user_menu.js index b69f853249e41..e3f589386fc2e 100644 --- a/x-pack/test/functional/services/user_menu.js +++ b/x-pack/test/functional/services/user_menu.js @@ -45,7 +45,7 @@ export function UserMenuProvider({ getService }) { await retry.try(async () => { await testSubjects.click('userMenuButton'); - await testSubjects.existOrFail('userMenu'); + await testSubjects.existOrFail('userMenu', { timeout: 2500 }); }); } })(); From 905d6b5274d4dd9d639dfec6a2c564b4e74a9479 Mon Sep 17 00:00:00 2001 From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com> Date: Thu, 25 Nov 2021 12:40:18 +0100 Subject: [PATCH 23/46] fix flaky test (#119713) --- .../fleet/server/telemetry/sender.test.ts | 21 +++++++++---------- .../plugins/fleet/server/telemetry/sender.ts | 6 +++--- 2 files changed, 13 insertions(+), 14 deletions(-) diff --git a/x-pack/plugins/fleet/server/telemetry/sender.test.ts b/x-pack/plugins/fleet/server/telemetry/sender.test.ts index a1ba0693bf3f3..1ed77d43b06ad 100644 --- a/x-pack/plugins/fleet/server/telemetry/sender.test.ts +++ b/x-pack/plugins/fleet/server/telemetry/sender.test.ts @@ -32,6 +32,15 @@ describe('TelemetryEventsSender', () => { beforeEach(() => { logger = loggingSystemMock.createLogger(); sender = new TelemetryEventsSender(logger); + sender['fetchClusterInfo'] = jest.fn(async () => { + return { + cluster_uuid: '1', + cluster_name: 'name', + version: { + number: '8.0.0', + }, + } as InfoResponse; + }); sender.start(undefined, { elasticsearch: { client: { asInternalUser: { info: jest.fn(async () => ({})) } } }, } as any); @@ -76,7 +85,7 @@ describe('TelemetryEventsSender', () => { expect(sender['sendEvents']).toHaveBeenCalledWith( 'https://telemetry-staging.elastic.co/v3/send/fleet-upgrades', - undefined, + { cluster_name: 'name', cluster_uuid: '1', version: { number: '8.0.0' } }, expect.anything() ); }); @@ -113,16 +122,6 @@ describe('TelemetryEventsSender', () => { ), }; - sender['fetchClusterInfo'] = jest.fn(async () => { - return { - cluster_uuid: '1', - cluster_name: 'name', - version: { - number: '8.0.0', - }, - } as InfoResponse; - }); - const myChannelEvents = [{ 'event.kind': '1' }, { 'event.kind': '2' }]; // @ts-ignore sender.queueTelemetryEvents('my-channel', myChannelEvents); diff --git a/x-pack/plugins/fleet/server/telemetry/sender.ts b/x-pack/plugins/fleet/server/telemetry/sender.ts index e7413872b6245..473ff470842bf 100644 --- a/x-pack/plugins/fleet/server/telemetry/sender.ts +++ b/x-pack/plugins/fleet/server/telemetry/sender.ts @@ -34,6 +34,7 @@ export class TelemetryEventsSender { private queuesPerChannel: { [channel: string]: TelemetryQueue } = {}; private isOptedIn?: boolean = true; // Assume true until the first check private esClient?: ElasticsearchClient; + private clusterInfo?: InfoResponse; constructor(logger: Logger) { this.logger = logger; @@ -46,6 +47,7 @@ export class TelemetryEventsSender { public async start(telemetryStart?: TelemetryPluginStart, core?: CoreStart) { this.telemetryStart = telemetryStart; this.esClient = core?.elasticsearch.client.asInternalUser; + this.clusterInfo = await this.fetchClusterInfo(); this.logger.debug(`Starting local task`); setTimeout(() => { @@ -92,12 +94,10 @@ export class TelemetryEventsSender { return; } - const clusterInfo = await this.fetchClusterInfo(); - for (const channel of Object.keys(this.queuesPerChannel)) { await this.sendEvents( await this.fetchTelemetryUrl(channel), - clusterInfo, + this.clusterInfo, this.queuesPerChannel[channel] ); } From 8fcbaead1098cfc35f8e04ff147ab6e957eb867b Mon Sep 17 00:00:00 2001 From: Dima Arnautov Date: Thu, 25 Nov 2021 12:54:13 +0100 Subject: [PATCH 24/46] update i18n import (#119724) --- .../trained_models/models_management/force_stop_dialog.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/ml/public/application/trained_models/models_management/force_stop_dialog.tsx b/x-pack/plugins/ml/public/application/trained_models/models_management/force_stop_dialog.tsx index 6d2a3880180eb..86120a4003e23 100644 --- a/x-pack/plugins/ml/public/application/trained_models/models_management/force_stop_dialog.tsx +++ b/x-pack/plugins/ml/public/application/trained_models/models_management/force_stop_dialog.tsx @@ -7,7 +7,7 @@ import React, { FC } from 'react'; import { EuiConfirmModal } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n/react'; +import { FormattedMessage } from '@kbn/i18n-react'; import type { OverlayStart } from 'kibana/public'; import type { ModelItem } from './models_list'; import { toMountPoint } from '../../../../../../../src/plugins/kibana_react/public'; From c7b0aabd062ee0cb339f9819ff2ffb7cd11b8c24 Mon Sep 17 00:00:00 2001 From: Anton Dosov Date: Thu, 25 Nov 2021 13:43:13 +0100 Subject: [PATCH 25/46] [FieldFormats] fix example plugin: register examples format on server (#119483) --- .../common/example_currency_format.ts | 39 +++++++++++++++++++ .../field_formats_example/common/index.ts | 9 +++++ examples/field_formats_example/kibana.json | 1 + examples/field_formats_example/public/app.tsx | 15 +++++-- .../examples/2_creating_custom_formatter.ts | 38 ++++-------------- .../3_creating_custom_format_editor.tsx | 2 +- .../examples/2_creating_custom_formatter.ts | 19 +++++++++ .../field_formats_example/server/index.ts | 13 +++++++ .../field_formats_example/server/plugin.ts | 29 ++++++++++++++ .../lib/babel_register_for_test_plugins.js | 1 + 10 files changed, 131 insertions(+), 35 deletions(-) create mode 100644 examples/field_formats_example/common/example_currency_format.ts create mode 100644 examples/field_formats_example/common/index.ts create mode 100644 examples/field_formats_example/server/examples/2_creating_custom_formatter.ts create mode 100644 examples/field_formats_example/server/index.ts create mode 100644 examples/field_formats_example/server/plugin.ts diff --git a/examples/field_formats_example/common/example_currency_format.ts b/examples/field_formats_example/common/example_currency_format.ts new file mode 100644 index 0000000000000..18ff46892a02c --- /dev/null +++ b/examples/field_formats_example/common/example_currency_format.ts @@ -0,0 +1,39 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { KBN_FIELD_TYPES } from '@kbn/field-types'; +import { FieldFormat } from '../../../src/plugins/field_formats/common'; + +// 1. Create a custom formatter by extending {@link FieldFormat} +export class ExampleCurrencyFormat extends FieldFormat { + static id = 'example-currency'; + static title = 'Currency (example)'; + + // 2. Specify field types that this formatter supports + static fieldType = KBN_FIELD_TYPES.NUMBER; + + // Or pass an array in case supports multiple types + // static fieldType = [KBN_FIELD_TYPES.NUMBER, KBN_FIELD_TYPES.DATE]; + + // 3. This formats support a `currency` param. Use `EUR` as a default. + getParamDefaults() { + return { + currency: 'EUR', + }; + } + + // 4. Implement a conversion function + textConvert = (val: unknown) => { + if (typeof val !== 'number') return `${val}`; + + return new Intl.NumberFormat(undefined, { + style: 'currency', + currency: this.param('currency'), + }).format(val); + }; +} diff --git a/examples/field_formats_example/common/index.ts b/examples/field_formats_example/common/index.ts new file mode 100644 index 0000000000000..f2d04e195d2d8 --- /dev/null +++ b/examples/field_formats_example/common/index.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { ExampleCurrencyFormat } from './example_currency_format'; diff --git a/examples/field_formats_example/kibana.json b/examples/field_formats_example/kibana.json index e8219c132dfa3..e3bca1b2fcb9e 100644 --- a/examples/field_formats_example/kibana.json +++ b/examples/field_formats_example/kibana.json @@ -3,6 +3,7 @@ "version": "1.0.0", "kibanaVersion": "kibana", "ui": true, + "server": true, "owner": { "name": "App Services", "githubTeam": "kibana-app-services" diff --git a/examples/field_formats_example/public/app.tsx b/examples/field_formats_example/public/app.tsx index ce4995672d227..f3ec0b15d2ab4 100644 --- a/examples/field_formats_example/public/app.tsx +++ b/examples/field_formats_example/public/app.tsx @@ -29,7 +29,11 @@ import * as example2 from './examples/2_creating_custom_formatter'; // @ts-ignore import example1SampleCode from '!!raw-loader!./examples/1_using_existing_format'; // @ts-ignore -import example2SampleCode from '!!raw-loader!./examples/2_creating_custom_formatter'; +import example2SampleCodePart1 from '!!raw-loader!../common/example_currency_format'; +// @ts-ignore +import example2SampleCodePart2 from '!!raw-loader!./examples/2_creating_custom_formatter'; +// @ts-ignore +import example2SampleCodePart3 from '!!raw-loader!../server/examples/2_creating_custom_formatter'; // @ts-ignore import example3SampleCode from '!!raw-loader!./examples/3_creating_custom_format_editor'; @@ -88,11 +92,16 @@ const CreatingCustomFieldFormat: React.FC<{ deps: Deps }> = (props) => {

This example shows how to create a custom field formatter. As an example, we create a - currency formatter and then display some values as USD. + currency formatter and then display some values as USD. Custom field + formatter has to be registered both client and server side.

- {example2SampleCode} + {example2SampleCodePart1} + + {example2SampleCodePart2} + + {example2SampleCodePart3} { - if (typeof val !== 'number') return `${val}`; - - return new Intl.NumberFormat(undefined, { - style: 'currency', - currency: this.param('currency'), - }).format(val); - }; -} +import { ExampleCurrencyFormat } from '../../common'; export function registerExampleFormat(fieldFormats: FieldFormatsSetup) { - // 5. Register a field format. This should happen in setup plugin lifecycle phase. + // 5.1 Register a field format. This should happen in setup plugin lifecycle phase. fieldFormats.register([ExampleCurrencyFormat]); } +// 5.2 also register a field formatter with the same `formatId` server-side. +// This is required for some server-side features like CSV export, +// see: examples/field_formats_example/public/examples/2_creating_custom_formatter.ts + // 6. Now let's apply the formatter to some sample values export function getSample(fieldFormats: FieldFormatsStart) { const exampleSerializedFieldFormat: SerializedFieldFormat<{ currency: string }> = { diff --git a/examples/field_formats_example/public/examples/3_creating_custom_format_editor.tsx b/examples/field_formats_example/public/examples/3_creating_custom_format_editor.tsx index e3b2a7a876500..e0863a952f8b3 100644 --- a/examples/field_formats_example/public/examples/3_creating_custom_format_editor.tsx +++ b/examples/field_formats_example/public/examples/3_creating_custom_format_editor.tsx @@ -13,7 +13,7 @@ import { FieldFormatEditorFactory, IndexPatternFieldEditorSetup, } from '../../../../src/plugins/data_view_field_editor/public'; -import { ExampleCurrencyFormat } from './2_creating_custom_formatter'; +import { ExampleCurrencyFormat } from '../../common'; // 1. Create an editor component // NOTE: the `params` field is not type checked and a consumer has to know the `param` format that a particular `formatId` expects, diff --git a/examples/field_formats_example/server/examples/2_creating_custom_formatter.ts b/examples/field_formats_example/server/examples/2_creating_custom_formatter.ts new file mode 100644 index 0000000000000..a2dbb9594512b --- /dev/null +++ b/examples/field_formats_example/server/examples/2_creating_custom_formatter.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +// This is server-side continuation of examples/field_formats_example/public/examples/2_creating_custom_formatter.ts + +import { FieldFormatsSetup } from '../../../../src/plugins/field_formats/server'; + +import { ExampleCurrencyFormat } from '../../common'; + +// When registering a field formatter, be sure to also register it server-side. +// This would be needed, for example, for CSV generation, as reports are generated server-side. +export function registerExampleFormat(fieldFormats: FieldFormatsSetup) { + fieldFormats.register(ExampleCurrencyFormat); +} diff --git a/examples/field_formats_example/server/index.ts b/examples/field_formats_example/server/index.ts new file mode 100644 index 0000000000000..cd8ee4c30b63a --- /dev/null +++ b/examples/field_formats_example/server/index.ts @@ -0,0 +1,13 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { FieldFormatsExamplePlugin } from './plugin'; + +export function plugin() { + return new FieldFormatsExamplePlugin(); +} diff --git a/examples/field_formats_example/server/plugin.ts b/examples/field_formats_example/server/plugin.ts new file mode 100644 index 0000000000000..2163e0fc6e9fe --- /dev/null +++ b/examples/field_formats_example/server/plugin.ts @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { CoreSetup, CoreStart, Plugin } from '../../../src/core/server'; +import { FieldFormatsSetup, FieldFormatsStart } from '../../../src/plugins/field_formats/server'; +import { registerExampleFormat } from './examples/2_creating_custom_formatter'; + +interface SetupDeps { + fieldFormats: FieldFormatsSetup; +} + +interface StartDeps { + fieldFormats: FieldFormatsStart; +} + +export class FieldFormatsExamplePlugin implements Plugin { + public setup(core: CoreSetup, deps: SetupDeps) { + registerExampleFormat(deps.fieldFormats); + } + public start(core: CoreStart) { + return {}; + } + public stop() {} +} diff --git a/packages/kbn-test/src/functional_tests/lib/babel_register_for_test_plugins.js b/packages/kbn-test/src/functional_tests/lib/babel_register_for_test_plugins.js index 09ed81b62a09d..03947f7e267ba 100644 --- a/packages/kbn-test/src/functional_tests/lib/babel_register_for_test_plugins.js +++ b/packages/kbn-test/src/functional_tests/lib/babel_register_for_test_plugins.js @@ -23,6 +23,7 @@ const transpileKbnPaths = [ // TODO: should should probably remove this link back to the source 'x-pack/plugins/task_manager/server/config.ts', 'src/core/utils/default_app_categories.ts', + 'src/plugins/field_formats/common', ].map((path) => Path.resolve(BASE_REPO_ROOT, path)); // modifies all future calls to require() to automatically From 8cbf57a7ffd23d7dec0dc98e19142c1ffd77b1c3 Mon Sep 17 00:00:00 2001 From: Corey Robertson Date: Thu, 25 Nov 2021 08:01:00 -0500 Subject: [PATCH 26/46] Revert "Unskip flaky test (#117402)" (#119549) --- .../apps/dashboard/feature_controls/dashboard_security.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/dashboard/feature_controls/dashboard_security.ts b/x-pack/test/functional/apps/dashboard/feature_controls/dashboard_security.ts index 1873aeffb3884..1b1aa9abc831a 100644 --- a/x-pack/test/functional/apps/dashboard/feature_controls/dashboard_security.ts +++ b/x-pack/test/functional/apps/dashboard/feature_controls/dashboard_security.ts @@ -499,7 +499,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); }); - describe('no dashboard privileges', () => { + // FLAKY: https://github.com/elastic/kibana/issues/116881 + describe.skip('no dashboard privileges', () => { before(async () => { await security.role.create('no_dashboard_privileges_role', { elasticsearch: { From 5e93d91fae39d7ef18d16503f23eb294bcd6c450 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 25 Nov 2021 14:19:43 +0100 Subject: [PATCH 27/46] [Uptime] Generate api key for synthetics service (#119590) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../synthetics_service_api_key.ts | 26 ++++++ x-pack/plugins/uptime/kibana.json | 8 +- x-pack/plugins/uptime/server/kibana.index.ts | 4 +- .../lib/adapters/framework/adapter_types.ts | 16 +++- .../server/lib/alerts/duration_anomaly.ts | 4 +- .../server/lib/alerts/test_utils/index.ts | 6 +- .../plugins/uptime/server/lib/alerts/types.ts | 4 +- .../uptime/server/lib/saved_objects/index.ts | 8 ++ .../server/lib/saved_objects/saved_objects.ts | 26 ++++-- .../lib/saved_objects/service_api_key.ts | 74 +++++++++++++++ .../synthetics_service/get_api_key.test.ts | 90 +++++++++++++++++++ .../lib/synthetics_service/get_api_key.ts | 85 ++++++++++++++++++ x-pack/plugins/uptime/server/plugin.ts | 27 +++--- .../server/rest_api/create_route_with_auth.ts | 2 + .../plugins/uptime/server/rest_api/types.ts | 8 +- .../server/rest_api/uptime_route_wrapper.ts | 3 +- x-pack/plugins/uptime/server/uptime_server.ts | 6 +- 17 files changed, 360 insertions(+), 37 deletions(-) create mode 100644 x-pack/plugins/uptime/common/runtime_types/synthetics_service_api_key.ts create mode 100644 x-pack/plugins/uptime/server/lib/saved_objects/index.ts create mode 100644 x-pack/plugins/uptime/server/lib/saved_objects/service_api_key.ts create mode 100644 x-pack/plugins/uptime/server/lib/synthetics_service/get_api_key.test.ts create mode 100644 x-pack/plugins/uptime/server/lib/synthetics_service/get_api_key.ts diff --git a/x-pack/plugins/uptime/common/runtime_types/synthetics_service_api_key.ts b/x-pack/plugins/uptime/common/runtime_types/synthetics_service_api_key.ts new file mode 100644 index 0000000000000..e216c0f791203 --- /dev/null +++ b/x-pack/plugins/uptime/common/runtime_types/synthetics_service_api_key.ts @@ -0,0 +1,26 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import * as t from 'io-ts'; + +export const SyntheticsServiceApiKeyType = t.type({ + id: t.string, + name: t.string, + apiKey: t.string, +}); + +export const SyntheticsServiceApiKeySaveType = t.intersection([ + t.type({ + success: t.boolean, + }), + t.partial({ + error: t.string, + }), +]); + +export type SyntheticsServiceApiKey = t.TypeOf; +export type SyntheticsServiceApiKeySaveResponse = t.TypeOf; diff --git a/x-pack/plugins/uptime/kibana.json b/x-pack/plugins/uptime/kibana.json index 409436d734011..18865735f3ebc 100644 --- a/x-pack/plugins/uptime/kibana.json +++ b/x-pack/plugins/uptime/kibana.json @@ -14,13 +14,15 @@ "requiredPlugins": [ "alerting", "embeddable", + "encryptedSavedObjects", "inspector", "features", "licensing", - "triggersActionsUi", - "usageCollection", + "observability", "ruleRegistry", - "observability" + "security", + "triggersActionsUi", + "usageCollection" ], "server": true, "ui": true, diff --git a/x-pack/plugins/uptime/server/kibana.index.ts b/x-pack/plugins/uptime/server/kibana.index.ts index 131510e62c5d9..945a4295148a2 100644 --- a/x-pack/plugins/uptime/server/kibana.index.ts +++ b/x-pack/plugins/uptime/server/kibana.index.ts @@ -11,7 +11,7 @@ import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/server'; import { PLUGIN } from '../common/constants/plugin'; import { compose } from './lib/compose/kibana'; import { initUptimeServer } from './uptime_server'; -import { UptimeCorePlugins, UptimeCoreSetup } from './lib/adapters/framework'; +import { UptimeCorePluginsSetup, UptimeCoreSetup } from './lib/adapters/framework'; import { umDynamicSettings } from './lib/saved_objects/uptime_settings'; import { UptimeRuleRegistry } from './plugin'; @@ -29,7 +29,7 @@ export interface KibanaServer extends Server { export const initServerWithKibana = ( server: UptimeCoreSetup, - plugins: UptimeCorePlugins, + plugins: UptimeCorePluginsSetup, ruleRegistry: UptimeRuleRegistry, logger: Logger ) => { diff --git a/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts index d9648a8aae575..bafaf60770dcd 100644 --- a/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts @@ -12,12 +12,17 @@ import type { IScopedClusterClient, } from 'src/core/server'; import { ObservabilityPluginSetup } from '../../../../../observability/server'; +import { + EncryptedSavedObjectsPluginSetup, + EncryptedSavedObjectsPluginStart, +} from '../../../../../encrypted_saved_objects/server'; import { UMKibanaRoute } from '../../../rest_api'; import { PluginSetupContract } from '../../../../../features/server'; import { MlPluginSetup as MlSetup } from '../../../../../ml/server'; import { RuleRegistryPluginSetupContract } from '../../../../../rule_registry/server'; import { UptimeESClient } from '../../lib'; import type { UptimeRouter } from '../../../types'; +import { SecurityPluginStart } from '../../../../../security/server'; import { UptimeConfig } from '../../../../common/config'; export type UMElasticsearchQueryFn = ( @@ -35,16 +40,23 @@ export type UMSavedObjectsQueryFn = ( export interface UptimeCoreSetup { router: UptimeRouter; config: UptimeConfig; + security: SecurityPluginStart; + encryptedSavedObjects: EncryptedSavedObjectsPluginStart; } -export interface UptimeCorePlugins { +export interface UptimeCorePluginsSetup { features: PluginSetupContract; alerting: any; - elasticsearch: any; observability: ObservabilityPluginSetup; usageCollection: UsageCollectionSetup; ml: MlSetup; ruleRegistry: RuleRegistryPluginSetupContract; + encryptedSavedObjects: EncryptedSavedObjectsPluginSetup; +} + +export interface UptimeCorePluginsStart { + security: SecurityPluginStart; + encryptedSavedObjects: EncryptedSavedObjectsPluginStart; } export interface UMBackendFrameworkAdapter { diff --git a/x-pack/plugins/uptime/server/lib/alerts/duration_anomaly.ts b/x-pack/plugins/uptime/server/lib/alerts/duration_anomaly.ts index cf241386ec277..7dc962c38fec7 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/duration_anomaly.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/duration_anomaly.ts @@ -19,7 +19,7 @@ import { DURATION_ANOMALY } from '../../../common/constants/alerts'; import { commonStateTranslations, durationAnomalyTranslations } from './translations'; import { AnomaliesTableRecord } from '../../../../ml/common/types/anomalies'; import { getSeverityType } from '../../../../ml/common/util/anomaly_utils'; -import { UptimeCorePlugins } from '../adapters/framework'; +import { UptimeCorePluginsSetup } from '../adapters/framework'; import { UptimeAlertTypeFactory } from './types'; import { Ping } from '../../../common/runtime_types/ping'; import { getMLJobId } from '../../../common/lib'; @@ -45,7 +45,7 @@ export const getAnomalySummary = (anomaly: AnomaliesTableRecord, monitorInfo: Pi }; const getAnomalies = async ( - plugins: UptimeCorePlugins, + plugins: UptimeCorePluginsSetup, savedObjectsClient: SavedObjectsClientContract, params: Record, lastCheckedAt: string diff --git a/x-pack/plugins/uptime/server/lib/alerts/test_utils/index.ts b/x-pack/plugins/uptime/server/lib/alerts/test_utils/index.ts index bc9aa76cb4a5b..6481a1e2ebdcf 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/test_utils/index.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/test_utils/index.ts @@ -7,7 +7,7 @@ import { Logger } from 'kibana/server'; import { UMServerLibs } from '../../lib'; -import { UptimeCorePlugins, UptimeCoreSetup } from '../../adapters'; +import { UptimeCorePluginsSetup, UptimeCoreSetup } from '../../adapters'; import type { UptimeRouter } from '../../../types'; import type { IRuleDataClient } from '../../../../../rule_registry/server'; import { ruleRegistryMocks } from '../../../../../rule_registry/server/mocks'; @@ -27,8 +27,8 @@ export const bootstrapDependencies = (customRequests?: any, customPlugins: any = const router = {} as UptimeRouter; // these server/libs parameters don't have any functionality, which is fine // because we aren't testing them here - const server: UptimeCoreSetup = { router, config: {} }; - const plugins: UptimeCorePlugins = customPlugins as any; + const server = { router, config: {} } as UptimeCoreSetup; + const plugins: UptimeCorePluginsSetup = customPlugins as any; const libs: UMServerLibs = { requests: {} } as UMServerLibs; libs.requests = { ...libs.requests, ...customRequests }; return { server, libs, plugins }; diff --git a/x-pack/plugins/uptime/server/lib/alerts/types.ts b/x-pack/plugins/uptime/server/lib/alerts/types.ts index f4ac2f354d814..f734628e61b95 100644 --- a/x-pack/plugins/uptime/server/lib/alerts/types.ts +++ b/x-pack/plugins/uptime/server/lib/alerts/types.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ -import { UptimeCorePlugins, UptimeCoreSetup } from '../adapters'; +import { UptimeCorePluginsSetup, UptimeCoreSetup } from '../adapters'; import { UMServerLibs } from '../lib'; import { AlertTypeWithExecutor } from '../../../../rule_registry/server'; import { AlertInstanceContext, AlertTypeState } from '../../../../alerting/common'; @@ -32,5 +32,5 @@ export type DefaultUptimeAlertInstance = AlertTy export type UptimeAlertTypeFactory = ( server: UptimeCoreSetup, libs: UMServerLibs, - plugins: UptimeCorePlugins + plugins: UptimeCorePluginsSetup ) => DefaultUptimeAlertInstance; diff --git a/x-pack/plugins/uptime/server/lib/saved_objects/index.ts b/x-pack/plugins/uptime/server/lib/saved_objects/index.ts new file mode 100644 index 0000000000000..ee1cfbbc55acd --- /dev/null +++ b/x-pack/plugins/uptime/server/lib/saved_objects/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { savedObjectsAdapter } from './saved_objects'; diff --git a/x-pack/plugins/uptime/server/lib/saved_objects/saved_objects.ts b/x-pack/plugins/uptime/server/lib/saved_objects/saved_objects.ts index 7a53a37b804e9..5aa6b7ea7c5a9 100644 --- a/x-pack/plugins/uptime/server/lib/saved_objects/saved_objects.ts +++ b/x-pack/plugins/uptime/server/lib/saved_objects/saved_objects.ts @@ -9,33 +9,43 @@ import { SavedObjectsErrorHelpers, SavedObjectsServiceSetup, } from '../../../../../../src/core/server'; +import { EncryptedSavedObjectsPluginSetup } from '../../../../encrypted_saved_objects/server'; + import { DYNAMIC_SETTINGS_DEFAULTS } from '../../../common/constants'; import { DynamicSettings } from '../../../common/runtime_types'; import { UMSavedObjectsQueryFn } from '../adapters'; import { UptimeConfig } from '../../../common/config'; import { settingsObjectId, umDynamicSettings } from './uptime_settings'; import { syntheticsMonitor } from './synthetics_monitor'; - -export interface UMSavedObjectsAdapter { - config: UptimeConfig; - getUptimeDynamicSettings: UMSavedObjectsQueryFn; - setUptimeDynamicSettings: UMSavedObjectsQueryFn; -} +import { syntheticsServiceApiKey } from './service_api_key'; export const registerUptimeSavedObjects = ( savedObjectsService: SavedObjectsServiceSetup, + encryptedSavedObjects: EncryptedSavedObjectsPluginSetup, config: UptimeConfig ) => { savedObjectsService.registerType(umDynamicSettings); if (config?.unsafe?.service.enabled) { savedObjectsService.registerType(syntheticsMonitor); + savedObjectsService.registerType(syntheticsServiceApiKey); + + encryptedSavedObjects.registerType({ + type: syntheticsServiceApiKey.name, + attributesToEncrypt: new Set(['apiKey']), + }); } }; +export interface UMSavedObjectsAdapter { + config: UptimeConfig; + getUptimeDynamicSettings: UMSavedObjectsQueryFn; + setUptimeDynamicSettings: UMSavedObjectsQueryFn; +} + export const savedObjectsAdapter: UMSavedObjectsAdapter = { config: null, - getUptimeDynamicSettings: async (client): Promise => { + getUptimeDynamicSettings: async (client) => { try { const obj = await client.get(umDynamicSettings.name, settingsObjectId); return obj?.attributes ?? DYNAMIC_SETTINGS_DEFAULTS; @@ -50,7 +60,7 @@ export const savedObjectsAdapter: UMSavedObjectsAdapter = { throw getErr; } }, - setUptimeDynamicSettings: async (client, settings): Promise => { + setUptimeDynamicSettings: async (client, settings) => { await client.create(umDynamicSettings.name, settings, { id: settingsObjectId, overwrite: true, diff --git a/x-pack/plugins/uptime/server/lib/saved_objects/service_api_key.ts b/x-pack/plugins/uptime/server/lib/saved_objects/service_api_key.ts new file mode 100644 index 0000000000000..9a85b71356461 --- /dev/null +++ b/x-pack/plugins/uptime/server/lib/saved_objects/service_api_key.ts @@ -0,0 +1,74 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { i18n } from '@kbn/i18n'; +import { + SavedObjectsClientContract, + SavedObjectsErrorHelpers, + SavedObjectsType, +} from '../../../../../../src/core/server'; +import { SyntheticsServiceApiKey } from '../../../common/runtime_types/synthetics_service_api_key'; +import { EncryptedSavedObjectsClient } from '../../../../encrypted_saved_objects/server'; + +export const syntheticsApiKeyID = 'ba997842-b0cf-4429-aa9d-578d9bf0d391'; +const syntheticsApiKeyObjectType = 'uptime-synthetics-api-key'; + +export const syntheticsServiceApiKey: SavedObjectsType = { + name: syntheticsApiKeyObjectType, + hidden: true, + namespaceType: 'single', + mappings: { + dynamic: false, + properties: { + apiKey: { + type: 'binary', + }, + /* Leaving these commented to make it clear that these fields exist, even though we don't want them indexed. + When adding new fields please add them here. If they need to be searchable put them in the uncommented + part of properties. + id: { + type: 'keyword', + }, + name: { + type: 'long', + }, + */ + }, + }, + management: { + importableAndExportable: false, + icon: 'uptimeApp', + getTitle: () => + i18n.translate('xpack.uptime.synthetics.service.apiKey', { + defaultMessage: 'Synthetics service api key', + }), + }, +}; + +export const getSyntheticsServiceAPIKey = async (client: EncryptedSavedObjectsClient) => { + try { + const obj = await client.getDecryptedAsInternalUser( + syntheticsServiceApiKey.name, + syntheticsApiKeyID + ); + return obj?.attributes; + } catch (getErr) { + if (SavedObjectsErrorHelpers.isNotFoundError(getErr)) { + return undefined; + } + throw getErr; + } +}; +export const setSyntheticsServiceApiKey = async ( + client: SavedObjectsClientContract, + apiKey: SyntheticsServiceApiKey +) => { + await client.create(syntheticsServiceApiKey.name, apiKey, { + id: syntheticsApiKeyID, + overwrite: true, + }); +}; diff --git a/x-pack/plugins/uptime/server/lib/synthetics_service/get_api_key.test.ts b/x-pack/plugins/uptime/server/lib/synthetics_service/get_api_key.test.ts new file mode 100644 index 0000000000000..1d164f5dd5b62 --- /dev/null +++ b/x-pack/plugins/uptime/server/lib/synthetics_service/get_api_key.test.ts @@ -0,0 +1,90 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getAPIKeyForSyntheticsService } from './get_api_key'; +import { encryptedSavedObjectsMock } from '../../../../encrypted_saved_objects/server/mocks'; +import { securityMock } from '../../../../security/server/mocks'; +import { coreMock } from '../../../../../../src/core/server/mocks'; +import { syntheticsServiceApiKey } from '../saved_objects/service_api_key'; +import { KibanaRequest } from 'kibana/server'; + +describe('getAPIKeyTest', function () { + const core = coreMock.createStart(); + const security = securityMock.createStart(); + const encryptedSavedObject = encryptedSavedObjectsMock.createStart(); + const request = {} as KibanaRequest; + + security.authc.apiKeys.areAPIKeysEnabled = jest.fn().mockReturnValue(true); + security.authc.apiKeys.create = jest.fn().mockReturnValue({ + id: 'test', + name: 'service-api-key', + api_key: 'qwerty', + encoded: '@#$%^&', + }); + + it('should generate an api key and return it', async () => { + const apiKey = await getAPIKeyForSyntheticsService({ + request, + security, + encryptedSavedObject, + savedObjectsClient: core.savedObjects.getScopedClient(request), + }); + + expect(security.authc.apiKeys.areAPIKeysEnabled).toHaveBeenCalledTimes(1); + expect(security.authc.apiKeys.create).toHaveBeenCalledTimes(1); + expect(security.authc.apiKeys.create).toHaveBeenCalledWith( + {}, + { + name: 'synthetics-api-key', + role_descriptors: { + synthetics_writer: { + cluster: ['monitor', 'read_ilm', 'read_pipeline'], + index: [ + { + names: ['synthetics-*'], + privileges: ['view_index_metadata', 'create_doc', 'auto_configure'], + }, + ], + }, + }, + metadata: { + description: + 'Created for synthetics service to be passed to the heartbeat to communicate with ES', + }, + } + ); + expect(apiKey).toEqual({ apiKey: 'qwerty', id: 'test', name: 'service-api-key' }); + }); + + it('should return existing api key', async () => { + const getObject = jest + .fn() + .mockReturnValue({ attributes: { apiKey: 'qwerty', id: 'test', name: 'service-api-key' } }); + + encryptedSavedObject.getClient = jest.fn().mockReturnValue({ + getDecryptedAsInternalUser: getObject, + }); + const apiKey = await getAPIKeyForSyntheticsService({ + request, + security, + encryptedSavedObject, + savedObjectsClient: core.savedObjects.getScopedClient(request), + }); + + expect(apiKey).toEqual({ apiKey: 'qwerty', id: 'test', name: 'service-api-key' }); + + expect(encryptedSavedObject.getClient).toHaveBeenCalledTimes(1); + expect(getObject).toHaveBeenCalledTimes(1); + expect(encryptedSavedObject.getClient).toHaveBeenCalledWith({ + includedHiddenTypes: [syntheticsServiceApiKey.name], + }); + expect(getObject).toHaveBeenCalledWith( + 'uptime-synthetics-api-key', + 'ba997842-b0cf-4429-aa9d-578d9bf0d391' + ); + }); +}); diff --git a/x-pack/plugins/uptime/server/lib/synthetics_service/get_api_key.ts b/x-pack/plugins/uptime/server/lib/synthetics_service/get_api_key.ts new file mode 100644 index 0000000000000..2a291c64ca2b2 --- /dev/null +++ b/x-pack/plugins/uptime/server/lib/synthetics_service/get_api_key.ts @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { KibanaRequest, SavedObjectsClientContract } from '../../../../../../src/core/server'; +import { EncryptedSavedObjectsPluginStart } from '../../../../encrypted_saved_objects/server'; +import { SecurityPluginStart } from '../../../../security/server'; +import { + getSyntheticsServiceAPIKey, + setSyntheticsServiceApiKey, + syntheticsServiceApiKey, +} from '../saved_objects/service_api_key'; +import { SyntheticsServiceApiKey } from '../../../common/runtime_types/synthetics_service_api_key'; + +export const getAPIKeyForSyntheticsService = async ({ + encryptedSavedObject, + savedObjectsClient, + request, + security, +}: { + encryptedSavedObject: EncryptedSavedObjectsPluginStart; + request: KibanaRequest; + security: SecurityPluginStart; + savedObjectsClient: SavedObjectsClientContract; +}): Promise => { + const encryptedClient = encryptedSavedObject.getClient({ + includedHiddenTypes: [syntheticsServiceApiKey.name], + }); + + const apiKey = await getSyntheticsServiceAPIKey(encryptedClient); + if (apiKey) { + return apiKey; + } + return await generateAndSaveAPIKey({ request, security, savedObjectsClient }); +}; + +export const generateAndSaveAPIKey = async ({ + security, + request, + savedObjectsClient, +}: { + security: SecurityPluginStart; + request: KibanaRequest; + savedObjectsClient: SavedObjectsClientContract; +}) => { + try { + const isApiKeysEnabled = await security.authc.apiKeys?.areAPIKeysEnabled(); + + if (!isApiKeysEnabled) { + return new Error('Please enable API keys in kibana to use synthetics service.'); + } + + const apiKeyResult = await security.authc.apiKeys?.create(request, { + name: 'synthetics-api-key', + role_descriptors: { + synthetics_writer: { + cluster: ['monitor', 'read_ilm', 'read_pipeline'], + index: [ + { + names: ['synthetics-*'], + privileges: ['view_index_metadata', 'create_doc', 'auto_configure'], + }, + ], + }, + }, + metadata: { + description: + 'Created for synthetics service to be passed to the heartbeat to communicate with ES', + }, + }); + + if (apiKeyResult) { + const { id, name, api_key: apiKey } = apiKeyResult; + const apiKeyObject = { id, name, apiKey }; + // discard decoded key and rest of the keys + await setSyntheticsServiceApiKey(savedObjectsClient, apiKeyObject); + return apiKeyObject; + } + } catch (e) { + throw e; + } +}; diff --git a/x-pack/plugins/uptime/server/plugin.ts b/x-pack/plugins/uptime/server/plugin.ts index b1b85eb943c81..aa962605ef2b8 100644 --- a/x-pack/plugins/uptime/server/plugin.ts +++ b/x-pack/plugins/uptime/server/plugin.ts @@ -15,7 +15,12 @@ import { } from '../../../../src/core/server'; import { uptimeRuleFieldMap } from '../common/rules/uptime_rule_field_map'; import { initServerWithKibana } from './kibana.index'; -import { KibanaTelemetryAdapter, UptimeCorePlugins } from './lib/adapters'; +import { + KibanaTelemetryAdapter, + UptimeCorePluginsSetup, + UptimeCorePluginsStart, + UptimeCoreSetup, +} from './lib/adapters'; import { registerUptimeSavedObjects, savedObjectsAdapter } from './lib/saved_objects/saved_objects'; import { mappingFromFieldMap } from '../../rule_registry/common/mapping_from_field_map'; import { Dataset } from '../../rule_registry/server'; @@ -27,12 +32,13 @@ export class Plugin implements PluginType { private savedObjectsClient?: ISavedObjectsRepository; private initContext: PluginInitializerContext; private logger?: Logger; + private server?: UptimeCoreSetup; constructor(_initializerContext: PluginInitializerContext) { this.initContext = _initializerContext; } - public setup(core: CoreSetup, plugins: UptimeCorePlugins) { + public setup(core: CoreSetup, plugins: UptimeCorePluginsSetup) { const config = this.initContext.config.get(); savedObjectsAdapter.config = config; @@ -53,14 +59,11 @@ export class Plugin implements PluginType { ], }); - initServerWithKibana( - { router: core.http.createRouter(), config }, - plugins, - ruleDataClient, - this.logger - ); + this.server = { router: core.http.createRouter(), config } as UptimeCoreSetup; + + initServerWithKibana(this.server, plugins, ruleDataClient, this.logger); - registerUptimeSavedObjects(core.savedObjects, config); + registerUptimeSavedObjects(core.savedObjects, plugins.encryptedSavedObjects, config); KibanaTelemetryAdapter.registerUsageCollector( plugins.usageCollection, @@ -72,8 +75,12 @@ export class Plugin implements PluginType { }; } - public start(core: CoreStart, _plugins: any) { + public start(core: CoreStart, plugins: UptimeCorePluginsStart) { this.savedObjectsClient = core.savedObjects.createInternalRepository(); + if (this.server) { + this.server.security = plugins.security; + this.server.encryptedSavedObjects = plugins.encryptedSavedObjects; + } } public stop() {} diff --git a/x-pack/plugins/uptime/server/rest_api/create_route_with_auth.ts b/x-pack/plugins/uptime/server/rest_api/create_route_with_auth.ts index 8b6add27f889a..c3d7c693ef00a 100644 --- a/x-pack/plugins/uptime/server/rest_api/create_route_with_auth.ts +++ b/x-pack/plugins/uptime/server/rest_api/create_route_with_auth.ts @@ -20,6 +20,7 @@ export const createRouteWithAuth = ( request, response, savedObjectsClient, + server, }) => { const { statusCode, message } = libs.license(context.licensing.license); if (statusCode === 200) { @@ -29,6 +30,7 @@ export const createRouteWithAuth = ( request, response, savedObjectsClient, + server, }); } switch (statusCode) { diff --git a/x-pack/plugins/uptime/server/rest_api/types.ts b/x-pack/plugins/uptime/server/rest_api/types.ts index ea083fc04174e..f8027cefd3f58 100644 --- a/x-pack/plugins/uptime/server/rest_api/types.ts +++ b/x-pack/plugins/uptime/server/rest_api/types.ts @@ -17,6 +17,7 @@ import { } from 'kibana/server'; import { UMServerLibs, UptimeESClient } from '../lib/lib'; import type { UptimeRequestHandlerContext } from '../types'; +import { UptimeCoreSetup } from '../lib/adapters'; /** * Defines the basic properties employed by Uptime routes. @@ -58,7 +59,10 @@ export type UMRestApiRouteFactory = (libs: UMServerLibs) => UptimeRoute; * Functions of this type accept our internal route format and output a route * object that the Kibana platform can consume. */ -export type UMKibanaRouteWrapper = (uptimeRoute: UptimeRoute) => UMKibanaRoute; +export type UMKibanaRouteWrapper = ( + uptimeRoute: UptimeRoute, + server: UptimeCoreSetup +) => UMKibanaRoute; /** * This is the contract we specify internally for route handling. @@ -68,6 +72,7 @@ export type UMRouteHandler = ({ context, request, response, + server, savedObjectsClient, }: { uptimeEsClient: UptimeESClient; @@ -75,4 +80,5 @@ export type UMRouteHandler = ({ request: KibanaRequest, Record, Record>; response: KibanaResponseFactory; savedObjectsClient: SavedObjectsClientContract; + server: UptimeCoreSetup; }) => IKibanaResponse | Promise>; diff --git a/x-pack/plugins/uptime/server/rest_api/uptime_route_wrapper.ts b/x-pack/plugins/uptime/server/rest_api/uptime_route_wrapper.ts index ddde993cc9c70..cd25e0e742625 100644 --- a/x-pack/plugins/uptime/server/rest_api/uptime_route_wrapper.ts +++ b/x-pack/plugins/uptime/server/rest_api/uptime_route_wrapper.ts @@ -12,7 +12,7 @@ import { createUptimeESClient, inspectableEsQueriesMap } from '../lib/lib'; import { KibanaResponse } from '../../../../../src/core/server/http/router'; import { enableInspectEsQueries } from '../../../observability/common'; -export const uptimeRouteWrapper: UMKibanaRouteWrapper = (uptimeRoute) => ({ +export const uptimeRouteWrapper: UMKibanaRouteWrapper = (uptimeRoute, server) => ({ ...uptimeRoute, options: { tags: ['access:uptime-read', ...(uptimeRoute?.writeAccess ? ['access:uptime-write'] : [])], @@ -40,6 +40,7 @@ export const uptimeRouteWrapper: UMKibanaRouteWrapper = (uptimeRoute) => ({ context, request, response, + server, }); if (res instanceof KibanaResponse) { diff --git a/x-pack/plugins/uptime/server/uptime_server.ts b/x-pack/plugins/uptime/server/uptime_server.ts index ded76027a3c3a..ae606d7d4c3bf 100644 --- a/x-pack/plugins/uptime/server/uptime_server.ts +++ b/x-pack/plugins/uptime/server/uptime_server.ts @@ -9,7 +9,7 @@ import { Logger } from 'kibana/server'; import { createLifecycleRuleTypeFactory, IRuleDataClient } from '../../rule_registry/server'; import { UMServerLibs } from './lib/lib'; import { createRouteWithAuth, restApiRoutes, uptimeRouteWrapper } from './rest_api'; -import { UptimeCoreSetup, UptimeCorePlugins } from './lib/adapters'; +import { UptimeCoreSetup, UptimeCorePluginsSetup } from './lib/adapters'; import { statusCheckAlertFactory } from './lib/alerts/status_check'; import { tlsAlertFactory } from './lib/alerts/tls'; @@ -19,12 +19,12 @@ import { durationAnomalyAlertFactory } from './lib/alerts/duration_anomaly'; export const initUptimeServer = ( server: UptimeCoreSetup, libs: UMServerLibs, - plugins: UptimeCorePlugins, + plugins: UptimeCorePluginsSetup, ruleDataClient: IRuleDataClient, logger: Logger ) => { restApiRoutes.forEach((route) => - libs.framework.registerRoute(uptimeRouteWrapper(createRouteWithAuth(libs, route))) + libs.framework.registerRoute(uptimeRouteWrapper(createRouteWithAuth(libs, route), server)) ); const { From a66551e81b730487d8f1140891a79b0733763b73 Mon Sep 17 00:00:00 2001 From: Julia Bardi <90178898+juliaElastic@users.noreply.github.com> Date: Thu, 25 Nov 2021 14:27:56 +0100 Subject: [PATCH 28/46] [Fleet] updated agent standalone instructions (#119629) * updated agent standalone instructions * updated for kubernetes * updated public api md * fix import * fixed doc link * removed unused translations Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- ...-plugin-core-public.doclinksstart.links.md | 1 + ...kibana-plugin-core-public.doclinksstart.md | 2 +- .../public/doc_links/doc_links_service.ts | 2 + src/core/public/public.api.md | 1 + x-pack/plugins/fleet/common/constants/epm.ts | 3 +- .../standalone_instructions.tsx | 50 +++----- .../enrollment_instructions/manual/index.tsx | 88 ++----------- .../manual/platform_selector.tsx | 119 ++++++++++++++++++ .../translations/translations/ja-JP.json | 2 - .../translations/translations/zh-CN.json | 2 - 10 files changed, 151 insertions(+), 119 deletions(-) create mode 100644 x-pack/plugins/fleet/public/components/enrollment_instructions/manual/platform_selector.tsx diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md index 33f5775a429be..5c2c1d5317543 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.links.md @@ -252,6 +252,7 @@ readonly links: { datastreams: string; datastreamsNamingScheme: string; installElasticAgent: string; + installElasticAgentStandalone: string; upgradeElasticAgent: string; upgradeElasticAgent712lower: string; learnMoreBlog: string; diff --git a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md index 5a6c7131768bf..cbfe53d3eaea0 100644 --- a/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md +++ b/docs/development/core/public/kibana-plugin-core-public.doclinksstart.md @@ -17,5 +17,5 @@ export interface DocLinksStart | --- | --- | --- | | [DOC\_LINK\_VERSION](./kibana-plugin-core-public.doclinksstart.doc_link_version.md) | string | | | [ELASTIC\_WEBSITE\_URL](./kibana-plugin-core-public.doclinksstart.elastic_website_url.md) | string | | -| [links](./kibana-plugin-core-public.doclinksstart.links.md) | { readonly settings: string; readonly elasticStackGetStarted: string; readonly upgrade: { readonly upgradingElasticStack: string; }; readonly apm: { readonly kibanaSettings: string; readonly supportedServiceMaps: string; readonly customLinks: string; readonly droppedTransactionSpans: string; readonly upgrading: string; readonly metaData: string; }; readonly canvas: { readonly guide: string; }; readonly dashboard: { readonly guide: string; readonly drilldowns: string; readonly drilldownsTriggerPicker: string; readonly urlDrilldownTemplateSyntax: string; readonly urlDrilldownVariables: string; }; readonly discover: Record<string, string>; readonly filebeat: { readonly base: string; readonly installation: string; readonly configuration: string; readonly elasticsearchOutput: string; readonly elasticsearchModule: string; readonly startup: string; readonly exportedFields: string; readonly suricataModule: string; readonly zeekModule: string; }; readonly auditbeat: { readonly base: string; readonly auditdModule: string; readonly systemModule: string; }; readonly metricbeat: { readonly base: string; readonly configure: string; readonly httpEndpoint: string; readonly install: string; readonly start: string; }; readonly enterpriseSearch: { readonly base: string; readonly appSearchBase: string; readonly workplaceSearchBase: string; }; readonly heartbeat: { readonly base: string; }; readonly libbeat: { readonly getStarted: string; }; readonly logstash: { readonly base: string; }; readonly functionbeat: { readonly base: string; }; readonly winlogbeat: { readonly base: string; }; readonly aggs: { readonly composite: string; readonly composite\_missing\_bucket: string; readonly date\_histogram: string; readonly date\_range: string; readonly date\_format\_pattern: string; readonly filter: string; readonly filters: string; readonly geohash\_grid: string; readonly histogram: string; readonly ip\_range: string; readonly range: string; readonly significant\_terms: string; readonly terms: string; readonly terms\_doc\_count\_error: string; readonly avg: string; readonly avg\_bucket: string; readonly max\_bucket: string; readonly min\_bucket: string; readonly sum\_bucket: string; readonly cardinality: string; readonly count: string; readonly cumulative\_sum: string; readonly derivative: string; readonly geo\_bounds: string; readonly geo\_centroid: string; readonly max: string; readonly median: string; readonly min: string; readonly moving\_avg: string; readonly percentile\_ranks: string; readonly serial\_diff: string; readonly std\_dev: string; readonly sum: string; readonly top\_hits: string; }; readonly runtimeFields: { readonly overview: string; readonly mapping: string; }; readonly scriptedFields: { readonly scriptFields: string; readonly scriptAggs: string; readonly painless: string; readonly painlessApi: string; readonly painlessLangSpec: string; readonly painlessSyntax: string; readonly painlessWalkthrough: string; readonly luceneExpressions: string; }; readonly search: { readonly sessions: string; readonly sessionLimits: string; }; readonly indexPatterns: { readonly introduction: string; readonly fieldFormattersNumber: string; readonly fieldFormattersString: string; readonly runtimeFields: string; }; readonly addData: string; readonly kibana: string; readonly upgradeAssistant: { readonly overview: string; readonly batchReindex: string; readonly remoteReindex: string; }; readonly rollupJobs: string; readonly elasticsearch: Record<string, string>; readonly siem: { readonly privileges: string; readonly guide: string; readonly gettingStarted: string; readonly ml: string; readonly ruleChangeLog: string; readonly detectionsReq: string; readonly networkMap: string; readonly troubleshootGaps: string; }; readonly securitySolution: { readonly trustedApps: string; }; readonly query: { readonly eql: string; readonly kueryQuerySyntax: string; readonly luceneQuerySyntax: string; readonly percolate: string; readonly queryDsl: string; }; readonly date: { readonly dateMath: string; readonly dateMathIndexNames: string; }; readonly management: Record<string, string>; readonly ml: Record<string, string>; readonly transforms: Record<string, string>; readonly visualize: Record<string, string>; readonly apis: Readonly<{ bulkIndexAlias: string; byteSizeUnits: string; createAutoFollowPattern: string; createFollower: string; createIndex: string; createSnapshotLifecyclePolicy: string; createRoleMapping: string; createRoleMappingTemplates: string; createRollupJobsRequest: string; createApiKey: string; createPipeline: string; createTransformRequest: string; cronExpressions: string; executeWatchActionModes: string; indexExists: string; openIndex: string; putComponentTemplate: string; painlessExecute: string; painlessExecuteAPIContexts: string; putComponentTemplateMetadata: string; putSnapshotLifecyclePolicy: string; putIndexTemplateV1: string; putWatch: string; simulatePipeline: string; timeUnits: string; updateTransform: string; }>; readonly observability: Readonly<{ guide: string; infrastructureThreshold: string; logsThreshold: string; metricsThreshold: string; monitorStatus: string; monitorUptime: string; tlsCertificate: string; uptimeDurationAnomaly: string; }>; readonly alerting: Record<string, string>; readonly maps: Readonly<{ guide: string; importGeospatialPrivileges: string; gdalTutorial: string; }>; readonly monitoring: Record<string, string>; readonly security: Readonly<{ apiKeyServiceSettings: string; clusterPrivileges: string; elasticsearchSettings: string; elasticsearchEnableSecurity: string; elasticsearchEnableApiKeys: string; indicesPrivileges: string; kibanaTLS: string; kibanaPrivileges: string; mappingRoles: string; mappingRolesFieldRules: string; runAsPrivilege: string; }>; readonly spaces: Readonly<{ kibanaLegacyUrlAliases: string; kibanaDisableLegacyUrlAliasesApi: string; }>; readonly watcher: Record<string, string>; readonly ccs: Record<string, string>; readonly plugins: Record<string, string>; readonly snapshotRestore: Record<string, string>; readonly ingest: Record<string, string>; readonly fleet: Readonly<{ beatsAgentComparison: string; guide: string; fleetServer: string; fleetServerAddFleetServer: string; settings: string; settingsFleetServerHostSettings: string; settingsFleetServerProxySettings: string; troubleshooting: string; elasticAgent: string; datastreams: string; datastreamsNamingScheme: string; installElasticAgent: string; upgradeElasticAgent: string; upgradeElasticAgent712lower: string; learnMoreBlog: string; apiKeysLearnMore: string; onPremRegistry: string; }>; readonly ecs: { readonly guide: string; }; readonly clients: { readonly guide: string; readonly goOverview: string; readonly javaIndex: string; readonly jsIntro: string; readonly netGuide: string; readonly perlGuide: string; readonly phpGuide: string; readonly pythonGuide: string; readonly rubyOverview: string; readonly rustGuide: string; }; readonly endpoints: { readonly troubleshooting: string; }; } | | +| [links](./kibana-plugin-core-public.doclinksstart.links.md) | { readonly settings: string; readonly elasticStackGetStarted: string; readonly upgrade: { readonly upgradingElasticStack: string; }; readonly apm: { readonly kibanaSettings: string; readonly supportedServiceMaps: string; readonly customLinks: string; readonly droppedTransactionSpans: string; readonly upgrading: string; readonly metaData: string; }; readonly canvas: { readonly guide: string; }; readonly dashboard: { readonly guide: string; readonly drilldowns: string; readonly drilldownsTriggerPicker: string; readonly urlDrilldownTemplateSyntax: string; readonly urlDrilldownVariables: string; }; readonly discover: Record<string, string>; readonly filebeat: { readonly base: string; readonly installation: string; readonly configuration: string; readonly elasticsearchOutput: string; readonly elasticsearchModule: string; readonly startup: string; readonly exportedFields: string; readonly suricataModule: string; readonly zeekModule: string; }; readonly auditbeat: { readonly base: string; readonly auditdModule: string; readonly systemModule: string; }; readonly metricbeat: { readonly base: string; readonly configure: string; readonly httpEndpoint: string; readonly install: string; readonly start: string; }; readonly enterpriseSearch: { readonly base: string; readonly appSearchBase: string; readonly workplaceSearchBase: string; }; readonly heartbeat: { readonly base: string; }; readonly libbeat: { readonly getStarted: string; }; readonly logstash: { readonly base: string; }; readonly functionbeat: { readonly base: string; }; readonly winlogbeat: { readonly base: string; }; readonly aggs: { readonly composite: string; readonly composite\_missing\_bucket: string; readonly date\_histogram: string; readonly date\_range: string; readonly date\_format\_pattern: string; readonly filter: string; readonly filters: string; readonly geohash\_grid: string; readonly histogram: string; readonly ip\_range: string; readonly range: string; readonly significant\_terms: string; readonly terms: string; readonly terms\_doc\_count\_error: string; readonly avg: string; readonly avg\_bucket: string; readonly max\_bucket: string; readonly min\_bucket: string; readonly sum\_bucket: string; readonly cardinality: string; readonly count: string; readonly cumulative\_sum: string; readonly derivative: string; readonly geo\_bounds: string; readonly geo\_centroid: string; readonly max: string; readonly median: string; readonly min: string; readonly moving\_avg: string; readonly percentile\_ranks: string; readonly serial\_diff: string; readonly std\_dev: string; readonly sum: string; readonly top\_hits: string; }; readonly runtimeFields: { readonly overview: string; readonly mapping: string; }; readonly scriptedFields: { readonly scriptFields: string; readonly scriptAggs: string; readonly painless: string; readonly painlessApi: string; readonly painlessLangSpec: string; readonly painlessSyntax: string; readonly painlessWalkthrough: string; readonly luceneExpressions: string; }; readonly search: { readonly sessions: string; readonly sessionLimits: string; }; readonly indexPatterns: { readonly introduction: string; readonly fieldFormattersNumber: string; readonly fieldFormattersString: string; readonly runtimeFields: string; }; readonly addData: string; readonly kibana: string; readonly upgradeAssistant: { readonly overview: string; readonly batchReindex: string; readonly remoteReindex: string; }; readonly rollupJobs: string; readonly elasticsearch: Record<string, string>; readonly siem: { readonly privileges: string; readonly guide: string; readonly gettingStarted: string; readonly ml: string; readonly ruleChangeLog: string; readonly detectionsReq: string; readonly networkMap: string; readonly troubleshootGaps: string; }; readonly securitySolution: { readonly trustedApps: string; }; readonly query: { readonly eql: string; readonly kueryQuerySyntax: string; readonly luceneQuerySyntax: string; readonly percolate: string; readonly queryDsl: string; }; readonly date: { readonly dateMath: string; readonly dateMathIndexNames: string; }; readonly management: Record<string, string>; readonly ml: Record<string, string>; readonly transforms: Record<string, string>; readonly visualize: Record<string, string>; readonly apis: Readonly<{ bulkIndexAlias: string; byteSizeUnits: string; createAutoFollowPattern: string; createFollower: string; createIndex: string; createSnapshotLifecyclePolicy: string; createRoleMapping: string; createRoleMappingTemplates: string; createRollupJobsRequest: string; createApiKey: string; createPipeline: string; createTransformRequest: string; cronExpressions: string; executeWatchActionModes: string; indexExists: string; openIndex: string; putComponentTemplate: string; painlessExecute: string; painlessExecuteAPIContexts: string; putComponentTemplateMetadata: string; putSnapshotLifecyclePolicy: string; putIndexTemplateV1: string; putWatch: string; simulatePipeline: string; timeUnits: string; updateTransform: string; }>; readonly observability: Readonly<{ guide: string; infrastructureThreshold: string; logsThreshold: string; metricsThreshold: string; monitorStatus: string; monitorUptime: string; tlsCertificate: string; uptimeDurationAnomaly: string; }>; readonly alerting: Record<string, string>; readonly maps: Readonly<{ guide: string; importGeospatialPrivileges: string; gdalTutorial: string; }>; readonly monitoring: Record<string, string>; readonly security: Readonly<{ apiKeyServiceSettings: string; clusterPrivileges: string; elasticsearchSettings: string; elasticsearchEnableSecurity: string; elasticsearchEnableApiKeys: string; indicesPrivileges: string; kibanaTLS: string; kibanaPrivileges: string; mappingRoles: string; mappingRolesFieldRules: string; runAsPrivilege: string; }>; readonly spaces: Readonly<{ kibanaLegacyUrlAliases: string; kibanaDisableLegacyUrlAliasesApi: string; }>; readonly watcher: Record<string, string>; readonly ccs: Record<string, string>; readonly plugins: Record<string, string>; readonly snapshotRestore: Record<string, string>; readonly ingest: Record<string, string>; readonly fleet: Readonly<{ beatsAgentComparison: string; guide: string; fleetServer: string; fleetServerAddFleetServer: string; settings: string; settingsFleetServerHostSettings: string; settingsFleetServerProxySettings: string; troubleshooting: string; elasticAgent: string; datastreams: string; datastreamsNamingScheme: string; installElasticAgent: string; installElasticAgentStandalone: string; upgradeElasticAgent: string; upgradeElasticAgent712lower: string; learnMoreBlog: string; apiKeysLearnMore: string; onPremRegistry: string; }>; readonly ecs: { readonly guide: string; }; readonly clients: { readonly guide: string; readonly goOverview: string; readonly javaIndex: string; readonly jsIntro: string; readonly netGuide: string; readonly perlGuide: string; readonly phpGuide: string; readonly pythonGuide: string; readonly rubyOverview: string; readonly rustGuide: string; }; readonly endpoints: { readonly troubleshooting: string; }; } | | diff --git a/src/core/public/doc_links/doc_links_service.ts b/src/core/public/doc_links/doc_links_service.ts index ec7802b68e7c5..92b4c815f2249 100644 --- a/src/core/public/doc_links/doc_links_service.ts +++ b/src/core/public/doc_links/doc_links_service.ts @@ -498,6 +498,7 @@ export class DocLinksService { datastreams: `${FLEET_DOCS}data-streams.html`, datastreamsNamingScheme: `${FLEET_DOCS}data-streams.html#data-streams-naming-scheme`, installElasticAgent: `${FLEET_DOCS}install-fleet-managed-elastic-agent.html`, + installElasticAgentStandalone: `${FLEET_DOCS}install-standalone-elastic-agent.html`, upgradeElasticAgent: `${FLEET_DOCS}upgrade-elastic-agent.html`, upgradeElasticAgent712lower: `${FLEET_DOCS}upgrade-elastic-agent.html#upgrade-7.12-lower`, learnMoreBlog: `${ELASTIC_WEBSITE_URL}blog/elastic-agent-and-fleet-make-it-easier-to-integrate-your-systems-with-elastic`, @@ -777,6 +778,7 @@ export interface DocLinksStart { datastreams: string; datastreamsNamingScheme: string; installElasticAgent: string; + installElasticAgentStandalone: string; upgradeElasticAgent: string; upgradeElasticAgent712lower: string; learnMoreBlog: string; diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index 5dcd3422d5d86..772faa5321d98 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -734,6 +734,7 @@ export interface DocLinksStart { datastreams: string; datastreamsNamingScheme: string; installElasticAgent: string; + installElasticAgentStandalone: string; upgradeElasticAgent: string; upgradeElasticAgent712lower: string; learnMoreBlog: string; diff --git a/x-pack/plugins/fleet/common/constants/epm.ts b/x-pack/plugins/fleet/common/constants/epm.ts index 5137e422e0975..97672f4d4d657 100644 --- a/x-pack/plugins/fleet/common/constants/epm.ts +++ b/x-pack/plugins/fleet/common/constants/epm.ts @@ -18,7 +18,8 @@ export const FLEET_SYNTHETICS_PACKAGE = 'synthetics'; export const FLEET_KUBERNETES_PACKAGE = 'kubernetes'; export const KUBERNETES_RUN_INSTRUCTIONS = 'kubectl apply -f elastic-agent-standalone-kubernetes.yaml'; -export const STANDALONE_RUN_INSTRUCTIONS = './elastic-agent install'; +export const STANDALONE_RUN_INSTRUCTIONS_LINUXMAC = 'sudo ./elastic-agent install'; +export const STANDALONE_RUN_INSTRUCTIONS_WINDOWS = '.\\elastic-agent.exe install'; /* Package rules: diff --git a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/standalone_instructions.tsx b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/standalone_instructions.tsx index f1ab855059c3c..4e5f17509fb2d 100644 --- a/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/standalone_instructions.tsx +++ b/x-pack/plugins/fleet/public/components/agent_enrollment_flyout/standalone_instructions.tsx @@ -36,9 +36,12 @@ import type { PackagePolicy } from '../../../common'; import { FLEET_KUBERNETES_PACKAGE, KUBERNETES_RUN_INSTRUCTIONS, - STANDALONE_RUN_INSTRUCTIONS, + STANDALONE_RUN_INSTRUCTIONS_LINUXMAC, + STANDALONE_RUN_INSTRUCTIONS_WINDOWS, } from '../../../common'; +import { PlatformSelector } from '../enrollment_instructions/manual/platform_selector'; + import { DownloadStep, AgentPolicySelectionStep } from './steps'; import type { BaseProps } from './types'; @@ -55,8 +58,11 @@ export const StandaloneInstructions = React.memo(({ agentPolicy, agentPol 'IS_LOADING' ); const [yaml, setYaml] = useState(''); - const runInstructions = - isK8s === 'IS_KUBERNETES' ? KUBERNETES_RUN_INSTRUCTIONS : STANDALONE_RUN_INSTRUCTIONS; + const linuxMacCommand = + isK8s === 'IS_KUBERNETES' ? KUBERNETES_RUN_INSTRUCTIONS : STANDALONE_RUN_INSTRUCTIONS_LINUXMAC; + const windowsCommand = + isK8s === 'IS_KUBERNETES' ? KUBERNETES_RUN_INSTRUCTIONS : STANDALONE_RUN_INSTRUCTIONS_WINDOWS; + const { docLinks } = useStartServices(); useEffect(() => { async function checkifK8s() { @@ -172,19 +178,6 @@ export const StandaloneInstructions = React.memo(({ agentPolicy, agentPol /> ); - const applyMsg = - isK8s === 'IS_KUBERNETES' ? ( - - ) : ( - - ); - const steps = [ !agentPolicy ? AgentPolicySelectionStep({ agentPolicies, setSelectedPolicyId, excludeFleetServer: true }) @@ -231,24 +224,13 @@ export const StandaloneInstructions = React.memo(({ agentPolicy, agentPol defaultMessage: 'Start the agent', }), children: ( - <> - - <>{applyMsg} - - {runInstructions} - - - {(copy) => ( - - - - )} - - - + ), }, { diff --git a/x-pack/plugins/fleet/public/components/enrollment_instructions/manual/index.tsx b/x-pack/plugins/fleet/public/components/enrollment_instructions/manual/index.tsx index 574a04dfd54df..32846620221ae 100644 --- a/x-pack/plugins/fleet/public/components/enrollment_instructions/manual/index.tsx +++ b/x-pack/plugins/fleet/public/components/enrollment_instructions/manual/index.tsx @@ -6,25 +6,15 @@ */ import React from 'react'; -import styled from 'styled-components'; -import { EuiText, EuiSpacer, EuiLink, EuiCodeBlock, EuiButtonGroup } from '@elastic/eui'; -import { FormattedMessage } from '@kbn/i18n-react'; -import { i18n } from '@kbn/i18n'; - +import { useStartServices } from '../../../hooks'; import type { EnrollmentAPIKey } from '../../../types'; -import { PLATFORM_OPTIONS, usePlatform, useStartServices } from '../../../hooks'; -import type { PLATFORM_TYPE } from '../../../hooks'; +import { PlatformSelector } from './platform_selector'; interface Props { fleetServerHosts: string[]; apiKey: EnrollmentAPIKey; } -// Otherwise the copy button is over the text -const CommandCode = styled.pre({ - overflow: 'scroll', -}); - function getfleetServerHostsEnrollArgs(apiKey: EnrollmentAPIKey, fleetServerHosts: string[]) { return `--url=${fleetServerHosts[0]} --enrollment-token=${apiKey.api_key}`; } @@ -33,9 +23,7 @@ export const ManualInstructions: React.FunctionComponent = ({ apiKey, fleetServerHosts, }) => { - const { platform, setPlatform } = usePlatform(); const { docLinks } = useStartServices(); - const enrollArgs = getfleetServerHostsEnrollArgs(apiKey, fleetServerHosts); const linuxMacCommand = `sudo ./elastic-agent install ${enrollArgs}`; @@ -43,70 +31,12 @@ export const ManualInstructions: React.FunctionComponent = ({ const windowsCommand = `.\\elastic-agent.exe install ${enrollArgs}`; return ( - <> - - - - - setPlatform(id as PLATFORM_TYPE)} - legend={i18n.translate('xpack.fleet.enrollmentInstructions.platformSelectAriaLabel', { - defaultMessage: 'Platform', - })} - /> - - {platform === 'linux-mac' && ( - - {linuxMacCommand} - - )} - {platform === 'windows' && ( - - {windowsCommand} - - )} - - {platform === 'rpm-deb' && ( - - - - - ), - }} - /> - - )} - - - - - - - ), - }} - /> - - + ); }; diff --git a/x-pack/plugins/fleet/public/components/enrollment_instructions/manual/platform_selector.tsx b/x-pack/plugins/fleet/public/components/enrollment_instructions/manual/platform_selector.tsx new file mode 100644 index 0000000000000..315c5b78bb3ed --- /dev/null +++ b/x-pack/plugins/fleet/public/components/enrollment_instructions/manual/platform_selector.tsx @@ -0,0 +1,119 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; +import styled from 'styled-components'; +import { EuiText, EuiSpacer, EuiLink, EuiCodeBlock, EuiButtonGroup } from '@elastic/eui'; +import { FormattedMessage } from '@kbn/i18n-react'; +import { i18n } from '@kbn/i18n'; + +import type { PLATFORM_TYPE } from '../../../hooks'; +import { PLATFORM_OPTIONS, usePlatform } from '../../../hooks'; + +interface Props { + linuxMacCommand: string; + windowsCommand: string; + installAgentLink: string; + troubleshootLink: string; + isK8s: boolean; +} + +// Otherwise the copy button is over the text +const CommandCode = styled.pre({ + overflow: 'auto', +}); + +export const PlatformSelector: React.FunctionComponent = ({ + linuxMacCommand, + windowsCommand, + installAgentLink, + troubleshootLink, + isK8s, +}) => { + const { platform, setPlatform } = usePlatform(); + + return ( + <> + + {isK8s ? ( + + ) : ( + + )} + + + {isK8s ? ( + + {linuxMacCommand} + + ) : ( + <> + setPlatform(id as PLATFORM_TYPE)} + legend={i18n.translate('xpack.fleet.enrollmentInstructions.platformSelectAriaLabel', { + defaultMessage: 'Platform', + })} + /> + + {platform === 'linux-mac' && ( + + {linuxMacCommand} + + )} + {platform === 'windows' && ( + + {windowsCommand} + + )} + {platform === 'rpm-deb' && ( + + + + + ), + }} + /> + + )} + + )} + + + + + + ), + }} + /> + + + ); +}; diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 229a61d88e590..b983eaaeaae47 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -10087,7 +10087,6 @@ "xpack.fleet.agentEnrollment.agentsNotInitializedText": "エージェントを登録する前に、{link}。", "xpack.fleet.agentEnrollment.closeFlyoutButtonLabel": "閉じる", "xpack.fleet.agentEnrollment.copyPolicyButton": "クリップボードにコピー", - "xpack.fleet.agentEnrollment.copyRunInstructionsButton": "クリップボードにコピー", "xpack.fleet.agentEnrollment.downloadDescription": "FleetサーバーはElasticエージェントで実行されます。Elasticエージェントダウンロードページでは、Elasticエージェントバイナリと検証署名をダウンロードできます。", "xpack.fleet.agentEnrollment.downloadLink": "ダウンロードページに移動", "xpack.fleet.agentEnrollment.downloadPolicyButton": "ポリシーのダウンロード", @@ -10375,7 +10374,6 @@ "xpack.fleet.editPackagePolicy.upgradePageTitleWithPackageName": "{packageName}統合をアップグレード", "xpack.fleet.enrollemntAPIKeyList.emptyMessage": "登録トークンが見つかりません。", "xpack.fleet.enrollemntAPIKeyList.loadingTokensMessage": "登録トークンを読み込んでいます...", - "xpack.fleet.enrollmentInstructions.descriptionText": "エージェントのディレクトリから、該当するコマンドを実行し、Elasticエージェントをインストール、登録、起動します。これらのコマンドを再利用すると、複数のホストでエージェントを設定できます。管理者権限が必要です。", "xpack.fleet.enrollmentInstructions.moreInstructionsLink": "Elastic エージェントドキュメント", "xpack.fleet.enrollmentInstructions.moreInstructionsText": "RPM/DEB デプロイの手順については、{link}を参照してください。", "xpack.fleet.enrollmentInstructions.platformButtons.linux": "Linux / macOS", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index b17c984ac2474..8b0686d0a309f 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -10178,7 +10178,6 @@ "xpack.fleet.agentEnrollment.agentsNotInitializedText": "注册代理前,请{link}。", "xpack.fleet.agentEnrollment.closeFlyoutButtonLabel": "关闭", "xpack.fleet.agentEnrollment.copyPolicyButton": "复制到剪贴板", - "xpack.fleet.agentEnrollment.copyRunInstructionsButton": "复制到剪贴板", "xpack.fleet.agentEnrollment.downloadDescription": "Fleet 服务器运行在 Elastic 代理上。可从 Elastic 的下载页面下载 Elastic 代理二进制文件及验证签名。", "xpack.fleet.agentEnrollment.downloadLink": "前往下载页面", "xpack.fleet.agentEnrollment.downloadPolicyButton": "下载策略", @@ -10476,7 +10475,6 @@ "xpack.fleet.editPackagePolicy.upgradePageTitleWithPackageName": "升级 {packageName} 集成", "xpack.fleet.enrollemntAPIKeyList.emptyMessage": "未找到任何注册令牌。", "xpack.fleet.enrollemntAPIKeyList.loadingTokensMessage": "正在加载注册令牌......", - "xpack.fleet.enrollmentInstructions.descriptionText": "从代理目录运行相应命令,以安装、注册并启动 Elastic 代理。您可以重复使用这些命令在多个主机上设置代理。需要管理员权限。", "xpack.fleet.enrollmentInstructions.moreInstructionsLink": "Elastic 代理文档", "xpack.fleet.enrollmentInstructions.moreInstructionsText": "有关 RPM/DEB 部署说明,请参见 {link}。", "xpack.fleet.enrollmentInstructions.platformButtons.linux": "Linux/macOS", From 283005631f14148df087570121661ca834e7b636 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Thu, 25 Nov 2021 13:34:59 +0000 Subject: [PATCH 29/46] [ML] Fix data view service permissions (#119712) --- x-pack/plugins/ml/server/lib/data_views_utils.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/ml/server/lib/data_views_utils.ts b/x-pack/plugins/ml/server/lib/data_views_utils.ts index 497404425eff8..b76765c85d886 100644 --- a/x-pack/plugins/ml/server/lib/data_views_utils.ts +++ b/x-pack/plugins/ml/server/lib/data_views_utils.ts @@ -22,5 +22,5 @@ export function getDataViewsServiceFactory( throw Error('data views service has not been initialized'); } - return () => dataViews.dataViewsServiceFactory(savedObjectClient, scopedClient.asInternalUser); + return () => dataViews.dataViewsServiceFactory(savedObjectClient, scopedClient.asCurrentUser); } From 6d6aec0941c88a0bc77b51d97f77ed641ace16ec Mon Sep 17 00:00:00 2001 From: Robert Oskamp Date: Thu, 25 Nov 2021 17:24:58 +0100 Subject: [PATCH 30/46] [ML] Functional tests - stabilize and re-enable index data visualizer tests (#119720) This PR stabilizes and re-enabled the index data visualizer tests by waiting for global loading to finish before validating row content. --- .../apps/ml/data_visualizer/index_data_visualizer.ts | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts index 55a11e6ec2d20..756b43fdad604 100644 --- a/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts +++ b/x-pack/test/functional/apps/ml/data_visualizer/index_data_visualizer.ts @@ -15,7 +15,8 @@ import { sampleLogTestData, } from './index_test_data'; -export default function ({ getService }: FtrProviderContext) { +export default function ({ getPageObject, getService }: FtrProviderContext) { + const headerPage = getPageObject('header'); const esArchiver = getService('esArchiver'); const ml = getService('ml'); @@ -42,6 +43,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.dataVisualizerIndexBased.clickUseFullDataButton( testData.expected.totalDocCountFormatted ); + await headerPage.waitUntilLoadingHasFinished(); await ml.testExecution.logTestStep( `${testData.suiteTitle} displays elements in the doc count panel correctly` @@ -166,8 +168,7 @@ export default function ({ getService }: FtrProviderContext) { await ml.securityUI.loginAsMlPowerUser(); }); - // FLAKY: https://github.com/elastic/kibana/issues/118472 - describe.skip('with farequote', function () { + describe('with farequote', function () { // Run tests on full farequote index. it(`${farequoteDataViewTestData.suiteTitle} loads the data visualizer selector page`, async () => { // Start navigation from the base of the ML app. From 0b52f05d47da0aeb6e9266f526c4f0d6f9c8dfb0 Mon Sep 17 00:00:00 2001 From: Shahzad Date: Thu, 25 Nov 2021 17:29:38 +0100 Subject: [PATCH 31/46] [Uptime] Determine es hosts from synthetics service (#119708) --- x-pack/plugins/uptime/kibana.json | 5 +- .../lib/adapters/framework/adapter_types.ts | 3 + .../synthetics_service/get_es_hosts.test.ts | 65 +++++++++++++++++++ .../lib/synthetics_service/get_es_hosts.ts | 40 ++++++++++++ x-pack/plugins/uptime/server/plugin.ts | 6 +- 5 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 x-pack/plugins/uptime/server/lib/synthetics_service/get_es_hosts.test.ts create mode 100644 x-pack/plugins/uptime/server/lib/synthetics_service/get_es_hosts.ts diff --git a/x-pack/plugins/uptime/kibana.json b/x-pack/plugins/uptime/kibana.json index 18865735f3ebc..803d1d82d933a 100644 --- a/x-pack/plugins/uptime/kibana.json +++ b/x-pack/plugins/uptime/kibana.json @@ -6,10 +6,11 @@ "id": "uptime", "kibanaVersion": "kibana", "optionalPlugins": [ + "cloud", "data", + "fleet", "home", - "ml", - "fleet" + "ml" ], "requiredPlugins": [ "alerting", diff --git a/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts index bafaf60770dcd..bb8e413b75880 100644 --- a/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts @@ -23,6 +23,7 @@ import { RuleRegistryPluginSetupContract } from '../../../../../rule_registry/se import { UptimeESClient } from '../../lib'; import type { UptimeRouter } from '../../../types'; import { SecurityPluginStart } from '../../../../../security/server'; +import { CloudSetup } from '../../../../../cloud/server'; import { UptimeConfig } from '../../../../common/config'; export type UMElasticsearchQueryFn = ( @@ -40,6 +41,7 @@ export type UMSavedObjectsQueryFn = ( export interface UptimeCoreSetup { router: UptimeRouter; config: UptimeConfig; + cloud: CloudSetup; security: SecurityPluginStart; encryptedSavedObjects: EncryptedSavedObjectsPluginStart; } @@ -50,6 +52,7 @@ export interface UptimeCorePluginsSetup { observability: ObservabilityPluginSetup; usageCollection: UsageCollectionSetup; ml: MlSetup; + cloud?: CloudSetup; ruleRegistry: RuleRegistryPluginSetupContract; encryptedSavedObjects: EncryptedSavedObjectsPluginSetup; } diff --git a/x-pack/plugins/uptime/server/lib/synthetics_service/get_es_hosts.test.ts b/x-pack/plugins/uptime/server/lib/synthetics_service/get_es_hosts.test.ts new file mode 100644 index 0000000000000..f028d5e154a56 --- /dev/null +++ b/x-pack/plugins/uptime/server/lib/synthetics_service/get_es_hosts.test.ts @@ -0,0 +1,65 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { getEsHosts } from './get_es_hosts'; +import { CloudSetup } from '../../../../cloud/server'; + +describe('getEsHostsTest', () => { + const cloudSetup = { + cloudId: + 'TLS_Test:dXMtY2VudHJhbDEuZ2NwLmNsb3VkLmVzLmlvJDI0ZDYwY2NjYmZjODRhZmZhNGRjYTQ3M2M2YjFlZDgwJGUxMjkyY2YzMTczZTRkNTViZDViM2NlNzYyZDg1NzY3', + isCloudEnabled: true, + } as CloudSetup; + + it('should return expected host in cloud', function () { + const esHosts = getEsHosts({ + cloud: cloudSetup, + config: {}, + }); + + expect(esHosts).toEqual([ + 'https://24d60cccbfc84affa4dca473c6b1ed80.us-central1.gcp.cloud.es.io:443', + ]); + }); + + it('should return expected host from config', function () { + const esHosts = getEsHosts({ + config: { + unsafe: { + service: { + hosts: ['http://localhost:9200'], + }, + }, + }, + }); + + expect(esHosts).toEqual(['http://localhost:9200']); + }); + it('should return cloud hosts when both config and cloud are present', function () { + const esHosts = getEsHosts({ + cloud: cloudSetup, + config: { + unsafe: { + service: { + hosts: ['http://localhost:9200'], + }, + }, + }, + }); + + expect(esHosts).toEqual([ + 'https://24d60cccbfc84affa4dca473c6b1ed80.us-central1.gcp.cloud.es.io:443', + ]); + }); +}); diff --git a/x-pack/plugins/uptime/server/lib/synthetics_service/get_es_hosts.ts b/x-pack/plugins/uptime/server/lib/synthetics_service/get_es_hosts.ts new file mode 100644 index 0000000000000..d0de73b73e23e --- /dev/null +++ b/x-pack/plugins/uptime/server/lib/synthetics_service/get_es_hosts.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { CloudSetup } from '../../../../cloud/server'; +import { decodeCloudId } from '../../../../fleet/common'; +import { UptimeConfig } from '../../../common/config'; + +export function getEsHosts({ + cloud, + config, +}: { + cloud?: CloudSetup; + config: UptimeConfig; +}): string[] { + const cloudId = cloud?.isCloudEnabled && cloud.cloudId; + const cloudUrl = cloudId && decodeCloudId(cloudId)?.elasticsearchUrl; + const cloudHosts = cloudUrl ? [cloudUrl] : undefined; + if (cloudHosts && cloudHosts.length > 0) { + return cloudHosts; + } + + const flagHosts = config?.unsafe?.service?.hosts; + + if (flagHosts && flagHosts.length > 0) { + return flagHosts; + } + + return []; +} diff --git a/x-pack/plugins/uptime/server/plugin.ts b/x-pack/plugins/uptime/server/plugin.ts index aa962605ef2b8..a94f9650e32cc 100644 --- a/x-pack/plugins/uptime/server/plugin.ts +++ b/x-pack/plugins/uptime/server/plugin.ts @@ -59,7 +59,11 @@ export class Plugin implements PluginType { ], }); - this.server = { router: core.http.createRouter(), config } as UptimeCoreSetup; + this.server = { + router: core.http.createRouter(), + config, + cloud: plugins.cloud, + } as UptimeCoreSetup; initServerWithKibana(this.server, plugins, ruleDataClient, this.logger); From e2a673faa3400193b6295de829749c140ea3ca05 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Thu, 25 Nov 2021 17:15:57 +0000 Subject: [PATCH 32/46] [ML] Disabling delete data view for data frame analytics and transforms wizards (#119732) * [ML] Disabling delete data view for data frame analytics and transforms wizards * bulk transforms * unused variable --- .../components/action_delete/delete_action_modal.tsx | 2 ++ .../components/action_delete/use_delete_action.tsx | 11 +++++++++++ .../public/app/hooks/use_delete_transform.tsx | 12 +++++++++++- .../components/action_delete/delete_action_modal.tsx | 3 +++ .../components/action_delete/use_delete_action.tsx | 4 +++- 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_modal.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_modal.tsx index 6767ee439ca61..3d22ed72487f5 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_modal.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/delete_action_modal.tsx @@ -28,6 +28,7 @@ export const DeleteActionModal: FC = ({ toggleDeleteIndex, toggleDeleteIndexPattern, userCanDeleteIndex, + userCanDeleteDataView, }) => { if (item === undefined) { return null; @@ -85,6 +86,7 @@ export const DeleteActionModal: FC = ({ })} checked={deleteIndexPattern} onChange={toggleDeleteIndexPattern} + disabled={userCanDeleteDataView === false} /> )} diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx index bed9a2bbc018a..64d91b9897314 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_management/components/action_delete/use_delete_action.tsx @@ -42,11 +42,13 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => { const [deleteTargetIndex, setDeleteTargetIndex] = useState(true); const [deleteIndexPattern, setDeleteIndexPattern] = useState(true); const [userCanDeleteIndex, setUserCanDeleteIndex] = useState(false); + const [userCanDeleteDataView, setUserCanDeleteDataView] = useState(false); const [indexPatternExists, setIndexPatternExists] = useState(false); const [isLoading, setIsLoading] = useState(false); const { data: { dataViews }, + application: { capabilities }, } = useMlKibana().services; const indexName = item?.config.dest.index ?? ''; @@ -83,6 +85,14 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => { if (userCanDelete) { setUserCanDeleteIndex(true); } + + const canDeleteDataView = + capabilities.savedObjectsManagement.delete === true || + capabilities.indexPatterns.save === true; + setUserCanDeleteDataView(canDeleteDataView); + if (canDeleteDataView === false) { + setDeleteIndexPattern(false); + } } catch (e) { const error = extractErrorMessage(e); setIsLoading(false); @@ -180,5 +190,6 @@ export const useDeleteAction = (canDeleteDataFrameAnalytics: boolean) => { toggleDeleteIndex, toggleDeleteIndexPattern, userCanDeleteIndex, + userCanDeleteDataView, }; }; diff --git a/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx b/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx index 7b558f6a05d3c..9ea5856434c52 100644 --- a/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx +++ b/x-pack/plugins/transform/public/app/hooks/use_delete_transform.tsx @@ -25,6 +25,7 @@ export const useDeleteIndexAndTargetIndex = (items: TransformListRow[]) => { http, savedObjects, ml: { extractErrorMessage }, + application: { capabilities }, } = useAppDependencies(); const toastNotifications = useToastNotifications(); @@ -32,6 +33,7 @@ export const useDeleteIndexAndTargetIndex = (items: TransformListRow[]) => { const [deleteIndexPattern, setDeleteIndexPattern] = useState(true); const [userCanDeleteIndex, setUserCanDeleteIndex] = useState(false); const [indexPatternExists, setIndexPatternExists] = useState(false); + const [userCanDeleteDataView, setUserCanDeleteDataView] = useState(false); const toggleDeleteIndex = useCallback( () => setDeleteDestIndex(!deleteDestIndex), @@ -70,6 +72,13 @@ export const useDeleteIndexAndTargetIndex = (items: TransformListRow[]) => { if (userCanDelete) { setUserCanDeleteIndex(true); } + const canDeleteDataView = + capabilities.savedObjectsManagement.delete === true || + capabilities.indexPatterns.save === true; + setUserCanDeleteDataView(canDeleteDataView); + if (canDeleteDataView === false) { + setDeleteIndexPattern(false); + } } catch (e) { toastNotifications.addDanger( i18n.translate( @@ -80,7 +89,7 @@ export const useDeleteIndexAndTargetIndex = (items: TransformListRow[]) => { ) ); } - }, [http, toastNotifications]); + }, [http, toastNotifications, capabilities]); useEffect(() => { checkUserIndexPermission(); @@ -99,6 +108,7 @@ export const useDeleteIndexAndTargetIndex = (items: TransformListRow[]) => { return { userCanDeleteIndex, + userCanDeleteDataView, deleteDestIndex, indexPatternExists, deleteIndexPattern, diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_modal.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_modal.tsx index 4292f96859aaf..2986fcce554e8 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_modal.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/delete_action_modal.tsx @@ -29,6 +29,7 @@ export const DeleteActionModal: FC = ({ toggleDeleteIndex, toggleDeleteIndexPattern, userCanDeleteIndex, + userCanDeleteDataView, }) => { const isBulkAction = items.length > 1; @@ -74,6 +75,7 @@ export const DeleteActionModal: FC = ({ )} checked={deleteIndexPattern} onChange={toggleDeleteIndexPattern} + disabled={userCanDeleteDataView === false} /> } @@ -114,6 +116,7 @@ export const DeleteActionModal: FC = ({ )} checked={deleteIndexPattern} onChange={toggleDeleteIndexPattern} + disabled={userCanDeleteDataView === false} /> )} diff --git a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx index ff0ad94eba91c..8c2fb6c96417e 100644 --- a/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx +++ b/x-pack/plugins/transform/public/app/sections/transform_management/components/action_delete/use_delete_action.tsx @@ -38,6 +38,7 @@ export const useDeleteAction = (forceDisable: boolean) => { const { userCanDeleteIndex, + userCanDeleteDataView, deleteDestIndex, indexPatternExists, deleteIndexPattern, @@ -50,7 +51,7 @@ export const useDeleteAction = (forceDisable: boolean) => { const shouldDeleteDestIndex = userCanDeleteIndex && deleteDestIndex; const shouldDeleteDestIndexPattern = - userCanDeleteIndex && indexPatternExists && deleteIndexPattern; + userCanDeleteIndex && userCanDeleteDataView && indexPatternExists && deleteIndexPattern; // if we are deleting multiple transforms, then force delete all if at least one item has failed // else, force delete only when the item user picks has failed const forceDelete = isBulkAction @@ -113,5 +114,6 @@ export const useDeleteAction = (forceDisable: boolean) => { toggleDeleteIndex, toggleDeleteIndexPattern, userCanDeleteIndex, + userCanDeleteDataView, }; }; From d954cbc6ed54f94067555d1032a038493f53c0ff Mon Sep 17 00:00:00 2001 From: Vitalii Dmyterko <92328789+vitaliidm@users.noreply.github.com> Date: Thu, 25 Nov 2021 18:03:39 +0000 Subject: [PATCH 33/46] [Security Solution][Detections] Improves Table UI: do not show dash when tags field is empty #119726 --- .../detections/pages/detection_engine/rules/all/columns.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/columns.tsx b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/columns.tsx index 0c500ee805a8f..235cdd9c740ee 100644 --- a/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/columns.tsx +++ b/x-pack/plugins/security_solution/public/detections/pages/detection_engine/rules/all/columns.tsx @@ -189,7 +189,7 @@ export const getColumns = ({ align: 'center', render: (tags: Rule['tags']) => { if (tags.length === 0) { - return getEmptyTagValue(); + return null; } const renderItem = (tag: string, i: number) => ( From 8fc2df7225d4d05f41a332b2e1e739834058eff6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ester=20Mart=C3=AD=20Vilaseca?= Date: Thu, 25 Nov 2021 19:07:46 +0100 Subject: [PATCH 34/46] [Stack monitoring] Add basic tests for alerts modal (#116769) * Add basic tests for alerts modal * fix types * fix setup mode button test subj * fix unit tests * Move alerts modal tests to functional since ssl is not required anymore * Remove not needed config change * fix test for overview alerts badge * Extract alerts deletion to a new service * exit setup mode in alerts test * add missing file * update test snapshots Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../monitoring/public/alerts/badge.tsx | 1 + .../public/alerts/lib/alerts_toast.tsx | 1 + .../__snapshots__/setup_mode.test.js.snap | 2 + .../public/components/renderers/setup_mode.js | 1 + .../__snapshots__/enter_button.test.tsx.snap | 2 +- .../components/setup_mode/enter_button.tsx | 3 +- .../apps/monitoring/_get_lifecycle_methods.js | 2 +- .../apps/monitoring/cluster/list.js | 26 ++++++++++++ .../apps/monitoring/cluster/overview.js | 41 +++++++++++++++++++ x-pack/test/functional/config.js | 5 +++ x-pack/test/functional/services/index.ts | 2 + .../functional/services/monitoring/alerts.js | 23 +++++++++++ .../services/monitoring/cluster_list.js | 4 ++ .../functional/services/monitoring/index.js | 1 + .../services/monitoring/setup_mode.js | 5 +++ 15 files changed, 116 insertions(+), 3 deletions(-) create mode 100644 x-pack/test/functional/services/monitoring/alerts.js diff --git a/x-pack/plugins/monitoring/public/alerts/badge.tsx b/x-pack/plugins/monitoring/public/alerts/badge.tsx index 22bffb5d62b19..6ccca9278edc0 100644 --- a/x-pack/plugins/monitoring/public/alerts/badge.tsx +++ b/x-pack/plugins/monitoring/public/alerts/badge.tsx @@ -97,6 +97,7 @@ export const AlertsBadge: React.FC = (props: Props) => { { })}

), + 'data-test-subj': 'alertsCreatedToast', }); }; diff --git a/x-pack/plugins/monitoring/public/components/renderers/__snapshots__/setup_mode.test.js.snap b/x-pack/plugins/monitoring/public/components/renderers/__snapshots__/setup_mode.test.js.snap index 8134143ca5320..b5d37c2c2afae 100644 --- a/x-pack/plugins/monitoring/public/components/renderers/__snapshots__/setup_mode.test.js.snap +++ b/x-pack/plugins/monitoring/public/components/renderers/__snapshots__/setup_mode.test.js.snap @@ -78,6 +78,7 @@ exports[`SetupModeRenderer should render the flyout open 1`] = ` > toggleSetupMode(false)} + data-test-subj="exitSetupModeBtn" > {i18n.translate('xpack.monitoring.setupMode.exit', { defaultMessage: `Exit setup mode`, diff --git a/x-pack/plugins/monitoring/public/components/setup_mode/__snapshots__/enter_button.test.tsx.snap b/x-pack/plugins/monitoring/public/components/setup_mode/__snapshots__/enter_button.test.tsx.snap index 0d9e50d14657b..0cf078d260ec7 100644 --- a/x-pack/plugins/monitoring/public/components/setup_mode/__snapshots__/enter_button.test.tsx.snap +++ b/x-pack/plugins/monitoring/public/components/setup_mode/__snapshots__/enter_button.test.tsx.snap @@ -3,9 +3,9 @@ exports[`EnterButton should render properly 1`] = `
= ( } return ( -
+
{i18n.translate('xpack.monitoring.setupMode.enter', { defaultMessage: 'Enter setup mode', diff --git a/x-pack/test/functional/apps/monitoring/_get_lifecycle_methods.js b/x-pack/test/functional/apps/monitoring/_get_lifecycle_methods.js index fce6fcfff7772..702a333999619 100644 --- a/x-pack/test/functional/apps/monitoring/_get_lifecycle_methods.js +++ b/x-pack/test/functional/apps/monitoring/_get_lifecycle_methods.js @@ -15,7 +15,7 @@ export const getLifecycleMethods = (getService, getPageObjects) => { async setup(archive, { from, to, useSuperUser = false }) { _archive = archive; if (!useSuperUser) { - await security.testUser.setRoles(['monitoring_user', 'kibana_admin']); + await security.testUser.setRoles(['monitoring_user', 'kibana_admin', 'test_monitoring']); } const kibanaServer = getService('kibanaServer'); diff --git a/x-pack/test/functional/apps/monitoring/cluster/list.js b/x-pack/test/functional/apps/monitoring/cluster/list.js index 09361f88f5652..61b783efe3e68 100644 --- a/x-pack/test/functional/apps/monitoring/cluster/list.js +++ b/x-pack/test/functional/apps/monitoring/cluster/list.js @@ -13,6 +13,8 @@ export default function ({ getService, getPageObjects }) { const clusterOverview = getService('monitoringClusterOverview'); const testSubjects = getService('testSubjects'); const PageObjects = getPageObjects(['monitoring', 'header', 'common']); + const alertsService = getService('monitoringAlerts'); + const browser = getService('browser'); describe('Cluster listing', () => { describe('with trial license clusters', () => { @@ -150,5 +152,29 @@ export default function ({ getService, getPageObjects }) { }); }); }); + + describe('Alerts', () => { + const { setup, tearDown } = getLifecycleMethods(getService, getPageObjects); + + before(async () => { + await setup('x-pack/test/functional/es_archives/monitoring/multicluster', { + from: 'Aug 15, 2017 @ 21:00:00.000', + to: 'Aug 16, 2017 @ 00:00:00.000', + }); + }); + + after(async () => { + await tearDown(); + + await alertsService.deleteAlerts(); + + await browser.clearLocalStorage(); + }); + + it('should show a toast when alerts are created successfully', async () => { + await clusterList.acceptAlertsModal(); + expect(await testSubjects.exists('alertsCreatedToast', { timeout: 10000 })).to.be(true); + }); + }); }); } diff --git a/x-pack/test/functional/apps/monitoring/cluster/overview.js b/x-pack/test/functional/apps/monitoring/cluster/overview.js index 902c82f088152..25e52535a39b2 100644 --- a/x-pack/test/functional/apps/monitoring/cluster/overview.js +++ b/x-pack/test/functional/apps/monitoring/cluster/overview.js @@ -10,6 +10,11 @@ import { getLifecycleMethods } from '../_get_lifecycle_methods'; export default function ({ getService, getPageObjects }) { const overview = getService('monitoringClusterOverview'); + const testSubjects = getService('testSubjects'); + const PageObjects = getPageObjects(['monitoring', 'common', 'timePicker']); + const alertsService = getService('monitoringAlerts'); + const browser = getService('browser'); + const setupMode = getService('monitoringSetupMode'); describe('Cluster overview', () => { describe('for Green cluster with Gold license', () => { @@ -159,5 +164,41 @@ export default function ({ getService, getPageObjects }) { expect(await overview.doesLsPanelExist()).to.be(false); }); }); + + describe('Alerts', () => { + const { setup, tearDown } = getLifecycleMethods(getService, getPageObjects); + + before(async () => { + await setup('x-pack/test/functional/es_archives/monitoring/singlecluster_green_gold', { + from: 'Aug 23, 2017 @ 21:29:35.267', + to: 'Aug 23, 2017 @ 21:47:25.556', + }); + }); + + after(async () => { + await tearDown(); + await alertsService.deleteAlerts(); + await browser.clearLocalStorage(); + }); + + describe('when create alerts options is selected in the alerts modal', () => { + before(async () => { + await overview.acceptAlertsModal(); + }); + + it('should show a toast when alerts are created successfully', async () => { + expect(await testSubjects.exists('alertsCreatedToast', { timeout: 10000 })).to.be(true); + }); + + it('should show badges when entering setup mode', async () => { + await setupMode.clickSetupModeBtn(); + await PageObjects.timePicker.startAutoRefresh(1); + + expect(await testSubjects.exists('alertsBadge')).to.be(true); + await PageObjects.timePicker.pauseAutoRefresh(); + await setupMode.clickExitSetupModeBtn(); + }); + }); + }); }); } diff --git a/x-pack/test/functional/config.js b/x-pack/test/functional/config.js index 2abd91fd0433a..de0c5dbd3699f 100644 --- a/x-pack/test/functional/config.js +++ b/x-pack/test/functional/config.js @@ -213,6 +213,11 @@ export default async function ({ readConfigFile }) { }, security: { roles: { + test_monitoring: { + elasticsearch: { + cluster: ['monitor'], + }, + }, test_logstash_reader: { elasticsearch: { cluster: [], diff --git a/x-pack/test/functional/services/index.ts b/x-pack/test/functional/services/index.ts index 2f9259c16d4bf..10c68456e1262 100644 --- a/x-pack/test/functional/services/index.ts +++ b/x-pack/test/functional/services/index.ts @@ -37,6 +37,7 @@ import { MonitoringKibanaInstanceProvider, MonitoringKibanaSummaryStatusProvider, MonitoringSetupModeProvider, + MonitoringAlertsProvider, // @ts-ignore not ts yet } from './monitoring'; // @ts-ignore not ts yet @@ -101,6 +102,7 @@ export const services = { monitoringKibanaInstance: MonitoringKibanaInstanceProvider, monitoringKibanaSummaryStatus: MonitoringKibanaSummaryStatusProvider, monitoringSetupMode: MonitoringSetupModeProvider, + monitoringAlerts: MonitoringAlertsProvider, pipelineList: PipelineListProvider, pipelineEditor: PipelineEditorProvider, random: RandomProvider, diff --git a/x-pack/test/functional/services/monitoring/alerts.js b/x-pack/test/functional/services/monitoring/alerts.js new file mode 100644 index 0000000000000..c480cc0c45c03 --- /dev/null +++ b/x-pack/test/functional/services/monitoring/alerts.js @@ -0,0 +1,23 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export function MonitoringAlertsProvider({ getService }) { + const supertest = getService('supertest'); + + return new (class MonitoringAlerts { + async deleteAlerts() { + const apiResponse = await supertest.get('/api/alerts/_find?per_page=20'); + const alerts = apiResponse.body.data.filter(({ consumer }) => consumer === 'monitoring'); + + return await Promise.all( + alerts.map(async (alert) => + supertest.delete(`/api/alerts/alert/${alert.id}`).set('kbn-xsrf', 'true').expect(204) + ) + ); + } + })(); +} diff --git a/x-pack/test/functional/services/monitoring/cluster_list.js b/x-pack/test/functional/services/monitoring/cluster_list.js index bcf0e18ef4dd7..1873d191bca56 100644 --- a/x-pack/test/functional/services/monitoring/cluster_list.js +++ b/x-pack/test/functional/services/monitoring/cluster_list.js @@ -46,6 +46,10 @@ export function MonitoringClusterListProvider({ getService, getPageObjects }) { return testSubjects.click(ALERTS_MODAL_BUTTON); } + acceptAlertsModal() { + return testSubjects.click('alerts-modal-button'); + } + getClusterLink(clusterUuid) { return testSubjects.find(`${SUBJ_CLUSTER_ROW_PREFIX}${clusterUuid} > clusterLink`); } diff --git a/x-pack/test/functional/services/monitoring/index.js b/x-pack/test/functional/services/monitoring/index.js index 5d337dc6ca822..e02280c52d2c0 100644 --- a/x-pack/test/functional/services/monitoring/index.js +++ b/x-pack/test/functional/services/monitoring/index.js @@ -30,3 +30,4 @@ export { MonitoringKibanaInstancesProvider } from './kibana_instances'; export { MonitoringKibanaInstanceProvider } from './kibana_instance'; export { MonitoringKibanaSummaryStatusProvider } from './kibana_summary_status'; export { MonitoringSetupModeProvider } from './setup_mode'; +export { MonitoringAlertsProvider } from './alerts'; diff --git a/x-pack/test/functional/services/monitoring/setup_mode.js b/x-pack/test/functional/services/monitoring/setup_mode.js index 976b7b4214937..64139fbc5016f 100644 --- a/x-pack/test/functional/services/monitoring/setup_mode.js +++ b/x-pack/test/functional/services/monitoring/setup_mode.js @@ -13,6 +13,7 @@ export function MonitoringSetupModeProvider({ getService }) { const SUBJ_SETUP_MODE_METRICBEAT_MIGRATION_TOOLTIP = 'monitoringSetupModeMetricbeatMigrationTooltip'; const SUBJ_SETUP_MODE_ALERTS_BADGE = 'monitoringSetupModeAlertBadges'; + const SUBJ_EXIT_SETUP_MODE_BTN = 'exitSetupModeBtn'; return new (class SetupMode { async doesSetupModeBtnAppear() { @@ -34,5 +35,9 @@ export function MonitoringSetupModeProvider({ getService }) { async doesAlertsTooltipAppear() { return await testSubjects.exists(SUBJ_SETUP_MODE_ALERTS_BADGE); } + + async clickExitSetupModeBtn() { + return await testSubjects.click(SUBJ_EXIT_SETUP_MODE_BTN); + } })(); } From 6730b4bdf77982100fee3f4c818dbb81d33aaab1 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 25 Nov 2021 19:33:12 +0000 Subject: [PATCH 35/46] skip flaky suite (#118626) --- .../integration_tests/7_13_0_failed_action_tasks.test.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/server/saved_objects/migrations/integration_tests/7_13_0_failed_action_tasks.test.ts b/src/core/server/saved_objects/migrations/integration_tests/7_13_0_failed_action_tasks.test.ts index 479b1e78e1b72..2def8e375c81f 100644 --- a/src/core/server/saved_objects/migrations/integration_tests/7_13_0_failed_action_tasks.test.ts +++ b/src/core/server/saved_objects/migrations/integration_tests/7_13_0_failed_action_tasks.test.ts @@ -19,7 +19,8 @@ async function removeLogFile() { await fs.unlink(logFilePath).catch(() => void 0); } -describe('migration from 7.13 to 7.14+ with many failed action_tasks', () => { +// FLAKY: https://github.com/elastic/kibana/issues/118626 +describe.skip('migration from 7.13 to 7.14+ with many failed action_tasks', () => { let esServer: kbnTestServer.TestElasticsearchUtils; let root: Root; let startES: () => Promise; From a949989af843733720409a7616d93994cdc1a429 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Thu, 25 Nov 2021 19:53:24 +0000 Subject: [PATCH 36/46] skip flaky suite (#118981) --- test/functional/apps/management/_scripted_fields_preview.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/functional/apps/management/_scripted_fields_preview.js b/test/functional/apps/management/_scripted_fields_preview.js index 12a6cb9537c8d..a442b521d5d98 100644 --- a/test/functional/apps/management/_scripted_fields_preview.js +++ b/test/functional/apps/management/_scripted_fields_preview.js @@ -13,7 +13,8 @@ export default function ({ getService, getPageObjects }) { const PageObjects = getPageObjects(['settings']); const SCRIPTED_FIELD_NAME = 'myScriptedField'; - describe('scripted fields preview', () => { + // FLAKY: https://github.com/elastic/kibana/issues/118981 + describe.skip('scripted fields preview', () => { before(async function () { await browser.setWindowSize(1200, 800); await PageObjects.settings.navigateTo(); From cd89a55d2f45658c60b889f1b5e0c7c511f332d8 Mon Sep 17 00:00:00 2001 From: Pierre Gayvallet Date: Fri, 26 Nov 2021 08:21:31 +0100 Subject: [PATCH 37/46] remove link for last breadcrumb element of SOM and SOT sections (#119425) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../public/management_section/saved_objects_table_page.tsx | 1 - .../public/management/tag_management_page.tsx | 1 - 2 files changed, 2 deletions(-) diff --git a/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx b/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx index 3dd8c8ec65614..edbaa22869b33 100644 --- a/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx +++ b/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx @@ -63,7 +63,6 @@ const SavedObjectsTablePage = ({ text: i18n.translate('savedObjectsManagement.breadcrumb.index', { defaultMessage: 'Saved objects', }), - href: '/', }, ]); }, [setBreadcrumbs]); diff --git a/x-pack/plugins/saved_objects_tagging/public/management/tag_management_page.tsx b/x-pack/plugins/saved_objects_tagging/public/management/tag_management_page.tsx index f93a9541db039..bbc018f8e12b0 100644 --- a/x-pack/plugins/saved_objects_tagging/public/management/tag_management_page.tsx +++ b/x-pack/plugins/saved_objects_tagging/public/management/tag_management_page.tsx @@ -122,7 +122,6 @@ export const TagManagementPage: FC = ({ text: i18n.translate('xpack.savedObjectsTagging.management.breadcrumb.index', { defaultMessage: 'Tags', }), - href: '/', }, ]); }, [setBreadcrumbs]); From 97f41c6b2adb2d4f81358b6c8986303ab54dc69f Mon Sep 17 00:00:00 2001 From: Muhammad Ibragimov <53621505+mibragimov@users.noreply.github.com> Date: Fri, 26 Nov 2021 14:40:34 +0500 Subject: [PATCH 38/46] [Devtools] Handle binary data response (#119586) * Render text instead of binary data response Co-authored-by: Muhammad Ibragimov --- .../editor/legacy/console_editor/editor_output.tsx | 8 ++++++++ src/plugins/console/public/types/common.ts | 3 ++- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx index 23c1c515cc9fc..cb5301fa41c1d 100644 --- a/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx +++ b/src/plugins/console/public/application/containers/editor/legacy/console_editor/editor_output.tsx @@ -28,6 +28,9 @@ import { applyCurrentSettings } from './apply_editor_settings'; const isJSONContentType = (contentType?: string) => Boolean(contentType && contentType.indexOf('application/json') >= 0); +const isMapboxVectorTile = (contentType?: string) => + contentType?.includes('application/vnd.mapbox-vector-tile') ?? false; + /** * Best effort expand literal strings */ @@ -85,6 +88,11 @@ function EditorOutputUI() { if (readOnlySettings.tripleQuotes && isJSONContentType(contentType)) { return safeExpandLiteralStrings(value as string); } + if (isMapboxVectorTile(contentType)) { + return i18n.translate('console.outputCannotPreviewBinaryData', { + defaultMessage: 'Cannot preview binary data.', + }); + } return value; }) .join('\n'), diff --git a/src/plugins/console/public/types/common.ts b/src/plugins/console/public/types/common.ts index 53d896ad01d2f..79013ce312726 100644 --- a/src/plugins/console/public/types/common.ts +++ b/src/plugins/console/public/types/common.ts @@ -23,4 +23,5 @@ export type BaseResponseType = | 'text/tab-separated-values' | 'text/plain' | 'application/yaml' - | 'unknown'; + | 'unknown' + | 'application/vnd.mapbox-vector-tile'; From 614231c43db76c1be89b7a8b9e6f0200f7c79f3b Mon Sep 17 00:00:00 2001 From: Diana Derevyankina <54894989+DziyanaDzeraviankina@users.noreply.github.com> Date: Fri, 26 Nov 2021 12:56:52 +0300 Subject: [PATCH 39/46] [Vega] Hide warnings for view mode (#117518) * [Vega] Hide warnings for view mode * Update get_visualization_instance.test Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../vega/public/components/vega_vis_component.tsx | 15 +++++++++++---- .../vega/public/vega_view/vega_base_view.js | 3 ++- .../vis_types/vega/public/vega_vis_renderer.tsx | 1 + .../vis_types/vega/public/vega_visualization.ts | 11 ++++++----- .../public/embeddable/visualize_embeddable.tsx | 3 +++ .../utils/get_visualization_instance.test.ts | 4 ++++ .../utils/get_visualization_instance.ts | 1 + 7 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/plugins/vis_types/vega/public/components/vega_vis_component.tsx b/src/plugins/vis_types/vega/public/components/vega_vis_component.tsx index c9d89abcf265c..2639f39abd099 100644 --- a/src/plugins/vis_types/vega/public/components/vega_vis_component.tsx +++ b/src/plugins/vis_types/vega/public/components/vega_vis_component.tsx @@ -10,7 +10,7 @@ import React, { useEffect, useCallback, useRef } from 'react'; import { EuiResizeObserver } from '@elastic/eui'; import { throttle } from 'lodash'; -import { IInterpreterRenderHandlers } from 'src/plugins/expressions'; +import type { IInterpreterRenderHandlers, RenderMode } from 'src/plugins/expressions'; import { createVegaVisualization } from '../vega_visualization'; import { VegaVisualizationDependencies } from '../plugin'; import { VegaParser } from '../data_model/vega_parser'; @@ -21,18 +21,25 @@ interface VegaVisComponentProps { deps: VegaVisualizationDependencies; fireEvent: IInterpreterRenderHandlers['event']; renderComplete: () => void; + renderMode: RenderMode; visData: VegaParser; } type VegaVisController = InstanceType>; -const VegaVisComponent = ({ visData, fireEvent, renderComplete, deps }: VegaVisComponentProps) => { +const VegaVisComponent = ({ + visData, + fireEvent, + renderComplete, + deps, + renderMode, +}: VegaVisComponentProps) => { const chartDiv = useRef(null); const visController = useRef(null); useEffect(() => { if (chartDiv.current) { - const VegaVis = createVegaVisualization(deps); + const VegaVis = createVegaVisualization(deps, renderMode); visController.current = new VegaVis(chartDiv.current, fireEvent); } @@ -40,7 +47,7 @@ const VegaVisComponent = ({ visData, fireEvent, renderComplete, deps }: VegaVisC visController.current?.destroy(); visController.current = null; }; - }, [deps, fireEvent]); + }, [deps, fireEvent, renderMode]); useEffect(() => { if (visController.current) { diff --git a/src/plugins/vis_types/vega/public/vega_view/vega_base_view.js b/src/plugins/vis_types/vega/public/vega_view/vega_base_view.js index 8c725ba0a75a2..4485e2ed855f5 100644 --- a/src/plugins/vis_types/vega/public/vega_view/vega_base_view.js +++ b/src/plugins/vis_types/vega/public/vega_view/vega_base_view.js @@ -89,6 +89,7 @@ export class VegaBaseView { this._initialized = false; this._externalUrl = opts.externalUrl; this._enableExternalUrls = getEnableExternalUrls(); + this._renderMode = opts.renderMode; this._vegaStateRestorer = opts.vegaStateRestorer; } @@ -238,7 +239,7 @@ export class VegaBaseView { } onWarn() { - if (!this._parser || !this._parser.hideWarnings) { + if (this._renderMode !== 'view' && (!this._parser || !this._parser.hideWarnings)) { this._addMessage('warn', Utils.formatWarningToStr(...arguments)); } } diff --git a/src/plugins/vis_types/vega/public/vega_vis_renderer.tsx b/src/plugins/vis_types/vega/public/vega_vis_renderer.tsx index e6a39f5a18e83..b2f10c37c7905 100644 --- a/src/plugins/vis_types/vega/public/vega_vis_renderer.tsx +++ b/src/plugins/vis_types/vega/public/vega_vis_renderer.tsx @@ -33,6 +33,7 @@ export const getVegaVisRenderer: ( deps={deps} fireEvent={handlers.event} renderComplete={handlers.done} + renderMode={handlers.getRenderMode()} visData={visData} /> diff --git a/src/plugins/vis_types/vega/public/vega_visualization.ts b/src/plugins/vis_types/vega/public/vega_visualization.ts index 556f80cc3ebeb..2ab55a0358f4d 100644 --- a/src/plugins/vis_types/vega/public/vega_visualization.ts +++ b/src/plugins/vis_types/vega/public/vega_visualization.ts @@ -7,7 +7,7 @@ */ import { i18n } from '@kbn/i18n'; -import { IInterpreterRenderHandlers } from 'src/plugins/expressions'; +import type { IInterpreterRenderHandlers, RenderMode } from 'src/plugins/expressions'; import { VegaParser } from './data_model/vega_parser'; import { VegaVisualizationDependencies } from './plugin'; import { getNotifications, getData } from './services'; @@ -19,10 +19,10 @@ type VegaVisType = new (el: HTMLDivElement, fireEvent: IInterpreterRenderHandler destroy(): void; }; -export const createVegaVisualization = ({ - core, - getServiceSettings, -}: VegaVisualizationDependencies): VegaVisType => +export const createVegaVisualization = ( + { core, getServiceSettings }: VegaVisualizationDependencies, + renderMode: RenderMode +): VegaVisType => class VegaVisualization { private readonly dataPlugin = getData(); private vegaView: InstanceType | null = null; @@ -82,6 +82,7 @@ export const createVegaVisualization = ({ serviceSettings, filterManager, timefilter, + renderMode, }; if (vegaParser.useMap) { diff --git a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx index 3a248732eac0c..b87065a815410 100644 --- a/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx +++ b/src/plugins/visualizations/public/embeddable/visualize_embeddable.tsx @@ -46,6 +46,7 @@ import { SavedObjectAttributes } from '../../../../core/types'; import { getSavedVisualization } from '../utils/saved_visualize_utils'; import { VisSavedObject } from '../types'; import { toExpressionAst } from './to_ast'; +import type { RenderMode } from '../../../expressions'; const getKeys = (o: T): Array => Object.keys(o) as Array; @@ -63,6 +64,7 @@ export interface VisualizeInput extends EmbeddableInput { colors?: { [key: string]: string }; }; savedVis?: SerializedVis; + renderMode?: RenderMode; table?: unknown; query?: Query; filters?: Filter[]; @@ -314,6 +316,7 @@ export class VisualizeEmbeddable const expressions = getExpressions(); this.handler = await expressions.loader(this.domNode, undefined, { + renderMode: this.input.renderMode || 'view', onRenderError: (element: HTMLElement, error: ExpressionRenderError) => { this.onContainerError(error); }, diff --git a/src/plugins/visualize/public/application/utils/get_visualization_instance.test.ts b/src/plugins/visualize/public/application/utils/get_visualization_instance.test.ts index 777ba244c06a1..ce8fd951d7a13 100644 --- a/src/plugins/visualize/public/application/utils/get_visualization_instance.test.ts +++ b/src/plugins/visualize/public/application/utils/get_visualization_instance.test.ts @@ -87,8 +87,10 @@ describe('getVisualizationInstance', () => { serializedVisMock ); expect(mockServices.createVisEmbeddableFromObject).toHaveBeenCalledWith(visMock, { + searchSessionId: undefined, timeRange: undefined, filters: undefined, + renderMode: 'edit', id: '', }); @@ -203,8 +205,10 @@ describe('getVisualizationInstanceInput', () => { input.savedVis ); expect(mockServices.createVisEmbeddableFromObject).toHaveBeenCalledWith(visMock, { + searchSessionId: undefined, timeRange: undefined, filters: undefined, + renderMode: 'edit', id: '', }); diff --git a/src/plugins/visualize/public/application/utils/get_visualization_instance.ts b/src/plugins/visualize/public/application/utils/get_visualization_instance.ts index 876501d5f099b..bc51384408935 100644 --- a/src/plugins/visualize/public/application/utils/get_visualization_instance.ts +++ b/src/plugins/visualize/public/application/utils/get_visualization_instance.ts @@ -42,6 +42,7 @@ const createVisualizeEmbeddableAndLinkSavedSearch = async ( timeRange: data.query.timefilter.timefilter.getTime(), filters: data.query.filterManager.getFilters(), searchSessionId: data.search.session.getSessionId(), + renderMode: 'edit', })) as VisualizeEmbeddableContract; embeddableHandler.getOutput$().subscribe((output) => { From 4323cdadb6d06b948012f73f29fa0061162fb224 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 26 Nov 2021 05:57:07 -0500 Subject: [PATCH 40/46] Update dependency elastic-apm-node to ^3.25.0 (#119760) Co-authored-by: Renovate Bot --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index df39dd8c65d7e..983dddda5d4fb 100644 --- a/package.json +++ b/package.json @@ -222,7 +222,7 @@ "deep-freeze-strict": "^1.1.1", "deepmerge": "^4.2.2", "del": "^5.1.0", - "elastic-apm-node": "^3.24.0", + "elastic-apm-node": "^3.25.0", "execa": "^4.0.2", "exit-hook": "^2.2.0", "expiry-js": "0.1.7", diff --git a/yarn.lock b/yarn.lock index 3d1ab34b02f85..44185306ca38f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12407,10 +12407,10 @@ elastic-apm-http-client@^10.3.0: readable-stream "^3.4.0" stream-chopper "^3.0.1" -elastic-apm-node@^3.24.0: - version "3.24.0" - resolved "https://registry.yarnpkg.com/elastic-apm-node/-/elastic-apm-node-3.24.0.tgz#d7acb3352f928a23c28ebabab2bd30098562814e" - integrity sha512-Fmj/W2chWQa2zb1FfMYK2ypLB4TcnKNX+1klaJFbytRYDLgeSfo0EC7egvI3a+bLPZSRL5053PXOp7slVTPO6Q== +elastic-apm-node@^3.25.0: + version "3.25.0" + resolved "https://registry.yarnpkg.com/elastic-apm-node/-/elastic-apm-node-3.25.0.tgz#3207c936429739cd07f64cbf76d7b5b4b8e0da3e" + integrity sha512-3K+uUQkKeaJarjPb/pDY3fldP7QeppgPPx8nJOkOrW+BvQK5YBMiWbf4S9fdx0yUUkWsVX6K+CAc401+Y1COkg== dependencies: "@elastic/ecs-pino-format" "^1.2.0" after-all-results "^2.0.0" From 6d7f2ee6be04c4004240b5d6b5647c1e2fa0cadf Mon Sep 17 00:00:00 2001 From: Shahzad Date: Fri, 26 Nov 2021 16:06:14 +0100 Subject: [PATCH 41/46] [Uptime] Setup synthetics index template (#119727) --- .../uptime/common/constants/rest_api.ts | 3 ++ .../lib/adapters/framework/adapter_types.ts | 5 ++- x-pack/plugins/uptime/server/plugin.ts | 32 ++++++++++++-- .../plugins/uptime/server/rest_api/index.ts | 2 + .../install_index_templates.ts | 43 +++++++++++++++++++ 5 files changed, 80 insertions(+), 5 deletions(-) create mode 100644 x-pack/plugins/uptime/server/rest_api/synthetics_service/install_index_templates.ts diff --git a/x-pack/plugins/uptime/common/constants/rest_api.ts b/x-pack/plugins/uptime/common/constants/rest_api.ts index 26b2c7aad20ac..bef84c41796d9 100644 --- a/x-pack/plugins/uptime/common/constants/rest_api.ts +++ b/x-pack/plugins/uptime/common/constants/rest_api.ts @@ -35,4 +35,7 @@ export enum API_URLS { DELETE_RULE = '/api/alerting/rule/', RULES_FIND = '/api/alerting/rules/_find', CONNECTOR_TYPES = '/api/actions/connector_types', + + // Service end points + INDEX_TEMPLATES = '/api/uptime/service/index_templates', } diff --git a/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts b/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts index bb8e413b75880..029c6164c0481 100644 --- a/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts +++ b/x-pack/plugins/uptime/server/lib/adapters/framework/adapter_types.ts @@ -24,6 +24,7 @@ import { UptimeESClient } from '../../lib'; import type { UptimeRouter } from '../../../types'; import { SecurityPluginStart } from '../../../../../security/server'; import { CloudSetup } from '../../../../../cloud/server'; +import { FleetStartContract } from '../../../../../fleet/server'; import { UptimeConfig } from '../../../../common/config'; export type UMElasticsearchQueryFn = ( @@ -41,7 +42,8 @@ export type UMSavedObjectsQueryFn = ( export interface UptimeCoreSetup { router: UptimeRouter; config: UptimeConfig; - cloud: CloudSetup; + cloud?: CloudSetup; + fleet: FleetStartContract; security: SecurityPluginStart; encryptedSavedObjects: EncryptedSavedObjectsPluginStart; } @@ -59,6 +61,7 @@ export interface UptimeCorePluginsSetup { export interface UptimeCorePluginsStart { security: SecurityPluginStart; + fleet: FleetStartContract; encryptedSavedObjects: EncryptedSavedObjectsPluginStart; } diff --git a/x-pack/plugins/uptime/server/plugin.ts b/x-pack/plugins/uptime/server/plugin.ts index a94f9650e32cc..4276497257111 100644 --- a/x-pack/plugins/uptime/server/plugin.ts +++ b/x-pack/plugins/uptime/server/plugin.ts @@ -12,6 +12,7 @@ import { Plugin as PluginType, ISavedObjectsRepository, Logger, + SavedObjectsClient, } from '../../../../src/core/server'; import { uptimeRuleFieldMap } from '../common/rules/uptime_rule_field_map'; import { initServerWithKibana } from './kibana.index'; @@ -25,17 +26,19 @@ import { registerUptimeSavedObjects, savedObjectsAdapter } from './lib/saved_obj import { mappingFromFieldMap } from '../../rule_registry/common/mapping_from_field_map'; import { Dataset } from '../../rule_registry/server'; import { UptimeConfig } from '../common/config'; +import { installSyntheticsIndexTemplates } from './rest_api/synthetics_service/install_index_templates'; export type UptimeRuleRegistry = ReturnType['ruleRegistry']; export class Plugin implements PluginType { private savedObjectsClient?: ISavedObjectsRepository; private initContext: PluginInitializerContext; - private logger?: Logger; + private logger: Logger; private server?: UptimeCoreSetup; - constructor(_initializerContext: PluginInitializerContext) { - this.initContext = _initializerContext; + constructor(initializerContext: PluginInitializerContext) { + this.initContext = initializerContext; + this.logger = initializerContext.logger.get(); } public setup(core: CoreSetup, plugins: UptimeCorePluginsSetup) { @@ -60,8 +63,8 @@ export class Plugin implements PluginType { }); this.server = { - router: core.http.createRouter(), config, + router: core.http.createRouter(), cloud: plugins.cloud, } as UptimeCoreSetup; @@ -83,8 +86,29 @@ export class Plugin implements PluginType { this.savedObjectsClient = core.savedObjects.createInternalRepository(); if (this.server) { this.server.security = plugins.security; + this.server.fleet = plugins.fleet; this.server.encryptedSavedObjects = plugins.encryptedSavedObjects; } + + if (this.server?.config?.unsafe?.service.enabled) { + const esClient = core.elasticsearch.client.asInternalUser; + installSyntheticsIndexTemplates({ + esClient, + server: this.server, + savedObjectsClient: new SavedObjectsClient(core.savedObjects.createInternalRepository()), + }).then( + (result) => { + if (result.name === 'synthetics' && result.install_status === 'installed') { + this.logger.info('Installed synthetics index templates'); + } else if (result.name === 'synthetics' && result.install_status === 'install_failed') { + this.logger.warn('Failed to install synthetics index templates'); + } + }, + () => { + this.logger.warn('Failed to install synthetics index templates'); + } + ); + } } public stop() {} diff --git a/x-pack/plugins/uptime/server/rest_api/index.ts b/x-pack/plugins/uptime/server/rest_api/index.ts index d5aadf079931d..344dd4d203d8d 100644 --- a/x-pack/plugins/uptime/server/rest_api/index.ts +++ b/x-pack/plugins/uptime/server/rest_api/index.ts @@ -27,6 +27,7 @@ import { createGetIndexStatusRoute } from './index_state'; import { createNetworkEventsRoute } from './network_events'; import { createJourneyFailedStepsRoute } from './pings/journeys'; import { createLastSuccessfulStepRoute } from './synthetics/last_successful_step'; +import { installIndexTemplatesRoute } from './synthetics_service/install_index_templates'; export * from './types'; export { createRouteWithAuth } from './create_route_with_auth'; @@ -51,4 +52,5 @@ export const restApiRoutes: UMRestApiRouteFactory[] = [ createJourneyFailedStepsRoute, createLastSuccessfulStepRoute, createJourneyScreenshotBlocksRoute, + installIndexTemplatesRoute, ]; diff --git a/x-pack/plugins/uptime/server/rest_api/synthetics_service/install_index_templates.ts b/x-pack/plugins/uptime/server/rest_api/synthetics_service/install_index_templates.ts new file mode 100644 index 0000000000000..b40c6018f966b --- /dev/null +++ b/x-pack/plugins/uptime/server/rest_api/synthetics_service/install_index_templates.ts @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ +import { ElasticsearchClient, SavedObjectsClientContract } from 'kibana/server'; +import { UMRestApiRouteFactory } from '../types'; +import { API_URLS } from '../../../common/constants'; +import { UptimeCoreSetup } from '../../lib/adapters'; + +export const installIndexTemplatesRoute: UMRestApiRouteFactory = () => ({ + method: 'GET', + path: API_URLS.INDEX_TEMPLATES, + validate: {}, + handler: async ({ server, request, savedObjectsClient, uptimeEsClient }): Promise => { + return installSyntheticsIndexTemplates({ + server, + savedObjectsClient, + esClient: uptimeEsClient.baseESClient, + }); + }, +}); + +export async function installSyntheticsIndexTemplates({ + esClient, + server, + savedObjectsClient, +}: { + server: UptimeCoreSetup; + esClient: ElasticsearchClient; + savedObjectsClient: SavedObjectsClientContract; +}) { + // no need to add error handling here since fleetSetupCompleted is already wrapped in try/catch and will log + // warning if setup fails to complete + await server.fleet.fleetSetupCompleted(); + + return await server.fleet.packageService.ensureInstalledPackage({ + esClient, + savedObjectsClient, + pkgName: 'synthetics', + }); +} From 7d209140ac2c7947e44c1838bbd2342eaf7c46bd Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Fri, 26 Nov 2021 15:30:30 +0000 Subject: [PATCH 42/46] skip flaky suite (#119763) --- x-pack/test/functional/apps/infra/home_page.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/infra/home_page.ts b/x-pack/test/functional/apps/infra/home_page.ts index dfb5ba1cba4fd..9c53ba20d38de 100644 --- a/x-pack/test/functional/apps/infra/home_page.ts +++ b/x-pack/test/functional/apps/infra/home_page.ts @@ -35,7 +35,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); }); - describe('with metrics present', () => { + // FLAKY: https://github.com/elastic/kibana/issues/119763 + describe.skip('with metrics present', () => { before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/infra/metrics_and_logs'); await pageObjects.common.navigateToApp('infraOps'); From 736e31a489c68428fa88e456bb3ec27bb1f03b61 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Fri, 26 Nov 2021 15:38:50 +0000 Subject: [PATCH 43/46] skip flaky suite (#119272) --- x-pack/test/api_integration/apis/search/search.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/api_integration/apis/search/search.ts b/x-pack/test/api_integration/apis/search/search.ts index 45e8933bf715f..d36121a102a28 100644 --- a/x-pack/test/api_integration/apis/search/search.ts +++ b/x-pack/test/api_integration/apis/search/search.ts @@ -250,7 +250,8 @@ export default function ({ getService }: FtrProviderContext) { }); }); - describe('delete', () => { + // FLAKY: https://github.com/elastic/kibana/issues/119272 + describe.skip('delete', () => { it('should return 404 when no search id provided', async () => { await supertest.delete(`/internal/search/ese`).set('kbn-xsrf', 'foo').send().expect(404); }); From 6367b17d20b85b583033a0e8ff4e2d368cc83712 Mon Sep 17 00:00:00 2001 From: Joe Reuter Date: Sat, 27 Nov 2021 12:25:11 +0100 Subject: [PATCH 44/46] hide fit from suggestions (#119568) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- src/plugins/vis_types/timelion/common/types.ts | 1 + .../public/components/timelion_expression_input_helpers.ts | 2 +- src/plugins/vis_types/timelion/server/lib/classes/datasource.js | 1 + .../vis_types/timelion/server/series_functions/es/index.js | 1 + 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/plugins/vis_types/timelion/common/types.ts b/src/plugins/vis_types/timelion/common/types.ts index 8ce4bd8b45f0d..323539f69488a 100644 --- a/src/plugins/vis_types/timelion/common/types.ts +++ b/src/plugins/vis_types/timelion/common/types.ts @@ -20,6 +20,7 @@ export interface TimelionFunctionArgs { multi?: boolean; types: TimelionFunctionArgsTypes[]; suggestions?: TimelionFunctionArgsSuggestion[]; + hidden?: boolean; } export interface ITimelionFunction { diff --git a/src/plugins/vis_types/timelion/public/components/timelion_expression_input_helpers.ts b/src/plugins/vis_types/timelion/public/components/timelion_expression_input_helpers.ts index 6c3cd8058627a..676b5d91a803f 100644 --- a/src/plugins/vis_types/timelion/public/components/timelion_expression_input_helpers.ts +++ b/src/plugins/vis_types/timelion/public/components/timelion_expression_input_helpers.ts @@ -42,7 +42,7 @@ function getArgumentsHelp( // ignore arguments that are already provided in function declaration const functionArgNames = functionArgs.map((arg) => arg.name); - return argsHelp.filter((arg) => !functionArgNames.includes(arg.name)); + return argsHelp.filter((arg) => !arg.hidden && !functionArgNames.includes(arg.name)); } async function extractSuggestionsFromParsedResult( diff --git a/src/plugins/vis_types/timelion/server/lib/classes/datasource.js b/src/plugins/vis_types/timelion/server/lib/classes/datasource.js index f0af22793c98f..50129494bf84c 100644 --- a/src/plugins/vis_types/timelion/server/lib/classes/datasource.js +++ b/src/plugins/vis_types/timelion/server/lib/classes/datasource.js @@ -47,6 +47,7 @@ export default class Datasource extends TimelionFunction { fitFunctions: _.keys(fitFunctions).join(', '), }, }), + hidden: Boolean(config.hideFitArg), }); // Wrap the original function so we can modify inputs/outputs with offset & fit diff --git a/src/plugins/vis_types/timelion/server/series_functions/es/index.js b/src/plugins/vis_types/timelion/server/series_functions/es/index.js index 663d7714774c2..d613818d7c3e3 100644 --- a/src/plugins/vis_types/timelion/server/series_functions/es/index.js +++ b/src/plugins/vis_types/timelion/server/series_functions/es/index.js @@ -13,6 +13,7 @@ import buildRequest from './lib/build_request'; import toSeriesList from './lib/agg_response_to_series_list'; export default new Datasource('es', { + hideFitArg: true, args: [ { name: 'q', From 322303268a31305538a7b8997d08bf4668cf6ca6 Mon Sep 17 00:00:00 2001 From: Tiago Costa Date: Sat, 27 Nov 2021 16:04:17 +0000 Subject: [PATCH 45/46] skip flaky suite (#103390) --- x-pack/test/functional/apps/uptime/synthetics_integration.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/test/functional/apps/uptime/synthetics_integration.ts b/x-pack/test/functional/apps/uptime/synthetics_integration.ts index 9346867a0f1db..83fc3c4079619 100644 --- a/x-pack/test/functional/apps/uptime/synthetics_integration.ts +++ b/x-pack/test/functional/apps/uptime/synthetics_integration.ts @@ -170,7 +170,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { }); }); - describe('create new policy', () => { + // FLAKY: https://github.com/elastic/kibana/issues/103390 + describe.skip('create new policy', () => { let version: string; beforeEach(async () => { From a0650c7510e9396e16a24e2ed83fcd25ffac8f90 Mon Sep 17 00:00:00 2001 From: Dario Gieselaar Date: Sun, 28 Nov 2021 13:15:42 +0100 Subject: [PATCH 46/46] [Alerting] Add more rule execution context (#117504) Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com> --- .../actions/server/lib/action_executor.ts | 4 +- .../server/task_runner/task_runner.ts | 42 ++++++++++++++++++- .../server/task_scheduling.test.ts | 3 ++ .../task_manager/server/task_scheduling.ts | 8 +++- 4 files changed, 53 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/actions/server/lib/action_executor.ts b/x-pack/plugins/actions/server/lib/action_executor.ts index 518d4582de2bc..9458180fdd220 100644 --- a/x-pack/plugins/actions/server/lib/action_executor.ts +++ b/x-pack/plugins/actions/server/lib/action_executor.ts @@ -105,7 +105,7 @@ export class ActionExecutor { name: `execute_action`, type: 'actions', labels: { - actionId, + actions_connector_id: actionId, }, }, async (span) => { @@ -135,7 +135,7 @@ export class ActionExecutor { if (span) { span.name = `execute_action ${actionTypeId}`; span.addLabels({ - actionTypeId, + actions_connector_type_id: actionTypeId, }); } diff --git a/x-pack/plugins/alerting/server/task_runner/task_runner.ts b/x-pack/plugins/alerting/server/task_runner/task_runner.ts index f651f41ef0c1e..fe95ec646387d 100644 --- a/x-pack/plugins/alerting/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerting/server/task_runner/task_runner.ts @@ -4,7 +4,7 @@ * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ - +import apm from 'elastic-apm-node'; import type { PublicMethodsOf } from '@kbn/utility-types'; import { Dictionary, pickBy, mapValues, without, cloneDeep } from 'lodash'; import type { Request } from '@hapi/hapi'; @@ -529,6 +529,17 @@ export class TaskRunner< // Ensure API key is still valid and user has access try { alert = await rulesClient.get({ id: alertId }); + + if (apm.currentTransaction) { + apm.currentTransaction.name = `Execute Alerting Rule: "${alert.name}"`; + apm.currentTransaction.addLabels({ + alerting_rule_consumer: alert.consumer, + alerting_rule_name: alert.name, + alerting_rule_tags: alert.tags.join(', '), + alerting_rule_type_id: alert.alertTypeId, + alerting_rule_params: JSON.stringify(alert.params), + }); + } } catch (err) { throw new ErrorWithReason(AlertExecutionStatusErrorReasons.Read, err); } @@ -560,6 +571,13 @@ export class TaskRunner< schedule: taskSchedule, } = this.taskInstance; + if (apm.currentTransaction) { + apm.currentTransaction.name = `Execute Alerting Rule`; + apm.currentTransaction.addLabels({ + alerting_rule_id: alertId, + }); + } + const runDate = new Date(); const runDateString = runDate.toISOString(); this.logger.debug(`executing alert ${this.alertType.id}:${alertId} at ${runDateString}`); @@ -615,6 +633,14 @@ export class TaskRunner< executionStatus.lastExecutionDate = new Date(event.event.start); } + if (apm.currentTransaction) { + if (executionStatus.status === 'ok' || executionStatus.status === 'active') { + apm.currentTransaction.setOutcome('success'); + } else if (executionStatus.status === 'error' || executionStatus.status === 'unknown') { + apm.currentTransaction.setOutcome('failure'); + } + } + this.logger.debug( `alertExecutionStatus for ${this.alertType.id}:${alertId}: ${JSON.stringify(executionStatus)}` ); @@ -855,6 +881,12 @@ function generateNewAndRecoveredInstanceEvents< const recoveredAlertInstanceIds = Object.keys(recoveredAlertInstances); const newIds = without(currentAlertInstanceIds, ...originalAlertInstanceIds); + if (apm.currentTransaction) { + apm.currentTransaction.addLabels({ + alerting_new_alerts: newIds.length, + }); + } + for (const id of recoveredAlertInstanceIds) { const { group: actionGroup, subgroup: actionSubgroup } = recoveredAlertInstances[id].getLastScheduledActions() ?? {}; @@ -1035,6 +1067,14 @@ function logActiveAndRecoveredInstances< const { logger, activeAlertInstances, recoveredAlertInstances, alertLabel } = params; const activeInstanceIds = Object.keys(activeAlertInstances); const recoveredInstanceIds = Object.keys(recoveredAlertInstances); + + if (apm.currentTransaction) { + apm.currentTransaction.addLabels({ + alerting_active_alerts: activeInstanceIds.length, + alerting_recovered_alerts: recoveredInstanceIds.length, + }); + } + if (activeInstanceIds.length > 0) { logger.debug( `alert ${alertLabel} has ${activeInstanceIds.length} active alert instances: ${JSON.stringify( diff --git a/x-pack/plugins/task_manager/server/task_scheduling.test.ts b/x-pack/plugins/task_manager/server/task_scheduling.test.ts index 41a172bfb2f8e..f593363c53bcf 100644 --- a/x-pack/plugins/task_manager/server/task_scheduling.test.ts +++ b/x-pack/plugins/task_manager/server/task_scheduling.test.ts @@ -35,6 +35,9 @@ jest.mock('uuid', () => ({ jest.mock('elastic-apm-node', () => ({ currentTraceparent: 'parent', + currentTransaction: { + type: 'taskManager run', + }, })); describe('TaskScheduling', () => { diff --git a/x-pack/plugins/task_manager/server/task_scheduling.ts b/x-pack/plugins/task_manager/server/task_scheduling.ts index a89f66d9c772b..abf1ea0f50eda 100644 --- a/x-pack/plugins/task_manager/server/task_scheduling.ts +++ b/x-pack/plugins/task_manager/server/task_scheduling.ts @@ -99,9 +99,15 @@ export class TaskScheduling { ...options, taskInstance: ensureDeprecatedFieldsAreCorrected(taskInstance, this.logger), }); + + const traceparent = + agent.currentTransaction && agent.currentTransaction.type !== 'request' + ? agent.currentTraceparent + : ''; + return await this.store.schedule({ ...modifiedTask, - traceparent: agent.currentTraceparent ?? '', + traceparent: traceparent || '', }); }