diff --git a/docs/api/saved-objects/create.asciidoc b/docs/api/saved-objects/create.asciidoc index 900f87ec29d8a..e6f3301bfea2b 100644 --- a/docs/api/saved-objects/create.asciidoc +++ b/docs/api/saved-objects/create.asciidoc @@ -13,7 +13,7 @@ experimental[] Create {kib} saved objects. `POST :/api/saved_objects//` -`POST :/s//api/saved_objects/` +`POST :/s//saved_objects/` [[saved-objects-api-create-path-params]] ==== Path parameters diff --git a/docs/developer/getting-started/development-plugin-resources.asciidoc b/docs/developer/getting-started/development-plugin-resources.asciidoc index 8f81138b81ed7..1fe211c87c660 100644 --- a/docs/developer/getting-started/development-plugin-resources.asciidoc +++ b/docs/developer/getting-started/development-plugin-resources.asciidoc @@ -33,7 +33,7 @@ To enable TypeScript support, create a `tsconfig.json` file at the root of your ["source","js"] ----------- { - // extend {kib}'s tsconfig, or use your own settings + // extend Kibana's tsconfig, or use your own settings "extends": "../../kibana/tsconfig.json", // tell the TypeScript compiler where to find your source files diff --git a/package.json b/package.json index 5345f8752d4af..10083ff07fccd 100644 --- a/package.json +++ b/package.json @@ -227,9 +227,9 @@ "devDependencies": { "@babel/parser": "^7.11.2", "@babel/types": "^7.11.0", - "@elastic/apm-rum": "^5.5.0", + "@elastic/apm-rum": "^5.6.0", "@elastic/charts": "21.1.2", - "@elastic/ems-client": "7.9.3", + "@elastic/ems-client": "7.10.0", "@elastic/eslint-config-kibana": "0.15.0", "@elastic/eslint-plugin-eui": "0.0.2", "@elastic/filesaver": "1.1.2", diff --git a/packages/kbn-pm/dist/index.js b/packages/kbn-pm/dist/index.js index 9a3bb1c687032..902cc8839ac09 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__(503); +/* harmony import */ var _production__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(504); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _production__WEBPACK_IMPORTED_MODULE_1__["buildProductionProjects"]; }); /* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(145); @@ -150,7 +150,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _kbn_dev_utils_tooling_log__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(5); /* harmony import */ var _kbn_dev_utils_tooling_log__WEBPACK_IMPORTED_MODULE_3___default = /*#__PURE__*/__webpack_require__.n(_kbn_dev_utils_tooling_log__WEBPACK_IMPORTED_MODULE_3__); /* harmony import */ var _commands__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(127); -/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(496); +/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(497); /* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(143); /* * Licensed to Elasticsearch B.V. under one or more contributor @@ -8763,9 +8763,9 @@ exports.ToolingLogCollectingWriter = ToolingLogCollectingWriter; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "commands", function() { return commands; }); /* harmony import */ var _bootstrap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(128); -/* harmony import */ var _clean__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(287); -/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(395); -/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(396); +/* harmony import */ var _clean__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(288); +/* harmony import */ var _run__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(396); +/* harmony import */ var _watch__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(397); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -8808,6 +8808,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(145); /* harmony import */ var _utils_project_checksums__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(281); /* harmony import */ var _utils_bootstrap_cache_file__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(286); +/* harmony import */ var _utils_yarn_lock__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(283); +/* harmony import */ var _utils_validate_yarn_lock__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(287); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -8832,6 +8834,8 @@ __webpack_require__.r(__webpack_exports__); + + const BootstrapCommand = { description: 'Install dependencies and crosslink projects', name: 'bootstrap', @@ -8861,6 +8865,8 @@ const BootstrapCommand = { } } + const yarnLock = await Object(_utils_yarn_lock__WEBPACK_IMPORTED_MODULE_6__["readYarnLock"])(kbn); + await Object(_utils_validate_yarn_lock__WEBPACK_IMPORTED_MODULE_7__["validateYarnLock"])(kbn, yarnLock); await Object(_utils_link_project_executables__WEBPACK_IMPORTED_MODULE_0__["linkProjectExecutables"])(projects, projectGraph); /** * At the end of the bootstrapping process we call all `kbn:bootstrap` scripts @@ -8869,7 +8875,7 @@ const BootstrapCommand = { * have to, as it will slow down the bootstrapping process. */ - const checksums = await Object(_utils_project_checksums__WEBPACK_IMPORTED_MODULE_4__["getAllChecksums"])(kbn, _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"]); + const checksums = await Object(_utils_project_checksums__WEBPACK_IMPORTED_MODULE_4__["getAllChecksums"])(kbn, _utils_log__WEBPACK_IMPORTED_MODULE_1__["log"], yarnLock); const caches = new Map(); let cachedProjectCount = 0; @@ -8987,6 +8993,7 @@ async function linkProjectExecutables(projectsByName, projectGraph) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readFile", function() { return readFile; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "writeFile", function() { return writeFile; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "chmod", function() { return chmod; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "mkdirp", function() { return mkdirp; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "unlink", function() { return unlink; }); @@ -9030,6 +9037,7 @@ __webpack_require__.r(__webpack_exports__); const lstat = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.lstat); const readFile = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.readFile); +const writeFile = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.writeFile); const symlink = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.symlink); const chmod = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(fs__WEBPACK_IMPORTED_MODULE_1___default.a.chmod); const cmdShim = Object(util__WEBPACK_IMPORTED_MODULE_4__["promisify"])(cmd_shim__WEBPACK_IMPORTED_MODULE_0___default.a); @@ -29001,46 +29009,6 @@ async function getLatestSha(project, kbn) { }); return stdout.trim() || undefined; } -/** - * Get a list of the absolute dependencies of this project, as resolved - * in the yarn.lock file, does not include other projects in the workspace - * or their dependencies - */ - - -function resolveDepsForProject(project, yarnLock, kbn, log) { - /** map of [name@range, name@resolved] */ - const resolved = new Map(); - const queue = Object.entries(project.allDependencies); - - while (queue.length) { - const [name, versionRange] = queue.shift(); - const req = `${name}@${versionRange}`; - - if (resolved.has(req)) { - continue; - } - - if (!kbn.hasProject(name)) { - const pkg = yarnLock[req]; - - if (!pkg) { - log.warning('yarn.lock file is out of date, please run `yarn kbn bootstrap` to re-enable caching'); - return; - } - - const res = `${name}@${pkg.version}`; - resolved.set(req, res); - const allDepsEntries = [...Object.entries(pkg.dependencies || {}), ...Object.entries(pkg.optionalDependencies || {})]; - - for (const [childName, childVersionRange] of allDepsEntries) { - queue.push([childName, childVersionRange]); - } - } - } - - return Array.from(resolved.values()).sort((a, b) => a.localeCompare(b)); -} /** * Get the checksum for a specific project in the workspace */ @@ -29067,12 +29035,23 @@ async function getChecksum(project, changes, yarnLock, kbn, log) { log.verbose(`[${project.name}] modified time ${stats.mtimeMs} for ${path}`); return `${path}:${stats.mtimeMs}`; })); - const deps = await resolveDepsForProject(project, yarnLock, kbn, log); + const depMap = Object(_yarn_lock__WEBPACK_IMPORTED_MODULE_4__["resolveDepsForProject"])({ + project, + yarnLock, + kbn, + log, + includeDependentProject: false, + productionDepsOnly: false + }); - if (!deps) { + if (!depMap) { return; } + const deps = Array.from(depMap.values()).map(({ + name, + version + }) => `${name}@${version}`).sort((a, b) => a.localeCompare(b)); log.verbose(`[${project.name}] resolved %d deps`, deps.length); const checksum = JSON.stringify({ sha, @@ -29096,10 +29075,9 @@ async function getChecksum(project, changes, yarnLock, kbn, log) { */ -async function getAllChecksums(kbn, log) { +async function getAllChecksums(kbn, log, yarnLock) { const projects = kbn.getAllProjects(); const changesByProject = await getChangesForProjects(projects, kbn, log); - const yarnLock = await Object(_yarn_lock__WEBPACK_IMPORTED_MODULE_4__["readYarnLock"])(kbn); /** map of [project.name, cacheKey] */ const cacheKeys = new Map(); @@ -29122,6 +29100,7 @@ module.exports = require("crypto"); "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "readYarnLock", function() { return readYarnLock; }); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resolveDepsForProject", function() { return resolveDepsForProject; }); /* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(284); /* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__); /* harmony import */ var _utils_fs__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(130); @@ -29143,7 +29122,7 @@ __webpack_require__.r(__webpack_exports__); * specific language governing permissions and limitations * under the License. */ -// @ts-ignore published types are worthless +// @ts-expect-error published types are worthless async function readYarnLock(kbn) { @@ -29164,6 +29143,75 @@ async function readYarnLock(kbn) { return {}; } +/** + * Get a list of the absolute dependencies of this project, as resolved + * in the yarn.lock file, does not include other projects in the workspace + * or their dependencies + */ + +function resolveDepsForProject({ + project: rootProject, + yarnLock, + kbn, + log, + productionDepsOnly, + includeDependentProject +}) { + /** map of [name@range, { name, version }] */ + const resolved = new Map(); + const seenProjects = new Set(); + const projectQueue = [rootProject]; + const depQueue = []; + + while (projectQueue.length) { + const project = projectQueue.shift(); + + if (seenProjects.has(project)) { + continue; + } + + seenProjects.add(project); + const projectDeps = Object.entries(productionDepsOnly ? project.productionDependencies : project.allDependencies); + + for (const [name, versionRange] of projectDeps) { + depQueue.push([name, versionRange]); + } + + while (depQueue.length) { + const [name, versionRange] = depQueue.shift(); + const req = `${name}@${versionRange}`; + + if (resolved.has(req)) { + continue; + } + + if (includeDependentProject && kbn.hasProject(name)) { + projectQueue.push(kbn.getProject(name)); + } + + if (!kbn.hasProject(name)) { + const pkg = yarnLock[req]; + + if (!pkg) { + log.warning('yarn.lock file is out of date, please run `yarn kbn bootstrap` to re-enable caching'); + return; + } + + resolved.set(req, { + name, + version: pkg.version + }); + const allDepsEntries = [...Object.entries(pkg.dependencies || {}), ...Object.entries(pkg.optionalDependencies || {})]; + + for (const [childName, childVersionRange] of allDepsEntries) { + depQueue.push([childName, childVersionRange]); + } + } + } + } + + return resolved; +} /***/ }), /* 284 */ @@ -39550,12 +39598,119 @@ class BootstrapCacheFile { /* 287 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { +"use strict"; +__webpack_require__.r(__webpack_exports__); +/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "validateYarnLock", function() { return validateYarnLock; }); +/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(284); +/* harmony import */ var _yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__); +/* harmony import */ var dedent__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(2); +/* harmony import */ var dedent__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(dedent__WEBPACK_IMPORTED_MODULE_1__); +/* harmony import */ var _fs__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(130); +/* harmony import */ var _log__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(143); +/* + * 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. + */ +// @ts-expect-error published types are useless + + + + +async function validateYarnLock(kbn, yarnLock) { + // look through all of the packages in the yarn.lock file to see if + // we have accidentally installed multiple lodash v4 versions + const lodash4Versions = new Set(); + const lodash4Reqs = new Set(); + + for (const [req, dep] of Object.entries(yarnLock)) { + if (req.startsWith('lodash@') && dep.version.startsWith('4.')) { + lodash4Reqs.add(req); + lodash4Versions.add(dep.version); + } + } // if we find more than one lodash v4 version installed then delete + // lodash v4 requests from the yarn.lock file and prompt the user to + // retry bootstrap so that a single v4 version will be installed + + + if (lodash4Versions.size > 1) { + for (const req of lodash4Reqs) { + delete yarnLock[req]; + } + + await Object(_fs__WEBPACK_IMPORTED_MODULE_2__["writeFile"])(kbn.getAbsolute('yarn.lock'), Object(_yarnpkg_lockfile__WEBPACK_IMPORTED_MODULE_0__["stringify"])(yarnLock), 'utf8'); + _log__WEBPACK_IMPORTED_MODULE_3__["log"].error(dedent__WEBPACK_IMPORTED_MODULE_1___default.a` + + Multiple version of lodash v4 were detected, so they have been removed + from the yarn.lock file. Please rerun yarn kbn bootstrap to coalese the + lodash versions installed. + + If you still see this error when you re-bootstrap then you might need + to force a new dependency to use the latest version of lodash via the + "resolutions" field in package.json. + + If you have questions about this please reach out to the operations team. + + `); + process.exit(1); + } // look through all the dependencies of production packages and production + // dependencies of those packages to determine if we're shipping any versions + // of lodash v3 in the distributable + + + const prodDependencies = kbn.resolveAllProductionDependencies(yarnLock, _log__WEBPACK_IMPORTED_MODULE_3__["log"]); + const lodash3Versions = new Set(); + + for (const dep of prodDependencies.values()) { + if (dep.name === 'lodash' && dep.version.startsWith('3.')) { + lodash3Versions.add(dep.version); + } + } // if any lodash v3 packages were found we abort and tell the user to fix things + + + if (lodash3Versions.size) { + _log__WEBPACK_IMPORTED_MODULE_3__["log"].error(dedent__WEBPACK_IMPORTED_MODULE_1___default.a` + + Due to changes in the yarn.lock file and/or package.json files a version of + lodash 3 is now included in the production dependencies. To reduce the size of + our distributable and especially our front-end bundles we have decided to + prevent adding any new instances of lodash 3. + + Please inspect the changes to yarn.lock or package.json files to identify where + the lodash 3 version is coming from and remove it. + + If you have questions about this please reack out to the operations team. + + `); + process.exit(1); + } + + _log__WEBPACK_IMPORTED_MODULE_3__["log"].success('yarn.lock analysis completed without any issues'); +} + +/***/ }), +/* 288 */ +/***/ (function(module, __webpack_exports__, __webpack_require__) { + "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "CleanCommand", function() { return CleanCommand; }); -/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(288); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(289); /* harmony import */ var del__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_0__); -/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(375); +/* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(376); /* harmony import */ var ora__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(ora__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); @@ -39655,21 +39810,21 @@ const CleanCommand = { }; /***/ }), -/* 288 */ +/* 289 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const {promisify} = __webpack_require__(111); const path = __webpack_require__(4); -const globby = __webpack_require__(289); -const isGlob = __webpack_require__(367); -const slash = __webpack_require__(365); +const globby = __webpack_require__(290); +const isGlob = __webpack_require__(368); +const slash = __webpack_require__(366); const gracefulFs = __webpack_require__(132); -const isPathCwd = __webpack_require__(368); -const isPathInside = __webpack_require__(369); -const rimraf = __webpack_require__(370); -const pMap = __webpack_require__(371); +const isPathCwd = __webpack_require__(369); +const isPathInside = __webpack_require__(370); +const rimraf = __webpack_require__(371); +const pMap = __webpack_require__(372); const rimrafP = promisify(rimraf); @@ -39783,19 +39938,19 @@ module.exports.sync = (patterns, {force, dryRun, cwd = process.cwd(), ...options /***/ }), -/* 289 */ +/* 290 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(133); -const arrayUnion = __webpack_require__(290); -const merge2 = __webpack_require__(291); +const arrayUnion = __webpack_require__(291); +const merge2 = __webpack_require__(292); const glob = __webpack_require__(146); -const fastGlob = __webpack_require__(292); -const dirGlob = __webpack_require__(361); -const gitignore = __webpack_require__(363); -const {FilterStream, UniqueStream} = __webpack_require__(366); +const fastGlob = __webpack_require__(293); +const dirGlob = __webpack_require__(362); +const gitignore = __webpack_require__(364); +const {FilterStream, UniqueStream} = __webpack_require__(367); const DEFAULT_FILTER = () => false; @@ -39968,7 +40123,7 @@ module.exports.gitignore = gitignore; /***/ }), -/* 290 */ +/* 291 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -39980,7 +40135,7 @@ module.exports = (...arguments_) => { /***/ }), -/* 291 */ +/* 292 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -40131,17 +40286,17 @@ function pauseStreams (streams, options) { /***/ }), -/* 292 */ +/* 293 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const taskManager = __webpack_require__(293); -const async_1 = __webpack_require__(322); -const stream_1 = __webpack_require__(357); -const sync_1 = __webpack_require__(358); -const settings_1 = __webpack_require__(360); -const utils = __webpack_require__(294); +const taskManager = __webpack_require__(294); +const async_1 = __webpack_require__(323); +const stream_1 = __webpack_require__(358); +const sync_1 = __webpack_require__(359); +const settings_1 = __webpack_require__(361); +const utils = __webpack_require__(295); async function FastGlob(source, options) { assertPatternsInput(source); const works = getWorks(source, async_1.default, options); @@ -40205,13 +40360,13 @@ module.exports = FastGlob; /***/ }), -/* 293 */ +/* 294 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(294); +const utils = __webpack_require__(295); function generate(patterns, settings) { const positivePatterns = getPositivePatterns(patterns); const negativePatterns = getNegativePatternsAsPositive(patterns, settings.ignore); @@ -40276,30 +40431,30 @@ exports.convertPatternGroupToTask = convertPatternGroupToTask; /***/ }), -/* 294 */ +/* 295 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const array = __webpack_require__(295); +const array = __webpack_require__(296); exports.array = array; -const errno = __webpack_require__(296); +const errno = __webpack_require__(297); exports.errno = errno; -const fs = __webpack_require__(297); +const fs = __webpack_require__(298); exports.fs = fs; -const path = __webpack_require__(298); +const path = __webpack_require__(299); exports.path = path; -const pattern = __webpack_require__(299); +const pattern = __webpack_require__(300); exports.pattern = pattern; -const stream = __webpack_require__(320); +const stream = __webpack_require__(321); exports.stream = stream; -const string = __webpack_require__(321); +const string = __webpack_require__(322); exports.string = string; /***/ }), -/* 295 */ +/* 296 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -40327,7 +40482,7 @@ exports.splitWhen = splitWhen; /***/ }), -/* 296 */ +/* 297 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -40340,7 +40495,7 @@ exports.isEnoentCodeError = isEnoentCodeError; /***/ }), -/* 297 */ +/* 298 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -40365,7 +40520,7 @@ exports.createDirentFromStats = createDirentFromStats; /***/ }), -/* 298 */ +/* 299 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -40404,16 +40559,16 @@ exports.removeLeadingDotSegment = removeLeadingDotSegment; /***/ }), -/* 299 */ +/* 300 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = __webpack_require__(4); -const globParent = __webpack_require__(300); -const micromatch = __webpack_require__(303); -const picomatch = __webpack_require__(314); +const globParent = __webpack_require__(301); +const micromatch = __webpack_require__(304); +const picomatch = __webpack_require__(315); const GLOBSTAR = '**'; const ESCAPE_SYMBOL = '\\'; const COMMON_GLOB_SYMBOLS_RE = /[*?]|^!/; @@ -40523,13 +40678,13 @@ exports.matchAny = matchAny; /***/ }), -/* 300 */ +/* 301 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isGlob = __webpack_require__(301); +var isGlob = __webpack_require__(302); var pathPosixDirname = __webpack_require__(4).posix.dirname; var isWin32 = __webpack_require__(120).platform() === 'win32'; @@ -40571,7 +40726,7 @@ module.exports = function globParent(str, opts) { /***/ }), -/* 301 */ +/* 302 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -40581,7 +40736,7 @@ module.exports = function globParent(str, opts) { * Released under the MIT License. */ -var isExtglob = __webpack_require__(302); +var isExtglob = __webpack_require__(303); var chars = { '{': '}', '(': ')', '[': ']'}; var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; @@ -40625,7 +40780,7 @@ module.exports = function isGlob(str, options) { /***/ }), -/* 302 */ +/* 303 */ /***/ (function(module, exports) { /*! @@ -40651,16 +40806,16 @@ module.exports = function isExtglob(str) { /***/ }), -/* 303 */ +/* 304 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const util = __webpack_require__(111); -const braces = __webpack_require__(304); -const picomatch = __webpack_require__(314); -const utils = __webpack_require__(317); +const braces = __webpack_require__(305); +const picomatch = __webpack_require__(315); +const utils = __webpack_require__(318); const isEmptyString = val => typeof val === 'string' && (val === '' || val === './'); /** @@ -41125,16 +41280,16 @@ module.exports = micromatch; /***/ }), -/* 304 */ +/* 305 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const stringify = __webpack_require__(305); -const compile = __webpack_require__(307); -const expand = __webpack_require__(311); -const parse = __webpack_require__(312); +const stringify = __webpack_require__(306); +const compile = __webpack_require__(308); +const expand = __webpack_require__(312); +const parse = __webpack_require__(313); /** * Expand the given pattern or create a regex-compatible string. @@ -41302,13 +41457,13 @@ module.exports = braces; /***/ }), -/* 305 */ +/* 306 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const utils = __webpack_require__(306); +const utils = __webpack_require__(307); module.exports = (ast, options = {}) => { let stringify = (node, parent = {}) => { @@ -41341,7 +41496,7 @@ module.exports = (ast, options = {}) => { /***/ }), -/* 306 */ +/* 307 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -41460,14 +41615,14 @@ exports.flatten = (...args) => { /***/ }), -/* 307 */ +/* 308 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fill = __webpack_require__(308); -const utils = __webpack_require__(306); +const fill = __webpack_require__(309); +const utils = __webpack_require__(307); const compile = (ast, options = {}) => { let walk = (node, parent = {}) => { @@ -41524,7 +41679,7 @@ module.exports = compile; /***/ }), -/* 308 */ +/* 309 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -41538,7 +41693,7 @@ module.exports = compile; const util = __webpack_require__(111); -const toRegexRange = __webpack_require__(309); +const toRegexRange = __webpack_require__(310); const isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); @@ -41780,7 +41935,7 @@ module.exports = fill; /***/ }), -/* 309 */ +/* 310 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -41793,7 +41948,7 @@ module.exports = fill; -const isNumber = __webpack_require__(310); +const isNumber = __webpack_require__(311); const toRegexRange = (min, max, options) => { if (isNumber(min) === false) { @@ -42075,7 +42230,7 @@ module.exports = toRegexRange; /***/ }), -/* 310 */ +/* 311 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -42100,15 +42255,15 @@ module.exports = function(num) { /***/ }), -/* 311 */ +/* 312 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const fill = __webpack_require__(308); -const stringify = __webpack_require__(305); -const utils = __webpack_require__(306); +const fill = __webpack_require__(309); +const stringify = __webpack_require__(306); +const utils = __webpack_require__(307); const append = (queue = '', stash = '', enclose = false) => { let result = []; @@ -42220,13 +42375,13 @@ module.exports = expand; /***/ }), -/* 312 */ +/* 313 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const stringify = __webpack_require__(305); +const stringify = __webpack_require__(306); /** * Constants @@ -42248,7 +42403,7 @@ const { CHAR_SINGLE_QUOTE, /* ' */ CHAR_NO_BREAK_SPACE, CHAR_ZERO_WIDTH_NOBREAK_SPACE -} = __webpack_require__(313); +} = __webpack_require__(314); /** * parse @@ -42560,7 +42715,7 @@ module.exports = parse; /***/ }), -/* 313 */ +/* 314 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -42624,27 +42779,27 @@ module.exports = { /***/ }), -/* 314 */ +/* 315 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = __webpack_require__(315); +module.exports = __webpack_require__(316); /***/ }), -/* 315 */ +/* 316 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const scan = __webpack_require__(316); -const parse = __webpack_require__(319); -const utils = __webpack_require__(317); -const constants = __webpack_require__(318); +const scan = __webpack_require__(317); +const parse = __webpack_require__(320); +const utils = __webpack_require__(318); +const constants = __webpack_require__(319); const isObject = val => val && typeof val === 'object' && !Array.isArray(val); /** @@ -42980,13 +43135,13 @@ module.exports = picomatch; /***/ }), -/* 316 */ +/* 317 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const utils = __webpack_require__(317); +const utils = __webpack_require__(318); const { CHAR_ASTERISK, /* * */ CHAR_AT, /* @ */ @@ -43003,7 +43158,7 @@ const { CHAR_RIGHT_CURLY_BRACE, /* } */ CHAR_RIGHT_PARENTHESES, /* ) */ CHAR_RIGHT_SQUARE_BRACKET /* ] */ -} = __webpack_require__(318); +} = __webpack_require__(319); const isPathSeparator = code => { return code === CHAR_FORWARD_SLASH || code === CHAR_BACKWARD_SLASH; @@ -43370,7 +43525,7 @@ module.exports = scan; /***/ }), -/* 317 */ +/* 318 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -43383,7 +43538,7 @@ const { REGEX_REMOVE_BACKSLASH, REGEX_SPECIAL_CHARS, REGEX_SPECIAL_CHARS_GLOBAL -} = __webpack_require__(318); +} = __webpack_require__(319); exports.isObject = val => val !== null && typeof val === 'object' && !Array.isArray(val); exports.hasRegexChars = str => REGEX_SPECIAL_CHARS.test(str); @@ -43441,7 +43596,7 @@ exports.wrapOutput = (input, state = {}, options = {}) => { /***/ }), -/* 318 */ +/* 319 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -43627,14 +43782,14 @@ module.exports = { /***/ }), -/* 319 */ +/* 320 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const constants = __webpack_require__(318); -const utils = __webpack_require__(317); +const constants = __webpack_require__(319); +const utils = __webpack_require__(318); /** * Constants @@ -44712,13 +44867,13 @@ module.exports = parse; /***/ }), -/* 320 */ +/* 321 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const merge2 = __webpack_require__(291); +const merge2 = __webpack_require__(292); function merge(streams) { const mergedStream = merge2(streams); streams.forEach((stream) => { @@ -44735,7 +44890,7 @@ function propagateCloseEventToSources(streams) { /***/ }), -/* 321 */ +/* 322 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -44752,14 +44907,14 @@ exports.isEmpty = isEmpty; /***/ }), -/* 322 */ +/* 323 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const stream_1 = __webpack_require__(323); -const provider_1 = __webpack_require__(350); +const stream_1 = __webpack_require__(324); +const provider_1 = __webpack_require__(351); class ProviderAsync extends provider_1.default { constructor() { super(...arguments); @@ -44787,16 +44942,16 @@ exports.default = ProviderAsync; /***/ }), -/* 323 */ +/* 324 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const stream_1 = __webpack_require__(137); -const fsStat = __webpack_require__(324); -const fsWalk = __webpack_require__(329); -const reader_1 = __webpack_require__(349); +const fsStat = __webpack_require__(325); +const fsWalk = __webpack_require__(330); +const reader_1 = __webpack_require__(350); class ReaderStream extends reader_1.default { constructor() { super(...arguments); @@ -44849,15 +45004,15 @@ exports.default = ReaderStream; /***/ }), -/* 324 */ +/* 325 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async = __webpack_require__(325); -const sync = __webpack_require__(326); -const settings_1 = __webpack_require__(327); +const async = __webpack_require__(326); +const sync = __webpack_require__(327); +const settings_1 = __webpack_require__(328); exports.Settings = settings_1.default; function stat(path, optionsOrSettingsOrCallback, callback) { if (typeof optionsOrSettingsOrCallback === 'function') { @@ -44880,7 +45035,7 @@ function getSettings(settingsOrOptions = {}) { /***/ }), -/* 325 */ +/* 326 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -44918,7 +45073,7 @@ function callSuccessCallback(callback, result) { /***/ }), -/* 326 */ +/* 327 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -44947,13 +45102,13 @@ exports.read = read; /***/ }), -/* 327 */ +/* 328 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(328); +const fs = __webpack_require__(329); class Settings { constructor(_options = {}) { this._options = _options; @@ -44970,7 +45125,7 @@ exports.default = Settings; /***/ }), -/* 328 */ +/* 329 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -44993,16 +45148,16 @@ exports.createFileSystemAdapter = createFileSystemAdapter; /***/ }), -/* 329 */ +/* 330 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async_1 = __webpack_require__(330); -const stream_1 = __webpack_require__(345); -const sync_1 = __webpack_require__(346); -const settings_1 = __webpack_require__(348); +const async_1 = __webpack_require__(331); +const stream_1 = __webpack_require__(346); +const sync_1 = __webpack_require__(347); +const settings_1 = __webpack_require__(349); exports.Settings = settings_1.default; function walk(directory, optionsOrSettingsOrCallback, callback) { if (typeof optionsOrSettingsOrCallback === 'function') { @@ -45032,13 +45187,13 @@ function getSettings(settingsOrOptions = {}) { /***/ }), -/* 330 */ +/* 331 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async_1 = __webpack_require__(331); +const async_1 = __webpack_require__(332); class AsyncProvider { constructor(_root, _settings) { this._root = _root; @@ -45069,17 +45224,17 @@ function callSuccessCallback(callback, entries) { /***/ }), -/* 331 */ +/* 332 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const events_1 = __webpack_require__(155); -const fsScandir = __webpack_require__(332); -const fastq = __webpack_require__(341); -const common = __webpack_require__(343); -const reader_1 = __webpack_require__(344); +const fsScandir = __webpack_require__(333); +const fastq = __webpack_require__(342); +const common = __webpack_require__(344); +const reader_1 = __webpack_require__(345); class AsyncReader extends reader_1.default { constructor(_root, _settings) { super(_root, _settings); @@ -45169,15 +45324,15 @@ exports.default = AsyncReader; /***/ }), -/* 332 */ +/* 333 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const async = __webpack_require__(333); -const sync = __webpack_require__(338); -const settings_1 = __webpack_require__(339); +const async = __webpack_require__(334); +const sync = __webpack_require__(339); +const settings_1 = __webpack_require__(340); exports.Settings = settings_1.default; function scandir(path, optionsOrSettingsOrCallback, callback) { if (typeof optionsOrSettingsOrCallback === 'function') { @@ -45200,16 +45355,16 @@ function getSettings(settingsOrOptions = {}) { /***/ }), -/* 333 */ +/* 334 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(324); -const rpl = __webpack_require__(334); -const constants_1 = __webpack_require__(335); -const utils = __webpack_require__(336); +const fsStat = __webpack_require__(325); +const rpl = __webpack_require__(335); +const constants_1 = __webpack_require__(336); +const utils = __webpack_require__(337); function read(directory, settings, callback) { if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { return readdirWithFileTypes(directory, settings, callback); @@ -45297,7 +45452,7 @@ function callSuccessCallback(callback, result) { /***/ }), -/* 334 */ +/* 335 */ /***/ (function(module, exports) { module.exports = runParallel @@ -45351,7 +45506,7 @@ function runParallel (tasks, cb) { /***/ }), -/* 335 */ +/* 336 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -45371,18 +45526,18 @@ exports.IS_SUPPORT_READDIR_WITH_FILE_TYPES = IS_MATCHED_BY_MAJOR || IS_MATCHED_B /***/ }), -/* 336 */ +/* 337 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fs = __webpack_require__(337); +const fs = __webpack_require__(338); exports.fs = fs; /***/ }), -/* 337 */ +/* 338 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -45407,15 +45562,15 @@ exports.createDirentFromStats = createDirentFromStats; /***/ }), -/* 338 */ +/* 339 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(324); -const constants_1 = __webpack_require__(335); -const utils = __webpack_require__(336); +const fsStat = __webpack_require__(325); +const constants_1 = __webpack_require__(336); +const utils = __webpack_require__(337); function read(directory, settings) { if (!settings.stats && constants_1.IS_SUPPORT_READDIR_WITH_FILE_TYPES) { return readdirWithFileTypes(directory, settings); @@ -45466,15 +45621,15 @@ exports.readdir = readdir; /***/ }), -/* 339 */ +/* 340 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = __webpack_require__(4); -const fsStat = __webpack_require__(324); -const fs = __webpack_require__(340); +const fsStat = __webpack_require__(325); +const fs = __webpack_require__(341); class Settings { constructor(_options = {}) { this._options = _options; @@ -45497,7 +45652,7 @@ exports.default = Settings; /***/ }), -/* 340 */ +/* 341 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -45522,13 +45677,13 @@ exports.createFileSystemAdapter = createFileSystemAdapter; /***/ }), -/* 341 */ +/* 342 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var reusify = __webpack_require__(342) +var reusify = __webpack_require__(343) function fastqueue (context, worker, concurrency) { if (typeof context === 'function') { @@ -45702,7 +45857,7 @@ module.exports = fastqueue /***/ }), -/* 342 */ +/* 343 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -45742,7 +45897,7 @@ module.exports = reusify /***/ }), -/* 343 */ +/* 344 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -45773,13 +45928,13 @@ exports.joinPathSegments = joinPathSegments; /***/ }), -/* 344 */ +/* 345 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const common = __webpack_require__(343); +const common = __webpack_require__(344); class Reader { constructor(_root, _settings) { this._root = _root; @@ -45791,14 +45946,14 @@ exports.default = Reader; /***/ }), -/* 345 */ +/* 346 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const stream_1 = __webpack_require__(137); -const async_1 = __webpack_require__(331); +const async_1 = __webpack_require__(332); class StreamProvider { constructor(_root, _settings) { this._root = _root; @@ -45828,13 +45983,13 @@ exports.default = StreamProvider; /***/ }), -/* 346 */ +/* 347 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const sync_1 = __webpack_require__(347); +const sync_1 = __webpack_require__(348); class SyncProvider { constructor(_root, _settings) { this._root = _root; @@ -45849,15 +46004,15 @@ exports.default = SyncProvider; /***/ }), -/* 347 */ +/* 348 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsScandir = __webpack_require__(332); -const common = __webpack_require__(343); -const reader_1 = __webpack_require__(344); +const fsScandir = __webpack_require__(333); +const common = __webpack_require__(344); +const reader_1 = __webpack_require__(345); class SyncReader extends reader_1.default { constructor() { super(...arguments); @@ -45915,14 +46070,14 @@ exports.default = SyncReader; /***/ }), -/* 348 */ +/* 349 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = __webpack_require__(4); -const fsScandir = __webpack_require__(332); +const fsScandir = __webpack_require__(333); class Settings { constructor(_options = {}) { this._options = _options; @@ -45948,15 +46103,15 @@ exports.default = Settings; /***/ }), -/* 349 */ +/* 350 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = __webpack_require__(4); -const fsStat = __webpack_require__(324); -const utils = __webpack_require__(294); +const fsStat = __webpack_require__(325); +const utils = __webpack_require__(295); class Reader { constructor(_settings) { this._settings = _settings; @@ -45988,17 +46143,17 @@ exports.default = Reader; /***/ }), -/* 350 */ +/* 351 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const path = __webpack_require__(4); -const deep_1 = __webpack_require__(351); -const entry_1 = __webpack_require__(354); -const error_1 = __webpack_require__(355); -const entry_2 = __webpack_require__(356); +const deep_1 = __webpack_require__(352); +const entry_1 = __webpack_require__(355); +const error_1 = __webpack_require__(356); +const entry_2 = __webpack_require__(357); class Provider { constructor(_settings) { this._settings = _settings; @@ -46043,14 +46198,14 @@ exports.default = Provider; /***/ }), -/* 351 */ +/* 352 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(294); -const partial_1 = __webpack_require__(352); +const utils = __webpack_require__(295); +const partial_1 = __webpack_require__(353); class DeepFilter { constructor(_settings, _micromatchOptions) { this._settings = _settings; @@ -46104,13 +46259,13 @@ exports.default = DeepFilter; /***/ }), -/* 352 */ +/* 353 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const matcher_1 = __webpack_require__(353); +const matcher_1 = __webpack_require__(354); class PartialMatcher extends matcher_1.default { match(filepath) { const parts = filepath.split('/'); @@ -46149,13 +46304,13 @@ exports.default = PartialMatcher; /***/ }), -/* 353 */ +/* 354 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(294); +const utils = __webpack_require__(295); class Matcher { constructor(_patterns, _settings, _micromatchOptions) { this._patterns = _patterns; @@ -46206,13 +46361,13 @@ exports.default = Matcher; /***/ }), -/* 354 */ +/* 355 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(294); +const utils = __webpack_require__(295); class EntryFilter { constructor(_settings, _micromatchOptions) { this._settings = _settings; @@ -46268,13 +46423,13 @@ exports.default = EntryFilter; /***/ }), -/* 355 */ +/* 356 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(294); +const utils = __webpack_require__(295); class ErrorFilter { constructor(_settings) { this._settings = _settings; @@ -46290,13 +46445,13 @@ exports.default = ErrorFilter; /***/ }), -/* 356 */ +/* 357 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const utils = __webpack_require__(294); +const utils = __webpack_require__(295); class EntryTransformer { constructor(_settings) { this._settings = _settings; @@ -46323,15 +46478,15 @@ exports.default = EntryTransformer; /***/ }), -/* 357 */ +/* 358 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const stream_1 = __webpack_require__(137); -const stream_2 = __webpack_require__(323); -const provider_1 = __webpack_require__(350); +const stream_2 = __webpack_require__(324); +const provider_1 = __webpack_require__(351); class ProviderStream extends provider_1.default { constructor() { super(...arguments); @@ -46361,14 +46516,14 @@ exports.default = ProviderStream; /***/ }), -/* 358 */ +/* 359 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const sync_1 = __webpack_require__(359); -const provider_1 = __webpack_require__(350); +const sync_1 = __webpack_require__(360); +const provider_1 = __webpack_require__(351); class ProviderSync extends provider_1.default { constructor() { super(...arguments); @@ -46391,15 +46546,15 @@ exports.default = ProviderSync; /***/ }), -/* 359 */ +/* 360 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsStat = __webpack_require__(324); -const fsWalk = __webpack_require__(329); -const reader_1 = __webpack_require__(349); +const fsStat = __webpack_require__(325); +const fsWalk = __webpack_require__(330); +const reader_1 = __webpack_require__(350); class ReaderSync extends reader_1.default { constructor() { super(...arguments); @@ -46441,7 +46596,7 @@ exports.default = ReaderSync; /***/ }), -/* 360 */ +/* 361 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -46500,13 +46655,13 @@ exports.default = Settings; /***/ }), -/* 361 */ +/* 362 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const pathType = __webpack_require__(362); +const pathType = __webpack_require__(363); const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; @@ -46582,7 +46737,7 @@ module.exports.sync = (input, options) => { /***/ }), -/* 362 */ +/* 363 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -46632,7 +46787,7 @@ exports.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink'); /***/ }), -/* 363 */ +/* 364 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -46640,9 +46795,9 @@ exports.isSymlinkSync = isTypeSync.bind(null, 'lstatSync', 'isSymbolicLink'); const {promisify} = __webpack_require__(111); const fs = __webpack_require__(133); const path = __webpack_require__(4); -const fastGlob = __webpack_require__(292); -const gitIgnore = __webpack_require__(364); -const slash = __webpack_require__(365); +const fastGlob = __webpack_require__(293); +const gitIgnore = __webpack_require__(365); +const slash = __webpack_require__(366); const DEFAULT_IGNORE = [ '**/node_modules/**', @@ -46756,7 +46911,7 @@ module.exports.sync = options => { /***/ }), -/* 364 */ +/* 365 */ /***/ (function(module, exports) { // A simple implementation of make-array @@ -47359,7 +47514,7 @@ if ( /***/ }), -/* 365 */ +/* 366 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -47377,7 +47532,7 @@ module.exports = path => { /***/ }), -/* 366 */ +/* 367 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -47430,7 +47585,7 @@ module.exports = { /***/ }), -/* 367 */ +/* 368 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -47440,7 +47595,7 @@ module.exports = { * Released under the MIT License. */ -var isExtglob = __webpack_require__(302); +var isExtglob = __webpack_require__(303); var chars = { '{': '}', '(': ')', '[': ']'}; var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; @@ -47484,7 +47639,7 @@ module.exports = function isGlob(str, options) { /***/ }), -/* 368 */ +/* 369 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -47506,7 +47661,7 @@ module.exports = path_ => { /***/ }), -/* 369 */ +/* 370 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -47534,7 +47689,7 @@ module.exports = (childPath, parentPath) => { /***/ }), -/* 370 */ +/* 371 */ /***/ (function(module, exports, __webpack_require__) { const assert = __webpack_require__(139) @@ -47900,12 +48055,12 @@ rimraf.sync = rimrafSync /***/ }), -/* 371 */ +/* 372 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const AggregateError = __webpack_require__(372); +const AggregateError = __webpack_require__(373); module.exports = async ( iterable, @@ -47988,13 +48143,13 @@ module.exports = async ( /***/ }), -/* 372 */ +/* 373 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const indentString = __webpack_require__(373); -const cleanStack = __webpack_require__(374); +const indentString = __webpack_require__(374); +const cleanStack = __webpack_require__(375); const cleanInternalStack = stack => stack.replace(/\s+at .*aggregate-error\/index.js:\d+:\d+\)?/g, ''); @@ -48042,7 +48197,7 @@ module.exports = AggregateError; /***/ }), -/* 373 */ +/* 374 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48084,7 +48239,7 @@ module.exports = (string, count = 1, options) => { /***/ }), -/* 374 */ +/* 375 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -48131,15 +48286,15 @@ module.exports = (stack, options) => { /***/ }), -/* 375 */ +/* 376 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const chalk = __webpack_require__(376); -const cliCursor = __webpack_require__(385); -const cliSpinners = __webpack_require__(389); -const logSymbols = __webpack_require__(391); +const chalk = __webpack_require__(377); +const cliCursor = __webpack_require__(386); +const cliSpinners = __webpack_require__(390); +const logSymbols = __webpack_require__(392); class Ora { constructor(options) { @@ -48286,16 +48441,16 @@ module.exports.promise = (action, options) => { /***/ }), -/* 376 */ +/* 377 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const escapeStringRegexp = __webpack_require__(178); -const ansiStyles = __webpack_require__(377); -const stdoutColor = __webpack_require__(382).stdout; +const ansiStyles = __webpack_require__(378); +const stdoutColor = __webpack_require__(383).stdout; -const template = __webpack_require__(384); +const template = __webpack_require__(385); const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); @@ -48521,12 +48676,12 @@ module.exports.default = module.exports; // For TypeScript /***/ }), -/* 377 */ +/* 378 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; /* WEBPACK VAR INJECTION */(function(module) { -const colorConvert = __webpack_require__(378); +const colorConvert = __webpack_require__(379); const wrapAnsi16 = (fn, offset) => function () { const code = fn.apply(colorConvert, arguments); @@ -48694,11 +48849,11 @@ Object.defineProperty(module, 'exports', { /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) /***/ }), -/* 378 */ +/* 379 */ /***/ (function(module, exports, __webpack_require__) { -var conversions = __webpack_require__(379); -var route = __webpack_require__(381); +var conversions = __webpack_require__(380); +var route = __webpack_require__(382); var convert = {}; @@ -48778,11 +48933,11 @@ module.exports = convert; /***/ }), -/* 379 */ +/* 380 */ /***/ (function(module, exports, __webpack_require__) { /* MIT license */ -var cssKeywords = __webpack_require__(380); +var cssKeywords = __webpack_require__(381); // NOTE: conversions should only return primitive values (i.e. arrays, or // values that give correct `typeof` results). @@ -49652,7 +49807,7 @@ convert.rgb.gray = function (rgb) { /***/ }), -/* 380 */ +/* 381 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -49811,10 +49966,10 @@ module.exports = { /***/ }), -/* 381 */ +/* 382 */ /***/ (function(module, exports, __webpack_require__) { -var conversions = __webpack_require__(379); +var conversions = __webpack_require__(380); /* this function routes a model to all other models. @@ -49914,13 +50069,13 @@ module.exports = function (fromModel) { /***/ }), -/* 382 */ +/* 383 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const os = __webpack_require__(120); -const hasFlag = __webpack_require__(383); +const hasFlag = __webpack_require__(384); const env = process.env; @@ -50052,7 +50207,7 @@ module.exports = { /***/ }), -/* 383 */ +/* 384 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50067,7 +50222,7 @@ module.exports = (flag, argv) => { /***/ }), -/* 384 */ +/* 385 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50202,12 +50357,12 @@ module.exports = (chalk, tmp) => { /***/ }), -/* 385 */ +/* 386 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const restoreCursor = __webpack_require__(386); +const restoreCursor = __webpack_require__(387); let hidden = false; @@ -50248,12 +50403,12 @@ exports.toggle = (force, stream) => { /***/ }), -/* 386 */ +/* 387 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const onetime = __webpack_require__(387); +const onetime = __webpack_require__(388); const signalExit = __webpack_require__(217); module.exports = onetime(() => { @@ -50264,12 +50419,12 @@ module.exports = onetime(() => { /***/ }), -/* 387 */ +/* 388 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const mimicFn = __webpack_require__(388); +const mimicFn = __webpack_require__(389); module.exports = (fn, opts) => { // TODO: Remove this in v3 @@ -50310,7 +50465,7 @@ module.exports = (fn, opts) => { /***/ }), -/* 388 */ +/* 389 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50326,27 +50481,27 @@ module.exports = (to, from) => { /***/ }), -/* 389 */ +/* 390 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -module.exports = __webpack_require__(390); +module.exports = __webpack_require__(391); /***/ }), -/* 390 */ +/* 391 */ /***/ (function(module) { module.exports = JSON.parse("{\"dots\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠹\",\"⠸\",\"⠼\",\"⠴\",\"⠦\",\"⠧\",\"⠇\",\"⠏\"]},\"dots2\":{\"interval\":80,\"frames\":[\"⣾\",\"⣽\",\"⣻\",\"⢿\",\"⡿\",\"⣟\",\"⣯\",\"⣷\"]},\"dots3\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠞\",\"⠖\",\"⠦\",\"⠴\",\"⠲\",\"⠳\",\"⠓\"]},\"dots4\":{\"interval\":80,\"frames\":[\"⠄\",\"⠆\",\"⠇\",\"⠋\",\"⠙\",\"⠸\",\"⠰\",\"⠠\",\"⠰\",\"⠸\",\"⠙\",\"⠋\",\"⠇\",\"⠆\"]},\"dots5\":{\"interval\":80,\"frames\":[\"⠋\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\"]},\"dots6\":{\"interval\":80,\"frames\":[\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠴\",\"⠲\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠚\",\"⠙\",\"⠉\",\"⠁\"]},\"dots7\":{\"interval\":80,\"frames\":[\"⠈\",\"⠉\",\"⠋\",\"⠓\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠖\",\"⠦\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\"]},\"dots8\":{\"interval\":80,\"frames\":[\"⠁\",\"⠁\",\"⠉\",\"⠙\",\"⠚\",\"⠒\",\"⠂\",\"⠂\",\"⠒\",\"⠲\",\"⠴\",\"⠤\",\"⠄\",\"⠄\",\"⠤\",\"⠠\",\"⠠\",\"⠤\",\"⠦\",\"⠖\",\"⠒\",\"⠐\",\"⠐\",\"⠒\",\"⠓\",\"⠋\",\"⠉\",\"⠈\",\"⠈\"]},\"dots9\":{\"interval\":80,\"frames\":[\"⢹\",\"⢺\",\"⢼\",\"⣸\",\"⣇\",\"⡧\",\"⡗\",\"⡏\"]},\"dots10\":{\"interval\":80,\"frames\":[\"⢄\",\"⢂\",\"⢁\",\"⡁\",\"⡈\",\"⡐\",\"⡠\"]},\"dots11\":{\"interval\":100,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⡀\",\"⢀\",\"⠠\",\"⠐\",\"⠈\"]},\"dots12\":{\"interval\":80,\"frames\":[\"⢀⠀\",\"⡀⠀\",\"⠄⠀\",\"⢂⠀\",\"⡂⠀\",\"⠅⠀\",\"⢃⠀\",\"⡃⠀\",\"⠍⠀\",\"⢋⠀\",\"⡋⠀\",\"⠍⠁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⢈⠩\",\"⡀⢙\",\"⠄⡙\",\"⢂⠩\",\"⡂⢘\",\"⠅⡘\",\"⢃⠨\",\"⡃⢐\",\"⠍⡐\",\"⢋⠠\",\"⡋⢀\",\"⠍⡁\",\"⢋⠁\",\"⡋⠁\",\"⠍⠉\",\"⠋⠉\",\"⠋⠉\",\"⠉⠙\",\"⠉⠙\",\"⠉⠩\",\"⠈⢙\",\"⠈⡙\",\"⠈⠩\",\"⠀⢙\",\"⠀⡙\",\"⠀⠩\",\"⠀⢘\",\"⠀⡘\",\"⠀⠨\",\"⠀⢐\",\"⠀⡐\",\"⠀⠠\",\"⠀⢀\",\"⠀⡀\"]},\"line\":{\"interval\":130,\"frames\":[\"-\",\"\\\\\",\"|\",\"/\"]},\"line2\":{\"interval\":100,\"frames\":[\"⠂\",\"-\",\"–\",\"—\",\"–\",\"-\"]},\"pipe\":{\"interval\":100,\"frames\":[\"┤\",\"┘\",\"┴\",\"└\",\"├\",\"┌\",\"┬\",\"┐\"]},\"simpleDots\":{\"interval\":400,\"frames\":[\". \",\".. \",\"...\",\" \"]},\"simpleDotsScrolling\":{\"interval\":200,\"frames\":[\". \",\".. \",\"...\",\" ..\",\" .\",\" \"]},\"star\":{\"interval\":70,\"frames\":[\"✶\",\"✸\",\"✹\",\"✺\",\"✹\",\"✷\"]},\"star2\":{\"interval\":80,\"frames\":[\"+\",\"x\",\"*\"]},\"flip\":{\"interval\":70,\"frames\":[\"_\",\"_\",\"_\",\"-\",\"`\",\"`\",\"'\",\"´\",\"-\",\"_\",\"_\",\"_\"]},\"hamburger\":{\"interval\":100,\"frames\":[\"☱\",\"☲\",\"☴\"]},\"growVertical\":{\"interval\":120,\"frames\":[\"▁\",\"▃\",\"▄\",\"▅\",\"▆\",\"▇\",\"▆\",\"▅\",\"▄\",\"▃\"]},\"growHorizontal\":{\"interval\":120,\"frames\":[\"▏\",\"▎\",\"▍\",\"▌\",\"▋\",\"▊\",\"▉\",\"▊\",\"▋\",\"▌\",\"▍\",\"▎\"]},\"balloon\":{\"interval\":140,\"frames\":[\" \",\".\",\"o\",\"O\",\"@\",\"*\",\" \"]},\"balloon2\":{\"interval\":120,\"frames\":[\".\",\"o\",\"O\",\"°\",\"O\",\"o\",\".\"]},\"noise\":{\"interval\":100,\"frames\":[\"▓\",\"▒\",\"░\"]},\"bounce\":{\"interval\":120,\"frames\":[\"⠁\",\"⠂\",\"⠄\",\"⠂\"]},\"boxBounce\":{\"interval\":120,\"frames\":[\"▖\",\"▘\",\"▝\",\"▗\"]},\"boxBounce2\":{\"interval\":100,\"frames\":[\"▌\",\"▀\",\"▐\",\"▄\"]},\"triangle\":{\"interval\":50,\"frames\":[\"◢\",\"◣\",\"◤\",\"◥\"]},\"arc\":{\"interval\":100,\"frames\":[\"◜\",\"◠\",\"◝\",\"◞\",\"◡\",\"◟\"]},\"circle\":{\"interval\":120,\"frames\":[\"◡\",\"⊙\",\"◠\"]},\"squareCorners\":{\"interval\":180,\"frames\":[\"◰\",\"◳\",\"◲\",\"◱\"]},\"circleQuarters\":{\"interval\":120,\"frames\":[\"◴\",\"◷\",\"◶\",\"◵\"]},\"circleHalves\":{\"interval\":50,\"frames\":[\"◐\",\"◓\",\"◑\",\"◒\"]},\"squish\":{\"interval\":100,\"frames\":[\"╫\",\"╪\"]},\"toggle\":{\"interval\":250,\"frames\":[\"⊶\",\"⊷\"]},\"toggle2\":{\"interval\":80,\"frames\":[\"▫\",\"▪\"]},\"toggle3\":{\"interval\":120,\"frames\":[\"□\",\"■\"]},\"toggle4\":{\"interval\":100,\"frames\":[\"■\",\"□\",\"▪\",\"▫\"]},\"toggle5\":{\"interval\":100,\"frames\":[\"▮\",\"▯\"]},\"toggle6\":{\"interval\":300,\"frames\":[\"ဝ\",\"၀\"]},\"toggle7\":{\"interval\":80,\"frames\":[\"⦾\",\"⦿\"]},\"toggle8\":{\"interval\":100,\"frames\":[\"◍\",\"◌\"]},\"toggle9\":{\"interval\":100,\"frames\":[\"◉\",\"◎\"]},\"toggle10\":{\"interval\":100,\"frames\":[\"㊂\",\"㊀\",\"㊁\"]},\"toggle11\":{\"interval\":50,\"frames\":[\"⧇\",\"⧆\"]},\"toggle12\":{\"interval\":120,\"frames\":[\"☗\",\"☖\"]},\"toggle13\":{\"interval\":80,\"frames\":[\"=\",\"*\",\"-\"]},\"arrow\":{\"interval\":100,\"frames\":[\"←\",\"↖\",\"↑\",\"↗\",\"→\",\"↘\",\"↓\",\"↙\"]},\"arrow2\":{\"interval\":80,\"frames\":[\"⬆️ \",\"↗️ \",\"➡️ \",\"↘️ \",\"⬇️ \",\"↙️ \",\"⬅️ \",\"↖️ \"]},\"arrow3\":{\"interval\":120,\"frames\":[\"▹▹▹▹▹\",\"▸▹▹▹▹\",\"▹▸▹▹▹\",\"▹▹▸▹▹\",\"▹▹▹▸▹\",\"▹▹▹▹▸\"]},\"bouncingBar\":{\"interval\":80,\"frames\":[\"[ ]\",\"[= ]\",\"[== ]\",\"[=== ]\",\"[ ===]\",\"[ ==]\",\"[ =]\",\"[ ]\",\"[ =]\",\"[ ==]\",\"[ ===]\",\"[====]\",\"[=== ]\",\"[== ]\",\"[= ]\"]},\"bouncingBall\":{\"interval\":80,\"frames\":[\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ●)\",\"( ● )\",\"( ● )\",\"( ● )\",\"( ● )\",\"(● )\"]},\"smiley\":{\"interval\":200,\"frames\":[\"😄 \",\"😝 \"]},\"monkey\":{\"interval\":300,\"frames\":[\"🙈 \",\"🙈 \",\"🙉 \",\"🙊 \"]},\"hearts\":{\"interval\":100,\"frames\":[\"💛 \",\"💙 \",\"💜 \",\"💚 \",\"❤️ \"]},\"clock\":{\"interval\":100,\"frames\":[\"🕐 \",\"🕑 \",\"🕒 \",\"🕓 \",\"🕔 \",\"🕕 \",\"🕖 \",\"🕗 \",\"🕘 \",\"🕙 \",\"🕚 \"]},\"earth\":{\"interval\":180,\"frames\":[\"🌍 \",\"🌎 \",\"🌏 \"]},\"moon\":{\"interval\":80,\"frames\":[\"🌑 \",\"🌒 \",\"🌓 \",\"🌔 \",\"🌕 \",\"🌖 \",\"🌗 \",\"🌘 \"]},\"runner\":{\"interval\":140,\"frames\":[\"🚶 \",\"🏃 \"]},\"pong\":{\"interval\":80,\"frames\":[\"▐⠂ ▌\",\"▐⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂▌\",\"▐ ⠠▌\",\"▐ ⡀▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐ ⠠ ▌\",\"▐ ⠂ ▌\",\"▐ ⠈ ▌\",\"▐ ⠂ ▌\",\"▐ ⠠ ▌\",\"▐ ⡀ ▌\",\"▐⠠ ▌\"]},\"shark\":{\"interval\":120,\"frames\":[\"▐|\\\\____________▌\",\"▐_|\\\\___________▌\",\"▐__|\\\\__________▌\",\"▐___|\\\\_________▌\",\"▐____|\\\\________▌\",\"▐_____|\\\\_______▌\",\"▐______|\\\\______▌\",\"▐_______|\\\\_____▌\",\"▐________|\\\\____▌\",\"▐_________|\\\\___▌\",\"▐__________|\\\\__▌\",\"▐___________|\\\\_▌\",\"▐____________|\\\\▌\",\"▐____________/|▌\",\"▐___________/|_▌\",\"▐__________/|__▌\",\"▐_________/|___▌\",\"▐________/|____▌\",\"▐_______/|_____▌\",\"▐______/|______▌\",\"▐_____/|_______▌\",\"▐____/|________▌\",\"▐___/|_________▌\",\"▐__/|__________▌\",\"▐_/|___________▌\",\"▐/|____________▌\"]},\"dqpb\":{\"interval\":100,\"frames\":[\"d\",\"q\",\"p\",\"b\"]},\"weather\":{\"interval\":100,\"frames\":[\"☀️ \",\"☀️ \",\"☀️ \",\"🌤 \",\"⛅️ \",\"🌥 \",\"☁️ \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"🌧 \",\"🌨 \",\"⛈ \",\"🌨 \",\"🌧 \",\"🌨 \",\"☁️ \",\"🌥 \",\"⛅️ \",\"🌤 \",\"☀️ \",\"☀️ \"]},\"christmas\":{\"interval\":400,\"frames\":[\"🌲\",\"🎄\"]}}"); /***/ }), -/* 391 */ +/* 392 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const chalk = __webpack_require__(392); +const chalk = __webpack_require__(393); const isSupported = process.platform !== 'win32' || process.env.CI || process.env.TERM === 'xterm-256color'; @@ -50368,16 +50523,16 @@ module.exports = isSupported ? main : fallbacks; /***/ }), -/* 392 */ +/* 393 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const escapeStringRegexp = __webpack_require__(178); -const ansiStyles = __webpack_require__(393); +const ansiStyles = __webpack_require__(394); const stdoutColor = __webpack_require__(184).stdout; -const template = __webpack_require__(394); +const template = __webpack_require__(395); const isSimpleWindowsTerm = process.platform === 'win32' && !(process.env.TERM || '').toLowerCase().startsWith('xterm'); @@ -50603,7 +50758,7 @@ module.exports.default = module.exports; // For TypeScript /***/ }), -/* 393 */ +/* 394 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50776,7 +50931,7 @@ Object.defineProperty(module, 'exports', { /* WEBPACK VAR INJECTION */}.call(this, __webpack_require__(114)(module))) /***/ }), -/* 394 */ +/* 395 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -50911,7 +51066,7 @@ module.exports = (chalk, tmp) => { /***/ }), -/* 395 */ +/* 396 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -50972,7 +51127,7 @@ const RunCommand = { }; /***/ }), -/* 396 */ +/* 397 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -50982,7 +51137,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); /* harmony import */ var _utils_parallelize__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(144); /* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(145); -/* harmony import */ var _utils_watch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(397); +/* harmony import */ var _utils_watch__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(398); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -51067,14 +51222,14 @@ const WatchCommand = { }; /***/ }), -/* 397 */ +/* 398 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "waitUntilWatchIsReady", function() { return waitUntilWatchIsReady; }); /* harmony import */ var rxjs__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(8); -/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(398); +/* harmony import */ var rxjs_operators__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(399); /* * Licensed to Elasticsearch B.V. under one or more contributor * license agreements. See the NOTICE file distributed with @@ -51141,141 +51296,141 @@ function waitUntilWatchIsReady(stream, opts = {}) { } /***/ }), -/* 398 */ +/* 399 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); -/* harmony import */ var _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(399); +/* harmony import */ var _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(400); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "audit", function() { return _internal_operators_audit__WEBPACK_IMPORTED_MODULE_0__["audit"]; }); -/* harmony import */ var _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(400); +/* harmony import */ var _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(401); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "auditTime", function() { return _internal_operators_auditTime__WEBPACK_IMPORTED_MODULE_1__["auditTime"]; }); -/* harmony import */ var _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(401); +/* harmony import */ var _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(402); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buffer", function() { return _internal_operators_buffer__WEBPACK_IMPORTED_MODULE_2__["buffer"]; }); -/* harmony import */ var _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(402); +/* harmony import */ var _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(403); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferCount", function() { return _internal_operators_bufferCount__WEBPACK_IMPORTED_MODULE_3__["bufferCount"]; }); -/* harmony import */ var _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(403); +/* harmony import */ var _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(404); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferTime", function() { return _internal_operators_bufferTime__WEBPACK_IMPORTED_MODULE_4__["bufferTime"]; }); -/* harmony import */ var _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(404); +/* harmony import */ var _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(405); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferToggle", function() { return _internal_operators_bufferToggle__WEBPACK_IMPORTED_MODULE_5__["bufferToggle"]; }); -/* harmony import */ var _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(405); +/* harmony import */ var _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__ = __webpack_require__(406); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "bufferWhen", function() { return _internal_operators_bufferWhen__WEBPACK_IMPORTED_MODULE_6__["bufferWhen"]; }); -/* harmony import */ var _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(406); +/* harmony import */ var _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__ = __webpack_require__(407); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "catchError", function() { return _internal_operators_catchError__WEBPACK_IMPORTED_MODULE_7__["catchError"]; }); -/* harmony import */ var _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(407); +/* harmony import */ var _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__ = __webpack_require__(408); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineAll", function() { return _internal_operators_combineAll__WEBPACK_IMPORTED_MODULE_8__["combineAll"]; }); -/* harmony import */ var _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(408); +/* harmony import */ var _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__ = __webpack_require__(409); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "combineLatest", function() { return _internal_operators_combineLatest__WEBPACK_IMPORTED_MODULE_9__["combineLatest"]; }); -/* harmony import */ var _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(409); +/* harmony import */ var _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__ = __webpack_require__(410); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concat", function() { return _internal_operators_concat__WEBPACK_IMPORTED_MODULE_10__["concat"]; }); /* harmony import */ var _internal_operators_concatAll__WEBPACK_IMPORTED_MODULE_11__ = __webpack_require__(80); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatAll", function() { return _internal_operators_concatAll__WEBPACK_IMPORTED_MODULE_11__["concatAll"]; }); -/* harmony import */ var _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(410); +/* harmony import */ var _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__ = __webpack_require__(411); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatMap", function() { return _internal_operators_concatMap__WEBPACK_IMPORTED_MODULE_12__["concatMap"]; }); -/* harmony import */ var _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(411); +/* harmony import */ var _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__ = __webpack_require__(412); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "concatMapTo", function() { return _internal_operators_concatMapTo__WEBPACK_IMPORTED_MODULE_13__["concatMapTo"]; }); -/* harmony import */ var _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(412); +/* harmony import */ var _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__ = __webpack_require__(413); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "count", function() { return _internal_operators_count__WEBPACK_IMPORTED_MODULE_14__["count"]; }); -/* harmony import */ var _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(413); +/* harmony import */ var _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__ = __webpack_require__(414); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "debounce", function() { return _internal_operators_debounce__WEBPACK_IMPORTED_MODULE_15__["debounce"]; }); -/* harmony import */ var _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(414); +/* harmony import */ var _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__ = __webpack_require__(415); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "debounceTime", function() { return _internal_operators_debounceTime__WEBPACK_IMPORTED_MODULE_16__["debounceTime"]; }); -/* harmony import */ var _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(415); +/* harmony import */ var _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__ = __webpack_require__(416); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "defaultIfEmpty", function() { return _internal_operators_defaultIfEmpty__WEBPACK_IMPORTED_MODULE_17__["defaultIfEmpty"]; }); -/* harmony import */ var _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(416); +/* harmony import */ var _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__ = __webpack_require__(417); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "delay", function() { return _internal_operators_delay__WEBPACK_IMPORTED_MODULE_18__["delay"]; }); -/* harmony import */ var _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(418); +/* harmony import */ var _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__ = __webpack_require__(419); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "delayWhen", function() { return _internal_operators_delayWhen__WEBPACK_IMPORTED_MODULE_19__["delayWhen"]; }); -/* harmony import */ var _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(419); +/* harmony import */ var _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__ = __webpack_require__(420); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "dematerialize", function() { return _internal_operators_dematerialize__WEBPACK_IMPORTED_MODULE_20__["dematerialize"]; }); -/* harmony import */ var _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(420); +/* harmony import */ var _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__ = __webpack_require__(421); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinct", function() { return _internal_operators_distinct__WEBPACK_IMPORTED_MODULE_21__["distinct"]; }); -/* harmony import */ var _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(421); +/* harmony import */ var _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__ = __webpack_require__(422); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinctUntilChanged", function() { return _internal_operators_distinctUntilChanged__WEBPACK_IMPORTED_MODULE_22__["distinctUntilChanged"]; }); -/* harmony import */ var _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(422); +/* harmony import */ var _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__ = __webpack_require__(423); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "distinctUntilKeyChanged", function() { return _internal_operators_distinctUntilKeyChanged__WEBPACK_IMPORTED_MODULE_23__["distinctUntilKeyChanged"]; }); -/* harmony import */ var _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(423); +/* harmony import */ var _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__ = __webpack_require__(424); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "elementAt", function() { return _internal_operators_elementAt__WEBPACK_IMPORTED_MODULE_24__["elementAt"]; }); -/* harmony import */ var _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(426); +/* harmony import */ var _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__ = __webpack_require__(427); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "endWith", function() { return _internal_operators_endWith__WEBPACK_IMPORTED_MODULE_25__["endWith"]; }); -/* harmony import */ var _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(427); +/* harmony import */ var _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__ = __webpack_require__(428); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "every", function() { return _internal_operators_every__WEBPACK_IMPORTED_MODULE_26__["every"]; }); -/* harmony import */ var _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(428); +/* harmony import */ var _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__ = __webpack_require__(429); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "exhaust", function() { return _internal_operators_exhaust__WEBPACK_IMPORTED_MODULE_27__["exhaust"]; }); -/* harmony import */ var _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(429); +/* harmony import */ var _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__ = __webpack_require__(430); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "exhaustMap", function() { return _internal_operators_exhaustMap__WEBPACK_IMPORTED_MODULE_28__["exhaustMap"]; }); -/* harmony import */ var _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(430); +/* harmony import */ var _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__ = __webpack_require__(431); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "expand", function() { return _internal_operators_expand__WEBPACK_IMPORTED_MODULE_29__["expand"]; }); /* harmony import */ var _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__ = __webpack_require__(104); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "filter", function() { return _internal_operators_filter__WEBPACK_IMPORTED_MODULE_30__["filter"]; }); -/* harmony import */ var _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(431); +/* harmony import */ var _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__ = __webpack_require__(432); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "finalize", function() { return _internal_operators_finalize__WEBPACK_IMPORTED_MODULE_31__["finalize"]; }); -/* harmony import */ var _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(432); +/* harmony import */ var _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__ = __webpack_require__(433); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "find", function() { return _internal_operators_find__WEBPACK_IMPORTED_MODULE_32__["find"]; }); -/* harmony import */ var _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(433); +/* harmony import */ var _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__ = __webpack_require__(434); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "findIndex", function() { return _internal_operators_findIndex__WEBPACK_IMPORTED_MODULE_33__["findIndex"]; }); -/* harmony import */ var _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(434); +/* harmony import */ var _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__ = __webpack_require__(435); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "first", function() { return _internal_operators_first__WEBPACK_IMPORTED_MODULE_34__["first"]; }); /* harmony import */ var _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_35__ = __webpack_require__(31); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "groupBy", function() { return _internal_operators_groupBy__WEBPACK_IMPORTED_MODULE_35__["groupBy"]; }); -/* harmony import */ var _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(435); +/* harmony import */ var _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__ = __webpack_require__(436); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "ignoreElements", function() { return _internal_operators_ignoreElements__WEBPACK_IMPORTED_MODULE_36__["ignoreElements"]; }); -/* harmony import */ var _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(436); +/* harmony import */ var _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__ = __webpack_require__(437); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "isEmpty", function() { return _internal_operators_isEmpty__WEBPACK_IMPORTED_MODULE_37__["isEmpty"]; }); -/* harmony import */ var _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(437); +/* harmony import */ var _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__ = __webpack_require__(438); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "last", function() { return _internal_operators_last__WEBPACK_IMPORTED_MODULE_38__["last"]; }); /* harmony import */ var _internal_operators_map__WEBPACK_IMPORTED_MODULE_39__ = __webpack_require__(66); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "map", function() { return _internal_operators_map__WEBPACK_IMPORTED_MODULE_39__["map"]; }); -/* harmony import */ var _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(439); +/* harmony import */ var _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__ = __webpack_require__(440); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mapTo", function() { return _internal_operators_mapTo__WEBPACK_IMPORTED_MODULE_40__["mapTo"]; }); -/* harmony import */ var _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(440); +/* harmony import */ var _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__ = __webpack_require__(441); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "materialize", function() { return _internal_operators_materialize__WEBPACK_IMPORTED_MODULE_41__["materialize"]; }); -/* harmony import */ var _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(441); +/* harmony import */ var _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__ = __webpack_require__(442); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "max", function() { return _internal_operators_max__WEBPACK_IMPORTED_MODULE_42__["max"]; }); -/* harmony import */ var _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(444); +/* harmony import */ var _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__ = __webpack_require__(445); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "merge", function() { return _internal_operators_merge__WEBPACK_IMPORTED_MODULE_43__["merge"]; }); /* harmony import */ var _internal_operators_mergeAll__WEBPACK_IMPORTED_MODULE_44__ = __webpack_require__(81); @@ -51286,175 +51441,175 @@ __webpack_require__.r(__webpack_exports__); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "flatMap", function() { return _internal_operators_mergeMap__WEBPACK_IMPORTED_MODULE_45__["mergeMap"]; }); -/* harmony import */ var _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(445); +/* harmony import */ var _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__ = __webpack_require__(446); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeMapTo", function() { return _internal_operators_mergeMapTo__WEBPACK_IMPORTED_MODULE_46__["mergeMapTo"]; }); -/* harmony import */ var _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(446); +/* harmony import */ var _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__ = __webpack_require__(447); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "mergeScan", function() { return _internal_operators_mergeScan__WEBPACK_IMPORTED_MODULE_47__["mergeScan"]; }); -/* harmony import */ var _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(447); +/* harmony import */ var _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__ = __webpack_require__(448); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "min", function() { return _internal_operators_min__WEBPACK_IMPORTED_MODULE_48__["min"]; }); -/* harmony import */ var _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(448); +/* harmony import */ var _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__ = __webpack_require__(449); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "multicast", function() { return _internal_operators_multicast__WEBPACK_IMPORTED_MODULE_49__["multicast"]; }); /* harmony import */ var _internal_operators_observeOn__WEBPACK_IMPORTED_MODULE_50__ = __webpack_require__(41); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "observeOn", function() { return _internal_operators_observeOn__WEBPACK_IMPORTED_MODULE_50__["observeOn"]; }); -/* harmony import */ var _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(449); +/* harmony import */ var _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__ = __webpack_require__(450); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "onErrorResumeNext", function() { return _internal_operators_onErrorResumeNext__WEBPACK_IMPORTED_MODULE_51__["onErrorResumeNext"]; }); -/* harmony import */ var _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(450); +/* harmony import */ var _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__ = __webpack_require__(451); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pairwise", function() { return _internal_operators_pairwise__WEBPACK_IMPORTED_MODULE_52__["pairwise"]; }); -/* harmony import */ var _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(451); +/* harmony import */ var _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__ = __webpack_require__(452); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "partition", function() { return _internal_operators_partition__WEBPACK_IMPORTED_MODULE_53__["partition"]; }); -/* harmony import */ var _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(452); +/* harmony import */ var _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__ = __webpack_require__(453); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "pluck", function() { return _internal_operators_pluck__WEBPACK_IMPORTED_MODULE_54__["pluck"]; }); -/* harmony import */ var _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(453); +/* harmony import */ var _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__ = __webpack_require__(454); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publish", function() { return _internal_operators_publish__WEBPACK_IMPORTED_MODULE_55__["publish"]; }); -/* harmony import */ var _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(454); +/* harmony import */ var _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__ = __webpack_require__(455); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishBehavior", function() { return _internal_operators_publishBehavior__WEBPACK_IMPORTED_MODULE_56__["publishBehavior"]; }); -/* harmony import */ var _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(455); +/* harmony import */ var _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__ = __webpack_require__(456); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishLast", function() { return _internal_operators_publishLast__WEBPACK_IMPORTED_MODULE_57__["publishLast"]; }); -/* harmony import */ var _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(456); +/* harmony import */ var _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__ = __webpack_require__(457); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "publishReplay", function() { return _internal_operators_publishReplay__WEBPACK_IMPORTED_MODULE_58__["publishReplay"]; }); -/* harmony import */ var _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(457); +/* harmony import */ var _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__ = __webpack_require__(458); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "race", function() { return _internal_operators_race__WEBPACK_IMPORTED_MODULE_59__["race"]; }); -/* harmony import */ var _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(442); +/* harmony import */ var _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__ = __webpack_require__(443); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "reduce", function() { return _internal_operators_reduce__WEBPACK_IMPORTED_MODULE_60__["reduce"]; }); -/* harmony import */ var _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__ = __webpack_require__(458); +/* harmony import */ var _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__ = __webpack_require__(459); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "repeat", function() { return _internal_operators_repeat__WEBPACK_IMPORTED_MODULE_61__["repeat"]; }); -/* harmony import */ var _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__ = __webpack_require__(459); +/* harmony import */ var _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__ = __webpack_require__(460); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "repeatWhen", function() { return _internal_operators_repeatWhen__WEBPACK_IMPORTED_MODULE_62__["repeatWhen"]; }); -/* harmony import */ var _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__ = __webpack_require__(460); +/* harmony import */ var _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__ = __webpack_require__(461); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "retry", function() { return _internal_operators_retry__WEBPACK_IMPORTED_MODULE_63__["retry"]; }); -/* harmony import */ var _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__ = __webpack_require__(461); +/* harmony import */ var _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__ = __webpack_require__(462); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "retryWhen", function() { return _internal_operators_retryWhen__WEBPACK_IMPORTED_MODULE_64__["retryWhen"]; }); /* harmony import */ var _internal_operators_refCount__WEBPACK_IMPORTED_MODULE_65__ = __webpack_require__(30); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "refCount", function() { return _internal_operators_refCount__WEBPACK_IMPORTED_MODULE_65__["refCount"]; }); -/* harmony import */ var _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__ = __webpack_require__(462); +/* harmony import */ var _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__ = __webpack_require__(463); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sample", function() { return _internal_operators_sample__WEBPACK_IMPORTED_MODULE_66__["sample"]; }); -/* harmony import */ var _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__ = __webpack_require__(463); +/* harmony import */ var _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__ = __webpack_require__(464); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sampleTime", function() { return _internal_operators_sampleTime__WEBPACK_IMPORTED_MODULE_67__["sampleTime"]; }); -/* harmony import */ var _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__ = __webpack_require__(443); +/* harmony import */ var _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__ = __webpack_require__(444); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "scan", function() { return _internal_operators_scan__WEBPACK_IMPORTED_MODULE_68__["scan"]; }); -/* harmony import */ var _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__ = __webpack_require__(464); +/* harmony import */ var _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__ = __webpack_require__(465); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "sequenceEqual", function() { return _internal_operators_sequenceEqual__WEBPACK_IMPORTED_MODULE_69__["sequenceEqual"]; }); -/* harmony import */ var _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__ = __webpack_require__(465); +/* harmony import */ var _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__ = __webpack_require__(466); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "share", function() { return _internal_operators_share__WEBPACK_IMPORTED_MODULE_70__["share"]; }); -/* harmony import */ var _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__ = __webpack_require__(466); +/* harmony import */ var _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__ = __webpack_require__(467); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "shareReplay", function() { return _internal_operators_shareReplay__WEBPACK_IMPORTED_MODULE_71__["shareReplay"]; }); -/* harmony import */ var _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__ = __webpack_require__(467); +/* harmony import */ var _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__ = __webpack_require__(468); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "single", function() { return _internal_operators_single__WEBPACK_IMPORTED_MODULE_72__["single"]; }); -/* harmony import */ var _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__ = __webpack_require__(468); +/* harmony import */ var _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__ = __webpack_require__(469); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skip", function() { return _internal_operators_skip__WEBPACK_IMPORTED_MODULE_73__["skip"]; }); -/* harmony import */ var _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__ = __webpack_require__(469); +/* harmony import */ var _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__ = __webpack_require__(470); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipLast", function() { return _internal_operators_skipLast__WEBPACK_IMPORTED_MODULE_74__["skipLast"]; }); -/* harmony import */ var _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__ = __webpack_require__(470); +/* harmony import */ var _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__ = __webpack_require__(471); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipUntil", function() { return _internal_operators_skipUntil__WEBPACK_IMPORTED_MODULE_75__["skipUntil"]; }); -/* harmony import */ var _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__ = __webpack_require__(471); +/* harmony import */ var _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__ = __webpack_require__(472); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "skipWhile", function() { return _internal_operators_skipWhile__WEBPACK_IMPORTED_MODULE_76__["skipWhile"]; }); -/* harmony import */ var _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__ = __webpack_require__(472); +/* harmony import */ var _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__ = __webpack_require__(473); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "startWith", function() { return _internal_operators_startWith__WEBPACK_IMPORTED_MODULE_77__["startWith"]; }); -/* harmony import */ var _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__ = __webpack_require__(473); +/* harmony import */ var _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__ = __webpack_require__(474); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "subscribeOn", function() { return _internal_operators_subscribeOn__WEBPACK_IMPORTED_MODULE_78__["subscribeOn"]; }); -/* harmony import */ var _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__ = __webpack_require__(475); +/* harmony import */ var _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__ = __webpack_require__(476); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchAll", function() { return _internal_operators_switchAll__WEBPACK_IMPORTED_MODULE_79__["switchAll"]; }); -/* harmony import */ var _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__ = __webpack_require__(476); +/* harmony import */ var _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__ = __webpack_require__(477); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchMap", function() { return _internal_operators_switchMap__WEBPACK_IMPORTED_MODULE_80__["switchMap"]; }); -/* harmony import */ var _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__ = __webpack_require__(477); +/* harmony import */ var _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__ = __webpack_require__(478); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "switchMapTo", function() { return _internal_operators_switchMapTo__WEBPACK_IMPORTED_MODULE_81__["switchMapTo"]; }); -/* harmony import */ var _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__ = __webpack_require__(425); +/* harmony import */ var _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__ = __webpack_require__(426); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "take", function() { return _internal_operators_take__WEBPACK_IMPORTED_MODULE_82__["take"]; }); -/* harmony import */ var _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__ = __webpack_require__(438); +/* harmony import */ var _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__ = __webpack_require__(439); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeLast", function() { return _internal_operators_takeLast__WEBPACK_IMPORTED_MODULE_83__["takeLast"]; }); -/* harmony import */ var _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__ = __webpack_require__(478); +/* harmony import */ var _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__ = __webpack_require__(479); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeUntil", function() { return _internal_operators_takeUntil__WEBPACK_IMPORTED_MODULE_84__["takeUntil"]; }); -/* harmony import */ var _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__ = __webpack_require__(479); +/* harmony import */ var _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__ = __webpack_require__(480); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "takeWhile", function() { return _internal_operators_takeWhile__WEBPACK_IMPORTED_MODULE_85__["takeWhile"]; }); -/* harmony import */ var _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__ = __webpack_require__(480); +/* harmony import */ var _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__ = __webpack_require__(481); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "tap", function() { return _internal_operators_tap__WEBPACK_IMPORTED_MODULE_86__["tap"]; }); -/* harmony import */ var _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__ = __webpack_require__(481); +/* harmony import */ var _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__ = __webpack_require__(482); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throttle", function() { return _internal_operators_throttle__WEBPACK_IMPORTED_MODULE_87__["throttle"]; }); -/* harmony import */ var _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__ = __webpack_require__(482); +/* harmony import */ var _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__ = __webpack_require__(483); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throttleTime", function() { return _internal_operators_throttleTime__WEBPACK_IMPORTED_MODULE_88__["throttleTime"]; }); -/* harmony import */ var _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__ = __webpack_require__(424); +/* harmony import */ var _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__ = __webpack_require__(425); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "throwIfEmpty", function() { return _internal_operators_throwIfEmpty__WEBPACK_IMPORTED_MODULE_89__["throwIfEmpty"]; }); -/* harmony import */ var _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__ = __webpack_require__(483); +/* harmony import */ var _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__ = __webpack_require__(484); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeInterval", function() { return _internal_operators_timeInterval__WEBPACK_IMPORTED_MODULE_90__["timeInterval"]; }); -/* harmony import */ var _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__ = __webpack_require__(484); +/* harmony import */ var _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__ = __webpack_require__(485); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeout", function() { return _internal_operators_timeout__WEBPACK_IMPORTED_MODULE_91__["timeout"]; }); -/* harmony import */ var _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__ = __webpack_require__(485); +/* harmony import */ var _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__ = __webpack_require__(486); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timeoutWith", function() { return _internal_operators_timeoutWith__WEBPACK_IMPORTED_MODULE_92__["timeoutWith"]; }); -/* harmony import */ var _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__ = __webpack_require__(486); +/* harmony import */ var _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__ = __webpack_require__(487); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "timestamp", function() { return _internal_operators_timestamp__WEBPACK_IMPORTED_MODULE_93__["timestamp"]; }); -/* harmony import */ var _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__ = __webpack_require__(487); +/* harmony import */ var _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__ = __webpack_require__(488); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return _internal_operators_toArray__WEBPACK_IMPORTED_MODULE_94__["toArray"]; }); -/* harmony import */ var _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__ = __webpack_require__(488); +/* harmony import */ var _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__ = __webpack_require__(489); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "window", function() { return _internal_operators_window__WEBPACK_IMPORTED_MODULE_95__["window"]; }); -/* harmony import */ var _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__ = __webpack_require__(489); +/* harmony import */ var _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__ = __webpack_require__(490); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowCount", function() { return _internal_operators_windowCount__WEBPACK_IMPORTED_MODULE_96__["windowCount"]; }); -/* harmony import */ var _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__ = __webpack_require__(490); +/* harmony import */ var _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__ = __webpack_require__(491); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowTime", function() { return _internal_operators_windowTime__WEBPACK_IMPORTED_MODULE_97__["windowTime"]; }); -/* harmony import */ var _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__ = __webpack_require__(491); +/* harmony import */ var _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__ = __webpack_require__(492); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowToggle", function() { return _internal_operators_windowToggle__WEBPACK_IMPORTED_MODULE_98__["windowToggle"]; }); -/* harmony import */ var _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__ = __webpack_require__(492); +/* harmony import */ var _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__ = __webpack_require__(493); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "windowWhen", function() { return _internal_operators_windowWhen__WEBPACK_IMPORTED_MODULE_99__["windowWhen"]; }); -/* harmony import */ var _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__ = __webpack_require__(493); +/* harmony import */ var _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__ = __webpack_require__(494); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "withLatestFrom", function() { return _internal_operators_withLatestFrom__WEBPACK_IMPORTED_MODULE_100__["withLatestFrom"]; }); -/* harmony import */ var _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__ = __webpack_require__(494); +/* harmony import */ var _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__ = __webpack_require__(495); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zip", function() { return _internal_operators_zip__WEBPACK_IMPORTED_MODULE_101__["zip"]; }); -/* harmony import */ var _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__ = __webpack_require__(495); +/* harmony import */ var _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__ = __webpack_require__(496); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "zipAll", function() { return _internal_operators_zipAll__WEBPACK_IMPORTED_MODULE_102__["zipAll"]; }); /** PURE_IMPORTS_START PURE_IMPORTS_END */ @@ -51566,7 +51721,7 @@ __webpack_require__.r(__webpack_exports__); /***/ }), -/* 399 */ +/* 400 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51647,14 +51802,14 @@ var AuditSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 400 */ +/* 401 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "auditTime", function() { return auditTime; }); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); -/* harmony import */ var _audit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(399); +/* harmony import */ var _audit__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(400); /* harmony import */ var _observable_timer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(107); /** PURE_IMPORTS_START _scheduler_async,_audit,_observable_timer PURE_IMPORTS_END */ @@ -51670,7 +51825,7 @@ function auditTime(duration, scheduler) { /***/ }), -/* 401 */ +/* 402 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51719,7 +51874,7 @@ var BufferSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 402 */ +/* 403 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51820,7 +51975,7 @@ var BufferSkipCountSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 403 */ +/* 404 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -51981,7 +52136,7 @@ function dispatchBufferClose(arg) { /***/ }), -/* 404 */ +/* 405 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52101,7 +52256,7 @@ var BufferToggleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 405 */ +/* 406 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52196,7 +52351,7 @@ var BufferWhenSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 406 */ +/* 407 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52260,7 +52415,7 @@ var CatchSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 407 */ +/* 408 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52276,7 +52431,7 @@ function combineAll(project) { /***/ }), -/* 408 */ +/* 409 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52308,7 +52463,7 @@ function combineLatest() { /***/ }), -/* 409 */ +/* 410 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52328,7 +52483,7 @@ function concat() { /***/ }), -/* 410 */ +/* 411 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52344,13 +52499,13 @@ function concatMap(project, resultSelector) { /***/ }), -/* 411 */ +/* 412 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "concatMapTo", function() { return concatMapTo; }); -/* harmony import */ var _concatMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(410); +/* harmony import */ var _concatMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(411); /** PURE_IMPORTS_START _concatMap PURE_IMPORTS_END */ function concatMapTo(innerObservable, resultSelector) { @@ -52360,7 +52515,7 @@ function concatMapTo(innerObservable, resultSelector) { /***/ }), -/* 412 */ +/* 413 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52425,7 +52580,7 @@ var CountSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 413 */ +/* 414 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52513,7 +52668,7 @@ var DebounceSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 414 */ +/* 415 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52589,7 +52744,7 @@ function dispatchNext(subscriber) { /***/ }), -/* 415 */ +/* 416 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52639,7 +52794,7 @@ var DefaultIfEmptySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 416 */ +/* 417 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52647,7 +52802,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "delay", function() { return delay; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(55); -/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(417); +/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(418); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(11); /* harmony import */ var _Notification__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(42); /** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_Subscriber,_Notification PURE_IMPORTS_END */ @@ -52746,7 +52901,7 @@ var DelayMessage = /*@__PURE__*/ (function () { /***/ }), -/* 417 */ +/* 418 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52760,7 +52915,7 @@ function isDate(value) { /***/ }), -/* 418 */ +/* 419 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52906,7 +53061,7 @@ var SubscriptionDelaySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 419 */ +/* 420 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -52944,7 +53099,7 @@ var DeMaterializeSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 420 */ +/* 421 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53022,7 +53177,7 @@ var DistinctSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 421 */ +/* 422 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53093,13 +53248,13 @@ var DistinctUntilChangedSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 422 */ +/* 423 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "distinctUntilKeyChanged", function() { return distinctUntilKeyChanged; }); -/* harmony import */ var _distinctUntilChanged__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(421); +/* harmony import */ var _distinctUntilChanged__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(422); /** PURE_IMPORTS_START _distinctUntilChanged PURE_IMPORTS_END */ function distinctUntilKeyChanged(key, compare) { @@ -53109,7 +53264,7 @@ function distinctUntilKeyChanged(key, compare) { /***/ }), -/* 423 */ +/* 424 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53117,9 +53272,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "elementAt", function() { return elementAt; }); /* harmony import */ var _util_ArgumentOutOfRangeError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(62); /* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(104); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(424); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(415); -/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(425); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(425); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(416); +/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(426); /** PURE_IMPORTS_START _util_ArgumentOutOfRangeError,_filter,_throwIfEmpty,_defaultIfEmpty,_take PURE_IMPORTS_END */ @@ -53141,7 +53296,7 @@ function elementAt(index, defaultValue) { /***/ }), -/* 424 */ +/* 425 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53207,7 +53362,7 @@ function defaultErrorFactory() { /***/ }), -/* 425 */ +/* 426 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53269,7 +53424,7 @@ var TakeSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 426 */ +/* 427 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53291,7 +53446,7 @@ function endWith() { /***/ }), -/* 427 */ +/* 428 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53353,7 +53508,7 @@ var EverySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 428 */ +/* 429 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53410,7 +53565,7 @@ var SwitchFirstSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 429 */ +/* 430 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53510,7 +53665,7 @@ var ExhaustMapSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 430 */ +/* 431 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53629,7 +53784,7 @@ var ExpandSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 431 */ +/* 432 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53667,7 +53822,7 @@ var FinallySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 432 */ +/* 433 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53739,13 +53894,13 @@ var FindValueSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 433 */ +/* 434 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "findIndex", function() { return findIndex; }); -/* harmony import */ var _operators_find__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(432); +/* harmony import */ var _operators_find__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(433); /** PURE_IMPORTS_START _operators_find PURE_IMPORTS_END */ function findIndex(predicate, thisArg) { @@ -53755,7 +53910,7 @@ function findIndex(predicate, thisArg) { /***/ }), -/* 434 */ +/* 435 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53763,9 +53918,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "first", function() { return first; }); /* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63); /* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(104); -/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(425); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(415); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(424); +/* harmony import */ var _take__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(426); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(416); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(425); /* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(25); /** PURE_IMPORTS_START _util_EmptyError,_filter,_take,_defaultIfEmpty,_throwIfEmpty,_util_identity PURE_IMPORTS_END */ @@ -53782,7 +53937,7 @@ function first(predicate, defaultValue) { /***/ }), -/* 435 */ +/* 436 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53819,7 +53974,7 @@ var IgnoreElementsSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 436 */ +/* 437 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53863,7 +54018,7 @@ var IsEmptySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 437 */ +/* 438 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53871,9 +54026,9 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "last", function() { return last; }); /* harmony import */ var _util_EmptyError__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(63); /* harmony import */ var _filter__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(104); -/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(438); -/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(424); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(415); +/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(439); +/* harmony import */ var _throwIfEmpty__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(425); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(416); /* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(25); /** PURE_IMPORTS_START _util_EmptyError,_filter,_takeLast,_throwIfEmpty,_defaultIfEmpty,_util_identity PURE_IMPORTS_END */ @@ -53890,7 +54045,7 @@ function last(predicate, defaultValue) { /***/ }), -/* 438 */ +/* 439 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -53967,7 +54122,7 @@ var TakeLastSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 439 */ +/* 440 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54006,7 +54161,7 @@ var MapToSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 440 */ +/* 441 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54056,13 +54211,13 @@ var MaterializeSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 441 */ +/* 442 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "max", function() { return max; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(442); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(443); /** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ function max(comparer) { @@ -54075,15 +54230,15 @@ function max(comparer) { /***/ }), -/* 442 */ +/* 443 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "reduce", function() { return reduce; }); -/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(443); -/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(438); -/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(415); +/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(444); +/* harmony import */ var _takeLast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(439); +/* harmony import */ var _defaultIfEmpty__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(416); /* harmony import */ var _util_pipe__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(24); /** PURE_IMPORTS_START _scan,_takeLast,_defaultIfEmpty,_util_pipe PURE_IMPORTS_END */ @@ -54104,7 +54259,7 @@ function reduce(accumulator, seed) { /***/ }), -/* 443 */ +/* 444 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54186,7 +54341,7 @@ var ScanSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 444 */ +/* 445 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54206,7 +54361,7 @@ function merge() { /***/ }), -/* 445 */ +/* 446 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54231,7 +54386,7 @@ function mergeMapTo(innerObservable, resultSelector, concurrent) { /***/ }), -/* 446 */ +/* 447 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54346,13 +54501,13 @@ var MergeScanSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 447 */ +/* 448 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "min", function() { return min; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(442); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(443); /** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ function min(comparer) { @@ -54365,7 +54520,7 @@ function min(comparer) { /***/ }), -/* 448 */ +/* 449 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54414,7 +54569,7 @@ var MulticastOperator = /*@__PURE__*/ (function () { /***/ }), -/* 449 */ +/* 450 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54508,7 +54663,7 @@ var OnErrorResumeNextSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 450 */ +/* 451 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54556,7 +54711,7 @@ var PairwiseSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 451 */ +/* 452 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54579,7 +54734,7 @@ function partition(predicate, thisArg) { /***/ }), -/* 452 */ +/* 453 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54619,14 +54774,14 @@ function plucker(props, length) { /***/ }), -/* 453 */ +/* 454 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publish", function() { return publish; }); /* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(27); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(448); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(449); /** PURE_IMPORTS_START _Subject,_multicast PURE_IMPORTS_END */ @@ -54639,14 +54794,14 @@ function publish(selector) { /***/ }), -/* 454 */ +/* 455 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishBehavior", function() { return publishBehavior; }); /* harmony import */ var _BehaviorSubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(32); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(448); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(449); /** PURE_IMPORTS_START _BehaviorSubject,_multicast PURE_IMPORTS_END */ @@ -54657,14 +54812,14 @@ function publishBehavior(value) { /***/ }), -/* 455 */ +/* 456 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishLast", function() { return publishLast; }); /* harmony import */ var _AsyncSubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(50); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(448); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(449); /** PURE_IMPORTS_START _AsyncSubject,_multicast PURE_IMPORTS_END */ @@ -54675,14 +54830,14 @@ function publishLast() { /***/ }), -/* 456 */ +/* 457 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "publishReplay", function() { return publishReplay; }); /* harmony import */ var _ReplaySubject__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(33); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(448); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(449); /** PURE_IMPORTS_START _ReplaySubject,_multicast PURE_IMPORTS_END */ @@ -54698,7 +54853,7 @@ function publishReplay(bufferSize, windowTime, selectorOrScheduler, scheduler) { /***/ }), -/* 457 */ +/* 458 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54725,7 +54880,7 @@ function race() { /***/ }), -/* 458 */ +/* 459 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54790,7 +54945,7 @@ var RepeatSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 459 */ +/* 460 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54886,7 +55041,7 @@ var RepeatWhenSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 460 */ +/* 461 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -54939,7 +55094,7 @@ var RetrySubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 461 */ +/* 462 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55027,7 +55182,7 @@ var RetryWhenSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 462 */ +/* 463 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55084,7 +55239,7 @@ var SampleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 463 */ +/* 464 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55144,7 +55299,7 @@ function dispatchNotification(state) { /***/ }), -/* 464 */ +/* 465 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55267,13 +55422,13 @@ var SequenceEqualCompareToSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 465 */ +/* 466 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "share", function() { return share; }); -/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(448); +/* harmony import */ var _multicast__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(449); /* harmony import */ var _refCount__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(30); /* harmony import */ var _Subject__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(27); /** PURE_IMPORTS_START _multicast,_refCount,_Subject PURE_IMPORTS_END */ @@ -55290,7 +55445,7 @@ function share() { /***/ }), -/* 466 */ +/* 467 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55355,7 +55510,7 @@ function shareReplayOperator(_a) { /***/ }), -/* 467 */ +/* 468 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55435,7 +55590,7 @@ var SingleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 468 */ +/* 469 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55477,7 +55632,7 @@ var SkipSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 469 */ +/* 470 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55539,7 +55694,7 @@ var SkipLastSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 470 */ +/* 471 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55600,7 +55755,7 @@ var SkipUntilSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 471 */ +/* 472 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55656,7 +55811,7 @@ var SkipWhileSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 472 */ +/* 473 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55685,13 +55840,13 @@ function startWith() { /***/ }), -/* 473 */ +/* 474 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "subscribeOn", function() { return subscribeOn; }); -/* harmony import */ var _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(474); +/* harmony import */ var _observable_SubscribeOnObservable__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(475); /** PURE_IMPORTS_START _observable_SubscribeOnObservable PURE_IMPORTS_END */ function subscribeOn(scheduler, delay) { @@ -55716,7 +55871,7 @@ var SubscribeOnOperator = /*@__PURE__*/ (function () { /***/ }), -/* 474 */ +/* 475 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55780,13 +55935,13 @@ var SubscribeOnObservable = /*@__PURE__*/ (function (_super) { /***/ }), -/* 475 */ +/* 476 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchAll", function() { return switchAll; }); -/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(476); +/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(477); /* harmony import */ var _util_identity__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(25); /** PURE_IMPORTS_START _switchMap,_util_identity PURE_IMPORTS_END */ @@ -55798,7 +55953,7 @@ function switchAll() { /***/ }), -/* 476 */ +/* 477 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55892,13 +56047,13 @@ var SwitchMapSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 477 */ +/* 478 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "switchMapTo", function() { return switchMapTo; }); -/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(476); +/* harmony import */ var _switchMap__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(477); /** PURE_IMPORTS_START _switchMap PURE_IMPORTS_END */ function switchMapTo(innerObservable, resultSelector) { @@ -55908,7 +56063,7 @@ function switchMapTo(innerObservable, resultSelector) { /***/ }), -/* 478 */ +/* 479 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -55958,7 +56113,7 @@ var TakeUntilSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 479 */ +/* 480 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56026,7 +56181,7 @@ var TakeWhileSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 480 */ +/* 481 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56114,7 +56269,7 @@ var TapSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 481 */ +/* 482 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56218,7 +56373,7 @@ var ThrottleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 482 */ +/* 483 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56227,7 +56382,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _Subscriber__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(11); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(55); -/* harmony import */ var _throttle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(481); +/* harmony import */ var _throttle__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(482); /** PURE_IMPORTS_START tslib,_Subscriber,_scheduler_async,_throttle PURE_IMPORTS_END */ @@ -56316,7 +56471,7 @@ function dispatchNext(arg) { /***/ }), -/* 483 */ +/* 484 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56324,7 +56479,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeInterval", function() { return timeInterval; }); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TimeInterval", function() { return TimeInterval; }); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); -/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(443); +/* harmony import */ var _scan__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(444); /* harmony import */ var _observable_defer__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(90); /* harmony import */ var _map__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(66); /** PURE_IMPORTS_START _scheduler_async,_scan,_observable_defer,_map PURE_IMPORTS_END */ @@ -56360,7 +56515,7 @@ var TimeInterval = /*@__PURE__*/ (function () { /***/ }), -/* 484 */ +/* 485 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56368,7 +56523,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeout", function() { return timeout; }); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(55); /* harmony import */ var _util_TimeoutError__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(64); -/* harmony import */ var _timeoutWith__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(485); +/* harmony import */ var _timeoutWith__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(486); /* harmony import */ var _observable_throwError__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(49); /** PURE_IMPORTS_START _scheduler_async,_util_TimeoutError,_timeoutWith,_observable_throwError PURE_IMPORTS_END */ @@ -56385,7 +56540,7 @@ function timeout(due, scheduler) { /***/ }), -/* 485 */ +/* 486 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56393,7 +56548,7 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "timeoutWith", function() { return timeoutWith; }); /* harmony import */ var tslib__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(12); /* harmony import */ var _scheduler_async__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(55); -/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(417); +/* harmony import */ var _util_isDate__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(418); /* harmony import */ var _OuterSubscriber__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(69); /* harmony import */ var _util_subscribeToResult__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(70); /** PURE_IMPORTS_START tslib,_scheduler_async,_util_isDate,_OuterSubscriber,_util_subscribeToResult PURE_IMPORTS_END */ @@ -56467,7 +56622,7 @@ var TimeoutWithSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 486 */ +/* 487 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56497,13 +56652,13 @@ var Timestamp = /*@__PURE__*/ (function () { /***/ }), -/* 487 */ +/* 488 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "toArray", function() { return toArray; }); -/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(442); +/* harmony import */ var _reduce__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(443); /** PURE_IMPORTS_START _reduce PURE_IMPORTS_END */ function toArrayReducer(arr, item, index) { @@ -56520,7 +56675,7 @@ function toArray() { /***/ }), -/* 488 */ +/* 489 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56600,7 +56755,7 @@ var WindowSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 489 */ +/* 490 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56690,7 +56845,7 @@ var WindowCountSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 490 */ +/* 491 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -56860,7 +57015,7 @@ function dispatchWindowClose(state) { /***/ }), -/* 491 */ +/* 492 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57003,7 +57158,7 @@ var WindowToggleSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 492 */ +/* 493 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57100,7 +57255,7 @@ var WindowSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 493 */ +/* 494 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57195,7 +57350,7 @@ var WithLatestFromSubscriber = /*@__PURE__*/ (function (_super) { /***/ }), -/* 494 */ +/* 495 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57217,7 +57372,7 @@ function zip() { /***/ }), -/* 495 */ +/* 496 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57233,7 +57388,7 @@ function zipAll(project) { /***/ }), -/* 496 */ +/* 497 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57242,8 +57397,8 @@ __webpack_require__.r(__webpack_exports__); /* harmony import */ var _utils_errors__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(162); /* harmony import */ var _utils_log__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(143); /* harmony import */ var _utils_projects__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(145); -/* harmony import */ var _utils_projects_tree__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(497); -/* harmony import */ var _utils_kibana__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(498); +/* harmony import */ var _utils_projects_tree__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(498); +/* harmony import */ var _utils_kibana__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(499); 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(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } @@ -57325,7 +57480,7 @@ function toArray(value) { } /***/ }), -/* 497 */ +/* 498 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57478,7 +57633,7 @@ function addProjectToTree(tree, pathParts, project) { } /***/ }), -/* 498 */ +/* 499 */ /***/ (function(module, __webpack_exports__, __webpack_require__) { "use strict"; @@ -57486,12 +57641,13 @@ __webpack_require__.r(__webpack_exports__); /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Kibana", function() { return Kibana; }); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(4); /* 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__(499); +/* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(500); /* harmony import */ var multimatch__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(multimatch__WEBPACK_IMPORTED_MODULE_1__); -/* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(369); +/* harmony import */ var is_path_inside__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(370); /* 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__(145); -/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(280); +/* harmony import */ var _yarn_lock__WEBPACK_IMPORTED_MODULE_3__ = __webpack_require__(283); +/* harmony import */ var _projects__WEBPACK_IMPORTED_MODULE_4__ = __webpack_require__(145); +/* harmony import */ var _config__WEBPACK_IMPORTED_MODULE_5__ = __webpack_require__(280); 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(Object(source), true).forEach(function (key) { _defineProperty(target, key, source[key]); }); } else if (Object.getOwnPropertyDescriptors) { Object.defineProperties(target, Object.getOwnPropertyDescriptors(source)); } else { ownKeys(Object(source)).forEach(function (key) { Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key)); }); } } return target; } @@ -57521,6 +57677,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 @@ -57535,7 +57692,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_3__["getProjects"])(rootPath, Object(_config__WEBPACK_IMPORTED_MODULE_4__["getProjectPaths"])({ + return new Kibana(await Object(_projects__WEBPACK_IMPORTED_MODULE_4__["getProjects"])(rootPath, Object(_config__WEBPACK_IMPORTED_MODULE_5__["getProjectPaths"])({ rootPath }))); } @@ -57594,7 +57751,7 @@ class Kibana { getProjectAndDeps(name) { const project = this.getProject(name); - return Object(_projects__WEBPACK_IMPORTED_MODULE_3__["includeTransitiveProjects"])([project], this.allWorkspaceProjects); + return Object(_projects__WEBPACK_IMPORTED_MODULE_4__["includeTransitiveProjects"])([project], this.allWorkspaceProjects); } /** filter the projects to just those matching certain paths/include/exclude tags */ @@ -57603,7 +57760,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_4__["getProjectPaths"])(_objectSpread(_objectSpread({}, options), {}, { + const filteredPkgJsonGlobs = Object(_config__WEBPACK_IMPORTED_MODULE_5__["getProjectPaths"])(_objectSpread(_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); @@ -57629,18 +57786,38 @@ class Kibana { return !this.isPartOfRepo(project); } + resolveAllProductionDependencies(yarnLock, log) { + const kibanaDeps = Object(_yarn_lock__WEBPACK_IMPORTED_MODULE_3__["resolveDepsForProject"])({ + project: this.kibanaProject, + yarnLock, + kbn: this, + includeDependentProject: true, + productionDepsOnly: true, + log + }); + const xpackDeps = Object(_yarn_lock__WEBPACK_IMPORTED_MODULE_3__["resolveDepsForProject"])({ + project: this.getProject('x-pack'), + yarnLock, + kbn: this, + includeDependentProject: true, + productionDepsOnly: true, + log + }); + return new Map([...kibanaDeps.entries(), ...xpackDeps.entries()]); + } + } /***/ }), -/* 499 */ +/* 500 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const minimatch = __webpack_require__(149); -const arrayUnion = __webpack_require__(500); -const arrayDiffer = __webpack_require__(501); -const arrify = __webpack_require__(502); +const arrayUnion = __webpack_require__(501); +const arrayDiffer = __webpack_require__(502); +const arrify = __webpack_require__(503); module.exports = (list, patterns, options = {}) => { list = arrify(list); @@ -57664,7 +57841,7 @@ module.exports = (list, patterns, options = {}) => { /***/ }), -/* 500 */ +/* 501 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57676,7 +57853,7 @@ module.exports = (...arguments_) => { /***/ }), -/* 501 */ +/* 502 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57691,7 +57868,7 @@ module.exports = arrayDiffer; /***/ }), -/* 502 */ +/* 503 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57721,12 +57898,12 @@ module.exports = arrify; /***/ }), -/* 503 */ +/* 504 */ /***/ (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__(504); +/* harmony import */ var _build_production_projects__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(505); /* harmony reexport (safe) */ __webpack_require__.d(__webpack_exports__, "buildProductionProjects", function() { return _build_production_projects__WEBPACK_IMPORTED_MODULE_0__["buildProductionProjects"]; }); /* @@ -57750,15 +57927,15 @@ __webpack_require__.r(__webpack_exports__); /***/ }), -/* 504 */ +/* 505 */ /***/ (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__(505); +/* harmony import */ var cpy__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(506); /* 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__(288); +/* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(289); /* harmony import */ var del__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(del__WEBPACK_IMPORTED_MODULE_1__); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(4); /* harmony import */ var path__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(path__WEBPACK_IMPORTED_MODULE_2__); @@ -57898,7 +58075,7 @@ async function copyToBuild(project, kibanaRoot, buildRoot) { } /***/ }), -/* 505 */ +/* 506 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -57906,13 +58083,13 @@ async function copyToBuild(project, kibanaRoot, buildRoot) { const EventEmitter = __webpack_require__(155); const path = __webpack_require__(4); const os = __webpack_require__(120); -const pAll = __webpack_require__(506); -const arrify = __webpack_require__(508); -const globby = __webpack_require__(509); -const isGlob = __webpack_require__(719); -const cpFile = __webpack_require__(720); -const junk = __webpack_require__(732); -const CpyError = __webpack_require__(733); +const pAll = __webpack_require__(507); +const arrify = __webpack_require__(509); +const globby = __webpack_require__(510); +const isGlob = __webpack_require__(720); +const cpFile = __webpack_require__(721); +const junk = __webpack_require__(733); +const CpyError = __webpack_require__(734); const defaultOptions = { ignoreJunk: true @@ -58031,12 +58208,12 @@ module.exports = (source, destination, { /***/ }), -/* 506 */ +/* 507 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pMap = __webpack_require__(507); +const pMap = __webpack_require__(508); module.exports = (iterable, options) => pMap(iterable, element => element(), options); // TODO: Remove this for the next major release @@ -58044,7 +58221,7 @@ module.exports.default = module.exports; /***/ }), -/* 507 */ +/* 508 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58123,7 +58300,7 @@ module.exports.default = pMap; /***/ }), -/* 508 */ +/* 509 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58153,17 +58330,17 @@ module.exports = arrify; /***/ }), -/* 509 */ +/* 510 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(133); -const arrayUnion = __webpack_require__(510); +const arrayUnion = __webpack_require__(511); const glob = __webpack_require__(146); -const fastGlob = __webpack_require__(512); -const dirGlob = __webpack_require__(712); -const gitignore = __webpack_require__(715); +const fastGlob = __webpack_require__(513); +const dirGlob = __webpack_require__(713); +const gitignore = __webpack_require__(716); const DEFAULT_FILTER = () => false; @@ -58308,12 +58485,12 @@ module.exports.gitignore = gitignore; /***/ }), -/* 510 */ +/* 511 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var arrayUniq = __webpack_require__(511); +var arrayUniq = __webpack_require__(512); module.exports = function () { return arrayUniq([].concat.apply([], arguments)); @@ -58321,7 +58498,7 @@ module.exports = function () { /***/ }), -/* 511 */ +/* 512 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58390,10 +58567,10 @@ if ('Set' in global) { /***/ }), -/* 512 */ +/* 513 */ /***/ (function(module, exports, __webpack_require__) { -const pkg = __webpack_require__(513); +const pkg = __webpack_require__(514); module.exports = pkg.async; module.exports.default = pkg.async; @@ -58406,19 +58583,19 @@ module.exports.generateTasks = pkg.generateTasks; /***/ }), -/* 513 */ +/* 514 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var optionsManager = __webpack_require__(514); -var taskManager = __webpack_require__(515); -var reader_async_1 = __webpack_require__(683); -var reader_stream_1 = __webpack_require__(707); -var reader_sync_1 = __webpack_require__(708); -var arrayUtils = __webpack_require__(710); -var streamUtils = __webpack_require__(711); +var optionsManager = __webpack_require__(515); +var taskManager = __webpack_require__(516); +var reader_async_1 = __webpack_require__(684); +var reader_stream_1 = __webpack_require__(708); +var reader_sync_1 = __webpack_require__(709); +var arrayUtils = __webpack_require__(711); +var streamUtils = __webpack_require__(712); /** * Synchronous API. */ @@ -58484,7 +58661,7 @@ function isString(source) { /***/ }), -/* 514 */ +/* 515 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58522,13 +58699,13 @@ exports.prepare = prepare; /***/ }), -/* 515 */ +/* 516 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var patternUtils = __webpack_require__(516); +var patternUtils = __webpack_require__(517); /** * Generate tasks based on parent directory of each pattern. */ @@ -58619,16 +58796,16 @@ exports.convertPatternGroupToTask = convertPatternGroupToTask; /***/ }), -/* 516 */ +/* 517 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path = __webpack_require__(4); -var globParent = __webpack_require__(517); -var isGlob = __webpack_require__(520); -var micromatch = __webpack_require__(521); +var globParent = __webpack_require__(518); +var isGlob = __webpack_require__(521); +var micromatch = __webpack_require__(522); var GLOBSTAR = '**'; /** * Return true for static pattern. @@ -58774,15 +58951,15 @@ exports.matchAny = matchAny; /***/ }), -/* 517 */ +/* 518 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var path = __webpack_require__(4); -var isglob = __webpack_require__(518); -var pathDirname = __webpack_require__(519); +var isglob = __webpack_require__(519); +var pathDirname = __webpack_require__(520); var isWin32 = __webpack_require__(120).platform() === 'win32'; module.exports = function globParent(str) { @@ -58805,7 +58982,7 @@ module.exports = function globParent(str) { /***/ }), -/* 518 */ +/* 519 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -58815,7 +58992,7 @@ module.exports = function globParent(str) { * Licensed under the MIT License. */ -var isExtglob = __webpack_require__(302); +var isExtglob = __webpack_require__(303); module.exports = function isGlob(str) { if (typeof str !== 'string' || str === '') { @@ -58836,7 +59013,7 @@ module.exports = function isGlob(str) { /***/ }), -/* 519 */ +/* 520 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -58986,7 +59163,7 @@ module.exports.win32 = win32; /***/ }), -/* 520 */ +/* 521 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -58996,7 +59173,7 @@ module.exports.win32 = win32; * Released under the MIT License. */ -var isExtglob = __webpack_require__(302); +var isExtglob = __webpack_require__(303); var chars = { '{': '}', '(': ')', '[': ']'}; module.exports = function isGlob(str, options) { @@ -59038,7 +59215,7 @@ module.exports = function isGlob(str, options) { /***/ }), -/* 521 */ +/* 522 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59049,18 +59226,18 @@ module.exports = function isGlob(str, options) { */ var util = __webpack_require__(111); -var braces = __webpack_require__(522); -var toRegex = __webpack_require__(635); -var extend = __webpack_require__(643); +var braces = __webpack_require__(523); +var toRegex = __webpack_require__(636); +var extend = __webpack_require__(644); /** * Local dependencies */ -var compilers = __webpack_require__(646); -var parsers = __webpack_require__(679); -var cache = __webpack_require__(680); -var utils = __webpack_require__(681); +var compilers = __webpack_require__(647); +var parsers = __webpack_require__(680); +var cache = __webpack_require__(681); +var utils = __webpack_require__(682); var MAX_LENGTH = 1024 * 64; /** @@ -59922,7 +60099,7 @@ module.exports = micromatch; /***/ }), -/* 522 */ +/* 523 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -59932,18 +60109,18 @@ module.exports = micromatch; * Module dependencies */ -var toRegex = __webpack_require__(523); -var unique = __webpack_require__(537); -var extend = __webpack_require__(532); +var toRegex = __webpack_require__(524); +var unique = __webpack_require__(538); +var extend = __webpack_require__(533); /** * Local dependencies */ -var compilers = __webpack_require__(538); -var parsers = __webpack_require__(555); -var Braces = __webpack_require__(565); -var utils = __webpack_require__(539); +var compilers = __webpack_require__(539); +var parsers = __webpack_require__(556); +var Braces = __webpack_require__(566); +var utils = __webpack_require__(540); var MAX_LENGTH = 1024 * 64; var cache = {}; @@ -60247,15 +60424,15 @@ module.exports = braces; /***/ }), -/* 523 */ +/* 524 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(524); -var extend = __webpack_require__(532); -var not = __webpack_require__(534); +var define = __webpack_require__(525); +var extend = __webpack_require__(533); +var not = __webpack_require__(535); var MAX_LENGTH = 1024 * 64; /** @@ -60402,7 +60579,7 @@ module.exports.makeRe = makeRe; /***/ }), -/* 524 */ +/* 525 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60415,7 +60592,7 @@ module.exports.makeRe = makeRe; -var isDescriptor = __webpack_require__(525); +var isDescriptor = __webpack_require__(526); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -60440,7 +60617,7 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 525 */ +/* 526 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60453,9 +60630,9 @@ module.exports = function defineProperty(obj, prop, val) { -var typeOf = __webpack_require__(526); -var isAccessor = __webpack_require__(527); -var isData = __webpack_require__(530); +var typeOf = __webpack_require__(527); +var isAccessor = __webpack_require__(528); +var isData = __webpack_require__(531); module.exports = function isDescriptor(obj, key) { if (typeOf(obj) !== 'object') { @@ -60469,7 +60646,7 @@ module.exports = function isDescriptor(obj, key) { /***/ }), -/* 526 */ +/* 527 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -60622,7 +60799,7 @@ function isBuffer(val) { /***/ }), -/* 527 */ +/* 528 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60635,7 +60812,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(528); +var typeOf = __webpack_require__(529); // accessor descriptor properties var accessor = { @@ -60698,10 +60875,10 @@ module.exports = isAccessorDescriptor; /***/ }), -/* 528 */ +/* 529 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(529); +var isBuffer = __webpack_require__(530); var toString = Object.prototype.toString; /** @@ -60820,7 +60997,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 529 */ +/* 530 */ /***/ (function(module, exports) { /*! @@ -60847,7 +61024,7 @@ function isSlowBuffer (obj) { /***/ }), -/* 530 */ +/* 531 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -60860,7 +61037,7 @@ function isSlowBuffer (obj) { -var typeOf = __webpack_require__(531); +var typeOf = __webpack_require__(532); // data descriptor properties var data = { @@ -60909,10 +61086,10 @@ module.exports = isDataDescriptor; /***/ }), -/* 531 */ +/* 532 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(529); +var isBuffer = __webpack_require__(530); var toString = Object.prototype.toString; /** @@ -61031,13 +61208,13 @@ module.exports = function kindOf(val) { /***/ }), -/* 532 */ +/* 533 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(533); +var isObject = __webpack_require__(534); module.exports = function extend(o/*, objects*/) { if (!isObject(o)) { o = {}; } @@ -61071,7 +61248,7 @@ function hasOwn(obj, key) { /***/ }), -/* 533 */ +/* 534 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61091,13 +61268,13 @@ module.exports = function isExtendable(val) { /***/ }), -/* 534 */ +/* 535 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(535); +var extend = __webpack_require__(536); /** * The main export is a function that takes a `pattern` string and an `options` object. @@ -61164,13 +61341,13 @@ module.exports = toRegex; /***/ }), -/* 535 */ +/* 536 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(536); +var isObject = __webpack_require__(537); module.exports = function extend(o/*, objects*/) { if (!isObject(o)) { o = {}; } @@ -61204,7 +61381,7 @@ function hasOwn(obj, key) { /***/ }), -/* 536 */ +/* 537 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61224,7 +61401,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 537 */ +/* 538 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61274,13 +61451,13 @@ module.exports.immutable = function uniqueImmutable(arr) { /***/ }), -/* 538 */ +/* 539 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(539); +var utils = __webpack_require__(540); module.exports = function(braces, options) { braces.compiler @@ -61563,25 +61740,25 @@ function hasQueue(node) { /***/ }), -/* 539 */ +/* 540 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var splitString = __webpack_require__(540); +var splitString = __webpack_require__(541); var utils = module.exports; /** * Module dependencies */ -utils.extend = __webpack_require__(532); -utils.flatten = __webpack_require__(546); -utils.isObject = __webpack_require__(544); -utils.fillRange = __webpack_require__(547); -utils.repeat = __webpack_require__(554); -utils.unique = __webpack_require__(537); +utils.extend = __webpack_require__(533); +utils.flatten = __webpack_require__(547); +utils.isObject = __webpack_require__(545); +utils.fillRange = __webpack_require__(548); +utils.repeat = __webpack_require__(555); +utils.unique = __webpack_require__(538); utils.define = function(obj, key, val) { Object.defineProperty(obj, key, { @@ -61913,7 +62090,7 @@ utils.escapeRegex = function(str) { /***/ }), -/* 540 */ +/* 541 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -61926,7 +62103,7 @@ utils.escapeRegex = function(str) { -var extend = __webpack_require__(541); +var extend = __webpack_require__(542); module.exports = function(str, options, fn) { if (typeof str !== 'string') { @@ -62091,14 +62268,14 @@ function keepEscaping(opts, str, idx) { /***/ }), -/* 541 */ +/* 542 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(542); -var assignSymbols = __webpack_require__(545); +var isExtendable = __webpack_require__(543); +var assignSymbols = __webpack_require__(546); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -62158,7 +62335,7 @@ function isEnum(obj, key) { /***/ }), -/* 542 */ +/* 543 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62171,7 +62348,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(543); +var isPlainObject = __webpack_require__(544); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -62179,7 +62356,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 543 */ +/* 544 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62192,7 +62369,7 @@ module.exports = function isExtendable(val) { -var isObject = __webpack_require__(544); +var isObject = __webpack_require__(545); function isObjectObject(o) { return isObject(o) === true @@ -62223,7 +62400,7 @@ module.exports = function isPlainObject(o) { /***/ }), -/* 544 */ +/* 545 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62242,7 +62419,7 @@ module.exports = function isObject(val) { /***/ }), -/* 545 */ +/* 546 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62289,7 +62466,7 @@ module.exports = function(receiver, objects) { /***/ }), -/* 546 */ +/* 547 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62318,7 +62495,7 @@ function flat(arr, res) { /***/ }), -/* 547 */ +/* 548 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62332,10 +62509,10 @@ function flat(arr, res) { var util = __webpack_require__(111); -var isNumber = __webpack_require__(548); -var extend = __webpack_require__(550); -var repeat = __webpack_require__(552); -var toRegex = __webpack_require__(553); +var isNumber = __webpack_require__(549); +var extend = __webpack_require__(551); +var repeat = __webpack_require__(553); +var toRegex = __webpack_require__(554); /** * Return a range of numbers or letters. @@ -62533,7 +62710,7 @@ module.exports = fillRange; /***/ }), -/* 548 */ +/* 549 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62546,7 +62723,7 @@ module.exports = fillRange; -var typeOf = __webpack_require__(549); +var typeOf = __webpack_require__(550); module.exports = function isNumber(num) { var type = typeOf(num); @@ -62562,10 +62739,10 @@ module.exports = function isNumber(num) { /***/ }), -/* 549 */ +/* 550 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(529); +var isBuffer = __webpack_require__(530); var toString = Object.prototype.toString; /** @@ -62684,13 +62861,13 @@ module.exports = function kindOf(val) { /***/ }), -/* 550 */ +/* 551 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(551); +var isObject = __webpack_require__(552); module.exports = function extend(o/*, objects*/) { if (!isObject(o)) { o = {}; } @@ -62724,7 +62901,7 @@ function hasOwn(obj, key) { /***/ }), -/* 551 */ +/* 552 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62744,7 +62921,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 552 */ +/* 553 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62821,7 +62998,7 @@ function repeat(str, num) { /***/ }), -/* 553 */ +/* 554 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -62834,8 +63011,8 @@ function repeat(str, num) { -var repeat = __webpack_require__(552); -var isNumber = __webpack_require__(548); +var repeat = __webpack_require__(553); +var isNumber = __webpack_require__(549); var cache = {}; function toRegexRange(min, max, options) { @@ -63122,7 +63299,7 @@ module.exports = toRegexRange; /***/ }), -/* 554 */ +/* 555 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -63147,14 +63324,14 @@ module.exports = function repeat(ele, num) { /***/ }), -/* 555 */ +/* 556 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var Node = __webpack_require__(556); -var utils = __webpack_require__(539); +var Node = __webpack_require__(557); +var utils = __webpack_require__(540); /** * Braces parsers @@ -63514,15 +63691,15 @@ function concatNodes(pos, node, parent, options) { /***/ }), -/* 556 */ +/* 557 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(544); -var define = __webpack_require__(557); -var utils = __webpack_require__(564); +var isObject = __webpack_require__(545); +var define = __webpack_require__(558); +var utils = __webpack_require__(565); var ownNames; /** @@ -64013,7 +64190,7 @@ exports = module.exports = Node; /***/ }), -/* 557 */ +/* 558 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -64026,7 +64203,7 @@ exports = module.exports = Node; -var isDescriptor = __webpack_require__(558); +var isDescriptor = __webpack_require__(559); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -64051,7 +64228,7 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 558 */ +/* 559 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -64064,9 +64241,9 @@ module.exports = function defineProperty(obj, prop, val) { -var typeOf = __webpack_require__(559); -var isAccessor = __webpack_require__(560); -var isData = __webpack_require__(562); +var typeOf = __webpack_require__(560); +var isAccessor = __webpack_require__(561); +var isData = __webpack_require__(563); module.exports = function isDescriptor(obj, key) { if (typeOf(obj) !== 'object') { @@ -64080,7 +64257,7 @@ module.exports = function isDescriptor(obj, key) { /***/ }), -/* 559 */ +/* 560 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -64215,7 +64392,7 @@ function isBuffer(val) { /***/ }), -/* 560 */ +/* 561 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -64228,7 +64405,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(561); +var typeOf = __webpack_require__(562); // accessor descriptor properties var accessor = { @@ -64291,7 +64468,7 @@ module.exports = isAccessorDescriptor; /***/ }), -/* 561 */ +/* 562 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -64426,7 +64603,7 @@ function isBuffer(val) { /***/ }), -/* 562 */ +/* 563 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -64439,7 +64616,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(563); +var typeOf = __webpack_require__(564); module.exports = function isDataDescriptor(obj, prop) { // data descriptor properties @@ -64482,7 +64659,7 @@ module.exports = function isDataDescriptor(obj, prop) { /***/ }), -/* 563 */ +/* 564 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -64617,13 +64794,13 @@ function isBuffer(val) { /***/ }), -/* 564 */ +/* 565 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var typeOf = __webpack_require__(549); +var typeOf = __webpack_require__(550); var utils = module.exports; /** @@ -65643,17 +65820,17 @@ function assert(val, message) { /***/ }), -/* 565 */ +/* 566 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(532); -var Snapdragon = __webpack_require__(566); -var compilers = __webpack_require__(538); -var parsers = __webpack_require__(555); -var utils = __webpack_require__(539); +var extend = __webpack_require__(533); +var Snapdragon = __webpack_require__(567); +var compilers = __webpack_require__(539); +var parsers = __webpack_require__(556); +var utils = __webpack_require__(540); /** * Customize Snapdragon parser and renderer @@ -65754,17 +65931,17 @@ module.exports = Braces; /***/ }), -/* 566 */ +/* 567 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var Base = __webpack_require__(567); -var define = __webpack_require__(593); -var Compiler = __webpack_require__(603); -var Parser = __webpack_require__(632); -var utils = __webpack_require__(612); +var Base = __webpack_require__(568); +var define = __webpack_require__(594); +var Compiler = __webpack_require__(604); +var Parser = __webpack_require__(633); +var utils = __webpack_require__(613); var regexCache = {}; var cache = {}; @@ -65935,20 +66112,20 @@ module.exports.Parser = Parser; /***/ }), -/* 567 */ +/* 568 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(111); -var define = __webpack_require__(568); -var CacheBase = __webpack_require__(569); -var Emitter = __webpack_require__(570); -var isObject = __webpack_require__(544); -var merge = __webpack_require__(587); -var pascal = __webpack_require__(590); -var cu = __webpack_require__(591); +var define = __webpack_require__(569); +var CacheBase = __webpack_require__(570); +var Emitter = __webpack_require__(571); +var isObject = __webpack_require__(545); +var merge = __webpack_require__(588); +var pascal = __webpack_require__(591); +var cu = __webpack_require__(592); /** * Optionally define a custom `cache` namespace to use. @@ -66377,7 +66554,7 @@ module.exports.namespace = namespace; /***/ }), -/* 568 */ +/* 569 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -66390,7 +66567,7 @@ module.exports.namespace = namespace; -var isDescriptor = __webpack_require__(558); +var isDescriptor = __webpack_require__(559); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -66415,21 +66592,21 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 569 */ +/* 570 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(544); -var Emitter = __webpack_require__(570); -var visit = __webpack_require__(571); -var toPath = __webpack_require__(574); -var union = __webpack_require__(575); -var del = __webpack_require__(579); -var get = __webpack_require__(577); -var has = __webpack_require__(584); -var set = __webpack_require__(578); +var isObject = __webpack_require__(545); +var Emitter = __webpack_require__(571); +var visit = __webpack_require__(572); +var toPath = __webpack_require__(575); +var union = __webpack_require__(576); +var del = __webpack_require__(580); +var get = __webpack_require__(578); +var has = __webpack_require__(585); +var set = __webpack_require__(579); /** * Create a `Cache` constructor that when instantiated will @@ -66683,7 +66860,7 @@ module.exports.namespace = namespace; /***/ }), -/* 570 */ +/* 571 */ /***/ (function(module, exports, __webpack_require__) { @@ -66852,7 +67029,7 @@ Emitter.prototype.hasListeners = function(event){ /***/ }), -/* 571 */ +/* 572 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -66865,8 +67042,8 @@ Emitter.prototype.hasListeners = function(event){ -var visit = __webpack_require__(572); -var mapVisit = __webpack_require__(573); +var visit = __webpack_require__(573); +var mapVisit = __webpack_require__(574); module.exports = function(collection, method, val) { var result; @@ -66889,7 +67066,7 @@ module.exports = function(collection, method, val) { /***/ }), -/* 572 */ +/* 573 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -66902,7 +67079,7 @@ module.exports = function(collection, method, val) { -var isObject = __webpack_require__(544); +var isObject = __webpack_require__(545); module.exports = function visit(thisArg, method, target, val) { if (!isObject(thisArg) && typeof thisArg !== 'function') { @@ -66929,14 +67106,14 @@ module.exports = function visit(thisArg, method, target, val) { /***/ }), -/* 573 */ +/* 574 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(111); -var visit = __webpack_require__(572); +var visit = __webpack_require__(573); /** * Map `visit` over an array of objects. @@ -66973,7 +67150,7 @@ function isObject(val) { /***/ }), -/* 574 */ +/* 575 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -66986,7 +67163,7 @@ function isObject(val) { -var typeOf = __webpack_require__(549); +var typeOf = __webpack_require__(550); module.exports = function toPath(args) { if (typeOf(args) !== 'arguments') { @@ -67013,16 +67190,16 @@ function filter(arr) { /***/ }), -/* 575 */ +/* 576 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isObject = __webpack_require__(536); -var union = __webpack_require__(576); -var get = __webpack_require__(577); -var set = __webpack_require__(578); +var isObject = __webpack_require__(537); +var union = __webpack_require__(577); +var get = __webpack_require__(578); +var set = __webpack_require__(579); module.exports = function unionValue(obj, prop, value) { if (!isObject(obj)) { @@ -67050,7 +67227,7 @@ function arrayify(val) { /***/ }), -/* 576 */ +/* 577 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67086,7 +67263,7 @@ module.exports = function union(init) { /***/ }), -/* 577 */ +/* 578 */ /***/ (function(module, exports) { /*! @@ -67142,7 +67319,7 @@ function toString(val) { /***/ }), -/* 578 */ +/* 579 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67155,10 +67332,10 @@ function toString(val) { -var split = __webpack_require__(540); -var extend = __webpack_require__(535); -var isPlainObject = __webpack_require__(543); -var isObject = __webpack_require__(536); +var split = __webpack_require__(541); +var extend = __webpack_require__(536); +var isPlainObject = __webpack_require__(544); +var isObject = __webpack_require__(537); module.exports = function(obj, prop, val) { if (!isObject(obj)) { @@ -67204,7 +67381,7 @@ function isValidKey(key) { /***/ }), -/* 579 */ +/* 580 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67217,8 +67394,8 @@ function isValidKey(key) { -var isObject = __webpack_require__(544); -var has = __webpack_require__(580); +var isObject = __webpack_require__(545); +var has = __webpack_require__(581); module.exports = function unset(obj, prop) { if (!isObject(obj)) { @@ -67243,7 +67420,7 @@ module.exports = function unset(obj, prop) { /***/ }), -/* 580 */ +/* 581 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67256,9 +67433,9 @@ module.exports = function unset(obj, prop) { -var isObject = __webpack_require__(581); -var hasValues = __webpack_require__(583); -var get = __webpack_require__(577); +var isObject = __webpack_require__(582); +var hasValues = __webpack_require__(584); +var get = __webpack_require__(578); module.exports = function(obj, prop, noZero) { if (isObject(obj)) { @@ -67269,7 +67446,7 @@ module.exports = function(obj, prop, noZero) { /***/ }), -/* 581 */ +/* 582 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67282,7 +67459,7 @@ module.exports = function(obj, prop, noZero) { -var isArray = __webpack_require__(582); +var isArray = __webpack_require__(583); module.exports = function isObject(val) { return val != null && typeof val === 'object' && isArray(val) === false; @@ -67290,7 +67467,7 @@ module.exports = function isObject(val) { /***/ }), -/* 582 */ +/* 583 */ /***/ (function(module, exports) { var toString = {}.toString; @@ -67301,7 +67478,7 @@ module.exports = Array.isArray || function (arr) { /***/ }), -/* 583 */ +/* 584 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67344,7 +67521,7 @@ module.exports = function hasValue(o, noZero) { /***/ }), -/* 584 */ +/* 585 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67357,9 +67534,9 @@ module.exports = function hasValue(o, noZero) { -var isObject = __webpack_require__(544); -var hasValues = __webpack_require__(585); -var get = __webpack_require__(577); +var isObject = __webpack_require__(545); +var hasValues = __webpack_require__(586); +var get = __webpack_require__(578); module.exports = function(val, prop) { return hasValues(isObject(val) && prop ? get(val, prop) : val); @@ -67367,7 +67544,7 @@ module.exports = function(val, prop) { /***/ }), -/* 585 */ +/* 586 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67380,8 +67557,8 @@ module.exports = function(val, prop) { -var typeOf = __webpack_require__(586); -var isNumber = __webpack_require__(548); +var typeOf = __webpack_require__(587); +var isNumber = __webpack_require__(549); module.exports = function hasValue(val) { // is-number checks for NaN and other edge cases @@ -67434,10 +67611,10 @@ module.exports = function hasValue(val) { /***/ }), -/* 586 */ +/* 587 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(529); +var isBuffer = __webpack_require__(530); var toString = Object.prototype.toString; /** @@ -67559,14 +67736,14 @@ module.exports = function kindOf(val) { /***/ }), -/* 587 */ +/* 588 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(588); -var forIn = __webpack_require__(589); +var isExtendable = __webpack_require__(589); +var forIn = __webpack_require__(590); function mixinDeep(target, objects) { var len = arguments.length, i = 0; @@ -67630,7 +67807,7 @@ module.exports = mixinDeep; /***/ }), -/* 588 */ +/* 589 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67643,7 +67820,7 @@ module.exports = mixinDeep; -var isPlainObject = __webpack_require__(543); +var isPlainObject = __webpack_require__(544); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -67651,7 +67828,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 589 */ +/* 590 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -67674,7 +67851,7 @@ module.exports = function forIn(obj, fn, thisArg) { /***/ }), -/* 590 */ +/* 591 */ /***/ (function(module, exports) { /*! @@ -67701,14 +67878,14 @@ module.exports = pascalcase; /***/ }), -/* 591 */ +/* 592 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; var util = __webpack_require__(111); -var utils = __webpack_require__(592); +var utils = __webpack_require__(593); /** * Expose class utils @@ -68073,7 +68250,7 @@ cu.bubble = function(Parent, events) { /***/ }), -/* 592 */ +/* 593 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68087,10 +68264,10 @@ var utils = {}; * Lazily required module dependencies */ -utils.union = __webpack_require__(576); -utils.define = __webpack_require__(593); -utils.isObj = __webpack_require__(544); -utils.staticExtend = __webpack_require__(600); +utils.union = __webpack_require__(577); +utils.define = __webpack_require__(594); +utils.isObj = __webpack_require__(545); +utils.staticExtend = __webpack_require__(601); /** @@ -68101,7 +68278,7 @@ module.exports = utils; /***/ }), -/* 593 */ +/* 594 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68114,7 +68291,7 @@ module.exports = utils; -var isDescriptor = __webpack_require__(594); +var isDescriptor = __webpack_require__(595); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -68139,7 +68316,7 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 594 */ +/* 595 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68152,9 +68329,9 @@ module.exports = function defineProperty(obj, prop, val) { -var typeOf = __webpack_require__(595); -var isAccessor = __webpack_require__(596); -var isData = __webpack_require__(598); +var typeOf = __webpack_require__(596); +var isAccessor = __webpack_require__(597); +var isData = __webpack_require__(599); module.exports = function isDescriptor(obj, key) { if (typeOf(obj) !== 'object') { @@ -68168,7 +68345,7 @@ module.exports = function isDescriptor(obj, key) { /***/ }), -/* 595 */ +/* 596 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -68321,7 +68498,7 @@ function isBuffer(val) { /***/ }), -/* 596 */ +/* 597 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68334,7 +68511,7 @@ function isBuffer(val) { -var typeOf = __webpack_require__(597); +var typeOf = __webpack_require__(598); // accessor descriptor properties var accessor = { @@ -68397,10 +68574,10 @@ module.exports = isAccessorDescriptor; /***/ }), -/* 597 */ +/* 598 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(529); +var isBuffer = __webpack_require__(530); var toString = Object.prototype.toString; /** @@ -68519,7 +68696,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 598 */ +/* 599 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68532,7 +68709,7 @@ module.exports = function kindOf(val) { -var typeOf = __webpack_require__(599); +var typeOf = __webpack_require__(600); // data descriptor properties var data = { @@ -68581,10 +68758,10 @@ module.exports = isDataDescriptor; /***/ }), -/* 599 */ +/* 600 */ /***/ (function(module, exports, __webpack_require__) { -var isBuffer = __webpack_require__(529); +var isBuffer = __webpack_require__(530); var toString = Object.prototype.toString; /** @@ -68703,7 +68880,7 @@ module.exports = function kindOf(val) { /***/ }), -/* 600 */ +/* 601 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -68716,8 +68893,8 @@ module.exports = function kindOf(val) { -var copy = __webpack_require__(601); -var define = __webpack_require__(593); +var copy = __webpack_require__(602); +var define = __webpack_require__(594); var util = __webpack_require__(111); /** @@ -68800,15 +68977,15 @@ module.exports = extend; /***/ }), -/* 601 */ +/* 602 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var typeOf = __webpack_require__(549); -var copyDescriptor = __webpack_require__(602); -var define = __webpack_require__(593); +var typeOf = __webpack_require__(550); +var copyDescriptor = __webpack_require__(603); +var define = __webpack_require__(594); /** * Copy static properties, prototype properties, and descriptors from one object to another. @@ -68981,7 +69158,7 @@ module.exports.has = has; /***/ }), -/* 602 */ +/* 603 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69069,16 +69246,16 @@ function isObject(val) { /***/ }), -/* 603 */ +/* 604 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(604); -var define = __webpack_require__(593); -var debug = __webpack_require__(606)('snapdragon:compiler'); -var utils = __webpack_require__(612); +var use = __webpack_require__(605); +var define = __webpack_require__(594); +var debug = __webpack_require__(607)('snapdragon:compiler'); +var utils = __webpack_require__(613); /** * Create a new `Compiler` with the given `options`. @@ -69232,7 +69409,7 @@ Compiler.prototype = { // source map support if (opts.sourcemap) { - var sourcemaps = __webpack_require__(631); + var sourcemaps = __webpack_require__(632); sourcemaps(this); this.mapVisit(this.ast.nodes); this.applySourceMaps(); @@ -69253,7 +69430,7 @@ module.exports = Compiler; /***/ }), -/* 604 */ +/* 605 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69266,7 +69443,7 @@ module.exports = Compiler; -var utils = __webpack_require__(605); +var utils = __webpack_require__(606); module.exports = function base(app, opts) { if (!utils.isObject(app) && typeof app !== 'function') { @@ -69381,7 +69558,7 @@ module.exports = function base(app, opts) { /***/ }), -/* 605 */ +/* 606 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -69395,8 +69572,8 @@ var utils = {}; * Lazily required module dependencies */ -utils.define = __webpack_require__(593); -utils.isObject = __webpack_require__(544); +utils.define = __webpack_require__(594); +utils.isObject = __webpack_require__(545); utils.isString = function(val) { @@ -69411,7 +69588,7 @@ module.exports = utils; /***/ }), -/* 606 */ +/* 607 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -69420,14 +69597,14 @@ module.exports = utils; */ if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(607); + module.exports = __webpack_require__(608); } else { - module.exports = __webpack_require__(610); + module.exports = __webpack_require__(611); } /***/ }), -/* 607 */ +/* 608 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -69436,7 +69613,7 @@ if (typeof process !== 'undefined' && process.type === 'renderer') { * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(608); +exports = module.exports = __webpack_require__(609); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; @@ -69618,7 +69795,7 @@ function localstorage() { /***/ }), -/* 608 */ +/* 609 */ /***/ (function(module, exports, __webpack_require__) { @@ -69634,7 +69811,7 @@ exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; -exports.humanize = __webpack_require__(609); +exports.humanize = __webpack_require__(610); /** * The currently active debug mode names, and names to skip. @@ -69826,7 +70003,7 @@ function coerce(val) { /***/ }), -/* 609 */ +/* 610 */ /***/ (function(module, exports) { /** @@ -69984,7 +70161,7 @@ function plural(ms, n, name) { /***/ }), -/* 610 */ +/* 611 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -70000,7 +70177,7 @@ var util = __webpack_require__(111); * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(608); +exports = module.exports = __webpack_require__(609); exports.init = init; exports.log = log; exports.formatArgs = formatArgs; @@ -70179,7 +70356,7 @@ function createWritableStdioStream (fd) { case 'PIPE': case 'TCP': - var net = __webpack_require__(611); + var net = __webpack_require__(612); stream = new net.Socket({ fd: fd, readable: false, @@ -70238,13 +70415,13 @@ exports.enable(load()); /***/ }), -/* 611 */ +/* 612 */ /***/ (function(module, exports) { module.exports = require("net"); /***/ }), -/* 612 */ +/* 613 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -70254,9 +70431,9 @@ module.exports = require("net"); * Module dependencies */ -exports.extend = __webpack_require__(535); -exports.SourceMap = __webpack_require__(613); -exports.sourceMapResolve = __webpack_require__(624); +exports.extend = __webpack_require__(536); +exports.SourceMap = __webpack_require__(614); +exports.sourceMapResolve = __webpack_require__(625); /** * Convert backslash in the given string to forward slashes @@ -70299,7 +70476,7 @@ exports.last = function(arr, n) { /***/ }), -/* 613 */ +/* 614 */ /***/ (function(module, exports, __webpack_require__) { /* @@ -70307,13 +70484,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__(614).SourceMapGenerator; -exports.SourceMapConsumer = __webpack_require__(620).SourceMapConsumer; -exports.SourceNode = __webpack_require__(623).SourceNode; +exports.SourceMapGenerator = __webpack_require__(615).SourceMapGenerator; +exports.SourceMapConsumer = __webpack_require__(621).SourceMapConsumer; +exports.SourceNode = __webpack_require__(624).SourceNode; /***/ }), -/* 614 */ +/* 615 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -70323,10 +70500,10 @@ exports.SourceNode = __webpack_require__(623).SourceNode; * http://opensource.org/licenses/BSD-3-Clause */ -var base64VLQ = __webpack_require__(615); -var util = __webpack_require__(617); -var ArraySet = __webpack_require__(618).ArraySet; -var MappingList = __webpack_require__(619).MappingList; +var base64VLQ = __webpack_require__(616); +var util = __webpack_require__(618); +var ArraySet = __webpack_require__(619).ArraySet; +var MappingList = __webpack_require__(620).MappingList; /** * An instance of the SourceMapGenerator represents a source map which is @@ -70735,7 +70912,7 @@ exports.SourceMapGenerator = SourceMapGenerator; /***/ }), -/* 615 */ +/* 616 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -70775,7 +70952,7 @@ exports.SourceMapGenerator = SourceMapGenerator; * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -var base64 = __webpack_require__(616); +var base64 = __webpack_require__(617); // 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, @@ -70881,7 +71058,7 @@ exports.decode = function base64VLQ_decode(aStr, aIndex, aOutParam) { /***/ }), -/* 616 */ +/* 617 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -70954,7 +71131,7 @@ exports.decode = function (charCode) { /***/ }), -/* 617 */ +/* 618 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71377,7 +71554,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate /***/ }), -/* 618 */ +/* 619 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71387,7 +71564,7 @@ exports.compareByGeneratedPositionsInflated = compareByGeneratedPositionsInflate * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(617); +var util = __webpack_require__(618); var has = Object.prototype.hasOwnProperty; var hasNativeMap = typeof Map !== "undefined"; @@ -71504,7 +71681,7 @@ exports.ArraySet = ArraySet; /***/ }), -/* 619 */ +/* 620 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71514,7 +71691,7 @@ exports.ArraySet = ArraySet; * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(617); +var util = __webpack_require__(618); /** * Determine whether mappingB is after mappingA with respect to generated @@ -71589,7 +71766,7 @@ exports.MappingList = MappingList; /***/ }), -/* 620 */ +/* 621 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -71599,11 +71776,11 @@ exports.MappingList = MappingList; * http://opensource.org/licenses/BSD-3-Clause */ -var util = __webpack_require__(617); -var binarySearch = __webpack_require__(621); -var ArraySet = __webpack_require__(618).ArraySet; -var base64VLQ = __webpack_require__(615); -var quickSort = __webpack_require__(622).quickSort; +var util = __webpack_require__(618); +var binarySearch = __webpack_require__(622); +var ArraySet = __webpack_require__(619).ArraySet; +var base64VLQ = __webpack_require__(616); +var quickSort = __webpack_require__(623).quickSort; function SourceMapConsumer(aSourceMap) { var sourceMap = aSourceMap; @@ -72677,7 +72854,7 @@ exports.IndexedSourceMapConsumer = IndexedSourceMapConsumer; /***/ }), -/* 621 */ +/* 622 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -72794,7 +72971,7 @@ exports.search = function search(aNeedle, aHaystack, aCompare, aBias) { /***/ }), -/* 622 */ +/* 623 */ /***/ (function(module, exports) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -72914,7 +73091,7 @@ exports.quickSort = function (ary, comparator) { /***/ }), -/* 623 */ +/* 624 */ /***/ (function(module, exports, __webpack_require__) { /* -*- Mode: js; js-indent-level: 2; -*- */ @@ -72924,8 +73101,8 @@ exports.quickSort = function (ary, comparator) { * http://opensource.org/licenses/BSD-3-Clause */ -var SourceMapGenerator = __webpack_require__(614).SourceMapGenerator; -var util = __webpack_require__(617); +var SourceMapGenerator = __webpack_require__(615).SourceMapGenerator; +var util = __webpack_require__(618); // Matches a Windows-style `\r\n` newline or a `\n` newline used by all other // operating systems these days (capturing the result). @@ -73333,17 +73510,17 @@ exports.SourceNode = SourceNode; /***/ }), -/* 624 */ +/* 625 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014, 2015, 2016, 2017 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var sourceMappingURL = __webpack_require__(625) -var resolveUrl = __webpack_require__(626) -var decodeUriComponent = __webpack_require__(627) -var urix = __webpack_require__(629) -var atob = __webpack_require__(630) +var sourceMappingURL = __webpack_require__(626) +var resolveUrl = __webpack_require__(627) +var decodeUriComponent = __webpack_require__(628) +var urix = __webpack_require__(630) +var atob = __webpack_require__(631) @@ -73641,7 +73818,7 @@ module.exports = { /***/ }), -/* 625 */ +/* 626 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;// Copyright 2014 Simon Lydell @@ -73704,7 +73881,7 @@ void (function(root, factory) { /***/ }), -/* 626 */ +/* 627 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014 Simon Lydell @@ -73722,13 +73899,13 @@ module.exports = resolveUrl /***/ }), -/* 627 */ +/* 628 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2017 Simon Lydell // X11 (“MIT”) Licensed. (See LICENSE.) -var decodeUriComponent = __webpack_require__(628) +var decodeUriComponent = __webpack_require__(629) function customDecodeUriComponent(string) { // `decodeUriComponent` turns `+` into ` `, but that's not wanted. @@ -73739,7 +73916,7 @@ module.exports = customDecodeUriComponent /***/ }), -/* 628 */ +/* 629 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -73840,7 +74017,7 @@ module.exports = function (encodedURI) { /***/ }), -/* 629 */ +/* 630 */ /***/ (function(module, exports, __webpack_require__) { // Copyright 2014 Simon Lydell @@ -73863,7 +74040,7 @@ module.exports = urix /***/ }), -/* 630 */ +/* 631 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -73877,7 +74054,7 @@ module.exports = atob.atob = atob; /***/ }), -/* 631 */ +/* 632 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -73885,8 +74062,8 @@ module.exports = atob.atob = atob; var fs = __webpack_require__(133); var path = __webpack_require__(4); -var define = __webpack_require__(593); -var utils = __webpack_require__(612); +var define = __webpack_require__(594); +var utils = __webpack_require__(613); /** * Expose `mixin()`. @@ -74029,19 +74206,19 @@ exports.comment = function(node) { /***/ }), -/* 632 */ +/* 633 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var use = __webpack_require__(604); +var use = __webpack_require__(605); var util = __webpack_require__(111); -var Cache = __webpack_require__(633); -var define = __webpack_require__(593); -var debug = __webpack_require__(606)('snapdragon:parser'); -var Position = __webpack_require__(634); -var utils = __webpack_require__(612); +var Cache = __webpack_require__(634); +var define = __webpack_require__(594); +var debug = __webpack_require__(607)('snapdragon:parser'); +var Position = __webpack_require__(635); +var utils = __webpack_require__(613); /** * Create a new `Parser` with the given `input` and `options`. @@ -74569,7 +74746,7 @@ module.exports = Parser; /***/ }), -/* 633 */ +/* 634 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -74676,13 +74853,13 @@ MapCache.prototype.del = function mapDelete(key) { /***/ }), -/* 634 */ +/* 635 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(593); +var define = __webpack_require__(594); /** * Store position for a node @@ -74697,16 +74874,16 @@ module.exports = function Position(start, parser) { /***/ }), -/* 635 */ +/* 636 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var safe = __webpack_require__(636); -var define = __webpack_require__(642); -var extend = __webpack_require__(643); -var not = __webpack_require__(645); +var safe = __webpack_require__(637); +var define = __webpack_require__(643); +var extend = __webpack_require__(644); +var not = __webpack_require__(646); var MAX_LENGTH = 1024 * 64; /** @@ -74859,10 +75036,10 @@ module.exports.makeRe = makeRe; /***/ }), -/* 636 */ +/* 637 */ /***/ (function(module, exports, __webpack_require__) { -var parse = __webpack_require__(637); +var parse = __webpack_require__(638); var types = parse.types; module.exports = function (re, opts) { @@ -74908,13 +75085,13 @@ function isRegExp (x) { /***/ }), -/* 637 */ +/* 638 */ /***/ (function(module, exports, __webpack_require__) { -var util = __webpack_require__(638); -var types = __webpack_require__(639); -var sets = __webpack_require__(640); -var positions = __webpack_require__(641); +var util = __webpack_require__(639); +var types = __webpack_require__(640); +var sets = __webpack_require__(641); +var positions = __webpack_require__(642); module.exports = function(regexpStr) { @@ -75196,11 +75373,11 @@ module.exports.types = types; /***/ }), -/* 638 */ +/* 639 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(639); -var sets = __webpack_require__(640); +var types = __webpack_require__(640); +var sets = __webpack_require__(641); // All of these are private and only used by randexp. @@ -75313,7 +75490,7 @@ exports.error = function(regexp, msg) { /***/ }), -/* 639 */ +/* 640 */ /***/ (function(module, exports) { module.exports = { @@ -75329,10 +75506,10 @@ module.exports = { /***/ }), -/* 640 */ +/* 641 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(639); +var types = __webpack_require__(640); var INTS = function() { return [{ type: types.RANGE , from: 48, to: 57 }]; @@ -75417,10 +75594,10 @@ exports.anyChar = function() { /***/ }), -/* 641 */ +/* 642 */ /***/ (function(module, exports, __webpack_require__) { -var types = __webpack_require__(639); +var types = __webpack_require__(640); exports.wordBoundary = function() { return { type: types.POSITION, value: 'b' }; @@ -75440,7 +75617,7 @@ exports.end = function() { /***/ }), -/* 642 */ +/* 643 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75453,8 +75630,8 @@ exports.end = function() { -var isobject = __webpack_require__(544); -var isDescriptor = __webpack_require__(558); +var isobject = __webpack_require__(545); +var isDescriptor = __webpack_require__(559); var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) ? Reflect.defineProperty : Object.defineProperty; @@ -75485,14 +75662,14 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 643 */ +/* 644 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(644); -var assignSymbols = __webpack_require__(545); +var isExtendable = __webpack_require__(645); +var assignSymbols = __webpack_require__(546); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -75552,7 +75729,7 @@ function isEnum(obj, key) { /***/ }), -/* 644 */ +/* 645 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75565,7 +75742,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(543); +var isPlainObject = __webpack_require__(544); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -75573,14 +75750,14 @@ module.exports = function isExtendable(val) { /***/ }), -/* 645 */ +/* 646 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extend = __webpack_require__(643); -var safe = __webpack_require__(636); +var extend = __webpack_require__(644); +var safe = __webpack_require__(637); /** * The main export is a function that takes a `pattern` string and an `options` object. @@ -75652,14 +75829,14 @@ module.exports = toRegex; /***/ }), -/* 646 */ +/* 647 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var nanomatch = __webpack_require__(647); -var extglob = __webpack_require__(663); +var nanomatch = __webpack_require__(648); +var extglob = __webpack_require__(664); module.exports = function(snapdragon) { var compilers = snapdragon.compiler.compilers; @@ -75736,7 +75913,7 @@ function escapeExtglobs(compiler) { /***/ }), -/* 647 */ +/* 648 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -75747,17 +75924,17 @@ function escapeExtglobs(compiler) { */ var util = __webpack_require__(111); -var toRegex = __webpack_require__(648); -var extend = __webpack_require__(649); +var toRegex = __webpack_require__(649); +var extend = __webpack_require__(650); /** * Local dependencies */ -var compilers = __webpack_require__(651); -var parsers = __webpack_require__(652); -var cache = __webpack_require__(655); -var utils = __webpack_require__(657); +var compilers = __webpack_require__(652); +var parsers = __webpack_require__(653); +var cache = __webpack_require__(656); +var utils = __webpack_require__(658); var MAX_LENGTH = 1024 * 64; /** @@ -76581,15 +76758,15 @@ module.exports = nanomatch; /***/ }), -/* 648 */ +/* 649 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var define = __webpack_require__(593); -var extend = __webpack_require__(535); -var not = __webpack_require__(534); +var define = __webpack_require__(594); +var extend = __webpack_require__(536); +var not = __webpack_require__(535); var MAX_LENGTH = 1024 * 64; /** @@ -76736,14 +76913,14 @@ module.exports.makeRe = makeRe; /***/ }), -/* 649 */ +/* 650 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var isExtendable = __webpack_require__(650); -var assignSymbols = __webpack_require__(545); +var isExtendable = __webpack_require__(651); +var assignSymbols = __webpack_require__(546); module.exports = Object.assign || function(obj/*, objects*/) { if (obj === null || typeof obj === 'undefined') { @@ -76803,7 +76980,7 @@ function isEnum(obj, key) { /***/ }), -/* 650 */ +/* 651 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -76816,7 +76993,7 @@ function isEnum(obj, key) { -var isPlainObject = __webpack_require__(543); +var isPlainObject = __webpack_require__(544); module.exports = function isExtendable(val) { return isPlainObject(val) || typeof val === 'function' || Array.isArray(val); @@ -76824,7 +77001,7 @@ module.exports = function isExtendable(val) { /***/ }), -/* 651 */ +/* 652 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77170,15 +77347,15 @@ module.exports = function(nanomatch, options) { /***/ }), -/* 652 */ +/* 653 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var regexNot = __webpack_require__(534); -var toRegex = __webpack_require__(648); -var isOdd = __webpack_require__(653); +var regexNot = __webpack_require__(535); +var toRegex = __webpack_require__(649); +var isOdd = __webpack_require__(654); /** * Characters to use in negation regex (we want to "not" match @@ -77564,7 +77741,7 @@ module.exports.not = NOT_REGEX; /***/ }), -/* 653 */ +/* 654 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77577,7 +77754,7 @@ module.exports.not = NOT_REGEX; -var isNumber = __webpack_require__(654); +var isNumber = __webpack_require__(655); module.exports = function isOdd(i) { if (!isNumber(i)) { @@ -77591,7 +77768,7 @@ module.exports = function isOdd(i) { /***/ }), -/* 654 */ +/* 655 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77619,14 +77796,14 @@ module.exports = function isNumber(num) { /***/ }), -/* 655 */ +/* 656 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(656))(); +module.exports = new (__webpack_require__(657))(); /***/ }), -/* 656 */ +/* 657 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77639,7 +77816,7 @@ module.exports = new (__webpack_require__(656))(); -var MapCache = __webpack_require__(633); +var MapCache = __webpack_require__(634); /** * Create a new `FragmentCache` with an optional object to use for `caches`. @@ -77761,7 +77938,7 @@ exports = module.exports = FragmentCache; /***/ }), -/* 657 */ +/* 658 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -77774,14 +77951,14 @@ var path = __webpack_require__(4); * Module dependencies */ -var isWindows = __webpack_require__(658)(); -var Snapdragon = __webpack_require__(566); -utils.define = __webpack_require__(659); -utils.diff = __webpack_require__(660); -utils.extend = __webpack_require__(649); -utils.pick = __webpack_require__(661); -utils.typeOf = __webpack_require__(662); -utils.unique = __webpack_require__(537); +var isWindows = __webpack_require__(659)(); +var Snapdragon = __webpack_require__(567); +utils.define = __webpack_require__(660); +utils.diff = __webpack_require__(661); +utils.extend = __webpack_require__(650); +utils.pick = __webpack_require__(662); +utils.typeOf = __webpack_require__(663); +utils.unique = __webpack_require__(538); /** * Returns true if the given value is effectively an empty string @@ -78147,7 +78324,7 @@ utils.unixify = function(options) { /***/ }), -/* 658 */ +/* 659 */ /***/ (function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! @@ -78175,7 +78352,7 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ /***/ }), -/* 659 */ +/* 660 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78188,8 +78365,8 @@ var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_ARRAY__, __WEBPACK_AMD_ -var isobject = __webpack_require__(544); -var isDescriptor = __webpack_require__(558); +var isobject = __webpack_require__(545); +var isDescriptor = __webpack_require__(559); var define = (typeof Reflect !== 'undefined' && Reflect.defineProperty) ? Reflect.defineProperty : Object.defineProperty; @@ -78220,7 +78397,7 @@ module.exports = function defineProperty(obj, key, val) { /***/ }), -/* 660 */ +/* 661 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78274,7 +78451,7 @@ function diffArray(one, two) { /***/ }), -/* 661 */ +/* 662 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78287,7 +78464,7 @@ function diffArray(one, two) { -var isObject = __webpack_require__(544); +var isObject = __webpack_require__(545); module.exports = function pick(obj, keys) { if (!isObject(obj) && typeof obj !== 'function') { @@ -78316,7 +78493,7 @@ module.exports = function pick(obj, keys) { /***/ }), -/* 662 */ +/* 663 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -78451,7 +78628,7 @@ function isBuffer(val) { /***/ }), -/* 663 */ +/* 664 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78461,18 +78638,18 @@ function isBuffer(val) { * Module dependencies */ -var extend = __webpack_require__(535); -var unique = __webpack_require__(537); -var toRegex = __webpack_require__(648); +var extend = __webpack_require__(536); +var unique = __webpack_require__(538); +var toRegex = __webpack_require__(649); /** * Local dependencies */ -var compilers = __webpack_require__(664); -var parsers = __webpack_require__(675); -var Extglob = __webpack_require__(678); -var utils = __webpack_require__(677); +var compilers = __webpack_require__(665); +var parsers = __webpack_require__(676); +var Extglob = __webpack_require__(679); +var utils = __webpack_require__(678); var MAX_LENGTH = 1024 * 64; /** @@ -78789,13 +78966,13 @@ module.exports = extglob; /***/ }), -/* 664 */ +/* 665 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(665); +var brackets = __webpack_require__(666); /** * Extglob compilers @@ -78965,7 +79142,7 @@ module.exports = function(extglob) { /***/ }), -/* 665 */ +/* 666 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -78975,17 +79152,17 @@ module.exports = function(extglob) { * Local dependencies */ -var compilers = __webpack_require__(666); -var parsers = __webpack_require__(668); +var compilers = __webpack_require__(667); +var parsers = __webpack_require__(669); /** * Module dependencies */ -var debug = __webpack_require__(670)('expand-brackets'); -var extend = __webpack_require__(535); -var Snapdragon = __webpack_require__(566); -var toRegex = __webpack_require__(648); +var debug = __webpack_require__(671)('expand-brackets'); +var extend = __webpack_require__(536); +var Snapdragon = __webpack_require__(567); +var toRegex = __webpack_require__(649); /** * Parses the given POSIX character class `pattern` and returns a @@ -79183,13 +79360,13 @@ module.exports = brackets; /***/ }), -/* 666 */ +/* 667 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var posix = __webpack_require__(667); +var posix = __webpack_require__(668); module.exports = function(brackets) { brackets.compiler @@ -79277,7 +79454,7 @@ module.exports = function(brackets) { /***/ }), -/* 667 */ +/* 668 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -79306,14 +79483,14 @@ module.exports = { /***/ }), -/* 668 */ +/* 669 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var utils = __webpack_require__(669); -var define = __webpack_require__(593); +var utils = __webpack_require__(670); +var define = __webpack_require__(594); /** * Text regex @@ -79532,14 +79709,14 @@ module.exports.TEXT_REGEX = TEXT_REGEX; /***/ }), -/* 669 */ +/* 670 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var toRegex = __webpack_require__(648); -var regexNot = __webpack_require__(534); +var toRegex = __webpack_require__(649); +var regexNot = __webpack_require__(535); var cached; /** @@ -79573,7 +79750,7 @@ exports.createRegex = function(pattern, include) { /***/ }), -/* 670 */ +/* 671 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -79582,14 +79759,14 @@ exports.createRegex = function(pattern, include) { */ if (typeof process !== 'undefined' && process.type === 'renderer') { - module.exports = __webpack_require__(671); + module.exports = __webpack_require__(672); } else { - module.exports = __webpack_require__(674); + module.exports = __webpack_require__(675); } /***/ }), -/* 671 */ +/* 672 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -79598,7 +79775,7 @@ if (typeof process !== 'undefined' && process.type === 'renderer') { * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(672); +exports = module.exports = __webpack_require__(673); exports.log = log; exports.formatArgs = formatArgs; exports.save = save; @@ -79780,7 +79957,7 @@ function localstorage() { /***/ }), -/* 672 */ +/* 673 */ /***/ (function(module, exports, __webpack_require__) { @@ -79796,7 +79973,7 @@ exports.coerce = coerce; exports.disable = disable; exports.enable = enable; exports.enabled = enabled; -exports.humanize = __webpack_require__(673); +exports.humanize = __webpack_require__(674); /** * The currently active debug mode names, and names to skip. @@ -79988,7 +80165,7 @@ function coerce(val) { /***/ }), -/* 673 */ +/* 674 */ /***/ (function(module, exports) { /** @@ -80146,7 +80323,7 @@ function plural(ms, n, name) { /***/ }), -/* 674 */ +/* 675 */ /***/ (function(module, exports, __webpack_require__) { /** @@ -80162,7 +80339,7 @@ var util = __webpack_require__(111); * Expose `debug()` as the module. */ -exports = module.exports = __webpack_require__(672); +exports = module.exports = __webpack_require__(673); exports.init = init; exports.log = log; exports.formatArgs = formatArgs; @@ -80341,7 +80518,7 @@ function createWritableStdioStream (fd) { case 'PIPE': case 'TCP': - var net = __webpack_require__(611); + var net = __webpack_require__(612); stream = new net.Socket({ fd: fd, readable: false, @@ -80400,15 +80577,15 @@ exports.enable(load()); /***/ }), -/* 675 */ +/* 676 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var brackets = __webpack_require__(665); -var define = __webpack_require__(676); -var utils = __webpack_require__(677); +var brackets = __webpack_require__(666); +var define = __webpack_require__(677); +var utils = __webpack_require__(678); /** * Characters to use in text regex (we want to "not" match @@ -80563,7 +80740,7 @@ module.exports = parsers; /***/ }), -/* 676 */ +/* 677 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80576,7 +80753,7 @@ module.exports = parsers; -var isDescriptor = __webpack_require__(558); +var isDescriptor = __webpack_require__(559); module.exports = function defineProperty(obj, prop, val) { if (typeof obj !== 'object' && typeof obj !== 'function') { @@ -80601,14 +80778,14 @@ module.exports = function defineProperty(obj, prop, val) { /***/ }), -/* 677 */ +/* 678 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var regex = __webpack_require__(534); -var Cache = __webpack_require__(656); +var regex = __webpack_require__(535); +var Cache = __webpack_require__(657); /** * Utils @@ -80677,7 +80854,7 @@ utils.createRegex = function(str) { /***/ }), -/* 678 */ +/* 679 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80687,16 +80864,16 @@ utils.createRegex = function(str) { * Module dependencies */ -var Snapdragon = __webpack_require__(566); -var define = __webpack_require__(676); -var extend = __webpack_require__(535); +var Snapdragon = __webpack_require__(567); +var define = __webpack_require__(677); +var extend = __webpack_require__(536); /** * Local dependencies */ -var compilers = __webpack_require__(664); -var parsers = __webpack_require__(675); +var compilers = __webpack_require__(665); +var parsers = __webpack_require__(676); /** * Customize Snapdragon parser and renderer @@ -80762,16 +80939,16 @@ module.exports = Extglob; /***/ }), -/* 679 */ +/* 680 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -var extglob = __webpack_require__(663); -var nanomatch = __webpack_require__(647); -var regexNot = __webpack_require__(534); -var toRegex = __webpack_require__(635); +var extglob = __webpack_require__(664); +var nanomatch = __webpack_require__(648); +var regexNot = __webpack_require__(535); +var toRegex = __webpack_require__(636); var not; /** @@ -80852,14 +81029,14 @@ function textRegex(pattern) { /***/ }), -/* 680 */ +/* 681 */ /***/ (function(module, exports, __webpack_require__) { -module.exports = new (__webpack_require__(656))(); +module.exports = new (__webpack_require__(657))(); /***/ }), -/* 681 */ +/* 682 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -80872,13 +81049,13 @@ var path = __webpack_require__(4); * Module dependencies */ -var Snapdragon = __webpack_require__(566); -utils.define = __webpack_require__(642); -utils.diff = __webpack_require__(660); -utils.extend = __webpack_require__(643); -utils.pick = __webpack_require__(661); -utils.typeOf = __webpack_require__(682); -utils.unique = __webpack_require__(537); +var Snapdragon = __webpack_require__(567); +utils.define = __webpack_require__(643); +utils.diff = __webpack_require__(661); +utils.extend = __webpack_require__(644); +utils.pick = __webpack_require__(662); +utils.typeOf = __webpack_require__(683); +utils.unique = __webpack_require__(538); /** * Returns true if the platform is windows, or `path.sep` is `\\`. @@ -81175,7 +81352,7 @@ utils.unixify = function(options) { /***/ }), -/* 682 */ +/* 683 */ /***/ (function(module, exports) { var toString = Object.prototype.toString; @@ -81310,7 +81487,7 @@ function isBuffer(val) { /***/ }), -/* 683 */ +/* 684 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81329,9 +81506,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(684); -var reader_1 = __webpack_require__(697); -var fs_stream_1 = __webpack_require__(701); +var readdir = __webpack_require__(685); +var reader_1 = __webpack_require__(698); +var fs_stream_1 = __webpack_require__(702); var ReaderAsync = /** @class */ (function (_super) { __extends(ReaderAsync, _super); function ReaderAsync() { @@ -81392,15 +81569,15 @@ exports.default = ReaderAsync; /***/ }), -/* 684 */ +/* 685 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const readdirSync = __webpack_require__(685); -const readdirAsync = __webpack_require__(693); -const readdirStream = __webpack_require__(696); +const readdirSync = __webpack_require__(686); +const readdirAsync = __webpack_require__(694); +const readdirStream = __webpack_require__(697); module.exports = exports = readdirAsyncPath; exports.readdir = exports.readdirAsync = exports.async = readdirAsyncPath; @@ -81484,7 +81661,7 @@ function readdirStreamStat (dir, options) { /***/ }), -/* 685 */ +/* 686 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81492,11 +81669,11 @@ function readdirStreamStat (dir, options) { module.exports = readdirSync; -const DirectoryReader = __webpack_require__(686); +const DirectoryReader = __webpack_require__(687); let syncFacade = { - fs: __webpack_require__(691), - forEach: __webpack_require__(692), + fs: __webpack_require__(692), + forEach: __webpack_require__(693), sync: true }; @@ -81525,7 +81702,7 @@ function readdirSync (dir, options, internalOptions) { /***/ }), -/* 686 */ +/* 687 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -81534,9 +81711,9 @@ function readdirSync (dir, options, internalOptions) { const Readable = __webpack_require__(137).Readable; const EventEmitter = __webpack_require__(155).EventEmitter; const path = __webpack_require__(4); -const normalizeOptions = __webpack_require__(687); -const stat = __webpack_require__(689); -const call = __webpack_require__(690); +const normalizeOptions = __webpack_require__(688); +const stat = __webpack_require__(690); +const call = __webpack_require__(691); /** * Asynchronously reads the contents of a directory and streams the results @@ -81912,14 +82089,14 @@ module.exports = DirectoryReader; /***/ }), -/* 687 */ +/* 688 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const globToRegExp = __webpack_require__(688); +const globToRegExp = __webpack_require__(689); module.exports = normalizeOptions; @@ -82096,7 +82273,7 @@ function normalizeOptions (options, internalOptions) { /***/ }), -/* 688 */ +/* 689 */ /***/ (function(module, exports) { module.exports = function (glob, opts) { @@ -82233,13 +82410,13 @@ module.exports = function (glob, opts) { /***/ }), -/* 689 */ +/* 690 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const call = __webpack_require__(690); +const call = __webpack_require__(691); module.exports = stat; @@ -82314,7 +82491,7 @@ function symlinkStat (fs, path, lstats, callback) { /***/ }), -/* 690 */ +/* 691 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82375,14 +82552,14 @@ function callOnce (fn) { /***/ }), -/* 691 */ +/* 692 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(133); -const call = __webpack_require__(690); +const call = __webpack_require__(691); /** * A facade around {@link fs.readdirSync} that allows it to be called @@ -82446,7 +82623,7 @@ exports.lstat = function (path, callback) { /***/ }), -/* 692 */ +/* 693 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82475,7 +82652,7 @@ function syncForEach (array, iterator, done) { /***/ }), -/* 693 */ +/* 694 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82483,12 +82660,12 @@ function syncForEach (array, iterator, done) { module.exports = readdirAsync; -const maybe = __webpack_require__(694); -const DirectoryReader = __webpack_require__(686); +const maybe = __webpack_require__(695); +const DirectoryReader = __webpack_require__(687); let asyncFacade = { fs: __webpack_require__(133), - forEach: __webpack_require__(695), + forEach: __webpack_require__(696), async: true }; @@ -82530,7 +82707,7 @@ function readdirAsync (dir, options, callback, internalOptions) { /***/ }), -/* 694 */ +/* 695 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82557,7 +82734,7 @@ module.exports = function maybe (cb, promise) { /***/ }), -/* 695 */ +/* 696 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82593,7 +82770,7 @@ function asyncForEach (array, iterator, done) { /***/ }), -/* 696 */ +/* 697 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82601,11 +82778,11 @@ function asyncForEach (array, iterator, done) { module.exports = readdirStream; -const DirectoryReader = __webpack_require__(686); +const DirectoryReader = __webpack_require__(687); let streamFacade = { fs: __webpack_require__(133), - forEach: __webpack_require__(695), + forEach: __webpack_require__(696), async: true }; @@ -82625,16 +82802,16 @@ function readdirStream (dir, options, internalOptions) { /***/ }), -/* 697 */ +/* 698 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var path = __webpack_require__(4); -var deep_1 = __webpack_require__(698); -var entry_1 = __webpack_require__(700); -var pathUtil = __webpack_require__(699); +var deep_1 = __webpack_require__(699); +var entry_1 = __webpack_require__(701); +var pathUtil = __webpack_require__(700); var Reader = /** @class */ (function () { function Reader(options) { this.options = options; @@ -82700,14 +82877,14 @@ exports.default = Reader; /***/ }), -/* 698 */ +/* 699 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(699); -var patternUtils = __webpack_require__(516); +var pathUtils = __webpack_require__(700); +var patternUtils = __webpack_require__(517); var DeepFilter = /** @class */ (function () { function DeepFilter(options, micromatchOptions) { this.options = options; @@ -82790,7 +82967,7 @@ exports.default = DeepFilter; /***/ }), -/* 699 */ +/* 700 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82821,14 +82998,14 @@ exports.makeAbsolute = makeAbsolute; /***/ }), -/* 700 */ +/* 701 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var pathUtils = __webpack_require__(699); -var patternUtils = __webpack_require__(516); +var pathUtils = __webpack_require__(700); +var patternUtils = __webpack_require__(517); var EntryFilter = /** @class */ (function () { function EntryFilter(options, micromatchOptions) { this.options = options; @@ -82913,7 +83090,7 @@ exports.default = EntryFilter; /***/ }), -/* 701 */ +/* 702 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -82933,8 +83110,8 @@ var __extends = (this && this.__extends) || (function () { })(); Object.defineProperty(exports, "__esModule", { value: true }); var stream = __webpack_require__(137); -var fsStat = __webpack_require__(702); -var fs_1 = __webpack_require__(706); +var fsStat = __webpack_require__(703); +var fs_1 = __webpack_require__(707); var FileSystemStream = /** @class */ (function (_super) { __extends(FileSystemStream, _super); function FileSystemStream() { @@ -82984,14 +83161,14 @@ exports.default = FileSystemStream; /***/ }), -/* 702 */ +/* 703 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const optionsManager = __webpack_require__(703); -const statProvider = __webpack_require__(705); +const optionsManager = __webpack_require__(704); +const statProvider = __webpack_require__(706); /** * Asynchronous API. */ @@ -83022,13 +83199,13 @@ exports.statSync = statSync; /***/ }), -/* 703 */ +/* 704 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -const fsAdapter = __webpack_require__(704); +const fsAdapter = __webpack_require__(705); function prepare(opts) { const options = Object.assign({ fs: fsAdapter.getFileSystemAdapter(opts ? opts.fs : undefined), @@ -83041,7 +83218,7 @@ exports.prepare = prepare; /***/ }), -/* 704 */ +/* 705 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83064,7 +83241,7 @@ exports.getFileSystemAdapter = getFileSystemAdapter; /***/ }), -/* 705 */ +/* 706 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83116,7 +83293,7 @@ exports.isFollowedSymlink = isFollowedSymlink; /***/ }), -/* 706 */ +/* 707 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83147,7 +83324,7 @@ exports.default = FileSystem; /***/ }), -/* 707 */ +/* 708 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83167,9 +83344,9 @@ var __extends = (this && this.__extends) || (function () { })(); Object.defineProperty(exports, "__esModule", { value: true }); var stream = __webpack_require__(137); -var readdir = __webpack_require__(684); -var reader_1 = __webpack_require__(697); -var fs_stream_1 = __webpack_require__(701); +var readdir = __webpack_require__(685); +var reader_1 = __webpack_require__(698); +var fs_stream_1 = __webpack_require__(702); var TransformStream = /** @class */ (function (_super) { __extends(TransformStream, _super); function TransformStream(reader) { @@ -83237,7 +83414,7 @@ exports.default = ReaderStream; /***/ }), -/* 708 */ +/* 709 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83256,9 +83433,9 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var readdir = __webpack_require__(684); -var reader_1 = __webpack_require__(697); -var fs_sync_1 = __webpack_require__(709); +var readdir = __webpack_require__(685); +var reader_1 = __webpack_require__(698); +var fs_sync_1 = __webpack_require__(710); var ReaderSync = /** @class */ (function (_super) { __extends(ReaderSync, _super); function ReaderSync() { @@ -83318,7 +83495,7 @@ exports.default = ReaderSync; /***/ }), -/* 709 */ +/* 710 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83337,8 +83514,8 @@ var __extends = (this && this.__extends) || (function () { }; })(); Object.defineProperty(exports, "__esModule", { value: true }); -var fsStat = __webpack_require__(702); -var fs_1 = __webpack_require__(706); +var fsStat = __webpack_require__(703); +var fs_1 = __webpack_require__(707); var FileSystemSync = /** @class */ (function (_super) { __extends(FileSystemSync, _super); function FileSystemSync() { @@ -83384,7 +83561,7 @@ exports.default = FileSystemSync; /***/ }), -/* 710 */ +/* 711 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83400,13 +83577,13 @@ exports.flatten = flatten; /***/ }), -/* 711 */ +/* 712 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -var merge2 = __webpack_require__(291); +var merge2 = __webpack_require__(292); /** * Merge multiple streams and propagate their errors into one stream in parallel. */ @@ -83421,13 +83598,13 @@ exports.merge = merge; /***/ }), -/* 712 */ +/* 713 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); -const pathType = __webpack_require__(713); +const pathType = __webpack_require__(714); const getExtensions = extensions => extensions.length > 1 ? `{${extensions.join(',')}}` : extensions[0]; @@ -83493,13 +83670,13 @@ module.exports.sync = (input, opts) => { /***/ }), -/* 713 */ +/* 714 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(133); -const pify = __webpack_require__(714); +const pify = __webpack_require__(715); function type(fn, fn2, fp) { if (typeof fp !== 'string') { @@ -83542,7 +83719,7 @@ exports.symlinkSync = typeSync.bind(null, 'lstatSync', 'isSymbolicLink'); /***/ }), -/* 714 */ +/* 715 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -83633,17 +83810,17 @@ module.exports = (obj, opts) => { /***/ }), -/* 715 */ +/* 716 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const fs = __webpack_require__(133); const path = __webpack_require__(4); -const fastGlob = __webpack_require__(512); -const gitIgnore = __webpack_require__(716); -const pify = __webpack_require__(717); -const slash = __webpack_require__(718); +const fastGlob = __webpack_require__(513); +const gitIgnore = __webpack_require__(717); +const pify = __webpack_require__(718); +const slash = __webpack_require__(719); const DEFAULT_IGNORE = [ '**/node_modules/**', @@ -83741,7 +83918,7 @@ module.exports.sync = options => { /***/ }), -/* 716 */ +/* 717 */ /***/ (function(module, exports) { // A simple implementation of make-array @@ -84210,7 +84387,7 @@ module.exports = options => new IgnoreBase(options) /***/ }), -/* 717 */ +/* 718 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84285,7 +84462,7 @@ module.exports = (input, options) => { /***/ }), -/* 718 */ +/* 719 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84303,7 +84480,7 @@ module.exports = input => { /***/ }), -/* 719 */ +/* 720 */ /***/ (function(module, exports, __webpack_require__) { /*! @@ -84313,7 +84490,7 @@ module.exports = input => { * Released under the MIT License. */ -var isExtglob = __webpack_require__(302); +var isExtglob = __webpack_require__(303); var chars = { '{': '}', '(': ')', '[': ']'}; var strictRegex = /\\(.)|(^!|\*|[\].+)]\?|\[[^\\\]]+\]|\{[^\\}]+\}|\(\?[:!=][^\\)]+\)|\([^|]+\|[^\\)]+\))/; var relaxedRegex = /\\(.)|(^!|[*?{}()[\]]|\(\?)/; @@ -84357,17 +84534,17 @@ module.exports = function isGlob(str, options) { /***/ }), -/* 720 */ +/* 721 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const path = __webpack_require__(4); const {constants: fsConstants} = __webpack_require__(133); -const pEvent = __webpack_require__(721); -const CpFileError = __webpack_require__(724); -const fs = __webpack_require__(728); -const ProgressEmitter = __webpack_require__(731); +const pEvent = __webpack_require__(722); +const CpFileError = __webpack_require__(725); +const fs = __webpack_require__(729); +const ProgressEmitter = __webpack_require__(732); const cpFileAsync = async (source, destination, options, progressEmitter) => { let readError; @@ -84481,12 +84658,12 @@ module.exports.sync = (source, destination, options) => { /***/ }), -/* 721 */ +/* 722 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pTimeout = __webpack_require__(722); +const pTimeout = __webpack_require__(723); const symbolAsyncIterator = Symbol.asyncIterator || '@@asyncIterator'; @@ -84777,12 +84954,12 @@ module.exports.iterator = (emitter, event, options) => { /***/ }), -/* 722 */ +/* 723 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const pFinally = __webpack_require__(723); +const pFinally = __webpack_require__(724); class TimeoutError extends Error { constructor(message) { @@ -84828,7 +85005,7 @@ module.exports.TimeoutError = TimeoutError; /***/ }), -/* 723 */ +/* 724 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -84850,12 +85027,12 @@ module.exports = (promise, onFinally) => { /***/ }), -/* 724 */ +/* 725 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(725); +const NestedError = __webpack_require__(726); class CpFileError extends NestedError { constructor(message, nested) { @@ -84869,10 +85046,10 @@ module.exports = CpFileError; /***/ }), -/* 725 */ +/* 726 */ /***/ (function(module, exports, __webpack_require__) { -var inherits = __webpack_require__(726); +var inherits = __webpack_require__(727); var NestedError = function (message, nested) { this.nested = nested; @@ -84923,7 +85100,7 @@ module.exports = NestedError; /***/ }), -/* 726 */ +/* 727 */ /***/ (function(module, exports, __webpack_require__) { try { @@ -84931,12 +85108,12 @@ try { if (typeof util.inherits !== 'function') throw ''; module.exports = util.inherits; } catch (e) { - module.exports = __webpack_require__(727); + module.exports = __webpack_require__(728); } /***/ }), -/* 727 */ +/* 728 */ /***/ (function(module, exports) { if (typeof Object.create === 'function') { @@ -84965,16 +85142,16 @@ if (typeof Object.create === 'function') { /***/ }), -/* 728 */ +/* 729 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; const {promisify} = __webpack_require__(111); const fs = __webpack_require__(132); -const makeDir = __webpack_require__(729); -const pEvent = __webpack_require__(721); -const CpFileError = __webpack_require__(724); +const makeDir = __webpack_require__(730); +const pEvent = __webpack_require__(722); +const CpFileError = __webpack_require__(725); const stat = promisify(fs.stat); const lstat = promisify(fs.lstat); @@ -85071,7 +85248,7 @@ exports.copyFileSync = (source, destination, flags) => { /***/ }), -/* 729 */ +/* 730 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -85079,7 +85256,7 @@ exports.copyFileSync = (source, destination, flags) => { const fs = __webpack_require__(133); const path = __webpack_require__(4); const {promisify} = __webpack_require__(111); -const semver = __webpack_require__(730); +const semver = __webpack_require__(731); const useNativeRecursiveOption = semver.satisfies(process.version, '>=10.12.0'); @@ -85234,7 +85411,7 @@ module.exports.sync = (input, options) => { /***/ }), -/* 730 */ +/* 731 */ /***/ (function(module, exports) { exports = module.exports = SemVer @@ -86836,7 +87013,7 @@ function coerce (version, options) { /***/ }), -/* 731 */ +/* 732 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -86877,7 +87054,7 @@ module.exports = ProgressEmitter; /***/ }), -/* 732 */ +/* 733 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; @@ -86923,12 +87100,12 @@ exports.default = module.exports; /***/ }), -/* 733 */ +/* 734 */ /***/ (function(module, exports, __webpack_require__) { "use strict"; -const NestedError = __webpack_require__(734); +const NestedError = __webpack_require__(735); class CpyError extends NestedError { constructor(message, nested) { @@ -86942,7 +87119,7 @@ module.exports = CpyError; /***/ }), -/* 734 */ +/* 735 */ /***/ (function(module, exports, __webpack_require__) { var inherits = __webpack_require__(111).inherits; diff --git a/packages/kbn-pm/src/commands/bootstrap.test.ts b/packages/kbn-pm/src/commands/bootstrap.test.ts index 97505a66a1fff..956c4e72933ba 100644 --- a/packages/kbn-pm/src/commands/bootstrap.test.ts +++ b/packages/kbn-pm/src/commands/bootstrap.test.ts @@ -19,6 +19,7 @@ jest.mock('../utils/scripts'); jest.mock('../utils/link_project_executables'); +jest.mock('../utils/validate_yarn_lock'); import { resolve } from 'path'; diff --git a/packages/kbn-pm/src/commands/bootstrap.ts b/packages/kbn-pm/src/commands/bootstrap.ts index a559f9a20432a..7cf89c5f08f96 100644 --- a/packages/kbn-pm/src/commands/bootstrap.ts +++ b/packages/kbn-pm/src/commands/bootstrap.ts @@ -25,6 +25,8 @@ import { Project } from '../utils/project'; import { ICommand } from './'; import { getAllChecksums } from '../utils/project_checksums'; import { BootstrapCacheFile } from '../utils/bootstrap_cache_file'; +import { readYarnLock } from '../utils/yarn_lock'; +import { validateYarnLock } from '../utils/validate_yarn_lock'; export const BootstrapCommand: ICommand = { description: 'Install dependencies and crosslink projects', @@ -54,6 +56,10 @@ export const BootstrapCommand: ICommand = { } } + const yarnLock = await readYarnLock(kbn); + + await validateYarnLock(kbn, yarnLock); + await linkProjectExecutables(projects, projectGraph); /** @@ -63,7 +69,7 @@ export const BootstrapCommand: ICommand = { * have to, as it will slow down the bootstrapping process. */ - const checksums = await getAllChecksums(kbn, log); + const checksums = await getAllChecksums(kbn, log, yarnLock); const caches = new Map(); let cachedProjectCount = 0; diff --git a/packages/kbn-pm/src/utils/__snapshots__/link_project_executables.test.ts.snap b/packages/kbn-pm/src/utils/__snapshots__/link_project_executables.test.ts.snap index 5bda7b544e201..311e350f6e865 100644 --- a/packages/kbn-pm/src/utils/__snapshots__/link_project_executables.test.ts.snap +++ b/packages/kbn-pm/src/utils/__snapshots__/link_project_executables.test.ts.snap @@ -18,6 +18,7 @@ Object { "mkdirp": Array [], "readFile": Array [], "unlink": Array [], + "writeFile": Array [], } `; @@ -66,5 +67,6 @@ Object { ], "readFile": Array [], "unlink": Array [], + "writeFile": Array [], } `; diff --git a/packages/kbn-pm/src/utils/fs.ts b/packages/kbn-pm/src/utils/fs.ts index 44fc59bdeba96..21fd2c32b9c7b 100644 --- a/packages/kbn-pm/src/utils/fs.ts +++ b/packages/kbn-pm/src/utils/fs.ts @@ -25,6 +25,7 @@ import { promisify } from 'util'; const lstat = promisify(fs.lstat); export const readFile = promisify(fs.readFile); +export const writeFile = promisify(fs.writeFile); const symlink = promisify(fs.symlink); export const chmod = promisify(fs.chmod); const cmdShim = promisify(cmdShimCb); diff --git a/packages/kbn-pm/src/utils/kibana.ts b/packages/kbn-pm/src/utils/kibana.ts index 7fca4bd01822b..e48b61611d63f 100644 --- a/packages/kbn-pm/src/utils/kibana.ts +++ b/packages/kbn-pm/src/utils/kibana.ts @@ -22,6 +22,8 @@ import Path from 'path'; import multimatch from 'multimatch'; import isPathInside from 'is-path-inside'; +import { resolveDepsForProject, YarnLock } from './yarn_lock'; +import { Log } from './log'; import { ProjectMap, getProjects, includeTransitiveProjects } from './projects'; import { Project } from './project'; import { getProjectPaths } from '../config'; @@ -133,4 +135,26 @@ export class Kibana { isOutsideRepo(project: Project) { return !this.isPartOfRepo(project); } + + resolveAllProductionDependencies(yarnLock: YarnLock, log: Log) { + const kibanaDeps = resolveDepsForProject({ + project: this.kibanaProject, + yarnLock, + kbn: this, + includeDependentProject: true, + productionDepsOnly: true, + log, + })!; + + const xpackDeps = resolveDepsForProject({ + project: this.getProject('x-pack')!, + yarnLock, + kbn: this, + includeDependentProject: true, + productionDepsOnly: true, + log, + })!; + + return new Map([...kibanaDeps.entries(), ...xpackDeps.entries()]); + } } diff --git a/packages/kbn-pm/src/utils/project_checksums.ts b/packages/kbn-pm/src/utils/project_checksums.ts index 839c44f4f18c4..c13788c89bfaa 100644 --- a/packages/kbn-pm/src/utils/project_checksums.ts +++ b/packages/kbn-pm/src/utils/project_checksums.ts @@ -24,7 +24,7 @@ import { promisify } from 'util'; import execa from 'execa'; -import { readYarnLock, YarnLock } from './yarn_lock'; +import { YarnLock, resolveDepsForProject } from './yarn_lock'; import { ProjectMap } from '../utils/projects'; import { Project } from '../utils/project'; import { Kibana } from '../utils/kibana'; @@ -145,51 +145,6 @@ async function getLatestSha(project: Project, kbn: Kibana) { return stdout.trim() || undefined; } -/** - * Get a list of the absolute dependencies of this project, as resolved - * in the yarn.lock file, does not include other projects in the workspace - * or their dependencies - */ -function resolveDepsForProject(project: Project, yarnLock: YarnLock, kbn: Kibana, log: Log) { - /** map of [name@range, name@resolved] */ - const resolved = new Map(); - - const queue: Array<[string, string]> = Object.entries(project.allDependencies); - - while (queue.length) { - const [name, versionRange] = queue.shift()!; - const req = `${name}@${versionRange}`; - - if (resolved.has(req)) { - continue; - } - - if (!kbn.hasProject(name)) { - const pkg = yarnLock[req]; - if (!pkg) { - log.warning( - 'yarn.lock file is out of date, please run `yarn kbn bootstrap` to re-enable caching' - ); - return; - } - - const res = `${name}@${pkg.version}`; - resolved.set(req, res); - - const allDepsEntries = [ - ...Object.entries(pkg.dependencies || {}), - ...Object.entries(pkg.optionalDependencies || {}), - ]; - - for (const [childName, childVersionRange] of allDepsEntries) { - queue.push([childName, childVersionRange]); - } - } - } - - return Array.from(resolved.values()).sort((a, b) => a.localeCompare(b)); -} - /** * Get the checksum for a specific project in the workspace */ @@ -224,11 +179,22 @@ async function getChecksum( }) ); - const deps = await resolveDepsForProject(project, yarnLock, kbn, log); - if (!deps) { + const depMap = resolveDepsForProject({ + project, + yarnLock, + kbn, + log, + includeDependentProject: false, + productionDepsOnly: false, + }); + if (!depMap) { return; } + const deps = Array.from(depMap.values()) + .map(({ name, version }) => `${name}@${version}`) + .sort((a, b) => a.localeCompare(b)); + log.verbose(`[${project.name}] resolved %d deps`, deps.length); const checksum = JSON.stringify( @@ -256,10 +222,9 @@ async function getChecksum( * - un-committed changes * - resolved dependencies from yarn.lock referenced by project package.json */ -export async function getAllChecksums(kbn: Kibana, log: Log) { +export async function getAllChecksums(kbn: Kibana, log: Log, yarnLock: YarnLock) { const projects = kbn.getAllProjects(); const changesByProject = await getChangesForProjects(projects, kbn, log); - const yarnLock = await readYarnLock(kbn); /** map of [project.name, cacheKey] */ const cacheKeys: ChecksumMap = new Map(); diff --git a/packages/kbn-pm/src/utils/validate_yarn_lock.ts b/packages/kbn-pm/src/utils/validate_yarn_lock.ts new file mode 100644 index 0000000000000..e110dc4d921cf --- /dev/null +++ b/packages/kbn-pm/src/utils/validate_yarn_lock.ts @@ -0,0 +1,99 @@ +/* + * 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. + */ + +// @ts-expect-error published types are useless +import { stringify as stringifyLockfile } from '@yarnpkg/lockfile'; +import dedent from 'dedent'; + +import { writeFile } from './fs'; +import { Kibana } from './kibana'; +import { YarnLock } from './yarn_lock'; +import { log } from './log'; + +export async function validateYarnLock(kbn: Kibana, yarnLock: YarnLock) { + // look through all of the packages in the yarn.lock file to see if + // we have accidentally installed multiple lodash v4 versions + const lodash4Versions = new Set(); + const lodash4Reqs = new Set(); + for (const [req, dep] of Object.entries(yarnLock)) { + if (req.startsWith('lodash@') && dep.version.startsWith('4.')) { + lodash4Reqs.add(req); + lodash4Versions.add(dep.version); + } + } + + // if we find more than one lodash v4 version installed then delete + // lodash v4 requests from the yarn.lock file and prompt the user to + // retry bootstrap so that a single v4 version will be installed + if (lodash4Versions.size > 1) { + for (const req of lodash4Reqs) { + delete yarnLock[req]; + } + + await writeFile(kbn.getAbsolute('yarn.lock'), stringifyLockfile(yarnLock), 'utf8'); + + log.error(dedent` + + Multiple version of lodash v4 were detected, so they have been removed + from the yarn.lock file. Please rerun yarn kbn bootstrap to coalese the + lodash versions installed. + + If you still see this error when you re-bootstrap then you might need + to force a new dependency to use the latest version of lodash via the + "resolutions" field in package.json. + + If you have questions about this please reach out to the operations team. + + `); + + process.exit(1); + } + + // look through all the dependencies of production packages and production + // dependencies of those packages to determine if we're shipping any versions + // of lodash v3 in the distributable + const prodDependencies = kbn.resolveAllProductionDependencies(yarnLock, log); + const lodash3Versions = new Set(); + for (const dep of prodDependencies.values()) { + if (dep.name === 'lodash' && dep.version.startsWith('3.')) { + lodash3Versions.add(dep.version); + } + } + + // if any lodash v3 packages were found we abort and tell the user to fix things + if (lodash3Versions.size) { + log.error(dedent` + + Due to changes in the yarn.lock file and/or package.json files a version of + lodash 3 is now included in the production dependencies. To reduce the size of + our distributable and especially our front-end bundles we have decided to + prevent adding any new instances of lodash 3. + + Please inspect the changes to yarn.lock or package.json files to identify where + the lodash 3 version is coming from and remove it. + + If you have questions about this please reack out to the operations team. + + `); + + process.exit(1); + } + + log.success('yarn.lock analysis completed without any issues'); +} diff --git a/packages/kbn-pm/src/utils/yarn_lock.ts b/packages/kbn-pm/src/utils/yarn_lock.ts index f46240c0e1d2e..953341915e232 100644 --- a/packages/kbn-pm/src/utils/yarn_lock.ts +++ b/packages/kbn-pm/src/utils/yarn_lock.ts @@ -17,14 +17,16 @@ * under the License. */ -// @ts-ignore published types are worthless +// @ts-expect-error published types are worthless import { parse as parseLockfile } from '@yarnpkg/lockfile'; import { readFile } from '../utils/fs'; import { Kibana } from '../utils/kibana'; +import { Project } from '../utils/project'; +import { Log } from '../utils/log'; export interface YarnLock { - /** a simple map of version@versionrange tags to metadata about a package */ + /** a simple map of name@versionrange tags to metadata about a package */ [key: string]: { /** resolved version installed for this pacakge */ version: string; @@ -61,3 +63,82 @@ export async function readYarnLock(kbn: Kibana): Promise { return {}; } + +/** + * Get a list of the absolute dependencies of this project, as resolved + * in the yarn.lock file, does not include other projects in the workspace + * or their dependencies + */ +export function resolveDepsForProject({ + project: rootProject, + yarnLock, + kbn, + log, + productionDepsOnly, + includeDependentProject, +}: { + project: Project; + yarnLock: YarnLock; + kbn: Kibana; + log: Log; + productionDepsOnly: boolean; + includeDependentProject: boolean; +}) { + /** map of [name@range, { name, version }] */ + const resolved = new Map(); + + const seenProjects = new Set(); + const projectQueue: Project[] = [rootProject]; + const depQueue: Array<[string, string]> = []; + + while (projectQueue.length) { + const project = projectQueue.shift()!; + if (seenProjects.has(project)) { + continue; + } + seenProjects.add(project); + + const projectDeps = Object.entries( + productionDepsOnly ? project.productionDependencies : project.allDependencies + ); + for (const [name, versionRange] of projectDeps) { + depQueue.push([name, versionRange]); + } + + while (depQueue.length) { + const [name, versionRange] = depQueue.shift()!; + const req = `${name}@${versionRange}`; + + if (resolved.has(req)) { + continue; + } + + if (includeDependentProject && kbn.hasProject(name)) { + projectQueue.push(kbn.getProject(name)!); + } + + if (!kbn.hasProject(name)) { + const pkg = yarnLock[req]; + if (!pkg) { + log.warning( + 'yarn.lock file is out of date, please run `yarn kbn bootstrap` to re-enable caching' + ); + return; + } + + resolved.set(req, { name, version: pkg.version }); + + const allDepsEntries = [ + ...Object.entries(pkg.dependencies || {}), + ...Object.entries(pkg.optionalDependencies || {}), + ]; + + for (const [childName, childVersionRange] of allDepsEntries) { + depQueue.push([childName, childVersionRange]); + } + } + } + } + + return resolved; +} diff --git a/packages/kbn-ui-shared-deps/entry.js b/packages/kbn-ui-shared-deps/entry.js index 365b84b83bd5f..69344174a2dc6 100644 --- a/packages/kbn-ui-shared-deps/entry.js +++ b/packages/kbn-ui-shared-deps/entry.js @@ -51,6 +51,8 @@ export const ElasticEui = require('@elastic/eui'); export const ElasticEuiLibServices = require('@elastic/eui/lib/services'); export const ElasticEuiLibServicesFormat = require('@elastic/eui/lib/services/format'); export const ElasticEuiChartsTheme = require('@elastic/eui/dist/eui_charts_theme'); +export const Lodash = require('lodash'); +export const LodashFp = require('lodash/fp'); import * as Theme from './theme.ts'; export { Theme }; diff --git a/packages/kbn-ui-shared-deps/index.js b/packages/kbn-ui-shared-deps/index.js index 84ca3435e02bc..a5d6954fd5cc0 100644 --- a/packages/kbn-ui-shared-deps/index.js +++ b/packages/kbn-ui-shared-deps/index.js @@ -62,5 +62,7 @@ exports.externals = { '@elastic/eui/dist/eui_charts_theme': '__kbnSharedDeps__.ElasticEuiChartsTheme', '@elastic/eui/dist/eui_theme_light.json': '__kbnSharedDeps__.Theme.euiLightVars', '@elastic/eui/dist/eui_theme_dark.json': '__kbnSharedDeps__.Theme.euiDarkVars', + lodash: '__kbnSharedDeps__.Lodash', + 'lodash/fp': '__kbnSharedDeps__.LodashFp', }; exports.publicPathLoader = require.resolve('./public_path_loader'); diff --git a/packages/kbn-ui-shared-deps/package.json b/packages/kbn-ui-shared-deps/package.json index 372126c4418f5..278e8efd2d29e 100644 --- a/packages/kbn-ui-shared-deps/package.json +++ b/packages/kbn-ui-shared-deps/package.json @@ -20,6 +20,7 @@ "core-js": "^3.6.4", "custom-event-polyfill": "^0.3.0", "jquery": "^3.5.0", + "lodash": "^4.17.20", "mini-css-extract-plugin": "0.8.0", "moment": "^2.24.0", "moment-timezone": "^0.5.27", diff --git a/renovate.json5 b/renovate.json5 index 3b2b0453014aa..17391c2f83827 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -27,8 +27,12 @@ ], }, separateMajorMinor: false, - masterIssue: false, + masterIssue: true, rangeStrategy: 'bump', + semanticCommits: false, + vulnerabilityAlerts: { + enabled: false, + }, npm: { lockFileMaintenance: { enabled: false, @@ -49,17 +53,10 @@ { groupName: 'vega related modules', packageNames: ['vega', 'vega-lite', 'vega-schema-url-parser', 'vega-tooltip'], - reviewers: ['team:elastic/kibana-app'], + reviewers: ['team:kibana-app'], labels: ['Feature:Lens', 'Team:KibanaApp'], enabled: true, }, ], }, - prConcurrentLimit: 0, - vulnerabilityAlerts: { - enabled: false, - }, - rebaseStalePrs: false, - rebaseConflictedPrs: false, - semanticCommits: false, } diff --git a/src/core/server/capabilities/capabilities_service.mock.ts b/src/core/server/capabilities/capabilities_service.mock.ts index 7d134f9592dc7..72824693705d9 100644 --- a/src/core/server/capabilities/capabilities_service.mock.ts +++ b/src/core/server/capabilities/capabilities_service.mock.ts @@ -18,6 +18,7 @@ */ import type { PublicMethodsOf } from '@kbn/utility-types'; import { CapabilitiesService, CapabilitiesSetup, CapabilitiesStart } from './capabilities_service'; +import { Capabilities } from './types'; const createSetupContractMock = () => { const setupContract: jest.Mocked = { @@ -34,6 +35,14 @@ const createStartContractMock = () => { return setupContract; }; +const createCapabilitiesMock = (): Capabilities => { + return { + navLinks: {}, + management: {}, + catalogue: {}, + }; +}; + type CapabilitiesServiceContract = PublicMethodsOf; const createMock = () => { const mocked: jest.Mocked = { @@ -47,4 +56,5 @@ export const capabilitiesServiceMock = { create: createMock, createSetupContract: createSetupContractMock, createStartContract: createStartContractMock, + createCapabilities: createCapabilitiesMock, }; diff --git a/src/core/server/mocks.ts b/src/core/server/mocks.ts index 7e001ffe28100..e9b345317e999 100644 --- a/src/core/server/mocks.ts +++ b/src/core/server/mocks.ts @@ -54,6 +54,7 @@ export { metricsServiceMock } from './metrics/metrics_service.mock'; export { renderingMock } from './rendering/rendering_service.mock'; export { statusServiceMock } from './status/status_service.mock'; export { contextServiceMock } from './context/context_service.mock'; +export { capabilitiesServiceMock } from './capabilities/capabilities_service.mock'; export function pluginInitializerContextConfigMock(config: T) { const globalConfig: SharedGlobalConfig = { diff --git a/src/plugins/data/server/server.api.md b/src/plugins/data/server/server.api.md index f465ece697a70..9cf7234c4a9ff 100644 --- a/src/plugins/data/server/server.api.md +++ b/src/plugins/data/server/server.api.md @@ -44,6 +44,7 @@ import { DeleteDocumentParams } from 'elasticsearch'; import { DeleteScriptParams } from 'elasticsearch'; import { DeleteTemplateParams } from 'elasticsearch'; import { Duration } from 'moment'; +import { ElasticsearchClient as ElasticsearchClient_2 } from 'kibana/server'; import { Ensure } from '@kbn/utility-types'; import { EnvironmentMode } from '@kbn/config'; import { ErrorToastOptions } from 'src/core/public/notifications'; diff --git a/src/plugins/kibana_usage_collection/server/collectors/application_usage/telemetry_application_usage_collector.test.ts b/src/plugins/kibana_usage_collection/server/collectors/application_usage/telemetry_application_usage_collector.test.ts index 709736a37d802..23a77c2d4c288 100644 --- a/src/plugins/kibana_usage_collection/server/collectors/application_usage/telemetry_application_usage_collector.test.ts +++ b/src/plugins/kibana_usage_collection/server/collectors/application_usage/telemetry_application_usage_collector.test.ts @@ -17,7 +17,11 @@ * under the License. */ -import { savedObjectsRepositoryMock, loggingSystemMock } from '../../../../../core/server/mocks'; +import { + savedObjectsRepositoryMock, + loggingSystemMock, + elasticsearchServiceMock, +} from '../../../../../core/server/mocks'; import { CollectorOptions, createUsageCollectionSetupMock, @@ -50,6 +54,7 @@ describe('telemetry_application_usage', () => { const getUsageCollector = jest.fn(); const registerType = jest.fn(); const callCluster = jest.fn(); + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; beforeAll(() => registerApplicationUsageCollector(logger, usageCollectionMock, registerType, getUsageCollector) @@ -62,7 +67,7 @@ describe('telemetry_application_usage', () => { test('if no savedObjectClient initialised, return undefined', async () => { expect(collector.isReady()).toBe(false); - expect(await collector.fetch(callCluster)).toBeUndefined(); + expect(await collector.fetch(callCluster, esClient)).toBeUndefined(); jest.runTimersToTime(ROLL_INDICES_START); }); @@ -80,7 +85,7 @@ describe('telemetry_application_usage', () => { jest.runTimersToTime(ROLL_TOTAL_INDICES_INTERVAL); // Force rollTotals to run expect(collector.isReady()).toBe(true); - expect(await collector.fetch(callCluster)).toStrictEqual({}); + expect(await collector.fetch(callCluster, esClient)).toStrictEqual({}); expect(savedObjectClient.bulkCreate).not.toHaveBeenCalled(); }); @@ -137,7 +142,7 @@ describe('telemetry_application_usage', () => { jest.runTimersToTime(ROLL_TOTAL_INDICES_INTERVAL); // Force rollTotals to run - expect(await collector.fetch(callCluster)).toStrictEqual({ + expect(await collector.fetch(callCluster, esClient)).toStrictEqual({ appId: { clicks_total: total + 1 + 10, clicks_7_days: total + 1, @@ -197,7 +202,7 @@ describe('telemetry_application_usage', () => { getUsageCollector.mockImplementation(() => savedObjectClient); - expect(await collector.fetch(callCluster)).toStrictEqual({ + expect(await collector.fetch(callCluster, esClient)).toStrictEqual({ appId: { clicks_total: 1, clicks_7_days: 0, diff --git a/src/plugins/telemetry/server/telemetry_collection/__tests__/get_cluster_stats.js b/src/plugins/maps_legacy/public/get_service_settings.ts similarity index 52% rename from src/plugins/telemetry/server/telemetry_collection/__tests__/get_cluster_stats.js rename to src/plugins/maps_legacy/public/get_service_settings.ts index d1354608385f6..8d0656237976d 100644 --- a/src/plugins/telemetry/server/telemetry_collection/__tests__/get_cluster_stats.js +++ b/src/plugins/maps_legacy/public/get_service_settings.ts @@ -17,33 +17,23 @@ * under the License. */ -import expect from '@kbn/expect'; -import sinon from 'sinon'; +import { lazyLoadMapsLegacyModules } from './lazy_load_bundle'; +// @ts-expect-error +import { getMapsLegacyConfig } from './kibana_services'; +import { IServiceSettings } from './map/service_settings_types'; -import { TIMEOUT } from '../constants'; -import { getClusterStats } from '../get_cluster_stats'; +let loadPromise: Promise; -export function mockGetClusterStats(callCluster, clusterStats, req) { - callCluster - .withArgs(req, 'cluster.stats', { - timeout: TIMEOUT, - }) - .returns(clusterStats); +export async function getServiceSettings(): Promise { + if (typeof loadPromise !== 'undefined') { + return loadPromise; + } - callCluster - .withArgs('cluster.stats', { - timeout: TIMEOUT, - }) - .returns(clusterStats); -} - -describe.skip('get_cluster_stats', () => { - it('uses callCluster to get cluster.stats API', async () => { - const callCluster = sinon.stub(); - const response = Promise.resolve({}); - - mockGetClusterStats(callCluster, response); - - expect(getClusterStats(callCluster)).to.be(response); + loadPromise = new Promise(async (resolve) => { + const modules = await lazyLoadMapsLegacyModules(); + const config = getMapsLegacyConfig(); + // @ts-expect-error + resolve(new modules.ServiceSettings(config, config.tilemap)); }); -}); + return loadPromise; +} diff --git a/src/plugins/maps_legacy/public/index.ts b/src/plugins/maps_legacy/public/index.ts index 8f14cd1b15e2c..d31f23f4bc4a6 100644 --- a/src/plugins/maps_legacy/public/index.ts +++ b/src/plugins/maps_legacy/public/index.ts @@ -19,8 +19,6 @@ // @ts-ignore import { PluginInitializerContext } from 'kibana/public'; -// @ts-ignore -import { L } from './leaflet'; import { MapsLegacyPlugin } from './plugin'; // @ts-ignore import * as colorUtil from './map/color_util'; @@ -29,14 +27,14 @@ import { KibanaMapLayer } from './map/kibana_map_layer'; // @ts-ignore import { convertToGeoJson } from './map/convert_to_geojson'; // @ts-ignore -import { scaleBounds, getPrecision, geoContains } from './map/decode_geo_hash'; +import { getPrecision, geoContains } from './map/decode_geo_hash'; import { VectorLayer, FileLayerField, FileLayer, TmsLayer, IServiceSettings, -} from './map/service_settings'; +} from './map/service_settings_types'; // @ts-ignore import { mapTooltipProvider } from './tooltip_provider'; @@ -48,7 +46,6 @@ export function plugin(initializerContext: PluginInitializerContext) { /** @public */ export { - scaleBounds, getPrecision, geoContains, colorUtil, @@ -60,7 +57,6 @@ export { FileLayer, TmsLayer, mapTooltipProvider, - L, }; export * from './common/types'; @@ -68,5 +64,7 @@ export { ORIGIN } from './common/constants/origin'; export { WmsOptions } from './components/wms_options'; +export { lazyLoadMapsLegacyModules } from './lazy_load_bundle'; + export type MapsLegacyPluginSetup = ReturnType; export type MapsLegacyPluginStart = ReturnType; diff --git a/src/plugins/telemetry/server/telemetry_collection/__tests__/get_cluster_info.js b/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts similarity index 58% rename from src/plugins/telemetry/server/telemetry_collection/__tests__/get_cluster_info.js rename to src/plugins/maps_legacy/public/lazy_load_bundle/index.ts index fe83b76cd1158..292949503a616 100644 --- a/src/plugins/telemetry/server/telemetry_collection/__tests__/get_cluster_info.js +++ b/src/plugins/maps_legacy/public/lazy_load_bundle/index.ts @@ -17,23 +17,27 @@ * under the License. */ -import expect from '@kbn/expect'; -import sinon from 'sinon'; +let loadModulesPromise: Promise; -import { getClusterInfo } from '../get_cluster_info'; - -export function mockGetClusterInfo(callCluster, clusterInfo, req) { - callCluster.withArgs(req, 'info').returns(clusterInfo); - callCluster.withArgs('info').returns(clusterInfo); +interface LazyLoadedMapsLegacyModules { + KibanaMap: unknown; + L: unknown; + ServiceSettings: unknown; } -describe('get_cluster_info', () => { - it('uses callCluster to get info API', () => { - const callCluster = sinon.stub(); - const response = Promise.resolve({}); +export async function lazyLoadMapsLegacyModules(): Promise { + if (typeof loadModulesPromise !== 'undefined') { + return loadModulesPromise; + } - mockGetClusterInfo(callCluster, response); + loadModulesPromise = new Promise(async (resolve) => { + const { KibanaMap, L, ServiceSettings } = await import('./lazy'); - expect(getClusterInfo(callCluster)).to.be(response); + resolve({ + KibanaMap, + L, + ServiceSettings, + }); }); -}); + return loadModulesPromise; +} diff --git a/src/plugins/maps_legacy/public/lazy_load_bundle/lazy/index.ts b/src/plugins/maps_legacy/public/lazy_load_bundle/lazy/index.ts new file mode 100644 index 0000000000000..5031b29e74b9a --- /dev/null +++ b/src/plugins/maps_legacy/public/lazy_load_bundle/lazy/index.ts @@ -0,0 +1,25 @@ +/* + * 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. + */ + +// @ts-expect-error +export { KibanaMap } from '../../map/kibana_map'; +// @ts-expect-error +export { ServiceSettings } from '../../map/service_settings'; +// @ts-expect-error +export { L } from '../../leaflet'; diff --git a/src/plugins/maps_legacy/public/map/base_maps_visualization.js b/src/plugins/maps_legacy/public/map/base_maps_visualization.js index 2d78fdc246e19..406dae43c9b5e 100644 --- a/src/plugins/maps_legacy/public/map/base_maps_visualization.js +++ b/src/plugins/maps_legacy/public/map/base_maps_visualization.js @@ -17,25 +17,22 @@ * under the License. */ -import _ from 'lodash'; import { i18n } from '@kbn/i18n'; import * as Rx from 'rxjs'; import { filter, first } from 'rxjs/operators'; import { getEmsTileLayerId, getUiSettings, getToasts } from '../kibana_services'; +import { lazyLoadMapsLegacyModules } from '../lazy_load_bundle'; +import { getServiceSettings } from '../get_service_settings'; const WMS_MINZOOM = 0; const WMS_MAXZOOM = 22; //increase this to 22. Better for WMS -export function BaseMapsVisualizationProvider(getKibanaMap, mapServiceSettings) { +export function BaseMapsVisualizationProvider() { /** * Abstract base class for a visualization consisting of a map with a single baselayer. * @class BaseMapsVisualization * @constructor */ - - const serviceSettings = mapServiceSettings; - const toastService = getToasts(); - return class BaseMapsVisualization { constructor(element, vis) { this.vis = vis; @@ -95,9 +92,9 @@ export function BaseMapsVisualizationProvider(getKibanaMap, mapServiceSettings) const centerFromUIState = uiState.get('mapCenter'); options.zoom = !isNaN(zoomFromUiState) ? zoomFromUiState : this.vis.params.mapZoom; options.center = centerFromUIState ? centerFromUIState : this.vis.params.mapCenter; - const services = { toastService }; - this._kibanaMap = getKibanaMap(this._container, options, services); + const modules = await lazyLoadMapsLegacyModules(); + this._kibanaMap = new modules.KibanaMap(this._container, options); this._kibanaMap.setMinZoom(WMS_MINZOOM); //use a default this._kibanaMap.setMaxZoom(WMS_MAXZOOM); //use a default @@ -138,6 +135,7 @@ export function BaseMapsVisualizationProvider(getKibanaMap, mapServiceSettings) const mapParams = this._getMapsParams(); if (!this._tmsConfigured()) { try { + const serviceSettings = await getServiceSettings(); const tmsServices = await serviceSettings.getTMSServices(); const userConfiguredTmsLayer = tmsServices[0]; const initBasemapLayer = userConfiguredTmsLayer @@ -147,7 +145,7 @@ export function BaseMapsVisualizationProvider(getKibanaMap, mapServiceSettings) this._setTmsLayer(initBasemapLayer); } } catch (e) { - toastService.addWarning(e.message); + getToasts().addWarning(e.message); return; } return; @@ -174,7 +172,7 @@ export function BaseMapsVisualizationProvider(getKibanaMap, mapServiceSettings) this._setTmsLayer(selectedTmsLayer); } } catch (tmsLoadingError) { - toastService.addWarning(tmsLoadingError.message); + getToasts().addWarning(tmsLoadingError.message); } } @@ -189,13 +187,14 @@ export function BaseMapsVisualizationProvider(getKibanaMap, mapServiceSettings) isDesaturated = true; } const isDarkMode = getUiSettings().get('theme:darkMode'); + const serviceSettings = await getServiceSettings(); const meta = await serviceSettings.getAttributesForTMSLayer( tmsLayer, isDesaturated, isDarkMode ); const showZoomMessage = serviceSettings.shouldShowZoomMessage(tmsLayer); - const options = _.cloneDeep(tmsLayer); + const options = { ...tmsLayer }; delete options.id; delete options.subdomains; this._kibanaMap.setBaseLayer({ @@ -228,12 +227,11 @@ export function BaseMapsVisualizationProvider(getKibanaMap, mapServiceSettings) } _getMapsParams() { - return _.assign( - {}, - this.vis.type.visConfig.defaults, - { type: this.vis.type.name }, - this._params - ); + return { + ...this.vis.type.visConfig.defaults, + type: this.vis.type.name, + ...this._params, + }; } _whenBaseLayerIsLoaded() { diff --git a/src/plugins/maps_legacy/public/map/decode_geo_hash.ts b/src/plugins/maps_legacy/public/map/decode_geo_hash.ts index 8c39ada03a46b..65184a8244777 100644 --- a/src/plugins/maps_legacy/public/map/decode_geo_hash.ts +++ b/src/plugins/maps_legacy/public/map/decode_geo_hash.ts @@ -17,8 +17,6 @@ * under the License. */ -import _ from 'lodash'; - interface DecodedGeoHash { latitude: number[]; longitude: number[]; @@ -101,33 +99,6 @@ interface GeoBoundingBox { bottom_right: GeoBoundingBoxCoordinate; } -export function scaleBounds(bounds: GeoBoundingBox): GeoBoundingBox { - const scale = 0.5; // scale bounds by 50% - - const topLeft = bounds.top_left; - const bottomRight = bounds.bottom_right; - let latDiff = _.round(Math.abs(topLeft.lat - bottomRight.lat), 5); - const lonDiff = _.round(Math.abs(bottomRight.lon - topLeft.lon), 5); - // map height can be zero when vis is first created - if (latDiff === 0) latDiff = lonDiff; - - const latDelta = latDiff * scale; - let topLeftLat = _.round(topLeft.lat, 5) + latDelta; - if (topLeftLat > 90) topLeftLat = 90; - let bottomRightLat = _.round(bottomRight.lat, 5) - latDelta; - if (bottomRightLat < -90) bottomRightLat = -90; - const lonDelta = lonDiff * scale; - let topLeftLon = _.round(topLeft.lon, 5) - lonDelta; - if (topLeftLon < -180) topLeftLon = -180; - let bottomRightLon = _.round(bottomRight.lon, 5) + lonDelta; - if (bottomRightLon > 180) bottomRightLon = 180; - - return { - top_left: { lat: topLeftLat, lon: topLeftLon }, - bottom_right: { lat: bottomRightLat, lon: bottomRightLon }, - }; -} - export function geoContains(collar?: GeoBoundingBox, bounds?: GeoBoundingBox) { if (!bounds || !collar) return false; // test if bounds top_left is outside collar diff --git a/src/plugins/maps_legacy/public/map/grid_dimensions.js b/src/plugins/maps_legacy/public/map/grid_dimensions.js index d146adf2ca67f..0f84e972104ba 100644 --- a/src/plugins/maps_legacy/public/map/grid_dimensions.js +++ b/src/plugins/maps_legacy/public/map/grid_dimensions.js @@ -17,8 +17,6 @@ * under the License. */ -import _ from 'lodash'; - // geohash precision mapping of geohash grid cell dimensions (width x height, in meters) at equator. // https://www.elastic.co/guide/en/elasticsearch/reference/current/search-aggregations-bucket-geohashgrid-aggregation.html#_cell_dimensions_at_the_equator const gridAtEquator = { @@ -37,5 +35,5 @@ const gridAtEquator = { }; export function gridDimensions(precision) { - return _.get(gridAtEquator, precision); + return gridAtEquator[precision]; } diff --git a/src/plugins/maps_legacy/public/map/kibana_map.js b/src/plugins/maps_legacy/public/map/kibana_map.js index ad5d2c089b875..3948692e55676 100644 --- a/src/plugins/maps_legacy/public/map/kibana_map.js +++ b/src/plugins/maps_legacy/public/map/kibana_map.js @@ -20,7 +20,7 @@ import { EventEmitter } from 'events'; import { createZoomWarningMsg } from './map_messages'; import $ from 'jquery'; -import _ from 'lodash'; +import { get, isEqual, escape } from 'lodash'; import { zoomToPrecision } from './zoom_to_precision'; import { i18n } from '@kbn/i18n'; import { ORIGIN } from '../common/constants/origin'; @@ -380,7 +380,7 @@ export class KibanaMap extends EventEmitter { const distanceX = latLngC.distanceTo(latLngX); // calculate distance between c and x (latitude) const distanceY = latLngC.distanceTo(latLngY); // calculate distance between c and y (longitude) - return _.min([distanceX, distanceY]); + return Math.min(distanceX, distanceY); } _getLeafletBounds(resizeOnFail) { @@ -544,7 +544,7 @@ export class KibanaMap extends EventEmitter { } setBaseLayer(settings) { - if (_.isEqual(settings, this._baseLayerSettings)) { + if (isEqual(settings, this._baseLayerSettings)) { return; } @@ -567,7 +567,7 @@ export class KibanaMap extends EventEmitter { let baseLayer; if (settings.baseLayerType === 'wms') { //This is user-input that is rendered with the Leaflet attribution control. Needs to be sanitized. - this._baseLayerSettings.options.attribution = _.escape(settings.options.attribution); + this._baseLayerSettings.options.attribution = escape(settings.options.attribution); baseLayer = this._getWMSBaseLayer(settings.options); } else if (settings.baseLayerType === 'tms') { baseLayer = this._getTMSBaseLayer(settings.options); @@ -661,7 +661,7 @@ export class KibanaMap extends EventEmitter { _updateDesaturation() { const tiles = $('img.leaflet-tile-loaded'); // Don't apply client-side styling to EMS basemaps - if (_.get(this._baseLayerSettings, 'options.origin') === ORIGIN.EMS) { + if (get(this._baseLayerSettings, 'options.origin') === ORIGIN.EMS) { tiles.addClass('filters-off'); } else { if (this._baseLayerIsDesaturated) { diff --git a/src/plugins/maps_legacy/public/map/service_settings.d.ts b/src/plugins/maps_legacy/public/map/service_settings_types.ts similarity index 100% rename from src/plugins/maps_legacy/public/map/service_settings.d.ts rename to src/plugins/maps_legacy/public/map/service_settings_types.ts diff --git a/src/plugins/maps_legacy/public/plugin.ts b/src/plugins/maps_legacy/public/plugin.ts index 8c9f1e9cef194..17cee226cb70c 100644 --- a/src/plugins/maps_legacy/public/plugin.ts +++ b/src/plugins/maps_legacy/public/plugin.ts @@ -22,15 +22,12 @@ import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'kibana/p // @ts-ignore import { setToasts, setUiSettings, setKibanaVersion, setMapsLegacyConfig } from './kibana_services'; // @ts-ignore -import { ServiceSettings } from './map/service_settings'; -// @ts-ignore import { getPrecision, getZoomPrecision } from './map/precision'; -// @ts-ignore -import { KibanaMap } from './map/kibana_map'; import { MapsLegacyPluginSetup, MapsLegacyPluginStart } from './index'; import { MapsLegacyConfig } from '../config'; // @ts-ignore import { BaseMapsVisualizationProvider } from './map/base_maps_visualization'; +import { getServiceSettings } from './get_service_settings'; /** * These are the interfaces with your public contracts. You should export these @@ -67,17 +64,13 @@ export class MapsLegacyPlugin implements Plugin new KibanaMap(...args); - const getBaseMapsVis = () => - new BaseMapsVisualizationProvider(getKibanaMapFactoryProvider, serviceSettings); + const getBaseMapsVis = () => new BaseMapsVisualizationProvider(); return { - serviceSettings, + getServiceSettings, getZoomPrecision, getPrecision, config, - getKibanaMapFactoryProvider, getBaseMapsVis, }; } diff --git a/src/plugins/region_map/public/choropleth_layer.js b/src/plugins/region_map/public/choropleth_layer.js index 30fa8b544cdec..14a91e189e0d5 100644 --- a/src/plugins/region_map/public/choropleth_layer.js +++ b/src/plugins/region_map/public/choropleth_layer.js @@ -33,7 +33,7 @@ const EMPTY_STYLE = { fillOpacity: 0, }; -export default class ChoroplethLayer extends KibanaMapLayer { +export class ChoroplethLayer extends KibanaMapLayer { static _doInnerJoin(sortedMetrics, sortedGeojsonFeatures, joinField) { let j = 0; for (let i = 0; i < sortedGeojsonFeatures.length; i++) { @@ -71,7 +71,16 @@ export default class ChoroplethLayer extends KibanaMapLayer { } } - constructor(name, attribution, format, showAllShapes, meta, layerConfig, serviceSettings) { + constructor( + name, + attribution, + format, + showAllShapes, + meta, + layerConfig, + serviceSettings, + leaflet + ) { super(); this._serviceSettings = serviceSettings; this._metrics = null; @@ -84,9 +93,10 @@ export default class ChoroplethLayer extends KibanaMapLayer { this._showAllShapes = showAllShapes; this._layerName = name; this._layerConfig = layerConfig; + this._leaflet = leaflet; // eslint-disable-next-line no-undef - this._leafletLayer = L.geoJson(null, { + this._leafletLayer = this._leaflet.geoJson(null, { onEachFeature: (feature, layer) => { layer.on('click', () => { this.emit('select', feature.properties[this._joinField]); @@ -97,7 +107,7 @@ export default class ChoroplethLayer extends KibanaMapLayer { const tooltipContents = this._tooltipFormatter(feature); if (!location) { // eslint-disable-next-line no-undef - const leafletGeojson = L.geoJson(feature); + const leafletGeojson = this._leaflet.geoJson(feature); location = leafletGeojson.getBounds().getCenter(); } this.emit('showTooltip', { @@ -425,7 +435,7 @@ CORS configuration of the server permits requests from the Kibana application on const { min, max } = getMinMax(this._metrics); // eslint-disable-next-line no-undef - const boundsOfAllFeatures = new L.LatLngBounds(); + const boundsOfAllFeatures = new this._leaflet.LatLngBounds(); return { leafletStyleFunction: (geojsonFeature) => { const match = geojsonFeature.__kbnJoinedMetric; @@ -433,7 +443,7 @@ CORS configuration of the server permits requests from the Kibana application on return emptyStyle(); } // eslint-disable-next-line no-undef - const boundsOfFeature = L.geoJson(geojsonFeature).getBounds(); + const boundsOfFeature = this._leaflet.geoJson(geojsonFeature).getBounds(); boundsOfAllFeatures.extend(boundsOfFeature); return { diff --git a/src/plugins/region_map/public/components/region_map_options.tsx b/src/plugins/region_map/public/components/region_map_options.tsx index be3d7fe86ab3f..4d564d7347a1e 100644 --- a/src/plugins/region_map/public/components/region_map_options.tsx +++ b/src/plugins/region_map/public/components/region_map_options.tsx @@ -37,11 +37,11 @@ const mapFieldForOption = ({ description, name }: FileLayerField) => ({ }); export type RegionMapOptionsProps = { - serviceSettings: IServiceSettings; + getServiceSettings: () => Promise; } & VisOptionsProps; function RegionMapOptions(props: RegionMapOptionsProps) { - const { serviceSettings, stateParams, vis, setValue } = props; + const { getServiceSettings, stateParams, vis, setValue } = props; const { vectorLayers } = vis.type.editorConfig.collections; const vectorLayerOptions = useMemo(() => vectorLayers.map(mapLayerForOption), [vectorLayers]); const fieldOptions = useMemo( @@ -54,10 +54,11 @@ function RegionMapOptions(props: RegionMapOptionsProps) { const setEmsHotLink = useCallback( async (layer: VectorLayer) => { + const serviceSettings = await getServiceSettings(); const emsHotLink = await serviceSettings.getEMSHotLink(layer); setValue('emsHotLink', emsHotLink); }, - [setValue, serviceSettings] + [setValue, getServiceSettings] ); const setLayer = useCallback( diff --git a/src/plugins/region_map/public/plugin.ts b/src/plugins/region_map/public/plugin.ts index ec9ee94310578..c641c16a8112b 100644 --- a/src/plugins/region_map/public/plugin.ts +++ b/src/plugins/region_map/public/plugin.ts @@ -41,7 +41,7 @@ import { KibanaLegacyStart } from '../../kibana_legacy/public'; interface RegionMapVisualizationDependencies { uiSettings: IUiSettingsClient; regionmapsConfig: RegionMapsConfig; - serviceSettings: IServiceSettings; + getServiceSettings: () => Promise; BaseMapsVisualization: any; } @@ -93,7 +93,7 @@ export class RegionMapPlugin implements Plugin = { uiSettings: core.uiSettings, regionmapsConfig: config as RegionMapsConfig, - serviceSettings: mapsLegacy.serviceSettings, + getServiceSettings: mapsLegacy.getServiceSettings, BaseMapsVisualization: mapsLegacy.getBaseMapsVis(), }; diff --git a/src/plugins/region_map/public/region_map_type.js b/src/plugins/region_map/public/region_map_type.js index def95950e6151..036726f6a4a9e 100644 --- a/src/plugins/region_map/public/region_map_type.js +++ b/src/plugins/region_map/public/region_map_type.js @@ -26,7 +26,7 @@ import { Schemas } from '../../vis_default_editor/public'; import { ORIGIN } from '../../maps_legacy/public'; export function createRegionMapTypeDefinition(dependencies) { - const { uiSettings, regionmapsConfig, serviceSettings } = dependencies; + const { uiSettings, regionmapsConfig, getServiceSettings } = dependencies; const visualization = createRegionMapVisualization(dependencies); return { @@ -54,7 +54,9 @@ provided base maps, or add your own. Darker colors represent higher values.', }, visualization, editorConfig: { - optionsTemplate: (props) => , + optionsTemplate: (props) => ( + + ), collections: { colorSchemas: truncatedColorSchemas, vectorLayers: [], @@ -97,6 +99,7 @@ provided base maps, or add your own. Darker colors represent higher values.', ]), }, setup: async (vis) => { + const serviceSettings = await getServiceSettings(); const tmsLayers = await serviceSettings.getTMSServices(); vis.type.editorConfig.collections.tmsLayers = tmsLayers; if (!vis.params.wms.selectedTmsLayer && tmsLayers.length) { diff --git a/src/plugins/region_map/public/region_map_visualization.js b/src/plugins/region_map/public/region_map_visualization.js index 43959c367558f..9b20a35630c86 100644 --- a/src/plugins/region_map/public/region_map_visualization.js +++ b/src/plugins/region_map/public/region_map_visualization.js @@ -18,18 +18,16 @@ */ import { i18n } from '@kbn/i18n'; -import ChoroplethLayer from './choropleth_layer'; import { getFormatService, getNotifications, getKibanaLegacy } from './kibana_services'; import { truncatedColorMaps } from '../../charts/public'; import { tooltipFormatter } from './tooltip_formatter'; -import { mapTooltipProvider, ORIGIN } from '../../maps_legacy/public'; -import _ from 'lodash'; +import { mapTooltipProvider, ORIGIN, lazyLoadMapsLegacyModules } from '../../maps_legacy/public'; export function createRegionMapVisualization({ regionmapsConfig, - serviceSettings, uiSettings, BaseMapsVisualization, + getServiceSettings, }) { return class RegionMapsVisualization extends BaseMapsVisualization { constructor(container, vis) { @@ -71,7 +69,7 @@ export function createRegionMapVisualization({ return; } - this._updateChoroplethLayerForNewMetrics( + await this._updateChoroplethLayerForNewMetrics( selectedLayer.name, selectedLayer.attribution, this._params.showAllShapes, @@ -98,10 +96,13 @@ export function createRegionMapVisualization({ // Do not use the selectedLayer from the visState. // These settings are stored in the URL and can be used to inject dirty display content. + const { escape } = await import('lodash'); + if ( fileLayerConfig.isEMS || //Hosted by EMS. Metadata needs to be resolved through EMS (fileLayerConfig.layerId && fileLayerConfig.layerId.startsWith(`${ORIGIN.EMS}.`)) //fallback for older saved objects ) { + const serviceSettings = await getServiceSettings(); return await serviceSettings.loadFileLayerConfig(fileLayerConfig); } @@ -113,7 +114,7 @@ export function createRegionMapVisualization({ if (configuredLayer) { return { ...configuredLayer, - attribution: _.escape(configuredLayer.attribution ? configuredLayer.attribution : ''), + attribution: escape(configuredLayer.attribution ? configuredLayer.attribution : ''), }; } @@ -133,7 +134,7 @@ export function createRegionMapVisualization({ return; } - this._updateChoroplethLayerForNewProperties( + await this._updateChoroplethLayerForNewProperties( selectedLayer.name, selectedLayer.attribution, this._params.showAllShapes @@ -151,24 +152,24 @@ export function createRegionMapVisualization({ ); } - _updateChoroplethLayerForNewMetrics(name, attribution, showAllData, newMetrics) { + async _updateChoroplethLayerForNewMetrics(name, attribution, showAllData, newMetrics) { if ( this._choroplethLayer && this._choroplethLayer.canReuseInstanceForNewMetrics(name, showAllData, newMetrics) ) { return; } - return this._recreateChoroplethLayer(name, attribution, showAllData); + await this._recreateChoroplethLayer(name, attribution, showAllData); } - _updateChoroplethLayerForNewProperties(name, attribution, showAllData) { + async _updateChoroplethLayerForNewProperties(name, attribution, showAllData) { if (this._choroplethLayer && this._choroplethLayer.canReuseInstance(name, showAllData)) { return; } - return this._recreateChoroplethLayer(name, attribution, showAllData); + await this._recreateChoroplethLayer(name, attribution, showAllData); } - _recreateChoroplethLayer(name, attribution, showAllData) { + async _recreateChoroplethLayer(name, attribution, showAllData) { this._kibanaMap.removeLayer(this._choroplethLayer); if (this._choroplethLayer) { @@ -179,9 +180,10 @@ export function createRegionMapVisualization({ showAllData, this._params.selectedLayer.meta, this._params.selectedLayer, - serviceSettings + await getServiceSettings() ); } else { + const { ChoroplethLayer } = await import('./choropleth_layer'); this._choroplethLayer = new ChoroplethLayer( name, attribution, @@ -189,7 +191,8 @@ export function createRegionMapVisualization({ showAllData, this._params.selectedLayer.meta, this._params.selectedLayer, - serviceSettings + await getServiceSettings(), + (await lazyLoadMapsLegacyModules()).L ); } diff --git a/src/plugins/telemetry/server/plugin.ts b/src/plugins/telemetry/server/plugin.ts index 005c5f96d98d0..dfbbe3355e69c 100644 --- a/src/plugins/telemetry/server/plugin.ts +++ b/src/plugins/telemetry/server/plugin.ts @@ -34,6 +34,7 @@ import { SavedObjectsClient, Plugin, Logger, + IClusterClient, } from '../../../core/server'; import { registerRoutes } from './routes'; import { registerCollection } from './telemetry_collection'; @@ -83,6 +84,7 @@ export class TelemetryPlugin implements Plugin) { this.logger = initializerContext.logger.get(); @@ -102,8 +104,11 @@ export class TelemetryPlugin implements Plugin this.elasticsearchClient + ); const router = http.createRouter(); registerRoutes({ @@ -126,14 +131,12 @@ export class TelemetryPlugin implements Plugin { - const { savedObjects, uiSettings } = core; + public async start(core: CoreStart, { telemetryCollectionManager }: TelemetryPluginsDepsStart) { + const { savedObjects, uiSettings, elasticsearch } = core; this.savedObjectsClient = savedObjects.createInternalRepository(); const savedObjectsClient = new SavedObjectsClient(this.savedObjectsClient); this.uiSettingsClient = uiSettings.asScopedToClient(savedObjectsClient); + this.elasticsearchClient = elasticsearch.client; try { await handleOldSettings(savedObjectsClient, this.uiSettingsClient); diff --git a/src/plugins/telemetry/server/telemetry_collection/__tests__/get_local_stats.js b/src/plugins/telemetry/server/telemetry_collection/__tests__/get_local_stats.js deleted file mode 100644 index 8541745faea3b..0000000000000 --- a/src/plugins/telemetry/server/telemetry_collection/__tests__/get_local_stats.js +++ /dev/null @@ -1,267 +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 expect from '@kbn/expect'; -import sinon from 'sinon'; -import { merge, omit } from 'lodash'; - -import { TIMEOUT } from '../constants'; -import { mockGetClusterInfo } from './get_cluster_info'; -import { mockGetClusterStats } from './get_cluster_stats'; - -import { getLocalStats, handleLocalStats } from '../get_local_stats'; - -const mockUsageCollection = (kibanaUsage = {}) => ({ - bulkFetch: () => kibanaUsage, - toObject: (data) => data, -}); - -const getMockServer = (getCluster = sinon.stub()) => ({ - log(tags, message) { - console.log({ tags, message }); - }, - config() { - return { - get(item) { - switch (item) { - case 'pkg.version': - return '8675309-snapshot'; - default: - throw Error(`unexpected config.get('${item}') received.`); - } - }, - }; - }, - plugins: { - elasticsearch: { getCluster }, - }, -}); -function mockGetNodesUsage(callCluster, nodesUsage, req) { - callCluster - .withArgs( - req, - { - method: 'GET', - path: '/_nodes/usage', - query: { - timeout: TIMEOUT, - }, - }, - 'transport.request' - ) - .returns(nodesUsage); -} - -function mockGetLocalStats(callCluster, clusterInfo, clusterStats, nodesUsage, req) { - mockGetClusterInfo(callCluster, clusterInfo, req); - mockGetClusterStats(callCluster, clusterStats, req); - mockGetNodesUsage(callCluster, nodesUsage, req); -} - -describe('get_local_stats', () => { - const clusterUuid = 'abc123'; - const clusterName = 'my-cool-cluster'; - const version = '2.3.4'; - const clusterInfo = { - cluster_uuid: clusterUuid, - cluster_name: clusterName, - version: { - number: version, - }, - }; - const nodesUsage = [ - { - node_id: 'some_node_id', - timestamp: 1588617023177, - since: 1588616945163, - rest_actions: { - nodes_usage_action: 1, - create_index_action: 1, - document_get_action: 1, - search_action: 19, - nodes_info_action: 36, - }, - aggregations: { - terms: { - bytes: 2, - }, - scripted_metric: { - other: 7, - }, - }, - }, - ]; - const clusterStats = { - _nodes: { failed: 123 }, - cluster_name: 'real-cool', - indices: { totally: 456 }, - nodes: { yup: 'abc' }, - random: 123, - }; - - const kibana = { - kibana: { - great: 'googlymoogly', - versions: [{ version: '8675309', count: 1 }], - }, - kibana_stats: { - os: { - platform: 'rocky', - platformRelease: 'iv', - }, - }, - localization: { - locale: 'en', - labelsCount: 0, - integrities: {}, - }, - sun: { chances: 5 }, - clouds: { chances: 95 }, - rain: { chances: 2 }, - snow: { chances: 0 }, - }; - - const clusterStatsWithNodesUsage = { - ...clusterStats, - nodes: merge(clusterStats.nodes, { usage: nodesUsage }), - }; - const combinedStatsResult = { - collection: 'local', - cluster_uuid: clusterUuid, - cluster_name: clusterName, - version, - cluster_stats: omit(clusterStatsWithNodesUsage, '_nodes', 'cluster_name'), - stack_stats: { - kibana: { - great: 'googlymoogly', - count: 1, - indices: 1, - os: { - platforms: [{ platform: 'rocky', count: 1 }], - platformReleases: [{ platformRelease: 'iv', count: 1 }], - }, - versions: [{ version: '8675309', count: 1 }], - plugins: { - localization: { - locale: 'en', - labelsCount: 0, - integrities: {}, - }, - sun: { chances: 5 }, - clouds: { chances: 95 }, - rain: { chances: 2 }, - snow: { chances: 0 }, - }, - }, - }, - }; - - const context = { - logger: console, - version: '8.0.0', - }; - - describe('handleLocalStats', () => { - it('returns expected object without xpack and kibana data', () => { - const result = handleLocalStats( - clusterInfo, - clusterStatsWithNodesUsage, - void 0, - void 0, - context - ); - expect(result.cluster_uuid).to.eql(combinedStatsResult.cluster_uuid); - expect(result.cluster_name).to.eql(combinedStatsResult.cluster_name); - expect(result.cluster_stats).to.eql(combinedStatsResult.cluster_stats); - expect(result.version).to.be('2.3.4'); - expect(result.collection).to.be('local'); - expect(result.license).to.be(undefined); - expect(result.stack_stats).to.eql({ kibana: undefined, data: undefined }); - }); - - it('returns expected object with xpack', () => { - const result = handleLocalStats( - clusterInfo, - clusterStatsWithNodesUsage, - void 0, - void 0, - context - ); - const { stack_stats: stack, ...cluster } = result; - expect(cluster.collection).to.be(combinedStatsResult.collection); - expect(cluster.cluster_uuid).to.be(combinedStatsResult.cluster_uuid); - expect(cluster.cluster_name).to.be(combinedStatsResult.cluster_name); - expect(stack.kibana).to.be(undefined); // not mocked for this test - expect(stack.data).to.be(undefined); // not mocked for this test - - expect(cluster.version).to.eql(combinedStatsResult.version); - expect(cluster.cluster_stats).to.eql(combinedStatsResult.cluster_stats); - expect(cluster.license).to.eql(combinedStatsResult.license); - expect(stack.xpack).to.eql(combinedStatsResult.stack_stats.xpack); - }); - }); - - describe.skip('getLocalStats', () => { - it('returns expected object without xpack data when X-Pack fails to respond', async () => { - const callClusterUsageFailed = sinon.stub(); - const usageCollection = mockUsageCollection(); - mockGetLocalStats( - callClusterUsageFailed, - Promise.resolve(clusterInfo), - Promise.resolve(clusterStats), - Promise.resolve(nodesUsage) - ); - const result = await getLocalStats([], { - server: getMockServer(), - callCluster: callClusterUsageFailed, - usageCollection, - }); - expect(result.cluster_uuid).to.eql(combinedStatsResult.cluster_uuid); - expect(result.cluster_name).to.eql(combinedStatsResult.cluster_name); - expect(result.cluster_stats).to.eql(combinedStatsResult.cluster_stats); - expect(result.cluster_stats.nodes).to.eql(combinedStatsResult.cluster_stats.nodes); - expect(result.version).to.be('2.3.4'); - expect(result.collection).to.be('local'); - - // license and xpack usage info come from the same cluster call - expect(result.license).to.be(undefined); - expect(result.stack_stats.xpack).to.be(undefined); - }); - - it('returns expected object with xpack and kibana data', async () => { - const callCluster = sinon.stub(); - const usageCollection = mockUsageCollection(kibana); - mockGetLocalStats( - callCluster, - Promise.resolve(clusterInfo), - Promise.resolve(clusterStats), - Promise.resolve(nodesUsage) - ); - - const result = await getLocalStats([], { - server: getMockServer(callCluster), - usageCollection, - callCluster, - }); - - expect(result.stack_stats.xpack).to.eql(combinedStatsResult.stack_stats.xpack); - expect(result.stack_stats.kibana).to.eql(combinedStatsResult.stack_stats.kibana); - }); - }); -}); diff --git a/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.test.ts b/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.test.ts new file mode 100644 index 0000000000000..459b18d252e17 --- /dev/null +++ b/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.test.ts @@ -0,0 +1,57 @@ +/* + * 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 { elasticsearchServiceMock } from '../../../../../src/core/server/mocks'; +import { getClusterInfo } from './get_cluster_info'; + +export function mockGetClusterInfo(clusterInfo: any) { + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + esClient.info + // @ts-ignore we only care about the response body + .mockResolvedValue( + // @ts-ignore we only care about the response body + { + body: { ...clusterInfo }, + } + ); + return esClient; +} + +describe('get_cluster_info using the elasticsearch client', () => { + it('uses the esClient to get info API', async () => { + const clusterInfo = { + cluster_uuid: '1234', + cluster_name: 'testCluster', + version: { + number: '7.9.2', + build_flavor: 'default', + build_type: 'docker', + build_hash: 'b5ca9c58fb664ca8bf', + build_date: '2020-07-21T16:40:44.668009Z', + build_snapshot: false, + lucene_version: '8.5.1', + minimum_wire_compatibility_version: '6.8.0', + minimum_index_compatibility_version: '6.0.0-beta1', + }, + }; + const esClient = mockGetClusterInfo(clusterInfo); + + expect(await getClusterInfo(esClient)).toStrictEqual(clusterInfo); + }); +}); diff --git a/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.ts b/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.ts index 4a33356ee9761..407f3325c3a9f 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_cluster_info.ts @@ -17,7 +17,7 @@ * under the License. */ -import { LegacyAPICaller } from 'kibana/server'; +import { ElasticsearchClient } from 'src/core/server'; // This can be removed when the ES client improves the types export interface ESClusterInfo { @@ -25,24 +25,24 @@ export interface ESClusterInfo { cluster_name: string; version: { number: string; - build_flavor: string; - build_type: string; - build_hash: string; - build_date: string; + build_flavor?: string; + build_type?: string; + build_hash?: string; + build_date?: string; build_snapshot?: boolean; - lucene_version: string; - minimum_wire_compatibility_version: string; - minimum_index_compatibility_version: string; + lucene_version?: string; + minimum_wire_compatibility_version?: string; + minimum_index_compatibility_version?: string; }; } - /** * Get the cluster info from the connected cluster. * * This is the equivalent to GET / * - * @param {function} callCluster The callWithInternalUser handler (exposed for testing) + * @param {function} esClient The asInternalUser handler (exposed for testing) */ -export function getClusterInfo(callCluster: LegacyAPICaller) { - return callCluster('info'); +export async function getClusterInfo(esClient: ElasticsearchClient) { + const { body } = await esClient.info(); + return body; } diff --git a/src/plugins/telemetry/server/telemetry_collection/get_cluster_stats.test.ts b/src/plugins/telemetry/server/telemetry_collection/get_cluster_stats.test.ts new file mode 100644 index 0000000000000..81551c0c4d93d --- /dev/null +++ b/src/plugins/telemetry/server/telemetry_collection/get_cluster_stats.test.ts @@ -0,0 +1,44 @@ +/* + * 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 { elasticsearchServiceMock } from '../../../../../src/core/server/mocks'; +import { getClusterStats } from './get_cluster_stats'; +import { TIMEOUT } from './constants'; + +export function mockGetClusterStats(clusterStats: any) { + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + esClient.cluster.stats.mockResolvedValue(clusterStats); + return esClient; +} + +describe('get_cluster_stats', () => { + it('uses the esClient to get the response from the `cluster.stats` API', async () => { + const response = Promise.resolve({ body: { cluster_uuid: '1234' } }); + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + esClient.cluster.stats.mockImplementationOnce( + // @ts-ignore the method only cares about the response body + async (_params = { timeout: TIMEOUT }) => { + return response; + } + ); + const result = getClusterStats(esClient); + expect(esClient.cluster.stats).toHaveBeenCalledWith({ timeout: TIMEOUT }); + expect(result).toStrictEqual(response); + }); +}); diff --git a/src/plugins/telemetry/server/telemetry_collection/get_cluster_stats.ts b/src/plugins/telemetry/server/telemetry_collection/get_cluster_stats.ts index d7c0110a99c6f..d2a64e4878679 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_cluster_stats.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_cluster_stats.ts @@ -18,23 +18,23 @@ */ import { ClusterDetailsGetter } from 'src/plugins/telemetry_collection_manager/server'; -import { LegacyAPICaller } from 'kibana/server'; +import { ElasticsearchClient } from 'src/core/server'; import { TIMEOUT } from './constants'; /** * Get the cluster stats from the connected cluster. * * This is the equivalent to GET /_cluster/stats?timeout=30s. */ -export async function getClusterStats(callCluster: LegacyAPICaller) { - return await callCluster('cluster.stats', { - timeout: TIMEOUT, - }); +export async function getClusterStats(esClient: ElasticsearchClient) { + const { body } = await esClient.cluster.stats({ timeout: TIMEOUT }); + return body; } /** * Get the cluster uuids from the connected cluster. */ -export const getClusterUuids: ClusterDetailsGetter = async ({ callCluster }) => { - const result = await getClusterStats(callCluster); - return [{ clusterUuid: result.cluster_uuid }]; +export const getClusterUuids: ClusterDetailsGetter = async ({ esClient }) => { + const { body } = await esClient.cluster.stats({ timeout: TIMEOUT }); + + return [{ clusterUuid: body.cluster_uuid }]; }; diff --git a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts index dee718decdc1f..bb5eb7f6b726d 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.test.ts @@ -19,6 +19,7 @@ import { buildDataTelemetryPayload, getDataTelemetry } from './get_data_telemetry'; import { DATA_DATASETS_INDEX_PATTERNS, DATA_DATASETS_INDEX_PATTERNS_UNIQUE } from './constants'; +import { elasticsearchServiceMock } from '../../../../../../src/core/server/mocks'; describe('get_data_telemetry', () => { describe('DATA_DATASETS_INDEX_PATTERNS', () => { @@ -195,13 +196,15 @@ describe('get_data_telemetry', () => { describe('getDataTelemetry', () => { test('it returns the base payload (all 0s) because no indices are found', async () => { - const callCluster = mockCallCluster(); - await expect(getDataTelemetry(callCluster)).resolves.toStrictEqual([]); + const esClient = mockEsClient(); + await expect(getDataTelemetry(esClient)).resolves.toStrictEqual([]); + expect(esClient.indices.getMapping).toHaveBeenCalledTimes(1); + expect(esClient.indices.stats).toHaveBeenCalledTimes(1); }); test('can only see the index mappings, but not the stats', async () => { - const callCluster = mockCallCluster(['filebeat-12314']); - await expect(getDataTelemetry(callCluster)).resolves.toStrictEqual([ + const esClient = mockEsClient(['filebeat-12314']); + await expect(getDataTelemetry(esClient)).resolves.toStrictEqual([ { pattern_name: 'filebeat', shipper: 'filebeat', @@ -209,10 +212,12 @@ describe('get_data_telemetry', () => { ecs_index_count: 0, }, ]); + expect(esClient.indices.getMapping).toHaveBeenCalledTimes(1); + expect(esClient.indices.stats).toHaveBeenCalledTimes(1); }); test('can see the mappings and the stats', async () => { - const callCluster = mockCallCluster( + const esClient = mockEsClient( ['filebeat-12314'], { isECS: true }, { @@ -221,7 +226,7 @@ describe('get_data_telemetry', () => { }, } ); - await expect(getDataTelemetry(callCluster)).resolves.toStrictEqual([ + await expect(getDataTelemetry(esClient)).resolves.toStrictEqual([ { pattern_name: 'filebeat', shipper: 'filebeat', @@ -234,7 +239,7 @@ describe('get_data_telemetry', () => { }); test('find an index that does not match any index pattern but has mappings metadata', async () => { - const callCluster = mockCallCluster( + const esClient = mockEsClient( ['cannot_match_anything'], { isECS: true, dataStreamType: 'traces', shipper: 'my-beat' }, { @@ -245,7 +250,7 @@ describe('get_data_telemetry', () => { }, } ); - await expect(getDataTelemetry(callCluster)).resolves.toStrictEqual([ + await expect(getDataTelemetry(esClient)).resolves.toStrictEqual([ { data_stream: { dataset: undefined, type: 'traces' }, shipper: 'my-beat', @@ -258,45 +263,51 @@ describe('get_data_telemetry', () => { }); test('return empty array when there is an error', async () => { - const callCluster = jest.fn().mockRejectedValue(new Error('Something went terribly wrong')); - await expect(getDataTelemetry(callCluster)).resolves.toStrictEqual([]); + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + esClient.indices.getMapping.mockRejectedValue(new Error('Something went terribly wrong')); + esClient.indices.stats.mockRejectedValue(new Error('Something went terribly wrong')); + await expect(getDataTelemetry(esClient)).resolves.toStrictEqual([]); }); }); }); - -function mockCallCluster( - indicesMappings: string[] = [], +function mockEsClient( + indicesMappings: string[] = [], // an array of `indices` to get mappings from. { isECS = false, dataStreamDataset = '', dataStreamType = '', shipper = '' } = {}, indexStats: any = {} ) { - return jest.fn().mockImplementation(async (method: string, opts: any) => { - if (method === 'indices.getMapping') { - return Object.fromEntries( - indicesMappings.map((index) => [ - index, - { - mappings: { - ...(shipper && { _meta: { beat: shipper } }), - properties: { - ...(isECS && { ecs: { properties: { version: { type: 'keyword' } } } }), - ...((dataStreamType || dataStreamDataset) && { - data_stream: { - properties: { - ...(dataStreamDataset && { - dataset: { type: 'constant_keyword', value: dataStreamDataset }, - }), - ...(dataStreamType && { - type: { type: 'constant_keyword', value: dataStreamType }, - }), - }, + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + // @ts-ignore + esClient.indices.getMapping.mockImplementationOnce(async () => { + const body = Object.fromEntries( + indicesMappings.map((index) => [ + index, + { + mappings: { + ...(shipper && { _meta: { beat: shipper } }), + properties: { + ...(isECS && { ecs: { properties: { version: { type: 'keyword' } } } }), + ...((dataStreamType || dataStreamDataset) && { + data_stream: { + properties: { + ...(dataStreamDataset && { + dataset: { type: 'constant_keyword', value: dataStreamDataset }, + }), + ...(dataStreamType && { + type: { type: 'constant_keyword', value: dataStreamType }, + }), }, - }), - }, + }, + }), }, }, - ]) - ); - } - return indexStats; + }, + ]) + ); + return { body }; + }); + // @ts-ignore + esClient.indices.stats.mockImplementationOnce(async () => { + return { body: indexStats }; }); + return esClient; } diff --git a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.ts b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.ts index f4734dde251cc..67769793cbfdf 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/get_data_telemetry.ts @@ -16,8 +16,8 @@ * specific language governing permissions and limitations * under the License. */ +import { ElasticsearchClient } from 'src/core/server'; -import { LegacyAPICaller } from 'kibana/server'; import { DATA_DATASETS_INDEX_PATTERNS_UNIQUE, DataPatternName, @@ -224,42 +224,50 @@ interface IndexMappings { }; } -export async function getDataTelemetry(callCluster: LegacyAPICaller) { +export async function getDataTelemetry(esClient: ElasticsearchClient) { try { const index = [ ...DATA_DATASETS_INDEX_PATTERNS_UNIQUE.map(({ pattern }) => pattern), '*-*-*', // Include data-streams aliases `{type}-{dataset}-{namespace}` ]; - const [indexMappings, indexStats]: [IndexMappings, IndexStats] = await Promise.all([ + const indexMappingsParams: { index: string; filter_path: string[] } = { // GET */_mapping?filter_path=*.mappings._meta.beat,*.mappings.properties.ecs.properties.version.type,*.mappings.properties.dataset.properties.type.value,*.mappings.properties.dataset.properties.name.value - callCluster('indices.getMapping', { - index: '*', // Request all indices because filter_path already filters out the indices without any of those fields - filterPath: [ - // _meta.beat tells the shipper - '*.mappings._meta.beat', - // _meta.package.name tells the Ingest Manager's package - '*.mappings._meta.package.name', - // _meta.managed_by is usually populated by Ingest Manager for the UI to identify it - '*.mappings._meta.managed_by', - // Does it have `ecs.version` in the mappings? => It follows the ECS conventions - '*.mappings.properties.ecs.properties.version.type', + index: '*', // Request all indices because filter_path already filters out the indices without any of those fields + filter_path: [ + // _meta.beat tells the shipper + '*.mappings._meta.beat', + // _meta.package.name tells the Ingest Manager's package + '*.mappings._meta.package.name', + // _meta.managed_by is usually populated by Ingest Manager for the UI to identify it + '*.mappings._meta.managed_by', + // Does it have `ecs.version` in the mappings? => It follows the ECS conventions + '*.mappings.properties.ecs.properties.version.type', - // If `data_stream.type` is a `constant_keyword`, it can be reported as a type - '*.mappings.properties.data_stream.properties.type.value', - // If `data_stream.dataset` is a `constant_keyword`, it can be reported as the dataset - '*.mappings.properties.data_stream.properties.dataset.value', - ], - }), + // If `data_stream.type` is a `constant_keyword`, it can be reported as a type + '*.mappings.properties.data_stream.properties.type.value', + // If `data_stream.dataset` is a `constant_keyword`, it can be reported as the dataset + '*.mappings.properties.data_stream.properties.dataset.value', + ], + }; + const indicesStatsParams: { + index: string | string[] | undefined; + level: 'cluster' | 'indices' | 'shards' | undefined; + metric: string[]; + filter_path: string[]; + } = { // GET /_stats/docs,store?level=indices&filter_path=indices.*.total - callCluster('indices.stats', { - index, - level: 'indices', - metric: ['docs', 'store'], - filterPath: ['indices.*.total'], - }), + index, + level: 'indices', + metric: ['docs', 'store'], + filter_path: ['indices.*.total'], + }; + const [{ body: indexMappings }, { body: indexStats }] = await Promise.all([ + esClient.indices.getMapping(indexMappingsParams), + esClient.indices.stats(indicesStatsParams), ]); const indexNames = Object.keys({ ...indexMappings, ...indexStats?.indices }); + const indices = indexNames.map((name) => { const baseIndexInfo = { name, diff --git a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/index.ts b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/index.ts index d056d1c9f299f..0e2ab98a24cba 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/index.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_data_telemetry/index.ts @@ -20,8 +20,8 @@ export { DATA_TELEMETRY_ID } from './constants'; export { - DataTelemetryIndex, - DataTelemetryPayload, getDataTelemetry, buildDataTelemetryPayload, + DataTelemetryPayload, + DataTelemetryIndex, } from './get_data_telemetry'; diff --git a/src/plugins/telemetry/server/telemetry_collection/get_kibana.ts b/src/plugins/telemetry/server/telemetry_collection/get_kibana.ts index 5d27774a630a5..0ef9815a4eadb 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_kibana.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_kibana.ts @@ -21,6 +21,7 @@ import { omit } from 'lodash'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; import { LegacyAPICaller } from 'kibana/server'; import { StatsCollectionContext } from 'src/plugins/telemetry_collection_manager/server'; +import { ElasticsearchClient } from 'src/core/server'; export interface KibanaUsageStats { kibana: { @@ -48,7 +49,6 @@ export function handleKibanaStats( logger.warn('No Kibana stats returned from usage collectors'); return; } - const { kibana, kibana_stats: kibanaStats, ...plugins } = response; const os = { @@ -83,8 +83,9 @@ export function handleKibanaStats( export async function getKibana( usageCollection: UsageCollectionSetup, - callWithInternalUser: LegacyAPICaller + callWithInternalUser: LegacyAPICaller, + asInternalUser: ElasticsearchClient ): Promise { - const usage = await usageCollection.bulkFetch(callWithInternalUser); + const usage = await usageCollection.bulkFetch(callWithInternalUser, asInternalUser); return usageCollection.toObject(usage); } diff --git a/src/plugins/telemetry/server/telemetry_collection/get_local_license.ts b/src/plugins/telemetry/server/telemetry_collection/get_local_license.ts index d41904c6d8e0e..879416cda62fc 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_local_license.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_local_license.ts @@ -17,44 +17,41 @@ * under the License. */ -import { LegacyAPICaller } from 'kibana/server'; import { ESLicense, LicenseGetter } from 'src/plugins/telemetry_collection_manager/server'; +import { ElasticsearchClient } from 'src/core/server'; let cachedLicense: ESLicense | undefined; -function fetchLicense(callCluster: LegacyAPICaller, local: boolean) { - return callCluster<{ license: ESLicense }>('transport.request', { - method: 'GET', - path: '/_license', - query: { - local, - // For versions >= 7.6 and < 8.0, this flag is needed otherwise 'platinum' is returned for 'enterprise' license. - accept_enterprise: 'true', - }, +async function fetchLicense(esClient: ElasticsearchClient, local: boolean) { + const { body } = await esClient.license.get({ + local, + // For versions >= 7.6 and < 8.0, this flag is needed otherwise 'platinum' is returned for 'enterprise' license. + accept_enterprise: true, }); + return body; } - /** * Get the cluster's license from the connected node. * - * This is the equivalent of GET /_license?local=true . + * This is the equivalent of GET /_license?local=true&accept_enterprise=true. * * Like any X-Pack related API, X-Pack must installed for this to work. + * + * In OSS we'll get a 400 response using the new elasticsearch client. */ -async function getLicenseFromLocalOrMaster(callCluster: LegacyAPICaller) { - // Fetching the local license is cheaper than getting it from the master and good enough - const { license } = await fetchLicense(callCluster, true).catch(async (err) => { +async function getLicenseFromLocalOrMaster(esClient: ElasticsearchClient) { + // Fetching the local license is cheaper than getting it from the master node and good enough + const { license } = await fetchLicense(esClient, true).catch(async (err) => { if (cachedLicense) { try { // Fallback to the master node's license info - const response = await fetchLicense(callCluster, false); + const response = await fetchLicense(esClient, false); return response; } catch (masterError) { - if (masterError.statusCode === 404) { + if ([400, 404].includes(masterError.statusCode)) { // If the master node does not have a license, we can assume there is no license cachedLicense = undefined; } else { - // Any other errors from the master node, throw and do not send any telemetry throw err; } } @@ -68,9 +65,8 @@ async function getLicenseFromLocalOrMaster(callCluster: LegacyAPICaller) { return license; } -export const getLocalLicense: LicenseGetter = async (clustersDetails, { callCluster }) => { - const license = await getLicenseFromLocalOrMaster(callCluster); - +export const getLocalLicense: LicenseGetter = async (clustersDetails, { esClient }) => { + const license = await getLicenseFromLocalOrMaster(esClient); // It should be called only with 1 cluster element in the clustersDetails array, but doing reduce just in case. return clustersDetails.reduce((acc, { clusterUuid }) => ({ ...acc, [clusterUuid]: license }), {}); }; diff --git a/src/plugins/telemetry/server/telemetry_collection/get_local_stats.test.ts b/src/plugins/telemetry/server/telemetry_collection/get_local_stats.test.ts new file mode 100644 index 0000000000000..0c8b0b249f7d1 --- /dev/null +++ b/src/plugins/telemetry/server/telemetry_collection/get_local_stats.test.ts @@ -0,0 +1,259 @@ +/* + * 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 { merge, omit } from 'lodash'; + +import { getLocalStats, handleLocalStats } from './get_local_stats'; +import { usageCollectionPluginMock } from '../../../usage_collection/server/mocks'; +import { elasticsearchServiceMock } from '../../../../../src/core/server/mocks'; + +function mockUsageCollection(kibanaUsage = {}) { + const usageCollection = usageCollectionPluginMock.createSetupContract(); + usageCollection.bulkFetch = jest.fn().mockResolvedValue(kibanaUsage); + usageCollection.toObject = jest.fn().mockImplementation((data: any) => data); + return usageCollection; +} +// set up successful call mocks for info, cluster stats, nodes usage and data telemetry +function mockGetLocalStats(clusterInfo: any, clusterStats: any) { + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + esClient.info + // @ts-ignore we only care about the response body + .mockResolvedValue( + // @ts-ignore we only care about the response body + { + body: { ...clusterInfo }, + } + ); + esClient.cluster.stats + // @ts-ignore we only care about the response body + .mockResolvedValue({ body: { ...clusterStats } }); + esClient.nodes.usage.mockResolvedValue( + // @ts-ignore we only care about the response body + { + body: { + cluster_name: 'testCluster', + nodes: { + some_node_id: { + timestamp: 1588617023177, + since: 1588616945163, + rest_actions: { + nodes_usage_action: 1, + create_index_action: 1, + document_get_action: 1, + search_action: 19, + nodes_info_action: 36, + }, + aggregations: { + terms: { + bytes: 2, + }, + scripted_metric: { + other: 7, + }, + }, + }, + }, + }, + } + ); + // @ts-ignore we only care about the response body + esClient.indices.getMapping.mockResolvedValue({ body: { mappings: {} } }); + // @ts-ignore we only care about the response body + esClient.indices.stats.mockResolvedValue({ body: { indices: {} } }); + return esClient; +} + +describe('get_local_stats', () => { + const clusterUuid = 'abc123'; + const clusterName = 'my-cool-cluster'; + const version = '2.3.4'; + const clusterInfo = { + cluster_uuid: clusterUuid, + cluster_name: clusterName, + version: { number: version }, + }; + const nodesUsage = [ + { + node_id: 'some_node_id', + timestamp: 1588617023177, + since: 1588616945163, + rest_actions: { + nodes_usage_action: 1, + create_index_action: 1, + document_get_action: 1, + search_action: 19, + nodes_info_action: 36, + }, + aggregations: { + terms: { + bytes: 2, + }, + scripted_metric: { + other: 7, + }, + }, + }, + ]; + const clusterStats = { + _nodes: { failed: 123 }, + cluster_name: 'real-cool', + indices: { totally: 456 }, + nodes: { yup: 'abc' }, + random: 123, + }; + + const kibana = { + kibana: { + great: 'googlymoogly', + versions: [{ version: '8675309', count: 1 }], + }, + kibana_stats: { + os: { + platform: 'rocky', + platformRelease: 'iv', + }, + }, + localization: { + locale: 'en', + labelsCount: 0, + integrities: {}, + }, + sun: { chances: 5 }, + clouds: { chances: 95 }, + rain: { chances: 2 }, + snow: { chances: 0 }, + }; + + const clusterStatsWithNodesUsage = { + ...clusterStats, + nodes: merge(clusterStats.nodes, { usage: { nodes: nodesUsage } }), + }; + + const combinedStatsResult = { + collection: 'local', + cluster_uuid: clusterUuid, + cluster_name: clusterName, + version, + cluster_stats: omit(clusterStatsWithNodesUsage, '_nodes', 'cluster_name'), + stack_stats: { + kibana: { + great: 'googlymoogly', + count: 1, + indices: 1, + os: { + platforms: [{ platform: 'rocky', count: 1 }], + platformReleases: [{ platformRelease: 'iv', count: 1 }], + }, + versions: [{ version: '8675309', count: 1 }], + plugins: { + localization: { + locale: 'en', + labelsCount: 0, + integrities: {}, + }, + sun: { chances: 5 }, + clouds: { chances: 95 }, + rain: { chances: 2 }, + snow: { chances: 0 }, + }, + }, + }, + }; + + const context = { + logger: console, + version: '8.0.0', + }; + + describe('handleLocalStats', () => { + it('returns expected object without xpack or kibana data', () => { + const result = handleLocalStats( + clusterInfo, + clusterStatsWithNodesUsage, + void 0, + void 0, + context + ); + expect(result.cluster_uuid).toStrictEqual(combinedStatsResult.cluster_uuid); + expect(result.cluster_name).toStrictEqual(combinedStatsResult.cluster_name); + expect(result.cluster_stats).toStrictEqual(combinedStatsResult.cluster_stats); + expect(result.version).toEqual('2.3.4'); + expect(result.collection).toEqual('local'); + expect(Object.keys(result)).not.toContain('license'); + expect(result.stack_stats).toEqual({ kibana: undefined, data: undefined }); + }); + + it('returns expected object with xpack', () => { + const result = handleLocalStats( + clusterInfo, + clusterStatsWithNodesUsage, + void 0, + void 0, + context + ); + + const { stack_stats: stack, ...cluster } = result; + expect(cluster.collection).toBe(combinedStatsResult.collection); + expect(cluster.cluster_uuid).toBe(combinedStatsResult.cluster_uuid); + expect(cluster.cluster_name).toBe(combinedStatsResult.cluster_name); + expect(stack.kibana).toBe(undefined); // not mocked for this test + expect(stack.data).toBe(undefined); // not mocked for this test + + expect(cluster.version).toEqual(combinedStatsResult.version); + expect(cluster.cluster_stats).toEqual(combinedStatsResult.cluster_stats); + expect(Object.keys(cluster).indexOf('license')).toBeLessThan(0); + expect(Object.keys(stack).indexOf('xpack')).toBeLessThan(0); + }); + }); + + describe('getLocalStats', () => { + it('returns expected object with kibana data', async () => { + const callCluster = jest.fn(); + const usageCollection = mockUsageCollection(kibana); + const esClient = mockGetLocalStats(clusterInfo, clusterStats); + const response = await getLocalStats( + [{ clusterUuid: 'abc123' }], + { callCluster, usageCollection, esClient, start: '', end: '' }, + context + ); + const result = response[0]; + expect(result.cluster_uuid).toEqual(combinedStatsResult.cluster_uuid); + expect(result.cluster_name).toEqual(combinedStatsResult.cluster_name); + expect(result.cluster_stats).toEqual(combinedStatsResult.cluster_stats); + expect(result.cluster_stats.nodes).toEqual(combinedStatsResult.cluster_stats.nodes); + expect(result.version).toBe('2.3.4'); + expect(result.collection).toBe('local'); + expect(Object.keys(result).indexOf('license')).toBeLessThan(0); + expect(Object.keys(result.stack_stats).indexOf('xpack')).toBeLessThan(0); + }); + + it('returns an empty array when no cluster uuid is provided', async () => { + const callCluster = jest.fn(); + const usageCollection = mockUsageCollection(kibana); + const esClient = mockGetLocalStats(clusterInfo, clusterStats); + const response = await getLocalStats( + [], + { callCluster, usageCollection, esClient, start: '', end: '' }, + context + ); + expect(response).toBeDefined(); + expect(response.length).toEqual(0); + }); + }); +}); diff --git a/src/plugins/telemetry/server/telemetry_collection/get_local_stats.ts b/src/plugins/telemetry/server/telemetry_collection/get_local_stats.ts index 98c83a3394628..6244c6fac51d3 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_local_stats.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_local_stats.ts @@ -40,8 +40,8 @@ export function handleLocalStats( // eslint-disable-next-line @typescript-eslint/naming-convention { cluster_name, cluster_uuid, version }: ESClusterInfo, { _nodes, cluster_name: clusterName, ...clusterStats }: any, - kibana: KibanaUsageStats, - dataTelemetry: DataTelemetryPayload, + kibana: KibanaUsageStats | undefined, + dataTelemetry: DataTelemetryPayload | undefined, context: StatsCollectionContext ) { return { @@ -62,22 +62,25 @@ export type TelemetryLocalStats = ReturnType; /** * Get statistics for all products joined by Elasticsearch cluster. + * @param {Array} cluster uuids + * @param {Object} config contains the new esClient already scoped contains usageCollection, callCluster, esClient, start, end + * @param {Object} StatsCollectionContext contains logger and version (string) */ export const getLocalStats: StatsGetter<{}, TelemetryLocalStats> = async ( - clustersDetails, - config, - context + clustersDetails, // array of cluster uuid's + config, // contains the new esClient already scoped contains usageCollection, callCluster, esClient, start, end + context // StatsCollectionContext contains logger and version (string) ) => { - const { callCluster, usageCollection } = config; + const { callCluster, usageCollection, esClient } = config; return await Promise.all( clustersDetails.map(async (clustersDetail) => { const [clusterInfo, clusterStats, nodesUsage, kibana, dataTelemetry] = await Promise.all([ - getClusterInfo(callCluster), // cluster info - getClusterStats(callCluster), // cluster stats (not to be confused with cluster _state_) - getNodesUsage(callCluster), // nodes_usage info - getKibana(usageCollection, callCluster), - getDataTelemetry(callCluster), + getClusterInfo(esClient), // cluster info + getClusterStats(esClient), // cluster stats (not to be confused with cluster _state_) + getNodesUsage(esClient), // nodes_usage info + getKibana(usageCollection, callCluster, esClient), + getDataTelemetry(esClient), ]); return handleLocalStats( clusterInfo, diff --git a/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.test.ts b/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.test.ts index 4e4b0e11b7979..acf403ba25447 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.test.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.test.ts @@ -19,6 +19,7 @@ import { getNodesUsage } from './get_nodes_usage'; import { TIMEOUT } from './constants'; +import { elasticsearchServiceMock } from '../../../../../src/core/server/mocks'; const mockedNodesFetchResponse = { cluster_name: 'test cluster', @@ -44,37 +45,35 @@ const mockedNodesFetchResponse = { }, }, }; + describe('get_nodes_usage', () => { - it('calls fetchNodesUsage', async () => { - const callCluster = jest.fn(); - callCluster.mockResolvedValueOnce(mockedNodesFetchResponse); - await getNodesUsage(callCluster); - expect(callCluster).toHaveBeenCalledWith('transport.request', { - path: '/_nodes/usage', - method: 'GET', - query: { - timeout: TIMEOUT, - }, - }); - }); - it('returns a modified array of node usage data', async () => { - const callCluster = jest.fn(); - callCluster.mockResolvedValueOnce(mockedNodesFetchResponse); - const result = await getNodesUsage(callCluster); - expect(result.nodes).toEqual([ - { - aggregations: { scripted_metric: { other: 7 }, terms: { bytes: 2 } }, - node_id: 'some_node_id', - rest_actions: { - create_index_action: 1, - document_get_action: 1, - nodes_info_action: 36, - nodes_usage_action: 1, - search_action: 19, + it('returns a modified array of nodes usage data', async () => { + const response = Promise.resolve({ body: mockedNodesFetchResponse }); + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + esClient.nodes.usage.mockImplementationOnce( + // @ts-ignore + async (_params = { timeout: TIMEOUT }) => { + return response; + } + ); + const item = await getNodesUsage(esClient); + expect(esClient.nodes.usage).toHaveBeenCalledWith({ timeout: TIMEOUT }); + expect(item).toStrictEqual({ + nodes: [ + { + aggregations: { scripted_metric: { other: 7 }, terms: { bytes: 2 } }, + node_id: 'some_node_id', + rest_actions: { + create_index_action: 1, + document_get_action: 1, + nodes_info_action: 36, + nodes_usage_action: 1, + search_action: 19, + }, + since: 1588616945163, + timestamp: 1588617023177, }, - since: 1588616945163, - timestamp: 1588617023177, - }, - ]); + ], + }); }); }); diff --git a/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.ts b/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.ts index c5c110fbb4149..959840d0020a2 100644 --- a/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.ts +++ b/src/plugins/telemetry/server/telemetry_collection/get_nodes_usage.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { LegacyAPICaller } from 'kibana/server'; +import { ElasticsearchClient } from 'src/core/server'; import { TIMEOUT } from './constants'; export interface NodeAggregation { @@ -44,7 +44,7 @@ export interface NodesFeatureUsageResponse { } export type NodesUsageGetter = ( - callCluster: LegacyAPICaller + esClient: ElasticsearchClient ) => Promise<{ nodes: NodeObj[] | Array<{}> }>; /** * Get the nodes usage data from the connected cluster. @@ -54,16 +54,12 @@ export type NodesUsageGetter = ( * The Nodes usage API was introduced in v6.0.0 */ export async function fetchNodesUsage( - callCluster: LegacyAPICaller + esClient: ElasticsearchClient ): Promise { - const response = await callCluster('transport.request', { - method: 'GET', - path: '/_nodes/usage', - query: { - timeout: TIMEOUT, - }, + const { body } = await esClient.nodes.usage({ + timeout: TIMEOUT, }); - return response; + return body; } /** @@ -71,8 +67,8 @@ export async function fetchNodesUsage( * @param callCluster APICaller * @returns Object containing array of modified usage information with the node_id nested within the data for that node. */ -export const getNodesUsage: NodesUsageGetter = async (callCluster) => { - const result = await fetchNodesUsage(callCluster); +export const getNodesUsage: NodesUsageGetter = async (esClient) => { + const result = await fetchNodesUsage(esClient); const transformedNodes = Object.entries(result?.nodes || {}).map(([key, value]) => ({ ...(value as NodeObj), node_id: key, diff --git a/src/plugins/telemetry/server/telemetry_collection/register_collection.ts b/src/plugins/telemetry/server/telemetry_collection/register_collection.ts index 438fcadad9255..9dac4900f5f10 100644 --- a/src/plugins/telemetry/server/telemetry_collection/register_collection.ts +++ b/src/plugins/telemetry/server/telemetry_collection/register_collection.ts @@ -38,16 +38,19 @@ import { ILegacyClusterClient } from 'kibana/server'; import { TelemetryCollectionManagerPluginSetup } from 'src/plugins/telemetry_collection_manager/server'; +import { IClusterClient } from '../../../../../src/core/server'; import { getLocalStats } from './get_local_stats'; import { getClusterUuids } from './get_cluster_stats'; import { getLocalLicense } from './get_local_license'; export function registerCollection( telemetryCollectionManager: TelemetryCollectionManagerPluginSetup, - esCluster: ILegacyClusterClient + esCluster: ILegacyClusterClient, + esClientGetter: () => IClusterClient | undefined ) { telemetryCollectionManager.setCollection({ esCluster, + esClientGetter, title: 'local', priority: 0, statsGetter: getLocalStats, diff --git a/src/plugins/telemetry_collection_manager/server/plugin.ts b/src/plugins/telemetry_collection_manager/server/plugin.ts index 051bb3a11cb16..e54e7451a670a 100644 --- a/src/plugins/telemetry_collection_manager/server/plugin.ts +++ b/src/plugins/telemetry_collection_manager/server/plugin.ts @@ -24,6 +24,7 @@ import { CoreStart, Plugin, Logger, + IClusterClient, } from '../../../core/server'; import { @@ -86,6 +87,7 @@ export class TelemetryCollectionManagerPlugin title, priority, esCluster, + esClientGetter, statsGetter, clusterDetailsGetter, licenseGetter, @@ -105,6 +107,9 @@ export class TelemetryCollectionManagerPlugin if (!esCluster) { throw Error('esCluster name must be set for the getCluster method.'); } + if (!esClientGetter) { + throw Error('esClientGetter method not set.'); + } if (!clusterDetailsGetter) { throw Error('Cluster UUIds method is not set.'); } @@ -118,6 +123,7 @@ export class TelemetryCollectionManagerPlugin clusterDetailsGetter, esCluster, title, + esClientGetter, }); this.usageGetterMethodPriority = priority; } @@ -126,6 +132,7 @@ export class TelemetryCollectionManagerPlugin private getStatsCollectionConfig( config: StatsGetterConfig, collection: Collection, + collectionEsClient: IClusterClient, usageCollection: UsageCollectionSetup ): StatsCollectionConfig { const { start, end, request } = config; @@ -133,8 +140,11 @@ export class TelemetryCollectionManagerPlugin const callCluster = config.unencrypted ? collection.esCluster.asScoped(request).callAsCurrentUser : collection.esCluster.callAsInternalUser; - - return { callCluster, start, end, usageCollection }; + // Scope the new elasticsearch Client appropriately and pass to the stats collection config + const esClient = config.unencrypted + ? collectionEsClient.asScoped(config.request).asCurrentUser + : collectionEsClient.asInternalUser; + return { callCluster, start, end, usageCollection, esClient }; } private async getOptInStats(optInStatus: boolean, config: StatsGetterConfig) { @@ -142,27 +152,33 @@ export class TelemetryCollectionManagerPlugin return []; } for (const collection of this.collections) { - const statsCollectionConfig = this.getStatsCollectionConfig( - config, - collection, - this.usageCollection - ); - try { - const optInStats = await this.getOptInStatsForCollection( + // first fetch the client and make sure it's not undefined. + const collectionEsClient = collection.esClientGetter(); + if (collectionEsClient !== undefined) { + const statsCollectionConfig = this.getStatsCollectionConfig( + config, collection, - optInStatus, - statsCollectionConfig + collectionEsClient, + this.usageCollection ); - if (optInStats && optInStats.length) { - this.logger.debug(`Got Opt In stats using ${collection.title} collection.`); - if (config.unencrypted) { - return optInStats; + + try { + const optInStats = await this.getOptInStatsForCollection( + collection, + optInStatus, + statsCollectionConfig + ); + if (optInStats && optInStats.length) { + this.logger.debug(`Got Opt In stats using ${collection.title} collection.`); + if (config.unencrypted) { + return optInStats; + } + return encryptTelemetry(optInStats, { useProdKey: this.isDistributable }); } - return encryptTelemetry(optInStats, { useProdKey: this.isDistributable }); + } catch (err) { + this.logger.debug(`Failed to collect any opt in stats with registered collections.`); + // swallow error to try next collection; } - } catch (err) { - this.logger.debug(`Failed to collect any opt in stats with registered collections.`); - // swallow error to try next collection; } } @@ -192,28 +208,32 @@ export class TelemetryCollectionManagerPlugin return []; } for (const collection of this.collections) { - const statsCollectionConfig = this.getStatsCollectionConfig( - config, - collection, - this.usageCollection - ); - try { - const usageData = await this.getUsageForCollection(collection, statsCollectionConfig); - if (usageData.length) { - this.logger.debug(`Got Usage using ${collection.title} collection.`); - if (config.unencrypted) { - return usageData; - } + const collectionEsClient = collection.esClientGetter(); + if (collectionEsClient !== undefined) { + const statsCollectionConfig = this.getStatsCollectionConfig( + config, + collection, + collectionEsClient, + this.usageCollection + ); + try { + const usageData = await this.getUsageForCollection(collection, statsCollectionConfig); + if (usageData.length) { + this.logger.debug(`Got Usage using ${collection.title} collection.`); + if (config.unencrypted) { + return usageData; + } - return encryptTelemetry(usageData.filter(isClusterOptedIn), { - useProdKey: this.isDistributable, - }); + return encryptTelemetry(usageData.filter(isClusterOptedIn), { + useProdKey: this.isDistributable, + }); + } + } catch (err) { + this.logger.debug( + `Failed to collect any usage with registered collection ${collection.title}.` + ); + // swallow error to try next collection; } - } catch (err) { - this.logger.debug( - `Failed to collect any usage with registered collection ${collection.title}.` - ); - // swallow error to try next collection; } } diff --git a/src/plugins/telemetry_collection_manager/server/types.ts b/src/plugins/telemetry_collection_manager/server/types.ts index 16f96c07fd8ea..44970df30fd16 100644 --- a/src/plugins/telemetry_collection_manager/server/types.ts +++ b/src/plugins/telemetry_collection_manager/server/types.ts @@ -17,8 +17,15 @@ * under the License. */ -import { LegacyAPICaller, Logger, KibanaRequest, ILegacyClusterClient } from 'kibana/server'; +import { + LegacyAPICaller, + Logger, + KibanaRequest, + ILegacyClusterClient, + IClusterClient, +} from 'kibana/server'; import { UsageCollectionSetup } from 'src/plugins/usage_collection/server'; +import { ElasticsearchClient } from '../../../../src/core/server'; import { TelemetryCollectionManagerPlugin } from './plugin'; export interface TelemetryCollectionManagerPluginSetup { @@ -67,6 +74,7 @@ export interface StatsCollectionConfig { callCluster: LegacyAPICaller; start: string | number; end: string | number; + esClient: ElasticsearchClient; } export interface BasicStatsPayload { @@ -100,7 +108,7 @@ export interface ESLicense { } export interface StatsCollectionContext { - logger: Logger; + logger: Logger | Console; version: string; } @@ -130,6 +138,7 @@ export interface CollectionConfig< title: string; priority: number; esCluster: ILegacyClusterClient; + esClientGetter: () => IClusterClient | undefined; // --> by now we know that the client getter will return the IClusterClient but we assure that through a code check statsGetter: StatsGetter; clusterDetailsGetter: ClusterDetailsGetter; licenseGetter: LicenseGetter; @@ -145,5 +154,6 @@ export interface Collection< licenseGetter: LicenseGetter; clusterDetailsGetter: ClusterDetailsGetter; esCluster: ILegacyClusterClient; + esClientGetter: () => IClusterClient | undefined; // the collection could still return undefined for the es client getter. title: string; } diff --git a/src/plugins/tile_map/public/geohash_layer.js b/src/plugins/tile_map/public/geohash_layer.js index ca2f49a1f31e0..ca992a0d09ec9 100644 --- a/src/plugins/tile_map/public/geohash_layer.js +++ b/src/plugins/tile_map/public/geohash_layer.js @@ -19,14 +19,14 @@ import { min, isEqual } from 'lodash'; import { i18n } from '@kbn/i18n'; -import { L, KibanaMapLayer, MapTypes } from '../../maps_legacy/public'; +import { KibanaMapLayer, MapTypes } from '../../maps_legacy/public'; import { HeatmapMarkers } from './markers/heatmap'; import { ScaledCirclesMarkers } from './markers/scaled_circles'; import { ShadedCirclesMarkers } from './markers/shaded_circles'; import { GeohashGridMarkers } from './markers/geohash_grid'; export class GeohashLayer extends KibanaMapLayer { - constructor(featureCollection, featureCollectionMetaData, options, zoom, kibanaMap) { + constructor(featureCollection, featureCollectionMetaData, options, zoom, kibanaMap, leaflet) { super(); this._featureCollection = featureCollection; @@ -35,7 +35,8 @@ export class GeohashLayer extends KibanaMapLayer { this._geohashOptions = options; this._zoom = zoom; this._kibanaMap = kibanaMap; - const geojson = L.geoJson(this._featureCollection); + this._leaflet = leaflet; + const geojson = this._leaflet.geoJson(this._featureCollection); this._bounds = geojson.getBounds(); this._createGeohashMarkers(); this._lastBounds = null; @@ -56,7 +57,8 @@ export class GeohashLayer extends KibanaMapLayer { this._featureCollectionMetaData, markerOptions, this._zoom, - this._kibanaMap + this._kibanaMap, + this._leaflet ); break; case MapTypes.ShadedCircleMarkers: @@ -65,7 +67,8 @@ export class GeohashLayer extends KibanaMapLayer { this._featureCollectionMetaData, markerOptions, this._zoom, - this._kibanaMap + this._kibanaMap, + this._leaflet ); break; case MapTypes.ShadedGeohashGrid: @@ -74,7 +77,8 @@ export class GeohashLayer extends KibanaMapLayer { this._featureCollectionMetaData, markerOptions, this._zoom, - this._kibanaMap + this._kibanaMap, + this._leaflet ); break; case MapTypes.Heatmap: @@ -95,7 +99,8 @@ export class GeohashLayer extends KibanaMapLayer { tooltipFormatter: this._geohashOptions.tooltipFormatter, }, this._zoom, - this._featureCollectionMetaData.max + this._featureCollectionMetaData.max, + this._leaflet ); break; default: @@ -126,9 +131,15 @@ export class GeohashLayer extends KibanaMapLayer { if (this._geohashOptions.fetchBounds) { const geoHashBounds = await this._geohashOptions.fetchBounds(); if (geoHashBounds) { - const northEast = L.latLng(geoHashBounds.top_left.lat, geoHashBounds.bottom_right.lon); - const southWest = L.latLng(geoHashBounds.bottom_right.lat, geoHashBounds.top_left.lon); - return L.latLngBounds(southWest, northEast); + const northEast = this._leaflet.latLng( + geoHashBounds.top_left.lat, + geoHashBounds.bottom_right.lon + ); + const southWest = this._leaflet.latLng( + geoHashBounds.bottom_right.lat, + geoHashBounds.top_left.lon + ); + return this._leaflet.latLngBounds(southWest, northEast); } } diff --git a/src/plugins/tile_map/public/markers/geohash_grid.js b/src/plugins/tile_map/public/markers/geohash_grid.js index 46e7987c601f5..d81e435a6dd5d 100644 --- a/src/plugins/tile_map/public/markers/geohash_grid.js +++ b/src/plugins/tile_map/public/markers/geohash_grid.js @@ -18,11 +18,10 @@ */ import { ScaledCirclesMarkers } from './scaled_circles'; -import { L } from '../../../maps_legacy/public'; export class GeohashGridMarkers extends ScaledCirclesMarkers { getMarkerFunction() { - return function (feature) { + return (feature) => { const geohashRect = feature.properties.geohash_meta.rectangle; // get bounds from northEast[3] and southWest[1] // corners in geohash rectangle @@ -30,7 +29,7 @@ export class GeohashGridMarkers extends ScaledCirclesMarkers { [geohashRect[3][0], geohashRect[3][1]], [geohashRect[1][0], geohashRect[1][1]], ]; - return L.rectangle(corners); + return this._leaflet.rectangle(corners); }; } } diff --git a/src/plugins/tile_map/public/markers/heatmap.js b/src/plugins/tile_map/public/markers/heatmap.js index f2d014797bce0..79bbee16548ac 100644 --- a/src/plugins/tile_map/public/markers/heatmap.js +++ b/src/plugins/tile_map/public/markers/heatmap.js @@ -20,7 +20,6 @@ import _ from 'lodash'; import d3 from 'd3'; import { EventEmitter } from 'events'; -import { L } from '../../../maps_legacy/public'; /** * Map overlay: canvas layer with leaflet.heat plugin @@ -30,17 +29,17 @@ import { L } from '../../../maps_legacy/public'; * @param params {Object} */ export class HeatmapMarkers extends EventEmitter { - constructor(featureCollection, options, zoom, max) { + constructor(featureCollection, options, zoom, max, leaflet) { super(); this._geojsonFeatureCollection = featureCollection; const points = dataToHeatArray(featureCollection, max); - this._leafletLayer = new L.HeatLayer(points, options); + this._leafletLayer = new leaflet.HeatLayer(points, options); this._tooltipFormatter = options.tooltipFormatter; this._zoom = zoom; this._disableTooltips = false; this._getLatLng = _.memoize( function (feature) { - return L.latLng(feature.geometry.coordinates[1], feature.geometry.coordinates[0]); + return leaflet.latLng(feature.geometry.coordinates[1], feature.geometry.coordinates[0]); }, function (feature) { // turn coords into a string for the memoize cache diff --git a/src/plugins/tile_map/public/markers/scaled_circles.js b/src/plugins/tile_map/public/markers/scaled_circles.js index cb111107f6fe3..4a5f1b452580b 100644 --- a/src/plugins/tile_map/public/markers/scaled_circles.js +++ b/src/plugins/tile_map/public/markers/scaled_circles.js @@ -21,7 +21,7 @@ import _ from 'lodash'; import d3 from 'd3'; import $ from 'jquery'; import { EventEmitter } from 'events'; -import { L, colorUtil } from '../../../maps_legacy/public'; +import { colorUtil } from '../../../maps_legacy/public'; import { truncatedColorMaps } from '../../../charts/public'; export class ScaledCirclesMarkers extends EventEmitter { @@ -31,14 +31,13 @@ export class ScaledCirclesMarkers extends EventEmitter { options, targetZoom, kibanaMap, - metricAgg + leaflet ) { super(); this._featureCollection = featureCollection; this._featureCollectionMetaData = featureCollectionMetaData; this._zoom = targetZoom; - this._metricAgg = metricAgg; this._valueFormatter = options.valueFormatter || @@ -55,6 +54,7 @@ export class ScaledCirclesMarkers extends EventEmitter { this._legendColors = null; this._legendQuantizer = null; + this._leaflet = leaflet; this._popups = []; @@ -72,7 +72,7 @@ export class ScaledCirclesMarkers extends EventEmitter { return kibanaMap.isInside(bucketRectBounds); }; } - this._leafletLayer = L.geoJson(null, layerOptions); + this._leafletLayer = this._leaflet.geoJson(null, layerOptions); this._leafletLayer.addData(this._featureCollection); } @@ -143,7 +143,7 @@ export class ScaledCirclesMarkers extends EventEmitter { mouseover: (e) => { const layer = e.target; // bring layer to front if not older browser - if (!L.Browser.ie && !L.Browser.opera) { + if (!this._leaflet.Browser.ie && !this._leaflet.Browser.opera) { layer.bringToFront(); } this._showTooltip(feature); @@ -170,7 +170,10 @@ export class ScaledCirclesMarkers extends EventEmitter { return; } - const latLng = L.latLng(feature.geometry.coordinates[1], feature.geometry.coordinates[0]); + const latLng = this._leaflet.latLng( + feature.geometry.coordinates[1], + feature.geometry.coordinates[0] + ); this.emit('showTooltip', { content: content, position: latLng, @@ -182,7 +185,7 @@ export class ScaledCirclesMarkers extends EventEmitter { return (feature, latlng) => { const value = feature.properties.value; const scaledRadius = this._radiusScale(value) * scaleFactor; - return L.circleMarker(latlng).setRadius(scaledRadius); + return this._leaflet.circleMarker(latlng).setRadius(scaledRadius); }; } diff --git a/src/plugins/tile_map/public/markers/shaded_circles.js b/src/plugins/tile_map/public/markers/shaded_circles.js index 745d0422856c6..3468cab7d8b75 100644 --- a/src/plugins/tile_map/public/markers/shaded_circles.js +++ b/src/plugins/tile_map/public/markers/shaded_circles.js @@ -19,7 +19,6 @@ import _ from 'lodash'; import { ScaledCirclesMarkers } from './scaled_circles'; -import { L } from '../../../maps_legacy/public'; export class ShadedCirclesMarkers extends ScaledCirclesMarkers { getMarkerFunction() { @@ -27,7 +26,7 @@ export class ShadedCirclesMarkers extends ScaledCirclesMarkers { const scaleFactor = 0.8; return (feature, latlng) => { const radius = this._geohashMinDistance(feature) * scaleFactor; - return L.circle(latlng, radius); + return this._leaflet.circle(latlng, radius); }; } @@ -49,12 +48,12 @@ export class ShadedCirclesMarkers extends ScaledCirclesMarkers { // clockwise, each value being an array of [lat, lng] // center lat and southeast lng - const east = L.latLng([centerPoint[0], geohashRect[2][1]]); + const east = this._leaflet.latLng([centerPoint[0], geohashRect[2][1]]); // southwest lat and center lng - const north = L.latLng([geohashRect[3][0], centerPoint[1]]); + const north = this._leaflet.latLng([geohashRect[3][0], centerPoint[1]]); // get latLng of geohash center point - const center = L.latLng([centerPoint[0], centerPoint[1]]); + const center = this._leaflet.latLng([centerPoint[0], centerPoint[1]]); // get smallest radius at center of geohash grid rectangle const eastRadius = Math.floor(center.distanceTo(east)); diff --git a/src/plugins/tile_map/public/plugin.ts b/src/plugins/tile_map/public/plugin.ts index 9a164f8a303f8..07add6901fb49 100644 --- a/src/plugins/tile_map/public/plugin.ts +++ b/src/plugins/tile_map/public/plugin.ts @@ -47,7 +47,7 @@ interface TileMapVisualizationDependencies { getZoomPrecision: any; getPrecision: any; BaseMapsVisualization: any; - serviceSettings: IServiceSettings; + getServiceSettings: () => Promise; } /** @internal */ @@ -81,13 +81,13 @@ export class TileMapPlugin implements Plugin = { getZoomPrecision, getPrecision, BaseMapsVisualization: mapsLegacy.getBaseMapsVis(), uiSettings: core.uiSettings, - serviceSettings, + getServiceSettings, }; expressions.registerFunction(() => createTileMapFn(visualizationDependencies)); diff --git a/src/plugins/tile_map/public/tile_map_type.js b/src/plugins/tile_map/public/tile_map_type.js index f76da26022a77..2b23f345f012e 100644 --- a/src/plugins/tile_map/public/tile_map_type.js +++ b/src/plugins/tile_map/public/tile_map_type.js @@ -28,7 +28,7 @@ import { truncatedColorSchemas } from '../../charts/public'; export function createTileMapTypeDefinition(dependencies) { const CoordinateMapsVisualization = createTileMapVisualization(dependencies); - const { uiSettings, serviceSettings } = dependencies; + const { uiSettings, getServiceSettings } = dependencies; return { name: 'tile_map', @@ -142,6 +142,7 @@ export function createTileMapTypeDefinition(dependencies) { let tmsLayers; try { + const serviceSettings = await getServiceSettings(); tmsLayers = await serviceSettings.getTMSServices(); } catch (e) { return vis; diff --git a/src/plugins/tile_map/public/tile_map_visualization.js b/src/plugins/tile_map/public/tile_map_visualization.js index 2ebb76d05c219..b09a2f3bac48f 100644 --- a/src/plugins/tile_map/public/tile_map_visualization.js +++ b/src/plugins/tile_map/public/tile_map_visualization.js @@ -17,12 +17,42 @@ * under the License. */ -import { get } from 'lodash'; -import { GeohashLayer } from './geohash_layer'; +import { get, round } from 'lodash'; import { getFormatService, getQueryService, getKibanaLegacy } from './services'; -import { scaleBounds, geoContains, mapTooltipProvider } from '../../maps_legacy/public'; +import { + geoContains, + mapTooltipProvider, + lazyLoadMapsLegacyModules, +} from '../../maps_legacy/public'; import { tooltipFormatter } from './tooltip_formatter'; +function scaleBounds(bounds) { + const scale = 0.5; // scale bounds by 50% + + const topLeft = bounds.top_left; + const bottomRight = bounds.bottom_right; + let latDiff = round(Math.abs(topLeft.lat - bottomRight.lat), 5); + const lonDiff = round(Math.abs(bottomRight.lon - topLeft.lon), 5); + // map height can be zero when vis is first created + if (latDiff === 0) latDiff = lonDiff; + + const latDelta = latDiff * scale; + let topLeftLat = round(topLeft.lat, 5) + latDelta; + if (topLeftLat > 90) topLeftLat = 90; + let bottomRightLat = round(bottomRight.lat, 5) - latDelta; + if (bottomRightLat < -90) bottomRightLat = -90; + const lonDelta = lonDiff * scale; + let topLeftLon = round(topLeft.lon, 5) - lonDelta; + if (topLeftLon < -180) topLeftLon = -180; + let bottomRightLon = round(bottomRight.lon, 5) + lonDelta; + if (bottomRightLon > 180) bottomRightLon = 180; + + return { + top_left: { lat: topLeftLat, lon: topLeftLon }, + bottom_right: { lat: bottomRightLat, lon: bottomRightLon }, + }; +} + export const createTileMapVisualization = (dependencies) => { const { getZoomPrecision, getPrecision, BaseMapsVisualization } = dependencies; @@ -147,7 +177,9 @@ export const createTileMapVisualization = (dependencies) => { this._recreateGeohashLayer(); } - _recreateGeohashLayer() { + async _recreateGeohashLayer() { + const { GeohashLayer } = await import('./geohash_layer'); + if (this._geohashLayer) { this._kibanaMap.removeLayer(this._geohashLayer); this._geohashLayer = null; @@ -158,7 +190,8 @@ export const createTileMapVisualization = (dependencies) => { this._geoJsonFeatureCollectionAndMeta.meta, geohashOptions, this._kibanaMap.getZoomLevel(), - this._kibanaMap + this._kibanaMap, + (await lazyLoadMapsLegacyModules()).L ); this._kibanaMap.addLayer(this._geohashLayer); } diff --git a/src/plugins/usage_collection/README.md b/src/plugins/usage_collection/README.md index 0b1cca07de007..d8edc5bb8d18a 100644 --- a/src/plugins/usage_collection/README.md +++ b/src/plugins/usage_collection/README.md @@ -63,7 +63,7 @@ All you need to provide is a `type` for organizing your fields, `schema` field t total: 'long', }, }, - fetch: async (callCluster: APICluster) => { + fetch: async (callCluster: APICluster, esClient: IClusterClient) => { // query ES and get some data // summarize the data into a model @@ -86,9 +86,9 @@ Some background: - `MY_USAGE_TYPE` can be any string. It usually matches the plugin name. As a safety mechanism, we double check there are no duplicates at the moment of registering the collector. - The `fetch` method needs to support multiple contexts in which it is called. For example, when stats are pulled from a Kibana Metricbeat module, the Beat calls Kibana's stats API to invoke usage collection. -In this case, the `fetch` method is called as a result of an HTTP API request and `callCluster` wraps `callWithRequest`, where the request headers are expected to have read privilege on the entire `.kibana' index. +In this case, the `fetch` method is called as a result of an HTTP API request and `callCluster` wraps `callWithRequest` or `esClient` wraps `asCurrentUser`, where the request headers are expected to have read privilege on the entire `.kibana' index. -Note: there will be many cases where you won't need to use the `callCluster` function that gets passed in to your `fetch` method at all. Your feature might have an accumulating value in server memory, or read something from the OS, or use other clients like a custom SavedObjects client. In that case it's up to the plugin to initialize those clients like the example below: +Note: there will be many cases where you won't need to use the `callCluster` (or `esClient`) function that gets passed in to your `fetch` method at all. Your feature might have an accumulating value in server memory, or read something from the OS, or use other clients like a custom SavedObjects client. In that case it's up to the plugin to initialize those clients like the example below: ```ts // server/plugin.ts @@ -302,4 +302,4 @@ These saved objects are automatically consumed by the stats API and surfaced und By storing these metrics and their counts as key-value pairs, we can add more metrics without having to worry about exceeding the 1000-field soft limit in Elasticsearch. -The only caveat is that it makes it harder to consume in Kibana when analysing each entry in the array separately. In the telemetry team we are working to find a solution to this. We are building a new way of reporting telemetry called [Pulse](../../../rfcs/text/0008_pulse.md) that will help on making these UI-Metrics easier to consume. +The only caveat is that it makes it harder to consume in Kibana when analysing each entry in the array separately. In the telemetry team we are working to find a solution to this. diff --git a/src/plugins/usage_collection/server/collector/collector.ts b/src/plugins/usage_collection/server/collector/collector.ts index d57700024c088..365e1ce201337 100644 --- a/src/plugins/usage_collection/server/collector/collector.ts +++ b/src/plugins/usage_collection/server/collector/collector.ts @@ -17,7 +17,7 @@ * under the License. */ -import { Logger, LegacyAPICaller } from 'kibana/server'; +import { Logger, LegacyAPICaller, ElasticsearchClient } from 'kibana/server'; export type CollectorFormatForBulkUpload = (result: T) => { type: string; payload: U }; @@ -48,7 +48,7 @@ export interface CollectorOptions { type: string; init?: Function; schema?: MakeSchemaFrom>; // Using Required to enforce all optional keys in the object - fetch: (callCluster: LegacyAPICaller) => Promise | T; + fetch: (callCluster: LegacyAPICaller, esClient?: ElasticsearchClient) => Promise | T; /* * A hook for allowing the fetched data payload to be organized into a typed * data model for internal bulk upload. See defaultFormatterForBulkUpload for diff --git a/src/plugins/usage_collection/server/collector/collector_set.test.ts b/src/plugins/usage_collection/server/collector/collector_set.test.ts index 545642c5dcfa3..3f943ad8bf2ff 100644 --- a/src/plugins/usage_collection/server/collector/collector_set.test.ts +++ b/src/plugins/usage_collection/server/collector/collector_set.test.ts @@ -21,7 +21,7 @@ import { noop } from 'lodash'; import { Collector } from './collector'; import { CollectorSet } from './collector_set'; import { UsageCollector } from './usage_collector'; -import { loggingSystemMock } from '../../../../core/server/mocks'; +import { elasticsearchServiceMock, loggingSystemMock } from '../../../../core/server/mocks'; const logger = loggingSystemMock.createLogger(); @@ -42,6 +42,7 @@ describe('CollectorSet', () => { }); const mockCallCluster = jest.fn().mockResolvedValue({ passTest: 1000 }); + const mockEsClient = elasticsearchServiceMock.createClusterClient().asInternalUser; it('should throw an error if non-Collector type of object is registered', () => { const collectors = new CollectorSet({ logger }); @@ -85,7 +86,7 @@ describe('CollectorSet', () => { }) ); - const result = await collectors.bulkFetch(mockCallCluster); + const result = await collectors.bulkFetch(mockCallCluster, mockEsClient); expect(loggerSpies.debug).toHaveBeenCalledTimes(1); expect(loggerSpies.debug).toHaveBeenCalledWith( 'Fetching data from MY_TEST_COLLECTOR collector' @@ -110,7 +111,7 @@ describe('CollectorSet', () => { let result; try { - result = await collectors.bulkFetch(mockCallCluster); + result = await collectors.bulkFetch(mockCallCluster, mockEsClient); } catch (err) { // Do nothing } @@ -128,7 +129,7 @@ describe('CollectorSet', () => { }) ); - const result = await collectors.bulkFetch(mockCallCluster); + const result = await collectors.bulkFetch(mockCallCluster, mockEsClient); expect(result).toStrictEqual([ { type: 'MY_TEST_COLLECTOR', @@ -146,7 +147,7 @@ describe('CollectorSet', () => { } as any) ); - const result = await collectors.bulkFetch(mockCallCluster); + const result = await collectors.bulkFetch(mockCallCluster, mockEsClient); expect(result).toStrictEqual([ { type: 'MY_TEST_COLLECTOR', @@ -169,7 +170,7 @@ describe('CollectorSet', () => { }) ); - const result = await collectors.bulkFetch(mockCallCluster); + const result = await collectors.bulkFetch(mockCallCluster, mockEsClient); expect(result).toStrictEqual([ { type: 'MY_TEST_COLLECTOR', diff --git a/src/plugins/usage_collection/server/collector/collector_set.ts b/src/plugins/usage_collection/server/collector/collector_set.ts index fce17a46b7168..6861be7f4f76b 100644 --- a/src/plugins/usage_collection/server/collector/collector_set.ts +++ b/src/plugins/usage_collection/server/collector/collector_set.ts @@ -18,7 +18,7 @@ */ import { snakeCase } from 'lodash'; -import { Logger, LegacyAPICaller } from 'kibana/server'; +import { Logger, LegacyAPICaller, ElasticsearchClient } from 'kibana/server'; import { Collector, CollectorOptions } from './collector'; import { UsageCollector } from './usage_collector'; @@ -117,8 +117,12 @@ export class CollectorSet { return allReady; }; + // all collections eventually pass through bulkFetch. + // the shape of the response is different when using the new ES client as is the error handling. + // We'll handle the refactor for using the new client in a follow up PR. public bulkFetch = async ( callCluster: LegacyAPICaller, + esClient: ElasticsearchClient, collectors: Map> = this.collectors ) => { const responses = await Promise.all( @@ -127,7 +131,7 @@ export class CollectorSet { try { return { type: collector.type, - result: await collector.fetch(callCluster), + result: await collector.fetch(callCluster, esClient), // each collector must ensure they handle the response appropriately. }; } catch (err) { this.logger.warn(err); @@ -149,9 +153,9 @@ export class CollectorSet { return this.makeCollectorSetFromArray(filtered); }; - public bulkFetchUsage = async (callCluster: LegacyAPICaller) => { + public bulkFetchUsage = async (callCluster: LegacyAPICaller, esClient: ElasticsearchClient) => { const usageCollectors = this.getFilteredCollectorSet((c) => c instanceof UsageCollector); - return await this.bulkFetch(callCluster, usageCollectors.collectors); + return await this.bulkFetch(callCluster, esClient, usageCollectors.collectors); }; // convert an array of fetched stats results into key/object diff --git a/src/plugins/usage_collection/server/routes/stats.ts b/src/plugins/usage_collection/server/routes/stats.ts index 7c64c9f180319..ef5da2eb11ba6 100644 --- a/src/plugins/usage_collection/server/routes/stats.ts +++ b/src/plugins/usage_collection/server/routes/stats.ts @@ -24,6 +24,7 @@ import { Observable } from 'rxjs'; import { first } from 'rxjs/operators'; import { + ElasticsearchClient, IRouter, LegacyAPICaller, MetricsServiceSetup, @@ -61,8 +62,11 @@ export function registerStatsRoute({ metrics: MetricsServiceSetup; overallStatus$: Observable; }) { - const getUsage = async (callCluster: LegacyAPICaller): Promise => { - const usage = await collectorSet.bulkFetchUsage(callCluster); + const getUsage = async ( + callCluster: LegacyAPICaller, + esClient: ElasticsearchClient + ): Promise => { + const usage = await collectorSet.bulkFetchUsage(callCluster, esClient); return collectorSet.toObject(usage); }; @@ -96,13 +100,14 @@ export function registerStatsRoute({ let extended; if (isExtended) { const callCluster = context.core.elasticsearch.legacy.client.callAsCurrentUser; + const esClient = context.core.elasticsearch.client.asCurrentUser; const collectorsReady = await collectorSet.areAllCollectorsReady(); if (shouldGetUsage && !collectorsReady) { return res.customError({ statusCode: 503, body: { message: STATS_NOT_READY_MESSAGE } }); } - const usagePromise = shouldGetUsage ? getUsage(callCluster) : Promise.resolve({}); + const usagePromise = shouldGetUsage ? getUsage(callCluster, esClient) : Promise.resolve({}); const [usage, clusterUuid] = await Promise.all([usagePromise, getClusterUuid(callCluster)]); let modifiedUsage = usage; diff --git a/src/plugins/vis_type_vega/public/data_model/vega_parser.test.js b/src/plugins/vis_type_vega/public/data_model/vega_parser.test.js index 4883a8129903a..5c7656efe925b 100644 --- a/src/plugins/vis_type_vega/public/data_model/vega_parser.test.js +++ b/src/plugins/vis_type_vega/public/data_model/vega_parser.test.js @@ -162,12 +162,15 @@ describe('VegaParser._resolveEsQueries', () => { function check(spec, expected, warnCount) { return async () => { - const vp = new VegaParser(spec, searchApiStub, 0, 0, { - getFileLayers: async () => [{ name: 'file1', url: 'url1' }], - getUrlForRegionLayer: async (layer) => { - return layer.url; - }, - }); + const mockGetServiceSettings = async () => { + return { + getFileLayers: async () => [{ name: 'file1', url: 'url1' }], + getUrlForRegionLayer: async (layer) => { + return layer.url; + }, + }; + }; + const vp = new VegaParser(spec, searchApiStub, 0, 0, mockGetServiceSettings); await vp._resolveDataUrls(); expect(vp.spec).toEqual(expected); diff --git a/src/plugins/vis_type_vega/public/data_model/vega_parser.ts b/src/plugins/vis_type_vega/public/data_model/vega_parser.ts index b3fb2d54cb266..ccb89207e222f 100644 --- a/src/plugins/vis_type_vega/public/data_model/vega_parser.ts +++ b/src/plugins/vis_type_vega/public/data_model/vega_parser.ts @@ -65,7 +65,7 @@ export class VegaParser { hideWarnings: boolean; error?: string; warnings: string[]; - _urlParsers: UrlParserConfig; + _urlParsers: UrlParserConfig | undefined; isVegaLite?: boolean; useHover?: boolean; _config?: VegaConfig; @@ -80,13 +80,16 @@ export class VegaParser { containerDir?: ControlsLocation | ControlsDirection; controlsDir?: ControlsLocation; searchAPI: SearchAPI; + getServiceSettings: () => Promise; + filters: Bool; + timeCache: TimeCache; constructor( spec: VegaSpec | string, searchAPI: SearchAPI, timeCache: TimeCache, filters: Bool, - serviceSettings: IServiceSettings + getServiceSettings: () => Promise ) { this.spec = spec as VegaSpec; this.hideWarnings = false; @@ -94,13 +97,9 @@ export class VegaParser { this.error = undefined; this.warnings = []; this.searchAPI = searchAPI; - - const onWarn = this._onWarning.bind(this); - this._urlParsers = { - elasticsearch: new EsQueryParser(timeCache, this.searchAPI, filters, onWarn), - emsfile: new EmsFileParser(serviceSettings), - url: new UrlParser(onWarn), - }; + this.getServiceSettings = getServiceSettings; + this.filters = filters; + this.timeCache = timeCache; } async parseAsync() { @@ -123,7 +122,7 @@ export class VegaParser { throw new Error( i18n.translate('visTypeVega.vegaParser.inputSpecDoesNotSpecifySchemaErrorMessage', { defaultMessage: `Your specification requires a {schemaParam} field with a valid URL for -Vega (see {vegaSchemaUrl}) or +Vega (see {vegaSchemaUrl}) or Vega-Lite (see {vegaLiteSchemaUrl}). The URL is an identifier only. Kibana and your browser will never access this URL.`, values: { @@ -547,6 +546,15 @@ The URL is an identifier only. Kibana and your browser will never access this UR * @private */ async _resolveDataUrls() { + if (!this._urlParsers) { + const serviceSettings = await this.getServiceSettings(); + const onWarn = this._onWarning.bind(this); + this._urlParsers = { + elasticsearch: new EsQueryParser(this.timeCache, this.searchAPI, this.filters, onWarn), + emsfile: new EmsFileParser(serviceSettings), + url: new UrlParser(onWarn), + }; + } const pending: PendingType = {}; this.searchAPI.resetSearchStats(); @@ -560,7 +568,7 @@ The URL is an identifier only. Kibana and your browser will never access this UR type = DEFAULT_PARSER; } - const parser = this._urlParsers[type]; + const parser = this._urlParsers![type]; if (parser === undefined) { throw new Error( i18n.translate('visTypeVega.vegaParser.notSupportedUrlTypeErrorMessage', { @@ -584,7 +592,7 @@ The URL is an identifier only. Kibana and your browser will never access this UR if (pendingParsers.length > 0) { // let each parser populate its data in parallel await Promise.all( - pendingParsers.map((type) => this._urlParsers[type].populateData(pending[type])) + pendingParsers.map((type) => this._urlParsers![type].populateData(pending[type])) ); } } diff --git a/src/plugins/vis_type_vega/public/plugin.ts b/src/plugins/vis_type_vega/public/plugin.ts index 4b8ff8e2cb43a..ce5c5130961c6 100644 --- a/src/plugins/vis_type_vega/public/plugin.ts +++ b/src/plugins/vis_type_vega/public/plugin.ts @@ -28,7 +28,6 @@ import { setSavedObjects, setInjectedVars, setUISettings, - setKibanaMapFactory, setMapsLegacyConfig, setInjectedMetadata, } from './services'; @@ -47,7 +46,7 @@ export interface VegaVisualizationDependencies { plugins: { data: DataPublicPluginSetup; }; - serviceSettings: IServiceSettings; + getServiceSettings: () => Promise; } /** @internal */ @@ -81,7 +80,6 @@ export class VegaPlugin implements Plugin, void> { emsTileLayerId: core.injectedMetadata.getInjectedVar('emsTileLayerId', true), }); setUISettings(core.uiSettings); - setKibanaMapFactory(mapsLegacy.getKibanaMapFactoryProvider); setMapsLegacyConfig(mapsLegacy.config); const visualizationDependencies: Readonly = { @@ -89,7 +87,7 @@ export class VegaPlugin implements Plugin, void> { plugins: { data, }, - serviceSettings: mapsLegacy.serviceSettings, + getServiceSettings: mapsLegacy.getServiceSettings, }; inspector.registerView(getVegaInspectorView({ uiSettings: core.uiSettings })); diff --git a/src/plugins/vis_type_vega/public/services.ts b/src/plugins/vis_type_vega/public/services.ts index dfb2c96e9f894..455fe67dbc423 100644 --- a/src/plugins/vis_type_vega/public/services.ts +++ b/src/plugins/vis_type_vega/public/services.ts @@ -33,9 +33,6 @@ export const [getData, setData] = createGetterSetter('Dat export const [getNotifications, setNotifications] = createGetterSetter( 'Notifications' ); -export const [getKibanaMapFactory, setKibanaMapFactory] = createGetterSetter( - 'KibanaMapFactory' -); export const [getUISettings, setUISettings] = createGetterSetter('UISettings'); diff --git a/src/plugins/vis_type_vega/public/vega_request_handler.ts b/src/plugins/vis_type_vega/public/vega_request_handler.ts index c09a9466df602..f48b61ed70822 100644 --- a/src/plugins/vis_type_vega/public/vega_request_handler.ts +++ b/src/plugins/vis_type_vega/public/vega_request_handler.ts @@ -40,7 +40,7 @@ interface VegaRequestHandlerContext { } export function createVegaRequestHandler( - { plugins: { data }, core: { uiSettings }, serviceSettings }: VegaVisualizationDependencies, + { plugins: { data }, core: { uiSettings }, getServiceSettings }: VegaVisualizationDependencies, context: VegaRequestHandlerContext = {} ) { let searchAPI: SearchAPI; @@ -70,7 +70,7 @@ export function createVegaRequestHandler( const esQueryConfigs = esQuery.getEsQueryConfig(uiSettings); const filtersDsl = esQuery.buildEsQuery(undefined, query, filters, esQueryConfigs); const { VegaParser } = await import('./data_model/vega_parser'); - const vp = new VegaParser(visParams.spec, searchAPI, timeCache, filtersDsl, serviceSettings); + const vp = new VegaParser(visParams.spec, searchAPI, timeCache, filtersDsl, getServiceSettings); return await vp.parseAsync(); }; diff --git a/src/plugins/vis_type_vega/public/vega_view/vega_map_layer.js b/src/plugins/vis_type_vega/public/vega_view/vega_map_layer.js index bc1cb4e4734c7..ec4959a51d741 100644 --- a/src/plugins/vis_type_vega/public/vega_view/vega_map_layer.js +++ b/src/plugins/vis_type_vega/public/vega_view/vega_map_layer.js @@ -17,16 +17,16 @@ * under the License. */ -import { KibanaMapLayer, L } from '../../../maps_legacy/public'; +import { KibanaMapLayer } from '../../../maps_legacy/public'; export class VegaMapLayer extends KibanaMapLayer { - constructor(spec, options) { + constructor(spec, options, leaflet) { super(); // Used by super.getAttributions() this._attribution = options.attribution; delete options.attribution; - this._leafletLayer = L.vega(spec, options); + this._leafletLayer = leaflet.vega(spec, options); } getVegaView() { diff --git a/src/plugins/vis_type_vega/public/vega_view/vega_map_view.js b/src/plugins/vis_type_vega/public/vega_view/vega_map_view.js index 78ae2efdbdda5..d925aaeeced66 100644 --- a/src/plugins/vis_type_vega/public/vega_view/vega_map_view.js +++ b/src/plugins/vis_type_vega/public/vega_view/vega_map_view.js @@ -21,7 +21,8 @@ import { i18n } from '@kbn/i18n'; import { vega } from '../lib/vega'; import { VegaBaseView } from './vega_base_view'; import { VegaMapLayer } from './vega_map_layer'; -import { getEmsTileLayerId, getUISettings, getKibanaMapFactory } from '../services'; +import { getEmsTileLayerId, getUISettings } from '../services'; +import { lazyLoadMapsLegacyModules } from '../../../maps_legacy/public'; export class VegaMapView extends VegaBaseView { constructor(opts) { @@ -106,7 +107,9 @@ export class VegaMapView extends VegaBaseView { // maxBounds = L.latLngBounds(L.latLng(b[1], b[0]), L.latLng(b[3], b[2])); // } - this._kibanaMap = getKibanaMapFactory()(this._$container.get(0), { + const modules = await lazyLoadMapsLegacyModules(); + + this._kibanaMap = new modules.KibanaMap(this._$container.get(0), { zoom, minZoom, maxZoom, @@ -122,14 +125,18 @@ export class VegaMapView extends VegaBaseView { }); } - const vegaMapLayer = new VegaMapLayer(this._parser.spec, { - vega, - bindingsContainer: this._$controls.get(0), - delayRepaint: mapConfig.delayRepaint, - viewConfig: this._vegaViewConfig, - onWarning: this.onWarn.bind(this), - onError: this.onError.bind(this), - }); + const vegaMapLayer = new VegaMapLayer( + this._parser.spec, + { + vega, + bindingsContainer: this._$controls.get(0), + delayRepaint: mapConfig.delayRepaint, + viewConfig: this._vegaViewConfig, + onWarning: this.onWarn.bind(this), + onError: this.onError.bind(this), + }, + modules.L + ); this._kibanaMap.addLayer(vegaMapLayer); diff --git a/src/plugins/vis_type_vega/public/vega_visualization.js b/src/plugins/vis_type_vega/public/vega_visualization.js index d6db0f9ea239f..2d58e9cda60cd 100644 --- a/src/plugins/vis_type_vega/public/vega_visualization.js +++ b/src/plugins/vis_type_vega/public/vega_visualization.js @@ -19,7 +19,7 @@ import { i18n } from '@kbn/i18n'; import { getNotifications, getData, getSavedObjects } from './services'; -export const createVegaVisualization = ({ serviceSettings }) => +export const createVegaVisualization = ({ getServiceSettings }) => class VegaVisualization { constructor(el, vis) { this._el = el; @@ -102,6 +102,7 @@ export const createVegaVisualization = ({ serviceSettings }) => this._vegaView = null; } + const serviceSettings = await getServiceSettings(); const { filterManager } = this.dataPlugin.query; const { timefilter } = this.dataPlugin.query.timefilter; const vegaViewParams = { diff --git a/src/plugins/vis_type_vega/public/vega_visualization.test.js b/src/plugins/vis_type_vega/public/vega_visualization.test.js index 1bf625af76207..dcf1722768075 100644 --- a/src/plugins/vis_type_vega/public/vega_visualization.test.js +++ b/src/plugins/vis_type_vega/public/vega_visualization.test.js @@ -32,16 +32,9 @@ import { SearchAPI } from './data_model/search_api'; import { createVegaTypeDefinition } from './vega_type'; -import { - setInjectedVars, - setData, - setSavedObjects, - setNotifications, - setKibanaMapFactory, -} from './services'; +import { setInjectedVars, setData, setSavedObjects, setNotifications } from './services'; import { coreMock } from '../../../core/public/mocks'; import { dataPluginMock } from '../../data/public/mocks'; -import { KibanaMap } from '../../maps_legacy/public/map/kibana_map'; jest.mock('./default_spec', () => ({ getDefaultSpec: () => jest.requireActual('./test_utils/default.spec.json'), @@ -77,8 +70,11 @@ describe('VegaVisualizations', () => { mockHeight = jest.spyOn($.prototype, 'height').mockImplementation(() => mockedHeightValue); }; + const mockGetServiceSettings = async () => { + return {}; + }; + beforeEach(() => { - setKibanaMapFactory((...args) => new KibanaMap(...args)); setInjectedVars({ emsTileLayerId: {}, enableExternalUrls: true, @@ -92,6 +88,7 @@ describe('VegaVisualizations', () => { plugins: { data: dataPluginMock.createSetupContract(), }, + getServiceSettings: mockGetServiceSettings, }; vegaVisType = createVegaTypeDefinition(vegaVisualizationDependencies); @@ -128,7 +125,10 @@ describe('VegaVisualizations', () => { search: dataPluginStart.search, uiSettings: coreStart.uiSettings, injectedMetadata: coreStart.injectedMetadata, - }) + }), + 0, + 0, + mockGetServiceSettings ); await vegaParser.parseAsync(); await vegaVis.render(vegaParser); @@ -155,7 +155,10 @@ describe('VegaVisualizations', () => { search: dataPluginStart.search, uiSettings: coreStart.uiSettings, injectedMetadata: coreStart.injectedMetadata, - }) + }), + 0, + 0, + mockGetServiceSettings ); await vegaParser.parseAsync(); @@ -176,7 +179,10 @@ describe('VegaVisualizations', () => { search: dataPluginStart.search, uiSettings: coreStart.uiSettings, injectedMetadata: coreStart.injectedMetadata, - }) + }), + 0, + 0, + mockGetServiceSettings ); await vegaParser.parseAsync(); diff --git a/x-pack/package.json b/x-pack/package.json index 3702e1a49cbe5..984843e5b6360 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -277,7 +277,7 @@ "@babel/register": "^7.10.5", "@babel/runtime": "^7.11.2", "@elastic/datemath": "5.0.3", - "@elastic/ems-client": "7.9.3", + "@elastic/ems-client": "7.10.0", "@elastic/eui": "29.0.0", "@elastic/filesaver": "1.1.2", "@elastic/node-crypto": "1.2.1", diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/enterprise_search_url.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/enterprise_search_url.mock.ts new file mode 100644 index 0000000000000..47660d0a31720 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/enterprise_search_url.mock.ts @@ -0,0 +1,9 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { externalUrl } from '../shared/enterprise_search_url'; + +externalUrl.enterpriseSearchUrl = 'http://localhost:3002'; diff --git a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts index ea3c3923cc472..ee77b0937cd82 100644 --- a/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts +++ b/x-pack/plugins/enterprise_search/public/applications/__mocks__/kibana_context.mock.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ExternalUrl } from '../shared/enterprise_search_url'; - /** * A set of default Kibana context values to use across component tests. * @see enterprise_search/public/index.tsx for the KibanaContext definition/import @@ -15,5 +13,4 @@ export const mockKibanaContext = { setBreadcrumbs: jest.fn(), setDocTitle: jest.fn(), config: { host: 'http://localhost:3002' }, - externalUrl: new ExternalUrl('http://localhost:3002'), }; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/empty_state.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/empty_state.test.tsx index 233db7d4c5917..53f50822cf653 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/empty_state.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/empty_state.test.tsx @@ -5,7 +5,6 @@ */ import '../../../../__mocks__/kea.mock'; -import '../../../../__mocks__/shallow_usecontext.mock'; import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/empty_state.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/empty_state.tsx index 5ed1f0b277306..cfe88d00ce14e 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/empty_state.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/empty_state.tsx @@ -4,15 +4,15 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; +import React from 'react'; import { useValues } from 'kea'; import { EuiPageContent, EuiEmptyPrompt, EuiButton } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { sendTelemetry } from '../../../../shared/telemetry'; import { HttpLogic } from '../../../../shared/http'; +import { getAppSearchUrl } from '../../../../shared/enterprise_search_url'; import { SetAppSearchChrome as SetPageChrome } from '../../../../shared/kibana_chrome'; -import { KibanaContext, IKibanaContext } from '../../../../index'; import { CREATE_ENGINES_PATH } from '../../../routes'; import { EngineOverviewHeader } from './header'; @@ -21,9 +21,6 @@ import './empty_state.scss'; export const EmptyState: React.FC = () => { const { http } = useValues(HttpLogic); - const { - externalUrl: { getAppSearchUrl }, - } = useContext(KibanaContext) as IKibanaContext; const buttonProps = { href: getAppSearchUrl(CREATE_ENGINES_PATH), diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/header.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/header.test.tsx index 8c7dfa2b7c3d6..78ee5764be5a9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/header.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/header.test.tsx @@ -5,7 +5,7 @@ */ import '../../../../__mocks__/kea.mock'; -import '../../../../__mocks__/shallow_usecontext.mock'; +import '../../../../__mocks__/enterprise_search_url.mock'; import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/header.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/header.tsx index dca0d45a207b4..6ebb2c5bf453d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/header.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/components/header.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; +import React from 'react'; import { useValues } from 'kea'; import { EuiPageHeader, @@ -18,13 +18,10 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { sendTelemetry } from '../../../../shared/telemetry'; import { HttpLogic } from '../../../../shared/http'; -import { KibanaContext, IKibanaContext } from '../../../../index'; +import { getAppSearchUrl } from '../../../../shared/enterprise_search_url'; export const EngineOverviewHeader: React.FC = () => { const { http } = useValues(HttpLogic); - const { - externalUrl: { getAppSearchUrl }, - } = useContext(KibanaContext) as IKibanaContext; const buttonProps = { fill: true, diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_table.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_table.test.tsx index 8e92f21f8ffed..c66fd24fee12a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_table.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_table.test.tsx @@ -5,7 +5,7 @@ */ import '../../../__mocks__/kea.mock'; -import '../../../__mocks__/shallow_usecontext.mock'; +import '../../../__mocks__/enterprise_search_url.mock'; import { mockHttpValues } from '../../../__mocks__/'; import React from 'react'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_table.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_table.tsx index 6888be1dc2b5b..40fb313f30b31 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_table.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/engine_overview/engine_table.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; +import React from 'react'; import { useValues } from 'kea'; import { EuiBasicTable, EuiBasicTableColumn, EuiLink } from '@elastic/eui'; import { FormattedMessage, FormattedDate, FormattedNumber } from '@kbn/i18n/react'; @@ -12,7 +12,7 @@ import { i18n } from '@kbn/i18n'; import { sendTelemetry } from '../../../shared/telemetry'; import { HttpLogic } from '../../../shared/http'; -import { KibanaContext, IKibanaContext } from '../../../index'; +import { getAppSearchUrl } from '../../../shared/enterprise_search_url'; import { getEngineRoute } from '../../routes'; import { ENGINES_PAGE_SIZE } from '../../../../../common/constants'; @@ -43,9 +43,6 @@ export const EngineTable: React.FC = ({ pagination: { totalEngines, pageIndex, onPaginate }, }) => { const { http } = useValues(HttpLogic); - const { - externalUrl: { getAppSearchUrl }, - } = useContext(KibanaContext) as IKibanaContext; const engineLinkProps = (name: string) => ({ href: getAppSearchUrl(getEngineRoute(name)), diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx index 350bc97085d7b..052f4446e4409 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.test.tsx @@ -6,6 +6,7 @@ import '../__mocks__/shallow_usecontext.mock'; import '../__mocks__/kea.mock'; +import '../__mocks__/enterprise_search_url.mock'; import React, { useContext } from 'react'; import { Redirect } from 'react-router-dom'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx index c848415daf612..410f6eb524822 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/index.tsx @@ -11,6 +11,7 @@ import { useActions, useValues } from 'kea'; import { i18n } from '@kbn/i18n'; import { KibanaContext, IKibanaContext } from '../index'; +import { getAppSearchUrl } from '../shared/enterprise_search_url'; import { HttpLogic } from '../shared/http'; import { AppLogic } from './app_logic'; import { IInitialAppData } from '../../../common/types'; @@ -86,10 +87,6 @@ export const AppSearchConfigured: React.FC = (props) => { }; export const AppSearchNav: React.FC = () => { - const { - externalUrl: { getAppSearchUrl }, - } = useContext(KibanaContext) as IKibanaContext; - const { myRole: { canViewSettings, canViewAccountCredentials, canViewRoleMappings }, } = useValues(AppLogic); diff --git a/x-pack/plugins/enterprise_search/public/applications/index.test.tsx b/x-pack/plugins/enterprise_search/public/applications/index.test.tsx index 6ee63ee22cae2..66772f96671e8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/index.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/index.test.tsx @@ -54,7 +54,7 @@ describe('renderHeaderActions', () => { const mockHeaderEl = document.createElement('header'); const MockHeaderActions = () => ; - const unmount = renderHeaderActions(MockHeaderActions, mockHeaderEl, {} as any); + const unmount = renderHeaderActions(MockHeaderActions, mockHeaderEl); expect(mockHeaderEl.querySelector('.hello-world')).not.toBeNull(); unmount(); diff --git a/x-pack/plugins/enterprise_search/public/applications/index.tsx b/x-pack/plugins/enterprise_search/public/applications/index.tsx index 4a25ecf6067cc..2c6bc787923e3 100644 --- a/x-pack/plugins/enterprise_search/public/applications/index.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/index.tsx @@ -18,12 +18,11 @@ import { PluginsStart, ClientConfigType, ClientData } from '../plugin'; import { mountLicensingLogic } from './shared/licensing'; import { mountHttpLogic } from './shared/http'; import { mountFlashMessagesLogic } from './shared/flash_messages'; -import { IExternalUrl } from './shared/enterprise_search_url'; +import { externalUrl } from './shared/enterprise_search_url'; import { IInitialAppData } from '../../common/types'; export interface IKibanaContext { config: { host?: string }; - externalUrl: IExternalUrl; navigateToUrl: ApplicationStart['navigateToUrl']; setBreadcrumbs(crumbs: ChromeBreadcrumb[]): void; setDocTitle(title: string): void; @@ -42,7 +41,8 @@ export const renderApp = ( { params, core, plugins }: { params: AppMountParameters; core: CoreStart; plugins: PluginsStart }, { config, data }: { config: ClientConfigType; data: ClientData } ) => { - const { externalUrl, errorConnecting, ...initialData } = data; + const { publicUrl, errorConnecting, ...initialData } = data; + externalUrl.enterpriseSearchUrl = publicUrl || config.host || ''; resetContext({ createStore: true }); const store = getContext().store as Store; @@ -64,7 +64,6 @@ export const renderApp = ( , - kibanaHeaderEl: HTMLElement, - externalUrl: IExternalUrl -) => { - ReactDOM.render(, kibanaHeaderEl); +export const renderHeaderActions = (HeaderActions: React.FC, kibanaHeaderEl: HTMLElement) => { + ReactDOM.render(, kibanaHeaderEl); return () => ReactDOM.unmountComponentAtNode(kibanaHeaderEl); }; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/external_url.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/external_url.test.ts new file mode 100644 index 0000000000000..55c4f465d9ed4 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/external_url.test.ts @@ -0,0 +1,42 @@ +/* + * 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 { externalUrl, getEnterpriseSearchUrl, getAppSearchUrl, getWorkplaceSearchUrl } from './'; + +describe('Enterprise Search external URL helpers', () => { + describe('getter/setter tests', () => { + it('defaults to an empty string', () => { + expect(externalUrl.enterpriseSearchUrl).toEqual(''); + }); + + it('sets the internal enterpriseSearchUrl value', () => { + externalUrl.enterpriseSearchUrl = 'http://localhost:3002'; + expect(externalUrl.enterpriseSearchUrl).toEqual('http://localhost:3002'); + }); + + it('does not allow mutating enterpriseSearchUrl once set', () => { + externalUrl.enterpriseSearchUrl = 'hello world'; + expect(externalUrl.enterpriseSearchUrl).toEqual('http://localhost:3002'); + }); + }); + + describe('function helpers', () => { + it('generates a public Enterprise Search URL', () => { + expect(getEnterpriseSearchUrl()).toEqual('http://localhost:3002'); + expect(getEnterpriseSearchUrl('/login')).toEqual('http://localhost:3002/login'); + }); + + it('generates a public App Search URL', () => { + expect(getAppSearchUrl()).toEqual('http://localhost:3002/as'); + expect(getAppSearchUrl('/path')).toEqual('http://localhost:3002/as/path'); + }); + + it('generates a public Workplace Search URL', () => { + expect(getWorkplaceSearchUrl()).toEqual('http://localhost:3002/ws'); + expect(getWorkplaceSearchUrl('/path')).toEqual('http://localhost:3002/ws/path'); + }); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/external_url.ts b/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/external_url.ts new file mode 100644 index 0000000000000..80b506f31ad61 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/external_url.ts @@ -0,0 +1,37 @@ +/* + * 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. + */ + +/** + * NOTE: The externalUrl obj holds the reference to externalUrl, which should + * only ever be updated once on plugin init. We're using a getter and setter + * here to ensure it isn't accidentally mutated. + * + * Someday (8.x+), when our UI is entirely on Kibana and no longer on + * Enterprise Search's standalone UI, we can potentially deprecate this helper. + */ +export const externalUrl = { + _enterpriseSearchUrl: '', + get enterpriseSearchUrl() { + return this._enterpriseSearchUrl; + }, + set enterpriseSearchUrl(value) { + if (this._enterpriseSearchUrl) { + // enterpriseSearchUrl is set once on plugin init - we should not mutate it + return; + } + this._enterpriseSearchUrl = value; + }, +}; + +export const getEnterpriseSearchUrl = (path: string = ''): string => { + return externalUrl.enterpriseSearchUrl + path; +}; +export const getAppSearchUrl = (path: string = ''): string => { + return getEnterpriseSearchUrl('/as' + path); +}; +export const getWorkplaceSearchUrl = (path: string = ''): string => { + return getEnterpriseSearchUrl('/ws' + path); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/generate_external_url.test.ts b/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/generate_external_url.test.ts deleted file mode 100644 index 1092c88cbbc11..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/generate_external_url.test.ts +++ /dev/null @@ -1,25 +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 { ExternalUrl } from './'; - -describe('Enterprise Search external URL helper', () => { - const externalUrl = new ExternalUrl('http://localhost:3002'); - - it('exposes a public enterpriseSearchUrl string', () => { - expect(externalUrl.enterpriseSearchUrl).toEqual('http://localhost:3002'); - }); - - it('generates a public App Search URL', () => { - expect(externalUrl.getAppSearchUrl()).toEqual('http://localhost:3002/as'); - expect(externalUrl.getAppSearchUrl('/path')).toEqual('http://localhost:3002/as/path'); - }); - - it('generates a public Workplace Search URL', () => { - expect(externalUrl.getWorkplaceSearchUrl()).toEqual('http://localhost:3002/ws'); - expect(externalUrl.getWorkplaceSearchUrl('/path')).toEqual('http://localhost:3002/ws/path'); - }); -}); diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/generate_external_url.ts b/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/generate_external_url.ts deleted file mode 100644 index 9db48d197f3bc..0000000000000 --- a/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/generate_external_url.ts +++ /dev/null @@ -1,38 +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. - */ - -/** - * Small helper for generating external public-facing URLs - * to the legacy/standalone Enterprise Search app - */ -export interface IExternalUrl { - enterpriseSearchUrl?: string; - getAppSearchUrl(path?: string): string; - getWorkplaceSearchUrl(path?: string): string; -} - -export class ExternalUrl { - public enterpriseSearchUrl: string; - - constructor(externalUrl: string) { - this.enterpriseSearchUrl = externalUrl; - - this.getAppSearchUrl = this.getAppSearchUrl.bind(this); - this.getWorkplaceSearchUrl = this.getWorkplaceSearchUrl.bind(this); - } - - private getExternalUrl(path: string): string { - return this.enterpriseSearchUrl + path; - } - - public getAppSearchUrl(path: string = ''): string { - return this.getExternalUrl('/as' + path); - } - - public getWorkplaceSearchUrl(path: string = ''): string { - return this.getExternalUrl('/ws' + path); - } -} diff --git a/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/index.ts b/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/index.ts index d2d82a43c6dd9..177d8e0535c72 100644 --- a/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/shared/enterprise_search_url/index.ts @@ -4,4 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -export { ExternalUrl, IExternalUrl } from './generate_external_url'; +export { + externalUrl, + getEnterpriseSearchUrl, + getAppSearchUrl, + getWorkplaceSearchUrl, +} from './external_url'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.test.tsx index a006c5e3775d5..0ebd59eda5be7 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.test.tsx @@ -4,26 +4,26 @@ * you may not use this file except in compliance with the Elastic License. */ +import { externalUrl } from '../../../shared/enterprise_search_url'; + import React from 'react'; import { shallow } from 'enzyme'; - import { EuiButtonEmpty } from '@elastic/eui'; -import { ExternalUrl } from '../../../shared/enterprise_search_url'; import { WorkplaceSearchHeaderActions } from './'; describe('WorkplaceSearchHeaderActions', () => { - const externalUrl = new ExternalUrl('http://localhost:3002'); + it('does not render without an Enterprise Search URL set', () => { + const wrapper = shallow(); - it('renders a link to the search application', () => { - const wrapper = shallow(); - - expect(wrapper.find(EuiButtonEmpty).prop('href')).toEqual('http://localhost:3002/ws/search'); + expect(wrapper.isEmptyRender()).toBe(true); }); - it('does not render without an Enterprise Search host URL set', () => { - const wrapper = shallow(); + it('renders a link to the search application', () => { + externalUrl.enterpriseSearchUrl = 'http://localhost:3002'; - expect(wrapper.isEmptyRender()).toBe(true); + const wrapper = shallow(); + + expect(wrapper.find(EuiButtonEmpty).prop('href')).toEqual('http://localhost:3002/ws/search'); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.tsx index fa32d598f848d..b7da5b4281aa0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/kibana_header_actions.tsx @@ -8,15 +8,10 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiButtonEmpty } from '@elastic/eui'; -import { IExternalUrl } from '../../../shared/enterprise_search_url'; +import { externalUrl, getWorkplaceSearchUrl } from '../../../shared/enterprise_search_url'; -interface IProps { - externalUrl: IExternalUrl; -} - -export const WorkplaceSearchHeaderActions: React.FC = ({ externalUrl }) => { - const { enterpriseSearchUrl, getWorkplaceSearchUrl } = externalUrl; - if (!enterpriseSearchUrl) return null; +export const WorkplaceSearchHeaderActions: React.FC = () => { + if (!externalUrl.enterpriseSearchUrl) return null; return ( diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.test.tsx index 0e85d8467cff0..2553284744e4d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.test.tsx @@ -4,7 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../__mocks__/shallow_usecontext.mock'; +import '../../../__mocks__/enterprise_search_url.mock'; + import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.tsx index 9fb627ed09791..5572716391112 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/layout/nav.tsx @@ -3,13 +3,13 @@ * 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, { useContext } from 'react'; +import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiSpacer } from '@elastic/eui'; import { WORKPLACE_SEARCH_PLUGIN } from '../../../../../common/constants'; -import { KibanaContext, IKibanaContext } from '../../../index'; +import { getWorkplaceSearchUrl } from '../../../shared/enterprise_search_url'; import { SideNav, SideNavLink } from '../../../shared/layout'; import { @@ -22,10 +22,6 @@ import { } from '../../routes'; export const WorkplaceSearchNav: React.FC = () => { - const { - externalUrl: { getWorkplaceSearchUrl }, - } = useContext(KibanaContext) as IKibanaContext; - // TODO: icons return ( diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.test.tsx index c73eb05ccec16..2013b2609f33b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.test.tsx @@ -5,7 +5,6 @@ */ import '../../../../__mocks__/kea.mock'; -import '../../../../__mocks__/shallow_usecontext.mock'; import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.tsx index a80de9fd6ac82..344b442d9a678 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/components/shared/product_button/product_button.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; +import React from 'react'; import { useValues } from 'kea'; import { EuiButton, EuiButtonProps, EuiLinkProps } from '@elastic/eui'; @@ -12,13 +12,10 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { sendTelemetry } from '../../../../shared/telemetry'; import { HttpLogic } from '../../../../shared/http'; -import { KibanaContext, IKibanaContext } from '../../../../index'; +import { getWorkplaceSearchUrl } from '../../../../shared/enterprise_search_url'; export const ProductButton: React.FC = () => { const { http } = useValues(HttpLogic); - const { - externalUrl: { getWorkplaceSearchUrl }, - } = useContext(KibanaContext) as IKibanaContext; const buttonProps = { fill: true, diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.test.tsx index c890adb8ea043..6be033d7225a8 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.test.tsx @@ -5,7 +5,7 @@ */ import '../../../__mocks__/kea.mock'; -import '../../../__mocks__/shallow_usecontext.mock'; +import '../../../__mocks__/enterprise_search_url.mock'; import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.tsx index 79be7ef1cb158..c1070d57f2856 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_card.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; +import React from 'react'; import { useValues } from 'kea'; import { @@ -21,7 +21,7 @@ import { import { sendTelemetry } from '../../../shared/telemetry'; import { HttpLogic } from '../../../shared/http'; -import { KibanaContext, IKibanaContext } from '../../../index'; +import { getWorkplaceSearchUrl } from '../../../shared/enterprise_search_url'; interface IOnboardingCardProps { title: React.ReactNode; @@ -43,9 +43,6 @@ export const OnboardingCard: React.FC = ({ complete, }) => { const { http } = useValues(HttpLogic); - const { - externalUrl: { getWorkplaceSearchUrl }, - } = useContext(KibanaContext) as IKibanaContext; const onClick = () => sendTelemetry({ diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.test.tsx index 0f3eee074caef..37b3340b96a6a 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.test.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../__mocks__/shallow_usecontext.mock'; import './__mocks__/overview_logic.mock'; import { setMockValues } from './__mocks__'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.tsx index 079d981533e01..132824833909d 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/onboarding_steps.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; +import React from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { useValues } from 'kea'; @@ -24,7 +24,7 @@ import { import sharedSourcesIcon from '../../components/shared/assets/share_circle.svg'; import { sendTelemetry } from '../../../shared/telemetry'; import { HttpLogic } from '../../../shared/http'; -import { KibanaContext, IKibanaContext } from '../../../index'; +import { getWorkplaceSearchUrl } from '../../../shared/enterprise_search_url'; import { ORG_SOURCES_PATH, USERS_PATH, ORG_SETTINGS_PATH } from '../../routes'; import { ContentSection } from '../../components/shared/content_section'; @@ -137,9 +137,6 @@ export const OnboardingSteps: React.FC = () => { export const OrgNameOnboarding: React.FC = () => { const { http } = useValues(HttpLogic); - const { - externalUrl: { getWorkplaceSearchUrl }, - } = useContext(KibanaContext) as IKibanaContext; const onClick = () => sendTelemetry({ diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.test.tsx index 31613098f9fcc..989ff800483f6 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.test.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../__mocks__/shallow_usecontext.mock'; import './__mocks__/overview_logic.mock'; import { setMockValues } from './__mocks__'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.tsx index dd62e6de7c046..d1b5228123d94 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/recent_activity.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; +import React from 'react'; import moment from 'moment'; import { useValues } from 'kea'; @@ -15,7 +15,7 @@ import { FormattedMessage } from '@kbn/i18n/react'; import { ContentSection } from '../../components/shared/content_section'; import { sendTelemetry } from '../../../shared/telemetry'; import { HttpLogic } from '../../../shared/http'; -import { KibanaContext, IKibanaContext } from '../../../index'; +import { getWorkplaceSearchUrl } from '../../../shared/enterprise_search_url'; import { SOURCE_DETAILS_PATH, getContentSourcePath } from '../../routes'; import { AppLogic } from '../../app_logic'; @@ -95,9 +95,6 @@ export const RecentActivityItem: React.FC = ({ sourceId, }) => { const { http } = useValues(HttpLogic); - const { - externalUrl: { getWorkplaceSearchUrl }, - } = useContext(KibanaContext) as IKibanaContext; const onClick = () => sendTelemetry({ diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.test.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.test.tsx index edf266231b39e..013b23d2a9ec0 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.test.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import '../../../__mocks__/shallow_usecontext.mock'; +import '../../../__mocks__/enterprise_search_url.mock'; import React from 'react'; import { shallow } from 'enzyme'; diff --git a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.tsx b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.tsx index 3e1d285698c0c..6c4f43b1a3a22 100644 --- a/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/workplace_search/views/overview/statistic_card.tsx @@ -4,11 +4,10 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { useContext } from 'react'; - +import React from 'react'; import { EuiCard, EuiFlexItem, EuiTitle, EuiTextColor } from '@elastic/eui'; -import { KibanaContext, IKibanaContext } from '../../../index'; +import { getWorkplaceSearchUrl } from '../../../shared/enterprise_search_url'; interface IStatisticCardProps { title: string; @@ -17,10 +16,6 @@ interface IStatisticCardProps { } export const StatisticCard: React.FC = ({ title, count = 0, actionPath }) => { - const { - externalUrl: { getWorkplaceSearchUrl }, - } = useContext(KibanaContext) as IKibanaContext; - const linkProps = actionPath ? { href: getWorkplaceSearchUrl(actionPath), diff --git a/x-pack/plugins/enterprise_search/public/plugin.ts b/x-pack/plugins/enterprise_search/public/plugin.ts index f59ec830c812f..d870127f297b4 100644 --- a/x-pack/plugins/enterprise_search/public/plugin.ts +++ b/x-pack/plugins/enterprise_search/public/plugin.ts @@ -23,13 +23,13 @@ import { WORKPLACE_SEARCH_PLUGIN, } from '../common/constants'; import { IInitialAppData } from '../common/types'; -import { ExternalUrl, IExternalUrl } from './applications/shared/enterprise_search_url'; +import { externalUrl } from './applications/shared/enterprise_search_url'; export interface ClientConfigType { host?: string; } export interface ClientData extends IInitialAppData { - externalUrl: IExternalUrl; + publicUrl?: string; errorConnecting?: boolean; } @@ -47,7 +47,6 @@ export class EnterpriseSearchPlugin implements Plugin { constructor(initializerContext: PluginInitializerContext) { this.config = initializerContext.config.get(); - this.data.externalUrl = new ExternalUrl(this.config.host || ''); } public setup(core: CoreSetup, plugins: PluginsSetup) { @@ -59,11 +58,11 @@ export class EnterpriseSearchPlugin implements Plugin { category: DEFAULT_APP_CATEGORIES.enterpriseSearch, mount: async (params: AppMountParameters) => { const kibanaDeps = await this.getKibanaDeps(core, params); - const pluginData = this.getPluginData(); - const { chrome, http } = kibanaDeps.core; chrome.docTitle.change(ENTERPRISE_SEARCH_PLUGIN.NAME); + await this.getInitialData(http); + const pluginData = this.getPluginData(); const { renderApp } = await import('./applications'); const { EnterpriseSearch } = await import('./applications/enterprise_search'); @@ -80,11 +79,11 @@ export class EnterpriseSearchPlugin implements Plugin { category: DEFAULT_APP_CATEGORIES.enterpriseSearch, mount: async (params: AppMountParameters) => { const kibanaDeps = await this.getKibanaDeps(core, params); - const pluginData = this.getPluginData(); - const { chrome, http } = kibanaDeps.core; chrome.docTitle.change(APP_SEARCH_PLUGIN.NAME); + await this.getInitialData(http); + const pluginData = this.getPluginData(); const { renderApp } = await import('./applications'); const { AppSearch } = await import('./applications/app_search'); @@ -101,11 +100,11 @@ export class EnterpriseSearchPlugin implements Plugin { category: DEFAULT_APP_CATEGORIES.enterpriseSearch, mount: async (params: AppMountParameters) => { const kibanaDeps = await this.getKibanaDeps(core, params); - const pluginData = this.getPluginData(); - const { chrome, http } = kibanaDeps.core; chrome.docTitle.change(APP_SEARCH_PLUGIN.NAME); + await this.getInitialData(http); + const pluginData = this.getPluginData(); const { renderApp, renderHeaderActions } = await import('./applications'); const { WorkplaceSearch } = await import('./applications/workplace_search'); @@ -114,7 +113,7 @@ export class EnterpriseSearchPlugin implements Plugin { './applications/workplace_search/components/layout' ); params.setHeaderActionMenu((element) => - renderHeaderActions(WorkplaceSearchHeaderActions, element, this.data.externalUrl) + renderHeaderActions(WorkplaceSearchHeaderActions, element) ); return renderApp(WorkplaceSearch, kibanaDeps, pluginData); @@ -174,14 +173,14 @@ export class EnterpriseSearchPlugin implements Plugin { if (this.hasInitialized) return; // We've already made an initial call try { - const { publicUrl, ...initialData } = await http.get('/api/enterprise_search/config_data'); - this.data = { ...this.data, ...initialData }; - if (publicUrl) this.data.externalUrl = new ExternalUrl(publicUrl); - + this.data = await http.get('/api/enterprise_search/config_data'); this.hasInitialized = true; + + // TODO: This is a temporary workaround to keep the WorkplaceSearchHeaderActions working. + // We'll solve this shortly by ensuring the main app store loads before the header actions. + externalUrl.enterpriseSearchUrl = this.data.publicUrl || this.config.host; } catch { this.data.errorConnecting = true; - // The plugin will attempt to re-fetch config data on page change } } } diff --git a/x-pack/plugins/global_search/server/services/context.mock.ts b/x-pack/plugins/global_search/server/services/context.mock.ts index 7c72686529c15..325d6ea5c6d19 100644 --- a/x-pack/plugins/global_search/server/services/context.mock.ts +++ b/x-pack/plugins/global_search/server/services/context.mock.ts @@ -4,14 +4,17 @@ * you may not use this file except in compliance with the Elastic License. */ +import { of } from 'rxjs'; +import { Capabilities } from 'src/core/server'; import { savedObjectsTypeRegistryMock, savedObjectsClientMock, elasticsearchServiceMock, uiSettingsServiceMock, + capabilitiesServiceMock, } from '../../../../../src/core/server/mocks'; -const createContextMock = () => { +const createContextMock = (capabilities: Partial = {}) => { return { core: { savedObjects: { @@ -26,6 +29,10 @@ const createContextMock = () => { uiSettings: { client: uiSettingsServiceMock.createClient(), }, + capabilities: of({ + ...capabilitiesServiceMock.createCapabilities(), + ...capabilities, + } as Capabilities), }, }; }; diff --git a/x-pack/plugins/global_search/server/services/context.test.ts b/x-pack/plugins/global_search/server/services/context.test.ts index 397a1ea170349..640f4c11b363f 100644 --- a/x-pack/plugins/global_search/server/services/context.test.ts +++ b/x-pack/plugins/global_search/server/services/context.test.ts @@ -27,11 +27,15 @@ describe('getContextFactory', () => { expect(coreStart.uiSettings.asScopedToClient).toHaveBeenCalledTimes(1); expect(coreStart.uiSettings.asScopedToClient).toHaveBeenCalledWith(soClient); + expect(coreStart.capabilities.resolveCapabilities).toHaveBeenCalledTimes(1); + expect(coreStart.capabilities.resolveCapabilities).toHaveBeenCalledWith(request); + expect(context).toEqual({ core: { savedObjects: expect.any(Object), elasticsearch: expect.any(Object), uiSettings: expect.any(Object), + capabilities: expect.any(Object), }, }); }); diff --git a/x-pack/plugins/global_search/server/services/context.ts b/x-pack/plugins/global_search/server/services/context.ts index b15deccaae018..62fddcfb152b3 100644 --- a/x-pack/plugins/global_search/server/services/context.ts +++ b/x-pack/plugins/global_search/server/services/context.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { from } from 'rxjs'; import { CoreStart, KibanaRequest } from 'src/core/server'; import { GlobalSearchProviderContext } from '../types'; @@ -30,6 +31,7 @@ export const getContextFactory = (coreStart: CoreStart) => ( uiSettings: { client: coreStart.uiSettings.asScopedToClient(soClient), }, + capabilities: from(coreStart.capabilities.resolveCapabilities(request)), }, }; }; diff --git a/x-pack/plugins/global_search/server/types.ts b/x-pack/plugins/global_search/server/types.ts index 7d3f5ebc5d079..07d21f54d7bf5 100644 --- a/x-pack/plugins/global_search/server/types.ts +++ b/x-pack/plugins/global_search/server/types.ts @@ -10,6 +10,7 @@ import { ILegacyScopedClusterClient, IUiSettingsClient, SavedObjectsClientContract, + Capabilities, } from 'src/core/server'; import { GlobalSearchBatchedResults, @@ -52,6 +53,7 @@ export interface GlobalSearchProviderContext { uiSettings: { client: IUiSettingsClient; }; + capabilities: Observable; }; } diff --git a/x-pack/plugins/global_search_providers/server/providers/saved_objects/map_object_to_result.test.ts b/x-pack/plugins/global_search_providers/server/providers/saved_objects/map_object_to_result.test.ts index 0085331c5be5f..8798fe6694c96 100644 --- a/x-pack/plugins/global_search_providers/server/providers/saved_objects/map_object_to_result.test.ts +++ b/x-pack/plugins/global_search_providers/server/providers/saved_objects/map_object_to_result.test.ts @@ -4,7 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { SavedObjectsFindResult, SavedObjectsType, SavedObjectTypeRegistry } from 'src/core/server'; +import { + SavedObjectsFindResult, + SavedObjectsType, + SavedObjectTypeRegistry, + Capabilities, +} from 'src/core/server'; import { mapToResult, mapToResults } from './map_object_to_result'; const createType = (props: Partial): SavedObjectsType => { @@ -111,18 +116,17 @@ describe('mapToResult', () => { describe('mapToResults', () => { let typeRegistry: SavedObjectTypeRegistry; + let capabilities: Capabilities; beforeEach(() => { typeRegistry = new SavedObjectTypeRegistry(); - }); - it('converts savedObjects to results', () => { typeRegistry.registerType( createType({ name: 'typeA', management: { defaultSearchField: 'title', - getInAppUrl: (obj) => ({ path: `/type-a/${obj.id}`, uiCapabilitiesPath: '' }), + getInAppUrl: (obj) => ({ path: `/type-a/${obj.id}`, uiCapabilitiesPath: 'test.typeA' }), }, }) ); @@ -131,7 +135,7 @@ describe('mapToResults', () => { name: 'typeB', management: { defaultSearchField: 'description', - getInAppUrl: (obj) => ({ path: `/type-b/${obj.id}`, uiCapabilitiesPath: 'foo' }), + getInAppUrl: (obj) => ({ path: `/type-b/${obj.id}`, uiCapabilitiesPath: 'test.typeB' }), }, }) ); @@ -140,11 +144,37 @@ describe('mapToResults', () => { name: 'typeC', management: { defaultSearchField: 'excerpt', - getInAppUrl: (obj) => ({ path: `/type-c/${obj.id}`, uiCapabilitiesPath: 'bar' }), + getInAppUrl: (obj) => ({ path: `/type-c/${obj.id}`, uiCapabilitiesPath: 'test.typeC' }), }, }) ); + typeRegistry.registerType( + createType({ + name: 'inaccessibleType', + management: { + defaultSearchField: 'excerpt', + getInAppUrl: (obj) => ({ + path: `/inaccessible-type/${obj.id}`, + uiCapabilitiesPath: 'test.inaccessibleType', + }), + }, + }) + ); + + capabilities = { + navLinks: {}, + management: {}, + catalogue: {}, + test: { + typeA: true, + typeB: true, + typeC: true, + inacessibleType: false, + }, + }; + }); + it('converts savedObjects to results', () => { const results = [ createObject( { @@ -181,7 +211,7 @@ describe('mapToResults', () => { ), ]; - expect(mapToResults(results, typeRegistry)).toEqual([ + expect(mapToResults(results, typeRegistry, capabilities)).toEqual([ { id: 'resultA', title: 'titleA', @@ -205,4 +235,41 @@ describe('mapToResults', () => { }, ]); }); + + it('filters results without permissions', () => { + const results = [ + createObject( + { + id: 'resultA', + type: 'typeA', + score: 100, + }, + { + title: 'titleA', + field: 'noise', + } + ), + createObject( + { + id: 'inaccessibleResult', + type: 'inaccessibleType', + score: 92, + }, + { + excerpt: 'inaccessibleTitle', + title: 'inaccessible', + } + ), + ]; + + expect(mapToResults(results, typeRegistry, capabilities)).toEqual([ + { + id: 'resultA', + title: 'titleA', + type: 'typeA', + url: '/type-a/resultA', + score: 100, + }, + ]); + }); }); diff --git a/x-pack/plugins/global_search_providers/server/providers/saved_objects/map_object_to_result.ts b/x-pack/plugins/global_search_providers/server/providers/saved_objects/map_object_to_result.ts index c93558b1a3cf4..14641e1aaffff 100644 --- a/x-pack/plugins/global_search_providers/server/providers/saved_objects/map_object_to_result.ts +++ b/x-pack/plugins/global_search_providers/server/providers/saved_objects/map_object_to_result.ts @@ -4,18 +4,36 @@ * you may not use this file except in compliance with the Elastic License. */ +import get from 'lodash/get'; import { SavedObjectsType, ISavedObjectTypeRegistry, SavedObjectsFindResult, + Capabilities, } from 'src/core/server'; import { GlobalSearchProviderResult } from '../../../../global_search/server'; export const mapToResults = ( objects: Array>, - registry: ISavedObjectTypeRegistry + registry: ISavedObjectTypeRegistry, + capabilities: Capabilities ): GlobalSearchProviderResult[] => { - return objects.map((obj) => mapToResult(obj, registry.getType(obj.type)!)); + return objects + .filter((obj) => isAccessible(obj, registry.getType(obj.type)!, capabilities)) + .map((obj) => mapToResult(obj, registry.getType(obj.type)!)); +}; + +const isAccessible = ( + object: SavedObjectsFindResult, + type: SavedObjectsType, + capabilities: Capabilities +): boolean => { + const { getInAppUrl } = type.management ?? {}; + if (getInAppUrl === undefined) { + throw new Error('Trying to map an object from a type without management metadata'); + } + const { uiCapabilitiesPath } = getInAppUrl(object); + return Boolean(get(capabilities, uiCapabilitiesPath) ?? false); }; export const mapToResult = ( diff --git a/x-pack/plugins/global_search_providers/server/providers/saved_objects/provider.test.ts b/x-pack/plugins/global_search_providers/server/providers/saved_objects/provider.test.ts index 11e3a40ddee17..352191658ed0d 100644 --- a/x-pack/plugins/global_search_providers/server/providers/saved_objects/provider.test.ts +++ b/x-pack/plugins/global_search_providers/server/providers/saved_objects/provider.test.ts @@ -33,16 +33,20 @@ const createFindResponse = ( total: results.length, }); -const createType = (props: Partial): SavedObjectsType => { +const createType = ( + props: Pick & Partial +): SavedObjectsType => { return { - name: 'type', hidden: false, namespaceType: 'single', mappings: { properties: {} }, ...props, management: { defaultSearchField: 'field', - getInAppUrl: (obj) => ({ path: `/object/${obj.id}`, uiCapabilitiesPath: '' }), + getInAppUrl: (obj) => ({ + path: `/object/${obj.id}`, + uiCapabilitiesPath: `types.${props.name}`, + }), ...props.management, }, }; @@ -82,7 +86,7 @@ describe('savedObjectsResultProvider', () => { name: 'typeA', management: { defaultSearchField: 'title', - getInAppUrl: (obj) => ({ path: `/type-a/${obj.id}`, uiCapabilitiesPath: '' }), + getInAppUrl: (obj) => ({ path: `/type-a/${obj.id}`, uiCapabilitiesPath: 'test.typeA' }), }, }) ); @@ -91,12 +95,17 @@ describe('savedObjectsResultProvider', () => { name: 'typeB', management: { defaultSearchField: 'description', - getInAppUrl: (obj) => ({ path: `/type-b/${obj.id}`, uiCapabilitiesPath: 'foo' }), + getInAppUrl: (obj) => ({ path: `/type-b/${obj.id}`, uiCapabilitiesPath: 'test.typeB' }), }, }) ); - context = globalSearchPluginMock.createProviderContext(); + context = globalSearchPluginMock.createProviderContext({ + test: { + typeA: true, + typeB: true, + }, + }); context.core.savedObjects.client.find.mockResolvedValue(createFindResponse([])); context.core.savedObjects.typeRegistry = registry as any; }); diff --git a/x-pack/plugins/global_search_providers/server/providers/saved_objects/provider.ts b/x-pack/plugins/global_search_providers/server/providers/saved_objects/provider.ts index 8a3d3d732531f..1c79380fe17fd 100644 --- a/x-pack/plugins/global_search_providers/server/providers/saved_objects/provider.ts +++ b/x-pack/plugins/global_search_providers/server/providers/saved_objects/provider.ts @@ -4,8 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { from } from 'rxjs'; -import { map, takeUntil } from 'rxjs/operators'; +import { from, combineLatest } from 'rxjs'; +import { map, takeUntil, first } from 'rxjs/operators'; import { GlobalSearchResultProvider } from '../../../../global_search/server'; import { mapToResults } from './map_object_to_result'; @@ -13,7 +13,10 @@ export const createSavedObjectsResultProvider = (): GlobalSearchResultProvider = return { id: 'savedObjects', find: (term, { aborted$, maxResults, preference }, { core }) => { - const { typeRegistry, client } = core.savedObjects; + const { + capabilities, + savedObjects: { client, typeRegistry }, + } = core; const searchableTypes = typeRegistry .getVisibleTypes() @@ -31,9 +34,9 @@ export const createSavedObjectsResultProvider = (): GlobalSearchResultProvider = type: searchableTypes.map((type) => type.name), }); - return from(responsePromise).pipe( + return combineLatest([from(responsePromise), capabilities.pipe(first())]).pipe( takeUntil(aborted$), - map((res) => mapToResults(res.saved_objects, typeRegistry)) + map(([res, cap]) => mapToResults(res.saved_objects, typeRegistry, cap)) ); }, }; diff --git a/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/quality_warning_notices.tsx b/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/quality_warning_notices.tsx index 928c9738c4761..4bf618923a138 100644 --- a/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/quality_warning_notices.tsx +++ b/x-pack/plugins/infra/public/components/logging/log_analysis_job_status/quality_warning_notices.tsx @@ -14,7 +14,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import groupBy from 'lodash/groupBy'; +import { groupBy } from 'lodash'; import React, { Fragment, useState } from 'react'; import { euiStyled } from '../../../../../observability/public'; import { diff --git a/x-pack/plugins/maps_legacy_licensing/public/plugin.ts b/x-pack/plugins/maps_legacy_licensing/public/plugin.ts index eaf527f856bc5..ed7321b2c0e74 100644 --- a/x-pack/plugins/maps_legacy_licensing/public/plugin.ts +++ b/x-pack/plugins/maps_legacy_licensing/public/plugin.ts @@ -26,12 +26,10 @@ export type MapsLegacyLicensingStart = ReturnType; export class MapsLegacyLicensing implements Plugin { public setup(core: CoreSetup, plugins: MapsLegacyLicensingSetupDependencies) { - const { - licensing, - mapsLegacy: { serviceSettings }, - } = plugins; + const { licensing, mapsLegacy } = plugins; if (licensing) { - licensing.license$.subscribe((license: ILicense) => { + licensing.license$.subscribe(async (license: ILicense) => { + const serviceSettings = await mapsLegacy.getServiceSettings(); const { uid, isActive } = license; if (isActive && license.hasAtLeast('basic')) { serviceSettings.setQueryParams({ license: uid }); diff --git a/x-pack/plugins/ml/public/application/components/data_grid/data_grid.tsx b/x-pack/plugins/ml/public/application/components/data_grid/data_grid.tsx index 6aad5d53c3a3c..1949a3c339161 100644 --- a/x-pack/plugins/ml/public/application/components/data_grid/data_grid.tsx +++ b/x-pack/plugins/ml/public/application/components/data_grid/data_grid.tsx @@ -188,6 +188,40 @@ export const DataGrid: FC = memo( ); } + let errorCallout; + + if (status === INDEX_STATUS.ERROR) { + // if it's a searchBar syntax error leave the table visible so they can try again + if (errorMessage && !errorMessage.includes('failed to create query')) { + errorCallout = ( + +

{errorMessage}

+
+ ); + } else { + errorCallout = ( + + + {errorMessage} + + + ); + } + } + return (
{isWithHeader(props) && ( @@ -211,19 +245,9 @@ export const DataGrid: FC = memo( )} - {status === INDEX_STATUS.ERROR && ( + {errorCallout !== undefined && (
- - - {errorMessage} - - + {errorCallout}
)} diff --git a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx index 84b1c4241aaf2..07a15b01fca93 100644 --- a/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx +++ b/x-pack/plugins/ml/public/application/data_frame_analytics/pages/analytics_exploration/components/exploration_results_table/exploration_results_table.tsx @@ -6,15 +6,7 @@ import React, { Fragment, FC, useEffect, useState } from 'react'; import { i18n } from '@kbn/i18n'; -import { - EuiCallOut, - EuiFlexGroup, - EuiFlexItem, - EuiFormRow, - EuiPanel, - EuiSpacer, - EuiText, -} from '@elastic/eui'; +import { EuiFlexGroup, EuiFlexItem, EuiFormRow, EuiPanel, EuiSpacer, EuiText } from '@elastic/eui'; import { IndexPattern } from '../../../../../../../../../../src/plugins/data/public'; @@ -25,7 +17,6 @@ import { getToastNotifications } from '../../../../../util/dependency_cache'; import { DataFrameAnalyticsConfig, MAX_COLUMNS, - INDEX_STATUS, SEARCH_SIZE, defaultSearchQuery, getAnalysisType, @@ -95,43 +86,11 @@ export const ExplorationResultsTable: FC = React.memo( ); const docFieldsCount = classificationData.columnsWithCharts.length; - const { - columnsWithCharts, - errorMessage, - status, - tableItems, - visibleColumns, - } = classificationData; + const { columnsWithCharts, tableItems, visibleColumns } = classificationData; if (jobConfig === undefined || classificationData === undefined) { return null; } - // if it's a searchBar syntax error leave the table visible so they can try again - if (status === INDEX_STATUS.ERROR && !errorMessage.includes('failed to create query')) { - return ( - - - - - - {jobStatus !== undefined && ( - - {getTaskStateBadge(jobStatus)} - - )} - - -

{errorMessage}

-
-
- ); - } return ( = React.memo(({ jobId }) = const [searchQuery, setSearchQuery] = useState(defaultSearchQuery); const outlierData = useOutlierData(indexPattern, jobConfig, searchQuery); - const { columnsWithCharts, errorMessage, status, tableItems } = outlierData; + const { columnsWithCharts, tableItems } = outlierData; const colorRange = useColorRange( COLOR_RANGE.BLUE, @@ -62,24 +55,6 @@ export const OutlierExploration: FC = React.memo(({ jobId }) = jobConfig !== undefined ? getFeatureCount(jobConfig.dest.results_field, tableItems) : 1 ); - // if it's a searchBar syntax error leave the table visible so they can try again - if (status === INDEX_STATUS.ERROR && !errorMessage.includes('failed to create query')) { - return ( - - - -

{errorMessage}

-
-
- ); - } - return ( {jobConfig !== undefined && needsDestIndexPattern && ( diff --git a/x-pack/plugins/monitoring/server/plugin.ts b/x-pack/plugins/monitoring/server/plugin.ts index 294f52cc3678f..8d3248ddf4369 100644 --- a/x-pack/plugins/monitoring/server/plugin.ts +++ b/x-pack/plugins/monitoring/server/plugin.ts @@ -20,6 +20,7 @@ import { CoreStart, CustomHttpResponseOptions, ResponseError, + IClusterClient, } from 'kibana/server'; import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/server'; import { @@ -73,6 +74,7 @@ export class Plugin { private monitoringCore = {} as MonitoringCore; private legacyShimDependencies = {} as LegacyShimDependencies; private bulkUploader: IBulkUploader = {} as IBulkUploader; + private telemetryElasticsearchClient: IClusterClient | undefined; constructor(initializerContext: PluginInitializerContext) { this.initializerContext = initializerContext; @@ -143,9 +145,14 @@ export class Plugin { // Initialize telemetry if (plugins.telemetryCollectionManager) { - registerMonitoringCollection(plugins.telemetryCollectionManager, this.cluster, { - maxBucketSize: config.ui.max_bucket_size, - }); + registerMonitoringCollection( + plugins.telemetryCollectionManager, + this.cluster, + () => this.telemetryElasticsearchClient, + { + maxBucketSize: config.ui.max_bucket_size, + } + ); } // Register collector objects for stats to show up in the APIs @@ -229,7 +236,13 @@ export class Plugin { }; } - start() {} + start({ elasticsearch }: CoreStart) { + // TODO: For the telemetry plugin to work, we need to provide the new ES client. + // The new client should be inititalized with a similar config to `this.cluster` but, since we're not using + // the new client in Monitoring Telemetry collection yet, setting the local client allos progress for now. + // We will update the client in a follow up PR. + this.telemetryElasticsearchClient = elasticsearch.client; + } stop() { if (this.cluster) { diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.test.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.test.ts index f0ad6399c6c72..89f09d349014f 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.test.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.test.ts @@ -15,6 +15,7 @@ describe('get_all_stats', () => { const start = 0; const end = 1; const callCluster = sinon.stub(); + const esClient = sinon.stub(); const esClusters = [ { cluster_uuid: 'a' }, @@ -176,6 +177,7 @@ describe('get_all_stats', () => { [{ clusterUuid: 'a' }], { callCluster: callCluster as any, + esClient: esClient as any, usageCollection: {} as any, start, end, @@ -201,6 +203,7 @@ describe('get_all_stats', () => { [], { callCluster: callCluster as any, + esClient: esClient as any, usageCollection: {} as any, start, end, diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.ts index 726db1706758d..1170380b26ac8 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_all_stats.ts @@ -21,7 +21,6 @@ type PromiseReturnType any> = ReturnType extend export interface CustomContext { maxBucketSize: number; } - /** * Get statistics for all products joined by Elasticsearch cluster. * Returns the array of clusters joined with the Kibana and Logstash instances. @@ -29,7 +28,7 @@ export interface CustomContext { */ export const getAllStats: StatsGetter = async ( clustersDetails, - { callCluster, start, end }, + { callCluster, start, end, esClient }, { maxBucketSize } ) => { const clusterUuids = clustersDetails.map((clusterDetails) => clusterDetails.clusterUuid); diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.test.ts b/x-pack/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.test.ts index 519dcc38875f5..b2f3cb6c61526 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.test.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/get_cluster_uuids.test.ts @@ -5,6 +5,7 @@ */ import sinon from 'sinon'; +import { elasticsearchServiceMock } from 'src/core/server/mocks'; import { getClusterUuids, fetchClusterUuids, @@ -13,6 +14,7 @@ import { describe('get_cluster_uuids', () => { const callCluster = sinon.stub(); + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; const response = { aggregations: { cluster_uuids: { @@ -30,7 +32,7 @@ describe('get_cluster_uuids', () => { it('returns cluster UUIDs', async () => { callCluster.withArgs('search').returns(Promise.resolve(response)); expect( - await getClusterUuids({ callCluster, start, end, usageCollection: {} as any }, { + await getClusterUuids({ callCluster, esClient, start, end, usageCollection: {} as any }, { maxBucketSize: 1, } as any) ).toStrictEqual(expectedUuids); @@ -41,7 +43,7 @@ describe('get_cluster_uuids', () => { it('searches for clusters', async () => { callCluster.returns(Promise.resolve(response)); expect( - await fetchClusterUuids({ callCluster, start, end, usageCollection: {} as any }, { + await fetchClusterUuids({ callCluster, esClient, start, end, usageCollection: {} as any }, { maxBucketSize: 1, } as any) ).toStrictEqual(response); diff --git a/x-pack/plugins/monitoring/server/telemetry_collection/register_monitoring_collection.ts b/x-pack/plugins/monitoring/server/telemetry_collection/register_monitoring_collection.ts index 1e5549fe4d800..3648ae4bd8551 100644 --- a/x-pack/plugins/monitoring/server/telemetry_collection/register_monitoring_collection.ts +++ b/x-pack/plugins/monitoring/server/telemetry_collection/register_monitoring_collection.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ILegacyCustomClusterClient } from 'kibana/server'; +import { ILegacyCustomClusterClient, IClusterClient } from 'kibana/server'; import { TelemetryCollectionManagerPluginSetup } from 'src/plugins/telemetry_collection_manager/server'; import { getAllStats, CustomContext } from './get_all_stats'; import { getClusterUuids } from './get_cluster_uuids'; @@ -13,10 +13,12 @@ import { getLicenses } from './get_licenses'; export function registerMonitoringCollection( telemetryCollectionManager: TelemetryCollectionManagerPluginSetup, esCluster: ILegacyCustomClusterClient, + esClientGetter: () => IClusterClient | undefined, customContext: CustomContext ) { telemetryCollectionManager.setCollection({ esCluster, + esClientGetter, title: 'monitoring', priority: 2, statsGetter: getAllStats, diff --git a/x-pack/plugins/security_solution/common/endpoint/schema/resolver.ts b/x-pack/plugins/security_solution/common/endpoint/schema/resolver.ts index 311aa0c04c9ab..a6d59615794a6 100644 --- a/x-pack/plugins/security_solution/common/endpoint/schema/resolver.ts +++ b/x-pack/plugins/security_solution/common/endpoint/schema/resolver.ts @@ -26,7 +26,7 @@ export const validateTree = { /** * Used to validate GET requests for non process events for a specific event. */ -export const validateEvents = { +export const validateRelatedEvents = { params: schema.object({ id: schema.string({ minLength: 1 }) }), query: schema.object({ events: schema.number({ defaultValue: 1000, min: 1, max: 10000 }), @@ -40,6 +40,22 @@ export const validateEvents = { ), }; +/** + * Used to validate POST requests for `/resolver/events` api. + */ +export const validateEvents = { + query: schema.object({ + // keeping the max as 10k because the limit in ES for a single query is also 10k + limit: schema.number({ defaultValue: 1000, min: 1, max: 10000 }), + afterEvent: schema.maybe(schema.string()), + }), + body: schema.nullable( + schema.object({ + filter: schema.maybe(schema.string()), + }) + ), +}; + /** * Used to validate GET requests for alerts for a specific process. */ diff --git a/x-pack/plugins/security_solution/common/endpoint/types/index.ts b/x-pack/plugins/security_solution/common/endpoint/types/index.ts index d97fdfbf7d186..abb0ccee8d909 100644 --- a/x-pack/plugins/security_solution/common/endpoint/types/index.ts +++ b/x-pack/plugins/security_solution/common/endpoint/types/index.ts @@ -276,6 +276,15 @@ export interface SafeResolverRelatedEvents { nextEvent: string | null; } +/** + * Response structure for the events route. + * `nextEvent` will be set to null when at the time of querying there were no more results to retrieve from ES. + */ +export interface ResolverPaginatedEvents { + events: SafeResolverEvent[]; + nextEvent: string | null; +} + /** * Response structure for the alerts route. */ diff --git a/x-pack/plugins/security_solution/cypress/integration/alerts.spec.ts b/x-pack/plugins/security_solution/cypress/integration/alerts.spec.ts index fdfa042e8fcc9..7f02d41ad1b0c 100644 --- a/x-pack/plugins/security_solution/cypress/integration/alerts.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/alerts.spec.ts @@ -30,8 +30,7 @@ import { loginAndWaitForPage } from '../tasks/login'; import { DETECTIONS_URL } from '../urls/navigation'; -// FLAKY: https://github.com/elastic/kibana/issues/77957 -describe.skip('Alerts', () => { +describe('Alerts', () => { context('Closing alerts', () => { beforeEach(() => { esArchiverLoad('alerts'); @@ -141,20 +140,20 @@ describe.skip('Alerts', () => { waitForAlerts(); const expectedNumberOfAlerts = +numberOfAlerts - numberOfAlertsToBeClosed; - cy.get(NUMBER_OF_ALERTS).invoke('text').should('eq', expectedNumberOfAlerts.toString()); - cy.get(SHOWING_ALERTS) - .invoke('text') - .should('eql', `Showing ${expectedNumberOfAlerts.toString()} alerts`); + cy.get(NUMBER_OF_ALERTS).should('have.text', expectedNumberOfAlerts.toString()); + cy.get(SHOWING_ALERTS).should( + 'have.text', + `Showing ${expectedNumberOfAlerts.toString()} alerts` + ); goToClosedAlerts(); waitForAlerts(); - cy.get(NUMBER_OF_ALERTS) - .invoke('text') - .should('eql', numberOfAlertsToBeClosed.toString()); - cy.get(SHOWING_ALERTS) - .invoke('text') - .should('eql', `Showing ${numberOfAlertsToBeClosed.toString()} alert`); + cy.get(NUMBER_OF_ALERTS).should('have.text', numberOfAlertsToBeClosed.toString()); + cy.get(SHOWING_ALERTS).should( + 'have.text', + `Showing ${numberOfAlertsToBeClosed.toString()} alert` + ); cy.get(ALERTS).should('have.length', numberOfAlertsToBeClosed); }); }); @@ -187,20 +186,20 @@ describe.skip('Alerts', () => { waitForAlerts(); const expectedNumberOfAlerts = +numberOfAlerts - numberOfAlertsToBeOpened; - cy.get(NUMBER_OF_ALERTS).invoke('text').should('eq', expectedNumberOfAlerts.toString()); - cy.get(SHOWING_ALERTS) - .invoke('text') - .should('eql', `Showing ${expectedNumberOfAlerts.toString()} alerts`); + cy.get(NUMBER_OF_ALERTS).should('have.text', expectedNumberOfAlerts.toString()); + cy.get(SHOWING_ALERTS).should( + 'have.text', + `Showing ${expectedNumberOfAlerts.toString()} alerts` + ); goToOpenedAlerts(); waitForAlerts(); - cy.get(NUMBER_OF_ALERTS) - .invoke('text') - .should('eql', numberOfAlertsToBeOpened.toString()); - cy.get(SHOWING_ALERTS) - .invoke('text') - .should('eql', `Showing ${numberOfAlertsToBeOpened.toString()} alert`); + cy.get(NUMBER_OF_ALERTS).should('have.text', numberOfAlertsToBeOpened.toString()); + cy.get(SHOWING_ALERTS).should( + 'have.text', + `Showing ${numberOfAlertsToBeOpened.toString()} alert` + ); cy.get(ALERTS).should('have.length', numberOfAlertsToBeOpened); }); }); @@ -229,23 +228,25 @@ describe.skip('Alerts', () => { cy.reload(); goToOpenedAlerts(); waitForAlertsToBeLoaded(); - waitForAlerts(); const expectedNumberOfAlerts = +numberOfAlerts - numberOfAlertsToBeMarkedInProgress; - cy.get(NUMBER_OF_ALERTS).invoke('text').should('eq', expectedNumberOfAlerts.toString()); - cy.get(SHOWING_ALERTS) - .invoke('text') - .should('eql', `Showing ${expectedNumberOfAlerts.toString()} alerts`); + cy.get(NUMBER_OF_ALERTS).should('have.text', expectedNumberOfAlerts.toString()); + cy.get(SHOWING_ALERTS).should( + 'have.text', + `Showing ${expectedNumberOfAlerts.toString()} alerts` + ); goToInProgressAlerts(); waitForAlerts(); - cy.get(NUMBER_OF_ALERTS) - .invoke('text') - .should('eql', numberOfAlertsToBeMarkedInProgress.toString()); - cy.get(SHOWING_ALERTS) - .invoke('text') - .should('eql', `Showing ${numberOfAlertsToBeMarkedInProgress.toString()} alert`); + cy.get(NUMBER_OF_ALERTS).should( + 'have.text', + numberOfAlertsToBeMarkedInProgress.toString() + ); + cy.get(SHOWING_ALERTS).should( + 'have.text', + `Showing ${numberOfAlertsToBeMarkedInProgress.toString()} alert` + ); cy.get(ALERTS).should('have.length', numberOfAlertsToBeMarkedInProgress); }); }); diff --git a/x-pack/plugins/security_solution/cypress/integration/inspect.spec.ts b/x-pack/plugins/security_solution/cypress/integration/inspect.spec.ts index c19e51c3ada40..8414b4ef8f1a2 100644 --- a/x-pack/plugins/security_solution/cypress/integration/inspect.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/inspect.spec.ts @@ -21,7 +21,8 @@ import { import { HOSTS_URL, NETWORK_URL } from '../urls/navigation'; -describe('Inspect', () => { +// FLAKY: https://github.com/elastic/kibana/issues/78496 +describe.skip('Inspect', () => { context('Hosts stats and tables', () => { before(() => { loginAndWaitForPage(HOSTS_URL); diff --git a/x-pack/plugins/security_solution/cypress/integration/ml_conditional_links.spec.ts b/x-pack/plugins/security_solution/cypress/integration/ml_conditional_links.spec.ts index 7bdc461a7c73d..3b89163392626 100644 --- a/x-pack/plugins/security_solution/cypress/integration/ml_conditional_links.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/ml_conditional_links.spec.ts @@ -24,7 +24,20 @@ import { mlNetworkSingleIpNullKqlQuery, } from '../urls/ml_conditional_links'; -describe('ml conditional links', () => { +// FLAKY: https://github.com/elastic/kibana/issues/78512 +// FLAKY: https://github.com/elastic/kibana/issues/78511 +// FLAKY: https://github.com/elastic/kibana/issues/78510 +// FLAKY: https://github.com/elastic/kibana/issues/78509 +// FLAKY: https://github.com/elastic/kibana/issues/78508 +// FLAKY: https://github.com/elastic/kibana/issues/78507 +// FLAKY: https://github.com/elastic/kibana/issues/78506 +// FLAKY: https://github.com/elastic/kibana/issues/78505 +// FLAKY: https://github.com/elastic/kibana/issues/78504 +// FLAKY: https://github.com/elastic/kibana/issues/78503 +// FLAKY: https://github.com/elastic/kibana/issues/78502 +// FLAKY: https://github.com/elastic/kibana/issues/78501 +// FLAKY: https://github.com/elastic/kibana/issues/78500 +describe.skip('ml conditional links', () => { it('sets the KQL from a single IP with a value for the query', () => { loginAndWaitForPageWithoutDateRange(mlNetworkSingleIpKqlQuery); cy.get(KQL_INPUT) diff --git a/x-pack/plugins/security_solution/cypress/tasks/alerts.ts b/x-pack/plugins/security_solution/cypress/tasks/alerts.ts index ebd37b522924f..f7ef5a904de99 100644 --- a/x-pack/plugins/security_solution/cypress/tasks/alerts.ts +++ b/x-pack/plugins/security_solution/cypress/tasks/alerts.ts @@ -40,7 +40,7 @@ export const expandFirstAlert = () => { }; export const goToClosedAlerts = () => { - cy.get(CLOSED_ALERTS_FILTER_BTN).click({ force: true }); + cy.get(CLOSED_ALERTS_FILTER_BTN).click(); }; export const goToManageAlertsDetectionRules = () => { @@ -62,7 +62,7 @@ export const openAlerts = () => { }; export const goToInProgressAlerts = () => { - cy.get(IN_PROGRESS_ALERTS_FILTER_BTN).click({ force: true }); + cy.get(IN_PROGRESS_ALERTS_FILTER_BTN).click(); }; export const markInProgressFirstAlert = () => { @@ -86,7 +86,7 @@ export const investigateFirstAlertInTimeline = () => { }; export const waitForAlerts = () => { - cy.get(REFRESH_BUTTON).invoke('text').should('not.equal', 'Updating'); + cy.get(REFRESH_BUTTON).should('not.have.text', 'Updating'); }; export const waitForAlertsIndexToBeCreated = () => { diff --git a/x-pack/plugins/security_solution/public/common/components/top_n/translations.ts b/x-pack/plugins/security_solution/public/common/components/top_n/translations.ts index b149a5eb1458f..76bb3dcfa6d37 100644 --- a/x-pack/plugins/security_solution/public/common/components/top_n/translations.ts +++ b/x-pack/plugins/security_solution/public/common/components/top_n/translations.ts @@ -19,5 +19,5 @@ export const RAW_EVENTS = i18n.translate('xpack.securitySolution.topN.rawEventsS }); export const ALERT_EVENTS = i18n.translate('xpack.securitySolution.topN.alertEventsSelectLabel', { - defaultMessage: 'Alert events', + defaultMessage: 'Detection Alerts', }); diff --git a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/form.tsx b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/form.tsx index c35cc612129d5..5baa0ee5569d2 100644 --- a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/form.tsx +++ b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/form.tsx @@ -21,7 +21,7 @@ import { useImportList, ListSchema, Type } from '../../../shared_imports'; import * as i18n from './translations'; import { useKibana } from '../../../common/lib/kibana'; -const options: EuiSelectOption[] = [ +export const listFormOptions: EuiSelectOption[] = [ { value: 'keyword', text: i18n.KEYWORDS_RADIO, @@ -145,7 +145,7 @@ export const ValueListsFormComponent: React.FC = ({ onError theme.eui.euiSizeXS}; @@ -29,6 +30,16 @@ export const buildColumns = ( name: i18n.COLUMN_FILE_NAME, truncateText: true, }, + { + field: 'type', + name: i18n.COLUMN_TYPE, + width: '15%', + truncateText: true, + render: (type: ListSchema['type']) => { + const option = listFormOptions.find(({ value }) => value === type); + return <>{option ? option.text : type}; + }, + }, { field: 'created_at', name: i18n.COLUMN_UPLOAD_DATE, diff --git a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/translations.ts b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/translations.ts index 9beebdfb923dc..992c696121485 100644 --- a/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/translations.ts +++ b/x-pack/plugins/security_solution/public/detections/components/value_lists_management_modal/translations.ts @@ -76,6 +76,13 @@ export const COLUMN_FILE_NAME = i18n.translate( } ); +export const COLUMN_TYPE = i18n.translate( + 'xpack.securitySolution.lists.valueListsTable.typeColumn', + { + defaultMessage: 'Type', + } +); + export const COLUMN_UPLOAD_DATE = i18n.translate( 'xpack.securitySolution.lists.valueListsTable.uploadDateColumn', { diff --git a/x-pack/plugins/security_solution/public/resolver/data_access_layer/factory.ts b/x-pack/plugins/security_solution/public/resolver/data_access_layer/factory.ts index 55d52d4ba3252..7b09e748c0c28 100644 --- a/x-pack/plugins/security_solution/public/resolver/data_access_layer/factory.ts +++ b/x-pack/plugins/security_solution/public/resolver/data_access_layer/factory.ts @@ -11,6 +11,8 @@ import { ResolverRelatedEvents, ResolverTree, ResolverEntityIndex, + ResolverPaginatedEvents, + SafeResolverEvent, } from '../../../common/endpoint/types'; /** @@ -22,12 +24,54 @@ export function dataAccessLayerFactory( const dataAccessLayer: DataAccessLayer = { /** * Used to get non-process related events for a node. + * @deprecated use the new API (eventsWithEntityIDAndCategory & event) instead */ async relatedEvents(entityID: string): Promise { - return context.services.http.post(`/api/endpoint/resolver/${entityID}/events`, { - query: { events: 100 }, + const response: ResolverPaginatedEvents = await context.services.http.post( + '/api/endpoint/resolver/events', + { + query: {}, + body: JSON.stringify({ + filter: `process.entity_id:"${entityID}" and not event.category:"process"`, + }), + } + ); + + return { ...response, entityID }; + }, + + /** + * Return events that have `process.entity_id` that includes `entityID` and that have + * a `event.category` that includes `category`. + */ + async eventsWithEntityIDAndCategory( + entityID: string, + category: string, + after?: string + ): Promise { + return context.services.http.post('/api/endpoint/resolver/events', { + query: { afterEvent: after }, + body: JSON.stringify({ + filter: `process.entity_id:"${entityID}" and event.category:"${category}"`, + }), }); }, + + /** + * Return up to one event that has an `event.id` that includes `eventID`. + */ + async event(eventID: string): Promise { + const response: ResolverPaginatedEvents = await context.services.http.post( + '/api/endpoint/resolver/events', + { + query: {}, + body: JSON.stringify({ filter: `event.id:"${eventID}"` }), + } + ); + const [oneEvent] = response.events; + return oneEvent ?? null; + }, + /** * Used to get descendant and ancestor process events for a node. */ diff --git a/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/emptify_mock.ts b/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/emptify_mock.ts index 631eab18fc014..88a3052a61f74 100644 --- a/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/emptify_mock.ts +++ b/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/emptify_mock.ts @@ -44,6 +44,7 @@ export function emptifyMock( return { metadata, dataAccessLayer: { + ...dataAccessLayer, /** * Fetch related events for an entity ID */ diff --git a/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children.ts b/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children.ts index fd086bd9b984e..09625e5726b1d 100644 --- a/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children.ts +++ b/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children.ts @@ -6,6 +6,7 @@ import { ResolverRelatedEvents, + SafeResolverEvent, ResolverTree, ResolverEntityIndex, } from '../../../../common/endpoint/types'; @@ -58,6 +59,29 @@ export function noAncestorsTwoChildren(): { dataAccessLayer: DataAccessLayer; me }); }, + /** + * Return events that have `process.entity_id` that includes `entityID` and that have + * a `event.category` that includes `category`. + */ + async eventsWithEntityIDAndCategory( + entityID: string, + category: string, + after?: string + ): Promise<{ + events: SafeResolverEvent[]; + nextEvent: string | null; + }> { + const events: SafeResolverEvent[] = []; + return { + events, + nextEvent: null, + }; + }, + + async event(_eventID: string): Promise { + return null; + }, + /** * Fetch a ResolverTree for a entityID */ diff --git a/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children_in_index_called_awesome_index.ts b/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children_in_index_called_awesome_index.ts index 86450b25eb1da..3bbe4bcf51060 100644 --- a/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children_in_index_called_awesome_index.ts +++ b/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children_in_index_called_awesome_index.ts @@ -8,6 +8,7 @@ import { ResolverRelatedEvents, ResolverTree, ResolverEntityIndex, + SafeResolverEvent, } from '../../../../common/endpoint/types'; import { mockEndpointEvent } from '../../mocks/endpoint_event'; import { mockTreeWithNoAncestorsAnd2Children } from '../../mocks/resolver_tree'; @@ -69,6 +70,32 @@ export function noAncestorsTwoChildenInIndexCalledAwesomeIndex(): { }); }, + async eventsWithEntityIDAndCategory( + entityID: string, + category, + after?: string + ): Promise<{ + events: SafeResolverEvent[]; + nextEvent: string | null; + }> { + return { + events: [ + mockEndpointEvent({ + entityID, + eventCategory: category, + }), + ], + nextEvent: null, + }; + }, + + async event(eventID: string): Promise { + return mockEndpointEvent({ + entityID: metadata.entityIDs.origin, + eventID, + }); + }, + /** * Fetch a ResolverTree for a entityID */ diff --git a/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children_with_related_events_on_origin.ts b/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children_with_related_events_on_origin.ts index ec773a09ae8e0..6fb84eaf7fda6 100644 --- a/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children_with_related_events_on_origin.ts +++ b/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/no_ancestors_two_children_with_related_events_on_origin.ts @@ -10,7 +10,9 @@ import { ResolverRelatedEvents, ResolverTree, ResolverEntityIndex, + SafeResolverEvent, } from '../../../../common/endpoint/types'; +import * as eventModel from '../../../../common/endpoint/models/event'; interface Metadata { /** @@ -56,31 +58,62 @@ export function noAncestorsTwoChildrenWithRelatedEventsOnOrigin(): { /** * Fetch related events for an entity ID */ - relatedEvents(entityID: string): Promise { + async relatedEvents(entityID: string): Promise { /** * Respond with the mocked related events when the origin's related events are fetched. **/ const events = entityID === metadata.entityIDs.origin ? tree.relatedEvents.events : []; - return Promise.resolve({ + return { entityID, events, nextEvent: null, - }); + }; + }, + + /** + * Any of the origin's related events by category. + * `entityID` must match the origin node's `process.entity_id`. + * Does not respect the `_after` parameter. + */ + async eventsWithEntityIDAndCategory( + entityID: string, + category: string, + after?: string + ): Promise<{ events: SafeResolverEvent[]; nextEvent: string | null }> { + const events = + entityID === metadata.entityIDs.origin + ? tree.relatedEvents.events.filter((event) => + eventModel.eventCategory(event).includes(category) + ) + : []; + return { + events, + nextEvent: null, + }; + }, + + /** + * Any of the origin's related events by event.id + */ + async event(eventID: string): Promise { + return ( + tree.relatedEvents.events.find((event) => eventModel.eventID(event) === eventID) ?? null + ); }, /** * Fetch a ResolverTree for a entityID */ - resolverTree(): Promise { - return Promise.resolve(tree); + async resolverTree(): Promise { + return tree; }, /** * Get entities matching a document. */ - entities(): Promise { - return Promise.resolve([{ entity_id: metadata.entityIDs.origin }]); + async entities(): Promise { + return [{ entity_id: metadata.entityIDs.origin }]; }, }, }; diff --git a/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/pausify_mock.ts b/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/pausify_mock.ts index 6a4955b104b8f..a3ec667385470 100644 --- a/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/pausify_mock.ts +++ b/x-pack/plugins/security_solution/public/resolver/data_access_layer/mocks/pausify_mock.ts @@ -89,6 +89,7 @@ export function pausifyMock({ } }, dataAccessLayer: { + ...dataAccessLayer, /** * Fetch related events for an entity ID */ diff --git a/x-pack/plugins/security_solution/public/resolver/types.ts b/x-pack/plugins/security_solution/public/resolver/types.ts index 4dc614abe3345..64147dd8feb75 100644 --- a/x-pack/plugins/security_solution/public/resolver/types.ts +++ b/x-pack/plugins/security_solution/public/resolver/types.ts @@ -16,6 +16,7 @@ import { ResolverTree, ResolverEntityIndex, SafeResolverEvent, + ResolverPaginatedEvents, } from '../../common/endpoint/types'; /** @@ -503,6 +504,21 @@ export interface DataAccessLayer { */ relatedEvents: (entityID: string) => Promise; + /** + * Return events that have `process.entity_id` that includes `entityID` and that have + * a `event.category` that includes `category`. + */ + eventsWithEntityIDAndCategory: ( + entityID: string, + category: string, + after?: string + ) => Promise; + + /** + * Return up to one event that has an `event.id` that includes `eventID`. + */ + event: (eventID: string) => Promise; + /** * Fetch a ResolverTree for a entityID */ diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver.ts index 3ec968e4a0e1a..c9159032a7917 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver.ts @@ -8,29 +8,42 @@ import { IRouter } from 'kibana/server'; import { EndpointAppContext } from '../types'; import { validateTree, + validateRelatedEvents, validateEvents, validateChildren, validateAncestry, validateAlerts, validateEntities, } from '../../../common/endpoint/schema/resolver'; -import { handleEvents } from './resolver/events'; +import { handleRelatedEvents } from './resolver/related_events'; import { handleChildren } from './resolver/children'; import { handleAncestry } from './resolver/ancestry'; import { handleTree } from './resolver/tree'; import { handleAlerts } from './resolver/alerts'; import { handleEntities } from './resolver/entity'; +import { handleEvents } from './resolver/events'; export function registerResolverRoutes(router: IRouter, endpointAppContext: EndpointAppContext) { const log = endpointAppContext.logFactory.get('resolver'); + // this route will be removed in favor of the one below router.post( { + // @deprecated use `/resolver/events` instead path: '/api/endpoint/resolver/{id}/events', + validate: validateRelatedEvents, + options: { authRequired: true }, + }, + handleRelatedEvents(log, endpointAppContext) + ); + + router.post( + { + path: '/api/endpoint/resolver/events', validate: validateEvents, options: { authRequired: true }, }, - handleEvents(log, endpointAppContext) + handleEvents(log) ); router.post( diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/events.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/events.ts index 80d21ae118284..a212215fe18a8 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/events.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/events.ts @@ -6,32 +6,39 @@ import { TypeOf } from '@kbn/config-schema'; import { RequestHandler, Logger } from 'kibana/server'; -import { eventsIndexPattern, alertsIndexPattern } from '../../../../common/endpoint/constants'; +import { eventsIndexPattern } from '../../../../common/endpoint/constants'; import { validateEvents } from '../../../../common/endpoint/schema/resolver'; -import { Fetcher } from './utils/fetch'; -import { EndpointAppContext } from '../../types'; +import { EventsQuery } from './queries/events'; +import { createEvents } from './utils/node'; +import { PaginationBuilder } from './utils/pagination'; +/** + * This function handles the `/events` api and returns an array of events and a cursor if more events exist than were + * requested. + * @param log a logger object + */ export function handleEvents( - log: Logger, - endpointAppContext: EndpointAppContext + log: Logger ): RequestHandler< - TypeOf, + unknown, TypeOf, TypeOf > { return async (context, req, res) => { const { - params: { id }, - query: { events, afterEvent, legacyEndpointID: endpointID }, + query: { limit, afterEvent }, body, } = req; try { - const client = context.core.elasticsearch.legacy.client; - - const fetcher = new Fetcher(client, id, eventsIndexPattern, alertsIndexPattern, endpointID); + const client = context.core.elasticsearch.client; + const query = new EventsQuery( + PaginationBuilder.createBuilder(limit, afterEvent), + eventsIndexPattern + ); + const results = await query.search(client, body?.filter); return res.ok({ - body: await fetcher.events(events, afterEvent, body?.filter), + body: createEvents(results, PaginationBuilder.buildCursorRequestLimit(limit, results)), }); } catch (err) { log.warn(err); diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/events.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/events.ts index bd054d548a93a..3be0cc5daff79 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/events.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/events.ts @@ -4,86 +4,59 @@ * you may not use this file except in compliance with the Elastic License. */ import { SearchResponse } from 'elasticsearch'; +import { IScopedClusterClient } from 'kibana/server'; +import { ApiResponse } from '@elastic/elasticsearch'; import { esKuery } from '../../../../../../../../src/plugins/data/server'; import { SafeResolverEvent } from '../../../../../common/endpoint/types'; -import { ResolverQuery } from './base'; import { PaginationBuilder } from '../utils/pagination'; import { JsonObject } from '../../../../../../../../src/plugins/kibana_utils/common'; /** - * Builds a query for retrieving related events for a node. + * Builds a query for retrieving events. */ -export class EventsQuery extends ResolverQuery { - private readonly kqlQuery: JsonObject[] = []; - +export class EventsQuery { constructor( private readonly pagination: PaginationBuilder, - indexPattern: string | string[], - endpointID?: string, - kql?: string - ) { - super(indexPattern, endpointID); - if (kql) { - this.kqlQuery.push(esKuery.toElasticsearchQuery(esKuery.fromKueryExpression(kql))); - } - } + private readonly indexPattern: string | string[] + ) {} - protected legacyQuery(endpointID: string, uniquePIDs: string[]): JsonObject { + private query(kqlQuery: JsonObject[]): JsonObject { return { query: { bool: { filter: [ - ...this.kqlQuery, - { - terms: { 'endgame.unique_pid': uniquePIDs }, - }, - { - term: { 'agent.id': endpointID }, - }, + ...kqlQuery, { term: { 'event.kind': 'event' }, }, - { - bool: { - must_not: { - term: { 'event.category': 'process' }, - }, - }, - }, ], }, }, - ...this.pagination.buildQueryFields('endgame.serial_event_id', 'desc'), + ...this.pagination.buildQueryFields('event.id', 'desc'), }; } - protected query(entityIDs: string[]): JsonObject { + private buildSearch(kql: JsonObject[]) { return { - query: { - bool: { - filter: [ - ...this.kqlQuery, - { - terms: { 'process.entity_id': entityIDs }, - }, - { - term: { 'event.kind': 'event' }, - }, - { - bool: { - must_not: { - term: { 'event.category': 'process' }, - }, - }, - }, - ], - }, - }, - ...this.pagination.buildQueryFields('event.id', 'desc'), + body: this.query(kql), + index: this.indexPattern, }; } - formatResponse(response: SearchResponse): SafeResolverEvent[] { - return this.getResults(response); + /** + * Searches ES for the specified events and format the response. + * + * @param client a client for searching ES + * @param kql an optional kql string for filtering the results + */ + async search(client: IScopedClusterClient, kql?: string): Promise { + const kqlQuery: JsonObject[] = []; + if (kql) { + kqlQuery.push(esKuery.toElasticsearchQuery(esKuery.fromKueryExpression(kql))); + } + const response: ApiResponse> = await client.asCurrentUser.search(this.buildSearch(kqlQuery)); + return response.body.hits.hits.map((hit) => hit._source); } } diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/events.test.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/related_events.test.ts similarity index 93% rename from x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/events.test.ts rename to x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/related_events.test.ts index 00d7570b2b65e..3ddf8fa4090d6 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/events.test.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/related_events.test.ts @@ -3,7 +3,10 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { EventsQuery } from './events'; +/** + * @deprecated use the `events.ts` file's query instead + */ +import { EventsQuery } from './related_events'; import { PaginationBuilder } from '../utils/pagination'; import { legacyEventIndexPattern } from './legacy_event_index_pattern'; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/related_events.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/related_events.ts new file mode 100644 index 0000000000000..f419c1fb6e1d5 --- /dev/null +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/queries/related_events.ts @@ -0,0 +1,92 @@ +/* + * 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. + */ +/** + * @deprecated use the `events.ts` file's query instead + */ +import { SearchResponse } from 'elasticsearch'; +import { esKuery } from '../../../../../../../../src/plugins/data/server'; +import { SafeResolverEvent } from '../../../../../common/endpoint/types'; +import { ResolverQuery } from './base'; +import { PaginationBuilder } from '../utils/pagination'; +import { JsonObject } from '../../../../../../../../src/plugins/kibana_utils/common'; + +/** + * Builds a query for retrieving related events for a node. + */ +export class EventsQuery extends ResolverQuery { + private readonly kqlQuery: JsonObject[] = []; + + constructor( + private readonly pagination: PaginationBuilder, + indexPattern: string | string[], + endpointID?: string, + kql?: string + ) { + super(indexPattern, endpointID); + if (kql) { + this.kqlQuery.push(esKuery.toElasticsearchQuery(esKuery.fromKueryExpression(kql))); + } + } + + protected legacyQuery(endpointID: string, uniquePIDs: string[]): JsonObject { + return { + query: { + bool: { + filter: [ + ...this.kqlQuery, + { + terms: { 'endgame.unique_pid': uniquePIDs }, + }, + { + term: { 'agent.id': endpointID }, + }, + { + term: { 'event.kind': 'event' }, + }, + { + bool: { + must_not: { + term: { 'event.category': 'process' }, + }, + }, + }, + ], + }, + }, + ...this.pagination.buildQueryFields('endgame.serial_event_id', 'desc'), + }; + } + + protected query(entityIDs: string[]): JsonObject { + return { + query: { + bool: { + filter: [ + ...this.kqlQuery, + { + terms: { 'process.entity_id': entityIDs }, + }, + { + term: { 'event.kind': 'event' }, + }, + { + bool: { + must_not: { + term: { 'event.category': 'process' }, + }, + }, + }, + ], + }, + }, + ...this.pagination.buildQueryFields('event.id', 'desc'), + }; + } + + formatResponse(response: SearchResponse): SafeResolverEvent[] { + return this.getResults(response); + } +} diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/related_events.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/related_events.ts new file mode 100644 index 0000000000000..8fd9ab9a5ccd3 --- /dev/null +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/related_events.ts @@ -0,0 +1,44 @@ +/* + * 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. + */ + +/** + * @deprecated use the `resolver/events` route and handler instead + */ +import { TypeOf } from '@kbn/config-schema'; +import { RequestHandler, Logger } from 'kibana/server'; +import { eventsIndexPattern, alertsIndexPattern } from '../../../../common/endpoint/constants'; +import { validateRelatedEvents } from '../../../../common/endpoint/schema/resolver'; +import { Fetcher } from './utils/fetch'; +import { EndpointAppContext } from '../../types'; + +export function handleRelatedEvents( + log: Logger, + endpointAppContext: EndpointAppContext +): RequestHandler< + TypeOf, + TypeOf, + TypeOf +> { + return async (context, req, res) => { + const { + params: { id }, + query: { events, afterEvent, legacyEndpointID: endpointID }, + body, + } = req; + try { + const client = context.core.elasticsearch.legacy.client; + + const fetcher = new Fetcher(client, id, eventsIndexPattern, alertsIndexPattern, endpointID); + + return res.ok({ + body: await fetcher.events(events, afterEvent, body?.filter), + }); + } catch (err) { + log.warn(err); + return res.internalError({ body: err }); + } + }; +} diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/events_query_handler.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/events_query_handler.ts index 5c4d9a4741ad7..a5aa9b6c288c8 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/events_query_handler.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/events_query_handler.ts @@ -3,12 +3,14 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ - +/** + * @deprecated msearch functionality for querying events will be removed shortly + */ import { SearchResponse } from 'elasticsearch'; import { ILegacyScopedClusterClient } from 'kibana/server'; import { SafeResolverRelatedEvents, SafeResolverEvent } from '../../../../../common/endpoint/types'; import { createRelatedEvents } from './node'; -import { EventsQuery } from '../queries/events'; +import { EventsQuery } from '../queries/related_events'; import { PaginationBuilder } from './pagination'; import { QueryInfo } from '../queries/multi_searcher'; import { SingleQueryHandler } from './fetch'; diff --git a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/node.ts b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/node.ts index 535ee37f3db32..cecdc8a478958 100644 --- a/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/node.ts +++ b/x-pack/plugins/security_solution/server/endpoint/routes/resolver/utils/node.ts @@ -13,6 +13,7 @@ import { SafeResolverEvent, SafeResolverChildNode, SafeResolverRelatedEvents, + ResolverPaginatedEvents, } from '../../../../../common/endpoint/types'; /** @@ -30,6 +31,19 @@ export function createRelatedEvents( return { entityID, events, nextEvent }; } +/** + * Creates an object that the events handler would return + * + * @param events array of events + * @param nextEvent the cursor to retrieve the next event + */ +export function createEvents( + events: SafeResolverEvent[] = [], + nextEvent: string | null = null +): ResolverPaginatedEvents { + return { events, nextEvent }; +} + /** * Creates an alert object that the alerts handler would return * diff --git a/x-pack/plugins/telemetry_collection_xpack/server/plugin.ts b/x-pack/plugins/telemetry_collection_xpack/server/plugin.ts index 3f01d7423eded..6ef44e325b0a7 100644 --- a/x-pack/plugins/telemetry_collection_xpack/server/plugin.ts +++ b/x-pack/plugins/telemetry_collection_xpack/server/plugin.ts @@ -4,7 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { PluginInitializerContext, CoreSetup, CoreStart, Plugin } from 'kibana/server'; +import { + PluginInitializerContext, + CoreSetup, + CoreStart, + Plugin, + IClusterClient, +} from 'kibana/server'; import { TelemetryCollectionManagerPluginSetup } from 'src/plugins/telemetry_collection_manager/server'; import { getClusterUuids, getLocalLicense } from '../../../../src/plugins/telemetry/server'; import { getStatsWithXpack } from './telemetry_collection'; @@ -14,11 +20,13 @@ interface TelemetryCollectionXpackDepsSetup { } export class TelemetryCollectionXpackPlugin implements Plugin { + private elasticsearchClient?: IClusterClient; constructor(initializerContext: PluginInitializerContext) {} public setup(core: CoreSetup, { telemetryCollectionManager }: TelemetryCollectionXpackDepsSetup) { telemetryCollectionManager.setCollection({ esCluster: core.elasticsearch.legacy.client, + esClientGetter: () => this.elasticsearchClient, title: 'local_xpack', priority: 1, statsGetter: getStatsWithXpack, @@ -27,5 +35,7 @@ export class TelemetryCollectionXpackPlugin implements Plugin { }); } - public start(core: CoreStart) {} + public start(core: CoreStart) { + this.elasticsearchClient = core.elasticsearch.client; + } } diff --git a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/__tests__/get_xpack.js b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/__tests__/get_xpack.js deleted file mode 100644 index eb03701fd195b..0000000000000 --- a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/__tests__/get_xpack.js +++ /dev/null @@ -1,46 +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 expect from '@kbn/expect'; -import sinon from 'sinon'; - -import { TIMEOUT } from '../constants'; -import { getXPackUsage } from '../get_xpack'; - -function mockGetXPackUsage(callCluster, usage, req) { - callCluster - .withArgs(req, 'transport.request', { - method: 'GET', - path: '/_xpack/usage', - query: { - master_timeout: TIMEOUT, - }, - }) - .returns(usage); - - callCluster - .withArgs('transport.request', { - method: 'GET', - path: '/_xpack/usage', - query: { - master_timeout: TIMEOUT, - }, - }) - .returns(usage); -} - -describe('get_xpack', () => { - describe('getXPackUsage', () => { - it('uses callCluster to get /_xpack/usage API', () => { - const response = Promise.resolve({}); - const callCluster = sinon.stub(); - - mockGetXPackUsage(callCluster, response); - - expect(getXPackUsage(callCluster)).to.be(response); - }); - }); -}); diff --git a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_stats_with_xpack.test.ts b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_stats_with_xpack.test.ts index 24382fb89d337..a4806cefeef3d 100644 --- a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_stats_with_xpack.test.ts +++ b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_stats_with_xpack.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { coreMock } from '../../../../../src/core/server/mocks'; +import { coreMock, elasticsearchServiceMock } from '../../../../../src/core/server/mocks'; import { getStatsWithXpack } from './get_stats_with_xpack'; const kibana = { @@ -55,32 +55,34 @@ const mockUsageCollection = (kibanaUsage = kibana) => ({ describe('Telemetry Collection: Get Aggregated Stats', () => { test('OSS-like telemetry (no license nor X-Pack telemetry)', async () => { - const callCluster = jest.fn(async (method: string, options: { path?: string }) => { - switch (method) { - case 'transport.request': - if (options.path === '/_license' || options.path === '/_xpack/usage') { - // eslint-disable-next-line no-throw-literal - throw { statusCode: 404 }; - } else if (options.path === '/_nodes/usage') { - return { - cluster_name: 'test cluster', - nodes: nodesUsage, - }; - } - return {}; - case 'info': - return { cluster_uuid: 'test', cluster_name: 'test', version: { number: '8.0.0' } }; - default: - return {}; + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + // mock for xpack.usage should throw a 404 for this test + esClient.xpack.usage.mockRejectedValue(new Error('Not Found')); + // mock for license should throw a 404 for this test + esClient.license.get.mockRejectedValue(new Error('Not Found')); + // mock for nodes usage should resolve for this test + esClient.nodes.usage.mockResolvedValue( + // @ts-ignore we only care about the response body + { body: { cluster_name: 'test cluster', nodes: nodesUsage } } + ); + // mock for info should resolve for this test + esClient.info.mockResolvedValue( + // @ts-ignore we only care about the response body + { + body: { + cluster_uuid: 'test', + cluster_name: 'test', + version: { number: '8.0.0' }, + }, } - }); + ); const usageCollection = mockUsageCollection(); const context = getContext(); const stats = await getStatsWithXpack( [{ clusterUuid: '1234' }], { - callCluster, + esClient, usageCollection, } as any, context @@ -93,36 +95,39 @@ describe('Telemetry Collection: Get Aggregated Stats', () => { }); test('X-Pack telemetry (license + X-Pack)', async () => { - const callCluster = jest.fn(async (method: string, options: { path?: string }) => { - switch (method) { - case 'transport.request': - if (options.path === '/_license') { - return { - license: { type: 'basic' }, - }; - } - if (options.path === '/_xpack/usage') { - return {}; - } - if (options.path === '/_nodes/usage') { - return { - cluster_name: 'test cluster', - nodes: nodesUsage, - }; - } - case 'info': - return { cluster_uuid: 'test', cluster_name: 'test', version: { number: '8.0.0' } }; - default: - return {}; + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + // mock for license should return a basic license + esClient.license.get.mockResolvedValue( + // @ts-ignore we only care about the response body + { body: { license: { type: 'basic' } } } + ); + // mock for xpack usage should return an empty object + esClient.xpack.usage.mockResolvedValue( + // @ts-ignore we only care about the response body + { body: {} } + ); + // mock for nodes usage should return the cluster name and nodes usage + esClient.nodes.usage.mockResolvedValue( + // @ts-ignore we only care about the response body + { body: { cluster_name: 'test cluster', nodes: nodesUsage } } + ); + esClient.info.mockResolvedValue( + // @ts-ignore we only care about the response body + { + body: { + cluster_uuid: 'test', + cluster_name: 'test', + version: { number: '8.0.0' }, + }, } - }); + ); const usageCollection = mockUsageCollection(); const context = getContext(); const stats = await getStatsWithXpack( [{ clusterUuid: '1234' }], { - callCluster, + esClient, usageCollection, } as any, context diff --git a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_stats_with_xpack.ts b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_stats_with_xpack.ts index 3fcd25c31e71e..87e3d0a9613da 100644 --- a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_stats_with_xpack.ts +++ b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_stats_with_xpack.ts @@ -17,9 +17,9 @@ export const getStatsWithXpack: StatsGetter<{}, TelemetryAggregatedStats> = asyn config, context ) { - const { callCluster } = config; + const { esClient } = config; const clustersLocalStats = await getLocalStats(clustersDetails, config, context); - const xpack = await getXPackUsage(callCluster).catch(() => undefined); // We want to still report something (and do not lose the license) even when this method fails. + const xpack = await getXPackUsage(esClient).catch(() => undefined); // We want to still report something (and do not lose the license) even when this method fails. return clustersLocalStats.map((localStats) => { if (xpack) { diff --git a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_xpack.test.ts b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_xpack.test.ts new file mode 100644 index 0000000000000..106df71e46c7e --- /dev/null +++ b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_xpack.test.ts @@ -0,0 +1,19 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { elasticsearchServiceMock } from '../../../../../src/core/server/mocks'; +import { getXPackUsage } from './get_xpack'; + +describe('get_xpack', () => { + describe('getXPackUsage', () => { + it('uses esClient to get /_xpack/usage API', async () => { + const esClient = elasticsearchServiceMock.createClusterClient().asInternalUser; + // @ts-ignore we only care about the response body + esClient.xpack.usage.mockResolvedValue({ body: {} }); + const result = await getXPackUsage(esClient); + expect(result).toEqual({}); + }); + }); +}); diff --git a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_xpack.ts b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_xpack.ts index 0ff75717c8b65..4dbf2052be28c 100644 --- a/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_xpack.ts +++ b/x-pack/plugins/telemetry_collection_xpack/server/telemetry_collection/get_xpack.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { LegacyAPICaller } from 'kibana/server'; +import { ElasticsearchClient } from 'src/core/server'; import { TIMEOUT } from './constants'; /** @@ -14,12 +14,7 @@ import { TIMEOUT } from './constants'; * * Like any X-Pack related API, X-Pack must installed for this to work. */ -export function getXPackUsage(callCluster: LegacyAPICaller) { - return callCluster('transport.request', { - method: 'GET', - path: '/_xpack/usage', - query: { - master_timeout: TIMEOUT, - }, - }); +export async function getXPackUsage(esClient: ElasticsearchClient) { + const { body } = await esClient.xpack.usage({ master_timeout: TIMEOUT }); + return body; } diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 42e695788448f..505affb4f419a 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -10780,7 +10780,6 @@ "xpack.ml.dataframe.analytics.exploration.colorRangeLegendTitle": "機能影響スコア", "xpack.ml.dataframe.analytics.exploration.experimentalBadgeLabel": "実験的", "xpack.ml.dataframe.analytics.exploration.experimentalBadgeTooltipContent": "データフレーム分析は実験段階の機能です。フィードバックをお待ちしています。", - "xpack.ml.dataframe.analytics.exploration.indexError": "インデックスデータの読み込み中にエラーが発生しました。", "xpack.ml.dataframe.analytics.exploration.jobIdTitle": "外れ値検出ジョブID {jobId}", "xpack.ml.dataframe.analytics.exploration.title": "分析の探索", "xpack.ml.dataframe.analytics.explorationResults.documentsShownHelpText": "予測があるドキュメントを示す", @@ -10796,7 +10795,6 @@ "xpack.ml.dataframe.analytics.regressionExploration.generalizationFilterText": ".学習データをフィルタリングしています。", "xpack.ml.dataframe.analytics.regressionExploration.huberLinkText": "Pseudo Huber損失関数", "xpack.ml.dataframe.analytics.regressionExploration.huberText": "{wikiLink}", - "xpack.ml.dataframe.analytics.regressionExploration.indexError": "インデックスデータの読み込み中にエラーが発生しました。", "xpack.ml.dataframe.analytics.regressionExploration.meanSquaredErrorText": "平均二乗エラー", "xpack.ml.dataframe.analytics.regressionExploration.meanSquaredErrorTooltipContent": "回帰分析モデルの実行の効果を測定します。真値と予測値の間の差異の二乗平均合計。", "xpack.ml.dataframe.analytics.regressionExploration.msleText": "平均二乗対数誤差", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 394acbf65d1b5..3bca7ea36661d 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -10786,7 +10786,6 @@ "xpack.ml.dataframe.analytics.exploration.colorRangeLegendTitle": "功能影响分数", "xpack.ml.dataframe.analytics.exploration.experimentalBadgeLabel": "实验性", "xpack.ml.dataframe.analytics.exploration.experimentalBadgeTooltipContent": "数据帧分析为实验功能。我们很乐意听取您的反馈意见。", - "xpack.ml.dataframe.analytics.exploration.indexError": "加载索引数据时出错。", "xpack.ml.dataframe.analytics.exploration.jobIdTitle": "离群值检测作业 ID {jobId}", "xpack.ml.dataframe.analytics.exploration.title": "分析浏览", "xpack.ml.dataframe.analytics.explorationResults.documentsShownHelpText": "正在显示有相关预测存在的文档", @@ -10802,7 +10801,6 @@ "xpack.ml.dataframe.analytics.regressionExploration.generalizationFilterText": ".筛留训练数据。", "xpack.ml.dataframe.analytics.regressionExploration.huberLinkText": "Pseudo Huber 损失函数", "xpack.ml.dataframe.analytics.regressionExploration.huberText": "{wikiLink}", - "xpack.ml.dataframe.analytics.regressionExploration.indexError": "加载索引数据时出错。", "xpack.ml.dataframe.analytics.regressionExploration.meanSquaredErrorText": "均方误差", "xpack.ml.dataframe.analytics.regressionExploration.meanSquaredErrorTooltipContent": "度量回归分析模型的表现。真实值与预测值之差的平均平方和。", "xpack.ml.dataframe.analytics.regressionExploration.msleText": "均方根对数误差", diff --git a/x-pack/test/functional/apps/ml/settings/calendar_edit.ts b/x-pack/test/functional/apps/ml/settings/calendar_edit.ts index f7c8c1f6f85f5..e738b50a2fe05 100644 --- a/x-pack/test/functional/apps/ml/settings/calendar_edit.ts +++ b/x-pack/test/functional/apps/ml/settings/calendar_edit.ts @@ -20,7 +20,8 @@ export default function ({ getService }: FtrProviderContext) { const jobConfigs = [createJobConfig('test_calendar_ad_1'), createJobConfig('test_calendar_ad_2')]; const newJobGroups = ['farequote']; - describe('calendar edit', function () { + // FLAKY: https://github.com/elastic/kibana/issues/78288 + describe.skip('calendar edit', function () { before(async () => { await esArchiver.loadIfNeeded('ml/farequote'); await ml.testResources.createIndexPatternIfNeeded('ft_farequote', '@timestamp'); diff --git a/x-pack/test/reporting_api_integration/reporting_and_security/network_policy.ts b/x-pack/test/reporting_api_integration/reporting_and_security/network_policy.ts index 8692f79d5aea9..a9a1b31072e7e 100644 --- a/x-pack/test/reporting_api_integration/reporting_and_security/network_policy.ts +++ b/x-pack/test/reporting_api_integration/reporting_and_security/network_policy.ts @@ -40,7 +40,7 @@ export default function ({ getService }: FtrProviderContext) { filter(({ statusCode }) => statusCode === 500), map(({ message }) => message), first(), - timeout(15000) + timeout(120000) ); const reportFailed = await fails$.toPromise(); diff --git a/x-pack/test/reporting_api_integration/reporting_and_security/spaces.ts b/x-pack/test/reporting_api_integration/reporting_and_security/spaces.ts index 3f2b2e7116206..b216f137e27b5 100644 --- a/x-pack/test/reporting_api_integration/reporting_and_security/spaces.ts +++ b/x-pack/test/reporting_api_integration/reporting_and_security/spaces.ts @@ -33,7 +33,7 @@ export default function ({ getService }: FtrProviderContext) { tap(() => log.debug(`report at ${downloadPath} is done`)), map((response) => response.text), first(), - timeout(15000) + timeout(120000) ); }; @@ -105,8 +105,7 @@ export default function ({ getService }: FtrProviderContext) { }); }); - // FLAKY: https://github.com/elastic/kibana/issues/76551 - it.skip('should complete a job of PNG export of a dashboard in non-default space', async () => { + it('should complete a job of PNG export of a dashboard in non-default space', async () => { const downloadPath = await reportingAPI.postJobJSON( `/s/non_default_space/api/reporting/generate/png`, { @@ -119,8 +118,7 @@ export default function ({ getService }: FtrProviderContext) { expect(reportCompleted).to.not.be(null); }); - // FLAKY: https://github.com/elastic/kibana/issues/76551 - it.skip('should complete a job of PDF export of a dashboard in non-default space', async () => { + it('should complete a job of PDF export of a dashboard in non-default space', async () => { const downloadPath = await reportingAPI.postJobJSON( `/s/non_default_space/api/reporting/generate/printablePdf`, { diff --git a/x-pack/test/reporting_api_integration/reporting_and_security/usage.ts b/x-pack/test/reporting_api_integration/reporting_and_security/usage.ts index 99a46684d8a67..e2c6e17064373 100644 --- a/x-pack/test/reporting_api_integration/reporting_and_security/usage.ts +++ b/x-pack/test/reporting_api_integration/reporting_and_security/usage.ts @@ -21,7 +21,8 @@ export default function ({ getService }: FtrProviderContext) { const reportingAPI = getService('reportingAPI'); const usageAPI = getService('usageAPI'); - describe('Usage', () => { + // FLAKY: https://github.com/elastic/kibana/issues/78494 + describe.skip('Usage', () => { before(async () => { await esArchiver.load(OSS_KIBANA_ARCHIVE_PATH); await esArchiver.load(OSS_DATA_ARCHIVE_PATH); @@ -132,8 +133,7 @@ export default function ({ getService }: FtrProviderContext) { reportingAPI.expectRecentJobTypeTotalStats(usage, 'printable_pdf', 0); }); - // FLAKY: https://github.com/elastic/kibana/issues/76581 - it.skip('should handle preserve_layout pdf', async () => { + it('should handle preserve_layout pdf', async () => { await reportingAPI.expectAllJobsToFinishSuccessfully( await Promise.all([ reportingAPI.postJob(GenerationUrls.PDF_PRESERVE_DASHBOARD_FILTER_6_3), @@ -150,8 +150,7 @@ export default function ({ getService }: FtrProviderContext) { reportingAPI.expectRecentJobTypeTotalStats(usage, 'printable_pdf', 2); }); - // FLAKY: https://github.com/elastic/kibana/issues/76581 - it.skip('should handle print_layout pdf', async () => { + it('should handle print_layout pdf', async () => { await reportingAPI.expectAllJobsToFinishSuccessfully( await Promise.all([ reportingAPI.postJob(GenerationUrls.PDF_PRINT_DASHBOARD_6_3), diff --git a/x-pack/test/security_solution_endpoint_api_int/apis/resolver/events.ts b/x-pack/test/security_solution_endpoint_api_int/apis/resolver/events.ts index 4e248f52ec297..b57486ee55ca4 100644 --- a/x-pack/test/security_solution_endpoint_api_int/apis/resolver/events.ts +++ b/x-pack/test/security_solution_endpoint_api_int/apis/resolver/events.ts @@ -5,7 +5,10 @@ */ import expect from '@kbn/expect'; import { eventIDSafeVersion } from '../../../../plugins/security_solution/common/endpoint/models/event'; -import { SafeResolverRelatedEvents } from '../../../../plugins/security_solution/common/endpoint/types'; +import { + ResolverPaginatedEvents, + SafeResolverRelatedEvents, +} from '../../../../plugins/security_solution/common/endpoint/types'; import { FtrProviderContext } from '../../ftr_provider_context'; import { Tree, @@ -41,97 +44,221 @@ export default function ({ getService }: FtrProviderContext) { ancestryArraySize: 2, }; - describe('related events route', () => { - before(async () => { - await esArchiver.load('endpoint/resolver/api_feature'); - resolverTrees = await resolver.createTrees(treeOptions); - // we only requested a single alert so there's only 1 tree - tree = resolverTrees.trees[0]; - }); - after(async () => { - await resolver.deleteData(resolverTrees); - await esArchiver.unload('endpoint/resolver/api_feature'); - }); + describe('event routes', () => { + describe('related events route', () => { + before(async () => { + await esArchiver.load('endpoint/resolver/api_feature'); + resolverTrees = await resolver.createTrees(treeOptions); + // we only requested a single alert so there's only 1 tree + tree = resolverTrees.trees[0]; + }); + after(async () => { + await resolver.deleteData(resolverTrees); + await esArchiver.unload('endpoint/resolver/api_feature'); + }); - describe('legacy events', () => { - const endpointID = '5a0c957f-b8e7-4538-965e-57e8bb86ad3a'; - const entityID = '94042'; - const cursor = 'eyJ0aW1lc3RhbXAiOjE1ODE0NTYyNTUwMDAsImV2ZW50SUQiOiI5NDA0MyJ9'; + describe('legacy events', () => { + const endpointID = '5a0c957f-b8e7-4538-965e-57e8bb86ad3a'; + const entityID = '94042'; + const cursor = 'eyJ0aW1lc3RhbXAiOjE1ODE0NTYyNTUwMDAsImV2ZW50SUQiOiI5NDA0MyJ9'; - it('should return details for the root node', async () => { - const { body }: { body: SafeResolverRelatedEvents } = await supertest - .post(`/api/endpoint/resolver/${entityID}/events?legacyEndpointID=${endpointID}`) - .set('kbn-xsrf', 'xxx') - .expect(200); - expect(body.events.length).to.eql(1); - expect(body.entityID).to.eql(entityID); - expect(body.nextEvent).to.eql(null); + it('should return details for the root node', async () => { + const { body }: { body: SafeResolverRelatedEvents } = await supertest + .post(`/api/endpoint/resolver/${entityID}/events?legacyEndpointID=${endpointID}`) + .set('kbn-xsrf', 'xxx') + .expect(200); + expect(body.events.length).to.eql(1); + expect(body.entityID).to.eql(entityID); + expect(body.nextEvent).to.eql(null); + }); + + it('returns no values when there is no more data', async () => { + const { body }: { body: SafeResolverRelatedEvents } = await supertest + // after is set to the document id of the last event so there shouldn't be any more after it + .post( + `/api/endpoint/resolver/${entityID}/events?legacyEndpointID=${endpointID}&afterEvent=${cursor}` + ) + .set('kbn-xsrf', 'xxx') + .expect(200); + expect(body.events).be.empty(); + expect(body.entityID).to.eql(entityID); + expect(body.nextEvent).to.eql(null); + }); + + it('should return the first page of information when the cursor is invalid', async () => { + const { body }: { body: SafeResolverRelatedEvents } = await supertest + .post( + `/api/endpoint/resolver/${entityID}/events?legacyEndpointID=${endpointID}&afterEvent=blah` + ) + .set('kbn-xsrf', 'xxx') + .expect(200); + expect(body.entityID).to.eql(entityID); + expect(body.nextEvent).to.eql(null); + }); + + it('should return no results for an invalid endpoint ID', async () => { + const { body }: { body: SafeResolverRelatedEvents } = await supertest + .post(`/api/endpoint/resolver/${entityID}/events?legacyEndpointID=foo`) + .set('kbn-xsrf', 'xxx') + .expect(200); + expect(body.nextEvent).to.eql(null); + expect(body.entityID).to.eql(entityID); + expect(body.events).to.be.empty(); + }); + + it('should error on invalid pagination values', async () => { + await supertest + .post(`/api/endpoint/resolver/${entityID}/events?events=0`) + .set('kbn-xsrf', 'xxx') + .expect(400); + await supertest + .post(`/api/endpoint/resolver/${entityID}/events?events=20000`) + .set('kbn-xsrf', 'xxx') + .expect(400); + await supertest + .post(`/api/endpoint/resolver/${entityID}/events?events=-1`) + .set('kbn-xsrf', 'xxx') + .expect(400); + }); }); - it('returns no values when there is no more data', async () => { - const { body }: { body: SafeResolverRelatedEvents } = await supertest - // after is set to the document id of the last event so there shouldn't be any more after it - .post( - `/api/endpoint/resolver/${entityID}/events?legacyEndpointID=${endpointID}&afterEvent=${cursor}` - ) - .set('kbn-xsrf', 'xxx') - .expect(200); - expect(body.events).be.empty(); - expect(body.entityID).to.eql(entityID); - expect(body.nextEvent).to.eql(null); + describe('endpoint events', () => { + it('should not find any events', async () => { + const { body }: { body: SafeResolverRelatedEvents } = await supertest + .post(`/api/endpoint/resolver/5555/events`) + .set('kbn-xsrf', 'xxx') + .expect(200); + expect(body.nextEvent).to.eql(null); + expect(body.events).to.be.empty(); + }); + + it('should return details for the root node', async () => { + const { body }: { body: SafeResolverRelatedEvents } = await supertest + .post(`/api/endpoint/resolver/${tree.origin.id}/events`) + .set('kbn-xsrf', 'xxx') + .expect(200); + expect(body.events.length).to.eql(4); + compareArrays(tree.origin.relatedEvents, body.events, true); + expect(body.nextEvent).to.eql(null); + }); + + it('should allow for the events to be filtered', async () => { + const filter = `event.category:"${RelatedEventCategory.Driver}"`; + const { body }: { body: SafeResolverRelatedEvents } = await supertest + .post(`/api/endpoint/resolver/${tree.origin.id}/events`) + .set('kbn-xsrf', 'xxx') + .send({ + filter, + }) + .expect(200); + expect(body.events.length).to.eql(2); + compareArrays(tree.origin.relatedEvents, body.events); + expect(body.nextEvent).to.eql(null); + for (const event of body.events) { + expect(event.event?.category).to.be(RelatedEventCategory.Driver); + } + }); + + it('should return paginated results for the root node', async () => { + let { body }: { body: SafeResolverRelatedEvents } = await supertest + .post(`/api/endpoint/resolver/${tree.origin.id}/events?events=2`) + .set('kbn-xsrf', 'xxx') + .expect(200); + expect(body.events.length).to.eql(2); + compareArrays(tree.origin.relatedEvents, body.events); + expect(body.nextEvent).not.to.eql(null); + + ({ body } = await supertest + .post( + `/api/endpoint/resolver/${tree.origin.id}/events?events=2&afterEvent=${body.nextEvent}` + ) + .set('kbn-xsrf', 'xxx') + .expect(200)); + expect(body.events.length).to.eql(2); + compareArrays(tree.origin.relatedEvents, body.events); + expect(body.nextEvent).to.not.eql(null); + + ({ body } = await supertest + .post( + `/api/endpoint/resolver/${tree.origin.id}/events?events=2&afterEvent=${body.nextEvent}` + ) + .set('kbn-xsrf', 'xxx') + .expect(200)); + expect(body.events).to.be.empty(); + expect(body.nextEvent).to.eql(null); + }); + + it('should return the first page of information when the cursor is invalid', async () => { + const { body }: { body: SafeResolverRelatedEvents } = await supertest + .post(`/api/endpoint/resolver/${tree.origin.id}/events?afterEvent=blah`) + .set('kbn-xsrf', 'xxx') + .expect(200); + expect(body.events.length).to.eql(4); + compareArrays(tree.origin.relatedEvents, body.events, true); + expect(body.nextEvent).to.eql(null); + }); + + it('should sort the events in descending order', async () => { + const { body }: { body: SafeResolverRelatedEvents } = await supertest + .post(`/api/endpoint/resolver/${tree.origin.id}/events`) + .set('kbn-xsrf', 'xxx') + .expect(200); + expect(body.events.length).to.eql(4); + // these events are created in the order they are defined in the array so the newest one is + // the last element in the array so let's reverse it + const relatedEvents = tree.origin.relatedEvents.reverse(); + for (let i = 0; i < body.events.length; i++) { + expect(body.events[i].event?.category).to.equal(relatedEvents[i].event?.category); + expect(eventIDSafeVersion(body.events[i])).to.equal(relatedEvents[i].event?.id); + } + }); }); + }); - it('should return the first page of information when the cursor is invalid', async () => { - const { body }: { body: SafeResolverRelatedEvents } = await supertest - .post( - `/api/endpoint/resolver/${entityID}/events?legacyEndpointID=${endpointID}&afterEvent=blah` - ) - .set('kbn-xsrf', 'xxx') - .expect(200); - expect(body.entityID).to.eql(entityID); - expect(body.nextEvent).to.eql(null); + describe('kql events route', () => { + let entityIDFilter: string | undefined; + before(async () => { + resolverTrees = await resolver.createTrees(treeOptions); + // we only requested a single alert so there's only 1 tree + tree = resolverTrees.trees[0]; + entityIDFilter = `process.entity_id:"${tree.origin.id}" and not event.category:"process"`; + }); + after(async () => { + await resolver.deleteData(resolverTrees); }); - it('should return no results for an invalid endpoint ID', async () => { - const { body }: { body: SafeResolverRelatedEvents } = await supertest - .post(`/api/endpoint/resolver/${entityID}/events?legacyEndpointID=foo`) + it('should filter events by event.id', async () => { + const { body }: { body: ResolverPaginatedEvents } = await supertest + .post(`/api/endpoint/resolver/events`) .set('kbn-xsrf', 'xxx') + .send({ + filter: `event.id:"${tree.origin.relatedEvents[0]?.event?.id}"`, + }) .expect(200); + expect(body.events.length).to.eql(1); + expect(tree.origin.relatedEvents[0]?.event?.id).to.eql(body.events[0].event?.id); expect(body.nextEvent).to.eql(null); - expect(body.entityID).to.eql(entityID); - expect(body.events).to.be.empty(); }); - it('should error on invalid pagination values', async () => { - await supertest - .post(`/api/endpoint/resolver/${entityID}/events?events=0`) - .set('kbn-xsrf', 'xxx') - .expect(400); - await supertest - .post(`/api/endpoint/resolver/${entityID}/events?events=20000`) - .set('kbn-xsrf', 'xxx') - .expect(400); - await supertest - .post(`/api/endpoint/resolver/${entityID}/events?events=-1`) - .set('kbn-xsrf', 'xxx') - .expect(400); - }); - }); - - describe('endpoint events', () => { - it('should not find any events', async () => { - const { body }: { body: SafeResolverRelatedEvents } = await supertest - .post(`/api/endpoint/resolver/5555/events`) + it('should not find any events when given an invalid entity id', async () => { + const { body }: { body: ResolverPaginatedEvents } = await supertest + .post(`/api/endpoint/resolver/events`) .set('kbn-xsrf', 'xxx') + .send({ + filter: 'process.entity_id:"5555"', + }) .expect(200); expect(body.nextEvent).to.eql(null); expect(body.events).to.be.empty(); }); - it('should return details for the root node', async () => { - const { body }: { body: SafeResolverRelatedEvents } = await supertest - .post(`/api/endpoint/resolver/${tree.origin.id}/events`) + it('should return related events for the root node', async () => { + const { body }: { body: ResolverPaginatedEvents } = await supertest + .post(`/api/endpoint/resolver/events`) .set('kbn-xsrf', 'xxx') + .send({ + filter: entityIDFilter, + }) .expect(200); expect(body.events.length).to.eql(4); compareArrays(tree.origin.relatedEvents, body.events, true); @@ -139,9 +266,9 @@ export default function ({ getService }: FtrProviderContext) { }); it('should allow for the events to be filtered', async () => { - const filter = `event.category:"${RelatedEventCategory.Driver}"`; - const { body }: { body: SafeResolverRelatedEvents } = await supertest - .post(`/api/endpoint/resolver/${tree.origin.id}/events`) + const filter = `event.category:"${RelatedEventCategory.Driver}" and ${entityIDFilter}`; + const { body }: { body: ResolverPaginatedEvents } = await supertest + .post(`/api/endpoint/resolver/events`) .set('kbn-xsrf', 'xxx') .send({ filter, @@ -156,38 +283,46 @@ export default function ({ getService }: FtrProviderContext) { }); it('should return paginated results for the root node', async () => { - let { body }: { body: SafeResolverRelatedEvents } = await supertest - .post(`/api/endpoint/resolver/${tree.origin.id}/events?events=2`) + let { body }: { body: ResolverPaginatedEvents } = await supertest + .post(`/api/endpoint/resolver/events?limit=2`) .set('kbn-xsrf', 'xxx') + .send({ + filter: entityIDFilter, + }) .expect(200); expect(body.events.length).to.eql(2); compareArrays(tree.origin.relatedEvents, body.events); expect(body.nextEvent).not.to.eql(null); ({ body } = await supertest - .post( - `/api/endpoint/resolver/${tree.origin.id}/events?events=2&afterEvent=${body.nextEvent}` - ) + .post(`/api/endpoint/resolver/events?limit=2&afterEvent=${body.nextEvent}`) .set('kbn-xsrf', 'xxx') + .send({ + filter: entityIDFilter, + }) .expect(200)); expect(body.events.length).to.eql(2); compareArrays(tree.origin.relatedEvents, body.events); expect(body.nextEvent).to.not.eql(null); ({ body } = await supertest - .post( - `/api/endpoint/resolver/${tree.origin.id}/events?events=2&afterEvent=${body.nextEvent}` - ) + .post(`/api/endpoint/resolver/events?limit=2&afterEvent=${body.nextEvent}`) .set('kbn-xsrf', 'xxx') + .send({ + filter: entityIDFilter, + }) .expect(200)); expect(body.events).to.be.empty(); expect(body.nextEvent).to.eql(null); }); it('should return the first page of information when the cursor is invalid', async () => { - const { body }: { body: SafeResolverRelatedEvents } = await supertest - .post(`/api/endpoint/resolver/${tree.origin.id}/events?afterEvent=blah`) + const { body }: { body: ResolverPaginatedEvents } = await supertest + .post(`/api/endpoint/resolver/events?afterEvent=blah`) .set('kbn-xsrf', 'xxx') + .send({ + filter: entityIDFilter, + }) .expect(200); expect(body.events.length).to.eql(4); compareArrays(tree.origin.relatedEvents, body.events, true); @@ -195,9 +330,12 @@ export default function ({ getService }: FtrProviderContext) { }); it('should sort the events in descending order', async () => { - const { body }: { body: SafeResolverRelatedEvents } = await supertest - .post(`/api/endpoint/resolver/${tree.origin.id}/events`) + const { body }: { body: ResolverPaginatedEvents } = await supertest + .post(`/api/endpoint/resolver/events`) .set('kbn-xsrf', 'xxx') + .send({ + filter: entityIDFilter, + }) .expect(200); expect(body.events.length).to.eql(4); // these events are created in the order they are defined in the array so the newest one is diff --git a/yarn.lock b/yarn.lock index 182eb90d5f7a4..7aa88bcc88348 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1128,15 +1128,6 @@ enabled "2.0.x" kuler "^2.0.0" -"@elastic/apm-rum-core@^5.6.0": - version "5.6.0" - resolved "https://registry.yarnpkg.com/@elastic/apm-rum-core/-/apm-rum-core-5.6.0.tgz#d1f643eb00e590d5884598a20bb54efb1490ee13" - integrity sha512-hG+lITWBQd0mw00BQ1zYVRKDCh5b9FKFiht9fMXcT0SENOsT5J37RIbQHPdVawluT7/mhDF07t4fR8V0xRB1/g== - dependencies: - error-stack-parser "^1.3.5" - opentracing "^0.14.3" - promise-polyfill "^8.1.3" - "@elastic/apm-rum-core@^5.6.1": version "5.6.1" resolved "https://registry.yarnpkg.com/@elastic/apm-rum-core/-/apm-rum-core-5.6.1.tgz#0870e654e84e1f2ffea7c8a247a2da1b72918bcd" @@ -1154,13 +1145,6 @@ "@elastic/apm-rum" "^5.6.0" hoist-non-react-statics "^3.3.0" -"@elastic/apm-rum@^5.5.0": - version "5.5.0" - resolved "https://registry.yarnpkg.com/@elastic/apm-rum/-/apm-rum-5.5.0.tgz#24a8b4db0fa328c1e54710d18837e1adba7e51e0" - integrity sha512-uEOJG7Lm0CLtGfXOLXSsiPLpTPvrNUqlWQEKf/D77lpHRVWxBb56xa4X4CK2on8V1XzHDufcYBPcBcKSGozTLw== - dependencies: - "@elastic/apm-rum-core" "^5.6.0" - "@elastic/apm-rum@^5.6.0": version "5.6.0" resolved "https://registry.yarnpkg.com/@elastic/apm-rum/-/apm-rum-5.6.0.tgz#0af2acb55091b9eb315cf38c6422a83cddfecb6f" @@ -1215,13 +1199,13 @@ pump "^3.0.0" secure-json-parse "^2.1.0" -"@elastic/ems-client@7.9.3": - version "7.9.3" - resolved "https://registry.yarnpkg.com/@elastic/ems-client/-/ems-client-7.9.3.tgz#71b79914f76e347f050ead8474ad65d761e94a8a" - integrity sha512-aun5rW9TQgWLVH77xBLLhempT3P+6AeQIEyK/CWYuVfCDpHfDxzMKWgQ076a7rSUqF059ayDGZbyOxf7l0M2Sw== +"@elastic/ems-client@7.10.0": + version "7.10.0" + resolved "https://registry.yarnpkg.com/@elastic/ems-client/-/ems-client-7.10.0.tgz#6d0e12ce99acd122d8066aa0a8685ecfd21637d3" + integrity sha512-84XqAhY4iaKwo2PnDwskNLvnprR3EYcS1AhN048xa8mIZlRJuycB4DwWnB699qvUTQqKcg5qLS0o5sEUs2HDeA== dependencies: lodash "^4.17.15" - semver "^6.3.0" + semver "7.3.2" "@elastic/eslint-plugin-eui@0.0.2": version "0.0.2" @@ -25861,6 +25845,11 @@ semver@7.0.0: resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== +semver@7.3.2, semver@^7.3.2: + version "7.3.2" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" + integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== + semver@^5.5.1: version "5.5.1" resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.1.tgz#7dfdd8814bdb7cabc7be0fb1d734cfb66c940477" @@ -25881,11 +25870,6 @@ semver@^7.1.3: resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.0.tgz#91f7c70ec944a63e5dc7a74cde2da375d8e0853c" integrity sha512-uyvgU/igkrMgNHwLgXvlpD9jEADbJhB0+JXSywoO47JgJ6c16iau9F9cjtc/E5o0PoqRYTiTIAPRKaYe84z6eQ== -semver@^7.3.2: - version "7.3.2" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938" - integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ== - semver@~5.3.0: version "5.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f"