diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index accc99170bb70..df3a56dd35130 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -29,33 +29,32 @@ /src/plugins/dashboard/ @elastic/kibana-app # App Architecture +/examples/url_generators_examples/ @elastic/kibana-app-arch +/examples/url_generators_explorer/ @elastic/kibana-app-arch /packages/kbn-interpreter/ @elastic/kibana-app-arch -/src/legacy/core_plugins/data/ @elastic/kibana-app-arch -/src/legacy/core_plugins/elasticsearch/lib/create_proxy.js @elastic/kibana-app-arch /src/legacy/core_plugins/embeddable_api/ @elastic/kibana-app-arch /src/legacy/core_plugins/interpreter/ @elastic/kibana-app-arch /src/legacy/core_plugins/kibana_react/ @elastic/kibana-app-arch /src/legacy/core_plugins/kibana/public/management/ @elastic/kibana-app-arch -/src/legacy/core_plugins/kibana/server/field_formats/ @elastic/kibana-app-arch /src/legacy/core_plugins/kibana/server/routes/api/management/ @elastic/kibana-app-arch -/src/legacy/core_plugins/kibana/server/routes/api/suggestions/ @elastic/kibana-app-arch /src/legacy/core_plugins/visualizations/ @elastic/kibana-app-arch /src/legacy/server/index_patterns/ @elastic/kibana-app-arch +/src/plugins/advanced_settings/ @elastic/kibana-app-arch /src/plugins/bfetch/ @elastic/kibana-app-arch /src/plugins/data/ @elastic/kibana-app-arch /src/plugins/embeddable/ @elastic/kibana-app-arch /src/plugins/expressions/ @elastic/kibana-app-arch /src/plugins/inspector/ @elastic/kibana-app-arch /src/plugins/kibana_react/ @elastic/kibana-app-arch +/src/plugins/kibana_react/public/code_editor @elastic/kibana-canvas /src/plugins/kibana_utils/ @elastic/kibana-app-arch /src/plugins/management/ @elastic/kibana-app-arch /src/plugins/navigation/ @elastic/kibana-app-arch +/src/plugins/share/ @elastic/kibana-app-arch /src/plugins/ui_actions/ @elastic/kibana-app-arch /src/plugins/visualizations/ @elastic/kibana-app-arch -/src/plugins/share/ @elastic/kibana-app-arch -/examples/url_generators_examples/ @elastic/kibana-app-arch -/examples/url_generators_explorer/ @elastic/kibana-app-arch /x-pack/plugins/advanced_ui_actions/ @elastic/kibana-app-arch +/x-pack/plugins/data_enhanced/ @elastic/kibana-app-arch /x-pack/plugins/drilldowns/ @elastic/kibana-app-arch # APM @@ -75,9 +74,9 @@ # Observability UIs /x-pack/legacy/plugins/infra/ @elastic/logs-metrics-ui /x-pack/plugins/infra/ @elastic/logs-metrics-ui -/x-pack/plugins/ingest_manager/ @elastic/ingest -/x-pack/legacy/plugins/ingest_manager/ @elastic/ingest -/x-pack/plugins/observability/ @elastic/logs-metrics-ui @elastic/apm-ui @elastic/uptime @elastic/ingest +/x-pack/plugins/ingest_manager/ @elastic/ingest-management +/x-pack/legacy/plugins/ingest_manager/ @elastic/ingest-management +/x-pack/plugins/observability/ @elastic/logs-metrics-ui @elastic/apm-ui @elastic/uptime @elastic/ingest-management /x-pack/legacy/plugins/monitoring/ @elastic/stack-monitoring-ui # Machine Learning diff --git a/docs/development/core/public/kibana-plugin-core-public.chromestart.getiscollapsed_.md b/docs/development/core/public/kibana-plugin-core-public.chromestart.getisnavdrawerlocked_.md similarity index 51% rename from docs/development/core/public/kibana-plugin-core-public.chromestart.getiscollapsed_.md rename to docs/development/core/public/kibana-plugin-core-public.chromestart.getisnavdrawerlocked_.md index 205f863526e22..78a4442a651e6 100644 --- a/docs/development/core/public/kibana-plugin-core-public.chromestart.getiscollapsed_.md +++ b/docs/development/core/public/kibana-plugin-core-public.chromestart.getisnavdrawerlocked_.md @@ -1,15 +1,15 @@ -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ChromeStart](./kibana-plugin-core-public.chromestart.md) > [getIsCollapsed$](./kibana-plugin-core-public.chromestart.getiscollapsed_.md) +[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ChromeStart](./kibana-plugin-core-public.chromestart.md) > [getIsNavDrawerLocked$](./kibana-plugin-core-public.chromestart.getisnavdrawerlocked_.md) -## ChromeStart.getIsCollapsed$() method +## ChromeStart.getIsNavDrawerLocked$() method -Get an observable of the current collapsed state of the chrome. +Get an observable of the current locked state of the nav drawer. Signature: ```typescript -getIsCollapsed$(): Observable; +getIsNavDrawerLocked$(): Observable; ``` Returns: diff --git a/docs/development/core/public/kibana-plugin-core-public.chromestart.md b/docs/development/core/public/kibana-plugin-core-public.chromestart.md index 7d9d47df544d0..c179e089d7cfd 100644 --- a/docs/development/core/public/kibana-plugin-core-public.chromestart.md +++ b/docs/development/core/public/kibana-plugin-core-public.chromestart.md @@ -56,7 +56,7 @@ core.chrome.setHelpExtension(elem => { | [getBrand$()](./kibana-plugin-core-public.chromestart.getbrand_.md) | Get an observable of the current brand information. | | [getBreadcrumbs$()](./kibana-plugin-core-public.chromestart.getbreadcrumbs_.md) | Get an observable of the current list of breadcrumbs | | [getHelpExtension$()](./kibana-plugin-core-public.chromestart.gethelpextension_.md) | Get an observable of the current custom help conttent | -| [getIsCollapsed$()](./kibana-plugin-core-public.chromestart.getiscollapsed_.md) | Get an observable of the current collapsed state of the chrome. | +| [getIsNavDrawerLocked$()](./kibana-plugin-core-public.chromestart.getisnavdrawerlocked_.md) | Get an observable of the current locked state of the nav drawer. | | [getIsVisible$()](./kibana-plugin-core-public.chromestart.getisvisible_.md) | Get an observable of the current visibility state of the chrome. | | [removeApplicationClass(className)](./kibana-plugin-core-public.chromestart.removeapplicationclass.md) | Remove a className added with addApplicationClass(). If className is unknown it is ignored. | | [setAppTitle(appTitle)](./kibana-plugin-core-public.chromestart.setapptitle.md) | Sets the current app's title | @@ -65,6 +65,5 @@ core.chrome.setHelpExtension(elem => { | [setBreadcrumbs(newBreadcrumbs)](./kibana-plugin-core-public.chromestart.setbreadcrumbs.md) | Override the current set of breadcrumbs | | [setHelpExtension(helpExtension)](./kibana-plugin-core-public.chromestart.sethelpextension.md) | Override the current set of custom help content | | [setHelpSupportUrl(url)](./kibana-plugin-core-public.chromestart.sethelpsupporturl.md) | Override the default support URL shown in the help menu | -| [setIsCollapsed(isCollapsed)](./kibana-plugin-core-public.chromestart.setiscollapsed.md) | Set the collapsed state of the chrome navigation. | | [setIsVisible(isVisible)](./kibana-plugin-core-public.chromestart.setisvisible.md) | Set the temporary visibility for the chrome. This does nothing if the chrome is hidden by default and should be used to hide the chrome for things like full-screen modes with an exit button. | diff --git a/docs/development/core/public/kibana-plugin-core-public.chromestart.setiscollapsed.md b/docs/development/core/public/kibana-plugin-core-public.chromestart.setiscollapsed.md deleted file mode 100644 index b1843ef326d96..0000000000000 --- a/docs/development/core/public/kibana-plugin-core-public.chromestart.setiscollapsed.md +++ /dev/null @@ -1,24 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-core-public](./kibana-plugin-core-public.md) > [ChromeStart](./kibana-plugin-core-public.chromestart.md) > [setIsCollapsed](./kibana-plugin-core-public.chromestart.setiscollapsed.md) - -## ChromeStart.setIsCollapsed() method - -Set the collapsed state of the chrome navigation. - -Signature: - -```typescript -setIsCollapsed(isCollapsed: boolean): void; -``` - -## Parameters - -| Parameter | Type | Description | -| --- | --- | --- | -| isCollapsed | boolean | | - -Returns: - -`void` - diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.icancel.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.icancel.md deleted file mode 100644 index 27141c68ae1a7..0000000000000 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.icancel.md +++ /dev/null @@ -1,11 +0,0 @@ - - -[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ICancel](./kibana-plugin-plugins-data-server.icancel.md) - -## ICancel type - -Signature: - -```typescript -export declare type ICancel = (id: string) => Promise; -``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchcancel.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchcancel.md new file mode 100644 index 0000000000000..99c30515e8da6 --- /dev/null +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.isearchcancel.md @@ -0,0 +1,11 @@ + + +[Home](./index.md) > [kibana-plugin-plugins-data-server](./kibana-plugin-plugins-data-server.md) > [ISearchCancel](./kibana-plugin-plugins-data-server.isearchcancel.md) + +## ISearchCancel type + +Signature: + +```typescript +export declare type ISearchCancel = (id: string) => Promise; +``` diff --git a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md index 12d53f1a35ea0..e756eb9b72905 100644 --- a/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md +++ b/docs/development/plugins/data/server/kibana-plugin-plugins-data-server.md @@ -67,9 +67,9 @@ | Type Alias | Description | | --- | --- | | [FieldFormatsGetConfigFn](./kibana-plugin-plugins-data-server.fieldformatsgetconfigfn.md) | | -| [ICancel](./kibana-plugin-plugins-data-server.icancel.md) | | | [IFieldFormatsRegistry](./kibana-plugin-plugins-data-server.ifieldformatsregistry.md) | | | [ISearch](./kibana-plugin-plugins-data-server.isearch.md) | | +| [ISearchCancel](./kibana-plugin-plugins-data-server.isearchcancel.md) | | | [ParsedInterval](./kibana-plugin-plugins-data-server.parsedinterval.md) | | | [TSearchStrategyProvider](./kibana-plugin-plugins-data-server.tsearchstrategyprovider.md) | Search strategy provider creates an instance of a search strategy with the request handler context bound to it. This way every search strategy can use whatever information they require from the request context. | diff --git a/docs/settings/monitoring-settings.asciidoc b/docs/settings/monitoring-settings.asciidoc index 8586d26e9a07a..6645f49029a51 100644 --- a/docs/settings/monitoring-settings.asciidoc +++ b/docs/settings/monitoring-settings.asciidoc @@ -20,9 +20,7 @@ which support the same values as <>. To control how data is collected from your {es} nodes, you configure {ref}/monitoring-settings.html[`xpack.monitoring.collection` settings] in `elasticsearch.yml`. To control how monitoring data is collected -from Logstash, you configure -{logstash-ref}/monitoring-internal-collection.html#monitoring-settings[`xpack.monitoring` settings] -in `logstash.yml`. +from Logstash, configure monitoring settings in `logstash.yml`. For more information, see {ref}/monitor-elasticsearch-cluster.html[Monitor a cluster]. diff --git a/package.json b/package.json index 1e729ec19918f..0a85764b567b7 100644 --- a/package.json +++ b/package.json @@ -120,7 +120,7 @@ "@elastic/apm-rum": "^4.6.0", "@elastic/charts": "^17.1.1", "@elastic/datemath": "5.0.2", - "@elastic/ems-client": "7.6.0", + "@elastic/ems-client": "7.7.0", "@elastic/eui": "20.0.2", "@elastic/filesaver": "1.1.2", "@elastic/good": "8.1.1-kibana2", @@ -240,7 +240,7 @@ "react-resize-detector": "^4.2.0", "react-router-dom": "^5.1.2", "react-sizeme": "^2.3.6", - "react-use": "^13.13.0", + "react-use": "^13.27.0", "reactcss": "1.2.3", "redux": "^4.0.5", "redux-actions": "^2.6.5", diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 4afb15bf0180e..1cfaac39df9f4 100644 --- a/packages/kbn-pm/dist/index.js +++ b/packages/kbn-pm/dist/index.js @@ -94,7 +94,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _cli__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(1); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "run", function() { return _cli__WEBPACK_IMPORTED_MODULE_0__["run"]; }); -/* harmony import */ var _production__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(704); +/* harmony import */ var _production__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(705); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _production__WEBPACK_IMPORTED_MODULE_1__["buildProductionProjects"]; }); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return _production__WEBPACK_IMPORTED_MODULE_1__["prepareExternalProjectDependencies"]; }); @@ -57075,7 +57075,7 @@ async function getChangesForProjects(projects, kbn, log) { log.verbose('getting changed files'); const { stdout - } = await execa__WEBPACK_IMPORTED_MODULE_3___default()('git', ['ls-files', '-dmt', '--', ...Array.from(projects.values()).map(p => p.path)], { + } = await execa__WEBPACK_IMPORTED_MODULE_3___default()('git', ['ls-files', '-dmt', '--', ...Array.from(projects.values()).filter(p => kbn.isPartOfRepo(p)).map(p => p.path)], { cwd: kbn.getAbsolute() }); const output = stdout.trim(); @@ -57118,6 +57118,11 @@ async function getChangesForProjects(projects, kbn, log) { const changesByProject = new Map(); for (const project of sortedRelevantProjects) { + if (kbn.isOutsideRepo(project)) { + changesByProject.set(project, undefined); + continue; + } + const ownChanges = new Map(); const prefix = kbn.getRelative(project.path); @@ -57142,6 +57147,10 @@ async function getChangesForProjects(projects, kbn, log) { async function getLatestSha(project, kbn) { + if (kbn.isOutsideRepo(project)) { + return; + } + const { stdout } = await execa__WEBPACK_IMPORTED_MODULE_3___default()('git', ['log', '-n', '1', '--pretty=format:%H', '--', project.path], { @@ -57201,7 +57210,7 @@ async function getChecksum(project, changes, yarnLock, kbn, log) { log.verbose(`[${project.name}] local sha:`, sha); } - if (Array.from(changes.values()).includes('invalid')) { + if (!changes || Array.from(changes.values()).includes('invalid')) { log.warning(`[${project.name}] unable to determine local changes, caching disabled`); return; } @@ -79163,8 +79172,10 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(700); /* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(multimatch__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(501); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(579); +/* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(704); +/* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(is_path_inside__WEBPACK_IMPORTED_MODULE_2__); +/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(501); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(579); function ownKeys(object, enumerableOnly) { var keys = Object.keys(object); if (Object.getOwnPropertySymbols) { var symbols = Object.getOwnPropertySymbols(object); if (enumerableOnly) symbols = symbols.filter(function (sym) { return Object.getOwnPropertyDescriptor(object, sym).enumerable; }); keys.push.apply(keys, symbols); } return keys; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; if (i % 2) { ownKeys(source, true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(source).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } @@ -79193,6 +79204,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope + /** * Helper class for dealing with a set of projects as children of * the Kibana project. The kbn/pm is currently implemented to be @@ -79207,7 +79219,7 @@ function _defineProperty(obj, key, value) { if (key in obj) { Object.definePrope class Kibana { static async loadFrom(rootPath) { - return new Kibana((await Object(_projects__WEBPACK_IMPORTED_MODULE_2__["getProjects"])(rootPath, Object(_config__WEBPACK_IMPORTED_MODULE_3__["getProjectPaths"])({ + return new Kibana((await Object(_projects__WEBPACK_IMPORTED_MODULE_3__["getProjects"])(rootPath, Object(_config__WEBPACK_IMPORTED_MODULE_4__["getProjectPaths"])({ rootPath })))); } @@ -79266,7 +79278,7 @@ class Kibana { getProjectAndDeps(name) { const project = this.getProject(name); - return Object(_projects__WEBPACK_IMPORTED_MODULE_2__["includeTransitiveProjects"])([project], this.allWorkspaceProjects); + return Object(_projects__WEBPACK_IMPORTED_MODULE_3__["includeTransitiveProjects"])([project], this.allWorkspaceProjects); } /** filter the projects to just those matching certain paths/include/exclude tags */ @@ -79275,7 +79287,7 @@ class Kibana { const allProjects = this.getAllProjects(); const filteredProjects = new Map(); const pkgJsonPaths = Array.from(allProjects.values()).map(p => p.packageJsonLocation); - const filteredPkgJsonGlobs = Object(_config__WEBPACK_IMPORTED_MODULE_3__["getProjectPaths"])(_objectSpread({}, options, { + const filteredPkgJsonGlobs = Object(_config__WEBPACK_IMPORTED_MODULE_4__["getProjectPaths"])(_objectSpread({}, options, { rootPath: this.kibanaProject.path })).map(g => path__WEBPACK_IMPORTED_MODULE_0___default.a.resolve(g, 'package.json')); const matchingPkgJsonPaths = multimatch__WEBPACK_IMPORTED_MODULE_1___default()(pkgJsonPaths, filteredPkgJsonGlobs); @@ -79293,6 +79305,14 @@ class Kibana { return filteredProjects; } + isPartOfRepo(project) { + return project.path === this.kibanaProject.path || is_path_inside__WEBPACK_IMPORTED_MODULE_2___default()(project.path, this.kibanaProject.path); + } + + isOutsideRepo(project) { + return !this.isPartOfRepo(project); + } + } /***/ }), @@ -79386,14 +79406,42 @@ module.exports = arrify; /***/ }), /* 704 */ +/***/ (function(module, exports, __webpack_require__) { + +"use strict"; + +const path = __webpack_require__(16); + +module.exports = (childPath, parentPath) => { + childPath = path.resolve(childPath); + parentPath = path.resolve(parentPath); + + if (process.platform === 'win32') { + childPath = childPath.toLowerCase(); + parentPath = parentPath.toLowerCase(); + } + + if (childPath === parentPath) { + return false; + } + + childPath += path.sep; + parentPath += path.sep; + + return childPath.startsWith(parentPath); +}; + + +/***/ }), +/* 705 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(705); +/* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(706); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _build_production_projects__WEBPACK_IMPORTED_MODULE_0__["buildProductionProjects"]; }); -/* harmony import */ var _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(928); +/* harmony import */ var _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(929); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "prepareExternalProjectDependencies", function() { return _prepare_project_dependencies__WEBPACK_IMPORTED_MODULE_1__["prepareExternalProjectDependencies"]; }); /* @@ -79418,13 +79466,13 @@ __webpack_require__.r(__webpack_exports__); /***/ }), -/* 705 */ +/* 706 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return buildProductionProjects; }); -/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(706); +/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(707); /* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(cpy__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(587); /* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_1__); @@ -79566,7 +79614,7 @@ async function copyToBuild(project, kibanaRoot, buildRoot) { } /***/ }), -/* 706 */ +/* 707 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79574,13 +79622,13 @@ async function copyToBuild(project, kibanaRoot, buildRoot) { const EventEmitter = __webpack_require__(379); const path = __webpack_require__(16); const os = __webpack_require__(11); -const pAll = __webpack_require__(707); -const arrify = __webpack_require__(709); -const globby = __webpack_require__(710); +const pAll = __webpack_require__(708); +const arrify = __webpack_require__(710); +const globby = __webpack_require__(711); const isGlob = __webpack_require__(605); -const cpFile = __webpack_require__(913); -const junk = __webpack_require__(925); -const CpyError = __webpack_require__(926); +const cpFile = __webpack_require__(914); +const junk = __webpack_require__(926); +const CpyError = __webpack_require__(927); const defaultOptions = { ignoreJunk: true @@ -79699,12 +79747,12 @@ module.exports = (source, destination, { /***/ }), -/* 707 */ +/* 708 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pMap = __webpack_require__(708); +const pMap = __webpack_require__(709); module.exports = (iterable, options) => pMap(iterable, element => element(), options); // TODO: Remove this for the next major release @@ -79712,7 +79760,7 @@ module.exports.default = module.exports; /***/ }), -/* 708 */ +/* 709 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79791,7 +79839,7 @@ module.exports.default = pMap; /***/ }), -/* 709 */ +/* 710 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79821,17 +79869,17 @@ module.exports = arrify; /***/ }), -/* 710 */ +/* 711 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(23); -const arrayUnion = __webpack_require__(711); -const glob = __webpack_require__(713); -const fastGlob = __webpack_require__(718); -const dirGlob = __webpack_require__(906); -const gitignore = __webpack_require__(909); +const arrayUnion = __webpack_require__(712); +const glob = __webpack_require__(714); +const fastGlob = __webpack_require__(719); +const dirGlob = __webpack_require__(907); +const gitignore = __webpack_require__(910); const DEFAULT_FILTER = () => false; @@ -79976,12 +80024,12 @@ module.exports.gitignore = gitignore; /***/ }), -/* 711 */ +/* 712 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var arrayUniq = __webpack_require__(712); +var arrayUniq = __webpack_require__(713); module.exports = function () { return arrayUniq([].concat.apply([], arguments)); @@ -79989,7 +80037,7 @@ module.exports = function () { /***/ }), -/* 712 */ +/* 713 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80058,7 +80106,7 @@ if ('Set' in global) { /***/ }), -/* 713 */ +/* 714 */ /***/ (function(module, exports, __webpack_require__) { // Approach: @@ -80107,13 +80155,13 @@ var fs = __webpack_require__(23) var rp = __webpack_require__(503) var minimatch = __webpack_require__(505) var Minimatch = minimatch.Minimatch -var inherits = __webpack_require__(714) +var inherits = __webpack_require__(715) var EE = __webpack_require__(379).EventEmitter var path = __webpack_require__(16) var assert = __webpack_require__(30) var isAbsolute = __webpack_require__(511) -var globSync = __webpack_require__(716) -var common = __webpack_require__(717) +var globSync = __webpack_require__(717) +var common = __webpack_require__(718) var alphasort = common.alphasort var alphasorti = common.alphasorti var setopts = common.setopts @@ -80854,7 +80902,7 @@ Glob.prototype._stat2 = function (f, abs, er, stat, cb) { /***/ }), -/* 714 */ +/* 715 */ /***/ (function(module, exports, __webpack_require__) { try { @@ -80864,12 +80912,12 @@ try { module.exports = util.inherits; } catch (e) { /* istanbul ignore next */ - module.exports = __webpack_require__(715); + module.exports = __webpack_require__(716); } /***/ }), -/* 715 */ +/* 716 */ /***/ (function(module, exports) { if (typeof Object.create === 'function') { @@ -80902,7 +80950,7 @@ if (typeof Object.create === 'function') { /***/ }), -/* 716 */ +/* 717 */ /***/ (function(module, exports, __webpack_require__) { module.exports = globSync @@ -80912,12 +80960,12 @@ var fs = __webpack_require__(23) var rp = __webpack_require__(503) var minimatch = __webpack_require__(505) var Minimatch = minimatch.Minimatch -var Glob = __webpack_require__(713).Glob +var Glob = __webpack_require__(714).Glob var util = __webpack_require__(29) var path = __webpack_require__(16) var assert = __webpack_require__(30) var isAbsolute = __webpack_require__(511) -var common = __webpack_require__(717) +var common = __webpack_require__(718) var alphasort = common.alphasort var alphasorti = common.alphasorti var setopts = common.setopts @@ -81394,7 +81442,7 @@ GlobSync.prototype._makeAbs = function (f) { /***/ }), -/* 717 */ +/* 718 */ /***/ (function(module, exports, __webpack_require__) { exports.alphasort = alphasort @@ -81640,10 +81688,10 @@ function childrenIgnored (self, path) { /***/ }), -/* 718 */ +/* 719 */ /***/ (function(module, exports, __webpack_require__) { -const pkg = __webpack_require__(719); +const pkg = __webpack_require__(720); module.exports = pkg.async; module.exports.default = pkg.async; @@ -81656,19 +81704,19 @@ module.exports.generateTasks = pkg.generateTasks; /***/ }), -/* 719 */ +/* 720 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var optionsManager = __webpack_require__(720); -var taskManager = __webpack_require__(721); -var reader_async_1 = __webpack_require__(877); -var reader_stream_1 = __webpack_require__(901); -var reader_sync_1 = __webpack_require__(902); -var arrayUtils = __webpack_require__(904); -var streamUtils = __webpack_require__(905); +var optionsManager = __webpack_require__(721); +var taskManager = __webpack_require__(722); +var reader_async_1 = __webpack_require__(878); +var reader_stream_1 = __webpack_require__(902); +var reader_sync_1 = __webpack_require__(903); +var arrayUtils = __webpack_require__(905); +var streamUtils = __webpack_require__(906); /** * Synchronous API. */ @@ -81734,7 +81782,7 @@ function isString(source) { /***/ }), -/* 720 */ +/* 721 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81772,13 +81820,13 @@ exports.prepare = prepare; /***/ }), -/* 721 */ +/* 722 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var patternUtils = __webpack_require__(722); +var patternUtils = __webpack_require__(723); /** * Generate tasks based on parent directory of each pattern. */ @@ -81869,16 +81917,16 @@ exports.convertPatternGroupToTask = convertPatternGroupToTask; /***/ }), -/* 722 */ +/* 723 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path = __webpack_require__(16); -var globParent = __webpack_require__(723); -var isGlob = __webpack_require__(726); -var micromatch = __webpack_require__(727); +var globParent = __webpack_require__(724); +var isGlob = __webpack_require__(727); +var micromatch = __webpack_require__(728); var GLOBSTAR = '**'; /** * Return true for static pattern. @@ -82024,15 +82072,15 @@ exports.matchAny = matchAny; /***/ }), -/* 723 */ +/* 724 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var path = __webpack_require__(16); -var isglob = __webpack_require__(724); -var pathDirname = __webpack_require__(725); +var isglob = __webpack_require__(725); +var pathDirname = __webpack_require__(726); var isWin32 = __webpack_require__(11).platform() === 'win32'; module.exports = function globParent(str) { @@ -82055,7 +82103,7 @@ module.exports = function globParent(str) { /***/ }), -/* 724 */ +/* 725 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -82086,7 +82134,7 @@ module.exports = function isGlob(str) { /***/ }), -/* 725 */ +/* 726 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82236,7 +82284,7 @@ module.exports.win32 = win32; /***/ }), -/* 726 */ +/* 727 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -82288,7 +82336,7 @@ module.exports = function isGlob(str, options) { /***/ }), -/* 727 */ +/* 728 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82299,18 +82347,18 @@ module.exports = function isGlob(str, options) { */ var util = __webpack_require__(29); -var braces = __webpack_require__(728); -var toRegex = __webpack_require__(830); -var extend = __webpack_require__(838); +var braces = __webpack_require__(729); +var toRegex = __webpack_require__(831); +var extend = __webpack_require__(839); /** * Local dependencies */ -var compilers = __webpack_require__(841); -var parsers = __webpack_require__(873); -var cache = __webpack_require__(874); -var utils = __webpack_require__(875); +var compilers = __webpack_require__(842); +var parsers = __webpack_require__(874); +var cache = __webpack_require__(875); +var utils = __webpack_require__(876); var MAX_LENGTH = 1024 * 64; /** @@ -83172,7 +83220,7 @@ module.exports = micromatch; /***/ }), -/* 728 */ +/* 729 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83182,18 +83230,18 @@ module.exports = micromatch; * Module dependencies */ -var toRegex = __webpack_require__(729); -var unique = __webpack_require__(741); -var extend = __webpack_require__(738); +var toRegex = __webpack_require__(730); +var unique = __webpack_require__(742); +var extend = __webpack_require__(739); /** * Local dependencies */ -var compilers = __webpack_require__(742); -var parsers = __webpack_require__(757); -var Braces = __webpack_require__(767); -var utils = __webpack_require__(743); +var compilers = __webpack_require__(743); +var parsers = __webpack_require__(758); +var Braces = __webpack_require__(768); +var utils = __webpack_require__(744); var MAX_LENGTH = 1024 * 64; var cache = {}; @@ -83497,15 +83545,15 @@ module.exports = braces; /***/ }), -/* 729 */ +/* 730 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(730); -var extend = __webpack_require__(738); -var not = __webpack_require__(740); +var define = __webpack_require__(731); +var extend = __webpack_require__(739); +var not = __webpack_require__(741); var MAX_LENGTH = 1024 * 64; /** @@ -83652,7 +83700,7 @@ module.exports.makeRe = makeRe; /***/ }), -/* 730 */ +/* 731 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83665,7 +83713,7 @@ module.exports.makeRe = makeRe; -var isDescriptor = __webpack_require__(731); +var isDescriptor = __webpack_require__(732); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -83690,7 +83738,7 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 731 */ +/* 732 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83703,9 +83751,9 @@ module.exports = function defineProperty(obj, prop, val) { -var typeOf = __webpack_require__(732); -var isAccessor = __webpack_require__(733); -var isData = __webpack_require__(736); +var typeOf = __webpack_require__(733); +var isAccessor = __webpack_require__(734); +var isData = __webpack_require__(737); module.exports = function isDescriptor(obj, key) { if (typeOf(obj) !== 'object') { @@ -83719,7 +83767,7 @@ module.exports = function isDescriptor(obj, key) { /***/ }), -/* 732 */ +/* 733 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -83872,7 +83920,7 @@ function isBuffer(val) { /***/ }), -/* 733 */ +/* 734 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83885,7 +83933,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(734); +var typeOf = __webpack_require__(735); // accessor descriptor properties var accessor = { @@ -83948,10 +83996,10 @@ module.exports = isAccessorDescriptor; /***/ }), -/* 734 */ +/* 735 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(735); +var isBuffer = __webpack_require__(736); var toString = Object.prototype.toString; /** @@ -84070,7 +84118,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 735 */ +/* 736 */ /***/ (function(module, exports) { /*! @@ -84097,7 +84145,7 @@ function isSlowBuffer (obj) { /***/ }), -/* 736 */ +/* 737 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84110,7 +84158,7 @@ function isSlowBuffer (obj) { -var typeOf = __webpack_require__(737); +var typeOf = __webpack_require__(738); // data descriptor properties var data = { @@ -84159,10 +84207,10 @@ module.exports = isDataDescriptor; /***/ }), -/* 737 */ +/* 738 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(735); +var isBuffer = __webpack_require__(736); var toString = Object.prototype.toString; /** @@ -84281,13 +84329,13 @@ module.exports = function kindOf(val) { /***/ }), -/* 738 */ +/* 739 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(739); +var isObject = __webpack_require__(740); module.exports = function extend(o/*, objects*/) { if (!isObject(o)) { o = {}; } @@ -84321,7 +84369,7 @@ function hasOwn(obj, key) { /***/ }), -/* 739 */ +/* 740 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84341,13 +84389,13 @@ module.exports = function isExtendable(val) { /***/ }), -/* 740 */ +/* 741 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(738); +var extend = __webpack_require__(739); /** * The main export is a function that takes a `pattern` string and an `options` object. @@ -84414,7 +84462,7 @@ module.exports = toRegex; /***/ }), -/* 741 */ +/* 742 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84464,13 +84512,13 @@ module.exports.immutable = function uniqueImmutable(arr) { /***/ }), -/* 742 */ +/* 743 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(743); +var utils = __webpack_require__(744); module.exports = function(braces, options) { braces.compiler @@ -84753,25 +84801,25 @@ function hasQueue(node) { /***/ }), -/* 743 */ +/* 744 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var splitString = __webpack_require__(744); +var splitString = __webpack_require__(745); var utils = module.exports; /** * Module dependencies */ -utils.extend = __webpack_require__(738); -utils.flatten = __webpack_require__(750); -utils.isObject = __webpack_require__(748); -utils.fillRange = __webpack_require__(751); -utils.repeat = __webpack_require__(756); -utils.unique = __webpack_require__(741); +utils.extend = __webpack_require__(739); +utils.flatten = __webpack_require__(751); +utils.isObject = __webpack_require__(749); +utils.fillRange = __webpack_require__(752); +utils.repeat = __webpack_require__(757); +utils.unique = __webpack_require__(742); utils.define = function(obj, key, val) { Object.defineProperty(obj, key, { @@ -85103,7 +85151,7 @@ utils.escapeRegex = function(str) { /***/ }), -/* 744 */ +/* 745 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85116,7 +85164,7 @@ utils.escapeRegex = function(str) { -var extend = __webpack_require__(745); +var extend = __webpack_require__(746); module.exports = function(str, options, fn) { if (typeof str !== 'string') { @@ -85281,14 +85329,14 @@ function keepEscaping(opts, str, idx) { /***/ }), -/* 745 */ +/* 746 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(746); -var assignSymbols = __webpack_require__(749); +var isExtendable = __webpack_require__(747); +var assignSymbols = __webpack_require__(750); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -85348,7 +85396,7 @@ function isEnum(obj, key) { /***/ }), -/* 746 */ +/* 747 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85361,7 +85409,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(747); +var isPlainObject = __webpack_require__(748); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -85369,7 +85417,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 747 */ +/* 748 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85382,7 +85430,7 @@ module.exports = function isExtendable(val) { -var isObject = __webpack_require__(748); +var isObject = __webpack_require__(749); function isObjectObject(o) { return isObject(o) === true @@ -85413,7 +85461,7 @@ module.exports = function isPlainObject(o) { /***/ }), -/* 748 */ +/* 749 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85432,7 +85480,7 @@ module.exports = function isObject(val) { /***/ }), -/* 749 */ +/* 750 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85479,7 +85527,7 @@ module.exports = function(receiver, objects) { /***/ }), -/* 750 */ +/* 751 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85508,7 +85556,7 @@ function flat(arr, res) { /***/ }), -/* 751 */ +/* 752 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85522,10 +85570,10 @@ function flat(arr, res) { var util = __webpack_require__(29); -var isNumber = __webpack_require__(752); -var extend = __webpack_require__(738); -var repeat = __webpack_require__(754); -var toRegex = __webpack_require__(755); +var isNumber = __webpack_require__(753); +var extend = __webpack_require__(739); +var repeat = __webpack_require__(755); +var toRegex = __webpack_require__(756); /** * Return a range of numbers or letters. @@ -85723,7 +85771,7 @@ module.exports = fillRange; /***/ }), -/* 752 */ +/* 753 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85736,7 +85784,7 @@ module.exports = fillRange; -var typeOf = __webpack_require__(753); +var typeOf = __webpack_require__(754); module.exports = function isNumber(num) { var type = typeOf(num); @@ -85752,10 +85800,10 @@ module.exports = function isNumber(num) { /***/ }), -/* 753 */ +/* 754 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(735); +var isBuffer = __webpack_require__(736); var toString = Object.prototype.toString; /** @@ -85874,7 +85922,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 754 */ +/* 755 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85951,7 +85999,7 @@ function repeat(str, num) { /***/ }), -/* 755 */ +/* 756 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85964,8 +86012,8 @@ function repeat(str, num) { -var repeat = __webpack_require__(754); -var isNumber = __webpack_require__(752); +var repeat = __webpack_require__(755); +var isNumber = __webpack_require__(753); var cache = {}; function toRegexRange(min, max, options) { @@ -86252,7 +86300,7 @@ module.exports = toRegexRange; /***/ }), -/* 756 */ +/* 757 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -86277,14 +86325,14 @@ module.exports = function repeat(ele, num) { /***/ }), -/* 757 */ +/* 758 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var Node = __webpack_require__(758); -var utils = __webpack_require__(743); +var Node = __webpack_require__(759); +var utils = __webpack_require__(744); /** * Braces parsers @@ -86644,15 +86692,15 @@ function concatNodes(pos, node, parent, options) { /***/ }), -/* 758 */ +/* 759 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(748); -var define = __webpack_require__(759); -var utils = __webpack_require__(766); +var isObject = __webpack_require__(749); +var define = __webpack_require__(760); +var utils = __webpack_require__(767); var ownNames; /** @@ -87143,7 +87191,7 @@ exports = module.exports = Node; /***/ }), -/* 759 */ +/* 760 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -87156,7 +87204,7 @@ exports = module.exports = Node; -var isDescriptor = __webpack_require__(760); +var isDescriptor = __webpack_require__(761); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -87181,7 +87229,7 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 760 */ +/* 761 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -87194,9 +87242,9 @@ module.exports = function defineProperty(obj, prop, val) { -var typeOf = __webpack_require__(761); -var isAccessor = __webpack_require__(762); -var isData = __webpack_require__(764); +var typeOf = __webpack_require__(762); +var isAccessor = __webpack_require__(763); +var isData = __webpack_require__(765); module.exports = function isDescriptor(obj, key) { if (typeOf(obj) !== 'object') { @@ -87210,7 +87258,7 @@ module.exports = function isDescriptor(obj, key) { /***/ }), -/* 761 */ +/* 762 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -87345,7 +87393,7 @@ function isBuffer(val) { /***/ }), -/* 762 */ +/* 763 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -87358,7 +87406,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(763); +var typeOf = __webpack_require__(764); // accessor descriptor properties var accessor = { @@ -87421,7 +87469,7 @@ module.exports = isAccessorDescriptor; /***/ }), -/* 763 */ +/* 764 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -87556,7 +87604,7 @@ function isBuffer(val) { /***/ }), -/* 764 */ +/* 765 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -87569,7 +87617,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(765); +var typeOf = __webpack_require__(766); module.exports = function isDataDescriptor(obj, prop) { // data descriptor properties @@ -87612,7 +87660,7 @@ module.exports = function isDataDescriptor(obj, prop) { /***/ }), -/* 765 */ +/* 766 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -87747,13 +87795,13 @@ function isBuffer(val) { /***/ }), -/* 766 */ +/* 767 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var typeOf = __webpack_require__(753); +var typeOf = __webpack_require__(754); var utils = module.exports; /** @@ -88773,17 +88821,17 @@ function assert(val, message) { /***/ }), -/* 767 */ +/* 768 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(738); -var Snapdragon = __webpack_require__(768); -var compilers = __webpack_require__(742); -var parsers = __webpack_require__(757); -var utils = __webpack_require__(743); +var extend = __webpack_require__(739); +var Snapdragon = __webpack_require__(769); +var compilers = __webpack_require__(743); +var parsers = __webpack_require__(758); +var utils = __webpack_require__(744); /** * Customize Snapdragon parser and renderer @@ -88884,17 +88932,17 @@ module.exports = Braces; /***/ }), -/* 768 */ +/* 769 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var Base = __webpack_require__(769); -var define = __webpack_require__(730); -var Compiler = __webpack_require__(798); -var Parser = __webpack_require__(827); -var utils = __webpack_require__(807); +var Base = __webpack_require__(770); +var define = __webpack_require__(731); +var Compiler = __webpack_require__(799); +var Parser = __webpack_require__(828); +var utils = __webpack_require__(808); var regexCache = {}; var cache = {}; @@ -89065,20 +89113,20 @@ module.exports.Parser = Parser; /***/ }), -/* 769 */ +/* 770 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(29); -var define = __webpack_require__(770); -var CacheBase = __webpack_require__(771); -var Emitter = __webpack_require__(772); -var isObject = __webpack_require__(748); -var merge = __webpack_require__(789); -var pascal = __webpack_require__(792); -var cu = __webpack_require__(793); +var define = __webpack_require__(771); +var CacheBase = __webpack_require__(772); +var Emitter = __webpack_require__(773); +var isObject = __webpack_require__(749); +var merge = __webpack_require__(790); +var pascal = __webpack_require__(793); +var cu = __webpack_require__(794); /** * Optionally define a custom `cache` namespace to use. @@ -89507,7 +89555,7 @@ module.exports.namespace = namespace; /***/ }), -/* 770 */ +/* 771 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -89520,7 +89568,7 @@ module.exports.namespace = namespace; -var isDescriptor = __webpack_require__(760); +var isDescriptor = __webpack_require__(761); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -89545,21 +89593,21 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 771 */ +/* 772 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(748); -var Emitter = __webpack_require__(772); -var visit = __webpack_require__(773); -var toPath = __webpack_require__(776); -var union = __webpack_require__(777); -var del = __webpack_require__(781); -var get = __webpack_require__(779); -var has = __webpack_require__(786); -var set = __webpack_require__(780); +var isObject = __webpack_require__(749); +var Emitter = __webpack_require__(773); +var visit = __webpack_require__(774); +var toPath = __webpack_require__(777); +var union = __webpack_require__(778); +var del = __webpack_require__(782); +var get = __webpack_require__(780); +var has = __webpack_require__(787); +var set = __webpack_require__(781); /** * Create a `Cache` constructor that when instantiated will @@ -89813,7 +89861,7 @@ module.exports.namespace = namespace; /***/ }), -/* 772 */ +/* 773 */ /***/ (function(module, exports, __webpack_require__) { @@ -89982,7 +90030,7 @@ Emitter.prototype.hasListeners = function(event){ /***/ }), -/* 773 */ +/* 774 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -89995,8 +90043,8 @@ Emitter.prototype.hasListeners = function(event){ -var visit = __webpack_require__(774); -var mapVisit = __webpack_require__(775); +var visit = __webpack_require__(775); +var mapVisit = __webpack_require__(776); module.exports = function(collection, method, val) { var result; @@ -90019,7 +90067,7 @@ module.exports = function(collection, method, val) { /***/ }), -/* 774 */ +/* 775 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90032,7 +90080,7 @@ module.exports = function(collection, method, val) { -var isObject = __webpack_require__(748); +var isObject = __webpack_require__(749); module.exports = function visit(thisArg, method, target, val) { if (!isObject(thisArg) && typeof thisArg !== 'function') { @@ -90059,14 +90107,14 @@ module.exports = function visit(thisArg, method, target, val) { /***/ }), -/* 775 */ +/* 776 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(29); -var visit = __webpack_require__(774); +var visit = __webpack_require__(775); /** * Map `visit` over an array of objects. @@ -90103,7 +90151,7 @@ function isObject(val) { /***/ }), -/* 776 */ +/* 777 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90116,7 +90164,7 @@ function isObject(val) { -var typeOf = __webpack_require__(753); +var typeOf = __webpack_require__(754); module.exports = function toPath(args) { if (typeOf(args) !== 'arguments') { @@ -90143,16 +90191,16 @@ function filter(arr) { /***/ }), -/* 777 */ +/* 778 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(739); -var union = __webpack_require__(778); -var get = __webpack_require__(779); -var set = __webpack_require__(780); +var isObject = __webpack_require__(740); +var union = __webpack_require__(779); +var get = __webpack_require__(780); +var set = __webpack_require__(781); module.exports = function unionValue(obj, prop, value) { if (!isObject(obj)) { @@ -90180,7 +90228,7 @@ function arrayify(val) { /***/ }), -/* 778 */ +/* 779 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90216,7 +90264,7 @@ module.exports = function union(init) { /***/ }), -/* 779 */ +/* 780 */ /***/ (function(module, exports) { /*! @@ -90272,7 +90320,7 @@ function toString(val) { /***/ }), -/* 780 */ +/* 781 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90285,10 +90333,10 @@ function toString(val) { -var split = __webpack_require__(744); -var extend = __webpack_require__(738); -var isPlainObject = __webpack_require__(747); -var isObject = __webpack_require__(739); +var split = __webpack_require__(745); +var extend = __webpack_require__(739); +var isPlainObject = __webpack_require__(748); +var isObject = __webpack_require__(740); module.exports = function(obj, prop, val) { if (!isObject(obj)) { @@ -90334,7 +90382,7 @@ function isValidKey(key) { /***/ }), -/* 781 */ +/* 782 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90347,8 +90395,8 @@ function isValidKey(key) { -var isObject = __webpack_require__(748); -var has = __webpack_require__(782); +var isObject = __webpack_require__(749); +var has = __webpack_require__(783); module.exports = function unset(obj, prop) { if (!isObject(obj)) { @@ -90373,7 +90421,7 @@ module.exports = function unset(obj, prop) { /***/ }), -/* 782 */ +/* 783 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90386,9 +90434,9 @@ module.exports = function unset(obj, prop) { -var isObject = __webpack_require__(783); -var hasValues = __webpack_require__(785); -var get = __webpack_require__(779); +var isObject = __webpack_require__(784); +var hasValues = __webpack_require__(786); +var get = __webpack_require__(780); module.exports = function(obj, prop, noZero) { if (isObject(obj)) { @@ -90399,7 +90447,7 @@ module.exports = function(obj, prop, noZero) { /***/ }), -/* 783 */ +/* 784 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90412,7 +90460,7 @@ module.exports = function(obj, prop, noZero) { -var isArray = __webpack_require__(784); +var isArray = __webpack_require__(785); module.exports = function isObject(val) { return val != null && typeof val === 'object' && isArray(val) === false; @@ -90420,7 +90468,7 @@ module.exports = function isObject(val) { /***/ }), -/* 784 */ +/* 785 */ /***/ (function(module, exports) { var toString = {}.toString; @@ -90431,7 +90479,7 @@ module.exports = Array.isArray || function (arr) { /***/ }), -/* 785 */ +/* 786 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90474,7 +90522,7 @@ module.exports = function hasValue(o, noZero) { /***/ }), -/* 786 */ +/* 787 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90487,9 +90535,9 @@ module.exports = function hasValue(o, noZero) { -var isObject = __webpack_require__(748); -var hasValues = __webpack_require__(787); -var get = __webpack_require__(779); +var isObject = __webpack_require__(749); +var hasValues = __webpack_require__(788); +var get = __webpack_require__(780); module.exports = function(val, prop) { return hasValues(isObject(val) && prop ? get(val, prop) : val); @@ -90497,7 +90545,7 @@ module.exports = function(val, prop) { /***/ }), -/* 787 */ +/* 788 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90510,8 +90558,8 @@ module.exports = function(val, prop) { -var typeOf = __webpack_require__(788); -var isNumber = __webpack_require__(752); +var typeOf = __webpack_require__(789); +var isNumber = __webpack_require__(753); module.exports = function hasValue(val) { // is-number checks for NaN and other edge cases @@ -90564,10 +90612,10 @@ module.exports = function hasValue(val) { /***/ }), -/* 788 */ +/* 789 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(735); +var isBuffer = __webpack_require__(736); var toString = Object.prototype.toString; /** @@ -90689,14 +90737,14 @@ module.exports = function kindOf(val) { /***/ }), -/* 789 */ +/* 790 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(790); -var forIn = __webpack_require__(791); +var isExtendable = __webpack_require__(791); +var forIn = __webpack_require__(792); function mixinDeep(target, objects) { var len = arguments.length, i = 0; @@ -90760,7 +90808,7 @@ module.exports = mixinDeep; /***/ }), -/* 790 */ +/* 791 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90773,7 +90821,7 @@ module.exports = mixinDeep; -var isPlainObject = __webpack_require__(747); +var isPlainObject = __webpack_require__(748); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -90781,7 +90829,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 791 */ +/* 792 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -90804,7 +90852,7 @@ module.exports = function forIn(obj, fn, thisArg) { /***/ }), -/* 792 */ +/* 793 */ /***/ (function(module, exports) { /*! @@ -90831,14 +90879,14 @@ module.exports = pascalcase; /***/ }), -/* 793 */ +/* 794 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(29); -var utils = __webpack_require__(794); +var utils = __webpack_require__(795); /** * Expose class utils @@ -91203,7 +91251,7 @@ cu.bubble = function(Parent, events) { /***/ }), -/* 794 */ +/* 795 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -91217,10 +91265,10 @@ var utils = {}; * Lazily required module dependencies */ -utils.union = __webpack_require__(778); -utils.define = __webpack_require__(730); -utils.isObj = __webpack_require__(748); -utils.staticExtend = __webpack_require__(795); +utils.union = __webpack_require__(779); +utils.define = __webpack_require__(731); +utils.isObj = __webpack_require__(749); +utils.staticExtend = __webpack_require__(796); /** @@ -91231,7 +91279,7 @@ module.exports = utils; /***/ }), -/* 795 */ +/* 796 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -91244,8 +91292,8 @@ module.exports = utils; -var copy = __webpack_require__(796); -var define = __webpack_require__(730); +var copy = __webpack_require__(797); +var define = __webpack_require__(731); var util = __webpack_require__(29); /** @@ -91328,15 +91376,15 @@ module.exports = extend; /***/ }), -/* 796 */ +/* 797 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var typeOf = __webpack_require__(753); -var copyDescriptor = __webpack_require__(797); -var define = __webpack_require__(730); +var typeOf = __webpack_require__(754); +var copyDescriptor = __webpack_require__(798); +var define = __webpack_require__(731); /** * Copy static properties, prototype properties, and descriptors from one object to another. @@ -91509,7 +91557,7 @@ module.exports.has = has; /***/ }), -/* 797 */ +/* 798 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -91597,16 +91645,16 @@ function isObject(val) { /***/ }), -/* 798 */ +/* 799 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(799); -var define = __webpack_require__(730); -var debug = __webpack_require__(801)('snapdragon:compiler'); -var utils = __webpack_require__(807); +var use = __webpack_require__(800); +var define = __webpack_require__(731); +var debug = __webpack_require__(802)('snapdragon:compiler'); +var utils = __webpack_require__(808); /** * Create a new `Compiler` with the given `options`. @@ -91760,7 +91808,7 @@ Compiler.prototype = { // source map support if (opts.sourcemap) { - var sourcemaps = __webpack_require__(826); + var sourcemaps = __webpack_require__(827); sourcemaps(this); this.mapVisit(this.ast.nodes); this.applySourceMaps(); @@ -91781,7 +91829,7 @@ module.exports = Compiler; /***/ }), -/* 799 */ +/* 800 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -91794,7 +91842,7 @@ module.exports = Compiler; -var utils = __webpack_require__(800); +var utils = __webpack_require__(801); module.exports = function base(app, opts) { if (!utils.isObject(app) && typeof app !== 'function') { @@ -91909,7 +91957,7 @@ module.exports = function base(app, opts) { /***/ }), -/* 800 */ +/* 801 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -91923,8 +91971,8 @@ var utils = {}; * Lazily required module dependencies */ -utils.define = __webpack_require__(730); -utils.isObject = __webpack_require__(748); +utils.define = __webpack_require__(731); +utils.isObject = __webpack_require__(749); utils.isString = function(val) { @@ -91939,7 +91987,7 @@ module.exports = utils; /***/ }), -/* 801 */ +/* 802 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -91948,14 +91996,14 @@ module.exports = utils; */ if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(802); + module.exports = __webpack_require__(803); } else { - module.exports = __webpack_require__(805); + module.exports = __webpack_require__(806); } /***/ }), -/* 802 */ +/* 803 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -91964,7 +92012,7 @@ if (typeof process !== 'undefined' && process.type === 'renderer') { * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(803); +exports = module.exports = __webpack_require__(804); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; @@ -92146,7 +92194,7 @@ function localstorage() { /***/ }), -/* 803 */ +/* 804 */ /***/ (function(module, exports, __webpack_require__) { @@ -92162,7 +92210,7 @@ exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; -exports.humanize = __webpack_require__(804); +exports.humanize = __webpack_require__(805); /** * The currently active debug mode names, and names to skip. @@ -92354,7 +92402,7 @@ function coerce(val) { /***/ }), -/* 804 */ +/* 805 */ /***/ (function(module, exports) { /** @@ -92512,7 +92560,7 @@ function plural(ms, n, name) { /***/ }), -/* 805 */ +/* 806 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -92528,7 +92576,7 @@ var util = __webpack_require__(29); * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(803); +exports = module.exports = __webpack_require__(804); exports.init = init; exports.log = log; exports.formatArgs = formatArgs; @@ -92707,7 +92755,7 @@ function createWritableStdioStream (fd) { case 'PIPE': case 'TCP': - var net = __webpack_require__(806); + var net = __webpack_require__(807); stream = new net.Socket({ fd: fd, readable: false, @@ -92766,13 +92814,13 @@ exports.enable(load()); /***/ }), -/* 806 */ +/* 807 */ /***/ (function(module, exports) { module.exports = require("net"); /***/ }), -/* 807 */ +/* 808 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -92782,9 +92830,9 @@ module.exports = require("net"); * Module dependencies */ -exports.extend = __webpack_require__(738); -exports.SourceMap = __webpack_require__(808); -exports.sourceMapResolve = __webpack_require__(819); +exports.extend = __webpack_require__(739); +exports.SourceMap = __webpack_require__(809); +exports.sourceMapResolve = __webpack_require__(820); /** * Convert backslash in the given string to forward slashes @@ -92827,7 +92875,7 @@ exports.last = function(arr, n) { /***/ }), -/* 808 */ +/* 809 */ /***/ (function(module, exports, __webpack_require__) { /* @@ -92835,13 +92883,13 @@ exports.last = function(arr, n) { * Licensed under the New BSD license. See LICENSE.txt or: * http://opensource.org/licenses/BSD-3-Clause */ -exports.SourceMapGenerator = __webpack_require__(809).SourceMapGenerator; -exports.SourceMapConsumer = __webpack_require__(815).SourceMapConsumer; -exports.SourceNode = __webpack_require__(818).SourceNode; +exports.SourceMapGenerator = __webpack_require__(810).SourceMapGenerator; +exports.SourceMapConsumer = __webpack_require__(816).SourceMapConsumer; +exports.SourceNode = __webpack_require__(819).SourceNode; /***/ }), -/* 809 */ +/* 810 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -92851,10 +92899,10 @@ exports.SourceNode = __webpack_require__(818).SourceNode; * http://opensource.org/licenses/BSD-3-Clause */ -var base64VLQ = __webpack_require__(810); -var util = __webpack_require__(812); -var ArraySet = __webpack_require__(813).ArraySet; -var MappingList = __webpack_require__(814).MappingList; +var base64VLQ = __webpack_require__(811); +var util = __webpack_require__(813); +var ArraySet = __webpack_require__(814).ArraySet; +var MappingList = __webpack_require__(815).MappingList; /** * An instance of the SourceMapGenerator represents a source map which is @@ -93263,7 +93311,7 @@ exports.SourceMapGenerator = SourceMapGenerator; /***/ }), -/* 810 */ +/* 811 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -93303,7 +93351,7 @@ exports.SourceMapGenerator = SourceMapGenerator; * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -var base64 = __webpack_require__(811); +var base64 = __webpack_require__(812); // A single base 64 digit can contain 6 bits of data. For the base 64 variable // length quantities we use in the source map spec, the first bit is the sign, @@ -93409,7 +93457,7 @@ exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { /***/ }), -/* 811 */ +/* 812 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -93482,7 +93530,7 @@ exports.decode = function (charCode) { /***/ }), -/* 812 */ +/* 813 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -93905,7 +93953,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate /***/ }), -/* 813 */ +/* 814 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -93915,7 +93963,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(812); +var util = __webpack_require__(813); var has = Object.prototype.hasOwnProperty; var hasNativeMap = typeof Map !== "undefined"; @@ -94032,7 +94080,7 @@ exports.ArraySet = ArraySet; /***/ }), -/* 814 */ +/* 815 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -94042,7 +94090,7 @@ exports.ArraySet = ArraySet; * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(812); +var util = __webpack_require__(813); /** * Determine whether mappingB is after mappingA with respect to generated @@ -94117,7 +94165,7 @@ exports.MappingList = MappingList; /***/ }), -/* 815 */ +/* 816 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -94127,11 +94175,11 @@ exports.MappingList = MappingList; * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(812); -var binarySearch = __webpack_require__(816); -var ArraySet = __webpack_require__(813).ArraySet; -var base64VLQ = __webpack_require__(810); -var quickSort = __webpack_require__(817).quickSort; +var util = __webpack_require__(813); +var binarySearch = __webpack_require__(817); +var ArraySet = __webpack_require__(814).ArraySet; +var base64VLQ = __webpack_require__(811); +var quickSort = __webpack_require__(818).quickSort; function SourceMapConsumer(aSourceMap) { var sourceMap = aSourceMap; @@ -95205,7 +95253,7 @@ exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; /***/ }), -/* 816 */ +/* 817 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -95322,7 +95370,7 @@ exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { /***/ }), -/* 817 */ +/* 818 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -95442,7 +95490,7 @@ exports.quickSort = function (ary, comparator) { /***/ }), -/* 818 */ +/* 819 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -95452,8 +95500,8 @@ exports.quickSort = function (ary, comparator) { * http://opensource.org/licenses/BSD-3-Clause */ -var SourceMapGenerator = __webpack_require__(809).SourceMapGenerator; -var util = __webpack_require__(812); +var SourceMapGenerator = __webpack_require__(810).SourceMapGenerator; +var util = __webpack_require__(813); // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other // operating systems these days (capturing the result). @@ -95861,17 +95909,17 @@ exports.SourceNode = SourceNode; /***/ }), -/* 819 */ +/* 820 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014, 2015, 2016, 2017 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var sourceMappingURL = __webpack_require__(820) -var resolveUrl = __webpack_require__(821) -var decodeUriComponent = __webpack_require__(822) -var urix = __webpack_require__(824) -var atob = __webpack_require__(825) +var sourceMappingURL = __webpack_require__(821) +var resolveUrl = __webpack_require__(822) +var decodeUriComponent = __webpack_require__(823) +var urix = __webpack_require__(825) +var atob = __webpack_require__(826) @@ -96169,7 +96217,7 @@ module.exports = { /***/ }), -/* 820 */ +/* 821 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;// Copyright 2014 Simon Lydell @@ -96232,7 +96280,7 @@ void (function(root, factory) { /***/ }), -/* 821 */ +/* 822 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014 Simon Lydell @@ -96250,13 +96298,13 @@ module.exports = resolveUrl /***/ }), -/* 822 */ +/* 823 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2017 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var decodeUriComponent = __webpack_require__(823) +var decodeUriComponent = __webpack_require__(824) function customDecodeUriComponent(string) { // `decodeUriComponent` turns `+` into ` `, but that's not wanted. @@ -96267,7 +96315,7 @@ module.exports = customDecodeUriComponent /***/ }), -/* 823 */ +/* 824 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -96368,7 +96416,7 @@ module.exports = function (encodedURI) { /***/ }), -/* 824 */ +/* 825 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014 Simon Lydell @@ -96391,7 +96439,7 @@ module.exports = urix /***/ }), -/* 825 */ +/* 826 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -96405,7 +96453,7 @@ module.exports = atob.atob = atob; /***/ }), -/* 826 */ +/* 827 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -96413,8 +96461,8 @@ module.exports = atob.atob = atob; var fs = __webpack_require__(23); var path = __webpack_require__(16); -var define = __webpack_require__(730); -var utils = __webpack_require__(807); +var define = __webpack_require__(731); +var utils = __webpack_require__(808); /** * Expose `mixin()`. @@ -96557,19 +96605,19 @@ exports.comment = function(node) { /***/ }), -/* 827 */ +/* 828 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(799); +var use = __webpack_require__(800); var util = __webpack_require__(29); -var Cache = __webpack_require__(828); -var define = __webpack_require__(730); -var debug = __webpack_require__(801)('snapdragon:parser'); -var Position = __webpack_require__(829); -var utils = __webpack_require__(807); +var Cache = __webpack_require__(829); +var define = __webpack_require__(731); +var debug = __webpack_require__(802)('snapdragon:parser'); +var Position = __webpack_require__(830); +var utils = __webpack_require__(808); /** * Create a new `Parser` with the given `input` and `options`. @@ -97097,7 +97145,7 @@ module.exports = Parser; /***/ }), -/* 828 */ +/* 829 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -97204,13 +97252,13 @@ MapCache.prototype.del = function mapDelete(key) { /***/ }), -/* 829 */ +/* 830 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(730); +var define = __webpack_require__(731); /** * Store position for a node @@ -97225,16 +97273,16 @@ module.exports = function Position(start, parser) { /***/ }), -/* 830 */ +/* 831 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var safe = __webpack_require__(831); -var define = __webpack_require__(837); -var extend = __webpack_require__(838); -var not = __webpack_require__(840); +var safe = __webpack_require__(832); +var define = __webpack_require__(838); +var extend = __webpack_require__(839); +var not = __webpack_require__(841); var MAX_LENGTH = 1024 * 64; /** @@ -97387,10 +97435,10 @@ module.exports.makeRe = makeRe; /***/ }), -/* 831 */ +/* 832 */ /***/ (function(module, exports, __webpack_require__) { -var parse = __webpack_require__(832); +var parse = __webpack_require__(833); var types = parse.types; module.exports = function (re, opts) { @@ -97436,13 +97484,13 @@ function isRegExp (x) { /***/ }), -/* 832 */ +/* 833 */ /***/ (function(module, exports, __webpack_require__) { -var util = __webpack_require__(833); -var types = __webpack_require__(834); -var sets = __webpack_require__(835); -var positions = __webpack_require__(836); +var util = __webpack_require__(834); +var types = __webpack_require__(835); +var sets = __webpack_require__(836); +var positions = __webpack_require__(837); module.exports = function(regexpStr) { @@ -97724,11 +97772,11 @@ module.exports.types = types; /***/ }), -/* 833 */ +/* 834 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(834); -var sets = __webpack_require__(835); +var types = __webpack_require__(835); +var sets = __webpack_require__(836); // All of these are private and only used by randexp. @@ -97841,7 +97889,7 @@ exports.error = function(regexp, msg) { /***/ }), -/* 834 */ +/* 835 */ /***/ (function(module, exports) { module.exports = { @@ -97857,10 +97905,10 @@ module.exports = { /***/ }), -/* 835 */ +/* 836 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(834); +var types = __webpack_require__(835); var INTS = function() { return [{ type: types.RANGE , from: 48, to: 57 }]; @@ -97945,10 +97993,10 @@ exports.anyChar = function() { /***/ }), -/* 836 */ +/* 837 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(834); +var types = __webpack_require__(835); exports.wordBoundary = function() { return { type: types.POSITION, value: 'b' }; @@ -97968,7 +98016,7 @@ exports.end = function() { /***/ }), -/* 837 */ +/* 838 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -97981,8 +98029,8 @@ exports.end = function() { -var isobject = __webpack_require__(748); -var isDescriptor = __webpack_require__(760); +var isobject = __webpack_require__(749); +var isDescriptor = __webpack_require__(761); var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) ? Reflect.defineProperty : Object.defineProperty; @@ -98013,14 +98061,14 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 838 */ +/* 839 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(839); -var assignSymbols = __webpack_require__(749); +var isExtendable = __webpack_require__(840); +var assignSymbols = __webpack_require__(750); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -98080,7 +98128,7 @@ function isEnum(obj, key) { /***/ }), -/* 839 */ +/* 840 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -98093,7 +98141,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(747); +var isPlainObject = __webpack_require__(748); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -98101,14 +98149,14 @@ module.exports = function isExtendable(val) { /***/ }), -/* 840 */ +/* 841 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(838); -var safe = __webpack_require__(831); +var extend = __webpack_require__(839); +var safe = __webpack_require__(832); /** * The main export is a function that takes a `pattern` string and an `options` object. @@ -98180,14 +98228,14 @@ module.exports = toRegex; /***/ }), -/* 841 */ +/* 842 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var nanomatch = __webpack_require__(842); -var extglob = __webpack_require__(857); +var nanomatch = __webpack_require__(843); +var extglob = __webpack_require__(858); module.exports = function(snapdragon) { var compilers = snapdragon.compiler.compilers; @@ -98264,7 +98312,7 @@ function escapeExtglobs(compiler) { /***/ }), -/* 842 */ +/* 843 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -98275,17 +98323,17 @@ function escapeExtglobs(compiler) { */ var util = __webpack_require__(29); -var toRegex = __webpack_require__(729); -var extend = __webpack_require__(843); +var toRegex = __webpack_require__(730); +var extend = __webpack_require__(844); /** * Local dependencies */ -var compilers = __webpack_require__(845); -var parsers = __webpack_require__(846); -var cache = __webpack_require__(849); -var utils = __webpack_require__(851); +var compilers = __webpack_require__(846); +var parsers = __webpack_require__(847); +var cache = __webpack_require__(850); +var utils = __webpack_require__(852); var MAX_LENGTH = 1024 * 64; /** @@ -99109,14 +99157,14 @@ module.exports = nanomatch; /***/ }), -/* 843 */ +/* 844 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(844); -var assignSymbols = __webpack_require__(749); +var isExtendable = __webpack_require__(845); +var assignSymbols = __webpack_require__(750); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -99176,7 +99224,7 @@ function isEnum(obj, key) { /***/ }), -/* 844 */ +/* 845 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -99189,7 +99237,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(747); +var isPlainObject = __webpack_require__(748); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -99197,7 +99245,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 845 */ +/* 846 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -99543,15 +99591,15 @@ module.exports = function(nanomatch, options) { /***/ }), -/* 846 */ +/* 847 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var regexNot = __webpack_require__(740); -var toRegex = __webpack_require__(729); -var isOdd = __webpack_require__(847); +var regexNot = __webpack_require__(741); +var toRegex = __webpack_require__(730); +var isOdd = __webpack_require__(848); /** * Characters to use in negation regex (we want to "not" match @@ -99937,7 +99985,7 @@ module.exports.not = NOT_REGEX; /***/ }), -/* 847 */ +/* 848 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -99950,7 +99998,7 @@ module.exports.not = NOT_REGEX; -var isNumber = __webpack_require__(848); +var isNumber = __webpack_require__(849); module.exports = function isOdd(i) { if (!isNumber(i)) { @@ -99964,7 +100012,7 @@ module.exports = function isOdd(i) { /***/ }), -/* 848 */ +/* 849 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -99992,14 +100040,14 @@ module.exports = function isNumber(num) { /***/ }), -/* 849 */ +/* 850 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(850))(); +module.exports = new (__webpack_require__(851))(); /***/ }), -/* 850 */ +/* 851 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -100012,7 +100060,7 @@ module.exports = new (__webpack_require__(850))(); -var MapCache = __webpack_require__(828); +var MapCache = __webpack_require__(829); /** * Create a new `FragmentCache` with an optional object to use for `caches`. @@ -100134,7 +100182,7 @@ exports = module.exports = FragmentCache; /***/ }), -/* 851 */ +/* 852 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -100147,14 +100195,14 @@ var path = __webpack_require__(16); * Module dependencies */ -var isWindows = __webpack_require__(852)(); -var Snapdragon = __webpack_require__(768); -utils.define = __webpack_require__(853); -utils.diff = __webpack_require__(854); -utils.extend = __webpack_require__(843); -utils.pick = __webpack_require__(855); -utils.typeOf = __webpack_require__(856); -utils.unique = __webpack_require__(741); +var isWindows = __webpack_require__(853)(); +var Snapdragon = __webpack_require__(769); +utils.define = __webpack_require__(854); +utils.diff = __webpack_require__(855); +utils.extend = __webpack_require__(844); +utils.pick = __webpack_require__(856); +utils.typeOf = __webpack_require__(857); +utils.unique = __webpack_require__(742); /** * Returns true if the given value is effectively an empty string @@ -100520,7 +100568,7 @@ utils.unixify = function(options) { /***/ }), -/* 852 */ +/* 853 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! @@ -100548,7 +100596,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ /***/ }), -/* 853 */ +/* 854 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -100561,8 +100609,8 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ -var isobject = __webpack_require__(748); -var isDescriptor = __webpack_require__(760); +var isobject = __webpack_require__(749); +var isDescriptor = __webpack_require__(761); var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) ? Reflect.defineProperty : Object.defineProperty; @@ -100593,7 +100641,7 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 854 */ +/* 855 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -100647,7 +100695,7 @@ function diffArray(one, two) { /***/ }), -/* 855 */ +/* 856 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -100660,7 +100708,7 @@ function diffArray(one, two) { -var isObject = __webpack_require__(748); +var isObject = __webpack_require__(749); module.exports = function pick(obj, keys) { if (!isObject(obj) && typeof obj !== 'function') { @@ -100689,7 +100737,7 @@ module.exports = function pick(obj, keys) { /***/ }), -/* 856 */ +/* 857 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -100824,7 +100872,7 @@ function isBuffer(val) { /***/ }), -/* 857 */ +/* 858 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -100834,18 +100882,18 @@ function isBuffer(val) { * Module dependencies */ -var extend = __webpack_require__(738); -var unique = __webpack_require__(741); -var toRegex = __webpack_require__(729); +var extend = __webpack_require__(739); +var unique = __webpack_require__(742); +var toRegex = __webpack_require__(730); /** * Local dependencies */ -var compilers = __webpack_require__(858); -var parsers = __webpack_require__(869); -var Extglob = __webpack_require__(872); -var utils = __webpack_require__(871); +var compilers = __webpack_require__(859); +var parsers = __webpack_require__(870); +var Extglob = __webpack_require__(873); +var utils = __webpack_require__(872); var MAX_LENGTH = 1024 * 64; /** @@ -101162,13 +101210,13 @@ module.exports = extglob; /***/ }), -/* 858 */ +/* 859 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(859); +var brackets = __webpack_require__(860); /** * Extglob compilers @@ -101338,7 +101386,7 @@ module.exports = function(extglob) { /***/ }), -/* 859 */ +/* 860 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -101348,17 +101396,17 @@ module.exports = function(extglob) { * Local dependencies */ -var compilers = __webpack_require__(860); -var parsers = __webpack_require__(862); +var compilers = __webpack_require__(861); +var parsers = __webpack_require__(863); /** * Module dependencies */ -var debug = __webpack_require__(864)('expand-brackets'); -var extend = __webpack_require__(738); -var Snapdragon = __webpack_require__(768); -var toRegex = __webpack_require__(729); +var debug = __webpack_require__(865)('expand-brackets'); +var extend = __webpack_require__(739); +var Snapdragon = __webpack_require__(769); +var toRegex = __webpack_require__(730); /** * Parses the given POSIX character class `pattern` and returns a @@ -101556,13 +101604,13 @@ module.exports = brackets; /***/ }), -/* 860 */ +/* 861 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var posix = __webpack_require__(861); +var posix = __webpack_require__(862); module.exports = function(brackets) { brackets.compiler @@ -101650,7 +101698,7 @@ module.exports = function(brackets) { /***/ }), -/* 861 */ +/* 862 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -101679,14 +101727,14 @@ module.exports = { /***/ }), -/* 862 */ +/* 863 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(863); -var define = __webpack_require__(730); +var utils = __webpack_require__(864); +var define = __webpack_require__(731); /** * Text regex @@ -101905,14 +101953,14 @@ module.exports.TEXT_REGEX = TEXT_REGEX; /***/ }), -/* 863 */ +/* 864 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var toRegex = __webpack_require__(729); -var regexNot = __webpack_require__(740); +var toRegex = __webpack_require__(730); +var regexNot = __webpack_require__(741); var cached; /** @@ -101946,7 +101994,7 @@ exports.createRegex = function(pattern, include) { /***/ }), -/* 864 */ +/* 865 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -101955,14 +102003,14 @@ exports.createRegex = function(pattern, include) { */ if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(865); + module.exports = __webpack_require__(866); } else { - module.exports = __webpack_require__(868); + module.exports = __webpack_require__(869); } /***/ }), -/* 865 */ +/* 866 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -101971,7 +102019,7 @@ if (typeof process !== 'undefined' && process.type === 'renderer') { * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(866); +exports = module.exports = __webpack_require__(867); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; @@ -102153,7 +102201,7 @@ function localstorage() { /***/ }), -/* 866 */ +/* 867 */ /***/ (function(module, exports, __webpack_require__) { @@ -102169,7 +102217,7 @@ exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; -exports.humanize = __webpack_require__(867); +exports.humanize = __webpack_require__(868); /** * The currently active debug mode names, and names to skip. @@ -102361,7 +102409,7 @@ function coerce(val) { /***/ }), -/* 867 */ +/* 868 */ /***/ (function(module, exports) { /** @@ -102519,7 +102567,7 @@ function plural(ms, n, name) { /***/ }), -/* 868 */ +/* 869 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -102535,7 +102583,7 @@ var util = __webpack_require__(29); * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(866); +exports = module.exports = __webpack_require__(867); exports.init = init; exports.log = log; exports.formatArgs = formatArgs; @@ -102714,7 +102762,7 @@ function createWritableStdioStream (fd) { case 'PIPE': case 'TCP': - var net = __webpack_require__(806); + var net = __webpack_require__(807); stream = new net.Socket({ fd: fd, readable: false, @@ -102773,15 +102821,15 @@ exports.enable(load()); /***/ }), -/* 869 */ +/* 870 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(859); -var define = __webpack_require__(870); -var utils = __webpack_require__(871); +var brackets = __webpack_require__(860); +var define = __webpack_require__(871); +var utils = __webpack_require__(872); /** * Characters to use in text regex (we want to "not" match @@ -102936,7 +102984,7 @@ module.exports = parsers; /***/ }), -/* 870 */ +/* 871 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -102949,7 +102997,7 @@ module.exports = parsers; -var isDescriptor = __webpack_require__(760); +var isDescriptor = __webpack_require__(761); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -102974,14 +103022,14 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 871 */ +/* 872 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var regex = __webpack_require__(740); -var Cache = __webpack_require__(850); +var regex = __webpack_require__(741); +var Cache = __webpack_require__(851); /** * Utils @@ -103050,7 +103098,7 @@ utils.createRegex = function(str) { /***/ }), -/* 872 */ +/* 873 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -103060,16 +103108,16 @@ utils.createRegex = function(str) { * Module dependencies */ -var Snapdragon = __webpack_require__(768); -var define = __webpack_require__(870); -var extend = __webpack_require__(738); +var Snapdragon = __webpack_require__(769); +var define = __webpack_require__(871); +var extend = __webpack_require__(739); /** * Local dependencies */ -var compilers = __webpack_require__(858); -var parsers = __webpack_require__(869); +var compilers = __webpack_require__(859); +var parsers = __webpack_require__(870); /** * Customize Snapdragon parser and renderer @@ -103135,16 +103183,16 @@ module.exports = Extglob; /***/ }), -/* 873 */ +/* 874 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extglob = __webpack_require__(857); -var nanomatch = __webpack_require__(842); -var regexNot = __webpack_require__(740); -var toRegex = __webpack_require__(830); +var extglob = __webpack_require__(858); +var nanomatch = __webpack_require__(843); +var regexNot = __webpack_require__(741); +var toRegex = __webpack_require__(831); var not; /** @@ -103225,14 +103273,14 @@ function textRegex(pattern) { /***/ }), -/* 874 */ +/* 875 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(850))(); +module.exports = new (__webpack_require__(851))(); /***/ }), -/* 875 */ +/* 876 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -103245,13 +103293,13 @@ var path = __webpack_require__(16); * Module dependencies */ -var Snapdragon = __webpack_require__(768); -utils.define = __webpack_require__(837); -utils.diff = __webpack_require__(854); -utils.extend = __webpack_require__(838); -utils.pick = __webpack_require__(855); -utils.typeOf = __webpack_require__(876); -utils.unique = __webpack_require__(741); +var Snapdragon = __webpack_require__(769); +utils.define = __webpack_require__(838); +utils.diff = __webpack_require__(855); +utils.extend = __webpack_require__(839); +utils.pick = __webpack_require__(856); +utils.typeOf = __webpack_require__(877); +utils.unique = __webpack_require__(742); /** * Returns true if the platform is windows, or `path.sep` is `\\`. @@ -103548,7 +103596,7 @@ utils.unixify = function(options) { /***/ }), -/* 876 */ +/* 877 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -103683,7 +103731,7 @@ function isBuffer(val) { /***/ }), -/* 877 */ +/* 878 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -103702,9 +103750,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(878); -var reader_1 = __webpack_require__(891); -var fs_stream_1 = __webpack_require__(895); +var readdir = __webpack_require__(879); +var reader_1 = __webpack_require__(892); +var fs_stream_1 = __webpack_require__(896); var ReaderAsync = /** @class */ (function (_super) { __extends(ReaderAsync, _super); function ReaderAsync() { @@ -103765,15 +103813,15 @@ exports.default = ReaderAsync; /***/ }), -/* 878 */ +/* 879 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const readdirSync = __webpack_require__(879); -const readdirAsync = __webpack_require__(887); -const readdirStream = __webpack_require__(890); +const readdirSync = __webpack_require__(880); +const readdirAsync = __webpack_require__(888); +const readdirStream = __webpack_require__(891); module.exports = exports = readdirAsyncPath; exports.readdir = exports.readdirAsync = exports.async = readdirAsyncPath; @@ -103857,7 +103905,7 @@ function readdirStreamStat (dir, options) { /***/ }), -/* 879 */ +/* 880 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -103865,11 +103913,11 @@ function readdirStreamStat (dir, options) { module.exports = readdirSync; -const DirectoryReader = __webpack_require__(880); +const DirectoryReader = __webpack_require__(881); let syncFacade = { - fs: __webpack_require__(885), - forEach: __webpack_require__(886), + fs: __webpack_require__(886), + forEach: __webpack_require__(887), sync: true }; @@ -103898,7 +103946,7 @@ function readdirSync (dir, options, internalOptions) { /***/ }), -/* 880 */ +/* 881 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -103907,9 +103955,9 @@ function readdirSync (dir, options, internalOptions) { const Readable = __webpack_require__(27).Readable; const EventEmitter = __webpack_require__(379).EventEmitter; const path = __webpack_require__(16); -const normalizeOptions = __webpack_require__(881); -const stat = __webpack_require__(883); -const call = __webpack_require__(884); +const normalizeOptions = __webpack_require__(882); +const stat = __webpack_require__(884); +const call = __webpack_require__(885); /** * Asynchronously reads the contents of a directory and streams the results @@ -104285,14 +104333,14 @@ module.exports = DirectoryReader; /***/ }), -/* 881 */ +/* 882 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(16); -const globToRegExp = __webpack_require__(882); +const globToRegExp = __webpack_require__(883); module.exports = normalizeOptions; @@ -104469,7 +104517,7 @@ function normalizeOptions (options, internalOptions) { /***/ }), -/* 882 */ +/* 883 */ /***/ (function(module, exports) { module.exports = function (glob, opts) { @@ -104606,13 +104654,13 @@ module.exports = function (glob, opts) { /***/ }), -/* 883 */ +/* 884 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const call = __webpack_require__(884); +const call = __webpack_require__(885); module.exports = stat; @@ -104687,7 +104735,7 @@ function symlinkStat (fs, path, lstats, callback) { /***/ }), -/* 884 */ +/* 885 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -104748,14 +104796,14 @@ function callOnce (fn) { /***/ }), -/* 885 */ +/* 886 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(23); -const call = __webpack_require__(884); +const call = __webpack_require__(885); /** * A facade around {@link fs.readdirSync} that allows it to be called @@ -104819,7 +104867,7 @@ exports.lstat = function (path, callback) { /***/ }), -/* 886 */ +/* 887 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -104848,7 +104896,7 @@ function syncForEach (array, iterator, done) { /***/ }), -/* 887 */ +/* 888 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -104856,12 +104904,12 @@ function syncForEach (array, iterator, done) { module.exports = readdirAsync; -const maybe = __webpack_require__(888); -const DirectoryReader = __webpack_require__(880); +const maybe = __webpack_require__(889); +const DirectoryReader = __webpack_require__(881); let asyncFacade = { fs: __webpack_require__(23), - forEach: __webpack_require__(889), + forEach: __webpack_require__(890), async: true }; @@ -104903,7 +104951,7 @@ function readdirAsync (dir, options, callback, internalOptions) { /***/ }), -/* 888 */ +/* 889 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -104930,7 +104978,7 @@ module.exports = function maybe (cb, promise) { /***/ }), -/* 889 */ +/* 890 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -104966,7 +105014,7 @@ function asyncForEach (array, iterator, done) { /***/ }), -/* 890 */ +/* 891 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -104974,11 +105022,11 @@ function asyncForEach (array, iterator, done) { module.exports = readdirStream; -const DirectoryReader = __webpack_require__(880); +const DirectoryReader = __webpack_require__(881); let streamFacade = { fs: __webpack_require__(23), - forEach: __webpack_require__(889), + forEach: __webpack_require__(890), async: true }; @@ -104998,16 +105046,16 @@ function readdirStream (dir, options, internalOptions) { /***/ }), -/* 891 */ +/* 892 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path = __webpack_require__(16); -var deep_1 = __webpack_require__(892); -var entry_1 = __webpack_require__(894); -var pathUtil = __webpack_require__(893); +var deep_1 = __webpack_require__(893); +var entry_1 = __webpack_require__(895); +var pathUtil = __webpack_require__(894); var Reader = /** @class */ (function () { function Reader(options) { this.options = options; @@ -105073,14 +105121,14 @@ exports.default = Reader; /***/ }), -/* 892 */ +/* 893 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(893); -var patternUtils = __webpack_require__(722); +var pathUtils = __webpack_require__(894); +var patternUtils = __webpack_require__(723); var DeepFilter = /** @class */ (function () { function DeepFilter(options, micromatchOptions) { this.options = options; @@ -105163,7 +105211,7 @@ exports.default = DeepFilter; /***/ }), -/* 893 */ +/* 894 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105194,14 +105242,14 @@ exports.makeAbsolute = makeAbsolute; /***/ }), -/* 894 */ +/* 895 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(893); -var patternUtils = __webpack_require__(722); +var pathUtils = __webpack_require__(894); +var patternUtils = __webpack_require__(723); var EntryFilter = /** @class */ (function () { function EntryFilter(options, micromatchOptions) { this.options = options; @@ -105286,7 +105334,7 @@ exports.default = EntryFilter; /***/ }), -/* 895 */ +/* 896 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105306,8 +105354,8 @@ var __extends = (this && this.__extends) || (function () { })(); Object.defineProperty(exports, "__esModule", { value: true }); var stream = __webpack_require__(27); -var fsStat = __webpack_require__(896); -var fs_1 = __webpack_require__(900); +var fsStat = __webpack_require__(897); +var fs_1 = __webpack_require__(901); var FileSystemStream = /** @class */ (function (_super) { __extends(FileSystemStream, _super); function FileSystemStream() { @@ -105357,14 +105405,14 @@ exports.default = FileSystemStream; /***/ }), -/* 896 */ +/* 897 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const optionsManager = __webpack_require__(897); -const statProvider = __webpack_require__(899); +const optionsManager = __webpack_require__(898); +const statProvider = __webpack_require__(900); /** * Asynchronous API. */ @@ -105395,13 +105443,13 @@ exports.statSync = statSync; /***/ }), -/* 897 */ +/* 898 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsAdapter = __webpack_require__(898); +const fsAdapter = __webpack_require__(899); function prepare(opts) { const options = Object.assign({ fs: fsAdapter.getFileSystemAdapter(opts ? opts.fs : undefined), @@ -105414,7 +105462,7 @@ exports.prepare = prepare; /***/ }), -/* 898 */ +/* 899 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105437,7 +105485,7 @@ exports.getFileSystemAdapter = getFileSystemAdapter; /***/ }), -/* 899 */ +/* 900 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105489,7 +105537,7 @@ exports.isFollowedSymlink = isFollowedSymlink; /***/ }), -/* 900 */ +/* 901 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105520,7 +105568,7 @@ exports.default = FileSystem; /***/ }), -/* 901 */ +/* 902 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105540,9 +105588,9 @@ var __extends = (this && this.__extends) || (function () { })(); Object.defineProperty(exports, "__esModule", { value: true }); var stream = __webpack_require__(27); -var readdir = __webpack_require__(878); -var reader_1 = __webpack_require__(891); -var fs_stream_1 = __webpack_require__(895); +var readdir = __webpack_require__(879); +var reader_1 = __webpack_require__(892); +var fs_stream_1 = __webpack_require__(896); var TransformStream = /** @class */ (function (_super) { __extends(TransformStream, _super); function TransformStream(reader) { @@ -105610,7 +105658,7 @@ exports.default = ReaderStream; /***/ }), -/* 902 */ +/* 903 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105629,9 +105677,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(878); -var reader_1 = __webpack_require__(891); -var fs_sync_1 = __webpack_require__(903); +var readdir = __webpack_require__(879); +var reader_1 = __webpack_require__(892); +var fs_sync_1 = __webpack_require__(904); var ReaderSync = /** @class */ (function (_super) { __extends(ReaderSync, _super); function ReaderSync() { @@ -105691,7 +105739,7 @@ exports.default = ReaderSync; /***/ }), -/* 903 */ +/* 904 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105710,8 +105758,8 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var fsStat = __webpack_require__(896); -var fs_1 = __webpack_require__(900); +var fsStat = __webpack_require__(897); +var fs_1 = __webpack_require__(901); var FileSystemSync = /** @class */ (function (_super) { __extends(FileSystemSync, _super); function FileSystemSync() { @@ -105757,7 +105805,7 @@ exports.default = FileSystemSync; /***/ }), -/* 904 */ +/* 905 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105773,7 +105821,7 @@ exports.flatten = flatten; /***/ }), -/* 905 */ +/* 906 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -105794,13 +105842,13 @@ exports.merge = merge; /***/ }), -/* 906 */ +/* 907 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(16); -const pathType = __webpack_require__(907); +const pathType = __webpack_require__(908); const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; @@ -105866,13 +105914,13 @@ module.exports.sync = (input, opts) => { /***/ }), -/* 907 */ +/* 908 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(23); -const pify = __webpack_require__(908); +const pify = __webpack_require__(909); function type(fn, fn2, fp) { if (typeof fp !== 'string') { @@ -105915,7 +105963,7 @@ exports.symlinkSync = typeSync.bind(null, 'lstatSync', 'isSymbolicLink'); /***/ }), -/* 908 */ +/* 909 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -106006,17 +106054,17 @@ module.exports = (obj, opts) => { /***/ }), -/* 909 */ +/* 910 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(23); const path = __webpack_require__(16); -const fastGlob = __webpack_require__(718); -const gitIgnore = __webpack_require__(910); -const pify = __webpack_require__(911); -const slash = __webpack_require__(912); +const fastGlob = __webpack_require__(719); +const gitIgnore = __webpack_require__(911); +const pify = __webpack_require__(912); +const slash = __webpack_require__(913); const DEFAULT_IGNORE = [ '**/node_modules/**', @@ -106114,7 +106162,7 @@ module.exports.sync = options => { /***/ }), -/* 910 */ +/* 911 */ /***/ (function(module, exports) { // A simple implementation of make-array @@ -106583,7 +106631,7 @@ module.exports = options => new IgnoreBase(options) /***/ }), -/* 911 */ +/* 912 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -106658,7 +106706,7 @@ module.exports = (input, options) => { /***/ }), -/* 912 */ +/* 913 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -106676,17 +106724,17 @@ module.exports = input => { /***/ }), -/* 913 */ +/* 914 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(16); const {constants: fsConstants} = __webpack_require__(23); -const pEvent = __webpack_require__(914); -const CpFileError = __webpack_require__(917); -const fs = __webpack_require__(921); -const ProgressEmitter = __webpack_require__(924); +const pEvent = __webpack_require__(915); +const CpFileError = __webpack_require__(918); +const fs = __webpack_require__(922); +const ProgressEmitter = __webpack_require__(925); const cpFileAsync = async (source, destination, options, progressEmitter) => { let readError; @@ -106800,12 +106848,12 @@ module.exports.sync = (source, destination, options) => { /***/ }), -/* 914 */ +/* 915 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pTimeout = __webpack_require__(915); +const pTimeout = __webpack_require__(916); const symbolAsyncIterator = Symbol.asyncIterator || '@@asyncIterator'; @@ -107096,12 +107144,12 @@ module.exports.iterator = (emitter, event, options) => { /***/ }), -/* 915 */ +/* 916 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pFinally = __webpack_require__(916); +const pFinally = __webpack_require__(917); class TimeoutError extends Error { constructor(message) { @@ -107147,7 +107195,7 @@ module.exports.TimeoutError = TimeoutError; /***/ }), -/* 916 */ +/* 917 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -107169,12 +107217,12 @@ module.exports = (promise, onFinally) => { /***/ }), -/* 917 */ +/* 918 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(918); +const NestedError = __webpack_require__(919); class CpFileError extends NestedError { constructor(message, nested) { @@ -107188,10 +107236,10 @@ module.exports = CpFileError; /***/ }), -/* 918 */ +/* 919 */ /***/ (function(module, exports, __webpack_require__) { -var inherits = __webpack_require__(919); +var inherits = __webpack_require__(920); var NestedError = function (message, nested) { this.nested = nested; @@ -107242,7 +107290,7 @@ module.exports = NestedError; /***/ }), -/* 919 */ +/* 920 */ /***/ (function(module, exports, __webpack_require__) { try { @@ -107250,12 +107298,12 @@ try { if (typeof util.inherits !== 'function') throw ''; module.exports = util.inherits; } catch (e) { - module.exports = __webpack_require__(920); + module.exports = __webpack_require__(921); } /***/ }), -/* 920 */ +/* 921 */ /***/ (function(module, exports) { if (typeof Object.create === 'function') { @@ -107284,16 +107332,16 @@ if (typeof Object.create === 'function') { /***/ }), -/* 921 */ +/* 922 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const {promisify} = __webpack_require__(29); const fs = __webpack_require__(22); -const makeDir = __webpack_require__(922); -const pEvent = __webpack_require__(914); -const CpFileError = __webpack_require__(917); +const makeDir = __webpack_require__(923); +const pEvent = __webpack_require__(915); +const CpFileError = __webpack_require__(918); const stat = promisify(fs.stat); const lstat = promisify(fs.lstat); @@ -107390,7 +107438,7 @@ exports.copyFileSync = (source, destination, flags) => { /***/ }), -/* 922 */ +/* 923 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -107398,7 +107446,7 @@ exports.copyFileSync = (source, destination, flags) => { const fs = __webpack_require__(23); const path = __webpack_require__(16); const {promisify} = __webpack_require__(29); -const semver = __webpack_require__(923); +const semver = __webpack_require__(924); const defaults = { mode: 0o777 & (~process.umask()), @@ -107547,7 +107595,7 @@ module.exports.sync = (input, options) => { /***/ }), -/* 923 */ +/* 924 */ /***/ (function(module, exports) { exports = module.exports = SemVer @@ -109149,7 +109197,7 @@ function coerce (version, options) { /***/ }), -/* 924 */ +/* 925 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -109190,7 +109238,7 @@ module.exports = ProgressEmitter; /***/ }), -/* 925 */ +/* 926 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -109236,12 +109284,12 @@ exports.default = module.exports; /***/ }), -/* 926 */ +/* 927 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(927); +const NestedError = __webpack_require__(928); class CpyError extends NestedError { constructor(message, nested) { @@ -109255,7 +109303,7 @@ module.exports = CpyError; /***/ }), -/* 927 */ +/* 928 */ /***/ (function(module, exports, __webpack_require__) { var inherits = __webpack_require__(29).inherits; @@ -109311,7 +109359,7 @@ module.exports = NestedError; /***/ }), -/* 928 */ +/* 929 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; diff --git a/packages/kbn-pm/package.json b/packages/kbn-pm/package.json index 444d46307b059..278fdbd2bc9a4 100644 --- a/packages/kbn-pm/package.json +++ b/packages/kbn-pm/package.json @@ -48,6 +48,7 @@ "globby": "^8.0.1", "has-ansi": "^3.0.0", "indent-string": "^3.2.0", + "is-path-inside": "^3.0.2", "lodash.clonedeepwith": "^4.5.0", "log-symbols": "^2.2.0", "multimatch": "^4.0.0", diff --git a/packages/kbn-pm/src/utils/kibana.ts b/packages/kbn-pm/src/utils/kibana.ts index 36f697d19fc1f..58af98b2a92db 100644 --- a/packages/kbn-pm/src/utils/kibana.ts +++ b/packages/kbn-pm/src/utils/kibana.ts @@ -20,6 +20,7 @@ import Path from 'path'; import multimatch from 'multimatch'; +import isPathInside from 'is-path-inside'; import { ProjectMap, getProjects, includeTransitiveProjects } from './projects'; import { Project } from './project'; @@ -121,4 +122,15 @@ export class Kibana { return filteredProjects; } + + isPartOfRepo(project: Project) { + return ( + project.path === this.kibanaProject.path || + isPathInside(project.path, this.kibanaProject.path) + ); + } + + isOutsideRepo(project: Project) { + return !this.isPartOfRepo(project); + } } diff --git a/packages/kbn-pm/src/utils/project_checksums.ts b/packages/kbn-pm/src/utils/project_checksums.ts index 2fd24c8fc9577..572f2adb19bd9 100644 --- a/packages/kbn-pm/src/utils/project_checksums.ts +++ b/packages/kbn-pm/src/utils/project_checksums.ts @@ -43,7 +43,14 @@ async function getChangesForProjects(projects: ProjectMap, kbn: Kibana, log: Too const { stdout } = await execa( 'git', - ['ls-files', '-dmt', '--', ...Array.from(projects.values()).map(p => p.path)], + [ + 'ls-files', + '-dmt', + '--', + ...Array.from(projects.values()) + .filter(p => kbn.isPartOfRepo(p)) + .map(p => p.path), + ], { cwd: kbn.getAbsolute(), } @@ -84,9 +91,14 @@ async function getChangesForProjects(projects: ProjectMap, kbn: Kibana, log: Too } const sortedRelevantProjects = Array.from(projects.values()).sort(projectBySpecificitySorter); - const changesByProject = new Map(); + const changesByProject = new Map(); for (const project of sortedRelevantProjects) { + if (kbn.isOutsideRepo(project)) { + changesByProject.set(project, undefined); + continue; + } + const ownChanges: Changes = new Map(); const prefix = kbn.getRelative(project.path); @@ -114,6 +126,10 @@ async function getChangesForProjects(projects: ProjectMap, kbn: Kibana, log: Too /** Get the latest commit sha for a project */ async function getLatestSha(project: Project, kbn: Kibana) { + if (kbn.isOutsideRepo(project)) { + return; + } + const { stdout } = await execa( 'git', ['log', '-n', '1', '--pretty=format:%H', '--', project.path], @@ -175,7 +191,7 @@ function resolveDepsForProject(project: Project, yarnLock: YarnLock, kbn: Kibana */ async function getChecksum( project: Project, - changes: Changes, + changes: Changes | undefined, yarnLock: YarnLock, kbn: Kibana, log: ToolingLog @@ -185,7 +201,7 @@ async function getChecksum( log.verbose(`[${project.name}] local sha:`, sha); } - if (Array.from(changes.values()).includes('invalid')) { + if (!changes || Array.from(changes.values()).includes('invalid')) { log.warning(`[${project.name}] unable to determine local changes, caching disabled`); return; } @@ -248,7 +264,7 @@ export async function getAllChecksums(kbn: Kibana, log: ToolingLog) { Array.from(projects.values()).map(async project => { cacheKeys.set( project.name, - await getChecksum(project, changesByProject.get(project)!, yarnLock, kbn, log) + await getChecksum(project, changesByProject.get(project), yarnLock, kbn, log) ); }) ); diff --git a/src/core/public/chrome/chrome_service.mock.ts b/src/core/public/chrome/chrome_service.mock.ts index bd932c5961eca..89007461b63e6 100644 --- a/src/core/public/chrome/chrome_service.mock.ts +++ b/src/core/public/chrome/chrome_service.mock.ts @@ -61,8 +61,6 @@ const createStartContractMock = () => { getBrand$: jest.fn(), setIsVisible: jest.fn(), getIsVisible$: jest.fn(), - setIsCollapsed: jest.fn(), - getIsCollapsed$: jest.fn(), addApplicationClass: jest.fn(), removeApplicationClass: jest.fn(), getApplicationClasses$: jest.fn(), @@ -73,15 +71,16 @@ const createStartContractMock = () => { getHelpExtension$: jest.fn(), setHelpExtension: jest.fn(), setHelpSupportUrl: jest.fn(), + getIsNavDrawerLocked$: jest.fn(), }; startContract.navLinks.getAll.mockReturnValue([]); startContract.getBrand$.mockReturnValue(new BehaviorSubject({} as ChromeBrand)); startContract.getIsVisible$.mockReturnValue(new BehaviorSubject(false)); - startContract.getIsCollapsed$.mockReturnValue(new BehaviorSubject(false)); startContract.getApplicationClasses$.mockReturnValue(new BehaviorSubject(['class-name'])); startContract.getBadge$.mockReturnValue(new BehaviorSubject({} as ChromeBadge)); startContract.getBreadcrumbs$.mockReturnValue(new BehaviorSubject([{} as ChromeBreadcrumb])); startContract.getHelpExtension$.mockReturnValue(new BehaviorSubject(undefined)); + startContract.getIsNavDrawerLocked$.mockReturnValue(new BehaviorSubject(false)); return startContract; }; diff --git a/src/core/public/chrome/chrome_service.test.ts b/src/core/public/chrome/chrome_service.test.ts index 9018b21973634..bf531aaa00fac 100644 --- a/src/core/public/chrome/chrome_service.test.ts +++ b/src/core/public/chrome/chrome_service.test.ts @@ -259,40 +259,6 @@ describe('start', () => { }); }); - describe('is collapsed', () => { - it('updates/emits isCollapsed', async () => { - const { chrome, service } = await start(); - const promise = chrome - .getIsCollapsed$() - .pipe(toArray()) - .toPromise(); - - chrome.setIsCollapsed(true); - chrome.setIsCollapsed(false); - chrome.setIsCollapsed(true); - service.stop(); - - await expect(promise).resolves.toMatchInlineSnapshot(` - Array [ - false, - true, - false, - true, - ] - `); - }); - - it('only stores true in localStorage', async () => { - const { chrome } = await start(); - - chrome.setIsCollapsed(true); - expect(store.size).toBe(1); - - chrome.setIsCollapsed(false); - expect(store.size).toBe(0); - }); - }); - describe('application classes', () => { it('updates/emits the application classes', async () => { const { chrome, service } = await start(); @@ -442,12 +408,12 @@ describe('start', () => { }); describe('stop', () => { - it('completes applicationClass$, isCollapsed$, breadcrumbs$, isVisible$, and brand$ observables', async () => { + it('completes applicationClass$, getIsNavDrawerLocked, breadcrumbs$, isVisible$, and brand$ observables', async () => { const { chrome, service } = await start(); const promise = Rx.combineLatest( chrome.getBrand$(), chrome.getApplicationClasses$(), - chrome.getIsCollapsed$(), + chrome.getIsNavDrawerLocked$(), chrome.getBreadcrumbs$(), chrome.getIsVisible$(), chrome.getHelpExtension$() @@ -465,7 +431,7 @@ describe('stop', () => { Rx.combineLatest( chrome.getBrand$(), chrome.getApplicationClasses$(), - chrome.getIsCollapsed$(), + chrome.getIsNavDrawerLocked$(), chrome.getBreadcrumbs$(), chrome.getIsVisible$(), chrome.getHelpExtension$() diff --git a/src/core/public/chrome/chrome_service.tsx b/src/core/public/chrome/chrome_service.tsx index 2b0b115ce068e..7c9b644b8b984 100644 --- a/src/core/public/chrome/chrome_service.tsx +++ b/src/core/public/chrome/chrome_service.tsx @@ -34,14 +34,14 @@ import { ChromeNavLinks, NavLinksService } from './nav_links'; import { ChromeRecentlyAccessed, RecentlyAccessedService } from './recently_accessed'; import { NavControlsService, ChromeNavControls } from './nav_controls'; import { DocTitleService, ChromeDocTitle } from './doc_title'; -import { LoadingIndicator, HeaderWrapper as Header } from './ui'; +import { LoadingIndicator, Header } from './ui'; import { DocLinksStart } from '../doc_links'; import { ChromeHelpExtensionMenuLink } from './ui/header/header_help_menu'; import { KIBANA_ASK_ELASTIC_LINK } from './constants'; import { IUiSettingsClient } from '../ui_settings'; export { ChromeNavControls, ChromeRecentlyAccessed, ChromeDocTitle }; -const IS_COLLAPSED_KEY = 'core.chrome.isCollapsed'; +const IS_LOCKED_KEY = 'core.chrome.isLocked'; /** @public */ export interface ChromeBadge { @@ -146,18 +146,25 @@ export class ChromeService { const appTitle$ = new BehaviorSubject('Kibana'); const brand$ = new BehaviorSubject({}); - const isCollapsed$ = new BehaviorSubject(!!localStorage.getItem(IS_COLLAPSED_KEY)); const applicationClasses$ = new BehaviorSubject>(new Set()); const helpExtension$ = new BehaviorSubject(undefined); const breadcrumbs$ = new BehaviorSubject([]); const badge$ = new BehaviorSubject(undefined); const helpSupportUrl$ = new BehaviorSubject(KIBANA_ASK_ELASTIC_LINK); + const isNavDrawerLocked$ = new BehaviorSubject(localStorage.getItem(IS_LOCKED_KEY) === 'true'); const navControls = this.navControls.start(); const navLinks = this.navLinks.start({ application, http }); const recentlyAccessed = await this.recentlyAccessed.start({ http }); const docTitle = this.docTitle.start({ document: window.document }); + const setIsNavDrawerLocked = (isLocked: boolean) => { + isNavDrawerLocked$.next(isLocked); + localStorage.setItem(IS_LOCKED_KEY, `${isLocked}`); + }; + + const getIsNavDrawerLocked$ = isNavDrawerLocked$.pipe(takeUntil(this.stop$)); + if (!this.params.browserSupportsCsp && injectedMetadata.getCspConfig().warnLegacyBrowsers) { notifications.toasts.addWarning( i18n.translate('core.chrome.legacyBrowserWarning', { @@ -193,6 +200,8 @@ export class ChromeService { recentlyAccessed$={recentlyAccessed.get$()} navControlsLeft$={navControls.getLeft$()} navControlsRight$={navControls.getRight$()} + onIsLockedUpdate={setIsNavDrawerLocked} + isLocked$={getIsNavDrawerLocked$} /> ), @@ -214,17 +223,6 @@ export class ChromeService { setIsVisible: (isVisible: boolean) => this.toggleHidden$.next(!isVisible), - getIsCollapsed$: () => isCollapsed$.pipe(takeUntil(this.stop$)), - - setIsCollapsed: (isCollapsed: boolean) => { - isCollapsed$.next(isCollapsed); - if (isCollapsed) { - localStorage.setItem(IS_COLLAPSED_KEY, 'true'); - } else { - localStorage.removeItem(IS_COLLAPSED_KEY); - } - }, - getApplicationClasses$: () => applicationClasses$.pipe( map(set => [...set]), @@ -262,6 +260,8 @@ export class ChromeService { }, setHelpSupportUrl: (url: string) => helpSupportUrl$.next(url), + + getIsNavDrawerLocked$: () => getIsNavDrawerLocked$, }; } @@ -353,16 +353,6 @@ export interface ChromeStart { */ setIsVisible(isVisible: boolean): void; - /** - * Get an observable of the current collapsed state of the chrome. - */ - getIsCollapsed$(): Observable; - - /** - * Set the collapsed state of the chrome navigation. - */ - setIsCollapsed(isCollapsed: boolean): void; - /** * Get the current set of classNames that will be set on the application container. */ @@ -413,6 +403,11 @@ export interface ChromeStart { * @param url The updated support URL */ setHelpSupportUrl(url: string): void; + + /** + * Get an observable of the current locked state of the nav drawer. + */ + getIsNavDrawerLocked$(): Observable; } /** @internal */ diff --git a/src/core/public/chrome/ui/header/header.tsx b/src/core/public/chrome/ui/header/header.tsx index c9a583f39b30c..4dec084fd8a83 100644 --- a/src/core/public/chrome/ui/header/header.tsx +++ b/src/core/public/chrome/ui/header/header.tsx @@ -30,6 +30,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import React, { Component, createRef } from 'react'; +import classnames from 'classnames'; import * as Rx from 'rxjs'; import { ChromeBadge, @@ -68,8 +69,8 @@ export interface HeaderProps { navControlsLeft$: Rx.Observable; navControlsRight$: Rx.Observable; basePath: HttpStart['basePath']; - isLocked?: boolean; - onIsLockedUpdate?: OnIsLockedUpdate; + isLocked$: Rx.Observable; + onIsLockedUpdate: OnIsLockedUpdate; } interface State { @@ -81,6 +82,7 @@ interface State { navControlsLeft: readonly ChromeNavControl[]; navControlsRight: readonly ChromeNavControl[]; currentAppId: string | undefined; + isLocked: boolean; } export class Header extends Component { @@ -99,6 +101,7 @@ export class Header extends Component { navControlsLeft: [], navControlsRight: [], currentAppId: '', + isLocked: false, }; } @@ -109,11 +112,12 @@ export class Header extends Component { this.props.forceAppSwitcherNavigation$, this.props.navLinks$, this.props.recentlyAccessed$, - // Types for combineLatest only handle up to 6 inferred types so we combine these two separately. + // Types for combineLatest only handle up to 6 inferred types so we combine these separately. Rx.combineLatest( this.props.navControlsLeft$, this.props.navControlsRight$, - this.props.application.currentAppId$ + this.props.application.currentAppId$, + this.props.isLocked$ ) ).subscribe({ next: ([ @@ -122,7 +126,7 @@ export class Header extends Component { forceNavigation, navLinks, recentlyAccessed, - [navControlsLeft, navControlsRight, currentAppId], + [navControlsLeft, navControlsRight, currentAppId, isLocked], ]) => { this.setState({ appTitle, @@ -133,6 +137,7 @@ export class Header extends Component { navControlsLeft, navControlsRight, currentAppId, + isLocked, }); }, }); @@ -181,8 +186,16 @@ export class Header extends Component { return null; } + const className = classnames( + 'chrHeaderWrapper', + { + 'chrHeaderWrapper--navIsLocked': this.state.isLocked, + }, + 'hide-for-sharing' + ); + return ( -
+
@@ -220,7 +233,7 @@ export class Header extends Component { = props => { - const initialIsLocked = localStorage.getItem(IS_LOCKED_KEY); - const [isLocked, setIsLocked] = useState(initialIsLocked === 'true'); - const setIsLockedStored = (locked: boolean) => { - localStorage.setItem(IS_LOCKED_KEY, `${locked}`); - setIsLocked(locked); - }; - const className = classnames( - 'chrHeaderWrapper', - { - 'chrHeaderWrapper--navIsLocked': isLocked, - }, - 'hide-for-sharing' - ); - return ( -
-
-
- ); -}; diff --git a/src/core/public/chrome/ui/header/index.ts b/src/core/public/chrome/ui/header/index.ts index 4521f1f74b31b..49e002a66d939 100644 --- a/src/core/public/chrome/ui/header/index.ts +++ b/src/core/public/chrome/ui/header/index.ts @@ -18,7 +18,6 @@ */ export { Header, HeaderProps } from './header'; -export { HeaderWrapper } from './header_wrapper'; export { ChromeHelpExtensionMenuLink, ChromeHelpExtensionMenuCustomLink, diff --git a/src/core/public/chrome/ui/index.ts b/src/core/public/chrome/ui/index.ts index 81b2fdfb0fcc0..460e19b7d9780 100644 --- a/src/core/public/chrome/ui/index.ts +++ b/src/core/public/chrome/ui/index.ts @@ -20,7 +20,6 @@ export { LoadingIndicator } from './loading_indicator'; export { Header, - HeaderWrapper, ChromeHelpExtensionMenuLink, ChromeHelpExtensionMenuCustomLink, ChromeHelpExtensionMenuDiscussLink, diff --git a/src/core/public/public.api.md b/src/core/public/public.api.md index fa5dc745e6931..7428280b2dccb 100644 --- a/src/core/public/public.api.md +++ b/src/core/public/public.api.md @@ -337,7 +337,7 @@ export interface ChromeStart { getBrand$(): Observable; getBreadcrumbs$(): Observable; getHelpExtension$(): Observable; - getIsCollapsed$(): Observable; + getIsNavDrawerLocked$(): Observable; getIsVisible$(): Observable; navControls: ChromeNavControls; navLinks: ChromeNavLinks; @@ -349,7 +349,6 @@ export interface ChromeStart { setBreadcrumbs(newBreadcrumbs: ChromeBreadcrumb[]): void; setHelpExtension(helpExtension?: ChromeHelpExtension): void; setHelpSupportUrl(url: string): void; - setIsCollapsed(isCollapsed: boolean): void; setIsVisible(isVisible: boolean): void; } diff --git a/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts index 8202ba13b30cc..5f3dbb65fd8ff 100644 --- a/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts +++ b/src/legacy/core_plugins/kibana/public/discover/kibana_services.ts @@ -53,8 +53,6 @@ export { wrapInI18nContext } from 'ui/i18n'; import { search } from '../../../../../plugins/data/public'; export const { getRequestInspectorStats, getResponseInspectorStats, tabifyAggResponse } = search; // @ts-ignore -export { shortenDottedString } from '../../common/utils/shorten_dotted_string'; -// @ts-ignore export { intervalOptions } from 'ui/agg_types'; export { subscribeWithScope } from '../../../../../plugins/kibana_legacy/public'; // @ts-ignore diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name/field_name.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name/field_name.tsx index 26d8a5abb2471..1b3b16332fa4f 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name/field_name.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/directives/field_name/field_name.tsx @@ -21,7 +21,7 @@ import classNames from 'classnames'; import { EuiFlexGroup, EuiFlexItem, EuiToolTip } from '@elastic/eui'; import { FieldIcon, FieldIconProps } from '../../../../../../../../../plugins/kibana_react/public'; -import { shortenDottedString } from '../../../../kibana_services'; +import { shortenDottedString } from '../../../helpers'; import { getFieldTypeName } from './field_type_name'; // property field is provided at discover's field chooser diff --git a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_header/helpers.tsx b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_header/helpers.tsx index a2ad18d59d935..bd48b1e083871 100644 --- a/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_header/helpers.tsx +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/angular/doc_table/components/table_header/helpers.tsx @@ -16,7 +16,8 @@ * specific language governing permissions and limitations * under the License. */ -import { IndexPattern, shortenDottedString } from '../../../../../kibana_services'; +import { IndexPattern } from '../../../../../kibana_services'; +import { shortenDottedString } from '../../../../helpers'; export type SortOrder = [string, string]; export interface ColumnProps { diff --git a/src/legacy/ui/public/chrome/services/index.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/index.ts similarity index 92% rename from src/legacy/ui/public/chrome/services/index.js rename to src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/index.ts index 3b3967f51b2ff..7196c96989e97 100644 --- a/src/legacy/ui/public/chrome/services/index.js +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/index.ts @@ -17,4 +17,4 @@ * under the License. */ -import './global_nav_state'; +export { shortenDottedString } from './shorten_dotted_string'; diff --git a/src/legacy/core_plugins/kibana/common/utils/shorten_dotted_string.js b/src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/shorten_dotted_string.ts similarity index 81% rename from src/legacy/core_plugins/kibana/common/utils/shorten_dotted_string.js rename to src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/shorten_dotted_string.ts index ca76a2a537742..9d78a96784339 100644 --- a/src/legacy/core_plugins/kibana/common/utils/shorten_dotted_string.js +++ b/src/legacy/core_plugins/kibana/public/discover/np_ready/helpers/shorten_dotted_string.ts @@ -22,10 +22,5 @@ const DOT_PREFIX_RE = /(.).+?\./g; /** * Convert a dot.notated.string into a short * version (d.n.string) - * - * @param {string} str - the long string to convert - * @return {string} */ -export function shortenDottedString(input) { - return typeof input !== 'string' ? input : input.replace(DOT_PREFIX_RE, '$1.'); -} +export const shortenDottedString = (input: string) => input.replace(DOT_PREFIX_RE, '$1.'); diff --git a/src/legacy/ui/public/chrome/chrome.js b/src/legacy/ui/public/chrome/chrome.js index 3355870eabfe7..7a75ad906a870 100644 --- a/src/legacy/ui/public/chrome/chrome.js +++ b/src/legacy/ui/public/chrome/chrome.js @@ -28,7 +28,6 @@ import '../private'; import '../promises'; import '../directives/storage'; import '../directives/watch_multi'; -import './services'; import '../react_components'; import '../i18n'; diff --git a/src/legacy/ui/public/chrome/services/global_nav_state.js b/src/legacy/ui/public/chrome/services/global_nav_state.js deleted file mode 100644 index 5a67806852fe8..0000000000000 --- a/src/legacy/ui/public/chrome/services/global_nav_state.js +++ /dev/null @@ -1,45 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ - -import { distinctUntilChanged } from 'rxjs/operators'; -import { npStart } from 'ui/new_platform'; -import { uiModules } from '../../modules'; - -const newPlatformChrome = npStart.core.chrome; - -uiModules.get('kibana').service('globalNavState', $rootScope => { - let isOpen = false; - newPlatformChrome - .getIsCollapsed$() - .pipe(distinctUntilChanged()) - .subscribe(isCollapsed => { - $rootScope.$evalAsync(() => { - isOpen = !isCollapsed; - $rootScope.$broadcast('globalNavState:change'); - }); - }); - - return { - isOpen: () => isOpen, - - setOpen: newValue => { - newPlatformChrome.setIsCollapsed(!newValue); - }, - }; -}); diff --git a/src/legacy/ui/public/vis/map/service_settings.js b/src/legacy/ui/public/vis/map/service_settings.js index 233ee526c439b..9f3d21831e3da 100644 --- a/src/legacy/ui/public/vis/map/service_settings.js +++ b/src/legacy/ui/public/vis/map/service_settings.js @@ -47,7 +47,8 @@ uiModules this._showZoomMessage = true; this._emsClient = new EMSClient({ language: i18n.getLocale(), - kbnVersion: kbnVersion, + appVersion: kbnVersion, + appName: 'kibana', fileApiUrl: mapConfig.emsFileApiUrl, tileApiUrl: mapConfig.emsTileApiUrl, htmlSanitizer: $sanitize, diff --git a/src/plugins/console/public/lib/kb/kb.js b/src/plugins/console/public/lib/kb/kb.js index 95896bed02988..053b82bd81d0a 100644 --- a/src/plugins/console/public/lib/kb/kb.js +++ b/src/plugins/console/public/lib/kb/kb.js @@ -147,13 +147,9 @@ function loadApisFromJson( } export function setActiveApi(api) { - if (_.isString(api)) { + if (!api) { $.ajax({ - url: - '../api/console/api_server?sense_version=' + - encodeURIComponent('@@SENSE_VERSION') + - '&apis=' + - encodeURIComponent(api), + url: '../api/console/api_server', dataType: 'json', // disable automatic guessing }).then( function(data) { @@ -169,7 +165,7 @@ export function setActiveApi(api) { ACTIVE_API = api; } -setActiveApi('es_6_0'); +setActiveApi(); export const _test = { loadApisFromJson: loadApisFromJson, diff --git a/src/plugins/console/server/lib/index.ts b/src/plugins/console/server/lib/index.ts index 98004768f880b..2347084b73a66 100644 --- a/src/plugins/console/server/lib/index.ts +++ b/src/plugins/console/server/lib/index.ts @@ -22,4 +22,4 @@ export { ProxyConfigCollection } from './proxy_config_collection'; export { proxyRequest } from './proxy_request'; export { getElasticsearchProxyConfig } from './elasticsearch_proxy_config'; export { setHeaders } from './set_headers'; -export { addProcessorDefinition, addExtensionSpecFilePath } from './spec_definitions'; +export { addProcessorDefinition, addExtensionSpecFilePath, loadSpec } from './spec_definitions'; diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0.js b/src/plugins/console/server/lib/spec_definitions/es.js similarity index 54% rename from src/plugins/console/server/lib/spec_definitions/es_6_0.js rename to src/plugins/console/server/lib/spec_definitions/es.js index 171d232407956..fc24a64f8a6f4 100644 --- a/src/plugins/console/server/lib/spec_definitions/es_6_0.js +++ b/src/plugins/console/server/lib/spec_definitions/es.js @@ -18,26 +18,30 @@ */ import Api from './api'; -import { getSpec } from './spec'; -import { register } from './es_6_0/ingest'; -const ES_6_0 = new Api('es_6_0'); -const spec = getSpec(); +import { getSpec } from './json'; +import { register } from './js/ingest'; +const ES = new Api('es'); -// adding generated specs -Object.keys(spec).forEach(endpoint => { - ES_6_0.addEndpointDescription(endpoint, spec[endpoint]); -}); +export const loadSpec = () => { + const spec = getSpec(); -//adding globals and custom API definitions -require('./es_6_0/aliases')(ES_6_0); -require('./es_6_0/aggregations')(ES_6_0); -require('./es_6_0/document')(ES_6_0); -require('./es_6_0/filter')(ES_6_0); -require('./es_6_0/globals')(ES_6_0); -register(ES_6_0); -require('./es_6_0/mappings')(ES_6_0); -require('./es_6_0/query')(ES_6_0); -require('./es_6_0/reindex')(ES_6_0); -require('./es_6_0/search')(ES_6_0); + // adding generated specs + Object.keys(spec).forEach(endpoint => { + ES.addEndpointDescription(endpoint, spec[endpoint]); + }); -export default ES_6_0; + // adding globals and custom API definitions + require('./js/aliases')(ES); + require('./js/aggregations')(ES); + require('./js/document')(ES); + require('./js/filter')(ES); + require('./js/globals')(ES); + register(ES); + require('./js/mappings')(ES); + require('./js/settings')(ES); + require('./js/query')(ES); + require('./js/reindex')(ES); + require('./js/search')(ES); +}; + +export default ES; diff --git a/src/plugins/console/server/lib/spec_definitions/index.d.ts b/src/plugins/console/server/lib/spec_definitions/index.d.ts index 0a79d3fb386f1..da0125a186c15 100644 --- a/src/plugins/console/server/lib/spec_definitions/index.d.ts +++ b/src/plugins/console/server/lib/spec_definitions/index.d.ts @@ -19,6 +19,13 @@ export declare function addProcessorDefinition(...args: any[]): any; -export declare function resolveApi(senseVersion: string, apis: string[]): object; +export declare function resolveApi(): object; export declare function addExtensionSpecFilePath(...args: any[]): any; + +/** + * A function that synchronously reads files JSON from disk and builds + * the autocomplete structures served to the client. This must be called + * after any extensions have been loaded. + */ +export declare function loadSpec(): any; diff --git a/src/plugins/console/server/lib/spec_definitions/index.js b/src/plugins/console/server/lib/spec_definitions/index.js index 3fe1913d5a193..abf55639fbee8 100644 --- a/src/plugins/console/server/lib/spec_definitions/index.js +++ b/src/plugins/console/server/lib/spec_definitions/index.js @@ -17,8 +17,10 @@ * under the License. */ -export { addProcessorDefinition } from './es_6_0/ingest'; +export { addProcessorDefinition } from './js/ingest'; -export { addExtensionSpecFilePath } from './spec'; +export { addExtensionSpecFilePath } from './json'; + +export { loadSpec } from './es'; export { resolveApi } from './server'; diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/aggregations.js b/src/plugins/console/server/lib/spec_definitions/js/aggregations.js similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/es_6_0/aggregations.js rename to src/plugins/console/server/lib/spec_definitions/js/aggregations.js diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/aliases.js b/src/plugins/console/server/lib/spec_definitions/js/aliases.js similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/es_6_0/aliases.js rename to src/plugins/console/server/lib/spec_definitions/js/aliases.js diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/document.js b/src/plugins/console/server/lib/spec_definitions/js/document.js similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/es_6_0/document.js rename to src/plugins/console/server/lib/spec_definitions/js/document.js diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/filter.js b/src/plugins/console/server/lib/spec_definitions/js/filter.js similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/es_6_0/filter.js rename to src/plugins/console/server/lib/spec_definitions/js/filter.js diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/globals.js b/src/plugins/console/server/lib/spec_definitions/js/globals.js similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/es_6_0/globals.js rename to src/plugins/console/server/lib/spec_definitions/js/globals.js diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/ingest.js b/src/plugins/console/server/lib/spec_definitions/js/ingest.js similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/es_6_0/ingest.js rename to src/plugins/console/server/lib/spec_definitions/js/ingest.js diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/mappings.js b/src/plugins/console/server/lib/spec_definitions/js/mappings.js similarity index 99% rename from src/plugins/console/server/lib/spec_definitions/es_6_0/mappings.js rename to src/plugins/console/server/lib/spec_definitions/js/mappings.js index 8c31e5bc6fbb2..5884d14d4dc8b 100644 --- a/src/plugins/console/server/lib/spec_definitions/es_6_0/mappings.js +++ b/src/plugins/console/server/lib/spec_definitions/js/mappings.js @@ -19,9 +19,7 @@ const _ = require('lodash'); -const BOOLEAN = { - __one_of: [true, false], -}; +import { BOOLEAN } from './shared'; export default function(api) { api.addEndpointDescription('put_mapping', { diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/query/dsl.js b/src/plugins/console/server/lib/spec_definitions/js/query/dsl.js similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/es_6_0/query/dsl.js rename to src/plugins/console/server/lib/spec_definitions/js/query/dsl.js diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/query/index.js b/src/plugins/console/server/lib/spec_definitions/js/query/index.js similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/es_6_0/query/index.js rename to src/plugins/console/server/lib/spec_definitions/js/query/index.js diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/query/templates.js b/src/plugins/console/server/lib/spec_definitions/js/query/templates.js similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/es_6_0/query/templates.js rename to src/plugins/console/server/lib/spec_definitions/js/query/templates.js diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/reindex.js b/src/plugins/console/server/lib/spec_definitions/js/reindex.js similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/es_6_0/reindex.js rename to src/plugins/console/server/lib/spec_definitions/js/reindex.js diff --git a/src/plugins/console/server/lib/spec_definitions/es_6_0/search.js b/src/plugins/console/server/lib/spec_definitions/js/search.js similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/es_6_0/search.js rename to src/plugins/console/server/lib/spec_definitions/js/search.js diff --git a/src/plugins/console/server/lib/spec_definitions/js/settings.js b/src/plugins/console/server/lib/spec_definitions/js/settings.js new file mode 100644 index 0000000000000..26cd0987c34a5 --- /dev/null +++ b/src/plugins/console/server/lib/spec_definitions/js/settings.js @@ -0,0 +1,74 @@ +/* + * Licensed to Elasticsearch B.V. under one or more contributor + * license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright + * ownership. Elasticsearch B.V. licenses this file to you under + * the Apache License, Version 2.0 (the "License"); you may + * not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +import { BOOLEAN } from './shared'; + +export default function(api) { + api.addEndpointDescription('put_settings', { + data_autocomplete_rules: { + refresh_interval: '1s', + number_of_shards: 1, + number_of_replicas: 1, + 'blocks.read_only': BOOLEAN, + 'blocks.read': BOOLEAN, + 'blocks.write': BOOLEAN, + 'blocks.metadata': BOOLEAN, + term_index_interval: 32, + term_index_divisor: 1, + 'translog.flush_threshold_ops': 5000, + 'translog.flush_threshold_size': '200mb', + 'translog.flush_threshold_period': '30m', + 'translog.disable_flush': BOOLEAN, + 'cache.filter.max_size': '2gb', + 'cache.filter.expire': '2h', + 'gateway.snapshot_interval': '10s', + routing: { + allocation: { + include: { + tag: '', + }, + exclude: { + tag: '', + }, + require: { + tag: '', + }, + total_shards_per_node: -1, + }, + }, + 'recovery.initial_shards': { + __one_of: ['quorum', 'quorum-1', 'half', 'full', 'full-1'], + }, + 'ttl.disable_purge': BOOLEAN, + analysis: { + analyzer: {}, + tokenizer: {}, + filter: {}, + char_filter: {}, + }, + 'cache.query.enable': BOOLEAN, + shadow_replicas: BOOLEAN, + shared_filesystem: BOOLEAN, + data_path: 'path', + codec: { + __one_of: ['default', 'best_compression', 'lucene_default'], + }, + }, + }); +} diff --git a/src/legacy/core_plugins/kibana/common/utils/__tests__/shorten_dotted_string.js b/src/plugins/console/server/lib/spec_definitions/js/shared.js similarity index 60% rename from src/legacy/core_plugins/kibana/common/utils/__tests__/shorten_dotted_string.js rename to src/plugins/console/server/lib/spec_definitions/js/shared.js index 267ca74c7c42a..ace189e2d0913 100644 --- a/src/legacy/core_plugins/kibana/common/utils/__tests__/shorten_dotted_string.js +++ b/src/plugins/console/server/lib/spec_definitions/js/shared.js @@ -17,18 +17,6 @@ * under the License. */ -import expect from '@kbn/expect'; -import { shortenDottedString } from '../shorten_dotted_string'; - -describe('shortenDottedString', () => { - it('Convert a dot.notated.string into a short string', () => { - expect(shortenDottedString('dot.notated.string')).to.equal('d.n.string'); - }); - - it('Ignores non-string values', () => { - expect(shortenDottedString(true)).to.equal(true); - expect(shortenDottedString(123)).to.equal(123); - const obj = { key: 'val' }; - expect(shortenDottedString(obj)).to.equal(obj); - }); +export const BOOLEAN = Object.freeze({ + __one_of: [true, false], }); diff --git a/src/plugins/console/server/lib/spec_definitions/spec/.eslintrc b/src/plugins/console/server/lib/spec_definitions/json/.eslintrc similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/.eslintrc rename to src/plugins/console/server/lib/spec_definitions/json/.eslintrc diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/_common.json b/src/plugins/console/server/lib/spec_definitions/json/generated/_common.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/_common.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/_common.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/bulk.json b/src/plugins/console/server/lib/spec_definitions/json/generated/bulk.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/bulk.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/bulk.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.aliases.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.aliases.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.aliases.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.aliases.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.allocation.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.allocation.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.allocation.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.allocation.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.count.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.count.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.count.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.count.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.fielddata.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.fielddata.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.fielddata.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.fielddata.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.health.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.health.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.health.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.health.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.help.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.help.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.help.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.help.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.indices.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.indices.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.indices.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.indices.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.master.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.master.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.master.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.master.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.nodeattrs.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.nodeattrs.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.nodeattrs.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.nodeattrs.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.nodes.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.nodes.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.nodes.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.nodes.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.pending_tasks.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.pending_tasks.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.pending_tasks.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.pending_tasks.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.plugins.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.plugins.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.plugins.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.plugins.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.recovery.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.recovery.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.recovery.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.recovery.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.repositories.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.repositories.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.repositories.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.repositories.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.segments.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.segments.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.segments.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.segments.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.shards.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.shards.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.shards.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.shards.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.snapshots.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.snapshots.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.snapshots.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.snapshots.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.tasks.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.tasks.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.tasks.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.tasks.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.templates.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.templates.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.templates.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.templates.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cat.thread_pool.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cat.thread_pool.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cat.thread_pool.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cat.thread_pool.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/clear_scroll.json b/src/plugins/console/server/lib/spec_definitions/json/generated/clear_scroll.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/clear_scroll.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/clear_scroll.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.allocation_explain.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.allocation_explain.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.allocation_explain.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.allocation_explain.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.get_settings.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.get_settings.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.get_settings.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.get_settings.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.health.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.health.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.health.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.health.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.pending_tasks.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.pending_tasks.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.pending_tasks.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.pending_tasks.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.put_settings.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.put_settings.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.put_settings.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.put_settings.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.remote_info.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.remote_info.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.remote_info.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.remote_info.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.reroute.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.reroute.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.reroute.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.reroute.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.state.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.state.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.state.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.state.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.stats.json b/src/plugins/console/server/lib/spec_definitions/json/generated/cluster.stats.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/cluster.stats.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/cluster.stats.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/count.json b/src/plugins/console/server/lib/spec_definitions/json/generated/count.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/count.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/count.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/create.json b/src/plugins/console/server/lib/spec_definitions/json/generated/create.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/create.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/create.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/delete.json b/src/plugins/console/server/lib/spec_definitions/json/generated/delete.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/delete.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/delete.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/delete_by_query.json b/src/plugins/console/server/lib/spec_definitions/json/generated/delete_by_query.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/delete_by_query.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/delete_by_query.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/delete_by_query_rethrottle.json b/src/plugins/console/server/lib/spec_definitions/json/generated/delete_by_query_rethrottle.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/delete_by_query_rethrottle.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/delete_by_query_rethrottle.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/delete_script.json b/src/plugins/console/server/lib/spec_definitions/json/generated/delete_script.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/delete_script.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/delete_script.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/exists.json b/src/plugins/console/server/lib/spec_definitions/json/generated/exists.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/exists.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/exists.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/exists_source.json b/src/plugins/console/server/lib/spec_definitions/json/generated/exists_source.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/exists_source.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/exists_source.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/explain.json b/src/plugins/console/server/lib/spec_definitions/json/generated/explain.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/explain.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/explain.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/field_caps.json b/src/plugins/console/server/lib/spec_definitions/json/generated/field_caps.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/field_caps.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/field_caps.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/get.json b/src/plugins/console/server/lib/spec_definitions/json/generated/get.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/get.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/get.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/get_script.json b/src/plugins/console/server/lib/spec_definitions/json/generated/get_script.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/get_script.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/get_script.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/get_script_context.json b/src/plugins/console/server/lib/spec_definitions/json/generated/get_script_context.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/get_script_context.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/get_script_context.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/get_script_languages.json b/src/plugins/console/server/lib/spec_definitions/json/generated/get_script_languages.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/get_script_languages.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/get_script_languages.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/get_source.json b/src/plugins/console/server/lib/spec_definitions/json/generated/get_source.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/get_source.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/get_source.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/index.json b/src/plugins/console/server/lib/spec_definitions/json/generated/index.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/index.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/index.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.analyze.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.analyze.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.analyze.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.analyze.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.clear_cache.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.clear_cache.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.clear_cache.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.clear_cache.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.clone.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.clone.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.clone.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.clone.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.close.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.close.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.close.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.close.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.create.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.create.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.create.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.create.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.delete.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.delete.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.delete.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.delete.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.delete_alias.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.delete_alias.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.delete_alias.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.delete_alias.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.delete_template.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.delete_template.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.delete_template.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.delete_template.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.exists.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.exists.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.exists_alias.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists_alias.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.exists_alias.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists_alias.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.exists_template.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists_template.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.exists_template.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists_template.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.exists_type.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists_type.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.exists_type.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.exists_type.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.flush.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.flush.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.flush.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.flush.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.flush_synced.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.flush_synced.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.flush_synced.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.flush_synced.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.forcemerge.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.forcemerge.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.forcemerge.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.forcemerge.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.get.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_alias.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_alias.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_alias.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_alias.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_field_mapping.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_field_mapping.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_field_mapping.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_field_mapping.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_mapping.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_mapping.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_mapping.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_mapping.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_settings.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_settings.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_settings.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_settings.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_template.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_template.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_template.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_template.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_upgrade.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_upgrade.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.get_upgrade.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.get_upgrade.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.open.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.open.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.open.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.open.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.put_alias.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.put_alias.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.put_alias.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.put_alias.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.put_mapping.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.put_mapping.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.put_mapping.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.put_mapping.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.put_settings.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.put_settings.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.put_settings.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.put_settings.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.put_template.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.put_template.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.put_template.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.put_template.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.recovery.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.recovery.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.recovery.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.recovery.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.refresh.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.refresh.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.refresh.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.refresh.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.rollover.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.rollover.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.rollover.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.rollover.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.segments.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.segments.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.segments.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.segments.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.shard_stores.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.shard_stores.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.shard_stores.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.shard_stores.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.shrink.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.shrink.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.shrink.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.shrink.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.split.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.split.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.split.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.split.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.stats.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.stats.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.stats.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.stats.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.update_aliases.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.update_aliases.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.update_aliases.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.update_aliases.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.upgrade.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.upgrade.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.upgrade.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.upgrade.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/indices.validate_query.json b/src/plugins/console/server/lib/spec_definitions/json/generated/indices.validate_query.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/indices.validate_query.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/indices.validate_query.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/info.json b/src/plugins/console/server/lib/spec_definitions/json/generated/info.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/info.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/info.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.delete_pipeline.json b/src/plugins/console/server/lib/spec_definitions/json/generated/ingest.delete_pipeline.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.delete_pipeline.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/ingest.delete_pipeline.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.get_pipeline.json b/src/plugins/console/server/lib/spec_definitions/json/generated/ingest.get_pipeline.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.get_pipeline.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/ingest.get_pipeline.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.processor_grok.json b/src/plugins/console/server/lib/spec_definitions/json/generated/ingest.processor_grok.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.processor_grok.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/ingest.processor_grok.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.put_pipeline.json b/src/plugins/console/server/lib/spec_definitions/json/generated/ingest.put_pipeline.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.put_pipeline.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/ingest.put_pipeline.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.simulate.json b/src/plugins/console/server/lib/spec_definitions/json/generated/ingest.simulate.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/ingest.simulate.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/ingest.simulate.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/mget.json b/src/plugins/console/server/lib/spec_definitions/json/generated/mget.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/mget.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/mget.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/msearch.json b/src/plugins/console/server/lib/spec_definitions/json/generated/msearch.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/msearch.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/msearch.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/msearch_template.json b/src/plugins/console/server/lib/spec_definitions/json/generated/msearch_template.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/msearch_template.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/msearch_template.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/mtermvectors.json b/src/plugins/console/server/lib/spec_definitions/json/generated/mtermvectors.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/mtermvectors.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/mtermvectors.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.hot_threads.json b/src/plugins/console/server/lib/spec_definitions/json/generated/nodes.hot_threads.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.hot_threads.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/nodes.hot_threads.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.info.json b/src/plugins/console/server/lib/spec_definitions/json/generated/nodes.info.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.info.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/nodes.info.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.reload_secure_settings.json b/src/plugins/console/server/lib/spec_definitions/json/generated/nodes.reload_secure_settings.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.reload_secure_settings.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/nodes.reload_secure_settings.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.stats.json b/src/plugins/console/server/lib/spec_definitions/json/generated/nodes.stats.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.stats.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/nodes.stats.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.usage.json b/src/plugins/console/server/lib/spec_definitions/json/generated/nodes.usage.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/nodes.usage.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/nodes.usage.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/ping.json b/src/plugins/console/server/lib/spec_definitions/json/generated/ping.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/ping.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/ping.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/put_script.json b/src/plugins/console/server/lib/spec_definitions/json/generated/put_script.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/put_script.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/put_script.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/rank_eval.json b/src/plugins/console/server/lib/spec_definitions/json/generated/rank_eval.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/rank_eval.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/rank_eval.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/reindex.json b/src/plugins/console/server/lib/spec_definitions/json/generated/reindex.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/reindex.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/reindex.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/reindex_rethrottle.json b/src/plugins/console/server/lib/spec_definitions/json/generated/reindex_rethrottle.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/reindex_rethrottle.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/reindex_rethrottle.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/render_search_template.json b/src/plugins/console/server/lib/spec_definitions/json/generated/render_search_template.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/render_search_template.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/render_search_template.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/scripts_painless_execute.json b/src/plugins/console/server/lib/spec_definitions/json/generated/scripts_painless_execute.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/scripts_painless_execute.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/scripts_painless_execute.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/scroll.json b/src/plugins/console/server/lib/spec_definitions/json/generated/scroll.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/scroll.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/scroll.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/search.json b/src/plugins/console/server/lib/spec_definitions/json/generated/search.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/search.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/search.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/search_shards.json b/src/plugins/console/server/lib/spec_definitions/json/generated/search_shards.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/search_shards.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/search_shards.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/search_template.json b/src/plugins/console/server/lib/spec_definitions/json/generated/search_template.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/search_template.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/search_template.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.cleanup_repository.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.cleanup_repository.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.cleanup_repository.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.cleanup_repository.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.create.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.create.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.create.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.create.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.create_repository.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.create_repository.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.create_repository.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.create_repository.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.delete.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.delete.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.delete.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.delete.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.delete_repository.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.delete_repository.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.delete_repository.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.delete_repository.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.get.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.get.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.get.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.get.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.get_repository.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.get_repository.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.get_repository.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.get_repository.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.restore.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.restore.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.restore.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.restore.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.status.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.status.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.status.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.status.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.verify_repository.json b/src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.verify_repository.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/snapshot.verify_repository.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/snapshot.verify_repository.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/tasks.cancel.json b/src/plugins/console/server/lib/spec_definitions/json/generated/tasks.cancel.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/tasks.cancel.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/tasks.cancel.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/tasks.get.json b/src/plugins/console/server/lib/spec_definitions/json/generated/tasks.get.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/tasks.get.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/tasks.get.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/tasks.list.json b/src/plugins/console/server/lib/spec_definitions/json/generated/tasks.list.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/tasks.list.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/tasks.list.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/termvectors.json b/src/plugins/console/server/lib/spec_definitions/json/generated/termvectors.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/termvectors.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/termvectors.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/update.json b/src/plugins/console/server/lib/spec_definitions/json/generated/update.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/update.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/update.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/update_by_query.json b/src/plugins/console/server/lib/spec_definitions/json/generated/update_by_query.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/update_by_query.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/update_by_query.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/generated/update_by_query_rethrottle.json b/src/plugins/console/server/lib/spec_definitions/json/generated/update_by_query_rethrottle.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/generated/update_by_query_rethrottle.json rename to src/plugins/console/server/lib/spec_definitions/json/generated/update_by_query_rethrottle.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/index.js b/src/plugins/console/server/lib/spec_definitions/json/index.js similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/index.js rename to src/plugins/console/server/lib/spec_definitions/json/index.js diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/clear_scroll.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/clear_scroll.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/clear_scroll.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/clear_scroll.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/cluster.health.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/cluster.health.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/cluster.health.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/cluster.health.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/cluster.put_settings.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/cluster.put_settings.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/cluster.put_settings.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/cluster.put_settings.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/cluster.reroute.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/cluster.reroute.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/cluster.reroute.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/cluster.reroute.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/count.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/count.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/count.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/count.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.analyze.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.analyze.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.analyze.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.analyze.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.clone.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.clone.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.clone.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.clone.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.create.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.create.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.create.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.create.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.delete_template.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.delete_template.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.delete_template.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.delete_template.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.exists_template.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.exists_template.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.exists_template.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.exists_template.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.get_field_mapping.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.get_field_mapping.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.get_field_mapping.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.get_field_mapping.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.get_mapping.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.get_mapping.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.get_mapping.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.get_mapping.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.get_template.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.get_template.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.get_template.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.get_template.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.put_alias.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.put_alias.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.put_alias.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.put_alias.json diff --git a/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.put_settings.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.put_settings.json new file mode 100644 index 0000000000000..2ae8fd82be4d8 --- /dev/null +++ b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.put_settings.json @@ -0,0 +1,7 @@ +{ + "indices.put_settings": { + "data_autocomplete_rules": { + "__scope_link": "put_settings" + } + } +} diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.put_template.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.put_template.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.put_template.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.put_template.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.rollover.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.rollover.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.rollover.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.rollover.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.update_aliases.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.update_aliases.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.update_aliases.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.update_aliases.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.validate_query.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/indices.validate_query.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.validate_query.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/indices.validate_query.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/snapshot.create.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/snapshot.create.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/snapshot.create.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/snapshot.create.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/snapshot.create_repository.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/snapshot.create_repository.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/snapshot.create_repository.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/snapshot.create_repository.json diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/snapshot.restore.json b/src/plugins/console/server/lib/spec_definitions/json/overrides/snapshot.restore.json similarity index 100% rename from src/plugins/console/server/lib/spec_definitions/spec/overrides/snapshot.restore.json rename to src/plugins/console/server/lib/spec_definitions/json/overrides/snapshot.restore.json diff --git a/src/plugins/console/server/lib/spec_definitions/server.js b/src/plugins/console/server/lib/spec_definitions/server.js index dd700bf019507..cb855958d403a 100644 --- a/src/plugins/console/server/lib/spec_definitions/server.js +++ b/src/plugins/console/server/lib/spec_definitions/server.js @@ -17,21 +17,10 @@ * under the License. */ -import _ from 'lodash'; +import es from './es'; -const KNOWN_APIS = ['es_6_0']; - -export function resolveApi(senseVersion, apis) { - const result = {}; - _.each(apis, function(name) { - { - if (KNOWN_APIS.includes(name)) { - // for now we ignore sense_version. might add it in the api name later - const api = require('./' + name); // eslint-disable-line import/no-dynamic-require - result[name] = api.asJson(); - } - } - }); - - return result; +export function resolveApi() { + return { + es: es.asJson(), + }; } diff --git a/src/plugins/console/server/lib/spec_definitions/server.test.js b/src/plugins/console/server/lib/spec_definitions/server.test.js deleted file mode 100644 index 747689237c177..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/server.test.js +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -import { resolveApi } from './server'; - -describe('resolveApi', () => { - it('allows known APIs to be resolved', () => { - const mockReply = jest.fn(result => ({ type: () => result })); - const result = resolveApi('Sense Version', ['es_6_0'], { response: mockReply }); - expect(result).toMatchObject({ - es_6_0: { - endpoints: expect.any(Object), - globals: expect.any(Object), - name: expect.any(String), - }, - }); - }); - - it('does not resolve APIs that are not known', () => { - const mockReply = jest.fn(result => ({ type: () => result })); - const result = resolveApi('Sense Version', ['unknown'], { response: mockReply }); - expect(result).toEqual({}); - }); - - it('handles request for apis that are known and unknown', () => { - const mockReply = jest.fn(result => ({ type: () => result })); - const result = resolveApi('Sense Version', ['es_6_0'], { response: mockReply }); - expect(result).toMatchObject({ - es_6_0: { - endpoints: expect.any(Object), - globals: expect.any(Object), - name: expect.any(String), - }, - }); - }); -}); diff --git a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.put_settings.json b/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.put_settings.json deleted file mode 100644 index 2e1e3024665a4..0000000000000 --- a/src/plugins/console/server/lib/spec_definitions/spec/overrides/indices.put_settings.json +++ /dev/null @@ -1,108 +0,0 @@ -{ - "indices.put_settings": { - "data_autocomplete_rules": { - "refresh_interval": "1s", - "number_of_shards": 1, - "number_of_replicas": 1, - "blocks.read_only": { - "__one_of": [ - false, - true - ] - }, - "blocks.read": { - "__one_of": [ - true, - false - ] - }, - "blocks.write": { - "__one_of": [ - true, - false - ] - }, - "blocks.metadata": { - "__one_of": [ - true, - false - ] - }, - "term_index_interval": 32, - "term_index_divisor": 1, - "translog.flush_threshold_ops": 5000, - "translog.flush_threshold_size": "200mb", - "translog.flush_threshold_period": "30m", - "translog.disable_flush": { - "__one_of": [ - true, - false - ] - }, - "cache.filter.max_size": "2gb", - "cache.filter.expire": "2h", - "gateway.snapshot_interval": "10s", - "routing": { - "allocation": { - "include": { - "tag": "" - }, - "exclude": { - "tag": "" - }, - "require": { - "tag": "" - }, - "total_shards_per_node": -1 - } - }, - "recovery.initial_shards": { - "__one_of": [ - "quorum", - "quorum-1", - "half", - "full", - "full-1" - ] - }, - "ttl.disable_purge": { - "__one_of": [ - true, - false - ] - }, - "analysis": { - "analyzer": {}, - "tokenizer": {}, - "filter": {}, - "char_filter": {} - }, - "cache.query.enable": { - "__one_of": [ - true, - false - ] - }, - "shadow_replicas": { - "__one_of": [ - true, - false - ] - }, - "shared_filesystem": { - "__one_of": [ - true, - false - ] - }, - "data_path": "path", - "codec": { - "__one_of": [ - "default", - "best_compression", - "lucene_default" - ] - } - } - } -} diff --git a/src/plugins/console/server/plugin.ts b/src/plugins/console/server/plugin.ts index 65647bd5acb7c..1954918f4d74f 100644 --- a/src/plugins/console/server/plugin.ts +++ b/src/plugins/console/server/plugin.ts @@ -21,7 +21,12 @@ import { CoreSetup, Logger, Plugin, PluginInitializerContext } from 'kibana/serv import { readLegacyEsConfig } from '../../../legacy/core_plugins/console_legacy'; -import { ProxyConfigCollection, addExtensionSpecFilePath, addProcessorDefinition } from './lib'; +import { + ProxyConfigCollection, + addExtensionSpecFilePath, + addProcessorDefinition, + loadSpec, +} from './lib'; import { ConfigType } from './config'; import { registerProxyRoute } from './routes/api/console/proxy'; import { registerSpecDefinitionsRoute } from './routes/api/console/spec_definitions'; @@ -75,5 +80,7 @@ export class ConsoleServerPlugin implements Plugin { }; } - start() {} + start() { + loadSpec(); + } } diff --git a/src/plugins/console/server/routes/api/console/spec_definitions/index.ts b/src/plugins/console/server/routes/api/console/spec_definitions/index.ts index e2ece37f407ac..88bc250bbfce6 100644 --- a/src/plugins/console/server/routes/api/console/spec_definitions/index.ts +++ b/src/plugins/console/server/routes/api/console/spec_definitions/index.ts @@ -16,33 +16,19 @@ * specific language governing permissions and limitations * under the License. */ -import { schema, TypeOf } from '@kbn/config-schema'; import { IRouter, RequestHandler } from 'kibana/server'; import { resolveApi } from '../../../../lib/spec_definitions'; export const registerSpecDefinitionsRoute = ({ router }: { router: IRouter }) => { - const handler: RequestHandler> = async ( - ctx, - request, - response - ) => { - const { sense_version: version, apis } = request.query; - + const handler: RequestHandler = async (ctx, request, response) => { return response.ok({ - body: resolveApi(version, apis.split(',')), + body: resolveApi(), headers: { 'Content-Type': 'application/json', }, }); }; - const validate = { - query: schema.object({ - sense_version: schema.string({ defaultValue: '' }), - apis: schema.string(), - }), - }; - - router.get({ path: '/api/console/api_server', validate }, handler); - router.post({ path: '/api/console/api_server', validate }, handler); + router.get({ path: '/api/console/api_server', validate: false }, handler); + router.post({ path: '/api/console/api_server', validate: false }, handler); }; diff --git a/src/plugins/data/server/index.ts b/src/plugins/data/server/index.ts index 0165486fc2de7..5038b4226fad8 100644 --- a/src/plugins/data/server/index.ts +++ b/src/plugins/data/server/index.ts @@ -166,7 +166,7 @@ export { ParsedInterval } from '../common'; export { ISearch, - ICancel, + ISearchCancel, ISearchOptions, IRequestTypesMap, IResponseTypesMap, diff --git a/src/plugins/data/server/search/i_route_handler_search_context.ts b/src/plugins/data/server/search/i_route_handler_search_context.ts index 89862781b826e..9888c774ea104 100644 --- a/src/plugins/data/server/search/i_route_handler_search_context.ts +++ b/src/plugins/data/server/search/i_route_handler_search_context.ts @@ -17,9 +17,9 @@ * under the License. */ -import { ISearchGeneric, ICancelGeneric } from './i_search'; +import { ISearchGeneric, ISearchCancelGeneric } from './i_search'; export interface IRouteHandlerSearchContext { search: ISearchGeneric; - cancel: ICancelGeneric; + cancel: ISearchCancelGeneric; } diff --git a/src/plugins/data/server/search/i_search.ts b/src/plugins/data/server/search/i_search.ts index ea014c5e136d9..fa4aa72ac7287 100644 --- a/src/plugins/data/server/search/i_search.ts +++ b/src/plugins/data/server/search/i_search.ts @@ -42,7 +42,7 @@ export type ISearchGeneric = Promise; -export type ICancelGeneric = ( +export type ISearchCancelGeneric = ( id: string, strategy?: T ) => Promise; @@ -52,4 +52,4 @@ export type ISearch = ( options?: ISearchOptions ) => Promise; -export type ICancel = (id: string) => Promise; +export type ISearchCancel = (id: string) => Promise; diff --git a/src/plugins/data/server/search/i_search_strategy.ts b/src/plugins/data/server/search/i_search_strategy.ts index 4cfc9608383a9..9b405034f883f 100644 --- a/src/plugins/data/server/search/i_search_strategy.ts +++ b/src/plugins/data/server/search/i_search_strategy.ts @@ -18,7 +18,7 @@ */ import { APICaller } from 'kibana/server'; -import { ISearch, ICancel, ISearchGeneric } from './i_search'; +import { ISearch, ISearchCancel, ISearchGeneric } from './i_search'; import { TStrategyTypes } from './strategy_types'; import { ISearchContext } from './i_search_context'; @@ -28,7 +28,7 @@ import { ISearchContext } from './i_search_context'; */ export interface ISearchStrategy { search: ISearch; - cancel?: ICancel; + cancel?: ISearchCancel; } /** diff --git a/src/plugins/data/server/search/index.ts b/src/plugins/data/server/search/index.ts index 385e96ee803b6..15738a3befb27 100644 --- a/src/plugins/data/server/search/index.ts +++ b/src/plugins/data/server/search/index.ts @@ -21,7 +21,13 @@ export { ISearchSetup } from './i_search_setup'; export { ISearchContext } from './i_search_context'; -export { ISearch, ICancel, ISearchOptions, IRequestTypesMap, IResponseTypesMap } from './i_search'; +export { + ISearch, + ISearchCancel, + ISearchOptions, + IRequestTypesMap, + IResponseTypesMap, +} from './i_search'; export { TStrategyTypes } from './strategy_types'; diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index 2a2d9bb414c14..178b2949a9456 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -329,12 +329,6 @@ export function getDefaultSearchParams(config: SharedGlobalConfig): { restTotalHitsAsInt: boolean; }; -// Warning: (ae-forgotten-export) The symbol "TStrategyTypes" needs to be exported by the entry point index.d.ts -// Warning: (ae-missing-release-tag) "ICancel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) -// -// @public (undocumented) -export type ICancel = (id: string) => Promise; - // Warning: (ae-missing-release-tag) "IFieldFormatsRegistry" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) @@ -507,11 +501,17 @@ export interface IResponseTypesMap { [ES_SEARCH_STRATEGY]: IEsSearchResponse; } +// Warning: (ae-forgotten-export) The symbol "TStrategyTypes" needs to be exported by the entry point index.d.ts // Warning: (ae-missing-release-tag) "ISearch" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) export type ISearch = (request: IRequestTypesMap[T], options?: ISearchOptions) => Promise; +// Warning: (ae-missing-release-tag) "ISearchCancel" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) +// +// @public (undocumented) +export type ISearchCancel = (id: string) => Promise; + // Warning: (ae-missing-release-tag) "ISearchContext" is exported by the package, but it is missing a release tag (@alpha, @beta, @public, or @internal) // // @public (undocumented) diff --git a/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/view.tsx b/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/view.tsx index 31fc4db8f1a2f..cff190cd98a11 100644 --- a/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/view.tsx +++ b/x-pack/legacy/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/MachineLearningFlyout/view.tsx @@ -209,7 +209,7 @@ export function MachineLearningFlyoutView({ {i18n.translate( 'xpack.apm.serviceDetails.enableAnomalyDetectionPanel.createNewJobButtonLabel', { - defaultMessage: 'Create new job' + defaultMessage: 'Create job' } )} diff --git a/x-pack/legacy/plugins/maps/public/meta.js b/x-pack/legacy/plugins/maps/public/meta.js index c5cfb582976c1..4d81785ff7a0a 100644 --- a/x-pack/legacy/plugins/maps/public/meta.js +++ b/x-pack/legacy/plugins/maps/public/meta.js @@ -9,6 +9,7 @@ import { EMS_FILES_CATALOGUE_PATH, EMS_TILES_CATALOGUE_PATH, EMS_GLYPHS_PATH, + EMS_APP_NAME, } from '../common/constants'; import chrome from 'ui/chrome'; import { i18n } from '@kbn/i18n'; @@ -56,7 +57,8 @@ export function getEMSClient() { emsClient = new EMSClient({ language: i18n.getLocale(), - kbnVersion: chrome.getInjected('kbnPkgVersion'), + appVersion: chrome.getInjected('kbnPkgVersion'), + appName: EMS_APP_NAME, tileApiUrl, fileApiUrl, landingPageUrl: chrome.getInjected('emsLandingPageUrl'), diff --git a/x-pack/legacy/plugins/maps/server/routes.js b/x-pack/legacy/plugins/maps/server/routes.js index 757750dbb0813..7ca659148449f 100644 --- a/x-pack/legacy/plugins/maps/server/routes.js +++ b/x-pack/legacy/plugins/maps/server/routes.js @@ -5,6 +5,7 @@ */ import { + EMS_APP_NAME, EMS_CATALOGUE_PATH, EMS_FILES_API_PATH, EMS_FILES_CATALOGUE_PATH, @@ -38,7 +39,8 @@ export function initRoutes(server, licenseUid) { if (mapConfig.includeElasticMapsService) { emsClient = new EMSClient({ language: i18n.getLocale(), - kbnVersion: serverConfig.get('pkg.version'), + appVersion: serverConfig.get('pkg.version'), + appName: EMS_APP_NAME, fileApiUrl: mapConfig.emsFileApiUrl, tileApiUrl: mapConfig.emsTileApiUrl, landingPageUrl: mapConfig.emsLandingPageUrl, diff --git a/x-pack/package.json b/x-pack/package.json index 3c8aa435c3e43..6f15b46e28f53 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -179,7 +179,7 @@ "@babel/runtime": "^7.5.5", "@elastic/apm-rum-react": "^0.3.2", "@elastic/datemath": "5.0.2", - "@elastic/ems-client": "7.6.0", + "@elastic/ems-client": "7.7.0", "@elastic/eui": "20.0.2", "@elastic/filesaver": "1.1.2", "@elastic/maki": "6.1.0", @@ -317,7 +317,7 @@ "react-sticky": "^6.0.3", "react-syntax-highlighter": "^5.7.0", "react-tiny-virtual-list": "^2.2.0", - "react-use": "^13.13.0", + "react-use": "^13.27.0", "react-vis": "^1.8.1", "react-visibility-sensor": "^5.1.1", "recompose": "^0.26.0", diff --git a/x-pack/plugins/actions/server/builtin_action_types/es_index.test.ts b/x-pack/plugins/actions/server/builtin_action_types/es_index.test.ts index 0be1983477256..7eded9bb40964 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/es_index.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/es_index.test.ts @@ -43,18 +43,46 @@ describe('actionTypeRegistry.get() works', () => { describe('config validation', () => { test('config validation succeeds when config is valid', () => { - const config: Record = {}; + const config: Record = { + index: 'testing-123', + refresh: false, + }; expect(validateConfig(actionType, config)).toEqual({ ...config, - index: null, + index: 'testing-123', + refresh: false, }); - config.index = 'testing-123'; + config.executionTimeField = 'field-123'; expect(validateConfig(actionType, config)).toEqual({ ...config, index: 'testing-123', + refresh: false, + executionTimeField: 'field-123', }); + + delete config.index; + + expect(() => { + validateConfig(actionType, { index: 666 }); + }).toThrowErrorMatchingInlineSnapshot( + `"error validating action type config: [index]: expected value of type [string] but got [number]"` + ); + delete config.executionTimeField; + + expect(() => { + validateConfig(actionType, { index: 'testing-123', executionTimeField: true }); + }).toThrowErrorMatchingInlineSnapshot( + `"error validating action type config: [executionTimeField]: expected value of type [string] but got [boolean]"` + ); + + delete config.refresh; + expect(() => { + validateConfig(actionType, { index: 'testing-123', refresh: 'foo' }); + }).toThrowErrorMatchingInlineSnapshot( + `"error validating action type config: [refresh]: expected value of type [boolean] but got [string]"` + ); }); test('config validation fails when config is not valid', () => { @@ -65,46 +93,16 @@ describe('config validation', () => { expect(() => { validateConfig(actionType, baseConfig); }).toThrowErrorMatchingInlineSnapshot( - `"error validating action type config: [indeX]: definition for this key is missing"` + `"error validating action type config: [index]: expected value of type [string] but got [undefined]"` ); - - delete baseConfig.user; - baseConfig.index = 666; - - expect(() => { - validateConfig(actionType, baseConfig); - }).toThrowErrorMatchingInlineSnapshot(` -"error validating action type config: [index]: types that failed validation: -- [index.0]: expected value of type [string] but got [number] -- [index.1]: expected value to equal [null]" -`); }); }); describe('params validation', () => { test('params validation succeeds when params is valid', () => { const params: Record = { - index: 'testing-123', - executionTimeField: 'field-used-for-time', - refresh: true, documents: [{ rando: 'thing' }], }; - expect(validateParams(actionType, params)).toMatchInlineSnapshot(` - Object { - "documents": Array [ - Object { - "rando": "thing", - }, - ], - "executionTimeField": "field-used-for-time", - "index": "testing-123", - "refresh": true, - } - `); - - delete params.index; - delete params.refresh; - delete params.executionTimeField; expect(validateParams(actionType, params)).toMatchInlineSnapshot(` Object { "documents": Array [ @@ -129,24 +127,6 @@ describe('params validation', () => { `"error validating action params: [documents]: expected value of type [array] but got [undefined]"` ); - expect(() => { - validateParams(actionType, { index: 666 }); - }).toThrowErrorMatchingInlineSnapshot( - `"error validating action params: [index]: expected value of type [string] but got [number]"` - ); - - expect(() => { - validateParams(actionType, { executionTimeField: true }); - }).toThrowErrorMatchingInlineSnapshot( - `"error validating action params: [executionTimeField]: expected value of type [string] but got [boolean]"` - ); - - expect(() => { - validateParams(actionType, { refresh: 'foo' }); - }).toThrowErrorMatchingInlineSnapshot( - `"error validating action params: [refresh]: expected value of type [boolean] but got [string]"` - ); - expect(() => { validateParams(actionType, { documents: ['should be an object'] }); }).toThrowErrorMatchingInlineSnapshot( @@ -162,13 +142,10 @@ describe('execute()', () => { let params: ActionParamsType; let executorOptions: ActionTypeExecutorOptions; - // minimal params, index via param - config = { index: null }; + // minimal params + config = { index: 'index-value', refresh: false, executionTimeField: undefined }; params = { - index: 'index-via-param', documents: [{ jim: 'bob' }], - executionTimeField: undefined, - refresh: undefined, }; const actionId = 'some-id'; @@ -190,19 +167,17 @@ describe('execute()', () => { "jim": "bob", }, ], - "index": "index-via-param", + "index": "index-value", + "refresh": false, }, ], ] `); - // full params (except index), index via config - config = { index: 'index-via-config' }; + // full params + config = { index: 'index-value', executionTimeField: 'field_to_use_for_time', refresh: true }; params = { - index: undefined, documents: [{ jimbob: 'jr' }], - executionTimeField: 'field_to_use_for_time', - refresh: true, }; executorOptions = { actionId, config, secrets, params, services }; @@ -226,20 +201,17 @@ describe('execute()', () => { "jimbob": "jr", }, ], - "index": "index-via-config", + "index": "index-value", "refresh": true, }, ], ] `); - // minimal params, index via config and param - config = { index: 'index-via-config' }; + // minimal params + config = { index: 'index-value', executionTimeField: undefined, refresh: false }; params = { - index: 'index-via-param', documents: [{ jim: 'bob' }], - executionTimeField: undefined, - refresh: undefined, }; executorOptions = { actionId, config, secrets, params, services }; @@ -259,19 +231,17 @@ describe('execute()', () => { "jim": "bob", }, ], - "index": "index-via-config", + "index": "index-value", + "refresh": false, }, ], ] `); // multiple documents - config = { index: null }; + config = { index: 'index-value', executionTimeField: undefined, refresh: false }; params = { - index: 'index-via-param', documents: [{ a: 1 }, { b: 2 }], - executionTimeField: undefined, - refresh: undefined, }; executorOptions = { actionId, config, secrets, params, services }; @@ -297,7 +267,8 @@ describe('execute()', () => { "b": 2, }, ], - "index": "index-via-param", + "index": "index-value", + "refresh": false, }, ], ] diff --git a/x-pack/plugins/actions/server/builtin_action_types/es_index.ts b/x-pack/plugins/actions/server/builtin_action_types/es_index.ts index f8217046b2ea5..b1fe5e3af2d11 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/es_index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/es_index.ts @@ -8,7 +8,6 @@ import { curry } from 'lodash'; import { i18n } from '@kbn/i18n'; import { schema, TypeOf } from '@kbn/config-schema'; -import { nullableType } from './lib/nullable'; import { Logger } from '../../../../../src/core/server'; import { ActionType, ActionTypeExecutorOptions, ActionTypeExecutorResult } from '../types'; @@ -17,7 +16,9 @@ import { ActionType, ActionTypeExecutorOptions, ActionTypeExecutorResult } from export type ActionTypeConfigType = TypeOf; const ConfigSchema = schema.object({ - index: nullableType(schema.string()), + index: schema.string(), + refresh: schema.boolean({ defaultValue: false }), + executionTimeField: schema.maybe(schema.string()), }); // params definition @@ -28,9 +29,6 @@ export type ActionParamsType = TypeOf; // - timeout not added here, as this seems to be a generic thing we want to do // eventually: https://github.com/elastic/kibana/projects/26#card-24087404 const ParamsSchema = schema.object({ - index: schema.maybe(schema.string()), - executionTimeField: schema.maybe(schema.string()), - refresh: schema.maybe(schema.boolean()), documents: schema.arrayOf(schema.recordOf(schema.string(), schema.any())), }); @@ -60,27 +58,12 @@ async function executor( const params = execOptions.params as ActionParamsType; const services = execOptions.services; - if (config.index == null && params.index == null) { - const message = i18n.translate('xpack.actions.builtin.esIndex.indexParamRequiredErrorMessage', { - defaultMessage: 'index param needs to be set because not set in config for action', - }); - return { - status: 'error', - actionId, - message, - }; - } - - if (config.index != null && params.index != null) { - logger.debug(`index passed in params overridden by index set in config for action ${actionId}`); - } - - const index = config.index || params.index; + const index = config.index; const bulkBody = []; for (const document of params.documents) { - if (params.executionTimeField != null) { - document[params.executionTimeField] = new Date(); + if (config.executionTimeField != null) { + document[config.executionTimeField] = new Date(); } bulkBody.push({ index: {} }); @@ -92,9 +75,7 @@ async function executor( body: bulkBody, }; - if (params.refresh != null) { - bulkParams.refresh = params.refresh; - } + bulkParams.refresh = config.refresh; let result; try { @@ -103,6 +84,7 @@ async function executor( const message = i18n.translate('xpack.actions.builtin.esIndex.errorIndexingErrorMessage', { defaultMessage: 'error indexing documents', }); + logger.error(`error indexing documents: ${err.message}`); return { status: 'error', actionId, diff --git a/x-pack/plugins/alerting/server/plugin.ts b/x-pack/plugins/alerting/server/plugin.ts index 1269dd38c561e..8d54432f7d9c3 100644 --- a/x-pack/plugins/alerting/server/plugin.ts +++ b/x-pack/plugins/alerting/server/plugin.ts @@ -174,16 +174,6 @@ export class AlertingPlugin { muteAlertInstanceRoute(router, this.licenseState); unmuteAlertInstanceRoute(router, this.licenseState); - alertTypeRegistry.register({ - id: 'test', - actionGroups: [{ id: 'default', name: 'Default' }], - defaultActionGroupId: 'default', - name: 'Test', - executor: async options => { - return { status: 'ok' }; - }, - }); - return { registerType: alertTypeRegistry.register.bind(alertTypeRegistry), }; diff --git a/x-pack/plugins/console_extensions/server/spec/generated/ml.estimate_memory_usage.json b/x-pack/plugins/console_extensions/server/spec/generated/ml.estimate_memory_usage.json index a6ec31465392a..2195b74640c79 100644 --- a/x-pack/plugins/console_extensions/server/spec/generated/ml.estimate_memory_usage.json +++ b/x-pack/plugins/console_extensions/server/spec/generated/ml.estimate_memory_usage.json @@ -1,7 +1,7 @@ { "ml.estimate_memory_usage": { "methods": [ - "POST" + "PUT" ], "patterns": [ "_ml/data_frame/analytics/_estimate_memory_usage" diff --git a/x-pack/plugins/data_enhanced/public/search/es_search_strategy.ts b/x-pack/plugins/data_enhanced/public/search/es_search_strategy.ts index 25c6a789cca93..c493e8ce86781 100644 --- a/x-pack/plugins/data_enhanced/public/search/es_search_strategy.ts +++ b/x-pack/plugins/data_enhanced/public/search/es_search_strategy.ts @@ -10,16 +10,17 @@ import { TSearchStrategyProvider, ISearchContext, ISearch, - SYNC_SEARCH_STRATEGY, getEsPreference, } from '../../../../../src/plugins/data/public'; import { IEnhancedEsSearchRequest, EnhancedSearchParams } from '../../common'; +import { ASYNC_SEARCH_STRATEGY } from './async_search_strategy'; +import { IAsyncSearchOptions } from './types'; export const enhancedEsSearchStrategyProvider: TSearchStrategyProvider = ( context: ISearchContext ) => { - const syncStrategyProvider = context.getSearchStrategy(SYNC_SEARCH_STRATEGY); - const { search: syncSearch } = syncStrategyProvider(context); + const asyncStrategyProvider = context.getSearchStrategy(ASYNC_SEARCH_STRATEGY); + const { search: asyncSearch } = asyncStrategyProvider(context); const search: ISearch = ( request: IEnhancedEsSearchRequest, @@ -32,9 +33,12 @@ export const enhancedEsSearchStrategyProvider: TSearchStrategyProvider; + const asyncOptions: IAsyncSearchOptions = { pollInterval: 0, ...options }; + + return asyncSearch( + { ...request, serverStrategy: ES_SEARCH_STRATEGY }, + asyncOptions + ) as Observable; }; return { search }; diff --git a/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts b/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts index 69b357196dc32..11f0b9a0dc83c 100644 --- a/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts +++ b/x-pack/plugins/data_enhanced/server/search/es_search_strategy.ts @@ -14,10 +14,16 @@ import { TSearchStrategyProvider, ISearch, ISearchOptions, + ISearchCancel, getDefaultSearchParams, } from '../../../../../src/plugins/data/server'; import { IEnhancedEsSearchRequest } from '../../common'; +export interface AsyncSearchResponse { + id: string; + response: SearchResponse; +} + export const enhancedEsSearchStrategyProvider: TSearchStrategyProvider = ( context: ISearchContext, caller: APICaller @@ -28,28 +34,62 @@ export const enhancedEsSearchStrategyProvider: TSearchStrategyProvider { const config = await context.config$.pipe(first()).toPromise(); const defaultParams = getDefaultSearchParams(config); - const params = { ...defaultParams, ...request.params }; + const params = { ...defaultParams, trackTotalHits: true, ...request.params }; - const rawResponse = (await (request.indexType === 'rollup' + const response = await (request.indexType === 'rollup' ? rollupSearch(caller, { ...request, params }, options) - : caller('search', params, options))) as SearchResponse; + : asyncSearch(caller, { ...request, params }, options)); + + const rawResponse = + request.indexType === 'rollup' + ? (response as SearchResponse) + : (response as AsyncSearchResponse).response; + + if (typeof rawResponse.hits.total !== 'number') { + // @ts-ignore This should be fixed as part of https://github.com/elastic/kibana/issues/26356 + rawResponse.hits.total = rawResponse.hits.total.value; + } + const id = (response as AsyncSearchResponse).id; const { total, failed, successful } = rawResponse._shards; const loaded = failed + successful; - return { total, loaded, rawResponse }; + return { id, total, loaded, rawResponse }; }; - return { search }; + const cancel: ISearchCancel = async id => { + const method = 'DELETE'; + const path = `_async_search/${id}`; + await caller('transport.request', { method, path }); + }; + + return { search, cancel }; }; -function rollupSearch( +function asyncSearch( + caller: APICaller, + request: IEnhancedEsSearchRequest, + options?: ISearchOptions +) { + const { body = undefined, index = undefined, ...params } = request.id ? {} : request.params; + + // If we have an ID, then just poll for that ID, otherwise send the entire request body + const method = request.id ? 'GET' : 'POST'; + const path = request.id ? `_async_search/${request.id}` : `${index}/_async_search`; + + // Wait up to 1s for the response to return + const query = toSnakeCase({ waitForCompletion: '1s', ...params }); + + return caller('transport.request', { method, path, body, query }, options); +} + +async function rollupSearch( caller: APICaller, request: IEnhancedEsSearchRequest, options?: ISearchOptions ) { + const { body, index, ...params } = request.params; const method = 'POST'; - const path = `${request.params.index}/_rollup_search`; - const { body, ...params } = request.params; + const path = `${index}/_rollup_search`; const query = toSnakeCase(params); return caller('transport.request', { method, path, body, query }, options); } diff --git a/x-pack/plugins/endpoint/common/generate_data.test.ts b/x-pack/plugins/endpoint/common/generate_data.test.ts index a687d7af1c590..dfb906c7af606 100644 --- a/x-pack/plugins/endpoint/common/generate_data.test.ts +++ b/x-pack/plugins/endpoint/common/generate_data.test.ts @@ -21,8 +21,8 @@ describe('data generator', () => { const generator1 = new EndpointDocGenerator('seed'); const generator2 = new EndpointDocGenerator('seed'); const timestamp = new Date().getTime(); - const metadata1 = generator1.generateEndpointMetadata(timestamp); - const metadata2 = generator2.generateEndpointMetadata(timestamp); + const metadata1 = generator1.generateHostMetadata(timestamp); + const metadata2 = generator2.generateHostMetadata(timestamp); expect(metadata1).toEqual(metadata2); }); @@ -30,14 +30,14 @@ describe('data generator', () => { const generator1 = new EndpointDocGenerator('seed'); const generator2 = new EndpointDocGenerator('different seed'); const timestamp = new Date().getTime(); - const metadata1 = generator1.generateEndpointMetadata(timestamp); - const metadata2 = generator2.generateEndpointMetadata(timestamp); + const metadata1 = generator1.generateHostMetadata(timestamp); + const metadata2 = generator2.generateHostMetadata(timestamp); expect(metadata1).not.toEqual(metadata2); }); - it('creates endpoint metadata documents', () => { + it('creates host metadata documents', () => { const timestamp = new Date().getTime(); - const metadata = generator.generateEndpointMetadata(timestamp); + const metadata = generator.generateHostMetadata(timestamp); expect(metadata['@timestamp']).toEqual(timestamp); expect(metadata.event.created).toEqual(timestamp); expect(metadata.endpoint).not.toBeNull(); diff --git a/x-pack/plugins/endpoint/common/generate_data.ts b/x-pack/plugins/endpoint/common/generate_data.ts index 36896e5af6810..2e1d6074d0c2f 100644 --- a/x-pack/plugins/endpoint/common/generate_data.ts +++ b/x-pack/plugins/endpoint/common/generate_data.ts @@ -6,7 +6,7 @@ import uuid from 'uuid'; import seedrandom from 'seedrandom'; -import { AlertEvent, EndpointEvent, EndpointMetadata, OSFields, HostFields } from './types'; +import { AlertEvent, EndpointEvent, HostMetadata, OSFields, HostFields } from './types'; export type Event = AlertEvent | EndpointEvent; @@ -104,8 +104,8 @@ export class EndpointDocGenerator { this.commonInfo = this.createHostData(); } - // This function will create new values for all the host fields, so documents from a different endpoint can be created - // This provides a convenient way to make documents from multiple endpoints that are all tied to a single seed value + // This function will create new values for all the host fields, so documents from a different host can be created + // This provides a convenient way to make documents from multiple hosts that are all tied to a single seed value public randomizeHostData() { this.commonInfo = this.createHostData(); } @@ -129,7 +129,7 @@ export class EndpointDocGenerator { }; } - public generateEndpointMetadata(ts = new Date().getTime()): EndpointMetadata { + public generateHostMetadata(ts = new Date().getTime()): HostMetadata { return { '@timestamp': ts, event: { diff --git a/x-pack/plugins/endpoint/common/types.ts b/x-pack/plugins/endpoint/common/types.ts index aa326c663965d..e423de56bf817 100644 --- a/x-pack/plugins/endpoint/common/types.ts +++ b/x-pack/plugins/endpoint/common/types.ts @@ -83,10 +83,10 @@ export interface AlertResultList { prev: string | null; } -export interface EndpointResultList { - /* the endpoints restricted by the page size */ - endpoints: EndpointMetadata[]; - /* the total number of unique endpoints in the index */ +export interface HostResultList { + /* the hosts restricted by the page size */ + hosts: HostMetadata[]; + /* the total number of unique hosts in the index */ total: number; /* the page size requested */ request_page_size: number; @@ -243,7 +243,7 @@ interface AlertMetadata { */ export type AlertData = AlertEvent & AlertMetadata; -export interface EndpointMetadata { +export type HostMetadata = Immutable<{ '@timestamp': number; event: { created: number; @@ -258,7 +258,7 @@ export interface EndpointMetadata { version: string; }; host: HostFields; -} +}>; /** * Represents `total` response from Elasticsearch after ES 7.0. diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/components/header_nav.tsx b/x-pack/plugins/endpoint/public/applications/endpoint/components/header_nav.tsx index f7d6551f9093b..1bafcbec93f5f 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/components/header_nav.tsx +++ b/x-pack/plugins/endpoint/public/applications/endpoint/components/header_nav.tsx @@ -24,11 +24,11 @@ export const navTabs: NavTabs[] = [ href: '/', }, { - id: 'management', - name: i18n.translate('xpack.endpoint.headerNav.management', { - defaultMessage: 'Management', + id: 'hosts', + name: i18n.translate('xpack.endpoint.headerNav.hosts', { + defaultMessage: 'Hosts', }), - href: '/management', + href: '/hosts', }, { id: 'alerts', diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/index.tsx b/x-pack/plugins/endpoint/public/applications/endpoint/index.tsx index cec51f570f95d..997113754f95d 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/index.tsx +++ b/x-pack/plugins/endpoint/public/applications/endpoint/index.tsx @@ -11,15 +11,17 @@ import { I18nProvider, FormattedMessage } from '@kbn/i18n/react'; import { Route, Switch, BrowserRouter } from 'react-router-dom'; import { Provider } from 'react-redux'; import { Store } from 'redux'; +import { useObservable } from 'react-use'; import { KibanaContextProvider } from '../../../../../../src/plugins/kibana_react/public'; import { RouteCapture } from './view/route_capture'; import { EndpointPluginStartDependencies } from '../../plugin'; import { appStoreFactory } from './store'; import { AlertIndex } from './view/alerts'; -import { ManagementList } from './view/managing'; +import { HostList } from './view/hosts'; import { PolicyList } from './view/policy'; import { PolicyDetails } from './view/policy'; import { HeaderNavigation } from './components/header_nav'; +import { EuiThemeProvider } from '../../../../../legacy/common/eui_styled_components'; /** * This module will be loaded asynchronously to reduce the bundle size of your plugin's main bundle. @@ -48,43 +50,49 @@ interface RouterProps { } const AppRoot: React.FunctionComponent = React.memo( - ({ basename, store, coreStart: { http, notifications }, depsStart: { data } }) => ( - - - - - - - - ( -

- -

- )} - /> - - - - - ( - { + const isDarkMode = useObservable(uiSettings.get$('theme:darkMode')); + + return ( + + + + + + + + + ( +

+ +

+ )} + /> + + + + + ( + + )} /> - )} - /> -
-
-
-
-
-
- ) +
+
+
+ +
+
+
+ ); + } ); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/action.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/action.ts index 85215238dbefc..2dce8ead38584 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/action.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/action.ts @@ -4,14 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ManagementAction } from './managing'; +import { HostAction } from './hosts'; import { AlertAction } from './alerts'; import { RoutingAction } from './routing'; import { PolicyListAction } from './policy_list'; import { PolicyDetailsAction } from './policy_details'; export type AppAction = - | ManagementAction + | HostAction | AlertAction | RoutingAction | PolicyListAction diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/action.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/action.ts new file mode 100644 index 0000000000000..dee35aa3b895a --- /dev/null +++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/action.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { HostListPagination, ServerApiError } from '../../types'; +import { HostResultList, HostMetadata } from '../../../../../common/types'; + +interface ServerReturnedHostList { + type: 'serverReturnedHostList'; + payload: HostResultList; +} + +interface ServerReturnedHostDetails { + type: 'serverReturnedHostDetails'; + payload: HostMetadata; +} + +interface ServerFailedToReturnHostDetails { + type: 'serverFailedToReturnHostDetails'; + payload: ServerApiError; +} + +interface UserPaginatedHostList { + type: 'userPaginatedHostList'; + payload: HostListPagination; +} + +// Why is FakeActionWithNoPayload here, see: https://github.com/elastic/endpoint-app-team/issues/273 +interface FakeActionWithNoPayload { + type: 'fakeActionWithNoPayLoad'; +} + +export type HostAction = + | ServerReturnedHostList + | ServerReturnedHostDetails + | ServerFailedToReturnHostDetails + | UserPaginatedHostList + | FakeActionWithNoPayload; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/index.test.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/index.test.ts new file mode 100644 index 0000000000000..9aff66cdfb75e --- /dev/null +++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/index.test.ts @@ -0,0 +1,73 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { createStore, Dispatch, Store } from 'redux'; +import { HostAction, hostListReducer } from './index'; +import { HostListState } from '../../types'; +import { listData } from './selectors'; +import { mockHostResultList } from './mock_host_result_list'; + +describe('HostList store concerns', () => { + let store: Store; + let dispatch: Dispatch; + const createTestStore = () => { + store = createStore(hostListReducer); + dispatch = store.dispatch; + }; + + const loadDataToStore = () => { + dispatch({ + type: 'serverReturnedHostList', + payload: mockHostResultList({ request_page_size: 1, request_page_index: 1, total: 10 }), + }); + }; + + describe('# Reducers', () => { + beforeEach(() => { + createTestStore(); + }); + + test('it creates default state', () => { + expect(store.getState()).toEqual({ + hosts: [], + pageSize: 10, + pageIndex: 0, + total: 0, + loading: false, + }); + }); + + test('it handles `serverReturnedHostList', () => { + const payload = mockHostResultList({ + request_page_size: 1, + request_page_index: 1, + total: 10, + }); + dispatch({ + type: 'serverReturnedHostList', + payload, + }); + + const currentState = store.getState(); + expect(currentState.hosts).toEqual(payload.hosts); + expect(currentState.pageSize).toEqual(payload.request_page_size); + expect(currentState.pageIndex).toEqual(payload.request_page_index); + expect(currentState.total).toEqual(payload.total); + }); + }); + + describe('# Selectors', () => { + beforeEach(() => { + createTestStore(); + loadDataToStore(); + }); + + test('it selects `hostListData`', () => { + const currentState = store.getState(); + expect(listData(currentState)).toEqual(currentState.hosts); + }); + }); +}); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/index.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/index.ts similarity index 60% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/managing/index.ts rename to x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/index.ts index f0bfe27c9e30f..e80d7a82dc8cb 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/index.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/index.ts @@ -4,6 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -export { managementListReducer } from './reducer'; -export { ManagementAction } from './action'; -export { managementMiddlewareFactory } from './middleware'; +export { hostListReducer } from './reducer'; +export { HostAction } from './action'; +export { hostMiddlewareFactory } from './middleware'; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/middleware.test.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.test.ts similarity index 63% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/managing/middleware.test.ts rename to x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.test.ts index 459a1789a58da..a1973a38b6534 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/middleware.test.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.test.ts @@ -7,51 +7,40 @@ import { CoreStart, HttpSetup } from 'kibana/public'; import { applyMiddleware, createStore, Dispatch, Store } from 'redux'; import { coreMock } from '../../../../../../../../src/core/public/mocks'; import { History, createBrowserHistory } from 'history'; -import { managementListReducer, managementMiddlewareFactory } from './index'; -import { EndpointMetadata, EndpointResultList } from '../../../../../common/types'; -import { EndpointDocGenerator } from '../../../../../common/generate_data'; -import { ManagementListState } from '../../types'; +import { hostListReducer, hostMiddlewareFactory } from './index'; +import { HostResultList } from '../../../../../common/types'; +import { HostListState } from '../../types'; import { AppAction } from '../action'; import { listData } from './selectors'; import { DepsStartMock, depsStartMock } from '../../mocks'; +import { mockHostResultList } from './mock_host_result_list'; -describe('endpoint list saga', () => { +describe('host list middleware', () => { const sleep = (ms = 100) => new Promise(wakeup => setTimeout(wakeup, ms)); let fakeCoreStart: jest.Mocked; let depsStart: DepsStartMock; let fakeHttpServices: jest.Mocked; - let store: Store; + let store: Store; let getState: typeof store['getState']; let dispatch: Dispatch; - const generator = new EndpointDocGenerator(); - // https://github.com/elastic/endpoint-app-team/issues/131 - const generateEndpoint = (): EndpointMetadata => { - return generator.generateEndpointMetadata(); - }; - let history: History; - const getEndpointListApiResponse = (): EndpointResultList => { - return { - endpoints: [generateEndpoint()], - request_page_size: 1, - request_page_index: 1, - total: 10, - }; + const getEndpointListApiResponse = (): HostResultList => { + return mockHostResultList({ request_page_size: 1, request_page_index: 1, total: 10 }); }; beforeEach(() => { fakeCoreStart = coreMock.createStart({ basePath: '/mock' }); depsStart = depsStartMock(); fakeHttpServices = fakeCoreStart.http as jest.Mocked; store = createStore( - managementListReducer, - applyMiddleware(managementMiddlewareFactory(fakeCoreStart, depsStart)) + hostListReducer, + applyMiddleware(hostMiddlewareFactory(fakeCoreStart, depsStart)) ); getState = store.getState; dispatch = store.dispatch; history = createBrowserHistory(); }); - test('it handles `userChangedUrl`', async () => { + test('handles `userChangedUrl`', async () => { const apiResponse = getEndpointListApiResponse(); fakeHttpServices.post.mockResolvedValue(apiResponse); expect(fakeHttpServices.post).not.toHaveBeenCalled(); @@ -60,7 +49,7 @@ describe('endpoint list saga', () => { type: 'userChangedUrl', payload: { ...history.location, - pathname: '/management', + pathname: '/hosts', }, }); await sleep(); @@ -69,6 +58,6 @@ describe('endpoint list saga', () => { paging_properties: [{ page_index: 0 }, { page_size: 10 }], }), }); - expect(listData(getState())).toEqual(apiResponse.endpoints); + expect(listData(getState())).toEqual(apiResponse.hosts); }); }); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/middleware.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.ts similarity index 59% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/managing/middleware.ts rename to x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.ts index 1131e8d769fcf..9481b6633f12e 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/middleware.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/middleware.ts @@ -5,39 +5,30 @@ */ import { MiddlewareFactory } from '../../types'; -import { - pageIndex, - pageSize, - isOnManagementPage, - hasSelectedHost, - uiQueryParams, -} from './selectors'; -import { ManagementListState } from '../../types'; +import { pageIndex, pageSize, isOnHostPage, hasSelectedHost, uiQueryParams } from './selectors'; +import { HostListState } from '../../types'; import { AppAction } from '../action'; -export const managementMiddlewareFactory: MiddlewareFactory = coreStart => { +export const hostMiddlewareFactory: MiddlewareFactory = coreStart => { return ({ getState, dispatch }) => next => async (action: AppAction) => { next(action); const state = getState(); if ( (action.type === 'userChangedUrl' && - isOnManagementPage(state) && + isOnHostPage(state) && hasSelectedHost(state) !== true) || - action.type === 'userPaginatedManagementList' + action.type === 'userPaginatedHostList' ) { - const managementPageIndex = pageIndex(state); - const managementPageSize = pageSize(state); + const hostPageIndex = pageIndex(state); + const hostPageSize = pageSize(state); const response = await coreStart.http.post('/api/endpoint/metadata', { body: JSON.stringify({ - paging_properties: [ - { page_index: managementPageIndex }, - { page_size: managementPageSize }, - ], + paging_properties: [{ page_index: hostPageIndex }, { page_size: hostPageSize }], }), }); - response.request_page_index = managementPageIndex; + response.request_page_index = hostPageIndex; dispatch({ - type: 'serverReturnedManagementList', + type: 'serverReturnedHostList', payload: response, }); } @@ -46,12 +37,12 @@ export const managementMiddlewareFactory: MiddlewareFactory try { const response = await coreStart.http.get(`/api/endpoint/metadata/${selectedHost}`); dispatch({ - type: 'serverReturnedManagementDetails', + type: 'serverReturnedHostDetails', payload: response, }); } catch (error) { dispatch({ - type: 'serverFailedToReturnManagementDetails', + type: 'serverFailedToReturnHostDetails', payload: error, }); } diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/mock_host_result_list.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/mock_host_result_list.ts similarity index 82% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/managing/mock_host_result_list.ts rename to x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/mock_host_result_list.ts index 61833d1dfb957..db39ecf448312 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/mock_host_result_list.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/mock_host_result_list.ts @@ -4,14 +4,14 @@ * you may not use this file except in compliance with the Elastic License. */ -import { EndpointResultList } from '../../../../../common/types'; +import { HostResultList } from '../../../../../common/types'; import { EndpointDocGenerator } from '../../../../../common/generate_data'; export const mockHostResultList: (options?: { total?: number; request_page_size?: number; request_page_index?: number; -}) => EndpointResultList = (options = {}) => { +}) => HostResultList = (options = {}) => { const { total = 1, request_page_size: requestPageSize = 10, @@ -24,13 +24,13 @@ export const mockHostResultList: (options?: { // total - numberToSkip is the count of non-skipped ones, but return no more than a pageSize, and no less than 0 const actualCountToReturn = Math.max(Math.min(total - numberToSkip, requestPageSize), 0); - const endpoints = []; + const hosts = []; for (let index = 0; index < actualCountToReturn; index++) { const generator = new EndpointDocGenerator('seed'); - endpoints.push(generator.generateEndpointMetadata()); + hosts.push(generator.generateHostMetadata()); } - const mock: EndpointResultList = { - endpoints, + const mock: HostResultList = { + hosts, total, request_page_size: requestPageSize, request_page_index: requestPageIndex, diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/reducer.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/reducer.ts similarity index 66% rename from x-pack/plugins/endpoint/public/applications/endpoint/store/managing/reducer.ts rename to x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/reducer.ts index 582aa6b7138c9..fd70317a9f37e 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/reducer.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/reducer.ts @@ -5,12 +5,12 @@ */ import { Reducer } from 'redux'; -import { ManagementListState } from '../../types'; +import { HostListState } from '../../types'; import { AppAction } from '../action'; -const initialState = (): ManagementListState => { +const initialState = (): HostListState => { return { - endpoints: [], + hosts: [], pageSize: 10, pageIndex: 0, total: 0, @@ -21,38 +21,36 @@ const initialState = (): ManagementListState => { }; }; -export const managementListReducer: Reducer = ( +export const hostListReducer: Reducer = ( state = initialState(), action ) => { - if (action.type === 'serverReturnedManagementList') { + if (action.type === 'serverReturnedHostList') { const { - endpoints, + hosts, total, request_page_size: pageSize, request_page_index: pageIndex, } = action.payload; return { ...state, - endpoints, + hosts, total, pageSize, pageIndex, loading: false, }; - } else if (action.type === 'serverReturnedManagementDetails') { + } else if (action.type === 'serverReturnedHostDetails') { return { ...state, details: action.payload, }; - } else if (action.type === 'serverFailedToReturnManagementDetails') { + } else if (action.type === 'serverFailedToReturnHostDetails') { return { ...state, detailsError: action.payload, }; - } else if (action.type === 'userExitedManagementList') { - return initialState(); - } else if (action.type === 'userPaginatedManagementList') { + } else if (action.type === 'userPaginatedHostList') { return { ...state, ...action.payload, diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/selectors.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/selectors.ts new file mode 100644 index 0000000000000..ebe310cb51190 --- /dev/null +++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/hosts/selectors.ts @@ -0,0 +1,60 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import querystring from 'querystring'; +import { createSelector } from 'reselect'; +import { Immutable } from '../../../../../common/types'; +import { HostListState, HostIndexUIQueryParams } from '../../types'; + +export const listData = (state: HostListState) => state.hosts; + +export const pageIndex = (state: HostListState) => state.pageIndex; + +export const pageSize = (state: HostListState) => state.pageSize; + +export const totalHits = (state: HostListState) => state.total; + +export const isLoading = (state: HostListState) => state.loading; + +export const detailsError = (state: HostListState) => state.detailsError; + +export const detailsData = (state: HostListState) => { + return state.details; +}; + +export const isOnHostPage = (state: HostListState) => + state.location ? state.location.pathname === '/hosts' : false; + +export const uiQueryParams: ( + state: HostListState +) => Immutable = createSelector( + (state: HostListState) => state.location, + (location: HostListState['location']) => { + const data: HostIndexUIQueryParams = {}; + if (location) { + // Removes the `?` from the beginning of query string if it exists + const query = querystring.parse(location.search.slice(1)); + + const keys: Array = ['selected_host']; + + for (const key of keys) { + const value = query[key]; + if (typeof value === 'string') { + data[key] = value; + } else if (Array.isArray(value)) { + data[key] = value[value.length - 1]; + } + } + } + return data; + } +); + +export const hasSelectedHost: (state: HostListState) => boolean = createSelector( + uiQueryParams, + ({ selected_host: selectedHost }) => { + return selectedHost !== undefined; + } +); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/index.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/index.ts index c051be2bb83cb..efa79b163d3b6 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/index.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/index.ts @@ -16,7 +16,7 @@ import { import { CoreStart } from 'kibana/public'; import { appReducer } from './reducer'; import { alertMiddlewareFactory } from './alerts/middleware'; -import { managementMiddlewareFactory } from './managing'; +import { hostMiddlewareFactory } from './hosts'; import { policyListMiddlewareFactory } from './policy_list'; import { policyDetailsMiddlewareFactory } from './policy_details'; import { GlobalState } from '../types'; @@ -69,8 +69,8 @@ export const appStoreFactory: (middlewareDeps?: { middleware = composeWithReduxDevTools( applyMiddleware( substateMiddlewareFactory( - globalState => globalState.managementList, - managementMiddlewareFactory(coreStart, depsStart) + globalState => globalState.hostList, + hostMiddlewareFactory(coreStart, depsStart) ), substateMiddlewareFactory( globalState => globalState.policyList, diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/action.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/action.ts deleted file mode 100644 index a42e23e57d107..0000000000000 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/action.ts +++ /dev/null @@ -1,39 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { ManagementListPagination, ServerApiError } from '../../types'; -import { EndpointResultList, EndpointMetadata } from '../../../../../common/types'; - -interface ServerReturnedManagementList { - type: 'serverReturnedManagementList'; - payload: EndpointResultList; -} - -interface ServerReturnedManagementDetails { - type: 'serverReturnedManagementDetails'; - payload: EndpointMetadata; -} - -interface ServerFailedToReturnManagementDetails { - type: 'serverFailedToReturnManagementDetails'; - payload: ServerApiError; -} - -interface UserExitedManagementList { - type: 'userExitedManagementList'; -} - -interface UserPaginatedManagementList { - type: 'userPaginatedManagementList'; - payload: ManagementListPagination; -} - -export type ManagementAction = - | ServerReturnedManagementList - | ServerReturnedManagementDetails - | ServerFailedToReturnManagementDetails - | UserExitedManagementList - | UserPaginatedManagementList; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/index.test.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/index.test.ts deleted file mode 100644 index e435fded13f4c..0000000000000 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/index.test.ts +++ /dev/null @@ -1,93 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { createStore, Dispatch, Store } from 'redux'; -import { ManagementAction, managementListReducer } from './index'; -import { EndpointMetadata } from '../../../../../common/types'; -import { EndpointDocGenerator } from '../../../../../common/generate_data'; -import { ManagementListState } from '../../types'; -import { listData } from './selectors'; - -describe('endpoint_list store concerns', () => { - let store: Store; - let dispatch: Dispatch; - const generator = new EndpointDocGenerator(); - const createTestStore = () => { - store = createStore(managementListReducer); - dispatch = store.dispatch; - }; - const generateEndpoint = (): EndpointMetadata => { - return generator.generateEndpointMetadata(); - }; - const loadDataToStore = () => { - dispatch({ - type: 'serverReturnedManagementList', - payload: { - endpoints: [generateEndpoint()], - request_page_size: 1, - request_page_index: 1, - total: 10, - }, - }); - }; - - describe('# Reducers', () => { - beforeEach(() => { - createTestStore(); - }); - - test('it creates default state', () => { - expect(store.getState()).toEqual({ - endpoints: [], - pageSize: 10, - pageIndex: 0, - total: 0, - loading: false, - }); - }); - - test('it handles `serverReturnedManagementList', () => { - const payload = { - endpoints: [generateEndpoint()], - request_page_size: 1, - request_page_index: 1, - total: 10, - }; - dispatch({ - type: 'serverReturnedManagementList', - payload, - }); - - const currentState = store.getState(); - expect(currentState.endpoints).toEqual(payload.endpoints); - expect(currentState.pageSize).toEqual(payload.request_page_size); - expect(currentState.pageIndex).toEqual(payload.request_page_index); - expect(currentState.total).toEqual(payload.total); - }); - - test('it handles `userExitedManagementListPage`', () => { - loadDataToStore(); - - expect(store.getState().total).toEqual(10); - - dispatch({ type: 'userExitedManagementList' }); - expect(store.getState().endpoints.length).toEqual(0); - expect(store.getState().pageIndex).toEqual(0); - }); - }); - - describe('# Selectors', () => { - beforeEach(() => { - createTestStore(); - loadDataToStore(); - }); - - test('it selects `managementListData`', () => { - const currentState = store.getState(); - expect(listData(currentState)).toEqual(currentState.endpoints); - }); - }); -}); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/selectors.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/selectors.ts deleted file mode 100644 index a7776f09fe2b8..0000000000000 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/managing/selectors.ts +++ /dev/null @@ -1,60 +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; - * you may not use this file except in compliance with the Elastic License. - */ -import querystring from 'querystring'; -import { createSelector } from 'reselect'; -import { Immutable } from '../../../../../common/types'; -import { ManagementListState, ManagingIndexUIQueryParams } from '../../types'; - -export const listData = (state: ManagementListState) => state.endpoints; - -export const pageIndex = (state: ManagementListState) => state.pageIndex; - -export const pageSize = (state: ManagementListState) => state.pageSize; - -export const totalHits = (state: ManagementListState) => state.total; - -export const isLoading = (state: ManagementListState) => state.loading; - -export const detailsError = (state: ManagementListState) => state.detailsError; - -export const detailsData = (state: ManagementListState) => { - return state.details; -}; - -export const isOnManagementPage = (state: ManagementListState) => - state.location ? state.location.pathname === '/management' : false; - -export const uiQueryParams: ( - state: ManagementListState -) => Immutable = createSelector( - (state: ManagementListState) => state.location, - (location: ManagementListState['location']) => { - const data: ManagingIndexUIQueryParams = {}; - if (location) { - // Removes the `?` from the beginning of query string if it exists - const query = querystring.parse(location.search.slice(1)); - - const keys: Array = ['selected_host']; - - for (const key of keys) { - const value = query[key]; - if (typeof value === 'string') { - data[key] = value; - } else if (Array.isArray(value)) { - data[key] = value[value.length - 1]; - } - } - } - return data; - } -); - -export const hasSelectedHost: (state: ManagementListState) => boolean = createSelector( - uiQueryParams, - ({ selected_host: selectedHost }) => { - return selectedHost !== undefined; - } -); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/store/reducer.ts b/x-pack/plugins/endpoint/public/applications/endpoint/store/reducer.ts index e655a8d5e46db..c8b2d08676724 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/store/reducer.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/store/reducer.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { combineReducers, Reducer } from 'redux'; -import { managementListReducer } from './managing'; +import { hostListReducer } from './hosts'; import { AppAction } from './action'; import { alertListReducer } from './alerts'; import { GlobalState } from '../types'; @@ -12,7 +12,7 @@ import { policyListReducer } from './policy_list'; import { policyDetailsReducer } from './policy_details'; export const appReducer: Reducer = combineReducers({ - managementList: managementListReducer, + hostList: hostListReducer, alertList: alertListReducer, policyList: policyListReducer, policyDetails: policyDetailsReducer, diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/types.ts b/x-pack/plugins/endpoint/public/applications/endpoint/types.ts index 91be6e4936dbe..3045f42a93fe2 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/types.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/types.ts @@ -7,7 +7,7 @@ import { Dispatch, MiddlewareAPI } from 'redux'; import { IIndexPattern } from 'src/plugins/data/public'; import { - EndpointMetadata, + HostMetadata, AlertData, AlertResultList, Immutable, @@ -25,22 +25,22 @@ export type MiddlewareFactory = ( api: MiddlewareAPI, S> ) => (next: Dispatch) => (action: AppAction) => unknown; -export interface ManagementListState { - endpoints: EndpointMetadata[]; - total: number; +export interface HostListState { + hosts: HostMetadata[]; pageSize: number; pageIndex: number; + total: number; loading: boolean; detailsError?: ServerApiError; - details?: Immutable; + details?: Immutable; location?: Immutable; } -export interface ManagementListPagination { +export interface HostListPagination { pageIndex: number; pageSize: number; } -export interface ManagingIndexUIQueryParams { +export interface HostIndexUIQueryParams { selected_host?: string; } @@ -92,7 +92,7 @@ export interface PolicyDetailsState { } export interface GlobalState { - readonly managementList: ManagementListState; + readonly hostList: HostListState; readonly alertList: AlertListState; readonly policyList: PolicyListState; readonly policyDetails: PolicyDetailsState; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/formatted_date_time.tsx b/x-pack/plugins/endpoint/public/applications/endpoint/view/formatted_date_time.tsx new file mode 100644 index 0000000000000..dcf97b4b2b226 --- /dev/null +++ b/x-pack/plugins/endpoint/public/applications/endpoint/view/formatted_date_time.tsx @@ -0,0 +1,24 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React from 'react'; +import { FormattedDate, FormattedTime, FormattedRelative } from '@kbn/i18n/react'; + +export const FormattedDateAndTime: React.FC<{ date: Date }> = ({ date }) => { + // If date is greater than or equal to 1h (ago), then show it as a date + // else, show it as relative to "now" + return Date.now() - date.getTime() >= 3.6e6 ? ( + <> + + {' @'} + + + ) : ( + <> + + + ); +}; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/managing/details.tsx b/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details.tsx similarity index 62% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/managing/details.tsx rename to x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details.tsx index 9f2a732042719..37080e8568350 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/managing/details.tsx +++ b/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/details.tsx @@ -13,38 +13,46 @@ import { EuiDescriptionList, EuiLoadingContent, EuiHorizontalRule, + EuiHealth, EuiSpacer, + EuiListGroup, + EuiListGroupItem, } from '@elastic/eui'; import { useHistory } from 'react-router-dom'; +import styled from 'styled-components'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { useKibana } from '../../../../../../../../src/plugins/kibana_react/public'; -import { useManagementListSelector } from './hooks'; +import { HostMetadata } from '../../../../../common/types'; +import { useHostListSelector } from './hooks'; import { urlFromQueryParams } from './url_from_query_params'; -import { uiQueryParams, detailsData, detailsError } from './../../store/managing/selectors'; +import { FormattedDateAndTime } from '../formatted_date_time'; +import { uiQueryParams, detailsData, detailsError } from './../../store/hosts/selectors'; -const HostDetails = memo(() => { - const details = useManagementListSelector(detailsData); - if (details === undefined) { - return null; +const HostIds = styled(EuiListGroupItem)` + margin-top: 0; + .euiListGroupItem__text { + padding: 0; } +`; +const HostDetails = memo(({ details }: { details: HostMetadata }) => { const detailsResultsUpper = useMemo(() => { return [ { - title: i18n.translate('xpack.endpoint.management.details.os', { + title: i18n.translate('xpack.endpoint.host.details.os', { defaultMessage: 'OS', }), description: details.host.os.full, }, { - title: i18n.translate('xpack.endpoint.management.details.lastSeen', { + title: i18n.translate('xpack.endpoint.host.details.lastSeen', { defaultMessage: 'Last Seen', }), - description: details['@timestamp'], + description: , }, { - title: i18n.translate('xpack.endpoint.management.details.alerts', { + title: i18n.translate('xpack.endpoint.host.details.alerts', { defaultMessage: 'Alerts', }), description: '0', @@ -55,62 +63,67 @@ const HostDetails = memo(() => { const detailsResultsLower = useMemo(() => { return [ { - title: i18n.translate('xpack.endpoint.management.details.policy', { + title: i18n.translate('xpack.endpoint.host.details.policy', { defaultMessage: 'Policy', }), description: details.endpoint.policy.id, }, { - title: i18n.translate('xpack.endpoint.management.details.policyStatus', { + title: i18n.translate('xpack.endpoint.host.details.policyStatus', { defaultMessage: 'Policy Status', }), - description: 'active', + description: active, }, { - title: i18n.translate('xpack.endpoint.management.details.ipAddress', { + title: i18n.translate('xpack.endpoint.host.details.ipAddress', { defaultMessage: 'IP Address', }), - description: details.host.ip, + description: ( + + {details.host.ip.map((ip: string, index: number) => ( + + ))} + + ), }, { - title: i18n.translate('xpack.endpoint.management.details.hostname', { + title: i18n.translate('xpack.endpoint.host.details.hostname', { defaultMessage: 'Hostname', }), description: details.host.hostname, }, { - title: i18n.translate('xpack.endpoint.management.details.sensorVersion', { + title: i18n.translate('xpack.endpoint.host.details.sensorVersion', { defaultMessage: 'Sensor Version', }), description: details.agent.version, }, ]; }, [details.agent.version, details.endpoint.policy.id, details.host.hostname, details.host.ip]); - return ( <> ); }); -export const ManagementDetails = () => { +export const HostDetailsFlyout = () => { const history = useHistory(); const { notifications } = useKibana(); - const queryParams = useManagementListSelector(uiQueryParams); + const queryParams = useHostListSelector(uiQueryParams); const { selected_host: selectedHost, ...queryParamsWithoutSelectedHost } = queryParams; - const details = useManagementListSelector(detailsData); - const error = useManagementListSelector(detailsError); + const details = useHostListSelector(detailsData); + const error = useHostListSelector(detailsError); const handleFlyoutClose = useCallback(() => { history.push(urlFromQueryParams(queryParamsWithoutSelectedHost)); @@ -121,13 +134,13 @@ export const ManagementDetails = () => { notifications.toasts.danger({ title: ( ), body: ( ), @@ -137,10 +150,10 @@ export const ManagementDetails = () => { }, [error, notifications.toasts]); return ( - + -

+

{details === undefined ? : details.host.hostname}

@@ -151,7 +164,7 @@ export const ManagementDetails = () => { ) : ( - + )}
diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/managing/hooks.ts b/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/hooks.ts similarity index 61% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/managing/hooks.ts rename to x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/hooks.ts index a0720fbd8aeeb..99a0073f46c74 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/managing/hooks.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/hooks.ts @@ -5,12 +5,10 @@ */ import { useSelector } from 'react-redux'; -import { GlobalState, ManagementListState } from '../../types'; +import { GlobalState, HostListState } from '../../types'; -export function useManagementListSelector( - selector: (state: ManagementListState) => TSelected -) { +export function useHostListSelector(selector: (state: HostListState) => TSelected) { return useSelector(function(state: GlobalState) { - return selector(state.managementList); + return selector(state.hostList); }); } diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/managing/index.test.tsx b/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/index.test.tsx similarity index 75% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/managing/index.test.tsx rename to x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/index.test.tsx index ced27ae8945b5..f6dfae99c1b11 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/managing/index.test.tsx +++ b/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/index.test.tsx @@ -8,15 +8,16 @@ import React from 'react'; import * as reactTestingLibrary from '@testing-library/react'; import { Provider } from 'react-redux'; import { I18nProvider } from '@kbn/i18n/react'; +import { EuiThemeProvider } from '../../../../../../../legacy/common/eui_styled_components'; import { appStoreFactory } from '../../store'; import { RouteCapture } from '../route_capture'; import { createMemoryHistory, MemoryHistory } from 'history'; import { Router } from 'react-router-dom'; import { AppAction } from '../../types'; -import { ManagementList } from './index'; -import { mockHostResultList } from '../../store/managing/mock_host_result_list'; +import { HostList } from './index'; +import { mockHostResultList } from '../../store/hosts/mock_host_result_list'; -describe('when on the managing page', () => { +describe('when on the hosts page', () => { let render: () => reactTestingLibrary.RenderResult; let history: MemoryHistory; let store: ReturnType; @@ -28,11 +29,13 @@ describe('when on the managing page', () => { return reactTestingLibrary.render( - - - - - + + + + + + + ); @@ -41,7 +44,7 @@ describe('when on the managing page', () => { it('should show a table', async () => { const renderResult = render(); - const table = await renderResult.findByTestId('managementListTable'); + const table = await renderResult.findByTestId('hostListTable'); expect(table).not.toBeNull(); }); @@ -49,7 +52,7 @@ describe('when on the managing page', () => { it('should not show the flyout', () => { const renderResult = render(); expect.assertions(1); - return renderResult.findByTestId('managementDetailsFlyout').catch(e => { + return renderResult.findByTestId('hostDetailsFlyout').catch(e => { expect(e).not.toBeNull(); }); }); @@ -57,14 +60,14 @@ describe('when on the managing page', () => { beforeEach(() => { reactTestingLibrary.act(() => { const action: AppAction = { - type: 'serverReturnedManagementList', + type: 'serverReturnedHostList', payload: mockHostResultList(), }; store.dispatch(action); }); }); - it('should render the management summary row in the table', async () => { + it('should render the host summary row in the table', async () => { const renderResult = render(); const rows = await renderResult.findAllByRole('row'); expect(rows).toHaveLength(2); @@ -81,7 +84,7 @@ describe('when on the managing page', () => { }); it('should show the flyout', () => { - return renderResult.findByTestId('managementDetailsFlyout').then(flyout => { + return renderResult.findByTestId('hostDetailsFlyout').then(flyout => { expect(flyout).not.toBeNull(); }); }); @@ -100,7 +103,7 @@ describe('when on the managing page', () => { }); it('should show the flyout', () => { const renderResult = render(); - return renderResult.findByTestId('managementDetailsFlyout').then(flyout => { + return renderResult.findByTestId('hostDetailsFlyout').then(flyout => { expect(flyout).not.toBeNull(); }); }); diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/managing/index.tsx b/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/index.tsx similarity index 55% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/managing/index.tsx rename to x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/index.tsx index ba9a931a233b2..94625b8c66191 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/managing/index.tsx +++ b/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/index.tsx @@ -10,28 +10,29 @@ import { useHistory } from 'react-router-dom'; import { EuiPage, EuiPageBody, + EuiPageHeader, EuiPageContent, - EuiPageContentBody, - EuiPageContentHeader, - EuiPageContentHeaderSection, + EuiHorizontalRule, EuiTitle, EuiBasicTable, - EuiTextColor, + EuiText, EuiLink, + EuiHealth, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; +import styled from 'styled-components'; import { FormattedMessage } from '@kbn/i18n/react'; import { createStructuredSelector } from 'reselect'; -import { ManagementDetails } from './details'; -import * as selectors from '../../store/managing/selectors'; -import { ManagementAction } from '../../store/managing/action'; -import { useManagementListSelector } from './hooks'; +import { HostDetailsFlyout } from './details'; +import * as selectors from '../../store/hosts/selectors'; +import { HostAction } from '../../store/hosts/action'; +import { useHostListSelector } from './hooks'; import { CreateStructuredSelector } from '../../types'; import { urlFromQueryParams } from './url_from_query_params'; const selector = (createStructuredSelector as CreateStructuredSelector)(selectors); -export const ManagementList = () => { - const dispatch = useDispatch<(a: ManagementAction) => void>(); +export const HostList = () => { + const dispatch = useDispatch<(a: HostAction) => void>(); const history = useHistory(); const { listData, @@ -41,7 +42,7 @@ export const ManagementList = () => { isLoading, uiQueryParams: queryParams, hasSelectedHost, - } = useManagementListSelector(selector); + } = useHostListSelector(selector); const paginationSetup = useMemo(() => { return { @@ -57,7 +58,7 @@ export const ManagementList = () => { ({ page }: { page: { index: number; size: number } }) => { const { index, size } = page; dispatch({ - type: 'userPaginatedManagementList', + type: 'userPaginatedHostList', payload: { pageIndex: index, pageSize: size }, }); }, @@ -68,7 +69,7 @@ export const ManagementList = () => { return [ { field: '', - name: i18n.translate('xpack.endpoint.management.list.host', { + name: i18n.translate('xpack.endpoint.host.list.hostname', { defaultMessage: 'Hostname', }), render: ({ host: { hostname, id } }: { host: { hostname: string; id: string } }) => { @@ -89,7 +90,7 @@ export const ManagementList = () => { }, { field: '', - name: i18n.translate('xpack.endpoint.management.list.policy', { + name: i18n.translate('xpack.endpoint.host.list.policy', { defaultMessage: 'Policy', }), render: () => { @@ -98,37 +99,38 @@ export const ManagementList = () => { }, { field: '', - name: i18n.translate('xpack.endpoint.management.list.policyStatus', { + name: i18n.translate('xpack.endpoint.host.list.policyStatus', { defaultMessage: 'Policy Status', }), render: () => { - return 'Policy Status'; + return Policy Status; }, }, { field: '', - name: i18n.translate('xpack.endpoint.management.list.alerts', { + name: i18n.translate('xpack.endpoint.host.list.alerts', { defaultMessage: 'Alerts', }), + dataType: 'number', render: () => { return '0'; }, }, { field: 'host.os.name', - name: i18n.translate('xpack.endpoint.management.list.os', { + name: i18n.translate('xpack.endpoint.host.list.os', { defaultMessage: 'Operating System', }), }, { field: 'host.ip', - name: i18n.translate('xpack.endpoint.management.list.ip', { + name: i18n.translate('xpack.endpoint.host.list.ip', { defaultMessage: 'IP Address', }), }, { field: '', - name: i18n.translate('xpack.endpoint.management.list.sensorVersion', { + name: i18n.translate('xpack.endpoint.host.list.sensorVersion', { defaultMessage: 'Sensor Version', }), render: () => { @@ -137,9 +139,10 @@ export const ManagementList = () => { }, { field: '', - name: i18n.translate('xpack.endpoint.management.list.lastActive', { + name: i18n.translate('xpack.endpoint.host.list.lastActive', { defaultMessage: 'Last Active', }), + dataType: 'date', render: () => { return 'xxxx'; }, @@ -148,45 +151,59 @@ export const ManagementList = () => { }, [queryParams, history]); return ( - <> - {hasSelectedHost && } - + + {hasSelectedHost && } + - - - - -

- -

-
-

- - - -

-
-
- - + +

+ +

+
+ + + + + -
+ + +
- +
); }; + +const HostPage = styled.div` + .hostPage { + padding: 0; + } + .hostHeader { + background-color: ${props => props.theme.eui.euiColorLightestShade}; + border-bottom: ${props => props.theme.eui.euiBorderThin}; + padding: ${props => + props.theme.eui.euiSizeXL + + ' ' + + 0 + + props.theme.eui.euiSizeXL + + ' ' + + props.theme.eui.euiSizeL}; + margin-bottom: 0; + } + .hostPageContent { + border: none; + } +`; diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/managing/url_from_query_params.ts b/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/url_from_query_params.ts similarity index 78% rename from x-pack/plugins/endpoint/public/applications/endpoint/view/managing/url_from_query_params.ts rename to x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/url_from_query_params.ts index ea6a4c6f684ad..225aad8cab020 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/managing/url_from_query_params.ts +++ b/x-pack/plugins/endpoint/public/applications/endpoint/view/hosts/url_from_query_params.ts @@ -5,10 +5,10 @@ */ import querystring from 'querystring'; -import { EndpointAppLocation, ManagingIndexUIQueryParams } from '../../types'; +import { EndpointAppLocation, HostIndexUIQueryParams } from '../../types'; export function urlFromQueryParams( - queryParams: ManagingIndexUIQueryParams + queryParams: HostIndexUIQueryParams ): Partial { const search = querystring.stringify(queryParams); return { diff --git a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_list.tsx b/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_list.tsx index cf573da3703cc..e7ce53679bbe7 100644 --- a/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_list.tsx +++ b/x-pack/plugins/endpoint/public/applications/endpoint/view/policy/policy_list.tsx @@ -20,17 +20,12 @@ import { EuiLink, } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { - FormattedMessage, - FormattedDate, - FormattedTime, - FormattedNumber, - FormattedRelative, -} from '@kbn/i18n/react'; +import { FormattedMessage, FormattedNumber } from '@kbn/i18n/react'; import { useDispatch } from 'react-redux'; import styled from 'styled-components'; import { useHistory } from 'react-router-dom'; import { usePageId } from '../use_page_id'; +import { FormattedDateAndTime } from '../formatted_date_time'; import { selectIsLoading, selectPageIndex, @@ -56,22 +51,6 @@ const TruncateTooltipText = styled(TruncateText)` } `; -const FormattedDateAndTime: React.FC<{ date: Date }> = ({ date }) => { - // If date is greater than or equal to 24h (ago), then show it as a date - // else, show it as relative to "now" - return Date.now() - date.getTime() >= 8.64e7 ? ( - <> - - {' @'} - - - ) : ( - <> - - - ); -}; - const PolicyLink: React.FC<{ name: string; route: string }> = ({ name, route }) => { const history = useHistory(); diff --git a/x-pack/plugins/endpoint/scripts/resolver_generator.ts b/x-pack/plugins/endpoint/scripts/resolver_generator.ts index a3e56497f0790..503999daec587 100644 --- a/x-pack/plugins/endpoint/scripts/resolver_generator.ts +++ b/x-pack/plugins/endpoint/scripts/resolver_generator.ts @@ -32,7 +32,7 @@ async function main() { }, metadataIndex: { alias: 'mi', - describe: 'index to store endpoint metadata in', + describe: 'index to store host metadata in', default: 'endpoint-agent-1', type: 'string', }, @@ -76,15 +76,15 @@ async function main() { type: 'number', default: 30, }, - numEndpoints: { + numHosts: { alias: 'ne', - describe: 'number of different endpoints to generate alerts for', + describe: 'number of different hosts to generate alerts for', type: 'number', default: 1, }, - alertsPerEndpoint: { + alertsPerHost: { alias: 'ape', - describe: 'number of resolver trees to make for each endpoint', + describe: 'number of resolver trees to make for each host', type: 'number', default: 1, }, @@ -133,12 +133,12 @@ async function main() { } const generator = new EndpointDocGenerator(argv.seed); - for (let i = 0; i < argv.numEndpoints; i++) { + for (let i = 0; i < argv.numHosts; i++) { await client.index({ index: argv.metadataIndex, - body: generator.generateEndpointMetadata(), + body: generator.generateHostMetadata(), }); - for (let j = 0; j < argv.alertsPerEndpoint; j++) { + for (let j = 0; j < argv.alertsPerHost; j++) { const resolverDocs = generator.generateFullResolverTree( argv.ancestors, argv.generations, diff --git a/x-pack/plugins/endpoint/server/routes/metadata.test.ts b/x-pack/plugins/endpoint/server/routes/metadata.test.ts index ee374bc1b57d6..65e07edbcde24 100644 --- a/x-pack/plugins/endpoint/server/routes/metadata.test.ts +++ b/x-pack/plugins/endpoint/server/routes/metadata.test.ts @@ -18,7 +18,7 @@ import { httpServiceMock, loggingServiceMock, } from '../../../../../src/core/server/mocks'; -import { EndpointMetadata, EndpointResultList } from '../../common/types'; +import { HostMetadata, HostResultList } from '../../common/types'; import { SearchResponse } from 'elasticsearch'; import { registerEndpointRoutes } from './metadata'; import { EndpointConfigSchema } from '../config'; @@ -49,8 +49,8 @@ describe('test endpoint route', () => { it('test find the latest of all endpoints', async () => { const mockRequest = httpServerMock.createKibanaRequest({}); - const response: SearchResponse = (data as unknown) as SearchResponse< - EndpointMetadata + const response: SearchResponse = (data as unknown) as SearchResponse< + HostMetadata >; mockScopedClient.callAsCurrentUser.mockImplementationOnce(() => Promise.resolve(response)); [routeConfig, routeHandler] = routerMock.post.mock.calls.find(([{ path }]) => @@ -72,8 +72,8 @@ describe('test endpoint route', () => { expect(mockScopedClient.callAsCurrentUser).toBeCalled(); expect(routeConfig.options).toEqual({ authRequired: true }); expect(mockResponse.ok).toBeCalled(); - const endpointResultList = mockResponse.ok.mock.calls[0][0]?.body as EndpointResultList; - expect(endpointResultList.endpoints.length).toEqual(2); + const endpointResultList = mockResponse.ok.mock.calls[0][0]?.body as HostResultList; + expect(endpointResultList.hosts.length).toEqual(2); expect(endpointResultList.total).toEqual(2); expect(endpointResultList.request_page_index).toEqual(0); expect(endpointResultList.request_page_size).toEqual(10); @@ -93,7 +93,7 @@ describe('test endpoint route', () => { }, }); mockScopedClient.callAsCurrentUser.mockImplementationOnce(() => - Promise.resolve((data as unknown) as SearchResponse) + Promise.resolve((data as unknown) as SearchResponse) ); [routeConfig, routeHandler] = routerMock.post.mock.calls.find(([{ path }]) => path.startsWith('/api/endpoint/metadata') @@ -117,8 +117,8 @@ describe('test endpoint route', () => { }); expect(routeConfig.options).toEqual({ authRequired: true }); expect(mockResponse.ok).toBeCalled(); - const endpointResultList = mockResponse.ok.mock.calls[0][0]?.body as EndpointResultList; - expect(endpointResultList.endpoints.length).toEqual(2); + const endpointResultList = mockResponse.ok.mock.calls[0][0]?.body as HostResultList; + expect(endpointResultList.hosts.length).toEqual(2); expect(endpointResultList.total).toEqual(2); expect(endpointResultList.request_page_index).toEqual(10); expect(endpointResultList.request_page_size).toEqual(10); @@ -140,7 +140,7 @@ describe('test endpoint route', () => { }, }); mockScopedClient.callAsCurrentUser.mockImplementationOnce(() => - Promise.resolve((data as unknown) as SearchResponse) + Promise.resolve((data as unknown) as SearchResponse) ); [routeConfig, routeHandler] = routerMock.post.mock.calls.find(([{ path }]) => path.startsWith('/api/endpoint/metadata') @@ -177,8 +177,8 @@ describe('test endpoint route', () => { }); expect(routeConfig.options).toEqual({ authRequired: true }); expect(mockResponse.ok).toBeCalled(); - const endpointResultList = mockResponse.ok.mock.calls[0][0]?.body as EndpointResultList; - expect(endpointResultList.endpoints.length).toEqual(2); + const endpointResultList = mockResponse.ok.mock.calls[0][0]?.body as HostResultList; + expect(endpointResultList.hosts.length).toEqual(2); expect(endpointResultList.total).toEqual(2); expect(endpointResultList.request_page_index).toEqual(10); expect(endpointResultList.request_page_size).toEqual(10); @@ -234,8 +234,8 @@ describe('test endpoint route', () => { const mockRequest = httpServerMock.createKibanaRequest({ params: { id: (data as any).hits.hits[0]._id }, }); - const response: SearchResponse = (data as unknown) as SearchResponse< - EndpointMetadata + const response: SearchResponse = (data as unknown) as SearchResponse< + HostMetadata >; mockScopedClient.callAsCurrentUser.mockImplementationOnce(() => Promise.resolve(response)); [routeConfig, routeHandler] = routerMock.get.mock.calls.find(([{ path }]) => @@ -257,7 +257,7 @@ describe('test endpoint route', () => { expect(mockScopedClient.callAsCurrentUser).toBeCalled(); expect(routeConfig.options).toEqual({ authRequired: true }); expect(mockResponse.ok).toBeCalled(); - const result = mockResponse.ok.mock.calls[0][0]?.body as EndpointMetadata; + const result = mockResponse.ok.mock.calls[0][0]?.body as HostMetadata; expect(result).toHaveProperty('endpoint'); }); }); diff --git a/x-pack/plugins/endpoint/server/routes/metadata.ts b/x-pack/plugins/endpoint/server/routes/metadata.ts index 278cfac020a3b..463a071ab0c77 100644 --- a/x-pack/plugins/endpoint/server/routes/metadata.ts +++ b/x-pack/plugins/endpoint/server/routes/metadata.ts @@ -12,11 +12,11 @@ import { kibanaRequestToMetadataListESQuery, kibanaRequestToMetadataGetESQuery, } from '../services/endpoint/metadata_query_builders'; -import { EndpointMetadata, EndpointResultList } from '../../common/types'; +import { HostMetadata, HostResultList } from '../../common/types'; import { EndpointAppContext } from '../types'; interface HitSource { - _source: EndpointMetadata; + _source: HostMetadata; } export function registerEndpointRoutes(router: IRouter, endpointAppContext: EndpointAppContext) { @@ -57,8 +57,8 @@ export function registerEndpointRoutes(router: IRouter, endpointAppContext: Endp const response = (await context.core.elasticsearch.dataClient.callAsCurrentUser( 'search', queryParams - )) as SearchResponse; - return res.ok({ body: mapToEndpointResultList(queryParams, response) }); + )) as SearchResponse; + return res.ok({ body: mapToHostResultList(queryParams, response) }); } catch (err) { return res.internalError({ body: err }); } @@ -79,7 +79,7 @@ export function registerEndpointRoutes(router: IRouter, endpointAppContext: Endp const response = (await context.core.elasticsearch.dataClient.callAsCurrentUser( 'search', query - )) as SearchResponse; + )) as SearchResponse; if (response.hits.hits.length === 0) { return res.notFound({ body: 'Endpoint Not Found' }); @@ -93,27 +93,27 @@ export function registerEndpointRoutes(router: IRouter, endpointAppContext: Endp ); } -function mapToEndpointResultList( +function mapToHostResultList( queryParams: Record, - searchResponse: SearchResponse -): EndpointResultList { - const totalNumberOfEndpoints = searchResponse?.aggregations?.total?.value || 0; + searchResponse: SearchResponse +): HostResultList { + const totalNumberOfHosts = searchResponse?.aggregations?.total?.value || 0; if (searchResponse.hits.hits.length > 0) { return { request_page_size: queryParams.size, request_page_index: queryParams.from, - endpoints: searchResponse.hits.hits + hosts: searchResponse.hits.hits .map(response => response.inner_hits.most_recent.hits.hits) .flatMap(data => data as HitSource) .map(entry => entry._source), - total: totalNumberOfEndpoints, + total: totalNumberOfHosts, }; } else { return { request_page_size: queryParams.size, request_page_index: queryParams.from, - total: totalNumberOfEndpoints, - endpoints: [], + total: totalNumberOfHosts, + hosts: [], }; } } diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/show_json.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/show_json.js index 50c0e331e3dbc..7b7ca08427087 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/show_json.js +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/detail_panel/show_json/show_json.js @@ -5,7 +5,7 @@ */ import React from 'react'; -import { EuiCodeEditor } from '@elastic/eui'; +import { EuiCodeBlock } from '@elastic/eui'; import 'brace/theme/textmate'; @@ -25,17 +25,6 @@ export class ShowJson extends React.PureComponent { return null; } const json = JSON.stringify(data, null, 2); - return ( - - ); + return {json}; } } diff --git a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/step_configure_datasource.tsx b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/step_configure_datasource.tsx index 484ea3f1d94a0..b45beef4a8b5e 100644 --- a/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/step_configure_datasource.tsx +++ b/x-pack/plugins/ingest_manager/public/applications/ingest_manager/sections/agent_config/create_datasource_page/step_configure_datasource.tsx @@ -183,7 +183,10 @@ export const StepConfigureDatasource: React.FunctionComponent<{ // Step B, configure inputs (and their streams) // Assume packages only export one datasource for now const ConfigureInputs = - packageInfo.datasources && packageInfo.datasources[0] ? ( + packageInfo.datasources && + packageInfo.datasources[0] && + packageInfo.datasources[0].inputs && + packageInfo.datasources[0].inputs.length ? ( {packageInfo.datasources[0].inputs.map(packageInput => { const datasourceInput = datasource.inputs.find(input => input.type === packageInput.type); diff --git a/x-pack/plugins/maps/common/constants.ts b/x-pack/plugins/maps/common/constants.ts index b1483cefa43bc..b608151d26ae8 100644 --- a/x-pack/plugins/maps/common/constants.ts +++ b/x-pack/plugins/maps/common/constants.ts @@ -10,6 +10,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { i18n } from '@kbn/i18n'; +export const EMS_APP_NAME = 'kibana'; export const EMS_CATALOGUE_PATH = 'ems/catalogue'; export const EMS_FILES_CATALOGUE_PATH = 'ems/files'; diff --git a/x-pack/plugins/ml/kibana.json b/x-pack/plugins/ml/kibana.json index 2f8863fc1d7cf..b6db289f4be6d 100644 --- a/x-pack/plugins/ml/kibana.json +++ b/x-pack/plugins/ml/kibana.json @@ -12,7 +12,8 @@ "features", "home", "licensing", - "usageCollection" + "usageCollection", + "share" ], "optionalPlugins": [ "security", diff --git a/x-pack/plugins/ml/mappings.json b/x-pack/plugins/ml/mappings.json deleted file mode 100644 index 041b85dbea4a1..0000000000000 --- a/x-pack/plugins/ml/mappings.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "ml-telemetry": { - "properties": { - "file_data_visualizer": { - "properties": { - "index_creation_count": { - "type" : "long" - } - } - } - } - } -} diff --git a/x-pack/plugins/ml/public/application/app.tsx b/x-pack/plugins/ml/public/application/app.tsx index 206189c79696f..2597715488399 100644 --- a/x-pack/plugins/ml/public/application/app.tsx +++ b/x-pack/plugins/ml/public/application/app.tsx @@ -41,6 +41,7 @@ const App: FC = ({ coreStart, deps, appMountParams }) => { application: coreStart.application, http: coreStart.http, security: deps.security, + urlGenerators: deps.share.urlGenerators, }); const mlLicense = setLicenseCache(deps.licensing); diff --git a/x-pack/plugins/ml/public/application/explorer/components/explorer_no_jobs_found/__snapshots__/explorer_no_jobs_found.test.js.snap b/x-pack/plugins/ml/public/application/explorer/components/explorer_no_jobs_found/__snapshots__/explorer_no_jobs_found.test.js.snap index 8aec3c8336da9..c6503a639997d 100644 --- a/x-pack/plugins/ml/public/application/explorer/components/explorer_no_jobs_found/__snapshots__/explorer_no_jobs_found.test.js.snap +++ b/x-pack/plugins/ml/public/application/explorer/components/explorer_no_jobs_found/__snapshots__/explorer_no_jobs_found.test.js.snap @@ -9,7 +9,7 @@ exports[`ExplorerNoInfluencersFound snapshot 1`] = ` href="ml#/jobs" > diff --git a/x-pack/plugins/ml/public/application/explorer/components/explorer_no_jobs_found/explorer_no_jobs_found.js b/x-pack/plugins/ml/public/application/explorer/components/explorer_no_jobs_found/explorer_no_jobs_found.js index 5cce2e1eece95..6f391f9746f23 100644 --- a/x-pack/plugins/ml/public/application/explorer/components/explorer_no_jobs_found/explorer_no_jobs_found.js +++ b/x-pack/plugins/ml/public/application/explorer/components/explorer_no_jobs_found/explorer_no_jobs_found.js @@ -23,10 +23,7 @@ export const ExplorerNoJobsFound = () => ( } actions={ - + } data-test-subj="mlNoJobsFound" diff --git a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.js b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.js index e9b39058c23a8..a7734289314ae 100644 --- a/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.js +++ b/x-pack/plugins/ml/public/application/jobs/components/custom_url_editor/utils.js @@ -7,10 +7,9 @@ import { TIME_RANGE_TYPE, URL_TYPE } from './constants'; import rison from 'rison-node'; -// import url from 'url'; +import url from 'url'; -// import { npStart } from 'ui/new_platform'; -// import { DASHBOARD_APP_URL_GENERATOR } from '../../../../../../../../src/plugins/dashboard_embeddable_container/public'; +import { DASHBOARD_APP_URL_GENERATOR } from '../../../../../../../../src/plugins/dashboard/public'; import { ML_RESULTS_INDEX_PATTERN } from '../../../../../common/constants/index_patterns'; import { getPartitioningFieldNames } from '../../../../../common/util/job_utils'; @@ -19,7 +18,7 @@ import { replaceTokensInUrlValue, isValidLabel } from '../../../util/custom_url_ import { ml } from '../../../services/ml_api_service'; import { mlJobService } from '../../../services/job_service'; import { escapeForElasticsearchQuery } from '../../../util/string_utils'; -// import { getSavedObjectsClient } from '../../../util/dependency_cache'; +import { getSavedObjectsClient, getGetUrlGenerator } from '../../../util/dependency_cache'; export function getNewCustomUrlDefaults(job, dashboards, indexPatterns) { // Returns the settings object in the format used by the custom URL editor @@ -119,7 +118,7 @@ export function buildCustomUrlFromSettings(settings) { // Dashboard URL returns a Promise as a query is made to obtain the full dashboard config. // So wrap the other two return types in a Promise for consistent return type. if (settings.type === URL_TYPE.KIBANA_DASHBOARD) { - // return buildDashboardUrlFromSettings(settings); + return buildDashboardUrlFromSettings(settings); } else if (settings.type === URL_TYPE.KIBANA_DISCOVER) { return Promise.resolve(buildDiscoverUrlFromSettings(settings)); } else { @@ -132,72 +131,70 @@ export function buildCustomUrlFromSettings(settings) { } } -// function buildDashboardUrlFromSettings(settings) { -// // Get the complete list of attributes for the selected dashboard (query, filters). -// return new Promise((resolve, reject) => { -// const { dashboardId, queryFieldNames } = settings.kibanaSettings; - -// const savedObjectsClient = getSavedObjectsClient(); -// savedObjectsClient -// .get('dashboard', dashboardId) -// .then(response => { -// // Use the filters from the saved dashboard if there are any. -// // let filters = []; - -// // Use the query from the dashboard only if no job entities are selected. -// let query = undefined; - -// const searchSourceJSON = response.get('kibanaSavedObjectMeta.searchSourceJSON'); -// if (searchSourceJSON !== undefined) { -// const searchSourceData = JSON.parse(searchSourceJSON); -// if (searchSourceData.filter !== undefined) { -// filters = searchSourceData.filter; -// } -// query = searchSourceData.query; -// } - -// const queryFromEntityFieldNames = buildAppStateQueryParam(queryFieldNames); -// if (queryFromEntityFieldNames !== undefined) { -// query = queryFromEntityFieldNames; -// } - -// const generator = npStart.plugins.share.urlGenerators.getUrlGenerator( -// DASHBOARD_APP_URL_GENERATOR -// ); - -// return generator -// .createUrl({ -// dashboardId, -// timeRange: { -// from: '$earliest$', -// to: '$latest$', -// mode: 'absolute', -// }, -// filters, -// query, -// // Don't hash the URL since this string will be 1. shown to the user and 2. used as a -// // template to inject the time parameters. -// useHash: false, -// }) -// .then(urlValue => { -// const urlToAdd = { -// url_name: settings.label, -// url_value: decodeURIComponent(`kibana${url.parse(urlValue).hash}`), -// time_range: TIME_RANGE_TYPE.AUTO, -// }; - -// if (settings.timeRange.type === TIME_RANGE_TYPE.INTERVAL) { -// urlToAdd.time_range = settings.timeRange.interval; -// } - -// resolve(urlToAdd); -// }); -// }) -// .catch(resp => { -// reject(resp); -// }); -// }); -// } +function buildDashboardUrlFromSettings(settings) { + // Get the complete list of attributes for the selected dashboard (query, filters). + return new Promise((resolve, reject) => { + const { dashboardId, queryFieldNames } = settings.kibanaSettings; + + const savedObjectsClient = getSavedObjectsClient(); + savedObjectsClient + .get('dashboard', dashboardId) + .then(response => { + // Use the filters from the saved dashboard if there are any. + let filters = []; + + // Use the query from the dashboard only if no job entities are selected. + let query = undefined; + + const searchSourceJSON = response.get('kibanaSavedObjectMeta.searchSourceJSON'); + if (searchSourceJSON !== undefined) { + const searchSourceData = JSON.parse(searchSourceJSON); + if (searchSourceData.filter !== undefined) { + filters = searchSourceData.filter; + } + query = searchSourceData.query; + } + + const queryFromEntityFieldNames = buildAppStateQueryParam(queryFieldNames); + if (queryFromEntityFieldNames !== undefined) { + query = queryFromEntityFieldNames; + } + + const getUrlGenerator = getGetUrlGenerator(); + const generator = getUrlGenerator(DASHBOARD_APP_URL_GENERATOR); + return generator + .createUrl({ + dashboardId, + timeRange: { + from: '$earliest$', + to: '$latest$', + mode: 'absolute', + }, + filters, + query, + // Don't hash the URL since this string will be 1. shown to the user and 2. used as a + // template to inject the time parameters. + useHash: false, + }) + .then(urlValue => { + const urlToAdd = { + url_name: settings.label, + url_value: decodeURIComponent(`kibana${url.parse(urlValue).hash}`), + time_range: TIME_RANGE_TYPE.AUTO, + }; + + if (settings.timeRange.type === TIME_RANGE_TYPE.INTERVAL) { + urlToAdd.time_range = settings.timeRange.interval; + } + + resolve(urlToAdd); + }); + }) + .catch(resp => { + reject(resp); + }); + }); +} function buildDiscoverUrlFromSettings(settings) { const { discoverIndexPatternId, queryFieldNames } = settings.kibanaSettings; diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/jobs_stats_bar/jobs_stats_bar.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/jobs_stats_bar/jobs_stats_bar.js index 08155f3f4edba..3c791ff658978 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/jobs_stats_bar/jobs_stats_bar.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/jobs_stats_bar/jobs_stats_bar.js @@ -15,7 +15,7 @@ function createJobStats(jobsSummaryList) { const jobStats = { activeNodes: { label: i18n.translate('xpack.ml.jobsList.statsBar.activeMLNodesLabel', { - defaultMessage: 'Active ML Nodes', + defaultMessage: 'Active ML nodes', }), value: 0, show: true, diff --git a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/new_job_button/new_job_button.js b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/new_job_button/new_job_button.js index cacca839a4f59..1297ca5b9afd1 100644 --- a/x-pack/plugins/ml/public/application/jobs/jobs_list/components/new_job_button/new_job_button.js +++ b/x-pack/plugins/ml/public/application/jobs/jobs_list/components/new_job_button/new_job_button.js @@ -29,7 +29,7 @@ export function NewJobButton() { > ); diff --git a/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/utils.ts b/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/utils.ts index eab40c0f577f8..b030a1ef45ab0 100644 --- a/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/utils.ts +++ b/x-pack/plugins/ml/public/application/overview/components/anomaly_detection_panel/utils.ts @@ -72,7 +72,7 @@ export function getStatsBarData(jobsList: any) { const jobStats = { activeNodes: { label: i18n.translate('xpack.ml.overviewJobsList.statsBar.activeMLNodesLabel', { - defaultMessage: 'Active ML Nodes', + defaultMessage: 'Active ML nodes', }), value: 0, show: true, diff --git a/x-pack/plugins/ml/public/application/services/job_service.js b/x-pack/plugins/ml/public/application/services/job_service.js index f092e85bef5ce..e087740ec0e99 100644 --- a/x-pack/plugins/ml/public/application/services/job_service.js +++ b/x-pack/plugins/ml/public/application/services/job_service.js @@ -45,7 +45,7 @@ class JobService { this.jobStats = { activeNodes: { label: i18n.translate('xpack.ml.jobService.activeMLNodesLabel', { - defaultMessage: 'Active ML Nodes', + defaultMessage: 'Active ML nodes', }), value: 0, show: true, diff --git a/x-pack/plugins/ml/public/application/util/dependency_cache.ts b/x-pack/plugins/ml/public/application/util/dependency_cache.ts index 5343c51b525d2..d5605d3bca65f 100644 --- a/x-pack/plugins/ml/public/application/util/dependency_cache.ts +++ b/x-pack/plugins/ml/public/application/util/dependency_cache.ts @@ -21,6 +21,7 @@ import { ChromeRecentlyAccessed, IBasePath, } from 'kibana/public'; +import { SharePluginStart } from 'src/plugins/share/public'; import { SecurityPluginSetup } from '../../../../security/public'; export interface DependencyCache { @@ -40,6 +41,7 @@ export interface DependencyCache { http: HttpStart | null; security: SecurityPluginSetup | null; i18n: I18nStart | null; + urlGenerators: SharePluginStart['urlGenerators'] | null; } const cache: DependencyCache = { @@ -59,6 +61,7 @@ const cache: DependencyCache = { http: null, security: null, i18n: null, + urlGenerators: null, }; export function setDependencyCache(deps: Partial) { @@ -78,6 +81,7 @@ export function setDependencyCache(deps: Partial) { cache.http = deps.http || null; cache.security = deps.security || null; cache.i18n = deps.i18n || null; + cache.urlGenerators = deps.urlGenerators || null; } export function getTimefilter() { @@ -191,6 +195,13 @@ export function getI18n() { return cache.i18n; } +export function getGetUrlGenerator() { + if (cache.urlGenerators === null) { + throw new Error("urlGenerators hasn't been initialized"); + } + return cache.urlGenerators.getUrlGenerator; +} + export function clearCache() { console.log('clearing dependency cache'); // eslint-disable-line no-console Object.keys(cache).forEach(k => { diff --git a/x-pack/plugins/ml/public/plugin.ts b/x-pack/plugins/ml/public/plugin.ts index ef85a36494df5..79aebece85af2 100644 --- a/x-pack/plugins/ml/public/plugin.ts +++ b/x-pack/plugins/ml/public/plugin.ts @@ -7,6 +7,8 @@ import { i18n } from '@kbn/i18n'; import { Plugin, CoreStart, CoreSetup, AppMountParameters } from 'kibana/public'; import { ManagementSetup } from 'src/plugins/management/public'; +import { SharePluginStart } from 'src/plugins/share/public'; +import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { DataPublicPluginStart } from 'src/plugins/data/public'; import { SecurityPluginSetup } from '../../security/public'; @@ -17,11 +19,13 @@ import { PLUGIN_ID, PLUGIN_ICON } from '../common/constants/app'; export interface MlStartDependencies { data: DataPublicPluginStart; + share: SharePluginStart; } export interface MlSetupDependencies { security: SecurityPluginSetup; licensing: LicensingPluginSetup; management: ManagementSetup; + usageCollection: UsageCollectionSetup; } export class MlPlugin implements Plugin { @@ -41,9 +45,11 @@ export class MlPlugin implements Plugin { coreStart, { data: pluginsStart.data, + share: pluginsStart.share, security: pluginsSetup.security, licensing: pluginsSetup.licensing, management: pluginsSetup.management, + usageCollection: pluginsSetup.usageCollection, }, { element: params.element, diff --git a/x-pack/plugins/ml/server/lib/ml_telemetry/index.ts b/x-pack/plugins/ml/server/lib/ml_telemetry/index.ts deleted file mode 100644 index dffd95f50e0d9..0000000000000 --- a/x-pack/plugins/ml/server/lib/ml_telemetry/index.ts +++ /dev/null @@ -1,15 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -export { - createMlTelemetry, - incrementFileDataVisualizerIndexCreationCount, - storeMlTelemetry, - MlTelemetry, - MlTelemetrySavedObject, - ML_TELEMETRY_DOC_ID, -} from './ml_telemetry'; -export { makeMlUsageCollector } from './make_ml_usage_collector'; diff --git a/x-pack/plugins/ml/server/lib/ml_telemetry/make_ml_usage_collector.ts b/x-pack/plugins/ml/server/lib/ml_telemetry/make_ml_usage_collector.ts deleted file mode 100644 index 15a430a08eac1..0000000000000 --- a/x-pack/plugins/ml/server/lib/ml_telemetry/make_ml_usage_collector.ts +++ /dev/null @@ -1,41 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; -import { SavedObjectsServiceStart } from 'kibana/server'; -import { - createMlTelemetry, - ML_TELEMETRY_DOC_ID, - MlTelemetry, - MlTelemetrySavedObject, -} from './ml_telemetry'; - -export function makeMlUsageCollector( - usageCollection: UsageCollectionSetup | undefined, - savedObjects: SavedObjectsServiceStart -): void { - if (!usageCollection) { - return; - } - - const mlUsageCollector = usageCollection.makeUsageCollector({ - type: 'ml', - isReady: () => true, - fetch: async (): Promise => { - try { - const mlTelemetrySavedObject: MlTelemetrySavedObject = await savedObjects - .createInternalRepository() - .get('ml-telemetry', ML_TELEMETRY_DOC_ID); - - return mlTelemetrySavedObject.attributes; - } catch (err) { - return createMlTelemetry(); - } - }, - }); - - usageCollection.registerCollector(mlUsageCollector); -} diff --git a/x-pack/plugins/ml/server/lib/ml_telemetry/ml_telemetry.test.ts b/x-pack/plugins/ml/server/lib/ml_telemetry/ml_telemetry.test.ts deleted file mode 100644 index cda160877f7ae..0000000000000 --- a/x-pack/plugins/ml/server/lib/ml_telemetry/ml_telemetry.test.ts +++ /dev/null @@ -1,128 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -// import { -// createMlTelemetry, -// incrementFileDataVisualizerIndexCreationCount, -// ML_TELEMETRY_DOC_ID, -// MlTelemetry, -// storeMlTelemetry, -// } from './ml_telemetry'; - -describe('ml_telemetry', () => { - describe('createMlTelemetry', () => { - it('should create a MlTelemetry object', () => { - // const mlTelemetry = createMlTelemetry(1); - // expect(mlTelemetry.file_data_visualizer.index_creation_count).toBe(1); - }); - it('should ignore undefined or unknown values', () => { - // const mlTelemetry = createMlTelemetry(undefined); - // expect(mlTelemetry.file_data_visualizer.index_creation_count).toBe(0); - }); - }); - - describe('storeMlTelemetry', () => { - // let mlTelemetry: MlTelemetry; - // let internalRepository: any; - - // beforeEach(() => { - // internalRepository = { create: jest.fn(), get: jest.fn() }; - // mlTelemetry = { - // file_data_visualizer: { - // index_creation_count: 1, - // }, - // }; - // }); - - it('should call internalRepository create with the given MlTelemetry object', () => { - // storeMlTelemetry(internalRepository, mlTelemetry); - // expect(internalRepository.create.mock.calls[0][1]).toBe(mlTelemetry); - }); - - it('should call internalRepository create with the ml-telemetry document type and ID', () => { - // storeMlTelemetry(internalRepository, mlTelemetry); - // expect(internalRepository.create.mock.calls[0][0]).toBe('ml-telemetry'); - // expect(internalRepository.create.mock.calls[0][2].id).toBe(ML_TELEMETRY_DOC_ID); - }); - - it('should call internalRepository create with overwrite: true', () => { - // storeMlTelemetry(internalRepository, mlTelemetry); - // expect(internalRepository.create.mock.calls[0][2].overwrite).toBe(true); - }); - }); - - describe('incrementFileDataVisualizerIndexCreationCount', () => { - // let savedObjectsClient: any; - - // function createSavedObjectsClientInstance( - // telemetryEnabled?: boolean, - // indexCreationCount?: number - // ) { - // return { - // create: jest.fn(), - // get: jest.fn(obj => { - // switch (obj) { - // case 'telemetry': - // if (telemetryEnabled === undefined) { - // throw Error; - // } - // return { - // attributes: { - // enabled: telemetryEnabled, - // }, - // }; - // case 'ml-telemetry': - // // emulate that a non-existing saved object will throw an error - // if (indexCreationCount === undefined) { - // throw Error; - // } - // return { - // attributes: { - // file_data_visualizer: { - // index_creation_count: indexCreationCount, - // }, - // }, - // }; - // } - // }), - // }; - // } - - // function mockInit(telemetryEnabled?: boolean, indexCreationCount?: number): void { - // savedObjectsClient = createSavedObjectsClientInstance(telemetryEnabled, indexCreationCount); - // } - - it('should not increment if telemetry status cannot be determined', async () => { - // mockInit(); - // await incrementFileDataVisualizerIndexCreationCount(savedObjectsClient); - // expect(savedObjectsClient.create.mock.calls).toHaveLength(0); - }); - - it('should not increment if telemetry status is disabled', async () => { - // mockInit(false); - // await incrementFileDataVisualizerIndexCreationCount(savedObjectsClient); - // expect(savedObjectsClient.create.mock.calls).toHaveLength(0); - }); - - it('should initialize index_creation_count with 1', async () => { - // mockInit(true); - // await incrementFileDataVisualizerIndexCreationCount(savedObjectsClient); - // expect(savedObjectsClient.create.mock.calls[0][0]).toBe('ml-telemetry'); - // expect(savedObjectsClient.create.mock.calls[0][1]).toEqual({ - // file_data_visualizer: { index_creation_count: 1 }, - // }); - }); - - it('should increment index_creation_count to 2', async () => { - // mockInit(true, 1); - // await incrementFileDataVisualizerIndexCreationCount(savedObjectsClient); - // expect(savedObjectsClient.create.mock.calls[0][0]).toBe('ml-telemetry'); - // expect(savedObjectsClient.create.mock.calls[0][1]).toEqual({ - // file_data_visualizer: { index_creation_count: 2 }, - // }); - }); - }); -}); diff --git a/x-pack/plugins/ml/server/lib/ml_telemetry/ml_telemetry.ts b/x-pack/plugins/ml/server/lib/ml_telemetry/ml_telemetry.ts deleted file mode 100644 index 1ca155582db11..0000000000000 --- a/x-pack/plugins/ml/server/lib/ml_telemetry/ml_telemetry.ts +++ /dev/null @@ -1,72 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { SavedObjectAttributes, SavedObjectsClientContract } from 'kibana/server'; - -export interface MlTelemetry extends SavedObjectAttributes { - file_data_visualizer: { - index_creation_count: number; - }; -} - -export interface MlTelemetrySavedObject { - attributes: MlTelemetry; -} - -export const ML_TELEMETRY_DOC_ID = 'ml-telemetry'; - -export function createMlTelemetry(count: number = 0): MlTelemetry { - return { - file_data_visualizer: { - index_creation_count: count, - }, - }; -} -// savedObjects -export function storeMlTelemetry( - savedObjectsClient: SavedObjectsClientContract, - mlTelemetry: MlTelemetry -): void { - savedObjectsClient.create('ml-telemetry', mlTelemetry, { - id: ML_TELEMETRY_DOC_ID, - overwrite: true, - }); -} - -export async function incrementFileDataVisualizerIndexCreationCount( - savedObjectsClient: SavedObjectsClientContract -): Promise { - return; - try { - const { attributes } = await savedObjectsClient.get<{ enabled: boolean }>( - 'telemetry', - 'telemetry' - ); - - if (attributes.enabled === false) { - return; - } - } catch (error) { - // if we aren't allowed to get the telemetry document, - // we assume we couldn't opt in to telemetry and won't increment the index count. - return; - } - - let indicesCount = 1; - - try { - const { attributes } = (await savedObjectsClient.get( - 'ml-telemetry', - ML_TELEMETRY_DOC_ID - )) as MlTelemetrySavedObject; - indicesCount = attributes.file_data_visualizer.index_creation_count + 1; - } catch (e) { - /* silently fail, this will happen if the saved object doesn't exist yet. */ - } - - const mlTelemetry = createMlTelemetry(indicesCount); - storeMlTelemetry(savedObjectsClient, mlTelemetry); -} diff --git a/x-pack/plugins/ml/server/lib/telemetry/index.ts b/x-pack/plugins/ml/server/lib/telemetry/index.ts new file mode 100644 index 0000000000000..b5ec80daf1787 --- /dev/null +++ b/x-pack/plugins/ml/server/lib/telemetry/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; + * you may not use this file except in compliance with the Elastic License. + */ + +export { initMlTelemetry } from './ml_usage_collector'; +export { updateTelemetry } from './telemetry'; diff --git a/x-pack/plugins/ml/server/lib/telemetry/internal_repository.ts b/x-pack/plugins/ml/server/lib/telemetry/internal_repository.ts new file mode 100644 index 0000000000000..a273ea4baadfa --- /dev/null +++ b/x-pack/plugins/ml/server/lib/telemetry/internal_repository.ts @@ -0,0 +1,15 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SavedObjectsServiceStart, ISavedObjectsRepository } from 'kibana/server'; + +let internalRepository: ISavedObjectsRepository | null = null; +export const setInternalRepository = ( + createInternalRepository: SavedObjectsServiceStart['createInternalRepository'] +) => { + internalRepository = createInternalRepository(); +}; +export const getInternalRepository = () => internalRepository; diff --git a/x-pack/plugins/ml/server/lib/telemetry/mappings.ts b/x-pack/plugins/ml/server/lib/telemetry/mappings.ts new file mode 100644 index 0000000000000..87e2243328422 --- /dev/null +++ b/x-pack/plugins/ml/server/lib/telemetry/mappings.ts @@ -0,0 +1,25 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { SavedObjectsType } from 'src/core/server'; +import { TELEMETRY_DOC_ID } from './telemetry'; + +export const mlTelemetryMappingsType: SavedObjectsType = { + name: TELEMETRY_DOC_ID, + hidden: false, + namespaceAgnostic: true, + mappings: { + properties: { + file_data_visualizer: { + properties: { + index_creation_count: { + type: 'long', + }, + }, + }, + }, + }, +}; diff --git a/x-pack/plugins/ml/server/lib/telemetry/ml_usage_collector.ts b/x-pack/plugins/ml/server/lib/telemetry/ml_usage_collector.ts new file mode 100644 index 0000000000000..21e5dce8e4706 --- /dev/null +++ b/x-pack/plugins/ml/server/lib/telemetry/ml_usage_collector.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { CoreSetup } from 'kibana/server'; + +import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; +import { getTelemetry, initTelemetry } from './telemetry'; +import { mlTelemetryMappingsType } from './mappings'; +import { setInternalRepository } from './internal_repository'; + +const TELEMETRY_TYPE = 'mlTelemetry'; + +export function initMlTelemetry(coreSetup: CoreSetup, usageCollection: UsageCollectionSetup) { + coreSetup.savedObjects.registerType(mlTelemetryMappingsType); + registerMlUsageCollector(usageCollection); + coreSetup.getStartServices().then(([core]) => { + setInternalRepository(core.savedObjects.createInternalRepository); + }); +} + +function registerMlUsageCollector(usageCollection: UsageCollectionSetup): void { + const mlUsageCollector = usageCollection.makeUsageCollector({ + type: TELEMETRY_TYPE, + isReady: () => true, + fetch: async () => (await getTelemetry()) || initTelemetry(), + }); + + usageCollection.registerCollector(mlUsageCollector); +} diff --git a/x-pack/plugins/ml/server/lib/telemetry/telemetry.test.ts b/x-pack/plugins/ml/server/lib/telemetry/telemetry.test.ts new file mode 100644 index 0000000000000..f41c4fda93a54 --- /dev/null +++ b/x-pack/plugins/ml/server/lib/telemetry/telemetry.test.ts @@ -0,0 +1,49 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { getTelemetry, updateTelemetry } from './telemetry'; + +const internalRepository = () => ({ + get: jest.fn(() => null), + create: jest.fn(() => ({ attributes: 'test' })), + update: jest.fn(() => ({ attributes: 'test' })), +}); + +function mockInit(getVal: any = { attributes: {} }): any { + return { + ...internalRepository(), + get: jest.fn(() => getVal), + }; +} + +describe('ml plugin telemetry', () => { + describe('getTelemetry', () => { + it('should get existing telemetry', async () => { + const internalRepo = mockInit(); + await getTelemetry(internalRepo); + expect(internalRepo.update.mock.calls.length).toBe(0); + expect(internalRepo.get.mock.calls.length).toBe(1); + expect(internalRepo.create.mock.calls.length).toBe(0); + }); + }); + + describe('updateTelemetry', () => { + it('should update existing telemetry', async () => { + const internalRepo = mockInit({ + attributes: { + file_data_visualizer: { + index_creation_count: 2, + }, + }, + }); + + await updateTelemetry(internalRepo); + expect(internalRepo.update.mock.calls.length).toBe(1); + expect(internalRepo.get.mock.calls.length).toBe(1); + expect(internalRepo.create.mock.calls.length).toBe(0); + }); + }); +}); diff --git a/x-pack/plugins/ml/server/lib/telemetry/telemetry.ts b/x-pack/plugins/ml/server/lib/telemetry/telemetry.ts new file mode 100644 index 0000000000000..bc56e8b2a4372 --- /dev/null +++ b/x-pack/plugins/ml/server/lib/telemetry/telemetry.ts @@ -0,0 +1,81 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import _ from 'lodash'; +import { ISavedObjectsRepository } from 'kibana/server'; + +import { getInternalRepository } from './internal_repository'; + +export const TELEMETRY_DOC_ID = 'ml-telemetry'; + +interface Telemetry { + file_data_visualizer: { + index_creation_count: number; + }; +} + +export interface TelemetrySavedObject { + attributes: Telemetry; +} + +export function initTelemetry(): Telemetry { + return { + file_data_visualizer: { + index_creation_count: 0, + }, + }; +} + +export async function getTelemetry( + internalRepository?: ISavedObjectsRepository +): Promise { + if (internalRepository === undefined) { + return null; + } + + let telemetrySavedObject; + + try { + telemetrySavedObject = await internalRepository.get( + TELEMETRY_DOC_ID, + TELEMETRY_DOC_ID + ); + } catch (e) { + // Fail silently + } + + return telemetrySavedObject ? telemetrySavedObject.attributes : null; +} + +export async function updateTelemetry(internalRepo?: ISavedObjectsRepository) { + const internalRepository = internalRepo || getInternalRepository(); + if (internalRepository === null) { + return; + } + + let telemetry = await getTelemetry(internalRepository); + // Create if doesn't exist + if (telemetry === null || _.isEmpty(telemetry)) { + const newTelemetrySavedObject = await internalRepository.create( + TELEMETRY_DOC_ID, + initTelemetry(), + { id: TELEMETRY_DOC_ID } + ); + telemetry = newTelemetrySavedObject.attributes; + } + + if (telemetry !== null) { + await internalRepository.update(TELEMETRY_DOC_ID, TELEMETRY_DOC_ID, incrementCounts(telemetry)); + } +} + +function incrementCounts(telemetry: Telemetry) { + return { + file_data_visualizer: { + index_creation_count: telemetry.file_data_visualizer.index_creation_count + 1, + }, + }; +} diff --git a/x-pack/plugins/ml/server/plugin.ts b/x-pack/plugins/ml/server/plugin.ts index 01d0bcc867019..8948d232b9e5e 100644 --- a/x-pack/plugins/ml/server/plugin.ts +++ b/x-pack/plugins/ml/server/plugin.ts @@ -16,7 +16,7 @@ import { PluginsSetup, RouteInitialization } from './types'; import { PLUGIN_ID, PLUGIN_ICON } from '../common/constants/app'; import { elasticsearchJsPlugin } from './client/elasticsearch_ml'; -import { makeMlUsageCollector } from './lib/ml_telemetry'; +import { initMlTelemetry } from './lib/telemetry'; import { initMlServerLog } from './client/log'; import { initSampleDataSets } from './lib/sample_data_sets'; @@ -130,9 +130,7 @@ export class MlServerPlugin implements Plugin { - makeMlUsageCollector(plugins.usageCollection, core.savedObjects); - }); + initMlTelemetry(coreSetup, plugins.usageCollection); return createSharedServices(this.mlLicense, plugins.spaces, plugins.cloud); } diff --git a/x-pack/plugins/ml/server/routes/file_data_visualizer.ts b/x-pack/plugins/ml/server/routes/file_data_visualizer.ts index a14d51ae61b05..fcfd6e121c9f1 100644 --- a/x-pack/plugins/ml/server/routes/file_data_visualizer.ts +++ b/x-pack/plugins/ml/server/routes/file_data_visualizer.ts @@ -19,7 +19,7 @@ import { } from '../models/file_data_visualizer'; import { RouteInitialization } from '../types'; -import { incrementFileDataVisualizerIndexCreationCount } from '../lib/ml_telemetry'; +import { updateTelemetry } from '../lib/telemetry'; function analyzeFiles(context: RequestHandlerContext, data: InputData, overrides: InputOverrides) { const { analyzeFile } = fileDataVisualizerProvider(context.ml!.mlClient.callAsCurrentUser); @@ -132,7 +132,7 @@ export function fileDataVisualizerRoutes({ router, mlLicense }: RouteInitializat // follow-up import calls to just add additional data will include the `id` of the created // index, we'll ignore those and don't increment the counter. if (id === undefined) { - await incrementFileDataVisualizerIndexCreationCount(context.core.savedObjects.client); + await updateTelemetry(); } const result = await importData( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/boot.tsx b/x-pack/plugins/triggers_actions_ui/public/application/boot.tsx index a458472c6d753..c157f923e4447 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/boot.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/boot.tsx @@ -9,7 +9,7 @@ import { render, unmountComponentAtNode } from 'react-dom'; import { SavedObjectsClientContract } from 'src/core/public'; import { App, AppDeps } from './app'; -import { setSavedObjectsClient } from '../application/components/builtin_alert_types/threshold/lib/api'; +import { setSavedObjectsClient } from '../common/lib/index_threshold_api'; interface BootDeps extends AppDeps { element: HTMLElement; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index.test.tsx index d44787f0c4ed6..f1d4790e67bbe 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index.test.tsx @@ -9,6 +9,7 @@ import { TypeRegistry } from '../../type_registry'; import { registerBuiltInActionTypes } from './index'; import { ActionTypeModel, ActionParamsProps } from '../../../types'; import { IndexActionParams, EsIndexActionConnector } from './types'; +import { coreMock } from '../../../../../../../src/core/public/mocks'; const ACTION_TYPE_ID = '.index'; let actionTypeModel: ActionTypeModel; @@ -38,16 +39,15 @@ describe('index connector validation', () => { name: 'es_index', config: { index: 'test_es_index', + refresh: false, + executionTimeField: '1', }, } as EsIndexActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ - errors: {}, - }); - - delete actionConnector.config.index; - expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ - errors: {}, + errors: { + index: [], + }, }); }); }); @@ -55,9 +55,6 @@ describe('index connector validation', () => { describe('action params validation', () => { test('action params validation succeeds when action params is valid', () => { const actionParams = { - index: 'test', - refresh: false, - executionTimeField: '1', documents: ['test'], }; @@ -75,6 +72,8 @@ describe('action params validation', () => { describe('IndexActionConnectorFields renders', () => { test('all connector fields is rendered', () => { + const mocks = coreMock.createSetup(); + expect(actionTypeModel.actionConnectorFields).not.toBeNull(); if (!actionTypeModel.actionConnectorFields) { return; @@ -87,23 +86,21 @@ describe('IndexActionConnectorFields renders', () => { name: 'es_index', config: { index: 'test', + refresh: false, + executionTimeField: 'test1', }, } as EsIndexActionConnector; const wrapper = mountWithIntl( {}} editActionSecrets={() => {}} + http={mocks.http} /> ); - expect(wrapper.find('[data-test-subj="indexInput"]').length > 0).toBeTruthy(); - expect( - wrapper - .find('[data-test-subj="indexInput"]') - .first() - .prop('value') - ).toBe('test'); + expect(wrapper.find('[data-test-subj="connectorIndexesComboBox"]').length > 0).toBeTruthy(); + expect(wrapper.find('[data-test-subj="indexRefreshCheckbox"]').length > 0).toBeTruthy(); }); }); @@ -117,8 +114,6 @@ describe('IndexParamsFields renders', () => { ActionParamsProps >; const actionParams = { - index: 'test_index', - refresh: false, documents: ['test'], }; const wrapper = mountWithIntl( @@ -129,13 +124,11 @@ describe('IndexParamsFields renders', () => { index={0} /> ); - expect(wrapper.find('[data-test-subj="indexInput"]').length > 0).toBeTruthy(); expect( wrapper - .find('[data-test-subj="indexInput"]') + .find('[data-test-subj="actionIndexDoc"]') .first() .prop('value') - ).toBe('test_index'); - expect(wrapper.find('[data-test-subj="indexRefreshCheckbox"]').length > 0).toBeTruthy(); + ).toBe('"test"'); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index.tsx index 6af54d2bf15b4..b3e62e022c412 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index.tsx @@ -3,8 +3,18 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment } from 'react'; -import { EuiFieldText, EuiFormRow, EuiSwitch, EuiSpacer } from '@elastic/eui'; +import React, { Fragment, useState, useEffect } from 'react'; +import { + EuiFormRow, + EuiSwitch, + EuiSpacer, + EuiCodeEditor, + EuiComboBox, + EuiComboBoxOptionOption, + EuiSelect, + EuiTitle, + EuiIconTip, +} from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; import { @@ -14,6 +24,13 @@ import { ActionParamsProps, } from '../../../types'; import { IndexActionParams, EsIndexActionConnector } from './types'; +import { getTimeFieldOptions } from '../../../common/lib/get_time_options'; +import { + firstFieldOption, + getFields, + getIndexOptions, + getIndexPatterns, +} from '../../../common/index_controls'; export function getActionType(): ActionTypeModel { return { @@ -25,8 +42,23 @@ export function getActionType(): ActionTypeModel { defaultMessage: 'Index data into Elasticsearch.', } ), - validateConnector: (): ValidationResult => { - return { errors: {} }; + validateConnector: (action: EsIndexActionConnector): ValidationResult => { + const validationResult = { errors: {} }; + const errors = { + index: new Array(), + }; + validationResult.errors = errors; + if (!action.config.index) { + errors.index.push( + i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.indexAction.error.requiredIndexText', + { + defaultMessage: 'Index is required.', + } + ) + ); + } + return validationResult; }, actionConnectorFields: IndexActionConnectorFields, actionParamsFields: IndexParamsFields, @@ -38,33 +70,189 @@ export function getActionType(): ActionTypeModel { const IndexActionConnectorFields: React.FunctionComponent> = ({ action, editActionConfig }) => { - const { index } = action.config; +>> = ({ action, editActionConfig, errors, http }) => { + const { index, refresh, executionTimeField } = action.config; + const [hasTimeFieldCheckbox, setTimeFieldCheckboxState] = useState( + executionTimeField !== undefined + ); + + const [indexPatterns, setIndexPatterns] = useState([]); + const [indexOptions, setIndexOptions] = useState([]); + const [timeFieldOptions, setTimeFieldOptions] = useState([firstFieldOption]); + const [isIndiciesLoading, setIsIndiciesLoading] = useState(false); + + useEffect(() => { + const indexPatternsFunction = async () => { + setIndexPatterns(await getIndexPatterns()); + if (index) { + const currentEsFields = await getFields(http!, [index]); + const timeFields = getTimeFieldOptions(currentEsFields as any); + setTimeFieldOptions([firstFieldOption, ...timeFields]); + } + }; + indexPatternsFunction(); + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + return ( - - + +
+ +
+
+ + ) => { - editActionConfig('index', e.target.value); - }} - onBlur={() => { - if (!index) { - editActionConfig('index', ''); + label={ + + } + isInvalid={errors.index.length > 0 && index !== undefined} + error={errors.index} + helpText={ + + } + > + 0 && index !== undefined} + noSuggestions={!indexOptions.length} + options={indexOptions} + data-test-subj="connectorIndexesComboBox" + selectedOptions={ + index + ? [ + { + value: index, + label: index, + }, + ] + : [] } + onChange={async (selected: EuiComboBoxOptionOption[]) => { + editActionConfig('index', selected[0].value); + const indices = selected.map(s => s.value as string); + + // reset time field and expression fields if indices are deleted + if (indices.length === 0) { + setTimeFieldOptions([]); + return; + } + const currentEsFields = await getFields(http!, indices); + const timeFields = getTimeFieldOptions(currentEsFields as any); + + setTimeFieldOptions([firstFieldOption, ...timeFields]); + }} + onSearchChange={async search => { + setIsIndiciesLoading(true); + setIndexOptions(await getIndexOptions(http!, search, indexPatterns)); + setIsIndiciesLoading(false); + }} + onBlur={() => { + if (!index) { + editActionConfig('index', ''); + } + }} + /> + + + { + editActionConfig('refresh', e.target.checked); }} + label={ + <> + {' '} + + + } + /> + + { + setTimeFieldCheckboxState(!hasTimeFieldCheckbox); + }} + label={ + <> + + + + } /> -
+ + {hasTimeFieldCheckbox ? ( + <> + + } + > + { + editActionConfig('executionTimeField', e.target.value); + }} + onBlur={() => { + if (executionTimeField === undefined) { + editActionConfig('executionTimeField', ''); + } + }} + /> + + + ) : null} + ); }; @@ -73,47 +261,48 @@ const IndexParamsFields: React.FunctionComponent { - const { refresh } = actionParams; + const { documents } = actionParams; + + function onDocumentsChange(updatedDocuments: string) { + try { + const documentsJSON = JSON.parse(updatedDocuments); + editAction('documents', [documentsJSON], index); + // eslint-disable-next-line no-empty + } catch (e) {} + } return ( - ) => { - editAction('index', e.target.value, index); + 0 ? documents[0] : {}, null, 2)} + onChange={onDocumentsChange} + width="100%" + height="auto" + minLines={6} + maxLines={30} + isReadOnly={false} + setOptions={{ + showLineNumbers: true, + tabSize: 2, }} - onBlur={() => { - if (!actionParams.index) { - editAction('index', '', index); - } + editorProps={{ + $blockScrolling: Infinity, }} + showGutter={true} /> - - { - editAction('refresh', e.target.checked, index); - }} - label={ - - } - /> ); }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/types.ts index 45a08b2d5263a..c0ddd6791e90e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/types.ts @@ -39,9 +39,6 @@ export interface PagerDutyActionParams { } export interface IndexActionParams { - index?: string; - refresh?: boolean; - executionTimeField?: string; documents: string[]; } @@ -85,7 +82,9 @@ export interface EmailActionConnector extends ActionConnector { } interface EsIndexConfig { - index?: string; + index: string; + executionTimeField?: string; + refresh?: boolean; } export interface EsIndexActionConnector extends ActionConnector { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.tsx index 2bf779e550618..5c7f48de81f75 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/expression.tsx @@ -23,12 +23,13 @@ import { EuiEmptyPrompt, EuiText, } from '@elastic/eui'; -import { COMPARATORS, builtInComparators } from '../../../../common/constants'; import { - getMatchingIndicesForThresholdAlertType, - getThresholdAlertTypeFields, - loadIndexPatterns, -} from './lib/api'; + firstFieldOption, + getIndexPatterns, + getIndexOptions, + getFields, +} from '../../../../common/index_controls'; +import { COMPARATORS, builtInComparators } from '../../../../common/constants'; import { getTimeFieldOptions } from '../../../../common/lib/get_time_options'; import { ThresholdVisualization } from './visualization'; import { WhenExpression } from '../../../../common'; @@ -95,15 +96,6 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent expressionFieldsWithValidation.includes(errorKey) && errors[errorKey].length >= 1 ); - const getIndexPatterns = async () => { - const indexPatternObjects = await loadIndexPatterns(); - const titles = indexPatternObjects.map((indexPattern: any) => indexPattern.attributes.title); - setIndexPatterns(titles); - }; - const expressionErrorMessage = i18n.translate( 'xpack.triggersActionsUI.sections.alertAdd.threshold.fixErrorInExpressionBelowValidationMessage', { @@ -150,7 +136,7 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent 0) { - const currentEsFields = await getFields(index); + const currentEsFields = await getFields(http, index); const timeFields = getTimeFieldOptions(currentEsFields as any); setEsFields(currentEsFields); @@ -158,12 +144,11 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent { - return await getThresholdAlertTypeFields({ indexes, http }); - }; - useEffect(() => { - getIndexPatterns(); + const indexPatternsFunction = async () => { + setIndexPatterns(await getIndexPatterns()); + }; + indexPatternsFunction(); }, []); useEffect(() => { @@ -171,60 +156,6 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent; - } - - const getIndexOptions = async (pattern: string, indexPatternsParam: string[]) => { - const options: IOption[] = []; - - if (!pattern) { - return options; - } - - const matchingIndices = (await getMatchingIndicesForThresholdAlertType({ - pattern, - http, - })) as string[]; - const matchingIndexPatterns = indexPatternsParam.filter(anIndexPattern => { - return anIndexPattern.includes(pattern); - }) as string[]; - - if (matchingIndices.length || matchingIndexPatterns.length) { - const matchingOptions = _.uniq([...matchingIndices, ...matchingIndexPatterns]); - - options.push({ - label: i18n.translate( - 'xpack.triggersActionsUI.sections.alertAdd.threshold.indicesAndIndexPatternsLabel', - { - defaultMessage: 'Based on your indices and index patterns', - } - ), - options: matchingOptions.map(match => { - return { - label: match, - value: match, - }; - }), - }); - } - - options.push({ - label: i18n.translate('xpack.triggersActionsUI.sections.alertAdd.threshold.chooseLabel', { - defaultMessage: 'Choose…', - }), - options: [ - { - value: pattern, - label: pattern, - }, - ], - }); - - return options; - }; - const indexPopover = ( @@ -285,7 +216,7 @@ export const IndexThresholdAlertTypeExpression: React.FunctionComponent { setIsIndiciesLoading(true); - setIndexOptions(await getIndexOptions(search, indexPatterns)); + setIndexOptions(await getIndexOptions(http, search, indexPatterns)); setIsIndiciesLoading(false); }} onBlur={() => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/types.ts index d5b64f1489b8d..356b0fbbc0845 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/types.ts @@ -4,12 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -export { - TimeSeriesResult, - TimeSeriesResultRow, - MetricResult, -} from '../../../../../../alerting_builtins/common/alert_types/index_threshold'; - export interface Comparator { text: string; value: string; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/visualization.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/visualization.tsx index f27e35fe7609d..0bcaa83127468 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/visualization.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/visualization.tsx @@ -23,7 +23,7 @@ import { import moment from 'moment-timezone'; import { EuiCallOut, EuiLoadingChart, EuiSpacer, EuiEmptyPrompt, EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { getThresholdAlertVisualizationData } from './lib/api'; +import { getThresholdAlertVisualizationData } from '../../../../common/lib/index_threshold_api'; import { AggregationType, Comparator } from '../../../../common/types'; import { AlertsContextValue } from '../../../context/alerts_context'; import { IndexThresholdAlertParams } from './types'; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx index f68cc5759fb54..1c70e42e7ae72 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx @@ -68,6 +68,7 @@ describe('action_connector_form', () => { dispatch={() => {}} errors={{ name: [] }} actionTypeRegistry={deps.actionTypeRegistry} + http={deps.http} /> ); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx index e221fff64048e..57333d8032793 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx @@ -15,6 +15,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; +import { HttpSetup } from 'kibana/public'; import { ReducerAction } from './connector_reducer'; import { ActionConnector, IErrorObject, ActionTypeModel } from '../../../types'; import { TypeRegistry } from '../../type_registry'; @@ -47,6 +48,7 @@ interface ActionConnectorProps { }; errors: IErrorObject; actionTypeRegistry: TypeRegistry; + http: HttpSetup; } export const ActionConnectorForm = ({ @@ -56,6 +58,7 @@ export const ActionConnectorForm = ({ serverError, errors, actionTypeRegistry, + http, }: ActionConnectorProps) => { const setActionProperty = (key: string, value: any) => { dispatch({ command: { type: 'setProperty' }, payload: { key, value } }); @@ -148,6 +151,7 @@ export const ActionConnectorForm = ({ errors={errors} editActionConfig={setActionConfigProperty} editActionSecrets={setActionSecretsProperty} + http={http} /> ) : null} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx index f265a1de6f56a..9aea2419ec619 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx @@ -104,6 +104,7 @@ export const ConnectorAddFlyout = ({ dispatch={dispatch} errors={errors} actionTypeRegistry={actionTypeRegistry} + http={http} /> ); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx index c7f52fb462cc0..977a908fd86f0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx @@ -152,6 +152,7 @@ export const ConnectorAddModal = ({ serverError={serverError} errors={errors} actionTypeRegistry={actionTypeRegistry} + http={http} /> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx index d0dcff9ef6a94..39c0b7255a7b9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx @@ -135,6 +135,7 @@ export const ConnectorEditFlyout = ({ actionTypeName={connector.actionType} dispatch={dispatch} actionTypeRegistry={actionTypeRegistry} + http={http} /> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx index 66583679cd792..9f98aef694c4e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.test.tsx @@ -247,6 +247,8 @@ describe('alerts_list component with items', () => { alertTypeRegistry: alertTypeRegistry as any, }; + alertTypeRegistry.has.mockReturnValue(true); + wrapper = mountWithIntl( @@ -262,11 +264,15 @@ describe('alerts_list component with items', () => { expect(loadActionTypes).toHaveBeenCalled(); } - it('renders table of connectors', async () => { + it('renders table of alerts', async () => { await setup(); expect(wrapper.find('EuiBasicTable')).toHaveLength(1); expect(wrapper.find('EuiTableRow')).toHaveLength(2); }); + it('renders edit button for registered alert types', async () => { + await setup(); + expect(wrapper.find('[data-test-subj="alertsTableCell-editLink"]').length).toBeGreaterThan(0); + }); }); describe('alerts_list component empty with show only capability', () => { @@ -464,6 +470,8 @@ describe('alerts_list with show only capability', () => { alertTypeRegistry: alertTypeRegistry as any, }; + alertTypeRegistry.has.mockReturnValue(false); + wrapper = mountWithIntl( @@ -482,4 +490,8 @@ describe('alerts_list with show only capability', () => { expect(wrapper.find('EuiTableRow')).toHaveLength(2); // TODO: check delete button }); + it('not renders edit button for non registered alert types', async () => { + await setup(); + expect(wrapper.find('[data-test-subj="alertsTableCell-editLink"]').length).toBe(0); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx index 2975b1ef6eba2..8d8fc177b57a0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alerts_list/components/alerts_list.tsx @@ -225,7 +225,7 @@ export const AlertsList: React.FunctionComponent = () => { ? [ { render: (item: AlertTableItem) => { - return ( + return alertTypeRegistry.has(item.alertTypeId) ? ( { id="xpack.triggersActionsUI.sections.alertsList.alertsListTable.columns.editLinkTitle" /> + ) : ( + <> ); }, }, diff --git a/x-pack/plugins/triggers_actions_ui/public/common/index_controls/index.ts b/x-pack/plugins/triggers_actions_ui/public/common/index_controls/index.ts new file mode 100644 index 0000000000000..32fb35d6adebb --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/common/index_controls/index.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; + * you may not use this file except in compliance with the Elastic License. + */ + +import { HttpSetup } from 'kibana/public'; +import { i18n } from '@kbn/i18n'; +import { + loadIndexPatterns, + getMatchingIndicesForThresholdAlertType, + getThresholdAlertTypeFields, +} from '../lib/index_threshold_api'; + +export interface IOption { + label: string; + options: Array<{ value: string; label: string }>; +} + +export const getIndexPatterns = async () => { + const indexPatternObjects = await loadIndexPatterns(); + return indexPatternObjects.map((indexPattern: any) => indexPattern.attributes.title); +}; + +export const getIndexOptions = async ( + http: HttpSetup, + pattern: string, + indexPatternsParam: string[] +) => { + const options: IOption[] = []; + + if (!pattern) { + return options; + } + + const matchingIndices = (await getMatchingIndicesForThresholdAlertType({ + pattern, + http, + })) as string[]; + const matchingIndexPatterns = indexPatternsParam.filter(anIndexPattern => { + return anIndexPattern.includes(pattern); + }) as string[]; + + if (matchingIndices.length || matchingIndexPatterns.length) { + const matchingOptions = _.uniq([...matchingIndices, ...matchingIndexPatterns]); + + options.push({ + label: i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.indexAction.indicesAndIndexPatternsLabel', + { + defaultMessage: 'Based on your index patterns', + } + ), + options: matchingOptions.map(match => { + return { + label: match, + value: match, + }; + }), + }); + } + + options.push({ + label: i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.indexAction.chooseLabel', + { + defaultMessage: 'Choose…', + } + ), + options: [ + { + value: pattern, + label: pattern, + }, + ], + }); + + return options; +}; + +export const getFields = async (http: HttpSetup, indexes: string[]) => { + return await getThresholdAlertTypeFields({ indexes, http }); +}; + +export const firstFieldOption = { + text: i18n.translate('xpack.triggersActionsUI.sections.alertAdd.threshold.timeFieldOptionLabel', { + defaultMessage: 'Select a field', + }), + value: '', +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/lib/api.ts b/x-pack/plugins/triggers_actions_ui/public/common/lib/index_threshold_api.ts similarity index 96% rename from x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/lib/api.ts rename to x-pack/plugins/triggers_actions_ui/public/common/lib/index_threshold_api.ts index 064f05b415d42..9ec198a43646f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_alert_types/threshold/lib/api.ts +++ b/x-pack/plugins/triggers_actions_ui/public/common/lib/index_threshold_api.ts @@ -4,8 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { HttpSetup } from 'kibana/public'; -import { TimeSeriesResult } from '../types'; -export { TimeSeriesResult } from '../types'; +import { TimeSeriesResult } from '../../../../alerting_builtins/common/alert_types/index_threshold'; const INDEX_THRESHOLD_API_ROOT = '/api/alerting_builtins/index_threshold'; diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index d9681e2474f00..900521830571c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -3,6 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import { HttpSetup } from 'kibana/public'; import { ActionGroup } from '../../alerting/common'; import { ActionType } from '../../actions/common'; import { TypeRegistry } from './application/type_registry'; @@ -20,11 +21,12 @@ export type AlertTypeIndex = Record; export type ActionTypeRegistryContract = PublicMethodsOf>; export type AlertTypeRegistryContract = PublicMethodsOf>; -export interface ActionConnectorFieldsProps { - action: TActionCOnnector; +export interface ActionConnectorFieldsProps { + action: TActionConnector; editActionConfig: (property: string, value: any) => void; editActionSecrets: (property: string, value: any) => void; errors: { [key: string]: string[] }; + http?: HttpSetup; } export interface ActionParamsProps { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts index 1aa0f8e2c9f16..6d76a00d39b97 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts @@ -31,7 +31,9 @@ export default function indexTest({ getService }: FtrProviderContext) { .send({ name: 'An index action', actionTypeId: '.index', - config: {}, + config: { + index: ES_TEST_INDEX_NAME, + }, secrets: {}, }) .expect(200); @@ -41,7 +43,8 @@ export default function indexTest({ getService }: FtrProviderContext) { name: 'An index action', actionTypeId: '.index', config: { - index: null, + index: ES_TEST_INDEX_NAME, + refresh: false, }, }); createdActionID = createdAction.id; @@ -55,10 +58,10 @@ export default function indexTest({ getService }: FtrProviderContext) { id: fetchedAction.id, name: 'An index action', actionTypeId: '.index', - config: { index: null }, + config: { index: ES_TEST_INDEX_NAME, refresh: false }, }); - // create action with index config + // create action with all config props const { body: createdActionWithIndex } = await supertest .post('/api/action') .set('kbn-xsrf', 'foo') @@ -67,6 +70,8 @@ export default function indexTest({ getService }: FtrProviderContext) { actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, + refresh: true, + executionTimeField: 'test', }, }) .expect(200); @@ -77,6 +82,8 @@ export default function indexTest({ getService }: FtrProviderContext) { actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, + refresh: true, + executionTimeField: 'test', }, }); createdActionIDWithIndex = createdActionWithIndex.id; @@ -92,6 +99,8 @@ export default function indexTest({ getService }: FtrProviderContext) { actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, + refresh: true, + executionTimeField: 'test', }, }); }); @@ -111,20 +120,31 @@ export default function indexTest({ getService }: FtrProviderContext) { statusCode: 400, error: 'Bad Request', message: - 'error validating action type config: [index]: types that failed validation:\n- [index.0]: expected value of type [string] but got [number]\n- [index.1]: expected value to equal [null]', + 'error validating action type config: [index]: expected value of type [string] but got [number]', }); }); }); it('should execute successly when expected for a single body', async () => { + const { body: createdAction } = await supertest + .post('/api/action') + .set('kbn-xsrf', 'foo') + .send({ + name: 'An index action', + actionTypeId: '.index', + config: { + index: ES_TEST_INDEX_NAME, + refresh: true, + }, + secrets: {}, + }) + .expect(200); const { body: result } = await supertest - .post(`/api/action/${createdActionID}/_execute`) + .post(`/api/action/${createdAction.id}/_execute`) .set('kbn-xsrf', 'foo') .send({ params: { - index: ES_TEST_INDEX_NAME, documents: [{ testing: [1, 2, 3] }], - refresh: true, }, }) .expect(200); @@ -136,14 +156,25 @@ export default function indexTest({ getService }: FtrProviderContext) { }); it('should execute successly when expected for with multiple bodies', async () => { + const { body: createdAction } = await supertest + .post('/api/action') + .set('kbn-xsrf', 'foo') + .send({ + name: 'An index action', + actionTypeId: '.index', + config: { + index: ES_TEST_INDEX_NAME, + refresh: true, + }, + secrets: {}, + }) + .expect(200); const { body: result } = await supertest - .post(`/api/action/${createdActionID}/_execute`) + .post(`/api/action/${createdAction.id}/_execute`) .set('kbn-xsrf', 'foo') .send({ params: { - index: ES_TEST_INDEX_NAME, documents: [{ testing: [1, 2, 3] }, { Testing: [4, 5, 6] }], - refresh: true, }, }) .expect(200); @@ -169,12 +200,25 @@ export default function indexTest({ getService }: FtrProviderContext) { }); it('should execute successly with refresh false', async () => { + const { body: createdAction } = await supertest + .post('/api/action') + .set('kbn-xsrf', 'foo') + .send({ + name: 'An index action', + actionTypeId: '.index', + config: { + index: ES_TEST_INDEX_NAME, + refresh: false, + executionTimeField: 'test', + }, + secrets: {}, + }) + .expect(200); const { body: result } = await supertest - .post(`/api/action/${createdActionID}/_execute`) + .post(`/api/action/${createdAction.id}/_execute`) .set('kbn-xsrf', 'foo') .send({ params: { - index: ES_TEST_INDEX_NAME, documents: [{ refresh: 'not set' }], }, }) @@ -185,57 +229,32 @@ export default function indexTest({ getService }: FtrProviderContext) { items = await getTestIndexItems(es); expect(items.length).to.be.lessThan(2); - const { body: result2 } = await supertest - .post(`/api/action/${createdActionID}/_execute`) + const { body: createdActionWithRefresh } = await supertest + .post('/api/action') .set('kbn-xsrf', 'foo') .send({ - params: { + name: 'An index action', + actionTypeId: '.index', + config: { index: ES_TEST_INDEX_NAME, - documents: [{ refresh: 'true' }], refresh: true, }, + secrets: {}, }) .expect(200); - expect(result2.status).to.eql('ok'); - - items = await getTestIndexItems(es); - expect(items.length).to.eql(2); - }); - - it('should execute unsuccessfully when expected', async () => { - let response; - let result; - - response = await supertest - .post(`/api/action/${createdActionID}/_execute`) + const { body: result2 } = await supertest + .post(`/api/action/${createdActionWithRefresh.id}/_execute`) .set('kbn-xsrf', 'foo') .send({ params: { - indeX: ES_TEST_INDEX_NAME, - documents: [{ testing: [1, 2, 3] }], + documents: [{ refresh: 'true' }], }, }) .expect(200); - result = response.body; - expect(result.status).to.equal('error'); - expect(result.message).to.eql( - 'error validating action params: [indeX]: definition for this key is missing' - ); + expect(result2.status).to.eql('ok'); - response = await supertest - .post(`/api/action/${createdActionID}/_execute`) - .set('kbn-xsrf', 'foo') - .send({ - params: { - documents: [{ testing: [1, 2, 3] }], - }, - }) - .expect(200); - result = response.body; - expect(result.status).to.equal('error'); - expect(result.message).to.eql( - 'index param needs to be set because not set in config for action' - ); + items = await getTestIndexItems(es); + expect(items.length).to.eql(2); }); }); } diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts index 79e0da3a4c68a..5cc3d7275a7bd 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts @@ -31,7 +31,7 @@ export default function indexTest({ getService }: FtrProviderContext) { .send({ name: 'An index action', actionTypeId: '.index', - config: {}, + config: { index: ES_TEST_INDEX_NAME }, secrets: {}, }) .expect(200); @@ -41,7 +41,8 @@ export default function indexTest({ getService }: FtrProviderContext) { name: 'An index action', actionTypeId: '.index', config: { - index: null, + index: ES_TEST_INDEX_NAME, + refresh: false, }, }); createdActionID = createdAction.id; @@ -55,10 +56,10 @@ export default function indexTest({ getService }: FtrProviderContext) { id: fetchedAction.id, name: 'An index action', actionTypeId: '.index', - config: { index: null }, + config: { index: ES_TEST_INDEX_NAME, refresh: false }, }); - // create action with index config + // create action with all config props const { body: createdActionWithIndex } = await supertest .post('/api/action') .set('kbn-xsrf', 'foo') @@ -67,6 +68,8 @@ export default function indexTest({ getService }: FtrProviderContext) { actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, + refresh: true, + executionTimeField: 'test', }, }) .expect(200); @@ -77,6 +80,8 @@ export default function indexTest({ getService }: FtrProviderContext) { actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, + refresh: true, + executionTimeField: 'test', }, }); createdActionIDWithIndex = createdActionWithIndex.id; @@ -92,19 +97,32 @@ export default function indexTest({ getService }: FtrProviderContext) { actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, + refresh: true, + executionTimeField: 'test', }, }); }); it('should execute successly when expected for a single body', async () => { + const { body: createdAction } = await supertest + .post('/api/action') + .set('kbn-xsrf', 'foo') + .send({ + name: 'An index action', + actionTypeId: '.index', + config: { + index: ES_TEST_INDEX_NAME, + refresh: true, + }, + secrets: {}, + }) + .expect(200); const { body: result } = await supertest - .post(`/api/action/${createdActionID}/_execute`) + .post(`/api/action/${createdAction.id}/_execute`) .set('kbn-xsrf', 'foo') .send({ params: { - index: ES_TEST_INDEX_NAME, documents: [{ testing: [1, 2, 3] }], - refresh: true, }, }) .expect(200); diff --git a/x-pack/test/api_integration/apis/endpoint/metadata.ts b/x-pack/test/api_integration/apis/endpoint/metadata.ts index 5f18bdd9bea02..49e527fa3e7e8 100644 --- a/x-pack/test/api_integration/apis/endpoint/metadata.ts +++ b/x-pack/test/api_integration/apis/endpoint/metadata.ts @@ -7,9 +7,9 @@ import expect from '@kbn/expect/expect.js'; import { FtrProviderContext } from '../../ftr_provider_context'; /** - * The number of alert documents in the es archive. + * The number of host documents in the es archive. */ -const numberOfEndpointsInFixture = 3; +const numberOfHostsInFixture = 3; export default function({ getService }: FtrProviderContext) { const esArchiver = getService('esArchiver'); @@ -24,7 +24,7 @@ export default function({ getService }: FtrProviderContext) { .send() .expect(200); expect(body.total).to.eql(0); - expect(body.endpoints.length).to.eql(0); + expect(body.hosts.length).to.eql(0); expect(body.request_page_size).to.eql(10); expect(body.request_page_index).to.eql(0); }); @@ -33,14 +33,14 @@ export default function({ getService }: FtrProviderContext) { describe('POST /api/endpoint/metadata when index is not empty', () => { before(() => esArchiver.load('endpoint/metadata/api_feature')); after(() => esArchiver.unload('endpoint/metadata/api_feature')); - it('metadata api should return one entry for each endpoint with default paging', async () => { + it('metadata api should return one entry for each host with default paging', async () => { const { body } = await supertest .post('/api/endpoint/metadata') .set('kbn-xsrf', 'xxx') .send() .expect(200); - expect(body.total).to.eql(numberOfEndpointsInFixture); - expect(body.endpoints.length).to.eql(numberOfEndpointsInFixture); + expect(body.total).to.eql(numberOfHostsInFixture); + expect(body.hosts.length).to.eql(numberOfHostsInFixture); expect(body.request_page_size).to.eql(10); expect(body.request_page_index).to.eql(0); }); @@ -60,8 +60,8 @@ export default function({ getService }: FtrProviderContext) { ], }) .expect(200); - expect(body.total).to.eql(numberOfEndpointsInFixture); - expect(body.endpoints.length).to.eql(1); + expect(body.total).to.eql(numberOfHostsInFixture); + expect(body.hosts.length).to.eql(1); expect(body.request_page_size).to.eql(1); expect(body.request_page_index).to.eql(1); }); @@ -84,8 +84,8 @@ export default function({ getService }: FtrProviderContext) { ], }) .expect(200); - expect(body.total).to.eql(numberOfEndpointsInFixture); - expect(body.endpoints.length).to.eql(0); + expect(body.total).to.eql(numberOfHostsInFixture); + expect(body.hosts.length).to.eql(0); expect(body.request_page_size).to.eql(10); expect(body.request_page_index).to.eql(30); }); @@ -115,7 +115,7 @@ export default function({ getService }: FtrProviderContext) { .send({ filter: 'not host.ip:10.100.170.247' }) .expect(200); expect(body.total).to.eql(2); - expect(body.endpoints.length).to.eql(2); + expect(body.hosts.length).to.eql(2); expect(body.request_page_size).to.eql(10); expect(body.request_page_index).to.eql(0); }); @@ -139,7 +139,7 @@ export default function({ getService }: FtrProviderContext) { .expect(200); expect(body.total).to.eql(2); const resultIps: string[] = [].concat( - ...body.endpoints.map((metadata: Record) => metadata.host.ip) + ...body.hosts.map((metadata: Record) => metadata.host.ip) ); expect(resultIps).to.eql([ '10.48.181.222', @@ -150,7 +150,7 @@ export default function({ getService }: FtrProviderContext) { '10.128.235.38', ]); expect(resultIps).not.include.eql(notIncludedIp); - expect(body.endpoints.length).to.eql(2); + expect(body.hosts.length).to.eql(2); expect(body.request_page_size).to.eql(10); expect(body.request_page_index).to.eql(0); }); @@ -166,10 +166,10 @@ export default function({ getService }: FtrProviderContext) { .expect(200); expect(body.total).to.eql(1); const resultOsVariantValue: Set = new Set( - body.endpoints.map((metadata: Record) => metadata.host.os.variant) + body.hosts.map((metadata: Record) => metadata.host.os.variant) ); expect(Array.from(resultOsVariantValue)).to.eql([variantValue]); - expect(body.endpoints.length).to.eql(1); + expect(body.hosts.length).to.eql(1); expect(body.request_page_size).to.eql(10); expect(body.request_page_index).to.eql(0); }); @@ -184,17 +184,17 @@ export default function({ getService }: FtrProviderContext) { }) .expect(200); expect(body.total).to.eql(1); - const resultIp: string = body.endpoints[0].host.ip.filter( + const resultIp: string = body.hosts[0].host.ip.filter( (ip: string) => ip === targetEndpointIp ); expect(resultIp).to.eql([targetEndpointIp]); - expect(body.endpoints[0].event.created).to.eql(1584044335459); - expect(body.endpoints.length).to.eql(1); + expect(body.hosts[0].event.created).to.eql(1584044335459); + expect(body.hosts.length).to.eql(1); expect(body.request_page_size).to.eql(10); expect(body.request_page_index).to.eql(0); }); - it('metadata api should return all endpoints when filter is empty string', async () => { + it('metadata api should return all hosts when filter is empty string', async () => { const { body } = await supertest .post('/api/endpoint/metadata') .set('kbn-xsrf', 'xxx') @@ -202,8 +202,8 @@ export default function({ getService }: FtrProviderContext) { filter: '', }) .expect(200); - expect(body.total).to.eql(numberOfEndpointsInFixture); - expect(body.endpoints.length).to.eql(numberOfEndpointsInFixture); + expect(body.total).to.eql(numberOfHostsInFixture); + expect(body.hosts.length).to.eql(numberOfHostsInFixture); expect(body.request_page_size).to.eql(10); expect(body.request_page_index).to.eql(0); }); diff --git a/x-pack/test/functional/apps/endpoint/feature_controls/endpoint_spaces.ts b/x-pack/test/functional/apps/endpoint/feature_controls/endpoint_spaces.ts index 287892903dd2b..bf3d642307d8c 100644 --- a/x-pack/test/functional/apps/endpoint/feature_controls/endpoint_spaces.ts +++ b/x-pack/test/functional/apps/endpoint/feature_controls/endpoint_spaces.ts @@ -41,18 +41,13 @@ export default function({ getPageObjects, getService }: FtrProviderContext) { await testSubjects.existOrFail('welcomeTitle'); }); - it(`endpoint management shows 'Manage Endpoints'`, async () => { - await pageObjects.common.navigateToUrlWithBrowserHistory( - 'endpoint', - '/management', - undefined, - { - basePath: '/s/custom_space', - ensureCurrentUrl: false, - shouldLoginIfPrompted: false, - } - ); - await testSubjects.existOrFail('managementViewTitle'); + it(`endpoint management shows 'Hosts'`, async () => { + await pageObjects.common.navigateToUrlWithBrowserHistory('endpoint', '/hosts', undefined, { + basePath: '/s/custom_space', + ensureCurrentUrl: false, + shouldLoginIfPrompted: false, + }); + await testSubjects.existOrFail('hostListTitle'); }); }); diff --git a/x-pack/test/functional/apps/endpoint/header_nav.ts b/x-pack/test/functional/apps/endpoint/header_nav.ts index 2368ad077cf64..d1fa7311d61e8 100644 --- a/x-pack/test/functional/apps/endpoint/header_nav.ts +++ b/x-pack/test/functional/apps/endpoint/header_nav.ts @@ -19,19 +19,19 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { it('renders the tabs when the app loads', async () => { const homeTabText = await testSubjects.getVisibleText('homeEndpointTab'); - const managementTabText = await testSubjects.getVisibleText('managementEndpointTab'); + const hostsTabText = await testSubjects.getVisibleText('hostsEndpointTab'); const alertsTabText = await testSubjects.getVisibleText('alertsEndpointTab'); const policiesTabText = await testSubjects.getVisibleText('policiesEndpointTab'); expect(homeTabText.trim()).to.be('Home'); - expect(managementTabText.trim()).to.be('Management'); + expect(hostsTabText.trim()).to.be('Hosts'); expect(alertsTabText.trim()).to.be('Alerts'); expect(policiesTabText.trim()).to.be('Policies'); }); - it('renders the management page when the Management tab is selected', async () => { - await (await testSubjects.find('managementEndpointTab')).click(); - await testSubjects.existOrFail('managementViewTitle'); + it('renders the hosts page when the Hosts tab is selected', async () => { + await (await testSubjects.find('hostsEndpointTab')).click(); + await testSubjects.existOrFail('hostListTitle'); }); it('renders the alerts page when the Alerts tab is selected', async () => { @@ -45,8 +45,8 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { }); it('renders the home page when Home tab is selected after selecting another tab', async () => { - await (await testSubjects.find('managementEndpointTab')).click(); - await testSubjects.existOrFail('managementViewTitle'); + await (await testSubjects.find('hostsEndpointTab')).click(); + await testSubjects.existOrFail('hostListTitle'); await (await testSubjects.find('homeEndpointTab')).click(); await testSubjects.existOrFail('welcomeTitle'); diff --git a/x-pack/test/functional/apps/endpoint/management.ts b/x-pack/test/functional/apps/endpoint/host_list.ts similarity index 58% rename from x-pack/test/functional/apps/endpoint/management.ts rename to x-pack/test/functional/apps/endpoint/host_list.ts index 640f6264c3a09..baace0f7670e1 100644 --- a/x-pack/test/functional/apps/endpoint/management.ts +++ b/x-pack/test/functional/apps/endpoint/host_list.ts @@ -12,15 +12,15 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const esArchiver = getService('esArchiver'); const testSubjects = getService('testSubjects'); - describe('Endpoint Management List', function() { + describe('host list', function() { this.tags('ciGroup7'); before(async () => { await esArchiver.load('endpoint/metadata/api_feature'); - await pageObjects.common.navigateToUrlWithBrowserHistory('endpoint', '/management'); + await pageObjects.common.navigateToUrlWithBrowserHistory('endpoint', '/hosts'); }); it('finds title', async () => { - const title = await testSubjects.getVisibleText('managementViewTitle'); + const title = await testSubjects.getVisibleText('hostListTitle'); expect(title).to.equal('Hosts'); }); @@ -67,21 +67,70 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { 'xxxx', ], ]; - const tableData = await pageObjects.endpoint.getEndpointAppTableData('managementListTable'); + const tableData = await pageObjects.endpoint.getEndpointAppTableData('hostListTable'); expect(tableData).to.eql(expectedData); }); - it('displays no items found', async () => { + it('display details flyout when the hostname is clicked on', async () => { + await (await testSubjects.find('hostnameCellLink')).click(); + await testSubjects.existOrFail('hostDetailsUpperList'); + await testSubjects.existOrFail('hostDetailsLowerList'); + }); + + it('displays no items found when empty', async () => { // clear out the data and reload the page await esArchiver.unload('endpoint/metadata/api_feature'); - await pageObjects.common.navigateToUrlWithBrowserHistory('endpoint', '/management'); + await pageObjects.common.navigateToUrlWithBrowserHistory('endpoint', '/hosts'); // get the table data and verify no entries appear - const tableData = await pageObjects.endpoint.getEndpointAppTableData('managementListTable'); + const tableData = await pageObjects.endpoint.getEndpointAppTableData('hostListTable'); expect(tableData[1][0]).to.equal('No items found'); // reload the data so the other tests continue to pass await esArchiver.load('endpoint/metadata/api_feature'); }); + describe('has a url with a host id', () => { + before(async () => { + await pageObjects.common.navigateToUrlWithBrowserHistory( + 'endpoint', + '/hosts', + 'selected_host=cbe80003-6964-4e0f-aba1-f94c32b44e95' + ); + }); + + it('shows a flyout', async () => { + await testSubjects.existOrFail('hostDetailsFlyout'); + }); + + it('displays details row headers', async () => { + const expectedData = [ + 'OS', + 'Last Seen', + 'Alerts', + 'Policy', + 'Policy Status', + 'IP Address', + 'Hostname', + 'Sensor Version', + ]; + const keys = await pageObjects.endpoint.hostFlyoutDescriptionKeys('hostDetailsFlyout'); + expect(keys).to.eql(expectedData); + }); + + it('displays details row descriptions', async () => { + const values = await pageObjects.endpoint.hostFlyoutDescriptionValues('hostDetailsFlyout'); + + expect(values).to.eql([ + 'Windows Server 2012', + '', + '0', + 'C2A9093E-E289-4C0A-AA44-8C32A414FA7A', + 'active', + '10.48.181.22210.116.62.6210.102.83.30', + 'Host-cxz5glsoup', + '6.6.9', + ]); + }); + }); after(async () => { await esArchiver.unload('endpoint/metadata/api_feature'); }); diff --git a/x-pack/test/functional/apps/endpoint/index.ts b/x-pack/test/functional/apps/endpoint/index.ts index 15ce522ce56ba..4d55b3af4956e 100644 --- a/x-pack/test/functional/apps/endpoint/index.ts +++ b/x-pack/test/functional/apps/endpoint/index.ts @@ -12,7 +12,7 @@ export default function({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./feature_controls')); loadTestFile(require.resolve('./landing_page')); loadTestFile(require.resolve('./header_nav')); - loadTestFile(require.resolve('./management')); + loadTestFile(require.resolve('./host_list')); loadTestFile(require.resolve('./policy_list')); loadTestFile(require.resolve('./policy_details')); loadTestFile(require.resolve('./alerts')); diff --git a/x-pack/test/functional/page_objects/endpoint_page.ts b/x-pack/test/functional/page_objects/endpoint_page.ts index 6350f51f707f4..4becbf797abc0 100644 --- a/x-pack/test/functional/page_objects/endpoint_page.ts +++ b/x-pack/test/functional/page_objects/endpoint_page.ts @@ -63,9 +63,42 @@ export function EndpointPageProvider({ getService }: FtrProviderContext) { async waitForTableToHaveData(dataTestSubj: string) { await retry.waitForWithTimeout('table to have data', 2000, async () => { const tableData = await this.getEndpointAppTableData(dataTestSubj); - if (tableData[1][0] === 'No items found') return false; + if (tableData[1][0] === 'No items found') { + return false; + } return true; }); }, + + async hostFlyoutDescriptionKeys(dataTestSubj: string) { + await testSubjects.exists(dataTestSubj); + const detailsData: WebElementWrapper = await testSubjects.find(dataTestSubj); + const $ = await detailsData.parseDomContent(); + return $('dt') + .toArray() + .map(key => + $(key) + .text() + .replace(/ /g, '') + .trim() + ); + }, + + async hostFlyoutDescriptionValues(dataTestSubj: string) { + await testSubjects.exists(dataTestSubj); + const detailsData: WebElementWrapper = await testSubjects.find(dataTestSubj); + const $ = await detailsData.parseDomContent(); + return $('dd') + .toArray() + .map((value, index) => { + if (index === 1) { + return ''; + } + return $(value) + .text() + .replace(/ /g, '') + .trim(); + }); + }, }; } diff --git a/yarn.lock b/yarn.lock index 1e5c160a7eb19..eaee706101a7b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1916,10 +1916,10 @@ once "^1.4.0" pump "^3.0.0" -"@elastic/ems-client@7.6.0": - version "7.6.0" - resolved "https://registry.yarnpkg.com/@elastic/ems-client/-/ems-client-7.6.0.tgz#ca548aba1a1f5170a1892de129b537b5248c74be" - integrity sha512-oBtLH24qIgTaMhlSske49FTd35Y0nv+PlZCZaHkBhOH+ScsTDL3LO2lbIcSmcYQod43Ly34v/xwJvFCTxojVEQ== +"@elastic/ems-client@7.7.0": + version "7.7.0" + resolved "https://registry.yarnpkg.com/@elastic/ems-client/-/ems-client-7.7.0.tgz#7d36d716dd941f060b9fcdae94f186a9aecc5cc2" + integrity sha512-JatsSyLik/8MTEOEimzEZ3NYjvGL1YzjbGujuSCgaXhPRqzu/wvMLEL8dlVpmYFZ7ALbGNsVdho4Hr8tngsIMw== dependencies: lodash "^4.17.15" node-fetch "^1.7.3" @@ -4678,6 +4678,11 @@ dependencies: "@types/sizzle" "*" +"@types/js-cookie@2.2.5": + version "2.2.5" + resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.2.5.tgz#38dfaacae8623b37cc0b0d27398e574e3fc28b1e" + integrity sha512-cpmwBRcHJmmZx0OGU7aPVwGWGbs4iKwVYchk9iuMtxNCA2zorwdaTz4GkLgs2WGxiRZRFKnV1k6tRUHX7tBMxg== + "@types/js-search@^1.4.0": version "1.4.0" resolved "https://registry.yarnpkg.com/@types/js-search/-/js-search-1.4.0.tgz#f2d4afa176a4fc7b17fb46a1593847887fa1fb7b" @@ -5768,10 +5773,10 @@ dependencies: tslib "^1.9.3" -"@xobotyi/scrollbar-width@1.5.0": - version "1.5.0" - resolved "https://registry.yarnpkg.com/@xobotyi/scrollbar-width/-/scrollbar-width-1.5.0.tgz#488210bff634548040dc22a72f62722a85b134e1" - integrity sha512-BK+HR1D00F2xh7n4+5en8/dMkG13uvIXLmEbsjtc1702b7+VwXkvlBDKoRPJMbkRN5hD7VqWa3nS9fNT8JG3CA== +"@xobotyi/scrollbar-width@1.9.4": + version "1.9.4" + resolved "https://registry.yarnpkg.com/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.4.tgz#a7dce20b7465bcad29cd6bbb557695e4ea7863cb" + integrity sha512-o12FCQt/X5n3pgKEWGpt0f/7Eg4mfv3uRwPUrctiOT8ZuxbH3cNLGWfH/8y6KxVJg4L2885ucuXQ6XECZzUiJA== "@xtuc/ieee754@^1.2.0": version "1.2.0" @@ -13667,10 +13672,10 @@ fast-safe-stringify@2.x.x, fast-safe-stringify@^2.0.4, fast-safe-stringify@^2.0. resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743" integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA== -fast-shallow-equal@^0.1.1: - version "0.1.1" - resolved "https://registry.yarnpkg.com/fast-shallow-equal/-/fast-shallow-equal-0.1.1.tgz#44d01324d7fd31e00a67bb02b9396e283d526c22" - integrity sha512-XVP6nhaXLYOH6JZCWBcNaeEer9GJ5/8cJWUP+OLmgwWgEkJp5Kpl/fdpJ01zl0mpLxrk7f5J3hIv+GmjTCi7Mg== +fast-shallow-equal@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz#d4dcaf6472440dcefa6f88b98e3251e27f25628b" + integrity sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw== fast-stream-to-buffer@^1.0.0: version "1.0.0" @@ -17571,7 +17576,7 @@ is-path-inside@^2.1.0: dependencies: path-is-inside "^1.0.2" -is-path-inside@^3.0.1: +is-path-inside@^3.0.1, is-path-inside@^3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/is-path-inside/-/is-path-inside-3.0.2.tgz#f5220fc82a3e233757291dddc9c5877f2a1f3017" integrity sha512-/2UGPSgmtqwo1ktx8NDHjuPwZWmHhO+gj0f93EkhLB5RgW9RZevWYYlIkS6zePc6U2WpOdQYIwHe9YC4DWEBVg== @@ -18498,6 +18503,11 @@ js-base64@^2.1.8: resolved "https://registry.yarnpkg.com/js-base64/-/js-base64-2.4.5.tgz#e293cd3c7c82f070d700fc7a1ca0a2e69f101f92" integrity sha512-aUnNwqMOXw3yvErjMPSQu6qIIzUmT1e5KcU1OZxRDU1g/am6mzBvcrmLAYwzmB59BHPrh5/tKaiF4OPhqRWESQ== +js-cookie@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8" + integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ== + js-levenshtein@^1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/js-levenshtein/-/js-levenshtein-1.1.3.tgz#3ef627df48ec8cf24bacf05c0f184ff30ef413c5" @@ -24919,16 +24929,18 @@ react-transition-group@^2.2.1: prop-types "^15.6.2" react-lifecycles-compat "^3.0.4" -react-use@^13.13.0: - version "13.13.0" - resolved "https://registry.yarnpkg.com/react-use/-/react-use-13.13.0.tgz#5d133c4d4d8d3f21f6ccf4ccbe54fbcd6fdafb36" - integrity sha512-J3/h5wvL6vXmecAvEnninCC3DviLMRWcQrEnouTliwws1b376DQKEgIFuTXlF8c3SKpXBQJdDDm1RpluokW6ag== +react-use@^13.27.0: + version "13.27.0" + resolved "https://registry.yarnpkg.com/react-use/-/react-use-13.27.0.tgz#53a619dc9213e2cbe65d6262e8b0e76641ade4aa" + integrity sha512-2lyTyqJWyvnaP/woVtDcFS4B5pUYz0FQWI9pVHk/6TBWom2x3/ziJthkEn/LbCA9Twv39xSQU7Dn0zdIWfsNTQ== dependencies: - "@xobotyi/scrollbar-width" "1.5.0" + "@types/js-cookie" "2.2.5" + "@xobotyi/scrollbar-width" "1.9.4" copy-to-clipboard "^3.2.0" - fast-shallow-equal "^0.1.1" + fast-deep-equal "^3.1.1" + fast-shallow-equal "^1.0.0" + js-cookie "^2.2.1" nano-css "^5.2.1" - react-fast-compare "^2.0.4" resize-observer-polyfill "^1.5.1" screenfull "^5.0.0" set-harmonic-interval "^1.0.1"