diff --git a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldformat.tojson.md b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldformat.tojson.md index 5fa7d4841537b..48ec9456c56dd 100644 --- a/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldformat.tojson.md +++ b/docs/development/plugins/data/public/kibana-plugin-plugins-data-public.fieldformat.tojson.md @@ -12,14 +12,14 @@ Serialize this format to a simple POJO, with only the params that are not defaul ```typescript toJSON(): { - id: unknown; - params: _.Dictionary | undefined; + id: any; + params: any; }; ``` Returns: `{ - id: unknown; - params: _.Dictionary | undefined; + id: any; + params: any; }` diff --git a/package.json b/package.json index b1dd8686f818b..3c15d9ee3c97b 100644 --- a/package.json +++ b/package.json @@ -86,8 +86,9 @@ "**/@types/angular": "^1.6.56", "**/@types/hoist-non-react-statics": "^3.3.1", "**/@types/chai": "^4.2.11", + "**/cypress/@types/lodash": "^4.14.155", "**/typescript": "3.9.5", - "**/graphql-toolkit/lodash": "^4.17.13", + "**/graphql-toolkit/lodash": "^4.17.15", "**/hoist-non-react-statics": "^3.3.2", "**/isomorphic-git/**/base64-js": "^1.2.1", "**/image-diff/gm/debug": "^2.6.9", @@ -213,8 +214,7 @@ "leaflet.heat": "0.2.0", "less": "npm:@elastic/less@2.7.3-kibana", "less-loader": "5.0.0", - "lodash": "npm:@elastic/lodash@3.10.1-kibana4", - "lodash.clonedeep": "^4.5.0", + "lodash": "^4.17.15", "lru-cache": "4.1.5", "markdown-it": "^10.0.0", "mini-css-extract-plugin": "0.8.0", @@ -355,8 +355,7 @@ "@types/json5": "^0.0.30", "@types/license-checker": "15.0.0", "@types/listr": "^0.14.0", - "@types/lodash": "^3.10.1", - "@types/lodash.clonedeep": "^4.5.4", + "@types/lodash": "^4.14.155", "@types/lru-cache": "^5.1.0", "@types/markdown-it": "^0.0.7", "@types/minimatch": "^2.0.29", diff --git a/packages/kbn-config-schema/package.json b/packages/kbn-config-schema/package.json index 015dca128ce91..10b607dcd4312 100644 --- a/packages/kbn-config-schema/package.json +++ b/packages/kbn-config-schema/package.json @@ -14,6 +14,7 @@ "tsd": "^0.7.4" }, "peerDependencies": { + "lodash": "^4.17.15", "joi": "^13.5.2", "moment": "^2.24.0", "type-detect": "^4.0.8" diff --git a/packages/kbn-interpreter/package.json b/packages/kbn-interpreter/package.json index ea72a4a48caeb..c6bb06e68b9c0 100644 --- a/packages/kbn-interpreter/package.json +++ b/packages/kbn-interpreter/package.json @@ -11,8 +11,7 @@ "dependencies": { "@babel/runtime": "^7.10.2", "@kbn/i18n": "1.0.0", - "lodash": "npm:@elastic/lodash@3.10.1-kibana4", - "lodash.clone": "^4.5.0", + "lodash": "^4.17.15", "uuid": "3.3.2" }, "devDependencies": { diff --git a/packages/kbn-interpreter/src/common/lib/registry.js b/packages/kbn-interpreter/src/common/lib/registry.js index 25b122f400711..16572cf494cd3 100644 --- a/packages/kbn-interpreter/src/common/lib/registry.js +++ b/packages/kbn-interpreter/src/common/lib/registry.js @@ -17,7 +17,7 @@ * under the License. */ -import clone from 'lodash.clone'; +import { clone } from 'lodash'; export class Registry { constructor(prop = 'name') { diff --git a/packages/kbn-plugin-generator/index.js b/packages/kbn-plugin-generator/index.js index e61037e42d63f..398b49fa1ecd5 100644 --- a/packages/kbn-plugin-generator/index.js +++ b/packages/kbn-plugin-generator/index.js @@ -23,7 +23,7 @@ const dedent = require('dedent'); const sao = require('sao'); const chalk = require('chalk'); const getopts = require('getopts'); -const snakeCase = require('lodash.snakecase'); +const { snakeCase } = require('lodash'); exports.run = function run(argv) { const options = getopts(argv, { @@ -41,7 +41,7 @@ exports.run = function run(argv) { if (options.help) { console.log( dedent(chalk` - # {dim Usage:} + # {dim Usage:} node scripts/generate-plugin {bold [name]} Generate a fresh Kibana plugin in the plugins/ directory `) + '\n' diff --git a/packages/kbn-plugin-generator/package.json b/packages/kbn-plugin-generator/package.json index b9df67b32e5d3..5c1e98cd869de 100644 --- a/packages/kbn-plugin-generator/package.json +++ b/packages/kbn-plugin-generator/package.json @@ -8,10 +8,7 @@ "dedent": "^0.7.0", "execa": "^4.0.2", "getopts": "^2.2.4", - "lodash.camelcase": "^4.3.0", - "lodash.kebabcase": "^4.1.1", - "lodash.snakecase": "^4.1.1", - "lodash.startcase": "^4.4.0", + "lodash": "^4.17.15", "sao": "^0.22.12" } } diff --git a/packages/kbn-plugin-generator/sao_template/sao.js b/packages/kbn-plugin-generator/sao_template/sao.js index 7fc29b1e6bd0a..dc4d8a2fc10fb 100755 --- a/packages/kbn-plugin-generator/sao_template/sao.js +++ b/packages/kbn-plugin-generator/sao_template/sao.js @@ -20,9 +20,7 @@ const { relative, resolve } = require('path'); const fs = require('fs'); -const startCase = require('lodash.startcase'); -const camelCase = require('lodash.camelcase'); -const snakeCase = require('lodash.snakecase'); +const { camelCase, startCase, snakeCase } = require('lodash'); const chalk = require('chalk'); const execa = require('execa'); diff --git a/packages/kbn-pm/package.json b/packages/kbn-pm/package.json index 3e7ed49c61314..188db0a8321a2 100644 --- a/packages/kbn-pm/package.json +++ b/packages/kbn-pm/package.json @@ -22,7 +22,7 @@ "@types/glob": "^5.0.35", "@types/globby": "^6.1.0", "@types/has-ansi": "^3.0.0", - "@types/lodash.clonedeepwith": "^4.5.3", + "@types/lodash": "^4.14.155", "@types/log-symbols": "^2.0.0", "@types/ncp": "^2.0.1", "@types/node": ">=10.17.17 <10.20.0", @@ -46,7 +46,7 @@ "globby": "^8.0.1", "has-ansi": "^3.0.0", "is-path-inside": "^3.0.2", - "lodash.clonedeepwith": "^4.5.0", + "lodash": "^4.17.15", "log-symbols": "^2.2.0", "multimatch": "^4.0.0", "ncp": "^2.0.0", diff --git a/packages/kbn-pm/src/test_helpers/absolute_path_snapshot_serializer.ts b/packages/kbn-pm/src/test_helpers/absolute_path_snapshot_serializer.ts index 96ce6fd1d919a..cf4ecbb4ad42c 100644 --- a/packages/kbn-pm/src/test_helpers/absolute_path_snapshot_serializer.ts +++ b/packages/kbn-pm/src/test_helpers/absolute_path_snapshot_serializer.ts @@ -17,7 +17,7 @@ * under the License. */ -import cloneDeepWith from 'lodash.clonedeepwith'; +import { cloneDeepWith } from 'lodash'; import { resolve, sep as pathSep } from 'path'; const repoRoot = resolve(__dirname, '../../../../'); diff --git a/packages/kbn-storybook/lib/webpack.dll.config.js b/packages/kbn-storybook/lib/webpack.dll.config.js index 534f503e2956a..740ee3819c36f 100644 --- a/packages/kbn-storybook/lib/webpack.dll.config.js +++ b/packages/kbn-storybook/lib/webpack.dll.config.js @@ -54,7 +54,6 @@ module.exports = { 'highlight.js', 'html-entities', 'jquery', - 'lodash.clone', 'lodash', 'markdown-it', 'mocha', diff --git a/packages/kbn-test/package.json b/packages/kbn-test/package.json index 042de2617565e..0c49ccf276b2b 100644 --- a/packages/kbn-test/package.json +++ b/packages/kbn-test/package.json @@ -14,6 +14,7 @@ "@kbn/babel-preset": "1.0.0", "@kbn/dev-utils": "1.0.0", "@types/joi": "^13.4.2", + "@types/lodash": "^4.14.155", "@types/parse-link-header": "^1.0.0", "@types/puppeteer": "^3.0.0", "@types/strip-ansi": "^5.2.1", @@ -28,6 +29,7 @@ "getopts": "^2.2.4", "glob": "^7.1.2", "joi": "^13.5.2", + "lodash": "^4.17.15", "parse-link-header": "^1.0.1", "puppeteer": "^3.3.0", "rxjs": "^6.5.5", diff --git a/packages/kbn-test/src/functional_test_runner/lib/config/config.ts b/packages/kbn-test/src/functional_test_runner/lib/config/config.ts index e38520f00e45b..687a0e87d4c68 100644 --- a/packages/kbn-test/src/functional_test_runner/lib/config/config.ts +++ b/packages/kbn-test/src/functional_test_runner/lib/config/config.ts @@ -18,10 +18,7 @@ */ import { Schema } from 'joi'; -import { cloneDeep, get, has } from 'lodash'; - -// @ts-ignore internal lodash module is not typed -import toPath from 'lodash/internal/toPath'; +import { cloneDeepWith, get, has, toPath } from 'lodash'; import { schema } from './schema'; @@ -114,7 +111,7 @@ export class Config { throw new Error(`Unknown config key "${key}"`); } - return cloneDeep(get(this[$values], key, defaultValue), (v) => { + return cloneDeepWith(get(this[$values], key, defaultValue), (v) => { if (typeof v === 'function') { return v; } @@ -122,7 +119,7 @@ export class Config { } public getAll() { - return cloneDeep(this[$values], (v) => { + return cloneDeepWith(this[$values], (v) => { if (typeof v === 'function') { return v; } diff --git a/packages/kbn-test/src/legacy_es/legacy_es_test_cluster.js b/packages/kbn-test/src/legacy_es/legacy_es_test_cluster.js index f795b32d78b8e..2d4c461cc2c2e 100644 --- a/packages/kbn-test/src/legacy_es/legacy_es_test_cluster.js +++ b/packages/kbn-test/src/legacy_es/legacy_es_test_cluster.js @@ -19,8 +19,7 @@ import { resolve } from 'path'; import { format } from 'url'; -import { get } from 'lodash'; -import toPath from 'lodash/internal/toPath'; +import { get, toPath } from 'lodash'; import { Cluster } from '@kbn/es'; import { CI_PARALLEL_PROCESS_PREFIX } from '../ci_parallel_process_prefix'; import { esTestConfig } from './es_test_config'; diff --git a/packages/kbn-test/src/page_load_metrics/navigation.ts b/packages/kbn-test/src/page_load_metrics/navigation.ts index 21dc681951b21..db53df789ac69 100644 --- a/packages/kbn-test/src/page_load_metrics/navigation.ts +++ b/packages/kbn-test/src/page_load_metrics/navigation.ts @@ -19,7 +19,6 @@ import Fs from 'fs'; import Url from 'url'; -import _ from 'lodash'; import puppeteer from 'puppeteer'; import { resolve } from 'path'; import { ToolingLog } from '@kbn/dev-utils'; diff --git a/packages/kbn-ui-framework/Gruntfile.js b/packages/kbn-ui-framework/Gruntfile.js index 177fd1f153155..b7ba1e87b2f00 100644 --- a/packages/kbn-ui-framework/Gruntfile.js +++ b/packages/kbn-ui-framework/Gruntfile.js @@ -21,7 +21,7 @@ const sass = require('node-sass'); const postcss = require('postcss'); const postcssConfig = require('../../src/optimize/postcss.config'); const chokidar = require('chokidar'); -const debounce = require('lodash/function/debounce'); +const { debounce } = require('lodash'); const platform = require('os').platform(); const isPlatformWindows = /^win/.test(platform); diff --git a/packages/kbn-ui-framework/package.json b/packages/kbn-ui-framework/package.json index 4da4fb21fbed5..abf64906e0253 100644 --- a/packages/kbn-ui-framework/package.json +++ b/packages/kbn-ui-framework/package.json @@ -17,7 +17,7 @@ "dependencies": { "classnames": "2.2.6", "focus-trap-react": "^3.1.1", - "lodash": "npm:@elastic/lodash@3.10.1-kibana4", + "lodash": "^4.17.15", "prop-types": "15.6.0", "react": "^16.12.0", "react-ace": "^5.9.0", diff --git a/renovate.json5 b/renovate.json5 index 49a255d60f29e..5a807b4b090c1 100644 --- a/renovate.json5 +++ b/renovate.json5 @@ -557,22 +557,6 @@ '@types/lodash', ], }, - { - groupSlug: 'lodash.clonedeep', - groupName: 'lodash.clonedeep related packages', - packageNames: [ - 'lodash.clonedeep', - '@types/lodash.clonedeep', - ], - }, - { - groupSlug: 'lodash.clonedeepwith', - groupName: 'lodash.clonedeepwith related packages', - packageNames: [ - 'lodash.clonedeepwith', - '@types/lodash.clonedeepwith', - ], - }, { groupSlug: 'log-symbols', groupName: 'log-symbols related packages', diff --git a/src/apm.js b/src/apm.js index 6c10539c6b7d3..effa6c77d7614 100644 --- a/src/apm.js +++ b/src/apm.js @@ -20,7 +20,7 @@ const { join } = require('path'); const { readFileSync } = require('fs'); const { execSync } = require('child_process'); -const merge = require('lodash.merge'); +const { merge } = require('lodash'); const { name, version, build } = require('../package.json'); const ROOT_DIR = join(__dirname, '..'); diff --git a/src/cli/cluster/cluster_manager.test.ts b/src/cli/cluster/cluster_manager.test.ts index 66f68f815edac..2ddccae2fada6 100644 --- a/src/cli/cluster/cluster_manager.test.ts +++ b/src/cli/cluster/cluster_manager.test.ts @@ -93,7 +93,7 @@ describe('CLI cluster manager', () => { } const football = {}; - const messenger = sample(manager.workers); + const messenger = sample(manager.workers) as any; messenger.emit('broadcast', football); for (const worker of manager.workers) { diff --git a/src/cli/cluster/worker.ts b/src/cli/cluster/worker.ts index dc6e6d5676651..097a549187429 100644 --- a/src/cli/cluster/worker.ts +++ b/src/cli/cluster/worker.ts @@ -177,7 +177,7 @@ export class Worker extends EventEmitter { } flushChangeBuffer() { - const files = _.unique(this.changes.splice(0)); + const files = _.uniq(this.changes.splice(0)); const prefix = files.length > 1 ? '\n - ' : ''; return files.reduce(function (list, file) { return `${list || ''}${prefix}"${file}"`; diff --git a/src/cli/help.js b/src/cli/help.js index 656944d85b254..0170cb53e19df 100644 --- a/src/cli/help.js +++ b/src/cli/help.js @@ -72,7 +72,7 @@ function commandsSummary(program) { }, 0); return cmds.reduce(function (help, cmd) { - return `${help || ''}${_.padRight(cmd[0], cmdLColWidth)} ${cmd[1] || ''}\n`; + return `${help || ''}${_.padEnd(cmd[0], cmdLColWidth)} ${cmd[1] || ''}\n`; }, ''); } diff --git a/src/core/public/http/fetch.ts b/src/core/public/http/fetch.ts index bf9b4235e9444..e31094d96f3d4 100644 --- a/src/core/public/http/fetch.ts +++ b/src/core/public/http/fetch.ts @@ -17,7 +17,7 @@ * under the License. */ -import { merge } from 'lodash'; +import { omitBy } from 'lodash'; import { format } from 'url'; import { BehaviorSubject } from 'rxjs'; @@ -42,6 +42,10 @@ interface Params { const JSON_CONTENT = /^(application\/(json|x-javascript)|text\/(x-)?javascript|x-json)(;.*)?$/; const NDJSON_CONTENT = /^(application\/ndjson)(;.*)?$/; +const removedUndefined = (obj: Record | undefined) => { + return omitBy(obj, (v) => v === undefined); +}; + export class Fetch { private readonly interceptors = new Set(); private readonly requestCount$ = new BehaviorSubject(0); @@ -119,24 +123,23 @@ export class Fetch { asResponse, asSystemRequest, ...fetchOptions - } = merge( - { - method: 'GET', - credentials: 'same-origin', - prependBasePath: true, - }, - options, - { - headers: { - 'Content-Type': 'application/json', - ...options.headers, - 'kbn-version': this.params.kibanaVersion, - }, - } - ); + } = { + method: 'GET', + credentials: 'same-origin', + prependBasePath: true, + ...options, + // options can pass an `undefined` Content-Type to erase the default value. + // however we can't pass it to `fetch` as it will send an `Content-Type: Undefined` header + headers: removedUndefined({ + 'Content-Type': 'application/json', + ...options.headers, + 'kbn-version': this.params.kibanaVersion, + }), + }; + const url = format({ pathname: shouldPrependBasePath ? this.params.basePath.prepend(options.path) : options.path, - query, + query: removedUndefined(query), }); // Make sure the system request header is only present if `asSystemRequest` is true. @@ -144,7 +147,7 @@ export class Fetch { fetchOptions.headers['kbn-system-request'] = 'true'; } - return new Request(url, fetchOptions); + return new Request(url, fetchOptions as RequestInit); } private async fetchResponse(fetchOptions: HttpFetchOptionsWithPath): Promise> { diff --git a/src/core/public/plugins/plugins_service.test.ts b/src/core/public/plugins/plugins_service.test.ts index cb8671ba37a6c..7dc5f3655fca0 100644 --- a/src/core/public/plugins/plugins_service.test.ts +++ b/src/core/public/plugins/plugins_service.test.ts @@ -91,7 +91,7 @@ describe('PluginsService', () => { context: contextServiceMock.createSetupContract(), fatalErrors: fatalErrorsServiceMock.createSetupContract(), http: httpServiceMock.createSetupContract(), - injectedMetadata: pick(injectedMetadataServiceMock.createStartContract(), 'getInjectedVar'), + injectedMetadata: injectedMetadataServiceMock.createStartContract(), notifications: notificationServiceMock.createSetupContract(), uiSettings: uiSettingsServiceMock.createSetupContract(), }; @@ -99,6 +99,7 @@ describe('PluginsService', () => { ...mockSetupDeps, application: expect.any(Object), getStartServices: expect.any(Function), + injectedMetadata: pick(mockSetupDeps.injectedMetadata, 'getInjectedVar'), }; mockStartDeps = { application: applicationServiceMock.createInternalStartContract(), @@ -106,7 +107,7 @@ describe('PluginsService', () => { http: httpServiceMock.createStartContract(), chrome: chromeServiceMock.createStartContract(), i18n: i18nServiceMock.createStartContract(), - injectedMetadata: pick(injectedMetadataServiceMock.createStartContract(), 'getInjectedVar'), + injectedMetadata: injectedMetadataServiceMock.createStartContract(), notifications: notificationServiceMock.createStartContract(), overlays: overlayServiceMock.createStartContract(), uiSettings: uiSettingsServiceMock.createStartContract(), @@ -117,6 +118,7 @@ describe('PluginsService', () => { ...mockStartDeps, application: expect.any(Object), chrome: omit(mockStartDeps.chrome, 'getComponent'), + injectedMetadata: pick(mockStartDeps.injectedMetadata, 'getInjectedVar'), }; // Reset these for each test. diff --git a/src/core/public/saved_objects/saved_objects_client.ts b/src/core/public/saved_objects/saved_objects_client.ts index cb279b2cc4c8f..c4daaf5d7f307 100644 --- a/src/core/public/saved_objects/saved_objects_client.ts +++ b/src/core/public/saved_objects/saved_objects_client.ts @@ -162,7 +162,9 @@ export class SavedObjectsClient { }); if (!foundObject) { - return queueItem.resolve(this.createSavedObject(pick(queueItem, ['id', 'type']))); + return queueItem.resolve( + this.createSavedObject(pick(queueItem, ['id', 'type']) as SavedObject) + ); } queueItem.resolve(foundObject); diff --git a/src/core/public/saved_objects/simple_saved_object.ts b/src/core/public/saved_objects/simple_saved_object.ts index d3ba506b865a4..165ef98be91d4 100644 --- a/src/core/public/saved_objects/simple_saved_object.ts +++ b/src/core/public/saved_objects/simple_saved_object.ts @@ -60,7 +60,7 @@ export class SimpleSavedObject { } public set(key: string, value: any): T { - return set(this.attributes, key, value); + return set(this.attributes as any, key, value); } public has(key: string): boolean { diff --git a/src/core/server/capabilities/merge_capabilities.ts b/src/core/server/capabilities/merge_capabilities.ts index 95296346ad835..06869089598a9 100644 --- a/src/core/server/capabilities/merge_capabilities.ts +++ b/src/core/server/capabilities/merge_capabilities.ts @@ -17,11 +17,11 @@ * under the License. */ -import { merge } from 'lodash'; +import { mergeWith } from 'lodash'; import { Capabilities } from './types'; export const mergeCapabilities = (...sources: Array>): Capabilities => - merge({}, ...sources, (a: any, b: any) => { + mergeWith({}, ...sources, (a: any, b: any) => { if ( (typeof a === 'boolean' && typeof b === 'object') || (typeof a === 'object' && typeof b === 'boolean') diff --git a/src/core/server/config/deprecation/core_deprecations.ts b/src/core/server/config/deprecation/core_deprecations.ts index 483534e0c145b..715f5b883139f 100644 --- a/src/core/server/config/deprecation/core_deprecations.ts +++ b/src/core/server/config/deprecation/core_deprecations.ts @@ -39,10 +39,7 @@ const dataPathDeprecation: ConfigDeprecation = (settings, fromPath, log) => { }; const xsrfDeprecation: ConfigDeprecation = (settings, fromPath, log) => { - if ( - has(settings, 'server.xsrf.whitelist') && - get(settings, 'server.xsrf.whitelist').length > 0 - ) { + if ((settings.server?.xsrf?.whitelist ?? []).length > 0) { log( 'It is not recommended to disable xsrf protections for API endpoints via [server.xsrf.whitelist]. ' + 'It will be removed in 8.0 release. Instead, supply the "kbn-xsrf" header.' diff --git a/src/core/server/elasticsearch/legacy/errors.ts b/src/core/server/elasticsearch/legacy/errors.ts index f81903d76547a..3b3b8da51a907 100644 --- a/src/core/server/elasticsearch/legacy/errors.ts +++ b/src/core/server/elasticsearch/legacy/errors.ts @@ -81,7 +81,7 @@ export class LegacyElasticsearchErrorHelpers { public static decorateNotAuthorizedError(error: Error, reason?: string) { const decoratedError = decorate(error, ErrorCode.NOT_AUTHORIZED, 401, reason); - const wwwAuthHeader = get(error, 'body.error.header[WWW-Authenticate]'); + const wwwAuthHeader = get(error, 'body.error.header[WWW-Authenticate]') as string; decoratedError.output.headers['WWW-Authenticate'] = wwwAuthHeader || 'Basic realm="Authorization Required"'; diff --git a/src/core/server/http/base_path_proxy_server.ts b/src/core/server/http/base_path_proxy_server.ts index ffbdabadd03f7..eccc9d013176c 100644 --- a/src/core/server/http/base_path_proxy_server.ts +++ b/src/core/server/http/base_path_proxy_server.ts @@ -24,7 +24,7 @@ import apm from 'elastic-apm-node'; import { ByteSizeValue } from '@kbn/config-schema'; import { Server, Request, ResponseToolkit } from 'hapi'; import HapiProxy from 'h2o2'; -import { sample } from 'lodash'; +import { sampleSize } from 'lodash'; import BrowserslistUserAgent from 'browserslist-useragent'; import * as Rx from 'rxjs'; import { take } from 'rxjs/operators'; @@ -90,7 +90,7 @@ export class BasePathProxyServer { httpConfig.maxPayload = new ByteSizeValue(ONE_GIGABYTE); if (!httpConfig.basePath) { - httpConfig.basePath = `/${sample(alphabet, 3).join('')}`; + httpConfig.basePath = `/${sampleSize(alphabet, 3).join('')}`; } } diff --git a/src/core/server/legacy/config/__snapshots__/legacy_object_to_config_adapter.test.ts.snap b/src/core/server/legacy/config/__snapshots__/legacy_object_to_config_adapter.test.ts.snap index 3b16bed92df97..4a6d86a0dfba6 100644 --- a/src/core/server/legacy/config/__snapshots__/legacy_object_to_config_adapter.test.ts.snap +++ b/src/core/server/legacy/config/__snapshots__/legacy_object_to_config_adapter.test.ts.snap @@ -119,7 +119,10 @@ Object { exports[`#set correctly sets values for paths that do not exist. 1`] = ` Object { - "unknown": "value", + "unknown": Object { + "sub1": "sub-value-1", + "sub2": "sub-value-2", + }, } `; diff --git a/src/core/server/saved_objects/mappings/lib/get_property.ts b/src/core/server/saved_objects/mappings/lib/get_property.ts index a31c9fe0c3ba1..91b2b1239fc55 100644 --- a/src/core/server/saved_objects/mappings/lib/get_property.ts +++ b/src/core/server/saved_objects/mappings/lib/get_property.ts @@ -17,7 +17,7 @@ * under the License. */ -import toPath from 'lodash/internal/toPath'; +import { toPath } from 'lodash'; import { SavedObjectsCoreFieldMapping, SavedObjectsFieldMapping, IndexMapping } from '../types'; function getPropertyMappingFromObjectMapping( diff --git a/src/core/server/saved_objects/migrations/core/document_migrator.ts b/src/core/server/saved_objects/migrations/core/document_migrator.ts index 376f823267ebe..07675bb0a6819 100644 --- a/src/core/server/saved_objects/migrations/core/document_migrator.ts +++ b/src/core/server/saved_objects/migrations/core/document_migrator.ts @@ -62,7 +62,6 @@ import Boom from 'boom'; import _ from 'lodash'; -import cloneDeep from 'lodash.clonedeep'; import Semver from 'semver'; import { Logger } from '../../../logging'; import { SavedObjectUnsanitizedDoc } from '../../serialization'; @@ -151,7 +150,7 @@ export class DocumentMigrator implements VersionedTransformer { // Clone the document to prevent accidental mutations on the original data // Ex: Importing sample data that is cached at import level, migrations would // execute on mutated data the second time. - const clonedDoc = cloneDeep(doc); + const clonedDoc = _.cloneDeep(doc); return this.transformDoc(clonedDoc); }; } @@ -220,7 +219,7 @@ function buildActiveMigrations( return { ...migrations, [type.name]: { - latestVersion: _.last(transforms).version, + latestVersion: _.last(transforms)!.version, transforms, }, }; diff --git a/src/core/server/saved_objects/migrations/core/migration_coordinator.test.ts b/src/core/server/saved_objects/migrations/core/migration_coordinator.test.ts index 3f2c31a7c0e5c..2d27ca7c8a29b 100644 --- a/src/core/server/saved_objects/migrations/core/migration_coordinator.test.ts +++ b/src/core/server/saved_objects/migrations/core/migration_coordinator.test.ts @@ -17,7 +17,6 @@ * under the License. */ -import _ from 'lodash'; import { coordinateMigration } from './migration_coordinator'; import { createSavedObjectsMigrationLoggerMock } from '../mocks'; diff --git a/src/core/server/saved_objects/service/lib/repository.ts b/src/core/server/saved_objects/service/lib/repository.ts index f24195c0f295e..880b71e164b5b 100644 --- a/src/core/server/saved_objects/service/lib/repository.ts +++ b/src/core/server/saved_objects/service/lib/repository.ts @@ -1346,7 +1346,7 @@ export class SavedObjectsRepository { // method transparently to the specified namespace. private _rawToSavedObject(raw: SavedObjectsRawDoc): SavedObject { const savedObject = this._serializer.rawToSavedObject(raw); - return omit(savedObject, 'namespace'); + return omit(savedObject, 'namespace') as SavedObject; } /** diff --git a/src/core/utils/deep_freeze.test.ts b/src/core/utils/deep_freeze.test.ts index 58aa9c9b8c92b..48f890160d05d 100644 --- a/src/core/utils/deep_freeze.test.ts +++ b/src/core/utils/deep_freeze.test.ts @@ -32,7 +32,8 @@ it('returns the first argument with all original references', () => { it('prevents adding properties to argument', () => { const frozen = deepFreeze({}); expect(() => { - // @ts-expect-error ts knows this shouldn't be possible, but just making sure + // ts knows this shouldn't be possible, but just making sure + // @ts-expect-error frozen.foo = true; }).toThrowError(`object is not extensible`); }); @@ -40,7 +41,8 @@ it('prevents adding properties to argument', () => { it('prevents changing properties on argument', () => { const frozen = deepFreeze({ foo: false }); expect(() => { - // @ts-expect-error ts knows this shouldn't be possible, but just making sure + // ts knows this shouldn't be possible, but just making sure + // @ts-expect-error frozen.foo = true; }).toThrowError(`read only property 'foo'`); }); @@ -48,7 +50,8 @@ it('prevents changing properties on argument', () => { it('prevents changing properties on nested children of argument', () => { const frozen = deepFreeze({ foo: { bar: { baz: { box: 1 } } } }); expect(() => { - // @ts-expect-error ts knows this shouldn't be possible, but just making sure + // ts knows this shouldn't be possible, but just making sure + // @ts-expect-error frozen.foo.bar.baz.box = 2; }).toThrowError(`read only property 'box'`); }); @@ -56,7 +59,8 @@ it('prevents changing properties on nested children of argument', () => { it('prevents adding items to a frozen array', () => { const frozen = deepFreeze({ foo: [1] }); expect(() => { - // @ts-expect-error ts knows this shouldn't be possible, but just making sure + // ts knows this shouldn't be possible, but just making sure + // @ts-expect-error frozen.foo.push(2); }).toThrowError(`object is not extensible`); }); @@ -64,7 +68,8 @@ it('prevents adding items to a frozen array', () => { it('prevents reassigning items in a frozen array', () => { const frozen = deepFreeze({ foo: [1] }); expect(() => { - // @ts-expect-error ts knows this shouldn't be possible, but just making sure + // ts knows this shouldn't be possible, but just making sure + // @ts-expect-error frozen.foo[0] = 2; }).toThrowError(`read only property '0'`); }); diff --git a/src/dev/precommit_hook/casing_check_config.js b/src/dev/precommit_hook/casing_check_config.js index bc3a6265cc582..cec80dd547a53 100644 --- a/src/dev/precommit_hook/casing_check_config.js +++ b/src/dev/precommit_hook/casing_check_config.js @@ -98,7 +98,6 @@ export const IGNORE_DIRECTORY_GLOBS = [ 'packages/*', 'packages/kbn-ui-framework/generator-kui', 'src/legacy/ui/public/flot-charts', - 'src/legacy/ui/public/utils/lodash-mixins', 'test/functional/fixtures/es_archiver/visualize_source-filters', 'packages/kbn-pm/src/utils/__fixtures__/*', 'x-pack/dev-tools', diff --git a/src/dev/sass/build_sass.js b/src/dev/sass/build_sass.js index 7075bcf55adf5..68058043477d0 100644 --- a/src/dev/sass/build_sass.js +++ b/src/dev/sass/build_sass.js @@ -23,11 +23,11 @@ import * as Rx from 'rxjs'; import { toArray } from 'rxjs/operators'; import { createFailError } from '@kbn/dev-utils'; +import { debounce } from 'lodash'; import { findPluginSpecs } from '../../legacy/plugin_discovery'; import { collectUiExports } from '../../legacy/ui'; import { buildAll } from '../../legacy/server/sass/build_all'; import chokidar from 'chokidar'; -import debounce from 'lodash/function/debounce'; // TODO: clintandrewhall - Extract and use FSWatcher from legacy/server/sass const build = async ({ log, kibanaDir, styleSheetPaths, watch }) => { diff --git a/src/fixtures/agg_resp/geohash_grid.js b/src/fixtures/agg_resp/geohash_grid.js index 0e576a88ab36a..fde1e54b0661d 100644 --- a/src/fixtures/agg_resp/geohash_grid.js +++ b/src/fixtures/agg_resp/geohash_grid.js @@ -44,7 +44,7 @@ export default function GeoHashGridAggResponseFixture() { // random number of tags let docCount = 0; const buckets = _.times(_.random(40, 200), function () { - return _.sample(geoHashCharts, 3).join(''); + return _.sampleSize(geoHashCharts, 3).join(''); }) .sort() .map(function (geoHash) { diff --git a/src/legacy/core_plugins/console_legacy/index.ts b/src/legacy/core_plugins/console_legacy/index.ts index c588b941112d1..82e00a99c6cfd 100644 --- a/src/legacy/core_plugins/console_legacy/index.ts +++ b/src/legacy/core_plugins/console_legacy/index.ts @@ -41,7 +41,7 @@ export default function (kibana: any) { uiExports: { injectDefaultVars: () => ({ elasticsearchUrl: url.format( - Object.assign(url.parse(head(_legacyEsConfig.hosts)), { auth: false }) + Object.assign(url.parse(head(_legacyEsConfig.hosts) as any), { auth: false }) ), }), }, diff --git a/src/legacy/core_plugins/elasticsearch/server/lib/handle_es_error.js b/src/legacy/core_plugins/elasticsearch/server/lib/handle_es_error.js index fc4ff512e2bd5..d76b2a2aa9364 100644 --- a/src/legacy/core_plugins/elasticsearch/server/lib/handle_es_error.js +++ b/src/legacy/core_plugins/elasticsearch/server/lib/handle_es_error.js @@ -35,7 +35,7 @@ export function handleESError(error) { return Boom.serverUnavailable(error); } else if ( error instanceof esErrors.Conflict || - _.contains(error.message, 'index_template_already_exists') + _.includes(error.message, 'index_template_already_exists') ) { return Boom.conflict(error); } else if (error instanceof esErrors[403]) { diff --git a/src/legacy/core_plugins/kibana/public/__tests__/vis_type_vislib/lib/dispatch.js b/src/legacy/core_plugins/kibana/public/__tests__/vis_type_vislib/lib/dispatch.js index 4f8cee2651a9f..20281d8479ab4 100644 --- a/src/legacy/core_plugins/kibana/public/__tests__/vis_type_vislib/lib/dispatch.js +++ b/src/legacy/core_plugins/kibana/public/__tests__/vis_type_vislib/lib/dispatch.js @@ -51,7 +51,7 @@ describe('Vislib Dispatch Class Test Suite', function () { }); it('implements on, off, emit methods', function () { - const events = _.pluck(vis.handler.charts, 'events'); + const events = _.map(vis.handler.charts, 'events'); expect(events.length).to.be.above(0); events.forEach(function (dispatch) { expect(dispatch).to.have.property('on'); diff --git a/src/legacy/core_plugins/kibana/public/__tests__/vis_type_vislib/visualizations/column_chart.js b/src/legacy/core_plugins/kibana/public/__tests__/vis_type_vislib/visualizations/column_chart.js index f075dff466793..6b7ccaed25d49 100644 --- a/src/legacy/core_plugins/kibana/public/__tests__/vis_type_vislib/visualizations/column_chart.js +++ b/src/legacy/core_plugins/kibana/public/__tests__/vis_type_vislib/visualizations/column_chart.js @@ -267,7 +267,7 @@ describe('stackData method - data set with zeros in percentage mode', function ( expect(chart.chartData.series).to.have.length(1); const series = chart.chartData.series[0].values; // with the interval set in seriesMonthlyInterval data, the point at x=1454309600000 does not exist - const point = _.find(series, 'x', 1454309600000); + const point = _.find(series, ['x', 1454309600000]); expect(point).to.not.be(undefined); expect(point.y).to.be(0); }); @@ -279,7 +279,7 @@ describe('stackData method - data set with zeros in percentage mode', function ( const chart = vis.handler.charts[0]; expect(chart.chartData.series).to.have.length(5); const series = chart.chartData.series[0].values; - const point = _.find(series, 'x', 1415826240000); + const point = _.find(series, ['x', 1415826240000]); expect(point).to.not.be(undefined); expect(point.y).to.be(0); }); diff --git a/src/legacy/core_plugins/timelion/public/app.js b/src/legacy/core_plugins/timelion/public/app.js index b5501982cec09..602b221b7d14d 100644 --- a/src/legacy/core_plugins/timelion/public/app.js +++ b/src/legacy/core_plugins/timelion/public/app.js @@ -427,7 +427,7 @@ app.controller('timelion', function ( const httpResult = $http .post('../api/timelion/run', { sheet: $scope.state.sheet, - time: _.extend( + time: _.assignIn( { from: timeRangeBounds.min, to: timeRangeBounds.max, diff --git a/src/legacy/core_plugins/timelion/public/directives/saved_object_finder.js b/src/legacy/core_plugins/timelion/public/directives/saved_object_finder.js index 879fab206b99d..ae042310fd464 100644 --- a/src/legacy/core_plugins/timelion/public/directives/saved_object_finder.js +++ b/src/legacy/core_plugins/timelion/public/directives/saved_object_finder.js @@ -165,7 +165,7 @@ module }; self.getLabel = function () { - return _.words(self.properties.nouns).map(_.capitalize).join(' '); + return _.words(self.properties.nouns).map(_.upperFirst).join(' '); }; //key handler for the filter text box diff --git a/src/legacy/core_plugins/timelion/public/directives/timelion_expression_input.js b/src/legacy/core_plugins/timelion/public/directives/timelion_expression_input.js index f3fd2fde8f2c5..2102b02194bc8 100644 --- a/src/legacy/core_plugins/timelion/public/directives/timelion_expression_input.js +++ b/src/legacy/core_plugins/timelion/public/directives/timelion_expression_input.js @@ -78,7 +78,7 @@ export function TimelionExpInput($http, $timeout) { function init() { $http.get('../api/timelion/functions').then(function (resp) { Object.assign(functionReference, { - byName: _.indexBy(resp.data, 'name'), + byName: _.keyBy(resp.data, 'name'), list: resp.data, }); }); diff --git a/src/legacy/core_plugins/timelion/public/directives/timelion_interval/timelion_interval.js b/src/legacy/core_plugins/timelion/public/directives/timelion_interval/timelion_interval.js index 577ee984e05c6..3750e15c000e7 100644 --- a/src/legacy/core_plugins/timelion/public/directives/timelion_interval/timelion_interval.js +++ b/src/legacy/core_plugins/timelion/public/directives/timelion_interval/timelion_interval.js @@ -47,7 +47,7 @@ export function TimelionInterval($timeout) { // Only run this on initialization if (newVal !== oldVal || oldVal == null) return; - if (_.contains($scope.intervalOptions, newVal)) { + if (_.includes($scope.intervalOptions, newVal)) { $scope.interval = newVal; } else { $scope.interval = 'other'; diff --git a/src/legacy/core_plugins/timelion/public/panels/timechart/schema.ts b/src/legacy/core_plugins/timelion/public/panels/timechart/schema.ts index b1999eb4b483c..087e166925327 100644 --- a/src/legacy/core_plugins/timelion/public/panels/timechart/schema.ts +++ b/src/legacy/core_plugins/timelion/public/panels/timechart/schema.ts @@ -346,7 +346,7 @@ export function timechartFn(dependencies: TimelionVisualizationDependencies) { } if (serie._global) { - _.merge(options, serie._global, function (objVal, srcVal) { + _.mergeWith(options, serie._global, function (objVal, srcVal) { // This is kind of gross, it means that you can't replace a global value with a null // best you can do is an empty string. Deal with it. if (objVal == null) return srcVal; diff --git a/src/legacy/plugin_discovery/plugin_spec/plugin_spec.js b/src/legacy/plugin_discovery/plugin_spec/plugin_spec.js index 17da5ffca1242..db1ec425f2ce5 100644 --- a/src/legacy/plugin_discovery/plugin_spec/plugin_spec.js +++ b/src/legacy/plugin_discovery/plugin_spec/plugin_spec.js @@ -19,8 +19,7 @@ import { resolve, basename, isAbsolute as isAbsolutePath } from 'path'; -import toPath from 'lodash/internal/toPath'; -import { get } from 'lodash'; +import { get, toPath } from 'lodash'; import { createInvalidPluginError } from '../errors'; import { isVersionCompatible } from './is_version_compatible'; diff --git a/src/legacy/server/i18n/localization/file_integrity.ts b/src/legacy/server/i18n/localization/file_integrity.ts index a852fba4a1c5a..7400d84ea2ce7 100644 --- a/src/legacy/server/i18n/localization/file_integrity.ts +++ b/src/legacy/server/i18n/localization/file_integrity.ts @@ -33,7 +33,7 @@ export interface Integrities { export async function getIntegrityHashes(filepaths: string[]): Promise { const hashes = await Promise.all(filepaths.map(getIntegrityHash)); - return zipObject(filepaths, hashes); + return zipObject(filepaths, hashes) as Integrities; } export async function getIntegrityHash(filepath: string): Promise { diff --git a/src/legacy/server/logging/log_format.js b/src/legacy/server/logging/log_format.js index 9bc1d67dd5857..8a80cbef1a9c5 100644 --- a/src/legacy/server/logging/log_format.js +++ b/src/legacy/server/logging/log_format.js @@ -144,7 +144,7 @@ export default class TransformObjStream extends Stream.Transform { data.message = message || 'Unknown error (no message)'; } else if (event.error instanceof Error) { data.type = 'error'; - data.level = _.contains(event.tags, 'fatal') ? 'fatal' : 'error'; + data.level = _.includes(event.tags, 'fatal') ? 'fatal' : 'error'; data.error = serializeError(event.error); const message = get(event, 'error.message'); data.message = message || 'Unknown error object (no message)'; diff --git a/src/legacy/server/status/server_status.js b/src/legacy/server/status/server_status.js index 3ee4d37d0b823..81d07de55faaf 100644 --- a/src/legacy/server/status/server_status.js +++ b/src/legacy/server/status/server_status.js @@ -81,7 +81,7 @@ export default class ServerStatus { // reduce to the state with the highest severity, defaulting to green .reduce((a, b) => (a.severity > b.severity ? a : b), states.get('green')); - const statuses = _.where(this._created, { state: state.id }); + const statuses = _.filter(this._created, { state: state.id }); const since = _.get(_.sortBy(statuses, 'since'), [0, 'since']); return { diff --git a/src/legacy/server/status/states.js b/src/legacy/server/status/states.js index bf05f45ff856c..4a34684571c3c 100644 --- a/src/legacy/server/status/states.js +++ b/src/legacy/server/status/states.js @@ -73,7 +73,7 @@ export const getAll = () => [ }, ]; -export const getAllById = () => _.indexBy(exports.getAll(), 'id'); +export const getAllById = () => _.keyBy(exports.getAll(), 'id'); export const defaults = { icon: 'question', diff --git a/src/legacy/ui/public/events.js b/src/legacy/ui/public/events.js index 1dc8a71afb193..464c03d98b83f 100644 --- a/src/legacy/ui/public/events.js +++ b/src/legacy/ui/public/events.js @@ -107,7 +107,7 @@ export function EventsProvider(Promise) { */ Events.prototype.emit = function (name) { const self = this; - const args = _.rest(arguments); + const args = _.tail(arguments); if (!self._listeners[name]) { return self._emitChain; @@ -131,7 +131,7 @@ export function EventsProvider(Promise) { * @return {array[function]} */ Events.prototype.listeners = function (name) { - return _.pluck(this._listeners[name], 'handler'); + return _.map(this._listeners[name], 'handler'); }; return Events; diff --git a/src/legacy/ui/public/indexed_array/__tests__/indexed_array.js b/src/legacy/ui/public/indexed_array/__tests__/indexed_array.js index a8abbba9df433..df96a58a6e99f 100644 --- a/src/legacy/ui/public/indexed_array/__tests__/indexed_array.js +++ b/src/legacy/ui/public/indexed_array/__tests__/indexed_array.js @@ -30,8 +30,8 @@ const users = [ ]; // this is how we used to accomplish this, before IndexedArray -users.byName = _.indexBy(users, 'name'); -users.byUsername = _.indexBy(users, 'username'); +users.byName = _.keyBy(users, 'name'); +users.byUsername = _.keyBy(users, 'username'); users.byGroup = _.groupBy(users, 'group'); users.inIdOrder = _.sortBy(users, 'id'); @@ -54,7 +54,7 @@ describe('IndexedArray', function () { }); it('clones to an object', function () { - expect(_.isPlainObject(_.clone(reg))).to.be(true); + expect(_.isObject(_.clone(reg))).to.be(true); expect(Array.isArray(_.clone(reg))).to.be(false); }); }); @@ -140,7 +140,7 @@ describe('IndexedArray', function () { reg.remove({ name: 'John' }); - expect(_.eq(reg.raw, reg.slice(0))).to.be(true); + expect(_.isEqual(reg.raw, reg.slice(0))).to.be(true); expect(reg.length).to.be(3); expect(reg[0].name).to.be('Anon'); }); diff --git a/src/legacy/ui/public/indexed_array/indexed_array.js b/src/legacy/ui/public/indexed_array/indexed_array.js index 79ef5e8c183da..b9a427b8da7ad 100644 --- a/src/legacy/ui/public/indexed_array/indexed_array.js +++ b/src/legacy/ui/public/indexed_array/indexed_array.js @@ -52,7 +52,7 @@ export class IndexedArray { this._indexNames = _.union( this._setupIndex(config.group, inflectIndex, organizeByIndexedArray(config)), - this._setupIndex(config.index, inflectIndex, _.indexBy), + this._setupIndex(config.index, inflectIndex, _.keyBy), this._setupIndex(config.order, inflectOrder, (raw, pluckValue) => { return [...raw].sort((itemA, itemB) => { const a = pluckValue(itemA); diff --git a/src/legacy/ui/public/routes/__tests__/_route_manager.js b/src/legacy/ui/public/routes/__tests__/_route_manager.js index 51bde8b8605ac..eb47a3e9ace70 100644 --- a/src/legacy/ui/public/routes/__tests__/_route_manager.js +++ b/src/legacy/ui/public/routes/__tests__/_route_manager.js @@ -46,7 +46,7 @@ describe('routes/route_manager', function () { }) ); - it('should have chainable methods: ' + _.pluck(chainableMethods, 'name').join(', '), function () { + it('should have chainable methods: ' + _.map(chainableMethods, 'name').join(', '), function () { chainableMethods.forEach(function (meth) { expect(routes[meth.name].apply(routes, _.clone(meth.args))).to.be(routes); }); diff --git a/src/legacy/ui/public/state_management/state.js b/src/legacy/ui/public/state_management/state.js index 93428e9f8fa4e..d91834adb4a79 100644 --- a/src/legacy/ui/public/state_management/state.js +++ b/src/legacy/ui/public/state_management/state.js @@ -341,7 +341,7 @@ export function StateProvider( * @return {object} */ State.prototype.toObject = function () { - return _.omit(this, (value, key) => { + return _.omitBy(this, (value, key) => { return key.charAt(0) === '$' || key.charAt(0) === '_' || _.isFunction(value); }); }; diff --git a/src/legacy/ui/public/utils/collection.ts b/src/legacy/ui/public/utils/collection.ts index 45e5a0704c37b..b882a2bbe6e5b 100644 --- a/src/legacy/ui/public/utils/collection.ts +++ b/src/legacy/ui/public/utils/collection.ts @@ -50,7 +50,7 @@ export function move( } below = !!below; - qualifier = qualifier && _.callback(qualifier); + qualifier = qualifier && _.iteratee(qualifier); const above = !below; const finder = below ? _.findIndex : _.findLastIndex; diff --git a/src/legacy/utils/deep_clone_with_buffers.ts b/src/legacy/utils/deep_clone_with_buffers.ts index 2e9120eb32b7c..2c58d85187985 100644 --- a/src/legacy/utils/deep_clone_with_buffers.ts +++ b/src/legacy/utils/deep_clone_with_buffers.ts @@ -17,7 +17,7 @@ * under the License. */ -import { cloneDeep } from 'lodash'; +import { cloneDeepWith } from 'lodash'; // We should add `any` return type to overcome bug in lodash types, customizer // in lodash 3.* can return `undefined` if cloning is handled by the lodash, but @@ -29,5 +29,5 @@ function cloneBuffersCustomizer(val: unknown): any { } export function deepCloneWithBuffers(val: T): T { - return cloneDeep(val, cloneBuffersCustomizer); + return cloneDeepWith(val, cloneBuffersCustomizer); } diff --git a/src/legacy/utils/unset.js b/src/legacy/utils/unset.js index 8b4cc0a7be1cd..db6f0e5ea9ef1 100644 --- a/src/legacy/utils/unset.js +++ b/src/legacy/utils/unset.js @@ -18,11 +18,10 @@ */ import _ from 'lodash'; -import toPath from 'lodash/internal/toPath'; export function unset(object, rawPath) { if (!object) return; - const path = toPath(rawPath); + const path = _.toPath(rawPath); switch (path.length) { case 0: diff --git a/src/plugins/charts/public/services/colors/mapped_colors.test.ts b/src/plugins/charts/public/services/colors/mapped_colors.test.ts index 2c9f37afc14c5..e97ca8ac257b4 100644 --- a/src/plugins/charts/public/services/colors/mapped_colors.test.ts +++ b/src/plugins/charts/public/services/colors/mapped_colors.test.ts @@ -61,7 +61,7 @@ describe('Mapped Colors', () => { mappedColors.mapKeys(arr); const colorValues = _(mappedColors.mapping).values(); - expect(colorValues.contains(seedColors[0])).toBe(false); + expect(colorValues.includes(seedColors[0])).toBe(false); expect(colorValues.uniq().size()).toBe(arr.length); }); diff --git a/src/plugins/charts/public/services/colors/mapped_colors.ts b/src/plugins/charts/public/services/colors/mapped_colors.ts index fe0deac734e6b..3b9e1501d638d 100644 --- a/src/plugins/charts/public/services/colors/mapped_colors.ts +++ b/src/plugins/charts/public/services/colors/mapped_colors.ts @@ -54,7 +54,7 @@ export class MappedColors { } get(key: string | number) { - return this.getConfigColorMapping()[key] || this._mapping[key]; + return this.getConfigColorMapping()[key as any] || this._mapping[key]; } flush() { @@ -75,10 +75,10 @@ export class MappedColors { const keysToMap: Array = []; _.each(keys, (key) => { // If this key is mapped in the config, it's unnecessary to have it mapped here - if (configMapping[key]) delete this._mapping[key]; + if (configMapping[key as any]) delete this._mapping[key]; // If this key is mapped to a color used by the config color mapping, we need to remap it - if (_.contains(configColors, this._mapping[key])) keysToMap.push(key); + if (_.includes(configColors, this._mapping[key])) keysToMap.push(key); // if key exist in oldMap, move it to mapping if (this._oldMap[key]) this._mapping[key] = this._oldMap[key]; @@ -93,7 +93,7 @@ export class MappedColors { let newColors = _.difference(colorPalette, allColors); while (keysToMap.length > newColors.length) { - newColors = newColors.concat(_.sample(allColors, keysToMap.length - newColors.length)); + newColors = newColors.concat(_.sampleSize(allColors, keysToMap.length - newColors.length)); } _.merge(this._mapping, _.zipObject(keysToMap, newColors)); diff --git a/src/plugins/console/public/application/components/settings_modal.tsx b/src/plugins/console/public/application/components/settings_modal.tsx index 377e739a0c59a..ebcc2a35b6111 100644 --- a/src/plugins/console/public/application/components/settings_modal.tsx +++ b/src/plugins/console/public/application/components/settings_modal.tsx @@ -17,6 +17,7 @@ * under the License. */ +import _ from 'lodash'; import React, { Fragment, useState } from 'react'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; diff --git a/src/plugins/console/public/application/models/sense_editor/__tests__/integration.test.js b/src/plugins/console/public/application/models/sense_editor/__tests__/integration.test.js index b7cc8f2f4b72f..06823a981af46 100644 --- a/src/plugins/console/public/application/models/sense_editor/__tests__/integration.test.js +++ b/src/plugins/console/public/application/models/sense_editor/__tests__/integration.test.js @@ -117,7 +117,7 @@ describe('Integration', () => { return t; }); if (terms.length !== expectedTerms.length) { - expect(_.pluck(terms, 'name')).toEqual(_.pluck(expectedTerms, 'name')); + expect(_.map(terms, 'name')).toEqual(_.map(expectedTerms, 'name')); } else { const filteredActualTerms = _.map(terms, function (actualTerm, i) { const expectedTerm = expectedTerms[i]; diff --git a/src/plugins/console/public/lib/autocomplete/body_completer.js b/src/plugins/console/public/lib/autocomplete/body_completer.js index f37b3ac0cca9c..d31507626146e 100644 --- a/src/plugins/console/public/lib/autocomplete/body_completer.js +++ b/src/plugins/console/public/lib/autocomplete/body_completer.js @@ -51,7 +51,7 @@ function resolvePathToComponents(tokenPath, context, editor, components) { context, editor ); - const result = [].concat.apply([], _.pluck(walkStates, 'components')); + const result = [].concat.apply([], _.map(walkStates, 'components')); return result; } diff --git a/src/plugins/console/public/lib/autocomplete/components/list_component.js b/src/plugins/console/public/lib/autocomplete/components/list_component.js index b770638a61ff7..b26a223433333 100644 --- a/src/plugins/console/public/lib/autocomplete/components/list_component.js +++ b/src/plugins/console/public/lib/autocomplete/components/list_component.js @@ -62,7 +62,7 @@ export class ListComponent extends SharedComponent { // verify we have all tokens const list = this.listGenerator(); - const notFound = _.any(tokens, function (token) { + const notFound = _.some(tokens, function (token) { return list.indexOf(token) === -1; }); diff --git a/src/plugins/console/public/lib/autocomplete/components/url_pattern_matcher.js b/src/plugins/console/public/lib/autocomplete/components/url_pattern_matcher.js index 79a332624e5e1..412fda16d45b6 100644 --- a/src/plugins/console/public/lib/autocomplete/components/url_pattern_matcher.js +++ b/src/plugins/console/public/lib/autocomplete/components/url_pattern_matcher.js @@ -61,73 +61,64 @@ export class UrlPatternMatcher { } const endpointComponents = endpoint.url_components || {}; const partList = pattern.split('/'); - _.each( - partList, - function (part, partIndex) { - if (part.search(/^{.+}$/) >= 0) { - part = part.substr(1, part.length - 2); - if (activeComponent.getComponent(part)) { - // we already have something for this, reuse - activeComponent = activeComponent.getComponent(part); - return; - } - // a new path, resolve. + _.each(partList, (part, partIndex) => { + if (part.search(/^{.+}$/) >= 0) { + part = part.substr(1, part.length - 2); + if (activeComponent.getComponent(part)) { + // we already have something for this, reuse + activeComponent = activeComponent.getComponent(part); + return; + } + // a new path, resolve. - if ((c = endpointComponents[part])) { - // endpoint specific. Support list - if (Array.isArray(c)) { - c = new ListComponent(part, c, activeComponent); - } else if (_.isObject(c) && c.type === 'list') { - c = new ListComponent( - part, - c.list, - activeComponent, - c.multiValued, - c.allow_non_valid - ); - } else { - console.warn( - 'incorrectly configured url component ', - part, - ' in endpoint', - endpoint - ); - c = new SharedComponent(part); - } - } else if ((c = this[method].parametrizedComponentFactories.getComponent(part))) { - // c is a f - c = c(part, activeComponent); + if ((c = endpointComponents[part])) { + // endpoint specific. Support list + if (Array.isArray(c)) { + c = new ListComponent(part, c, activeComponent); + } else if (_.isObject(c) && c.type === 'list') { + c = new ListComponent( + part, + c.list, + activeComponent, + c.multiValued, + c.allow_non_valid + ); } else { - // just accept whatever with not suggestions - c = new SimpleParamComponent(part, activeComponent); + console.warn('incorrectly configured url component ', part, ' in endpoint', endpoint); + c = new SharedComponent(part); } - - activeComponent = c; + } else if ((c = this[method].parametrizedComponentFactories.getComponent(part))) { + // c is a f + c = c(part, activeComponent); } else { - // not pattern - let lookAhead = part; - let s; + // just accept whatever with not suggestions + c = new SimpleParamComponent(part, activeComponent); + } - for (partIndex++; partIndex < partList.length; partIndex++) { - s = partList[partIndex]; - if (s.indexOf('{') >= 0) { - break; - } - lookAhead += '/' + s; - } + activeComponent = c; + } else { + // not pattern + let lookAhead = part; + let s; - if (activeComponent.getComponent(part)) { - // we already have something for this, reuse - activeComponent = activeComponent.getComponent(part); - activeComponent.addOption(lookAhead); - } else { - c = new ConstantComponent(part, activeComponent, lookAhead); - activeComponent = c; + for (partIndex++; partIndex < partList.length; partIndex++) { + s = partList[partIndex]; + if (s.indexOf('{') >= 0) { + break; } + lookAhead += '/' + s; } - }, - this - ); + + if (activeComponent.getComponent(part)) { + // we already have something for this, reuse + activeComponent = activeComponent.getComponent(part); + activeComponent.addOption(lookAhead); + } else { + c = new ConstantComponent(part, activeComponent, lookAhead); + activeComponent = c; + } + } + }); // mark end of endpoint path new AcceptEndpointComponent(endpoint, activeComponent); }); diff --git a/src/plugins/console/public/lib/autocomplete/engine.js b/src/plugins/console/public/lib/autocomplete/engine.js index 38be0d8a7e4c9..b893218f4967c 100644 --- a/src/plugins/console/public/lib/autocomplete/engine.js +++ b/src/plugins/console/public/lib/autocomplete/engine.js @@ -26,16 +26,12 @@ export function wrapComponentWithDefaults(component, defaults) { if (!result) { return result; } - result = _.map( - result, - function (term) { - if (!_.isObject(term)) { - term = { name: term }; - } - return _.defaults(term, defaults); - }, - this - ); + result = _.map(result, (term) => { + if (!_.isObject(term)) { + term = { name: term }; + } + return _.defaults(term, defaults); + }); return result; }; return component; @@ -145,7 +141,7 @@ export function populateContext(tokenPath, context, editor, includeAutoComplete, }); }); }); - autoCompleteSet = _.uniq(autoCompleteSet, false); + autoCompleteSet = _.uniq(autoCompleteSet); context.autoCompleteSet = autoCompleteSet; } diff --git a/src/plugins/console/public/lib/autocomplete/url_params.js b/src/plugins/console/public/lib/autocomplete/url_params.js index a237fe5dd59d6..037f4b1b27c50 100644 --- a/src/plugins/console/public/lib/autocomplete/url_params.js +++ b/src/plugins/console/public/lib/autocomplete/url_params.js @@ -50,18 +50,14 @@ export class UrlParams { } description = _.clone(description || {}); _.defaults(description, defaults); - _.each( - description, - function (pDescription, param) { - const component = new ParamComponent(param, this.rootComponent, pDescription); - if (Array.isArray(pDescription)) { - new ListComponent(param, pDescription, component); - } else if (pDescription === '__flag__') { - new ListComponent(param, ['true', 'false'], component); - } - }, - this - ); + _.each(description, (pDescription, param) => { + const component = new ParamComponent(param, this.rootComponent, pDescription); + if (Array.isArray(pDescription)) { + new ListComponent(param, pDescription, component); + } else if (pDescription === '__flag__') { + new ListComponent(param, ['true', 'false'], component); + } + }); } getTopLevelComponents() { return this.rootComponent.next; diff --git a/src/plugins/console/public/lib/kb/api.js b/src/plugins/console/public/lib/kb/api.js index aafb234b0f446..0e3b6a345836b 100644 --- a/src/plugins/console/public/lib/kb/api.js +++ b/src/plugins/console/public/lib/kb/api.js @@ -60,19 +60,15 @@ function Api(urlParametrizedComponentFactories, bodyParametrizedComponentFactori cls.addEndpointDescription = function (endpoint, description) { const copiedDescription = {}; - _.extend(copiedDescription, description || {}); + _.assign(copiedDescription, description || {}); _.defaults(copiedDescription, { id: endpoint, patterns: [endpoint], methods: ['GET'], }); - _.each( - copiedDescription.patterns, - function (p) { - this.urlPatternMatcher.addEndpoint(p, copiedDescription); - }, - this - ); + _.each(copiedDescription.patterns, (p) => { + this.urlPatternMatcher.addEndpoint(p, copiedDescription); + }); copiedDescription.paramsAutocomplete = new UrlParams(copiedDescription.url_params); copiedDescription.bodyAutocompleteRootComponents = compileBodyDescription( diff --git a/src/plugins/console/public/lib/mappings/mappings.js b/src/plugins/console/public/lib/mappings/mappings.js index 22aae8da030d4..88fe195bcbf2b 100644 --- a/src/plugins/console/public/lib/mappings/mappings.js +++ b/src/plugins/console/public/lib/mappings/mappings.js @@ -98,7 +98,7 @@ export function getFields(indices, types) { ret = [].concat.apply([], ret); } - return _.uniq(ret, function (f) { + return _.uniqBy(ret, function (f) { return f.name + ':' + f.type; }); } @@ -191,7 +191,7 @@ function getFieldNamesFromProperties(properties = {}) { }); // deduping - return _.uniq(fieldList, function (f) { + return _.uniqBy(fieldList, function (f) { return f.name + ':' + f.type; }); } diff --git a/src/plugins/console/server/lib/elasticsearch_proxy_config.ts b/src/plugins/console/server/lib/elasticsearch_proxy_config.ts index 28a971794d403..38592e66bd8be 100644 --- a/src/plugins/console/server/lib/elasticsearch_proxy_config.ts +++ b/src/plugins/console/server/lib/elasticsearch_proxy_config.ts @@ -25,7 +25,7 @@ import url from 'url'; import { ESConfigForProxy } from '../types'; const createAgent = (legacyConfig: ESConfigForProxy) => { - const target = url.parse(_.head(legacyConfig.hosts)); + const target = url.parse(_.head(legacyConfig.hosts) as any); if (!/^https/.test(target.protocol || '')) return new http.Agent(); const agentOptions: https.AgentOptions = {}; diff --git a/src/plugins/console/server/routes/api/console/proxy/create_handler.ts b/src/plugins/console/server/routes/api/console/proxy/create_handler.ts index 272f63322ffaa..a16fb1dadfbcf 100644 --- a/src/plugins/console/server/routes/api/console/proxy/create_handler.ts +++ b/src/plugins/console/server/routes/api/console/proxy/create_handler.ts @@ -19,7 +19,7 @@ import { Agent, IncomingMessage } from 'http'; import * as url from 'url'; -import { pick, trimLeft, trimRight } from 'lodash'; +import { pick, trimStart, trimEnd } from 'lodash'; import { KibanaRequest, Logger, RequestHandler } from 'kibana/server'; @@ -46,7 +46,7 @@ export interface CreateHandlerDependencies { } function toURL(base: string, path: string) { - const urlResult = new url.URL(`${trimRight(base, '/')}/${trimLeft(path, '/')}`); + const urlResult = new url.URL(`${trimEnd(base, '/')}/${trimStart(path, '/')}`); // Appending pretty here to have Elasticsearch do the JSON formatting, as doing // in JS can lead to data loss (7.0 will get munged into 7, thus losing indication of // measurement precision) diff --git a/src/plugins/console/server/services/spec_definitions_service.ts b/src/plugins/console/server/services/spec_definitions_service.ts index ccd3b6b1c0a82..ce990e62a2284 100644 --- a/src/plugins/console/server/services/spec_definitions_service.ts +++ b/src/plugins/console/server/services/spec_definitions_service.ts @@ -55,11 +55,11 @@ export class SpecDefinitionsService { }); if (urlParamsDef) { - description.url_params = _.extend(description.url_params || {}, copiedDescription.url_params); + description.url_params = _.assign(description.url_params || {}, copiedDescription.url_params); _.defaults(description.url_params, urlParamsDef); } - _.extend(copiedDescription, description); + _.assign(copiedDescription, description); _.defaults(copiedDescription, { id: endpoint, patterns: [endpoint], diff --git a/src/plugins/dashboard/public/application/actions/clone_panel_action.tsx b/src/plugins/dashboard/public/application/actions/clone_panel_action.tsx index 96210358c05e4..26af13b4410fe 100644 --- a/src/plugins/dashboard/public/application/actions/clone_panel_action.tsx +++ b/src/plugins/dashboard/public/application/actions/clone_panel_action.tsx @@ -20,6 +20,7 @@ import { i18n } from '@kbn/i18n'; import { CoreStart } from 'src/core/public'; import uuid from 'uuid'; +import _ from 'lodash'; import { ActionByType, IncompatibleActionError } from '../../ui_actions_plugin'; import { ViewMode, PanelState, IEmbeddable } from '../../embeddable_plugin'; import { SavedObject } from '../../../../saved_objects/public'; diff --git a/src/plugins/dashboard/public/application/actions/replace_panel_flyout.tsx b/src/plugins/dashboard/public/application/actions/replace_panel_flyout.tsx index 57fe4acf08145..e4a98ffac7a55 100644 --- a/src/plugins/dashboard/public/application/actions/replace_panel_flyout.tsx +++ b/src/plugins/dashboard/public/application/actions/replace_panel_flyout.tsx @@ -19,6 +19,7 @@ import { i18n } from '@kbn/i18n'; import React from 'react'; +import _ from 'lodash'; import { EuiFlyout, EuiFlyoutBody, EuiFlyoutHeader, EuiTitle } from '@elastic/eui'; import { NotificationsStart, Toast } from 'src/core/public'; import { DashboardPanelState } from '../embeddable'; diff --git a/src/plugins/dashboard/public/application/dashboard_app_controller.tsx b/src/plugins/dashboard/public/application/dashboard_app_controller.tsx index 58477d28f9081..a321bc7959c5c 100644 --- a/src/plugins/dashboard/public/application/dashboard_app_controller.tsx +++ b/src/plugins/dashboard/public/application/dashboard_app_controller.tsx @@ -17,7 +17,7 @@ * under the License. */ -import _, { uniq } from 'lodash'; +import _, { uniqBy } from 'lodash'; import { i18n } from '@kbn/i18n'; import { EUI_MODAL_CANCEL_BUTTON, EuiCheckboxGroup } from '@elastic/eui'; import { EuiCheckboxGroupIdToSelectedMap } from '@elastic/eui/src/components/form/checkbox/checkbox_group'; @@ -265,7 +265,7 @@ export class DashboardAppController { if (!embeddableIndexPatterns) return; panelIndexPatterns.push(...embeddableIndexPatterns); }); - panelIndexPatterns = uniq(panelIndexPatterns, 'id'); + panelIndexPatterns = uniqBy(panelIndexPatterns, 'id'); if (panelIndexPatterns && panelIndexPatterns.length > 0) { $scope.$evalAsync(() => { @@ -520,7 +520,7 @@ export class DashboardAppController { differences.filters = appStateDashboardInput.filters; } - Object.keys(_.omit(containerInput, 'filters')).forEach((key) => { + Object.keys(_.omit(containerInput, ['filters'])).forEach((key) => { const containerValue = (containerInput as { [key: string]: unknown })[key]; const appStateValue = ((appStateDashboardInput as unknown) as { [key: string]: unknown })[ key diff --git a/src/plugins/dashboard/public/application/embeddable/panel/create_panel_state.ts b/src/plugins/dashboard/public/application/embeddable/panel/create_panel_state.ts index 79116a57869d3..a6928c0608bd2 100644 --- a/src/plugins/dashboard/public/application/embeddable/panel/create_panel_state.ts +++ b/src/plugins/dashboard/public/application/embeddable/panel/create_panel_state.ts @@ -17,7 +17,6 @@ * under the License. */ -import _ from 'lodash'; import { PanelState, EmbeddableInput } from '../../../embeddable_plugin'; import { DEFAULT_PANEL_HEIGHT, DEFAULT_PANEL_WIDTH } from '../dashboard_constants'; import { DashboardPanelState } from '../types'; diff --git a/src/plugins/dashboard/public/application/embeddable/panel/dashboard_panel_placement.ts b/src/plugins/dashboard/public/application/embeddable/panel/dashboard_panel_placement.ts index 1b060c186db97..5ecd57d670ae8 100644 --- a/src/plugins/dashboard/public/application/embeddable/panel/dashboard_panel_placement.ts +++ b/src/plugins/dashboard/public/application/embeddable/panel/dashboard_panel_placement.ts @@ -17,6 +17,7 @@ * under the License. */ +import _ from 'lodash'; import { PanelNotFoundError } from '../../../embeddable_plugin'; import { GridData } from '../../../../common'; import { DashboardPanelState, DASHBOARD_GRID_COLUMN_COUNT } from '..'; diff --git a/src/plugins/dashboard/public/application/lib/update_saved_dashboard.ts b/src/plugins/dashboard/public/application/lib/update_saved_dashboard.ts index e3b6725ce7449..72d3ffe6b2322 100644 --- a/src/plugins/dashboard/public/application/lib/update_saved_dashboard.ts +++ b/src/plugins/dashboard/public/application/lib/update_saved_dashboard.ts @@ -47,7 +47,7 @@ export function updateSavedDashboard( 'pause', 'section', 'value', - ]); + ]) as RefreshInterval; savedDashboard.refreshInterval = savedDashboard.timeRestore ? timeRestoreObj : undefined; // save only unpinned filters diff --git a/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts b/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts index 4f7945d6dd601..1e8356a1ef100 100644 --- a/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts +++ b/src/plugins/dashboard/server/saved_objects/dashboard_migrations.ts @@ -111,7 +111,7 @@ export const dashboardSavedObjectTypeMigrations = { * in that version. So we apply this twice, once with 6.7.2 and once with 7.0.1 while the backport to 6.7 * only contained the 6.7.2 migration and not the 7.0.1 migration. */ - '6.7.2': flow>(migrateMatchAllQuery), - '7.0.0': flow>(migrations700), - '7.3.0': flow>(migrations730), + '6.7.2': flow(migrateMatchAllQuery), + '7.0.0': flow(migrations700), + '7.3.0': flow(migrations730), }; diff --git a/src/plugins/dashboard/server/saved_objects/migrate_match_all_query.ts b/src/plugins/dashboard/server/saved_objects/migrate_match_all_query.ts index 75e169b79f320..452d68aa92394 100644 --- a/src/plugins/dashboard/server/saved_objects/migrate_match_all_query.ts +++ b/src/plugins/dashboard/server/saved_objects/migrate_match_all_query.ts @@ -22,7 +22,7 @@ import { get } from 'lodash'; import { DEFAULT_QUERY_LANGUAGE } from '../../../data/common'; export const migrateMatchAllQuery: SavedObjectMigrationFn = (doc) => { - const searchSourceJSON = get(doc, 'attributes.kibanaSavedObjectMeta.searchSourceJSON'); + const searchSourceJSON = get(doc, 'attributes.kibanaSavedObjectMeta.searchSourceJSON'); if (searchSourceJSON) { let searchSource: any; diff --git a/src/plugins/data/common/es_query/es_query/migrate_filter.test.ts b/src/plugins/data/common/es_query/es_query/migrate_filter.test.ts index ae9d1c7921955..261977b859659 100644 --- a/src/plugins/data/common/es_query/es_query/migrate_filter.test.ts +++ b/src/plugins/data/common/es_query/es_query/migrate_filter.test.ts @@ -17,7 +17,7 @@ * under the License. */ -import { isEqual, clone } from 'lodash'; +import { isEqual, cloneDeep } from 'lodash'; import { migrateFilter, DeprecatedMatchPhraseFilter } from './migrate_filter'; import { PhraseFilter, MatchAllFilter } from '../filters'; @@ -52,7 +52,7 @@ describe('migrateFilter', function () { }); it('should not modify the original filter', function () { - const oldMatchPhraseFilterCopy = clone(oldMatchPhraseFilter, true); + const oldMatchPhraseFilterCopy = cloneDeep(oldMatchPhraseFilter); migrateFilter(oldMatchPhraseFilter, undefined); diff --git a/src/plugins/data/common/es_query/filters/index.ts b/src/plugins/data/common/es_query/filters/index.ts index 990d588359442..4441155ad9218 100644 --- a/src/plugins/data/common/es_query/filters/index.ts +++ b/src/plugins/data/common/es_query/filters/index.ts @@ -44,6 +44,6 @@ export * from './types'; * @param {object} filter The filter to clean * @returns {object} */ -export const cleanFilter = (filter: Filter): Filter => omit(filter, ['meta', '$state']); +export const cleanFilter = (filter: Filter): Filter => omit(filter, ['meta', '$state']) as Filter; export const isFilterDisabled = (filter: Filter): boolean => get(filter, 'meta.disabled', false); diff --git a/src/plugins/data/common/es_query/filters/range_filter.ts b/src/plugins/data/common/es_query/filters/range_filter.ts index c318a0f0c2c3d..c355a7397797c 100644 --- a/src/plugins/data/common/es_query/filters/range_filter.ts +++ b/src/plugins/data/common/es_query/filters/range_filter.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { map, reduce, mapValues, get, keys, pick } from 'lodash'; +import { map, reduce, mapValues, get, keys, pickBy } from 'lodash'; import { Filter, FilterMeta } from './meta_filter'; import { IIndexPattern, IFieldType } from '../../index_patterns'; @@ -112,7 +112,7 @@ export const buildRangeFilter = ( filter.meta.formattedValue = formattedValue; } - params = mapValues(params, (value) => (field.type === 'number' ? parseFloat(value) : value)); + params = mapValues(params, (value: any) => (field.type === 'number' ? parseFloat(value) : value)); if ('gte' in params && 'gt' in params) throw new Error('gte and gt are mutually exclusive'); if ('lte' in params && 'lt' in params) throw new Error('lte and lt are mutually exclusive'); @@ -148,7 +148,7 @@ export const buildRangeFilter = ( }; export const getRangeScript = (field: IFieldType, params: RangeFilterParams) => { - const knownParams = pick(params, (val, key: any) => key in operators); + const knownParams = pickBy(params, (val, key: any) => key in operators); let script = map( knownParams, (val: any, key: string) => '(' + field.script + ')' + get(operators, key) + key diff --git a/src/plugins/data/common/es_query/kuery/functions/is.ts b/src/plugins/data/common/es_query/kuery/functions/is.ts index 89aec6e55e81b..404f27b38992c 100644 --- a/src/plugins/data/common/es_query/kuery/functions/is.ts +++ b/src/plugins/data/common/es_query/kuery/functions/is.ts @@ -97,7 +97,7 @@ export function toElasticsearchQuery( }); } - const isExistsQuery = valueArg.type === 'wildcard' && value === '*'; + const isExistsQuery = valueArg.type === 'wildcard' && (value as any) === '*'; const isAllFieldsQuery = (fullFieldNameArg.type === 'wildcard' && ((fieldName as unknown) as string) === '*') || (fields && indexPattern && fields.length === indexPattern.fields.length); @@ -135,7 +135,7 @@ export function toElasticsearchQuery( ...accumulator, { script: { - ...getPhraseScript(field, value), + ...getPhraseScript(field, value as any), }, }, ]; diff --git a/src/plugins/data/common/field_formats/converters/truncate.ts b/src/plugins/data/common/field_formats/converters/truncate.ts index a6c4a1133a2ed..c9ab9df920e16 100644 --- a/src/plugins/data/common/field_formats/converters/truncate.ts +++ b/src/plugins/data/common/field_formats/converters/truncate.ts @@ -18,7 +18,7 @@ */ import { i18n } from '@kbn/i18n'; -import { trunc } from 'lodash'; +import { truncate } from 'lodash'; import { KBN_FIELD_TYPES } from '../../kbn_field_types/types'; import { FieldFormat } from '../field_format'; import { TextContextTypeConvert, FIELD_FORMAT_IDS } from '../types'; @@ -35,7 +35,7 @@ export class TruncateFormat extends FieldFormat { textConvert: TextContextTypeConvert = (val) => { const length = this.param('fieldLength'); if (length > 0) { - return trunc(val, { + return truncate(val, { length: length + omission.length, omission, }); diff --git a/src/plugins/data/common/field_formats/field_format.test.ts b/src/plugins/data/common/field_formats/field_format.test.ts index 2229601994496..2b8f9ad48a34b 100644 --- a/src/plugins/data/common/field_formats/field_format.test.ts +++ b/src/plugins/data/common/field_formats/field_format.test.ts @@ -17,7 +17,7 @@ * under the License. */ -import { constant, trimRight, trimLeft, get } from 'lodash'; +import { constant, trimEnd, trimStart, get } from 'lodash'; import { FieldFormat } from './field_format'; import { asPrettyString } from './utils'; @@ -120,8 +120,8 @@ describe('FieldFormat class', () => { test('does escape the output of the text converter if used in an html context', () => { const f = getTestFormat(undefined, constant('')); - const expected = trimRight( - trimLeft(f.convert('', 'html'), ''), + const expected = trimEnd( + trimStart(f.convert('', 'html'), ''), '' ); diff --git a/src/plugins/data/common/field_formats/field_format.ts b/src/plugins/data/common/field_formats/field_format.ts index 26f07a12067ce..9e4308d6fd559 100644 --- a/src/plugins/data/common/field_formats/field_format.ts +++ b/src/plugins/data/common/field_formats/field_format.ts @@ -185,7 +185,7 @@ export abstract class FieldFormat { const params = transform( this._params, - (uniqParams, val, param) => { + (uniqParams: any, val, param) => { if (param && val !== get(defaultsParams, param)) { uniqParams[param] = val; } diff --git a/src/plugins/data/common/field_formats/field_formats_registry.ts b/src/plugins/data/common/field_formats/field_formats_registry.ts index 9325485bce75d..74a942b51583d 100644 --- a/src/plugins/data/common/field_formats/field_formats_registry.ts +++ b/src/plugins/data/common/field_formats/field_formats_registry.ts @@ -233,7 +233,7 @@ export class FieldFormatsRegistry { parseDefaultTypeMap(value: any) { this.defaultMap = value; forOwn(this, (fn) => { - if (isFunction(fn) && fn.cache) { + if (isFunction(fn) && (fn as any).cache) { // clear all memoize caches // @ts-ignore fn.cache = new memoize.Cache(); diff --git a/src/plugins/data/common/field_mapping/mapping_setup.ts b/src/plugins/data/common/field_mapping/mapping_setup.ts index 99b49b401a8b8..0bad47d9889f0 100644 --- a/src/plugins/data/common/field_mapping/mapping_setup.ts +++ b/src/plugins/data/common/field_mapping/mapping_setup.ts @@ -28,7 +28,7 @@ type ShorthandFieldMapObject = FieldMappingSpec | ES_FIELD_TYPES | 'json'; /** @public */ export const expandShorthand = (sh: Record): MappingObject => { - return mapValues>(sh, (val: ShorthandFieldMapObject) => { + return mapValues(sh, (val: ShorthandFieldMapObject) => { const fieldMap = isString(val) ? { type: val } : val; const json: FieldMappingSpec = { type: ES_FIELD_TYPES.TEXT, diff --git a/src/plugins/data/common/index_patterns/index_patterns/ensure_default_index_pattern.ts b/src/plugins/data/common/index_patterns/index_patterns/ensure_default_index_pattern.ts index 26f1a185ada3a..1702441aa4ca1 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/ensure_default_index_pattern.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/ensure_default_index_pattern.ts @@ -17,7 +17,7 @@ * under the License. */ -import { contains } from 'lodash'; +import { includes } from 'lodash'; import { IndexPatternsContract } from './index_patterns'; import { UiSettingsCommon } from '../types'; @@ -35,7 +35,7 @@ export const createEnsureDefaultIndexPattern = ( const patterns = await this.getIds(); let defaultId = await uiSettings.get('defaultIndex'); let defined = !!defaultId; - const exists = contains(patterns, defaultId); + const exists = includes(patterns, defaultId); if (defined && !exists) { await uiSettings.remove('defaultIndex'); diff --git a/src/plugins/data/common/index_patterns/index_patterns/flatten_hit.ts b/src/plugins/data/common/index_patterns/index_patterns/flatten_hit.ts index c194687b7c3bf..c1aa2efe46998 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/flatten_hit.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/flatten_hit.ts @@ -77,7 +77,7 @@ function decorateFlattenedWrapper(hit: Record, metaFields: Record { const scriptedNames = mockLogStashFields() .filter((item: Field) => item.scripted === true) .map((item: Field) => item.name); - const respNames = pluck(indexPattern.getScriptedFields(), 'name'); + const respNames = map(indexPattern.getScriptedFields(), 'name'); expect(respNames).toEqual(scriptedNames); }); @@ -216,7 +216,7 @@ describe('IndexPattern', () => { const notScriptedNames = mockLogStashFields() .filter((item: Field) => item.scripted === false) .map((item: Field) => item.name); - const respNames = pluck(indexPattern.getNonScriptedFields(), 'name'); + const respNames = map(indexPattern.getNonScriptedFields(), 'name'); expect(respNames).toEqual(notScriptedNames); }); @@ -287,7 +287,7 @@ describe('IndexPattern', () => { // const saveSpy = sinon.spy(indexPattern, 'save'); const scriptedFields = indexPattern.getScriptedFields(); const oldCount = scriptedFields.length; - const scriptedField = last(scriptedFields); + const scriptedField = last(scriptedFields) as any; await indexPattern.removeScriptedField(scriptedField); @@ -298,7 +298,7 @@ describe('IndexPattern', () => { test('should not allow duplicate names', async () => { const scriptedFields = indexPattern.getScriptedFields(); - const scriptedField = last(scriptedFields); + const scriptedField = last(scriptedFields) as any; expect.assertions(1); try { await indexPattern.addScriptedField(scriptedField.name, "'new script'", 'string', 'lang'); diff --git a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts index bde550c660a32..dab11ad0ce29a 100644 --- a/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts +++ b/src/plugins/data/common/index_patterns/index_patterns/index_pattern.ts @@ -353,9 +353,9 @@ export class IndexPattern implements IIndexPattern { async addScriptedField(name: string, script: string, fieldType: string = 'string', lang: string) { const scriptedFields = this.getScriptedFields(); - const names = _.pluck(scriptedFields, 'name'); + const names = _.map(scriptedFields, 'name'); - if (_.contains(names, name)) { + if (_.includes(names, name)) { throw new DuplicateField(name); } @@ -417,11 +417,11 @@ export class IndexPattern implements IIndexPattern { } getNonScriptedFields() { - return _.where(this.fields, { scripted: false }); + return _.filter(this.fields, { scripted: false }); } getScriptedFields() { - return _.where(this.fields, { scripted: true }); + return _.filter(this.fields, { scripted: true }); } isTimeBased(): boolean { diff --git a/src/plugins/data/common/query/filter_manager/compare_filters.ts b/src/plugins/data/common/query/filter_manager/compare_filters.ts index 65df6e26a25b3..be8e9b13e7cff 100644 --- a/src/plugins/data/common/query/filter_manager/compare_filters.ts +++ b/src/plugins/data/common/query/filter_manager/compare_filters.ts @@ -44,7 +44,7 @@ const mapFilter = ( comparators: FilterCompareOptions, excludedAttributes: string[] ) => { - const cleaned: FilterMeta = omit(filter, excludedAttributes); + const cleaned: FilterMeta = omit(filter, excludedAttributes) as FilterMeta; if (comparators.index) cleaned.index = filter.meta?.index; if (comparators.negate) cleaned.negate = filter.meta && Boolean(filter.meta.negate); diff --git a/src/plugins/data/public/index_patterns/saved_objects_client_wrapper.ts b/src/plugins/data/public/index_patterns/saved_objects_client_wrapper.ts index 8f1d02c5ffd54..345dd3b32691e 100644 --- a/src/plugins/data/public/index_patterns/saved_objects_client_wrapper.ts +++ b/src/plugins/data/public/index_patterns/saved_objects_client_wrapper.ts @@ -27,12 +27,11 @@ import { type SOClient = Pick; -const simpleSavedObjectToSavedObject = ( - simpleSavedObject: SimpleSavedObject -): SavedObject => ({ - version: simpleSavedObject._version, - ...omit(simpleSavedObject, '_version'), -}); +const simpleSavedObjectToSavedObject = (simpleSavedObject: SimpleSavedObject): SavedObject => + ({ + version: simpleSavedObject._version, + ...omit(simpleSavedObject, '_version'), + } as any); export class SavedObjectsClientPublicToCommon implements SavedObjectsClientCommon { private savedObjectClient: SOClient; diff --git a/src/plugins/data/public/public.api.md b/src/plugins/data/public/public.api.md index f19611bc1d526..670b40e7d9472 100644 --- a/src/plugins/data/public/public.api.md +++ b/src/plugins/data/public/public.api.md @@ -584,8 +584,8 @@ export abstract class FieldFormat { textConvert: TextContextTypeConvert | undefined; static title: string; toJSON(): { - id: unknown; - params: _.Dictionary | undefined; + id: any; + params: any; }; type: any; } diff --git a/src/plugins/data/public/query/filter_manager/filter_manager.ts b/src/plugins/data/public/query/filter_manager/filter_manager.ts index 60a49a4bd50f4..eaf6ddc9afc35 100644 --- a/src/plugins/data/public/query/filter_manager/filter_manager.ts +++ b/src/plugins/data/public/query/filter_manager/filter_manager.ts @@ -65,7 +65,7 @@ export class FilterManager { } // matching filter in globalState, update global and don't add from appState - _.assign(match.meta, filter.meta); + _.assignIn(match.meta, filter.meta); }); return FilterManager.mergeFilters(cleanedAppFilters, globalFilters); diff --git a/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts b/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts index 432a763bfd48c..723001297e8f2 100644 --- a/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts +++ b/src/plugins/data/public/query/filter_manager/lib/generate_filters.ts @@ -53,7 +53,7 @@ function getExistingFilter( if (isScriptedPhraseFilter(filter)) { return filter.meta.field === fieldName && filter.script!.script.params.value === value; } - }); + }) as any; } function updateExistingFilter(existingFilter: Filter, negate: boolean) { diff --git a/src/plugins/data/public/query/filter_manager/lib/mappers/map_range.ts b/src/plugins/data/public/query/filter_manager/lib/mappers/map_range.ts index d2d5a4b069218..41457a01e0c97 100644 --- a/src/plugins/data/public/query/filter_manager/lib/mappers/map_range.ts +++ b/src/plugins/data/public/query/filter_manager/lib/mappers/map_range.ts @@ -17,7 +17,7 @@ * under the License. */ -import { get, has } from 'lodash'; +import { get, hasIn } from 'lodash'; import { FilterValueFormatter, RangeFilter, @@ -48,10 +48,10 @@ function getParams(filter: RangeFilter) { ? get(filter, 'script.script.params') : getRangeByKey(filter, key); - let left = has(params, 'gte') ? params.gte : params.gt; + let left = hasIn(params, 'gte') ? params.gte : params.gt; if (left == null) left = -Infinity; - let right = has(params, 'lte') ? params.lte : params.lt; + let right = hasIn(params, 'lte') ? params.lte : params.lt; if (right == null) right = Infinity; const value = getFormattedValueFn(left, right); diff --git a/src/plugins/data/public/search/aggs/agg_config.ts b/src/plugins/data/public/search/aggs/agg_config.ts index 8650f5920e520..de49e9ab6f66e 100644 --- a/src/plugins/data/public/search/aggs/agg_config.ts +++ b/src/plugins/data/public/search/aggs/agg_config.ts @@ -271,7 +271,7 @@ export class AggConfig { const outParams = _.transform( this.getAggParams(), - (out, aggParam) => { + (out: any, aggParam) => { let val = params[aggParam.name]; // don't serialize undefined/null values @@ -365,7 +365,7 @@ export class AggConfig { } getAggParams() { - return [...(_.has(this, 'type.params') ? this.type.params : [])]; + return [...(_.hasIn(this, 'type.params') ? this.type.params : [])]; } getRequestAggs() { @@ -438,14 +438,10 @@ export class AggConfig { public set type(type) { if (this.__typeDecorations) { - _.forOwn( - this.__typeDecorations, - function (prop, name: string | undefined) { - // @ts-ignore - delete this[name]; - }, - this - ); + _.forOwn(this.__typeDecorations, (prop, name: string | undefined) => { + // @ts-ignore + delete this[name]; + }); } if (type && _.isFunction(type.decorateAggConfig)) { diff --git a/src/plugins/data/public/search/aggs/agg_configs.test.ts b/src/plugins/data/public/search/aggs/agg_configs.test.ts index 121bb29f6f8ed..f3efeb028665b 100644 --- a/src/plugins/data/public/search/aggs/agg_configs.test.ts +++ b/src/plugins/data/public/search/aggs/agg_configs.test.ts @@ -17,7 +17,7 @@ * under the License. */ -import { indexBy } from 'lodash'; +import { keyBy } from 'lodash'; import { AggConfig } from './agg_config'; import { AggConfigs } from './agg_configs'; import { AggTypesRegistryStart } from './agg_types_registry'; @@ -166,7 +166,7 @@ describe('AggConfigs', () => { const ac = new AggConfigs(indexPattern, configStates, { typesRegistry }); const sorted = ac.getRequestAggs(); - const aggs = indexBy(ac.aggs, (agg) => agg.type.name); + const aggs = keyBy(ac.aggs, (agg) => agg.type.name); expect(sorted.shift()).toBe(aggs.terms); expect(sorted.shift()).toBe(aggs.histogram); @@ -189,7 +189,7 @@ describe('AggConfigs', () => { const ac = new AggConfigs(indexPattern, configStates, { typesRegistry }); const sorted = ac.getResponseAggs(); - const aggs = indexBy(ac.aggs, (agg) => agg.type.name); + const aggs = keyBy(ac.aggs, (agg) => agg.type.name); expect(sorted.shift()).toBe(aggs.terms); expect(sorted.shift()).toBe(aggs.date_histogram); @@ -206,7 +206,7 @@ describe('AggConfigs', () => { const ac = new AggConfigs(indexPattern, configStates, { typesRegistry }); const sorted = ac.getResponseAggs(); - const aggs = indexBy(ac.aggs, (agg) => agg.type.name); + const aggs = keyBy(ac.aggs, (agg) => agg.type.name); expect(sorted.shift()).toBe(aggs.terms); expect(sorted.shift()).toBe(aggs.date_histogram); diff --git a/src/plugins/data/public/search/aggs/buckets/filters.ts b/src/plugins/data/public/search/aggs/buckets/filters.ts index 4052c0b390155..cb17ef07a930b 100644 --- a/src/plugins/data/public/search/aggs/buckets/filters.ts +++ b/src/plugins/data/public/search/aggs/buckets/filters.ts @@ -90,7 +90,7 @@ export const getFiltersBucketAgg = ({ const outFilters = transform( inFilters, - function (filters, filter) { + function (filters: any, filter) { const input = cloneDeep(filter.input); if (!input) { diff --git a/src/plugins/data/public/search/aggs/buckets/ip_range.ts b/src/plugins/data/public/search/aggs/buckets/ip_range.ts index 018fcb365b585..ed9bc5e0462f1 100644 --- a/src/plugins/data/public/search/aggs/buckets/ip_range.ts +++ b/src/plugins/data/public/search/aggs/buckets/ip_range.ts @@ -17,7 +17,7 @@ * under the License. */ -import { noop, map, omit, isNull } from 'lodash'; +import { noop, map, omitBy, isNull } from 'lodash'; import { i18n } from '@kbn/i18n'; import { BucketAggType } from './bucket_agg_type'; import { BUCKET_TYPES } from './bucket_agg_types'; @@ -101,7 +101,7 @@ export const getIpRangeBucketAgg = ({ getInternalStartServices }: IpRangeBucketA let ranges = aggConfig.params.ranges[ipRangeType]; if (ipRangeType === IP_RANGE_TYPES.FROM_TO) { - ranges = map(ranges, (range: any) => omit(range, isNull)); + ranges = map(ranges, (range: any) => omitBy(range, isNull)); } output.params.ranges = ranges; diff --git a/src/plugins/data/public/search/aggs/buckets/lib/time_buckets/time_buckets.ts b/src/plugins/data/public/search/aggs/buckets/lib/time_buckets/time_buckets.ts index 12197c85f4a96..017f646258c01 100644 --- a/src/plugins/data/public/search/aggs/buckets/lib/time_buckets/time_buckets.ts +++ b/src/plugins/data/public/search/aggs/buckets/lib/time_buckets/time_buckets.ts @@ -113,7 +113,7 @@ export class TimeBuckets { bounds = Array.isArray(input) ? input : []; } - const moments: Moment[] = sortBy(bounds, Number); + const moments: Moment[] = sortBy(bounds, Number) as Moment[]; const valid = moments.length === 2 && moments.every(isValidMoment); if (!valid) { diff --git a/src/plugins/data/public/search/aggs/buckets/migrate_include_exclude_format.ts b/src/plugins/data/public/search/aggs/buckets/migrate_include_exclude_format.ts index 47da7e59af5e0..8dc8b786fcfcd 100644 --- a/src/plugins/data/public/search/aggs/buckets/migrate_include_exclude_format.ts +++ b/src/plugins/data/public/search/aggs/buckets/migrate_include_exclude_format.ts @@ -52,7 +52,7 @@ export const migrateIncludeExcludeFormat = { output.params[this.name] = parsedValue; } } else if (isObject(value)) { - output.params[this.name] = value.pattern; + output.params[this.name] = (value as any).pattern; } else if (value && isStringType(aggConfig)) { output.params[this.name] = value; } diff --git a/src/plugins/data/public/search/aggs/metrics/lib/get_response_agg_config_class.ts b/src/plugins/data/public/search/aggs/metrics/lib/get_response_agg_config_class.ts index 00d866e6f2b3e..25d3a3ea90a4a 100644 --- a/src/plugins/data/public/search/aggs/metrics/lib/get_response_agg_config_class.ts +++ b/src/plugins/data/public/search/aggs/metrics/lib/get_response_agg_config_class.ts @@ -17,7 +17,7 @@ * under the License. */ -import { assign } from 'lodash'; +import { assignIn } from 'lodash'; import { IMetricAggConfig } from '../metric_agg_type'; /** @@ -69,7 +69,7 @@ export const create = (parentAgg: IMetricAggConfig, props: Partial + isObject(nsValue) ? {} : nsValue + ); } const esQueryConfigs = getEsQueryConfig(uiSettings); @@ -460,7 +473,7 @@ export class SearchSource { ]); let serializedSearchSourceFields: SearchSourceFields = { ...searchSourceFields, - index: searchSourceFields.index ? searchSourceFields.index.id : undefined, + index: (searchSourceFields.index ? searchSourceFields.index.id : undefined) as any, }; if (originalFilters) { const filters = this.getFilters(originalFilters); diff --git a/src/plugins/data/public/ui/search_bar/create_search_bar.tsx b/src/plugins/data/public/ui/search_bar/create_search_bar.tsx index a0df7604f23aa..f8b7e4f480911 100644 --- a/src/plugins/data/public/ui/search_bar/create_search_bar.tsx +++ b/src/plugins/data/public/ui/search_bar/create_search_bar.tsx @@ -17,6 +17,7 @@ * under the License. */ +import _ from 'lodash'; import React, { useState, useEffect, useRef } from 'react'; import { CoreStart } from 'src/core/public'; import { IStorageWrapper } from 'src/plugins/kibana_utils/public'; diff --git a/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_capabilities.ts b/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_capabilities.ts index 502364cdcba32..b4b86b73a5f4a 100644 --- a/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_capabilities.ts +++ b/src/plugins/data/server/index_patterns/fetcher/lib/field_capabilities/field_capabilities.ts @@ -17,7 +17,7 @@ * under the License. */ -import { defaults, indexBy, sortBy } from 'lodash'; +import { defaults, keyBy, sortBy } from 'lodash'; import { LegacyAPICaller } from 'kibana/server'; import { callFieldCapsApi } from '../es_api'; @@ -44,7 +44,7 @@ export async function getFieldCapabilities( metaFields: string[] = [] ) { const esFieldCaps: FieldCapsResponse = await callFieldCapsApi(callCluster, indices); - const fieldsFromFieldCapsByName = indexBy(readFieldCapsResponse(esFieldCaps), 'name'); + const fieldsFromFieldCapsByName = keyBy(readFieldCapsResponse(esFieldCaps), 'name'); const allFieldsUnsorted = Object.keys(fieldsFromFieldCapsByName) .filter((name) => !name.startsWith('_')) diff --git a/src/plugins/data/server/index_patterns/fetcher/lib/resolve_time_pattern.ts b/src/plugins/data/server/index_patterns/fetcher/lib/resolve_time_pattern.ts index a01d34dbe9df6..2e408d7569be5 100644 --- a/src/plugins/data/server/index_patterns/fetcher/lib/resolve_time_pattern.ts +++ b/src/plugins/data/server/index_patterns/fetcher/lib/resolve_time_pattern.ts @@ -46,7 +46,7 @@ export async function resolveTimePattern(callCluster: LegacyAPICaller, timePatte [] ) .sortBy((indexName: string) => indexName) - .uniq(true) + .sortedUniq() .map((indexName) => { const parsed = moment(indexName, timePattern, true); if (!parsed.isValid()) { @@ -65,7 +65,7 @@ export async function resolveTimePattern(callCluster: LegacyAPICaller, timePatte isMatch: indexName === parsed.format(timePattern), }; }) - .sortByOrder(['valid', 'order'], ['desc', 'desc']) + .orderBy(['valid', 'order'], ['desc', 'desc']) .value(); return { diff --git a/src/plugins/data/server/saved_objects/index_pattern_migrations.ts b/src/plugins/data/server/saved_objects/index_pattern_migrations.ts index 37819a13b6518..768041a376ad1 100644 --- a/src/plugins/data/server/saved_objects/index_pattern_migrations.ts +++ b/src/plugins/data/server/saved_objects/index_pattern_migrations.ts @@ -55,6 +55,6 @@ const migrateSubTypeAndParentFieldProperties: SavedObjectMigrationFn = }; export const indexPatternSavedObjectTypeMigrations = { - '6.5.0': flow(migrateAttributeTypeAndAttributeTypeMeta), - '7.6.0': flow(migrateSubTypeAndParentFieldProperties), + '6.5.0': flow(migrateAttributeTypeAndAttributeTypeMeta), + '7.6.0': flow(migrateSubTypeAndParentFieldProperties), }; diff --git a/src/plugins/data/server/saved_objects/index_patterns.ts b/src/plugins/data/server/saved_objects/index_patterns.ts index 902cf2988f429..44d2813f6e3e8 100644 --- a/src/plugins/data/server/saved_objects/index_patterns.ts +++ b/src/plugins/data/server/saved_objects/index_patterns.ts @@ -54,5 +54,5 @@ export const indexPatternSavedObjectType: SavedObjectsType = { typeMeta: { type: 'keyword' }, }, }, - migrations: indexPatternSavedObjectTypeMigrations, + migrations: indexPatternSavedObjectTypeMigrations as any, }; diff --git a/src/plugins/data/server/saved_objects/search.ts b/src/plugins/data/server/saved_objects/search.ts index 437c83f67bf5d..16caaf05a0fc6 100644 --- a/src/plugins/data/server/saved_objects/search.ts +++ b/src/plugins/data/server/saved_objects/search.ts @@ -56,5 +56,5 @@ export const searchSavedObjectType: SavedObjectsType = { version: { type: 'integer' }, }, }, - migrations: searchSavedObjectTypeMigrations, + migrations: searchSavedObjectTypeMigrations as any, }; diff --git a/src/plugins/data/server/saved_objects/search_migrations.ts b/src/plugins/data/server/saved_objects/search_migrations.ts index 2e37cd1255cee..9bba429f8d71b 100644 --- a/src/plugins/data/server/saved_objects/search_migrations.ts +++ b/src/plugins/data/server/saved_objects/search_migrations.ts @@ -22,7 +22,7 @@ import { SavedObjectMigrationFn } from 'kibana/server'; import { DEFAULT_QUERY_LANGUAGE } from '../../common'; const migrateMatchAllQuery: SavedObjectMigrationFn = (doc) => { - const searchSourceJSON = get(doc, 'attributes.kibanaSavedObjectMeta.searchSourceJSON'); + const searchSourceJSON = get(doc, 'attributes.kibanaSavedObjectMeta.searchSourceJSON'); if (searchSourceJSON) { let searchSource: any; @@ -122,7 +122,7 @@ const migrateSearchSortToNestedArray: SavedObjectMigrationFn = (doc) = }; export const searchSavedObjectTypeMigrations = { - '6.7.2': flow>(migrateMatchAllQuery), - '7.0.0': flow>(setNewReferences), - '7.4.0': flow>(migrateSearchSortToNestedArray), + '6.7.2': flow(migrateMatchAllQuery), + '7.0.0': flow(setNewReferences), + '7.4.0': flow(migrateSearchSortToNestedArray), }; diff --git a/src/plugins/discover/public/application/angular/context/query/actions.js b/src/plugins/discover/public/application/angular/context/query/actions.js index 0e057e0a715c4..32fc2873d7f2a 100644 --- a/src/plugins/discover/public/application/angular/context/query/actions.js +++ b/src/plugins/discover/public/application/angular/context/query/actions.js @@ -70,7 +70,7 @@ export function QueryActionsProvider(Promise) { setLoadingStatus(state)('anchor'); return Promise.try(() => - fetchAnchor(indexPatternId, anchorId, [_.zipObject([sort]), { [tieBreakerField]: sort[1] }]) + fetchAnchor(indexPatternId, anchorId, [_.fromPairs([sort]), { [tieBreakerField]: sort[1] }]) ).then( (anchorDocument) => { setLoadedStatus(state)('anchor'); diff --git a/src/plugins/discover/public/application/components/sidebar/lib/field_calculator.test.ts b/src/plugins/discover/public/application/components/sidebar/lib/field_calculator.test.ts index 875cbf4075aa2..87401818c4907 100644 --- a/src/plugins/discover/public/application/components/sidebar/lib/field_calculator.test.ts +++ b/src/plugins/discover/public/application/components/sidebar/lib/field_calculator.test.ts @@ -186,7 +186,7 @@ describe('fieldCalculator', function () { expect(extensions).toBeInstanceOf(Object); expect(extensions.buckets).toBeInstanceOf(Array); expect(extensions.buckets.length).toBe(3); - expect(_.pluck(extensions.buckets, 'value')).toEqual(['html', 'php', 'gif']); + expect(_.map(extensions.buckets, 'value')).toEqual(['html', 'php', 'gif']); expect(extensions.error).toBe(undefined); }); diff --git a/src/plugins/discover/public/kibana_services.ts b/src/plugins/discover/public/kibana_services.ts index 2c6bbcc3ecce1..ecb5d7fd90283 100644 --- a/src/plugins/discover/public/kibana_services.ts +++ b/src/plugins/discover/public/kibana_services.ts @@ -16,6 +16,8 @@ * specific language governing permissions and limitations * under the License. */ + +import _ from 'lodash'; import { createHashHistory } from 'history'; import { ScopedHistory } from 'kibana/public'; import { DiscoverServices } from './build_services'; diff --git a/src/plugins/es_ui_shared/public/components/cron_editor/cron_editor.js b/src/plugins/es_ui_shared/public/components/cron_editor/cron_editor.js index 18e9ffcb27c56..cde2a253d7630 100644 --- a/src/plugins/es_ui_shared/public/components/cron_editor/cron_editor.js +++ b/src/plugins/es_ui_shared/public/components/cron_editor/cron_editor.js @@ -19,7 +19,7 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; -import { padLeft } from 'lodash'; +import { padStart } from 'lodash'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; @@ -55,12 +55,12 @@ function makeSequence(min, max) { const MINUTE_OPTIONS = makeSequence(0, 59).map((value) => ({ value: value.toString(), - text: padLeft(value, 2, '0'), + text: padStart(value, 2, '0'), })); const HOUR_OPTIONS = makeSequence(0, 23).map((value) => ({ value: value.toString(), - text: padLeft(value, 2, '0'), + text: padStart(value, 2, '0'), })); const DAY_OPTIONS = makeSequence(1, 7).map((value) => ({ diff --git a/src/plugins/expressions/common/expression_functions/specs/kibana_context.ts b/src/plugins/expressions/common/expression_functions/specs/kibana_context.ts index b8be273d7bbd3..2b7d1b8ed9d76 100644 --- a/src/plugins/expressions/common/expression_functions/specs/kibana_context.ts +++ b/src/plugins/expressions/common/expression_functions/specs/kibana_context.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { uniq } from 'lodash'; +import { uniqBy } from 'lodash'; import { i18n } from '@kbn/i18n'; import { ExpressionFunctionDefinition } from '../../expression_functions'; import { KibanaContext } from '../../expression_types'; @@ -40,7 +40,7 @@ const getParsedValue = (data: any, defaultValue: any) => typeof data === 'string' && data.length ? JSON.parse(data) || defaultValue : defaultValue; const mergeQueries = (first: Query | Query[] = [], second: Query | Query[]) => - uniq( + uniqBy( [...(Array.isArray(first) ? first : [first]), ...(Array.isArray(second) ? second : [second])], (n: any) => JSON.stringify(n.query) ); diff --git a/src/plugins/expressions/common/expression_types/specs/datatable.ts b/src/plugins/expressions/common/expression_types/specs/datatable.ts index c113765f8e7e7..5cd53df663e1d 100644 --- a/src/plugins/expressions/common/expression_types/specs/datatable.ts +++ b/src/plugins/expressions/common/expression_types/specs/datatable.ts @@ -20,7 +20,7 @@ import { map, pick, zipObject } from 'lodash'; import { ExpressionTypeDefinition } from '../types'; -import { PointSeries } from './pointseries'; +import { PointSeries, PointSeriesColumn } from './pointseries'; import { ExpressionValueRender } from './render'; const name = 'datatable'; @@ -109,8 +109,8 @@ export const datatable: ExpressionTypeDefinition ({ type: name, rows: value.rows, - columns: map(value.columns, (val, colName) => { - return { name: colName!, type: val.type }; + columns: map(value.columns, (val: PointSeriesColumn, colName) => { + return { name: colName, type: val.type }; }), }), }, diff --git a/src/plugins/expressions/common/expression_types/specs/kibana_datatable.ts b/src/plugins/expressions/common/expression_types/specs/kibana_datatable.ts index 7f2f3c37c587c..e226f3b124eed 100644 --- a/src/plugins/expressions/common/expression_types/specs/kibana_datatable.ts +++ b/src/plugins/expressions/common/expression_types/specs/kibana_datatable.ts @@ -19,7 +19,7 @@ import { map } from 'lodash'; import { SerializedFieldFormat } from '../../types/common'; -import { Datatable, PointSeries } from '.'; +import { Datatable, PointSeries, PointSeriesColumn } from '.'; const name = 'kibana_datatable'; @@ -62,7 +62,7 @@ export const kibanaDatatable = { }; }, pointseries: (context: PointSeries) => { - const columns = map(context.columns, (column, n) => { + const columns = map(context.columns, (column: PointSeriesColumn, n) => { return { id: n, name: n, ...column }; }); return { diff --git a/src/plugins/expressions/public/loader.ts b/src/plugins/expressions/public/loader.ts index 9428d7db1d9d0..f957f10a9aeba 100644 --- a/src/plugins/expressions/public/loader.ts +++ b/src/plugins/expressions/public/loader.ts @@ -19,6 +19,7 @@ import { BehaviorSubject, Observable, Subject } from 'rxjs'; import { filter, map } from 'rxjs/operators'; +import { defaults } from 'lodash'; import { Adapters } from '../../inspector/public'; import { IExpressionLoaderParams } from './types'; import { ExpressionAstExpression } from '../common'; @@ -168,7 +169,7 @@ export class ExpressionLoader { } if (params.searchContext) { - this.params.searchContext = _.defaults( + this.params.searchContext = defaults( {}, params.searchContext, this.params.searchContext || {} diff --git a/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/utils.ts b/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/utils.ts index 52cd5b0c3f5bd..5ab9c695caaa0 100644 --- a/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/utils.ts +++ b/src/plugins/index_pattern_management/public/components/edit_index_pattern/tabs/utils.ts @@ -17,7 +17,7 @@ * under the License. */ -import { Dictionary, countBy, defaults, unique } from 'lodash'; +import { Dictionary, countBy, defaults, uniq } from 'lodash'; import { i18n } from '@kbn/i18n'; import { IndexPattern, IndexPatternField } from '../../../../../../plugins/data/public'; import { IndexPatternManagementStart } from '../../../../../../plugins/index_pattern_management/public'; @@ -145,7 +145,7 @@ export function convertToEuiSelectOption(options: string[], type: string) { ] : []; return euiOptions.concat( - unique(options).map((option) => { + uniq(options).map((option) => { return { value: option, text: option, diff --git a/src/plugins/input_control_vis/public/control/filter_manager/phrase_filter_manager.ts b/src/plugins/input_control_vis/public/control/filter_manager/phrase_filter_manager.ts index 4eff5112c0c07..03ed6c5520dec 100644 --- a/src/plugins/input_control_vis/public/control/filter_manager/phrase_filter_manager.ts +++ b/src/plugins/input_control_vis/public/control/filter_manager/phrase_filter_manager.ts @@ -86,11 +86,11 @@ export class PhraseFilterManager extends FilterManager { private getValueFromFilter(kbnFilter: PhraseFilter): any { // bool filter - multiple phrase filters if (_.has(kbnFilter, 'query.bool.should')) { - return _.get(kbnFilter, 'query.bool.should') - .map((kbnQueryFilter) => { + return _.get(kbnFilter, 'query.bool.should') + .map((kbnQueryFilter: PhraseFilter) => { return this.getValueFromFilter(kbnQueryFilter); }) - .filter((value) => { + .filter((value: any) => { if (value) { return true; } diff --git a/src/plugins/inspector/common/adapters/request/request_adapter.ts b/src/plugins/inspector/common/adapters/request/request_adapter.ts index 70af6b5b51d18..af10d1b77b16d 100644 --- a/src/plugins/inspector/common/adapters/request/request_adapter.ts +++ b/src/plugins/inspector/common/adapters/request/request_adapter.ts @@ -18,7 +18,6 @@ */ import { EventEmitter } from 'events'; -import _ from 'lodash'; import uuid from 'uuid/v4'; import { RequestResponder } from './request_responder'; import { Request, RequestParams, RequestStatus } from './types'; diff --git a/src/plugins/inspector/public/views/data/lib/export_csv.ts b/src/plugins/inspector/public/views/data/lib/export_csv.ts index c0e0153c6053e..5a970cc6cff38 100644 --- a/src/plugins/inspector/public/views/data/lib/export_csv.ts +++ b/src/plugins/inspector/public/views/data/lib/export_csv.ts @@ -29,7 +29,7 @@ const allDoubleQuoteRE = /"/g; function escape(val: string, quoteValues: boolean) { if (isObject(val)) { - val = val.valueOf(); + val = (val as any).valueOf(); } val = String(val); diff --git a/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx b/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx index 87fdf0730c880..2fa1debf51b5c 100644 --- a/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx +++ b/src/plugins/kibana_react/public/table_list_view/table_list_view.tsx @@ -20,7 +20,7 @@ import React from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { debounce, indexBy, sortBy, uniq } from 'lodash'; +import { debounce, keyBy, sortBy, uniq } from 'lodash'; import { EuiTitle, EuiInMemoryTable, @@ -178,7 +178,7 @@ class TableListView extends React.Component itemsById[id])); } catch (error) { this.props.toastNotifications.addDanger({ diff --git a/src/plugins/kibana_utils/common/url/encode_uri_query.ts b/src/plugins/kibana_utils/common/url/encode_uri_query.ts index fb60f0ceff10f..fe8cf12d0d6f2 100644 --- a/src/plugins/kibana_utils/common/url/encode_uri_query.ts +++ b/src/plugins/kibana_utils/common/url/encode_uri_query.ts @@ -45,7 +45,7 @@ export const encodeQuery = ( query: ParsedQuery, encodeFunction: (val: string, pctEncodeSpaces?: boolean) => string = encodeUriQuery ) => - transform(query, (result, value, key) => { + transform(query, (result: any, value, key) => { if (key) { const singleValue = Array.isArray(value) ? value.join(',') : value; diff --git a/src/plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx b/src/plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx index 3a05ce59f5d13..1c5642f9b75b7 100644 --- a/src/plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx +++ b/src/plugins/navigation/public/top_nav_menu/top_nav_menu_item.tsx @@ -17,7 +17,7 @@ * under the License. */ -import { capitalize, isFunction } from 'lodash'; +import { upperFirst, isFunction } from 'lodash'; import React, { MouseEvent } from 'react'; import { EuiButtonEmpty, EuiToolTip } from '@elastic/eui'; @@ -50,11 +50,11 @@ export function TopNavMenuItem(props: TopNavMenuData) { const btn = props.emphasize ? ( - {capitalize(props.label || props.id!)} + {upperFirst(props.label || props.id!)} ) : ( - {capitalize(props.label || props.id!)} + {upperFirst(props.label || props.id!)} ); diff --git a/src/plugins/saved_objects_management/public/lib/create_field_list.ts b/src/plugins/saved_objects_management/public/lib/create_field_list.ts index 5f424751dd58e..dcfb44d8a5224 100644 --- a/src/plugins/saved_objects_management/public/lib/create_field_list.ts +++ b/src/plugins/saved_objects_management/public/lib/create_field_list.ts @@ -17,7 +17,7 @@ * under the License. */ -import { forOwn, indexBy, isNumber, isBoolean, isPlainObject, isString } from 'lodash'; +import { forOwn, keyBy, isNumber, isBoolean, isPlainObject, isString } from 'lodash'; import { SimpleSavedObject } from '../../../../core/public'; import { castEsToKbnFieldTypeName } from '../../../data/public'; import { ObjectField } from '../management_section/types'; @@ -93,9 +93,9 @@ const addFieldsFromClass = function ( Class: { mapping: Record; searchSource: any }, fields: ObjectField[] ) { - const fieldMap = indexBy(fields, 'name'); + const fieldMap = keyBy(fields, 'name'); - _.forOwn(Class.mapping, (esType, name) => { + forOwn(Class.mapping, (esType, name) => { if (!name || fieldMap[name]) { return; } diff --git a/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx b/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx index 75692777f08bb..dbbea4012aba9 100644 --- a/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx +++ b/src/plugins/saved_objects_management/public/management_section/saved_objects_table_page.tsx @@ -78,7 +78,7 @@ const SavedObjectsTablePage = ({ }} canGoInApp={(savedObject) => { const { inAppUrl } = savedObject.meta; - return inAppUrl ? get(capabilities, inAppUrl.uiCapabilitiesPath) : false; + return inAppUrl ? Boolean(get(capabilities, inAppUrl.uiCapabilitiesPath)) : false; }} /> ); diff --git a/src/plugins/vis_default_editor/public/components/agg_params_helper.ts b/src/plugins/vis_default_editor/public/components/agg_params_helper.ts index 39abddb3de853..ef2f937c8547c 100644 --- a/src/plugins/vis_default_editor/public/components/agg_params_helper.ts +++ b/src/plugins/vis_default_editor/public/components/agg_params_helper.ts @@ -87,7 +87,7 @@ function getAggParamsToRender({ // should be refactored in the future to provide a more general way // for visualization to override some agg config settings if (agg.type.name === 'top_hits' && param.name === 'field') { - const allowStrings = _.get(schema, `aggSettings[${agg.type.name}].allowStrings`, false); + const allowStrings = get(schema, `aggSettings[${agg.type.name}].allowStrings`, false); if (!allowStrings) { availableFields = availableFields.filter((field) => field.type === 'number'); } diff --git a/src/plugins/vis_default_editor/public/components/controls/components/input_list.tsx b/src/plugins/vis_default_editor/public/components/controls/components/input_list.tsx index a0bc0d78a2889..37e95f2419b45 100644 --- a/src/plugins/vis_default_editor/public/components/controls/components/input_list.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/components/input_list.tsx @@ -18,7 +18,7 @@ */ import React, { useState, useEffect, Fragment, useCallback } from 'react'; -import { isEmpty, isEqual, mapValues, omit, pick } from 'lodash'; +import { isEmpty, isEqual, mapValues, omitBy, pick } from 'lodash'; import { EuiButtonIcon, EuiFlexGroup, @@ -173,7 +173,7 @@ function InputList({ config, list, onChange, setValidity }: InputListProps) { const model: InputObject = mapValues(pick(models[index], modelNames), 'model'); // we need to skip empty values since they are not stored in saved object - return !isEqual(item, omit(model, isEmpty)); + return !isEqual(item, omitBy(model, isEmpty)); }) ) { setModels( diff --git a/src/plugins/vis_default_editor/public/components/controls/components/number_list/utils.ts b/src/plugins/vis_default_editor/public/components/controls/components/number_list/utils.ts index 6eaef3050029a..a3998cbd5954b 100644 --- a/src/plugins/vis_default_editor/public/components/controls/components/number_list/utils.ts +++ b/src/plugins/vis_default_editor/public/components/controls/components/number_list/utils.ts @@ -105,7 +105,7 @@ function validateValueUnique( } function getNextModel(list: NumberRowModel[], range: NumberListRange): NumberRowModel { - const lastValue = last(list).value; + const lastValue = (last(list) as NumberRowModel).value; let next = Number(lastValue) ? Number(lastValue) + 1 : 1; if (next >= range.max) { diff --git a/src/plugins/vis_default_editor/public/components/controls/filters.tsx b/src/plugins/vis_default_editor/public/components/controls/filters.tsx index 9a9933b5e1e83..04d0df27927fa 100644 --- a/src/plugins/vis_default_editor/public/components/controls/filters.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/filters.tsx @@ -43,7 +43,9 @@ function FiltersParamEditor({ agg, value = [], setValue }: AggParamEditorProps { // set parsed values into model after initialization - setValue(filters.map((filter) => omit({ ...filter, input: filter.input }, 'id'))); + setValue( + filters.map((filter) => omit({ ...filter, input: filter.input }, 'id') as FilterValue) + ); }); useEffect(() => { @@ -58,7 +60,7 @@ function FiltersParamEditor({ agg, value = [], setValue }: AggParamEditorProps { // do not set internal id parameter into saved object - setValue(updatedFilters.map((filter) => omit(filter, 'id'))); + setValue(updatedFilters.map((filter) => omit(filter, 'id') as FilterValue)); setFilters(updatedFilters); }; diff --git a/src/plugins/vis_default_editor/public/components/controls/number_interval.tsx b/src/plugins/vis_default_editor/public/components/controls/number_interval.tsx index 0d21eb04c12b2..f6354027ab01b 100644 --- a/src/plugins/vis_default_editor/public/components/controls/number_interval.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/number_interval.tsx @@ -56,7 +56,7 @@ function NumberIntervalParamEditor({ setValidity, setValue, }: AggParamEditorProps) { - const base: number = get(editorConfig, 'interval.base'); + const base: number = get(editorConfig, 'interval.base') as number; const min = base || 0; const isValid = value !== undefined && value >= min; diff --git a/src/plugins/vis_default_editor/public/components/controls/time_interval.tsx b/src/plugins/vis_default_editor/public/components/controls/time_interval.tsx index 4af41f67bc524..dd9e432fa512e 100644 --- a/src/plugins/vis_default_editor/public/components/controls/time_interval.tsx +++ b/src/plugins/vis_default_editor/public/components/controls/time_interval.tsx @@ -107,7 +107,7 @@ function TimeIntervalParamEditor({ setTouched, setValidity, }: AggParamEditorProps) { - const timeBase: string = get(editorConfig, 'interval.timeBase'); + const timeBase: string = get(editorConfig, 'interval.timeBase') as string; const options = timeBase ? [] : ((aggParam as any).options || []).reduce( diff --git a/src/plugins/vis_default_editor/public/components/sidebar/data_tab.tsx b/src/plugins/vis_default_editor/public/components/sidebar/data_tab.tsx index 26567d05e0427..b2c7bcafa15a3 100644 --- a/src/plugins/vis_default_editor/public/components/sidebar/data_tab.tsx +++ b/src/plugins/vis_default_editor/public/components/sidebar/data_tab.tsx @@ -74,7 +74,8 @@ function DefaultEditorDataTab({ ), [metricAggs] ); - const lastParentPipelineAggTitle = lastParentPipelineAgg && lastParentPipelineAgg.type.title; + const lastParentPipelineAggTitle = + lastParentPipelineAgg && (lastParentPipelineAgg as IAggConfig).type.title; const addSchema: AddSchema = useCallback((schema) => dispatch(addNewAgg(schema)), [dispatch]); @@ -116,7 +117,7 @@ function DefaultEditorDataTab({ setValidity, setTouched, removeAgg: onAggRemove, - }; + } as any; return ( <> diff --git a/src/plugins/vis_default_editor/public/schemas.ts b/src/plugins/vis_default_editor/public/schemas.ts index 54520b85cb5ec..d95a6252331bf 100644 --- a/src/plugins/vis_default_editor/public/schemas.ts +++ b/src/plugins/vis_default_editor/public/schemas.ts @@ -58,6 +58,7 @@ export class Schemas implements ISchemas { > ) { _(schemas || []) + .chain() .map((schema) => { if (!schema.name) throw new Error('all schema must have a unique name'); diff --git a/src/plugins/vis_type_metric/public/components/metric_vis_component.tsx b/src/plugins/vis_type_metric/public/components/metric_vis_component.tsx index 5e8a463748188..4385826762612 100644 --- a/src/plugins/vis_type_metric/public/components/metric_vis_component.tsx +++ b/src/plugins/vis_type_metric/public/components/metric_vis_component.tsx @@ -28,6 +28,7 @@ import { getHeatmapColors } from '../../../charts/public'; import { VisParams, MetricVisMetric } from '../types'; import { getFormatService } from '../services'; import { SchemaConfig, ExprVis } from '../../../visualizations/public'; +import { Range } from '../../../expressions/public'; export interface MetricVisComponentProps { visParams: VisParams; @@ -41,7 +42,7 @@ export class MetricVisComponent extends Component { const config = this.props.visParams.metric; const isPercentageMode = config.percentageMode; const colorsRange = config.colorsRange; - const max = last(colorsRange).to; + const max = (last(colorsRange) as Range).to; const labels: string[] = []; colorsRange.forEach((range: any) => { @@ -111,7 +112,7 @@ export class MetricVisComponent extends Component { const dimensions = this.props.visParams.dimensions; const isPercentageMode = config.percentageMode; const min = config.colorsRange[0].from; - const max = last(config.colorsRange).to; + const max = (last(config.colorsRange) as Range).to; const colors = this.getColors(); const labels = this.getLabels(); const metrics: MetricVisMetric[] = []; diff --git a/src/plugins/vis_type_timelion/public/helpers/panel_utils.ts b/src/plugins/vis_type_timelion/public/helpers/panel_utils.ts index db29d9112be8e..860b4e9f2dbde 100644 --- a/src/plugins/vis_type_timelion/public/helpers/panel_utils.ts +++ b/src/plugins/vis_type_timelion/public/helpers/panel_utils.ts @@ -17,7 +17,7 @@ * under the License. */ -import { cloneDeep, defaults, merge, compact } from 'lodash'; +import { cloneDeep, defaults, mergeWith, compact } from 'lodash'; import moment, { Moment } from 'moment-timezone'; import { TimefilterContract } from 'src/plugins/data/public'; @@ -91,7 +91,7 @@ function buildSeriesData(chart: Series[], options: jquery.flot.plotOptions) { } if (series._global) { - merge(options, series._global, (objVal, srcVal) => { + mergeWith(options, series._global, (objVal, srcVal) => { // This is kind of gross, it means that you can't replace a global value with a null // best you can do is an empty string. Deal with it. if (objVal == null) { diff --git a/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts b/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts index c02f43818af9c..7be18a4774d94 100644 --- a/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts +++ b/src/plugins/vis_type_timelion/public/timelion_vis_fn.ts @@ -27,6 +27,7 @@ import { import { getTimelionRequestHandler } from './helpers/timelion_request_handler'; import { TIMELION_VIS_NAME } from './timelion_vis_type'; import { TimelionVisDependencies } from './plugin'; +import { Filter, Query, TimeRange } from '../../data/common'; type Input = KibanaContext | null; type Output = Promise>; @@ -71,9 +72,9 @@ export const getTimelionVisualizationConfig = ( const visParams = { expression: args.expression, interval: args.interval }; const response = await timelionRequestHandler({ - timeRange: get(input, 'timeRange'), - query: get(input, 'query'), - filters: get(input, 'filters'), + timeRange: get(input, 'timeRange') as TimeRange, + query: get(input, 'query') as Query, + filters: get(input, 'filters') as Filter[], visParams, forceFetch: true, }); diff --git a/src/plugins/vis_type_timelion/server/fit_functions/average.js b/src/plugins/vis_type_timelion/server/fit_functions/average.js index 06db7bd0e9324..09518a3286487 100644 --- a/src/plugins/vis_type_timelion/server/fit_functions/average.js +++ b/src/plugins/vis_type_timelion/server/fit_functions/average.js @@ -27,7 +27,7 @@ export default function average(dataTuples, targetTuples) { // Phase 1: Downsample // We necessarily won't well match the dataSource here as we don't know how much data // they had when creating their own average - const resultTimes = _.pluck(targetTuples, 0); + const resultTimes = _.map(targetTuples, 0); const dataTuplesQueue = _.clone(dataTuples); const resultValues = _.map(targetTuples, function (bucket) { const time = bucket[0]; diff --git a/src/plugins/vis_type_timelion/server/handlers/chain_runner.js b/src/plugins/vis_type_timelion/server/handlers/chain_runner.js index 59adea30730c7..2ee8deb4dd049 100644 --- a/src/plugins/vis_type_timelion/server/handlers/chain_runner.js +++ b/src/plugins/vis_type_timelion/server/handlers/chain_runner.js @@ -132,7 +132,7 @@ export default function chainRunner(tlConfig) { }); }); return Bluebird.all(seriesList).then(function (args) { - const list = _.chain(args).pluck('list').flatten().value(); + const list = _.chain(args).map('list').flatten().value(); const seriesList = _.merge.apply(this, _.flatten([{}, args])); seriesList.list = list; return seriesList; diff --git a/src/plugins/vis_type_timelion/server/handlers/lib/validate_arg.js b/src/plugins/vis_type_timelion/server/handlers/lib/validate_arg.js index 9b4fdddc2186e..11004d2784d3c 100644 --- a/src/plugins/vis_type_timelion/server/handlers/lib/validate_arg.js +++ b/src/plugins/vis_type_timelion/server/handlers/lib/validate_arg.js @@ -28,7 +28,7 @@ export default function validateArgFn(functionDef) { const multi = argDef.multi; const isCorrectType = (function () { // If argument is not allow to be specified multiple times, we're dealing with a plain value for type - if (!multi) return _.contains(required, type); + if (!multi) return _.includes(required, type); // If it is, we'll get an array for type return _.difference(type, required).length === 0; })(); diff --git a/src/plugins/vis_type_timelion/server/lib/as_sorted.js b/src/plugins/vis_type_timelion/server/lib/as_sorted.js index 536145a6b8dcd..6a2b7c0f5a9f5 100644 --- a/src/plugins/vis_type_timelion/server/lib/as_sorted.js +++ b/src/plugins/vis_type_timelion/server/lib/as_sorted.js @@ -22,5 +22,5 @@ import unzipPairs from './unzip_pairs.js'; export default function asSorted(timeValObject, fn) { const data = unzipPairs(timeValObject); - return _.zipObject(fn(data)); + return _.fromPairs(fn(data)); } diff --git a/src/plugins/vis_type_timelion/server/lib/classes/timelion_function.js b/src/plugins/vis_type_timelion/server/lib/classes/timelion_function.js index 83466e263cf2f..3d53fc8d5bd09 100644 --- a/src/plugins/vis_type_timelion/server/lib/classes/timelion_function.js +++ b/src/plugins/vis_type_timelion/server/lib/classes/timelion_function.js @@ -25,7 +25,7 @@ export default class TimelionFunction { constructor(name, config) { this.name = name; this.args = config.args || []; - this.argsByName = _.indexBy(this.args, 'name'); + this.argsByName = _.keyBy(this.args, 'name'); this.help = config.help || ''; this.aliases = config.aliases || []; this.extended = config.extended || false; diff --git a/src/plugins/vis_type_timelion/server/lib/load_functions.js b/src/plugins/vis_type_timelion/server/lib/load_functions.js index d6cb63b7c427b..699342cff6a79 100644 --- a/src/plugins/vis_type_timelion/server/lib/load_functions.js +++ b/src/plugins/vis_type_timelion/server/lib/load_functions.js @@ -47,7 +47,7 @@ export default function (directory) { }) .value(); - const functions = _.zipObject(files.concat(directories)); + const functions = _.fromPairs(files.concat(directories)); _.each(functions, function (func) { _.assign(functions, processFunctionDefinition(func)); diff --git a/src/plugins/vis_type_timelion/server/lib/reduce.js b/src/plugins/vis_type_timelion/server/lib/reduce.js index cc13b75fde12d..1a5d78676fc72 100644 --- a/src/plugins/vis_type_timelion/server/lib/reduce.js +++ b/src/plugins/vis_type_timelion/server/lib/reduce.js @@ -42,7 +42,7 @@ async function pairwiseReduce(left, right, fn) { if (allSeriesContainKey(left, 'split') && allSeriesContainKey(right, 'split')) { pairwiseField = 'split'; } - const indexedList = _.indexBy(right.list, pairwiseField); + const indexedList = _.keyBy(right.list, pairwiseField); // ensure seriesLists contain same pairwise labels left.list.forEach((leftSeries) => { diff --git a/src/plugins/vis_type_timelion/server/lib/unzip_pairs.js b/src/plugins/vis_type_timelion/server/lib/unzip_pairs.js index 7a34b5ec98ff0..412049c89ef2f 100644 --- a/src/plugins/vis_type_timelion/server/lib/unzip_pairs.js +++ b/src/plugins/vis_type_timelion/server/lib/unzip_pairs.js @@ -21,7 +21,7 @@ import _ from 'lodash'; export default function unzipPairs(timeValObject) { const paired = _.chain(timeValObject) - .pairs() + .toPairs() .map(function (point) { return [parseInt(point[0], 10), point[1]]; }) diff --git a/src/plugins/vis_type_timelion/server/series_functions/es/lib/agg_response_to_series_list.js b/src/plugins/vis_type_timelion/server/series_functions/es/lib/agg_response_to_series_list.js index 409372da24724..fbae9c5afffe8 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/es/lib/agg_response_to_series_list.js +++ b/src/plugins/vis_type_timelion/server/series_functions/es/lib/agg_response_to_series_list.js @@ -20,7 +20,7 @@ import _ from 'lodash'; export function timeBucketsToPairs(buckets) { - const timestamps = _.pluck(buckets, 'key'); + const timestamps = _.map(buckets, 'key'); const series = {}; _.each(buckets, function (bucket) { _.forOwn(bucket, function (val, key) { diff --git a/src/plugins/vis_type_timelion/server/series_functions/es/lib/build_request.js b/src/plugins/vis_type_timelion/server/series_functions/es/lib/build_request.js index bc0e368fbdab1..e407636c41567 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/es/lib/build_request.js +++ b/src/plugins/vis_type_timelion/server/series_functions/es/lib/build_request.js @@ -50,7 +50,7 @@ export default function buildRequest(config, tlConfig, scriptedFields, timeout) .map(function (q) { return [q, { query_string: { query: q } }]; }) - .zipObject() + .fromPairs() .value(), }, aggs: {}, diff --git a/src/plugins/vis_type_timelion/server/series_functions/movingaverage.js b/src/plugins/vis_type_timelion/server/series_functions/movingaverage.js index 108eb0c72f19d..fdaa4dcd8c098 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/movingaverage.js +++ b/src/plugins/vis_type_timelion/server/series_functions/movingaverage.js @@ -81,7 +81,7 @@ export default new Chainable('movingaverage', { } _position = _position || defaultPosition; - if (!_.contains(validPositions, _position)) { + if (!_.includes(validPositions, _position)) { throw new Error( i18n.translate( 'timelion.serverSideErrors.movingaverageFunction.notValidPositionErrorMessage', diff --git a/src/plugins/vis_type_timelion/server/series_functions/movingstd.js b/src/plugins/vis_type_timelion/server/series_functions/movingstd.js index a7ecb4d5b4738..2b9ab08f02ede 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/movingstd.js +++ b/src/plugins/vis_type_timelion/server/series_functions/movingstd.js @@ -61,7 +61,7 @@ export default new Chainable('movingstd', { return alter(args, function (eachSeries, _window, _position) { _position = _position || defaultPosition; - if (!_.contains(positions, _position)) { + if (!_.includes(positions, _position)) { throw new Error( i18n.translate( 'timelion.serverSideErrors.movingstdFunction.notValidPositionErrorMessage', diff --git a/src/plugins/vis_type_timelion/server/series_functions/points.js b/src/plugins/vis_type_timelion/server/series_functions/points.js index bf797bb5aa343..74d616cffd52d 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/points.js +++ b/src/plugins/vis_type_timelion/server/series_functions/points.js @@ -105,7 +105,7 @@ export default new Chainable('points', { } symbol = symbol || defaultSymbol; - if (!_.contains(validSymbols, symbol)) { + if (!_.includes(validSymbols, symbol)) { throw new Error( i18n.translate('timelion.serverSideErrors.pointsFunction.notValidSymbolErrorMessage', { defaultMessage: 'Valid symbols are: {validSymbols}', diff --git a/src/plugins/vis_type_timelion/server/series_functions/static.test.js b/src/plugins/vis_type_timelion/server/series_functions/static.test.js index 88ec9fecd904a..36c5dc708f860 100644 --- a/src/plugins/vis_type_timelion/server/series_functions/static.test.js +++ b/src/plugins/vis_type_timelion/server/series_functions/static.test.js @@ -26,7 +26,7 @@ import invoke from './helpers/invoke_series_fn.js'; describe('static.js', () => { it('returns a series in which all numbers are the same', () => { return invoke(fn, [5]).then((r) => { - expect(_.unique(_.map(r.output.list[0].data, 1))).to.eql([5]); + expect(_.uniq(_.map(r.output.list[0].data, 1))).to.eql([5]); }); }); diff --git a/src/plugins/vis_type_timeseries/public/application/components/aggs/agg_row.tsx b/src/plugins/vis_type_timeseries/public/application/components/aggs/agg_row.tsx index 0363ba486a775..fcb22a9e79707 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/aggs/agg_row.tsx +++ b/src/plugins/vis_type_timeseries/public/application/components/aggs/agg_row.tsx @@ -39,7 +39,7 @@ interface AggRowProps { export function AggRow(props: AggRowProps) { let iconType = 'eyeClosed'; let iconColor = 'subdued'; - const lastSibling = last(props.siblings); + const lastSibling = last(props.siblings) as MetricsItemsSchema; if (lastSibling.id === props.model.id) { iconType = 'eye'; diff --git a/src/plugins/vis_type_timeseries/public/application/components/lib/series_change_handler.js b/src/plugins/vis_type_timeseries/public/application/components/lib/series_change_handler.js index beb691f4b7117..0638c6e67f5ef 100644 --- a/src/plugins/vis_type_timeseries/public/application/components/lib/series_change_handler.js +++ b/src/plugins/vis_type_timeseries/public/application/components/lib/series_change_handler.js @@ -31,7 +31,7 @@ export const seriesChangeHandler = (props, items) => (doc) => { const metric = newMetricAggFn(); metric.type = doc.type; const incompatPipelines = ['calculation', 'series_agg']; - if (!_.contains(incompatPipelines, doc.type)) metric.field = doc.id; + if (!_.includes(incompatPipelines, doc.type)) metric.field = doc.id; return metric; }); } else { diff --git a/src/plugins/vis_type_timeseries/server/lib/get_fields.ts b/src/plugins/vis_type_timeseries/server/lib/get_fields.ts index fd20ff8b024b3..0f0d99bff6f1c 100644 --- a/src/plugins/vis_type_timeseries/server/lib/get_fields.ts +++ b/src/plugins/vis_type_timeseries/server/lib/get_fields.ts @@ -16,7 +16,7 @@ * specific language governing permissions and limitations * under the License. */ -import { uniq } from 'lodash'; +import { uniqBy } from 'lodash'; import { first, map } from 'rxjs/operators'; import { KibanaRequest, RequestHandlerContext } from 'kibana/server'; @@ -87,5 +87,5 @@ export async function getFields( (field) => field.aggregatable && !indexPatterns.isNestedField(field) ); - return uniq(fields, (field) => field.name); + return uniqBy(fields, (field) => field.name); } diff --git a/src/plugins/vis_type_timeseries/server/saved_objects/tsvb_telemetry.ts b/src/plugins/vis_type_timeseries/server/saved_objects/tsvb_telemetry.ts index f6754e5fd9ca4..a9b542af68c9d 100644 --- a/src/plugins/vis_type_timeseries/server/saved_objects/tsvb_telemetry.ts +++ b/src/plugins/vis_type_timeseries/server/saved_objects/tsvb_telemetry.ts @@ -40,7 +40,7 @@ export const tsvbTelemetrySavedObjectType: SavedObjectsType = { }, }, migrations: { - '7.7.0': flow(resetCount), - '7.8.0': flow(resetCount), + '7.7.0': flow(resetCount), + '7.8.0': flow(resetCount), }, }; diff --git a/src/plugins/vis_type_vega/public/vega_fn.ts b/src/plugins/vis_type_vega/public/vega_fn.ts index a9c915fcfb636..6b1af6044a2c4 100644 --- a/src/plugins/vis_type_vega/public/vega_fn.ts +++ b/src/plugins/vis_type_vega/public/vega_fn.ts @@ -22,6 +22,7 @@ import { i18n } from '@kbn/i18n'; import { ExpressionFunctionDefinition, KibanaContext, Render } from '../../expressions/public'; import { VegaVisualizationDependencies } from './plugin'; import { createVegaRequestHandler } from './vega_request_handler'; +import { TimeRange, Query } from '../../data/public'; type Input = KibanaContext | null; type Output = Promise>; @@ -58,9 +59,9 @@ export const createVegaFn = ( const vegaRequestHandler = createVegaRequestHandler(dependencies, context.abortSignal); const response = await vegaRequestHandler({ - timeRange: get(input, 'timeRange'), - query: get(input, 'query'), - filters: get(input, 'filters'), + timeRange: get(input, 'timeRange') as TimeRange, + query: get(input, 'query') as Query, + filters: get(input, 'filters') as any, visParams: { spec: args.spec }, }); diff --git a/src/plugins/vis_type_vislib/public/components/options/metrics_axes/utils.ts b/src/plugins/vis_type_vislib/public/components/options/metrics_axes/utils.ts index 7c4f3b3ec8843..708e8cf15f029 100644 --- a/src/plugins/vis_type_vislib/public/components/options/metrics_axes/utils.ts +++ b/src/plugins/vis_type_vislib/public/components/options/metrics_axes/utils.ts @@ -17,7 +17,7 @@ * under the License. */ -import { capitalize } from 'lodash'; +import { upperFirst } from 'lodash'; import { BasicVislibParams, ValueAxis, SeriesParam } from '../../../types'; import { ChartModes, ChartTypes, InterpolationModes, Positions } from '../../../utils/collections'; @@ -67,7 +67,7 @@ const getUpdatedAxisName = ( axisPosition: ValueAxis['position'], valueAxes: BasicVislibParams['valueAxes'] ) => { - const axisName = capitalize(axisPosition) + AXIS_PREFIX; + const axisName = upperFirst(axisPosition) + AXIS_PREFIX; const nextAxisNameNumber = valueAxes.reduce(countNextAxisNumber(axisName, 'name'), 1); return `${axisName}${nextAxisNameNumber}`; diff --git a/src/plugins/vis_type_vislib/public/vislib/components/labels/flatten_series.js b/src/plugins/vis_type_vislib/public/vislib/components/labels/flatten_series.js index 87477332f76e5..4d4660371eaa4 100644 --- a/src/plugins/vis_type_vislib/public/vislib/components/labels/flatten_series.js +++ b/src/plugins/vis_type_vislib/public/vislib/components/labels/flatten_series.js @@ -30,5 +30,5 @@ export function flattenSeries(obj) { obj = obj.rows ? obj.rows : obj.columns; - return _.chain(obj).pluck('series').flattenDeep().value(); + return _.chain(obj).map('series').flattenDeep().value(); } diff --git a/src/plugins/vis_type_vislib/public/vislib/components/labels/labels.test.js b/src/plugins/vis_type_vislib/public/vislib/components/labels/labels.test.js index 5e78637ef0c02..f04d9d17eeccb 100644 --- a/src/plugins/vis_type_vislib/public/vislib/components/labels/labels.test.js +++ b/src/plugins/vis_type_vislib/public/vislib/components/labels/labels.test.js @@ -166,9 +166,9 @@ describe('Vislib Labels Module Test Suite', function () { seriesArr = Array.isArray(seriesLabels); rowsArr = Array.isArray(rowsLabels); uniqSeriesLabels = _.chain(rowsData.rows) - .pluck('series') + .map('series') .flattenDeep() - .pluck('label') + .map('label') .uniq() .value(); }); diff --git a/src/plugins/vis_type_vislib/public/vislib/components/labels/uniq_labels.js b/src/plugins/vis_type_vislib/public/vislib/components/labels/uniq_labels.js index 489cb81306b3d..cf98425c04ce7 100644 --- a/src/plugins/vis_type_vislib/public/vislib/components/labels/uniq_labels.js +++ b/src/plugins/vis_type_vislib/public/vislib/components/labels/uniq_labels.js @@ -28,5 +28,5 @@ export function uniqLabels(arr) { throw new TypeError('UniqLabelUtil expects an array of objects'); } - return _(arr).pluck('label').unique().value(); + return _(arr).map('label').uniq().value(); } diff --git a/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.tsx b/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.tsx index a2fe4d9249bd0..f7e44ed278787 100644 --- a/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.tsx +++ b/src/plugins/vis_type_vislib/public/vislib/components/legend/legend.tsx @@ -18,7 +18,7 @@ */ import React, { BaseSyntheticEvent, KeyboardEvent, PureComponent } from 'react'; import classNames from 'classnames'; -import { compact, uniq, map, every, isUndefined } from 'lodash'; +import { compact, uniqBy, map, every, isUndefined } from 'lodash'; import { i18n } from '@kbn/i18n'; import { EuiPopoverProps, EuiIcon, keyCodes, htmlIdGenerator } from '@elastic/eui'; @@ -119,7 +119,7 @@ export class VisLegend extends PureComponent { getSeriesLabels = (data: any[]) => { const values = data.map((chart) => chart.series).reduce((a, b) => a.concat(b), []); - return compact(uniq(values, 'label')).map((label: any) => ({ + return compact(uniqBy(values, 'label')).map((label: any) => ({ ...label, values: [label.values[0].seriesRaw], })); diff --git a/src/plugins/vis_type_vislib/public/vislib/components/legend/pie_utils.ts b/src/plugins/vis_type_vislib/public/vislib/components/legend/pie_utils.ts index 6b507862fb841..da046af83a495 100644 --- a/src/plugins/vis_type_vislib/public/vislib/components/legend/pie_utils.ts +++ b/src/plugins/vis_type_vislib/public/vislib/components/legend/pie_utils.ts @@ -39,7 +39,7 @@ export function getPieNames(data: any[]): string[] { }); }); - return _.uniq(names, 'label'); + return _.uniqBy(names, 'label'); } /** @@ -61,7 +61,7 @@ function getNames(data: any, columns: any): string[] { .sortBy(function (obj) { return obj.index; }) - .unique(function (d) { + .uniqBy(function (d) { return d.label; }) .value(); diff --git a/src/plugins/vis_type_vislib/public/vislib/components/tooltip/position_tooltip.js b/src/plugins/vis_type_vislib/public/vislib/components/tooltip/position_tooltip.js index e22105d5a086f..5324dc5318be5 100644 --- a/src/plugins/vis_type_vislib/public/vislib/components/tooltip/position_tooltip.js +++ b/src/plugins/vis_type_vislib/public/vislib/components/tooltip/position_tooltip.js @@ -110,7 +110,7 @@ function getOverflow(size, pos, containers) { } function mergeOverflows(dest, src) { - _.merge(dest, src, function (a, b) { + _.mergeWith(dest, src, function (a, b) { if (a == null || b == null) return a || b; if (a < 0 && b < 0) return Math.min(a, b); return Math.max(a, b); @@ -131,7 +131,7 @@ function pickPlacement(prop, pos, overflow, prev, pref, fallback, placement) { const stash = '_' + prop; // list of directions in order of preference - const dirs = _.unique([prev[stash], pref, fallback].filter(Boolean)); + const dirs = _.uniq([prev[stash], pref, fallback].filter(Boolean)); let dir; let value; diff --git a/src/plugins/vis_type_vislib/public/vislib/components/tooltip/tooltip.js b/src/plugins/vis_type_vislib/public/vislib/components/tooltip/tooltip.js index 0bfcedc5e6055..bafc3199de896 100644 --- a/src/plugins/vis_type_vislib/public/vislib/components/tooltip/tooltip.js +++ b/src/plugins/vis_type_vislib/public/vislib/components/tooltip/tooltip.js @@ -218,7 +218,7 @@ Tooltip.prototype.render = function () { if (html) allContents.push({ id, html, order }); - const allHtml = _(allContents).sortBy('order').pluck('html').compact().join('\n'); + const allHtml = _(allContents).sortBy('order').map('html').compact().join('\n'); if (allHtml) { $tooltip.html(allHtml); diff --git a/src/plugins/vis_type_vislib/public/vislib/components/zero_injection/flatten_data.js b/src/plugins/vis_type_vislib/public/vislib/components/zero_injection/flatten_data.js index 3269f54a621d0..8b7a44d95bb3b 100644 --- a/src/plugins/vis_type_vislib/public/vislib/components/zero_injection/flatten_data.js +++ b/src/plugins/vis_type_vislib/public/vislib/components/zero_injection/flatten_data.js @@ -35,9 +35,9 @@ export function flattenData(obj) { } return _(charts ? charts : [obj]) - .pluck('series') + .map('series') .flattenDeep() - .pluck('values') + .map('values') .flattenDeep() .filter(Boolean) .value(); diff --git a/src/plugins/vis_type_vislib/public/vislib/helpers/point_series/_get_series.ts b/src/plugins/vis_type_vislib/public/vislib/helpers/point_series/_get_series.ts index c5fb4761eb9ee..8a1f80df9f4db 100644 --- a/src/plugins/vis_type_vislib/public/vislib/helpers/point_series/_get_series.ts +++ b/src/plugins/vis_type_vislib/public/vislib/helpers/point_series/_get_series.ts @@ -71,7 +71,7 @@ export function getSeries(table: Table, chart: Chart) { seriesLabel = prefix + seriesLabel; } - point.seriesId = seriesId; + (point.seriesId as string | number) = seriesId; addToSiri( seriesMap, point, diff --git a/src/plugins/vis_type_vislib/public/vislib/lib/data.js b/src/plugins/vis_type_vislib/public/vislib/lib/data.js index 98d384f95a839..3633063966e17 100644 --- a/src/plugins/vis_type_vislib/public/vislib/lib/data.js +++ b/src/plugins/vis_type_vislib/public/vislib/lib/data.js @@ -248,7 +248,7 @@ export class Data { const visData = this.getVisData(); return _.reduce( - _.pluck(visData, 'geoJson.properties'), + _.map(visData, 'geoJson.properties'), function (minMax, props) { return { min: Math.min(props.min, minMax.min), @@ -312,7 +312,7 @@ export class Data { * @returns {Array} Value objects */ flatten() { - return _(this.chartData()).pluck('series').flattenDeep().pluck('values').flattenDeep().value(); + return _(this.chartData()).map('series').flattenDeep().map('values').flattenDeep().value(); } /** @@ -383,7 +383,7 @@ export class Data { .sortBy(function (obj) { return obj.index; }) - .unique(function (d) { + .uniqBy(function (d) { return d.label; }) .value(); @@ -452,7 +452,7 @@ export class Data { }); }); - return _.uniq(names, 'label'); + return _.uniqBy(names, 'label'); } /** diff --git a/src/plugins/vis_type_vislib/public/vislib/lib/dispatch.js b/src/plugins/vis_type_vislib/public/vislib/lib/dispatch.js index 37f395aab4011..4c50472b9d11a 100644 --- a/src/plugins/vis_type_vislib/public/vislib/lib/dispatch.js +++ b/src/plugins/vis_type_vislib/public/vislib/lib/dispatch.js @@ -18,7 +18,7 @@ */ import d3 from 'd3'; -import { get, pull, restParam, size, reduce } from 'lodash'; +import { get, pull, rest, size, reduce } from 'lodash'; import $ from 'jquery'; import { DIMMING_OPACITY_SETTING } from '../../../common'; @@ -97,7 +97,7 @@ export class Dispatch { * @param {*} [arg...] - any number of arguments that will be applied to each handler * @return {Dispatch} - this, for chaining */ - emit = restParam(function (name, args) { + emit = rest(function (name, args) { if (!this._listeners[name]) { return this; } diff --git a/src/plugins/visualizations/public/persisted_state/persisted_state.ts b/src/plugins/visualizations/public/persisted_state/persisted_state.ts index 7465f969f456f..c926c456da219 100644 --- a/src/plugins/visualizations/public/persisted_state/persisted_state.ts +++ b/src/plugins/visualizations/public/persisted_state/persisted_state.ts @@ -19,8 +19,17 @@ import { EventEmitter } from 'events'; -import { isPlainObject, cloneDeep, get, set, isEqual, isString, merge } from 'lodash'; -import toPath from 'lodash/internal/toPath'; +import { + isPlainObject, + cloneDeep, + get, + set, + isEqual, + isString, + merge, + mergeWith, + toPath, +} from 'lodash'; function prepSetParams(key: PersistedStateKey, value: any, path: PersistedStatePath) { // key must be the value, set the entire state using it @@ -150,7 +159,7 @@ export class PersistedState extends EventEmitter { while (partialPath.length > 0) { const lastKey = partialPath.splice(partialPath.length - 1, 1)[0]; const statePath = [...this._path, partialPath]; - const stateVal = statePath.length > 0 ? get(stateTree, statePath) : stateTree; + const stateVal = statePath.length > 0 ? get(stateTree, statePath as string[]) : stateTree; // if stateVal isn't an object, do nothing if (!isPlainObject(stateVal)) return; @@ -240,7 +249,7 @@ export class PersistedState extends EventEmitter { // If `mergeMethod` is provided it is invoked to produce the merged values of the // destination and source properties. // If `mergeMethod` returns `undefined` the default merging method is used - this._mergedState = merge(targetObj, sourceObj, mergeMethod); + this._mergedState = mergeWith(targetObj, sourceObj, mergeMethod); // sanity check; verify that there are actually changes if (isEqual(this._mergedState, this._defaultState)) this._changedState = {}; diff --git a/src/plugins/visualizations/public/saved_visualizations/find_list_items.ts b/src/plugins/visualizations/public/saved_visualizations/find_list_items.ts index 0c27c3a2c7782..60945b912e1b3 100644 --- a/src/plugins/visualizations/public/saved_visualizations/find_list_items.ts +++ b/src/plugins/visualizations/public/saved_visualizations/find_list_items.ts @@ -49,7 +49,7 @@ export async function findListItems({ }, acc); }, {} as { [visType: string]: VisualizationsAppExtension }); const searchOption = (field: string, ...defaults: string[]) => - _(extensions).pluck(field).concat(defaults).compact().flatten().uniq().value() as string[]; + _(extensions).map(field).concat(defaults).compact().flatten().uniq().value() as string[]; const searchOptions = { type: searchOption('docTypes', 'visualization'), searchFields: searchOption('searchFields', 'title^3', 'description'), diff --git a/src/plugins/visualizations/public/wizard/type_selection/type_selection.tsx b/src/plugins/visualizations/public/wizard/type_selection/type_selection.tsx index 47757593958d6..dc6ac4919a4c4 100644 --- a/src/plugins/visualizations/public/wizard/type_selection/type_selection.tsx +++ b/src/plugins/visualizations/public/wizard/type_selection/type_selection.tsx @@ -19,7 +19,7 @@ import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { sortByOrder } from 'lodash'; +import { orderBy } from 'lodash'; import React, { ChangeEvent } from 'react'; import { @@ -201,7 +201,7 @@ class TypeSelection extends React.Component { diff --git a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts index 27fe722019a27..74881b9d99ae8 100644 --- a/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts +++ b/src/plugins/visualizations/server/saved_objects/visualization_migrations.ts @@ -65,7 +65,7 @@ const migrateIndexPattern: SavedObjectMigrationFn = (doc) => { // [TSVB] Migrate percentile-rank aggregation (value -> values) const migratePercentileRankAggregation: SavedObjectMigrationFn = (doc) => { - const visStateJSON = get(doc, 'attributes.visState'); + const visStateJSON = get(doc, 'attributes.visState'); let visState; if (visStateJSON) { @@ -101,7 +101,7 @@ const migratePercentileRankAggregation: SavedObjectMigrationFn = (doc) // [TSVB] Remove stale opperator key const migrateOperatorKeyTypo: SavedObjectMigrationFn = (doc) => { - const visStateJSON = get(doc, 'attributes.visState'); + const visStateJSON = get(doc, 'attributes.visState'); let visState; if (visStateJSON) { @@ -137,7 +137,7 @@ const migrateOperatorKeyTypo: SavedObjectMigrationFn = (doc) => { * @see https://github.com/elastic/kibana/pull/58462/files#diff-ae69fe15b20a5099d038e9bbe2ed3849 **/ const migrateSplitByChartRow: SavedObjectMigrationFn = (doc) => { - const visStateJSON = get(doc, 'attributes.visState'); + const visStateJSON = get(doc, 'attributes.visState'); let visState: any; if (visStateJSON) { @@ -177,7 +177,7 @@ const migrateSplitByChartRow: SavedObjectMigrationFn = (doc) => { // Migrate date histogram aggregation (remove customInterval) const migrateDateHistogramAggregation: SavedObjectMigrationFn = (doc) => { - const visStateJSON = get(doc, 'attributes.visState'); + const visStateJSON = get(doc, 'attributes.visState'); let visState; if (visStateJSON) { @@ -219,7 +219,7 @@ const migrateDateHistogramAggregation: SavedObjectMigrationFn = (doc) }; const removeDateHistogramTimeZones: SavedObjectMigrationFn = (doc) => { - const visStateJSON = get(doc, 'attributes.visState'); + const visStateJSON = get(doc, 'attributes.visState'); if (visStateJSON) { let visState; try { @@ -251,7 +251,7 @@ const removeDateHistogramTimeZones: SavedObjectMigrationFn = (doc) => // migrate gauge verticalSplit to alignment // https://github.com/elastic/kibana/issues/34636 const migrateGaugeVerticalSplitToAlignment: SavedObjectMigrationFn = (doc, logger) => { - const visStateJSON = get(doc, 'attributes.visState'); + const visStateJSON = get(doc, 'attributes.visState'); if (visStateJSON) { try { @@ -289,7 +289,7 @@ const transformFilterStringToQueryObject: SavedObjectMigrationFn = (do // Migrate filters // If any filters exist and they are a string, we assume it to be lucene and transform the filter into an object accordingly const newDoc = cloneDeep(doc); - const visStateJSON = get(doc, 'attributes.visState'); + const visStateJSON = get(doc, 'attributes.visState'); if (visStateJSON) { let visState; try { @@ -298,7 +298,7 @@ const transformFilterStringToQueryObject: SavedObjectMigrationFn = (do // let it go, the data is invalid and we'll leave it as is } if (visState) { - const visType = get(visState, 'params.type'); + const visType = get(visState, 'params.type'); const tsvbTypes = ['metric', 'markdown', 'top_n', 'gauge', 'table', 'timeseries']; if (tsvbTypes.indexOf(visType) === -1) { // skip @@ -373,7 +373,7 @@ const transformSplitFiltersStringToQueryObject: SavedObjectMigrationFn // Migrate split_filters in TSVB objects that weren't migrated in 7.3 // If any filters exist and they are a string, we assume them to be lucene syntax and transform the filter into an object accordingly const newDoc = cloneDeep(doc); - const visStateJSON = get(doc, 'attributes.visState'); + const visStateJSON = get(doc, 'attributes.visState'); if (visStateJSON) { let visState; try { @@ -382,7 +382,7 @@ const transformSplitFiltersStringToQueryObject: SavedObjectMigrationFn // let it go, the data is invalid and we'll leave it as is } if (visState) { - const visType = get(visState, 'params.type'); + const visType = get(visState, 'params.type'); const tsvbTypes = ['metric', 'markdown', 'top_n', 'gauge', 'table', 'timeseries']; if (tsvbTypes.indexOf(visType) === -1) { // skip @@ -415,7 +415,7 @@ const transformSplitFiltersStringToQueryObject: SavedObjectMigrationFn }; const migrateFiltersAggQuery: SavedObjectMigrationFn = (doc) => { - const visStateJSON = get(doc, 'attributes.visState'); + const visStateJSON = get(doc, 'attributes.visState'); if (visStateJSON) { try { @@ -447,7 +447,7 @@ const migrateFiltersAggQuery: SavedObjectMigrationFn = (doc) => { }; const replaceMovAvgToMovFn: SavedObjectMigrationFn = (doc, logger) => { - const visStateJSON = get(doc, 'attributes.visState'); + const visStateJSON = get(doc, 'attributes.visState'); let visState; if (visStateJSON) { @@ -495,7 +495,7 @@ const replaceMovAvgToMovFn: SavedObjectMigrationFn = (doc, logger) => }; const migrateFiltersAggQueryStringQueries: SavedObjectMigrationFn = (doc, logger) => { - const visStateJSON = get(doc, 'attributes.visState'); + const visStateJSON = get(doc, 'attributes.visState'); if (visStateJSON) { try { @@ -533,7 +533,7 @@ const addDocReferences: SavedObjectMigrationFn = (doc) => ({ }); const migrateSavedSearch: SavedObjectMigrationFn = (doc) => { - const savedSearchId = get(doc, 'attributes.savedSearchId'); + const savedSearchId = get(doc, 'attributes.savedSearchId'); if (savedSearchId && doc.references) { doc.references.push({ @@ -550,7 +550,7 @@ const migrateSavedSearch: SavedObjectMigrationFn = (doc) => { }; const migrateControls: SavedObjectMigrationFn = (doc) => { - const visStateJSON = get(doc, 'attributes.visState'); + const visStateJSON = get(doc, 'attributes.visState'); if (visStateJSON) { let visState; @@ -617,7 +617,7 @@ const migrateTableSplits: SavedObjectMigrationFn = (doc) => { }; const migrateMatchAllQuery: SavedObjectMigrationFn = (doc) => { - const searchSourceJSON = get(doc, 'attributes.kibanaSavedObjectMeta.searchSourceJSON'); + const searchSourceJSON = get(doc, 'attributes.kibanaSavedObjectMeta.searchSourceJSON'); if (searchSourceJSON) { let searchSource: any; @@ -651,7 +651,7 @@ const migrateMatchAllQuery: SavedObjectMigrationFn = (doc) => { // [TSVB] Default color palette is changing, keep the default for older viz const migrateTsvbDefaultColorPalettes: SavedObjectMigrationFn = (doc) => { - const visStateJSON = get(doc, 'attributes.visState'); + const visStateJSON = get(doc, 'attributes.visState'); let visState; if (visStateJSON) { @@ -693,30 +693,24 @@ export const visualizationSavedObjectTypeMigrations = { * in that version. So we apply this twice, once with 6.7.2 and once with 7.0.1 while the backport to 6.7 * only contained the 6.7.2 migration and not the 7.0.1 migration. */ - '6.7.2': flow>( - migrateMatchAllQuery, - removeDateHistogramTimeZones - ), - '7.0.0': flow>( + '6.7.2': flow(migrateMatchAllQuery, removeDateHistogramTimeZones), + '7.0.0': flow( addDocReferences, migrateIndexPattern, migrateSavedSearch, migrateControls, migrateTableSplits ), - '7.0.1': flow>(removeDateHistogramTimeZones), - '7.2.0': flow>( - migratePercentileRankAggregation, - migrateDateHistogramAggregation - ), - '7.3.0': flow>( + '7.0.1': flow(removeDateHistogramTimeZones), + '7.2.0': flow(migratePercentileRankAggregation, migrateDateHistogramAggregation), + '7.3.0': flow( migrateGaugeVerticalSplitToAlignment, transformFilterStringToQueryObject, migrateFiltersAggQuery, replaceMovAvgToMovFn ), - '7.3.1': flow>(migrateFiltersAggQueryStringQueries), - '7.4.2': flow>(transformSplitFiltersStringToQueryObject), - '7.7.0': flow>(migrateOperatorKeyTypo, migrateSplitByChartRow), - '7.8.0': flow>(migrateTsvbDefaultColorPalettes), + '7.3.1': flow(migrateFiltersAggQueryStringQueries), + '7.4.2': flow(transformSplitFiltersStringToQueryObject), + '7.7.0': flow(migrateOperatorKeyTypo, migrateSplitByChartRow), + '7.8.0': flow(migrateTsvbDefaultColorPalettes), }; diff --git a/src/plugins/visualize/public/application/utils/create_visualize_app_state.ts b/src/plugins/visualize/public/application/utils/create_visualize_app_state.ts index 1e05c48ba7daf..52b7e3ede298b 100644 --- a/src/plugins/visualize/public/application/utils/create_visualize_app_state.ts +++ b/src/plugins/visualize/public/application/utils/create_visualize_app_state.ts @@ -17,7 +17,7 @@ * under the License. */ -import { isFunction, omit, union } from 'lodash'; +import { isFunction, omitBy, union } from 'lodash'; import { migrateAppState } from './migrate_app_state'; import { @@ -35,9 +35,9 @@ interface Arguments { } function toObject(state: PureVisState): PureVisState { - return omit(state, (value, key: string) => { + return omitBy(state, (value, key: string) => { return key.charAt(0) === '$' || key.charAt(0) === '_' || isFunction(value); - }); + }) as PureVisState; } export function createVisualizeAppState({ stateDefaults, kbnUrlStateStorage }: Arguments) { diff --git a/src/plugins/visualize/public/application/utils/migrate_app_state.ts b/src/plugins/visualize/public/application/utils/migrate_app_state.ts index f5f1a1785bbdf..94eba5a6d7ce2 100644 --- a/src/plugins/visualize/public/application/utils/migrate_app_state.ts +++ b/src/plugins/visualize/public/application/utils/migrate_app_state.ts @@ -36,7 +36,7 @@ export function migrateAppState(appState: VisualizeAppState) { return appState; } - const visAggs: any = get(appState, 'vis.aggs'); + const visAggs: any = get(appState, 'vis.aggs'); if (visAggs) { let splitCount = 0; diff --git a/src/setup_node_env/harden.js b/src/setup_node_env/harden.js deleted file mode 100644 index dead3db1d60b4..0000000000000 --- a/src/setup_node_env/harden.js +++ /dev/null @@ -1,24 +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. - */ - -var hook = require('require-in-the-middle'); - -hook(['child_process'], function (exports, name) { - return require(`./patches/${name}`)(exports); // eslint-disable-line import/no-dynamic-require -}); diff --git a/src/setup_node_env/patches/child_process.js b/src/setup_node_env/harden/child_process.js similarity index 97% rename from src/setup_node_env/patches/child_process.js rename to src/setup_node_env/harden/child_process.js index fb857b2092ee0..6b1ba779605c0 100644 --- a/src/setup_node_env/patches/child_process.js +++ b/src/setup_node_env/harden/child_process.js @@ -16,12 +16,13 @@ * specific language governing permissions and limitations * under the License. */ +var hook = require('require-in-the-middle'); // Ensure, when spawning a new child process, that the `options` and the // `options.env` object passed to the child process function doesn't inherit // from `Object.prototype`. This protects against similar RCE vulnerabilities // as described in CVE-2019-7609 -module.exports = function (cp) { +hook(['child_process'], function (cp) { // The `exec` function is currently just a wrapper around `execFile`. So for // now there's no need to patch it. If this changes in the future, our tests // will fail and we can uncomment the line below. @@ -36,7 +37,7 @@ module.exports = function (cp) { cp.spawnSync = new Proxy(cp.spawnSync, { apply: patchOptions(true) }); return cp; -}; +}); function patchOptions(hasArgs) { return function apply(target, thisArg, args) { diff --git a/typings/lodash.topath/index.d.ts b/src/setup_node_env/harden/index.js similarity index 87% rename from typings/lodash.topath/index.d.ts rename to src/setup_node_env/harden/index.js index 3630a13f72c28..25cb3bcd78ffb 100644 --- a/typings/lodash.topath/index.d.ts +++ b/src/setup_node_env/harden/index.js @@ -17,7 +17,5 @@ * under the License. */ -declare module 'lodash/internal/toPath' { - function toPath(value: string | string[]): string[]; - export = toPath; -} +require('./child_process'); +require('./lodash_template'); diff --git a/src/setup_node_env/harden/lodash_template.js b/src/setup_node_env/harden/lodash_template.js new file mode 100644 index 0000000000000..2add624f9f326 --- /dev/null +++ b/src/setup_node_env/harden/lodash_template.js @@ -0,0 +1,68 @@ +/* + * 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. + */ +var hook = require('require-in-the-middle'); +var isIterateeCall = require('lodash/_isIterateeCall'); + +hook(['lodash'], function (lodash) { + lodash.template = createProxy(lodash.template); + return lodash; +}); + +hook(['lodash/template'], function (template) { + return createProxy(template); +}); + +hook(['lodash/fp'], function (fp) { + fp.template = createFpProxy(fp.template); + return fp; +}); + +hook(['lodash/fp/template'], function (template) { + return createFpProxy(template); +}); + +function createProxy(template) { + return new Proxy(template, { + apply: function (target, thisArg, args) { + if (args.length === 1 || isIterateeCall(args)) { + return target.apply(thisArg, [args[0], { sourceURL: '' }]); + } + + var options = Object.assign({}, args[1]); + options.sourceURL = (options.sourceURL + '').replace(/\s/g, ' '); + var newArgs = args.slice(0); // copy + newArgs.splice(1, 1, options); // replace options in the copy + return target.apply(thisArg, newArgs); + }, + }); +} + +function createFpProxy(template) { + // we have to do the require here, so that we get the patched version + var _ = require('lodash'); + return new Proxy(template, { + apply: function (target, thisArg, args) { + // per https://github.com/lodash/lodash/wiki/FP-Guide + // > Iteratee arguments are capped to avoid gotchas with variadic iteratees. + // this means that we can't specify the options in the second argument to fp.template because it's ignored. + // Instead, we're going to use the non-FP _.template with only the first argument which has already been patched + return _.template(args[0]); + }, + }); +} diff --git a/src/test_utils/get_url.js b/src/test_utils/get_url.js index fbe16e798fff9..182cb8e6e118d 100644 --- a/src/test_utils/get_url.js +++ b/src/test_utils/get_url.js @@ -44,7 +44,7 @@ export default function getUrl(config, app) { } getUrl.noAuth = function getUrlNoAuth(config, app) { - config = _.pick(config, function (val, param) { + config = _.pickBy(config, function (val, param) { return param !== 'auth'; }); return getUrl(config, app); diff --git a/src/test_utils/kbn_server.ts b/src/test_utils/kbn_server.ts index 12f7eb5a0a043..6a20261421b5b 100644 --- a/src/test_utils/kbn_server.ts +++ b/src/test_utils/kbn_server.ts @@ -217,7 +217,7 @@ export function createTestServers({ if (!adjustTimeout) { throw new Error('adjustTimeout is required in order to avoid flaky tests'); } - const license = get<'oss' | 'basic' | 'gold' | 'trial'>(settings, 'es.license', 'oss'); + const license = get(settings, 'es.license', 'oss'); const usersToBeAdded = get(settings, 'users', []); if (usersToBeAdded.length > 0) { if (license !== 'trial') { diff --git a/test/api_integration/apis/saved_objects/migrations.js b/test/api_integration/apis/saved_objects/migrations.js index d0ff4cc06c57e..9ea3cf087be90 100644 --- a/test/api_integration/apis/saved_objects/migrations.js +++ b/test/api_integration/apis/saved_objects/migrations.js @@ -293,7 +293,7 @@ export default ({ getService }) => { // It only created the original and the dest assert.deepEqual( - _.pluck( + _.map( await callCluster('cat.indices', { index: '.migration-c*', format: 'json' }), 'index' ).sort(), diff --git a/test/functional/apps/management/_import_objects.js b/test/functional/apps/management/_import_objects.js index c69111be6972b..03db3a2b108f2 100644 --- a/test/functional/apps/management/_import_objects.js +++ b/test/functional/apps/management/_import_objects.js @@ -19,7 +19,7 @@ import expect from '@kbn/expect'; import path from 'path'; -import { indexBy } from 'lodash'; +import { keyBy } from 'lodash'; export default function ({ getService, getPageObjects }) { const kibanaServer = getService('kibanaServer'); @@ -50,12 +50,12 @@ export default function ({ getService, getPageObjects }) { await PageObjects.savedObjects.clickImportDone(); // get all the elements in the table, and index them by the 'title' visible text field - const elements = indexBy(await PageObjects.savedObjects.getElementsInTable(), 'title'); + const elements = keyBy(await PageObjects.savedObjects.getElementsInTable(), 'title'); log.debug("check that 'Log Agents' is in table as a visualization"); expect(elements['Log Agents'].objectType).to.eql('visualization'); await elements['logstash-*'].relationshipsElement.click(); - const flyout = indexBy(await PageObjects.savedObjects.getRelationshipFlyout(), 'title'); + const flyout = keyBy(await PageObjects.savedObjects.getRelationshipFlyout(), 'title'); log.debug( "check that 'Shared-Item Visualization AreaChart' shows 'logstash-*' as it's Parent" ); @@ -150,7 +150,7 @@ export default function ({ getService, getPageObjects }) { }); it('should not import saved objects linked to saved searches when saved search index pattern does not exist', async function () { - const elements = indexBy(await PageObjects.savedObjects.getElementsInTable(), 'title'); + const elements = keyBy(await PageObjects.savedObjects.getElementsInTable(), 'title'); await elements['logstash-*'].checkbox.click(); await PageObjects.savedObjects.clickDelete(); @@ -182,7 +182,7 @@ export default function ({ getService, getPageObjects }) { it('should import saved objects with index patterns when index patterns does not exists', async () => { // First, we need to delete the index pattern - const elements = indexBy(await PageObjects.savedObjects.getElementsInTable(), 'title'); + const elements = keyBy(await PageObjects.savedObjects.getElementsInTable(), 'title'); await elements['logstash-*'].checkbox.click(); await PageObjects.savedObjects.clickDelete(); @@ -321,7 +321,7 @@ export default function ({ getService, getPageObjects }) { await PageObjects.savedObjects.clickImportDone(); // Second, we need to delete the index pattern - const elements = indexBy(await PageObjects.savedObjects.getElementsInTable(), 'title'); + const elements = keyBy(await PageObjects.savedObjects.getElementsInTable(), 'title'); await elements['logstash-*'].checkbox.click(); await PageObjects.savedObjects.clickDelete(); @@ -353,7 +353,7 @@ export default function ({ getService, getPageObjects }) { it('should import saved objects with index patterns when index patterns does not exists', async () => { // First, we need to delete the index pattern - const elements = indexBy(await PageObjects.savedObjects.getElementsInTable(), 'title'); + const elements = keyBy(await PageObjects.savedObjects.getElementsInTable(), 'title'); await elements['logstash-*'].checkbox.click(); await PageObjects.savedObjects.clickDelete(); diff --git a/test/functional/services/common/browser.ts b/test/functional/services/common/browser.ts index d6a4fc91481de..2d35551b04808 100644 --- a/test/functional/services/common/browser.ts +++ b/test/functional/services/common/browser.ts @@ -17,7 +17,7 @@ * under the License. */ -import { cloneDeep } from 'lodash'; +import { cloneDeepWith } from 'lodash'; import { Key, Origin } from 'selenium-webdriver'; // @ts-ignore internal modules are not typed import { LegacyActionSequence } from 'selenium-webdriver/lib/actions'; @@ -471,7 +471,7 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { ): Promise { return await driver.executeScript( fn, - ...cloneDeep(args, (arg) => { + ...cloneDeepWith(args, (arg) => { if (arg instanceof WebElementWrapper) { return arg._webElement; } @@ -501,7 +501,7 @@ export async function BrowserProvider({ getService }: FtrProviderContext) { ): Promise { return await driver.executeAsyncScript( fn, - ...cloneDeep(args, (arg) => { + ...cloneDeepWith(args, (arg) => { if (arg instanceof WebElementWrapper) { return arg._webElement; } diff --git a/test/harden/lodash_template.js b/test/harden/lodash_template.js new file mode 100644 index 0000000000000..170e3a8fba43e --- /dev/null +++ b/test/harden/lodash_template.js @@ -0,0 +1,181 @@ +/* + * 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. + */ + +require('../../src/setup_node_env'); +const _ = require('lodash'); +const template = require('lodash/template'); +const fp = require('lodash/fp'); +const fpTemplate = require('lodash/fp/template'); +const test = require('tape'); + +Object.prototype.sourceURL = '\u2028\u2029\n;global.whoops=true'; // eslint-disable-line no-extend-native + +test.onFinish(() => { + delete Object.prototype.sourceURL; +}); + +test('test setup ok', (t) => { + t.equal({}.sourceURL, '\u2028\u2029\n;global.whoops=true'); + t.end(); +}); + +[_.template, template].forEach((fn) => { + test(`_.template('<%= foo %>')`, (t) => { + const output = fn('<%= foo %>')({ foo: 'bar' }); + t.equal(output, 'bar'); + t.equal(global.whoops, undefined); + t.end(); + }); + + test(`_.template('<%= foo %>', {})`, (t) => { + const output = fn('<%= foo %>', Object.freeze({}))({ foo: 'bar' }); + t.equal(output, 'bar'); + t.equal(global.whoops, undefined); + t.end(); + }); + + test(`_.template('<%= data.foo %>', { variable: 'data' })`, (t) => { + const output = fn('<%= data.foo %>', Object.freeze({ variable: 'data' }))({ foo: 'bar' }); + t.equal(output, 'bar'); + t.equal(global.whoops, undefined); + t.end(); + }); + + test(`_.template('<%= foo %>', { sourceURL: '/foo/bar' })`, (t) => { + // throwing errors in the template and parsing the stack, which is a string, is super ugly, but all I know to do + const template = fn('<% throw new Error() %>', Object.freeze({ sourceURL: '/foo/bar' })); + t.plan(2); + try { + template(); + } catch (err) { + const path = parsePathFromStack(err.stack); + t.equal(path, '/foo/bar'); + t.equal(global.whoops, undefined); + } + }); + + test(`_.template('<%= foo %>', { sourceURL: '\\u2028\\u2029\\nglobal.whoops=true' })`, (t) => { + // throwing errors in the template and parsing the stack, which is a string, is super ugly, but all I know to do + const template = fn( + '<% throw new Error() %>', + Object.freeze({ sourceURL: '\u2028\u2029\nglobal.whoops=true' }) + ); + t.plan(2); + try { + template(); + } catch (err) { + const path = parsePathFromStack(err.stack); + t.equal(path, 'global.whoops=true'); + t.equal(global.whoops, undefined); + } + }); + + test(`_.template used as an iteratee call(`, (t) => { + const templateStrArr = ['<%= data.foo %>', 'example <%= data.foo %>']; + const output = _.map(templateStrArr, fn); + + t.equal(output[0]({ data: { foo: 'bar' } }), 'bar'); + t.equal(output[1]({ data: { foo: 'bar' } }), 'example bar'); + t.equal(global.whoops, undefined); + t.end(); + }); +}); + +[fp.template, fpTemplate].forEach((fn) => { + test(`fp.template('<%= foo %>')`, (t) => { + const output = fn('<%= foo %>')({ foo: 'bar' }); + t.equal(output, 'bar'); + t.equal(global.whoops, undefined); + t.end(); + }); + + test(`fp.template('<%= foo %>', {})`, (t) => { + // fp.template ignores the second argument, this is negligible in this situation since options is an empty object + const output = fn('<%= foo %>', Object.freeze({}))({ foo: 'bar' }); + t.equal(output, 'bar'); + t.equal(global.whoops, undefined); + t.end(); + }); + + test(`fp.template('<%= data.foo %>', { variable: 'data' })`, (t) => { + // fp.template ignores the second argument, this causes an error to be thrown + t.plan(2); + try { + fn('<%= data.foo %>', Object.freeze({ variable: 'data' }))({ foo: 'bar' }); + } catch (err) { + t.equal(err.message, 'data is not defined'); + t.equal(global.whoops, undefined); + } + }); + + test(`fp.template('<%= foo %>', { sourceURL: '/foo/bar' })`, (t) => { + // fp.template ignores the second argument, the sourceURL is ignored + // throwing errors in the template and parsing the stack, which is a string, is super ugly, but all I know to do + // our patching to hard-code the sourceURL and use non-FP _.template does slightly alter the stack-traces but it's negligible + const template = fn('<% throw new Error() %>', Object.freeze({ sourceURL: '/foo/bar' })); + t.plan(3); + try { + template(); + } catch (err) { + const path = parsePathFromStack(err.stack); + t.match(path, /^eval at /); + t.doesNotMatch(path, /\/foo\/bar/); + t.equal(global.whoops, undefined); + } + }); + + test(`fp.template('<%= foo %>', { sourceURL: '\\u2028\\u2029\\nglobal.whoops=true' })`, (t) => { + // fp.template ignores the second argument, the sourceURL is ignored + // throwing errors in the template and parsing the stack, which is a string, is super ugly, but all I know to do + // our patching to hard-code the sourceURL and use non-FP _.template does slightly alter the stack-traces but it's negligible + const template = fn( + '<% throw new Error() %>', + Object.freeze({ sourceURL: '\u2028\u2029\nglobal.whoops=true' }) + ); + t.plan(3); + try { + template(); + } catch (err) { + const path = parsePathFromStack(err.stack); + t.match(path, /^eval at /); + t.doesNotMatch(path, /\/foo\/bar/); + t.equal(global.whoops, undefined); + } + }); + + test(`fp.template used as an iteratee call(`, (t) => { + const templateStrArr = ['<%= data.foo %>', 'example <%= data.foo %>']; + const output = fp.map(fn)(templateStrArr); + + t.equal(output[0]({ data: { foo: 'bar' } }), 'bar'); + t.equal(output[1]({ data: { foo: 'bar' } }), 'example bar'); + t.equal(global.whoops, undefined); + t.end(); + }); +}); + +function parsePathFromStack(stack) { + const lines = stack.split('\n'); + // the frame starts at the second line + const frame = lines[1]; + + // the path is in parathensis, and ends with a colon before the line/column numbers + const [, path] = /\(([^:]+)/.exec(frame); + return path; +} diff --git a/test/tsconfig.json b/test/tsconfig.json index a270144bd49fe..87e79b295315f 100644 --- a/test/tsconfig.json +++ b/test/tsconfig.json @@ -14,7 +14,6 @@ "include": [ "**/*.ts", "**/*.tsx", - "../typings/lodash.topath/*.ts", "../typings/elastic__node_crypto.d.ts", "typings/**/*" ], diff --git a/test/visual_regression/services/visual_testing/visual_testing.ts b/test/visual_regression/services/visual_testing/visual_testing.ts index 3a71c3aa9d3d6..e35ef41420dd6 100644 --- a/test/visual_regression/services/visual_testing/visual_testing.ts +++ b/test/visual_regression/services/visual_testing/visual_testing.ts @@ -19,7 +19,6 @@ import { postSnapshot } from '@percy/agent/dist/utils/sdk-utils'; import { Test } from 'mocha'; -import _ from 'lodash'; import testSubjSelector from '@kbn/test-subj-selector'; diff --git a/x-pack/legacy/plugins/beats_management/server/lib/adapters/beats/elasticsearch_beats_adapter.ts b/x-pack/legacy/plugins/beats_management/server/lib/adapters/beats/elasticsearch_beats_adapter.ts index 0600ed8e3fbf6..7c495ad605f6d 100644 --- a/x-pack/legacy/plugins/beats_management/server/lib/adapters/beats/elasticsearch_beats_adapter.ts +++ b/x-pack/legacy/plugins/beats_management/server/lib/adapters/beats/elasticsearch_beats_adapter.ts @@ -38,7 +38,7 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter { if (!response.found) { return null; } - const beat = _get(response, '_source.beat'); + const beat = _get(response, '_source.beat') as CMBeat; beat.tags = beat.tags || []; return beat; } @@ -101,7 +101,7 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter { const response = await this.database.search(user, params); - const beats = _get(response, 'hits.hits', []); + const beats = _get(response, 'hits.hits', []) as CMBeat[]; if (beats.length === 0) { return []; @@ -127,14 +127,12 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter { const response = await this.database.search(user, params); - const beats = _get(response, 'hits.hits', []); + const beats = _get(response, 'hits.hits', []) as CMBeat[]; if (beats.length === 0) { return null; } - return omit(_get(formatWithTags(beats[0]), '_source.beat'), [ - 'access_token', - ]); + return omit(_get(formatWithTags(beats[0]), '_source.beat'), ['access_token']) as CMBeat; } public async getAll(user: FrameworkUser, ESQuery?: any) { @@ -171,7 +169,7 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter { if (!response) { return []; } - const beats = _get(response, 'hits.hits', []); + const beats = _get(response, 'hits.hits', []) as any; return beats.map((beat: any) => formatWithTags(omit(beat._source.beat as CMBeat, ['access_token']) as CMBeat) @@ -202,7 +200,7 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter { index: INDEX_NAMES.BEATS, refresh: 'wait_for', }); - return _get(response, 'items', []).map((item: any, resultIdx: number) => ({ + return (_get(response, 'items', []) as any).map((item: any, resultIdx: number) => ({ idxInRequest: removals[resultIdx].idxInRequest, result: item.update.result, status: item.update.status, @@ -237,7 +235,7 @@ export class ElasticsearchBeatsAdapter implements CMBeatsAdapter { refresh: 'wait_for', }); // console.log(response.items[0].update.error); - return _get(response, 'items', []).map((item: any, resultIdx: any) => ({ + return (_get(response, 'items', []) as any).map((item: any, resultIdx: any) => ({ idxInRequest: assignments[resultIdx].idxInRequest, result: item.update.result, status: item.update.status, diff --git a/x-pack/legacy/plugins/beats_management/server/lib/adapters/configuration_blocks/elasticsearch_configuration_block_adapter.ts b/x-pack/legacy/plugins/beats_management/server/lib/adapters/configuration_blocks/elasticsearch_configuration_block_adapter.ts index 2bc6f18756447..ec559c3ee479c 100644 --- a/x-pack/legacy/plugins/beats_management/server/lib/adapters/configuration_blocks/elasticsearch_configuration_block_adapter.ts +++ b/x-pack/legacy/plugins/beats_management/server/lib/adapters/configuration_blocks/elasticsearch_configuration_block_adapter.ts @@ -35,7 +35,7 @@ export class ElasticsearchConfigurationBlockAdapter implements ConfigurationBloc }; const response = await this.database.search(user, params); - const configs = get(response, 'hits.hits', []); + const configs = get(response, 'hits.hits', []); return configs.map((tag: any) => ({ ...tag._source.tag, config: JSON.parse(tag._source.tag) })); } @@ -71,7 +71,7 @@ export class ElasticsearchConfigurationBlockAdapter implements ConfigurationBloc } else { response = await this.database.search(user, params); } - const configs = get(response, 'hits.hits', []); + const configs = get(response, 'hits.hits', []); return { blocks: configs.map((block: any) => ({ diff --git a/x-pack/legacy/plugins/beats_management/server/lib/adapters/tags/elasticsearch_tags_adapter.ts b/x-pack/legacy/plugins/beats_management/server/lib/adapters/tags/elasticsearch_tags_adapter.ts index 4e032001809f2..b5be3cfa99e5d 100644 --- a/x-pack/legacy/plugins/beats_management/server/lib/adapters/tags/elasticsearch_tags_adapter.ts +++ b/x-pack/legacy/plugins/beats_management/server/lib/adapters/tags/elasticsearch_tags_adapter.ts @@ -43,7 +43,7 @@ export class ElasticsearchTagsAdapter implements CMTagsAdapter { }; } const response = await this.database.search(user, params); - const tags = get(response, 'hits.hits', []); + const tags = get(response, 'hits.hits', []) as any; return tags.map((tag: any) => ({ hasConfigurationBlocksTypes: [], ...tag._source.tag })); } @@ -63,7 +63,7 @@ export class ElasticsearchTagsAdapter implements CMTagsAdapter { const beatsResponse = await this.database.search(user, params); - const beats = get(beatsResponse, 'hits.hits', []).map( + const beats = (get(beatsResponse, 'hits.hits', []) as BeatTag[]).map( (beat: any) => beat._source.beat ); @@ -142,7 +142,7 @@ export class ElasticsearchTagsAdapter implements CMTagsAdapter { }; const response = await this.database.index(user, params); - return get(response, 'result'); + return get(response, 'result') as string; } public async getWithoutConfigTypes( @@ -172,7 +172,7 @@ export class ElasticsearchTagsAdapter implements CMTagsAdapter { size: 10000, }; const response = await this.database.search(user, params); - const tags = get(response, 'hits.hits', []); + const tags = get(response, 'hits.hits', []) as any; return tags.map((tag: any) => ({ hasConfigurationBlocksTypes: [], ...tag._source.tag })); } diff --git a/x-pack/legacy/plugins/beats_management/server/lib/adapters/tokens/elasticsearch_tokens_adapter.ts b/x-pack/legacy/plugins/beats_management/server/lib/adapters/tokens/elasticsearch_tokens_adapter.ts index 4987e4dbd4e0a..6c5125ea4e0eb 100644 --- a/x-pack/legacy/plugins/beats_management/server/lib/adapters/tokens/elasticsearch_tokens_adapter.ts +++ b/x-pack/legacy/plugins/beats_management/server/lib/adapters/tokens/elasticsearch_tokens_adapter.ts @@ -34,10 +34,10 @@ export class ElasticsearchTokensAdapter implements CMTokensAdapter { const response = await this.database.get(user, params); - const tokenDetails = get(response, '_source.enrollment_token', { + const tokenDetails = get(response, '_source.enrollment_token', { expires_on: '0', token: null, - }); + }) as TokenEnrollmentData; // Elasticsearch might return fast if the token is not found. OR it might return fast // if the token *is* found. Either way, an attacker could using a timing attack to figure diff --git a/x-pack/package.json b/x-pack/package.json index 0a8bc6f1e6f58..b721cb2fc563a 100644 --- a/x-pack/package.json +++ b/x-pack/package.json @@ -81,7 +81,7 @@ "@types/jsdom": "^16.2.3", "@types/json-stable-stringify": "^1.0.32", "@types/jsonwebtoken": "^7.2.8", - "@types/lodash": "^3.10.1", + "@types/lodash": "^4.14.155", "@types/mapbox-gl": "^1.9.1", "@types/memoize-one": "^4.1.0", "@types/mime": "^2.0.1", @@ -281,11 +281,7 @@ "json-stable-stringify": "^1.0.1", "jsonwebtoken": "^8.5.1", "jsts": "^1.6.2", - "lodash": "npm:@elastic/lodash@3.10.1-kibana4", - "lodash.keyby": "^4.6.0", - "lodash.mean": "^4.1.0", - "lodash.topath": "^4.5.2", - "lodash.uniqby": "^4.7.0", + "lodash": "^4.17.15", "lz-string": "^1.4.4", "mapbox-gl": "^1.10.0", "mapbox-gl-draw-rectangle-mode": "^1.0.4", diff --git a/x-pack/plugins/actions/server/builtin_action_types/case/utils.ts b/x-pack/plugins/actions/server/builtin_action_types/case/utils.ts index dd8d971b7df44..2d81c2bf4e15f 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/case/utils.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/case/utils.ts @@ -26,7 +26,7 @@ import { ExecutorSubActionPushParams, } from './types'; -import { transformers, Transformer } from './transformers'; +import { transformers } from './transformers'; import { SUPPORTED_SOURCE_FIELDS } from './constants'; @@ -205,7 +205,7 @@ export const transformFields = ({ currentIncident, }: TransformFieldsArgs): Record => { return fields.reduce((prev, cur) => { - const transform = flow(...cur.pipes.map((p) => transformers[p])); + const transform = flow(...cur.pipes.map((p) => transformers[p])); return { ...prev, [cur.key]: transform({ @@ -228,7 +228,7 @@ export const transformFields = ({ export const transformComments = (comments: Comment[], pipes: string[]): Comment[] => { return comments.map((c) => ({ ...c, - comment: flow(...pipes.map((p) => transformers[p]))({ + comment: flow(...pipes.map((p) => transformers[p]))({ value: c.comment, date: c.updatedAt ?? c.createdAt, user: diff --git a/x-pack/plugins/actions/server/usage/actions_usage_collector.ts b/x-pack/plugins/actions/server/usage/actions_usage_collector.ts index 5dff062922200..aa546e08ea1ba 100644 --- a/x-pack/plugins/actions/server/usage/actions_usage_collector.ts +++ b/x-pack/plugins/actions/server/usage/actions_usage_collector.ts @@ -20,7 +20,7 @@ export function createActionsUsageCollector( try { const doc = await getLatestTaskState(await taskManager); // get the accumulated state from the recurring task - const state: ActionsUsage = get(doc, 'state'); + const state: ActionsUsage = get(doc, 'state') as ActionsUsage; return { ...state, diff --git a/x-pack/plugins/alerts/server/alerts_client.ts b/x-pack/plugins/alerts/server/alerts_client.ts index 6b091a5a4503b..e8e6f82f13882 100644 --- a/x-pack/plugins/alerts/server/alerts_client.ts +++ b/x-pack/plugins/alerts/server/alerts_client.ts @@ -5,7 +5,7 @@ */ import Boom from 'boom'; -import { omit, isEqual, pluck } from 'lodash'; +import { omit, isEqual, map } from 'lodash'; import { i18n } from '@kbn/i18n'; import { Logger, @@ -647,7 +647,7 @@ export class AlertsClient { private validateActions(alertType: AlertType, actions: NormalizedAlertAction[]): void { const { actionGroups: alertTypeActionGroups } = alertType; const usedAlertActionGroups = actions.map((action) => action.group); - const availableAlertTypeActionGroups = new Set(pluck(alertTypeActionGroups, 'id')); + const availableAlertTypeActionGroups = new Set(map(alertTypeActionGroups, 'id')); const invalidActionGroups = usedAlertActionGroups.filter( (group) => !availableAlertTypeActionGroups.has(group) ); diff --git a/x-pack/plugins/alerts/server/task_runner/create_execution_handler.ts b/x-pack/plugins/alerts/server/task_runner/create_execution_handler.ts index 8d859a570ba91..e1e1568d2f13c 100644 --- a/x-pack/plugins/alerts/server/task_runner/create_execution_handler.ts +++ b/x-pack/plugins/alerts/server/task_runner/create_execution_handler.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { pluck } from 'lodash'; +import { map } from 'lodash'; import { AlertAction, State, Context, AlertType } from '../types'; import { Logger, KibanaRequest } from '../../../../../src/core/server'; import { transformActionParams } from './transform_action_params'; @@ -46,7 +46,7 @@ export function createExecutionHandler({ eventLogger, request, }: CreateExecutionHandlerOptions) { - const alertTypeActionGroups = new Set(pluck(alertType.actionGroups, 'id')); + const alertTypeActionGroups = new Set(map(alertType.actionGroups, 'id')); return async ({ actionGroup, context, state, alertInstanceId }: ExecutionHandlerOptions) => { if (!alertTypeActionGroups.has(actionGroup)) { logger.error(`Invalid action group "${actionGroup}" for alert "${alertType.id}".`); diff --git a/x-pack/plugins/alerts/server/task_runner/task_runner.ts b/x-pack/plugins/alerts/server/task_runner/task_runner.ts index 3512ab16a3712..3c66b57bb9416 100644 --- a/x-pack/plugins/alerts/server/task_runner/task_runner.ts +++ b/x-pack/plugins/alerts/server/task_runner/task_runner.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { pick, mapValues, omit, without } from 'lodash'; +import { pickBy, mapValues, omit, without } from 'lodash'; import { Logger, SavedObject, KibanaRequest } from '../../../../../src/core/server'; import { TaskRunnerContext } from './task_runner_factory'; import { ConcreteTaskInstance } from '../../../task_manager/server'; @@ -18,12 +18,11 @@ import { IntervalSchedule, Services, AlertInfoParams, - RawAlertInstance, AlertTaskState, + RawAlertInstance, } from '../types'; import { promiseResult, map, Resultable, asOk, asErr, resolveErr } from '../lib/result_type'; import { taskInstanceToAlertTaskInstance } from './alert_task_instance'; -import { AlertInstances } from '../alert_instance/alert_instance'; import { EVENT_LOG_ACTIONS } from '../plugin'; import { IEvent, IEventLogger, SAVED_OBJECT_REL_PRIMARY } from '../../../event_log/server'; import { isAlertSavedObjectNotFoundError } from '../lib/is_alert_not_found_error'; @@ -167,7 +166,7 @@ export class TaskRunner { } = this.taskInstance; const namespace = this.context.spaceIdToNamespace(spaceId); - const alertInstances = mapValues( + const alertInstances = mapValues, AlertInstance>( alertRawInstances, (rawAlertInstance) => new AlertInstance(rawAlertInstance) ); @@ -227,9 +226,8 @@ export class TaskRunner { eventLogger.logEvent(event); // Cleanup alert instances that are no longer scheduling actions to avoid over populating the alertInstances object - const instancesWithScheduledActions = pick( - alertInstances, - (alertInstance: AlertInstance) => alertInstance.hasScheduledActions() + const instancesWithScheduledActions = pickBy(alertInstances, (alertInstance: AlertInstance) => + alertInstance.hasScheduledActions() ); const currentAlertInstanceIds = Object.keys(instancesWithScheduledActions); generateNewAndResolvedInstanceEvents({ @@ -242,10 +240,7 @@ export class TaskRunner { }); if (!muteAll) { - const enabledAlertInstances = omit( - instancesWithScheduledActions, - ...mutedInstanceIds - ); + const enabledAlertInstances = omit(instancesWithScheduledActions, ...mutedInstanceIds); await Promise.all( Object.entries(enabledAlertInstances) @@ -260,7 +255,7 @@ export class TaskRunner { return { alertTypeState: updatedAlertTypeState || undefined, - alertInstances: mapValues( + alertInstances: mapValues, RawAlertInstance>( instancesWithScheduledActions, (alertInstance) => alertInstance.toRaw() ), diff --git a/x-pack/plugins/alerts/server/task_runner/transform_action_params.ts b/x-pack/plugins/alerts/server/task_runner/transform_action_params.ts index 64f846d13c0bf..fa4a0e40ddee5 100644 --- a/x-pack/plugins/alerts/server/task_runner/transform_action_params.ts +++ b/x-pack/plugins/alerts/server/task_runner/transform_action_params.ts @@ -5,7 +5,7 @@ */ import Mustache from 'mustache'; -import { isString, cloneDeep } from 'lodash'; +import { isString, cloneDeepWith } from 'lodash'; import { AlertActionParams, State, Context } from '../types'; interface TransformActionParamsOptions { @@ -29,7 +29,7 @@ export function transformActionParams({ actionParams, state, }: TransformActionParamsOptions): AlertActionParams { - const result = cloneDeep(actionParams, (value: unknown) => { + const result = cloneDeepWith(actionParams, (value: unknown) => { if (!isString(value)) return; // when the list of variables we pass in here changes, diff --git a/x-pack/plugins/alerts/server/usage/alerts_usage_collector.ts b/x-pack/plugins/alerts/server/usage/alerts_usage_collector.ts index 7491508ee0745..64d3ad54a2318 100644 --- a/x-pack/plugins/alerts/server/usage/alerts_usage_collector.ts +++ b/x-pack/plugins/alerts/server/usage/alerts_usage_collector.ts @@ -20,7 +20,7 @@ export function createAlertsUsageCollector( try { const doc = await getLatestTaskState(await taskManager); // get the accumulated state from the recurring task - const state: AlertsUsage = get(doc, 'state'); + const state: AlertsUsage = get(doc, 'state') as AlertsUsage; return { ...state, diff --git a/x-pack/plugins/apm/common/projections/util/merge_projection/index.ts b/x-pack/plugins/apm/common/projections/util/merge_projection/index.ts index f3ae0752b908e..9dc1c815bf169 100644 --- a/x-pack/plugins/apm/common/projections/util/merge_projection/index.ts +++ b/x-pack/plugins/apm/common/projections/util/merge_projection/index.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { merge, isPlainObject, cloneDeep } from 'lodash'; +import { mergeWith, isPlainObject, cloneDeep } from 'lodash'; import { DeepPartial } from 'utility-types'; import { AggregationInputMap } from '../../../../typings/elasticsearch/aggregations'; import { @@ -35,7 +35,7 @@ export function mergeProjection< T extends Projection, U extends SourceProjection >(target: T, source: U): DeepMerge { - return merge({}, cloneDeep(target), source, (a, b) => { + return mergeWith({}, cloneDeep(target), source, (a, b) => { if (isPlainObject(a) && isPlainObject(b)) { return undefined; } diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx index 7ee8dfa496b57..4e1af6e0dc239 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/DetailView/index.tsx @@ -65,7 +65,7 @@ interface Props { function getCurrentTab( tabs: ErrorTab[] = [], currentTabKey: string | undefined -) { +): ErrorTab | {} { const selectedTab = tabs.find(({ key }) => key === currentTabKey); return selectedTab ? selectedTab : first(tabs) || {}; } @@ -78,7 +78,7 @@ export function DetailView({ errorGroup, urlParams, location }: Props) { } const tabs = getTabs(error); - const currentTab = getCurrentTab(tabs, urlParams.detailTab); + const currentTab = getCurrentTab(tabs, urlParams.detailTab) as ErrorTab; const errorUrl = error.error.page?.url || error.url?.full; diff --git a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx index d71d5f2cb480d..3cd04ee032e56 100644 --- a/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx +++ b/x-pack/plugins/apm/public/components/app/ErrorGroupDetails/Distribution/index.tsx @@ -10,7 +10,7 @@ import numeral from '@elastic/numeral'; import { i18n } from '@kbn/i18n'; import d3 from 'd3'; import { scaleUtc } from 'd3-scale'; -import mean from 'lodash.mean'; +import { mean } from 'lodash'; import React from 'react'; import { asRelativeDateTimeRange } from '../../../../utils/formatters'; import { getTimezoneOffsetInMs } from '../../../shared/charts/CustomPlot/getTimezoneOffsetInMs'; diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/WatcherFlyout.tsx b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/WatcherFlyout.tsx index 8a3e2b1a02dac..26cff5e71b610 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/WatcherFlyout.tsx +++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/WatcherFlyout.tsx @@ -26,7 +26,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { padLeft, range } from 'lodash'; +import { padStart, range } from 'lodash'; import moment from 'moment-timezone'; import React, { Component } from 'react'; import styled from 'styled-components'; @@ -288,7 +288,7 @@ export class WatcherFlyout extends Component< // Generate UTC hours for Daily Report select field const intervalHours = range(24).map((i) => { - const hour = padLeft(i.toString(), 2, '0'); + const hour = padStart(i.toString(), 2, '0'); return { value: `${hour}:00`, text: `${hour}:00 UTC` }; }); diff --git a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/__test__/createErrorGroupWatch.test.ts b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/__test__/createErrorGroupWatch.test.ts index f0bc313ab4644..054476af28de1 100644 --- a/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/__test__/createErrorGroupWatch.test.ts +++ b/x-pack/plugins/apm/public/components/app/ServiceDetails/ServiceIntegrations/__test__/createErrorGroupWatch.test.ts @@ -110,7 +110,7 @@ function renderMustache( if (isObject(input)) { return Object.keys(input).reduce((acc, key) => { - const value = input[key]; + const value = (input as any)[key]; return { ...acc, [key]: renderMustache(value, ctx) }; }, {}); diff --git a/x-pack/plugins/apm/public/components/app/TransactionDetails/index.tsx b/x-pack/plugins/apm/public/components/app/TransactionDetails/index.tsx index c1bfce4cdca49..620ae6708eda0 100644 --- a/x-pack/plugins/apm/public/components/app/TransactionDetails/index.tsx +++ b/x-pack/plugins/apm/public/components/app/TransactionDetails/index.tsx @@ -12,7 +12,6 @@ import { EuiFlexGroup, EuiFlexItem, } from '@elastic/eui'; -import _ from 'lodash'; import React, { useMemo } from 'react'; import { useTransactionCharts } from '../../../hooks/useTransactionCharts'; import { useTransactionDistribution } from '../../../hooks/useTransactionDistribution'; diff --git a/x-pack/plugins/apm/public/components/shared/ManagedTable/index.tsx b/x-pack/plugins/apm/public/components/shared/ManagedTable/index.tsx index ef7ebe684fade..3dbb1b2faac02 100644 --- a/x-pack/plugins/apm/public/components/shared/ManagedTable/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/ManagedTable/index.tsx @@ -5,7 +5,7 @@ */ import { EuiBasicTable, EuiBasicTableColumn } from '@elastic/eui'; -import { sortByOrder } from 'lodash'; +import { orderBy } from 'lodash'; import React, { useMemo, useCallback, ReactNode } from 'react'; import { useUrlParams } from '../../../hooks/useUrlParams'; import { history } from '../../../utils/history'; @@ -58,9 +58,8 @@ function UnoptimizedManagedTable(props: Props) { } = useUrlParams(); const renderedItems = useMemo(() => { - // TODO: Use _.orderBy once we upgrade to lodash 4+ const sortedItems = sortItems - ? sortByOrder(items, sortField, sortDirection) + ? orderBy(items, sortField, sortDirection as 'asc' | 'desc') : items; return sortedItems.slice(page * pageSize, (page + 1) * pageSize); diff --git a/x-pack/plugins/apm/public/components/shared/Stacktrace/index.tsx b/x-pack/plugins/apm/public/components/shared/Stacktrace/index.tsx index 01043f33ec7b7..b37146f3b3be5 100644 --- a/x-pack/plugins/apm/public/components/shared/Stacktrace/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/Stacktrace/index.tsx @@ -87,7 +87,7 @@ export function getGroupedStackframes(stackframes: IStackframe[]) { !stackframe.exclude_from_grouping; // append to group - if (shouldAppend) { + if (prevGroup && shouldAppend) { prevGroup.stackframes.push(stackframe); return acc; } diff --git a/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/sections.ts b/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/sections.ts index 7f99939a0a0d0..d3a9ade3925a1 100644 --- a/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/sections.ts +++ b/x-pack/plugins/apm/public/components/shared/TransactionActionMenu/sections.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; import { Location } from 'history'; -import { pick, isEmpty } from 'lodash'; +import { pickBy, isEmpty } from 'lodash'; import moment from 'moment'; import url from 'url'; import { Transaction } from '../../../../typings/es_schemas/ui/transaction'; @@ -63,13 +63,13 @@ export const getSections = ({ const uptimeLink = url.format({ pathname: basePath.prepend('/app/uptime'), search: `?${fromQuery( - pick( + pickBy( { dateRangeStart: urlParams.rangeFrom, dateRangeEnd: urlParams.rangeTo, search: `url.domain:"${transaction.url?.domain}"`, }, - (val: string) => !isEmpty(val) + (val) => !isEmpty(val) ) )}`, }); diff --git a/x-pack/plugins/apm/public/components/shared/charts/ErrorRateChart/index.tsx b/x-pack/plugins/apm/public/components/shared/charts/ErrorRateChart/index.tsx index 7aafa9e1fdcec..de60441f4faa0 100644 --- a/x-pack/plugins/apm/public/components/shared/charts/ErrorRateChart/index.tsx +++ b/x-pack/plugins/apm/public/components/shared/charts/ErrorRateChart/index.tsx @@ -6,7 +6,7 @@ import { EuiTitle } from '@elastic/eui'; import theme from '@elastic/eui/dist/eui_theme_light.json'; import { i18n } from '@kbn/i18n'; -import mean from 'lodash.mean'; +import { mean } from 'lodash'; import React, { useCallback } from 'react'; import { useChartsSync } from '../../../../hooks/useChartsSync'; import { useFetcher } from '../../../../hooks/useFetcher'; diff --git a/x-pack/plugins/apm/public/context/LoadingIndicatorContext.tsx b/x-pack/plugins/apm/public/context/LoadingIndicatorContext.tsx index a26653d3d5294..99822c0bbc5ca 100644 --- a/x-pack/plugins/apm/public/context/LoadingIndicatorContext.tsx +++ b/x-pack/plugins/apm/public/context/LoadingIndicatorContext.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import { EuiPortal, EuiProgress } from '@elastic/eui'; -import { pick } from 'lodash'; +import { pickBy } from 'lodash'; import React, { Fragment, useMemo, useReducer } from 'react'; import { useDelayedVisibility } from '../components/shared/useDelayedVisibility'; @@ -26,7 +26,7 @@ function reducer(statuses: State, action: Action) { // Return an object with only the ids with `true` as their value, so that ids // that previously had `false` are removed and do not remain hanging around in // the object. - return pick( + return pickBy( { ...statuses, [action.id.toString()]: action.isLoading }, Boolean ); diff --git a/x-pack/plugins/apm/public/context/UrlParamsContext/helpers.ts b/x-pack/plugins/apm/public/context/UrlParamsContext/helpers.ts index 9ce993e848488..d9781400f2272 100644 --- a/x-pack/plugins/apm/public/context/UrlParamsContext/helpers.ts +++ b/x-pack/plugins/apm/public/context/UrlParamsContext/helpers.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { compact, pick } from 'lodash'; +import { compact, pickBy } from 'lodash'; import datemath from '@elastic/datemath'; import { IUrlParams } from './types'; import { ProcessorEvent } from '../../../common/processor_event'; @@ -61,8 +61,8 @@ export function getPathAsArray(pathname: string = '') { return compact(pathname.split('/')); } -export function removeUndefinedProps(obj: T): Partial { - return pick(obj, (value) => value !== undefined); +export function removeUndefinedProps(obj: T): Partial { + return pickBy(obj, (value) => value !== undefined); } export function getPathParams(pathname: string = ''): PathParams { diff --git a/x-pack/plugins/apm/public/services/rest/observability_dashboard.ts b/x-pack/plugins/apm/public/services/rest/observability_dashboard.ts index 589199221d7a9..79ccf8dbd6f9b 100644 --- a/x-pack/plugins/apm/public/services/rest/observability_dashboard.ts +++ b/x-pack/plugins/apm/public/services/rest/observability_dashboard.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; -import mean from 'lodash.mean'; +import { mean } from 'lodash'; import { Theme } from '@kbn/ui-shared-deps/theme'; import { ApmFetchDataResponse, diff --git a/x-pack/plugins/apm/server/lib/service_map/__snapshots__/get_service_map_from_trace_ids.test.ts.snap b/x-pack/plugins/apm/server/lib/service_map/__snapshots__/get_service_map_from_trace_ids.test.ts.snap new file mode 100644 index 0000000000000..1f4a8a4367fad --- /dev/null +++ b/x-pack/plugins/apm/server/lib/service_map/__snapshots__/get_service_map_from_trace_ids.test.ts.snap @@ -0,0 +1,222 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`getConnections transforms a list of paths into a list of connections filtered by service.name and environment 1`] = ` +Array [ + Object { + "destination": Object { + "agent.name": "nodejs", + "service.environment": "production", + "service.name": "opbeans-node", + }, + "source": Object { + "agent.name": "python", + "service.environment": "production", + "service.name": "opbeans-python", + }, + }, + Object { + "destination": Object { + "span.destination.service.resource": "172.18.0.6:3000", + "span.subtype": "http", + "span.type": "external", + }, + "source": Object { + "agent.name": "nodejs", + "service.environment": "production", + "service.name": "opbeans-node", + }, + }, + Object { + "destination": Object { + "agent.name": "python", + "service.environment": "production", + "service.name": "opbeans-python", + }, + "source": Object { + "agent.name": "nodejs", + "service.environment": "production", + "service.name": "opbeans-node", + }, + }, + Object { + "destination": Object { + "agent.name": "ruby", + "service.environment": "production", + "service.name": "opbeans-ruby", + }, + "source": Object { + "agent.name": "python", + "service.environment": "production", + "service.name": "opbeans-python", + }, + }, + Object { + "destination": Object { + "span.destination.service.resource": "postgresql", + "span.subtype": "postgresql", + "span.type": "db", + }, + "source": Object { + "agent.name": "ruby", + "service.environment": "production", + "service.name": "opbeans-ruby", + }, + }, + Object { + "destination": Object { + "agent.name": "ruby", + "service.environment": "production", + "service.name": "opbeans-ruby", + }, + "source": Object { + "agent.name": "nodejs", + "service.environment": "production", + "service.name": "opbeans-node", + }, + }, + Object { + "destination": Object { + "span.destination.service.resource": "opbeans-python:3000", + "span.subtype": "http_rb", + "span.type": "ext", + }, + "source": Object { + "agent.name": "ruby", + "service.environment": "production", + "service.name": "opbeans-ruby", + }, + }, + Object { + "destination": Object { + "agent.name": "nodejs", + "service.environment": "production", + "service.name": "opbeans-node", + }, + "source": Object { + "agent.name": "ruby", + "service.environment": "production", + "service.name": "opbeans-ruby", + }, + }, + Object { + "destination": Object { + "span.destination.service.resource": "opbeans-node:3000", + "span.subtype": "http", + "span.type": "external", + }, + "source": Object { + "agent.name": "python", + "service.environment": "production", + "service.name": "opbeans-python", + }, + }, + Object { + "destination": Object { + "span.destination.service.resource": "172.18.0.7:3000", + "span.subtype": "http", + "span.type": "external", + }, + "source": Object { + "agent.name": "nodejs", + "service.environment": "production", + "service.name": "opbeans-node", + }, + }, + Object { + "destination": Object { + "span.destination.service.resource": "postgresql", + "span.subtype": "postgresql", + "span.type": "db", + }, + "source": Object { + "agent.name": "python", + "service.environment": "production", + "service.name": "opbeans-python", + }, + }, + Object { + "destination": Object { + "agent.name": "python", + "service.environment": "production", + "service.name": "opbeans-python", + }, + "source": Object { + "agent.name": "ruby", + "service.environment": "production", + "service.name": "opbeans-ruby", + }, + }, + Object { + "destination": Object { + "span.destination.service.resource": "postgresql", + "span.subtype": "postgresql", + "span.type": "db", + }, + "source": Object { + "agent.name": "nodejs", + "service.environment": "production", + "service.name": "opbeans-node", + }, + }, + Object { + "destination": Object { + "span.destination.service.resource": "93.184.216.34:80", + "span.subtype": "http", + "span.type": "external", + }, + "source": Object { + "agent.name": "nodejs", + "service.environment": "production", + "service.name": "opbeans-node", + }, + }, + Object { + "destination": Object { + "span.destination.service.resource": "opbeans-ruby:3000", + "span.subtype": "http_rb", + "span.type": "ext", + }, + "source": Object { + "agent.name": "ruby", + "service.environment": "production", + "service.name": "opbeans-ruby", + }, + }, + Object { + "destination": Object { + "span.destination.service.resource": "redis", + "span.subtype": "redis", + "span.type": "cache", + }, + "source": Object { + "agent.name": "nodejs", + "service.environment": "production", + "service.name": "opbeans-node", + }, + }, + Object { + "destination": Object { + "span.destination.service.resource": "opbeans-node:3000", + "span.subtype": "http_rb", + "span.type": "ext", + }, + "source": Object { + "agent.name": "ruby", + "service.environment": "production", + "service.name": "opbeans-ruby", + }, + }, + Object { + "destination": Object { + "span.destination.service.resource": "opbeans-ruby:3000", + "span.subtype": "http", + "span.type": "external", + }, + "source": Object { + "agent.name": "python", + "service.environment": "production", + "service.name": "opbeans-python", + }, + }, +] +`; diff --git a/x-pack/plugins/apm/server/lib/service_map/fetch_service_paths_from_trace_ids.ts b/x-pack/plugins/apm/server/lib/service_map/fetch_service_paths_from_trace_ids.ts new file mode 100644 index 0000000000000..08c8aba5f0207 --- /dev/null +++ b/x-pack/plugins/apm/server/lib/service_map/fetch_service_paths_from_trace_ids.ts @@ -0,0 +1,232 @@ +/* + * 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 { + PROCESSOR_EVENT, + TRACE_ID, +} from '../../../common/elasticsearch_fieldnames'; +import { + ConnectionNode, + ExternalConnectionNode, + ServiceConnectionNode, +} from '../../../common/service_map'; +import { Setup } from '../helpers/setup_request'; + +export async function fetchServicePathsFromTraceIds( + setup: Setup, + traceIds: string[] +) { + const { indices, client } = setup; + + const serviceMapParams = { + index: [ + indices['apm_oss.spanIndices'], + indices['apm_oss.transactionIndices'], + ], + body: { + size: 0, + query: { + bool: { + filter: [ + { + terms: { + [PROCESSOR_EVENT]: ['span', 'transaction'], + }, + }, + { + terms: { + [TRACE_ID]: traceIds, + }, + }, + ], + }, + }, + aggs: { + service_map: { + scripted_metric: { + init_script: { + lang: 'painless', + source: `state.eventsById = new HashMap(); + + String[] fieldsToCopy = new String[] { + 'parent.id', + 'service.name', + 'service.environment', + 'span.destination.service.resource', + 'trace.id', + 'processor.event', + 'span.type', + 'span.subtype', + 'agent.name' + }; + state.fieldsToCopy = fieldsToCopy;`, + }, + map_script: { + lang: 'painless', + source: `def id; + if (!doc['span.id'].empty) { + id = doc['span.id'].value; + } else { + id = doc['transaction.id'].value; + } + + def copy = new HashMap(); + copy.id = id; + + for(key in state.fieldsToCopy) { + if (!doc[key].empty) { + copy[key] = doc[key].value; + } + } + + state.eventsById[id] = copy`, + }, + combine_script: { + lang: 'painless', + source: `return state.eventsById;`, + }, + reduce_script: { + lang: 'painless', + source: ` + def getDestination ( def event ) { + def destination = new HashMap(); + destination['span.destination.service.resource'] = event['span.destination.service.resource']; + destination['span.type'] = event['span.type']; + destination['span.subtype'] = event['span.subtype']; + return destination; + } + + def processAndReturnEvent(def context, def eventId) { + if (context.processedEvents[eventId] != null) { + return context.processedEvents[eventId]; + } + + def event = context.eventsById[eventId]; + + if (event == null) { + return null; + } + + def service = new HashMap(); + service['service.name'] = event['service.name']; + service['service.environment'] = event['service.environment']; + service['agent.name'] = event['agent.name']; + + def basePath = new ArrayList(); + + def parentId = event['parent.id']; + def parent; + + if (parentId != null && parentId != event['id']) { + parent = processAndReturnEvent(context, parentId); + if (parent != null) { + /* copy the path from the parent */ + basePath.addAll(parent.path); + /* flag parent path for removal, as it has children */ + context.locationsToRemove.add(parent.path); + + /* if the parent has 'span.destination.service.resource' set, and the service is different, + we've discovered a service */ + + if (parent['span.destination.service.resource'] != null + && parent['span.destination.service.resource'] != "" + && (parent['service.name'] != event['service.name'] + || parent['service.environment'] != event['service.environment'] + ) + ) { + def parentDestination = getDestination(parent); + context.externalToServiceMap.put(parentDestination, service); + } + } + } + + def lastLocation = basePath.size() > 0 ? basePath[basePath.size() - 1] : null; + + def currentLocation = service; + + /* only add the current location to the path if it's different from the last one*/ + if (lastLocation == null || !lastLocation.equals(currentLocation)) { + basePath.add(currentLocation); + } + + /* if there is an outgoing span, create a new path */ + if (event['span.destination.service.resource'] != null + && event['span.destination.service.resource'] != '') { + def outgoingLocation = getDestination(event); + def outgoingPath = new ArrayList(basePath); + outgoingPath.add(outgoingLocation); + context.paths.add(outgoingPath); + } + + event.path = basePath; + + context.processedEvents[eventId] = event; + return event; + } + + def context = new HashMap(); + + context.processedEvents = new HashMap(); + context.eventsById = new HashMap(); + + context.paths = new HashSet(); + context.externalToServiceMap = new HashMap(); + context.locationsToRemove = new HashSet(); + + for (state in states) { + context.eventsById.putAll(state); + } + + for (entry in context.eventsById.entrySet()) { + processAndReturnEvent(context, entry.getKey()); + } + + def paths = new HashSet(); + + for(foundPath in context.paths) { + if (!context.locationsToRemove.contains(foundPath)) { + paths.add(foundPath); + } + } + + def response = new HashMap(); + response.paths = paths; + + def discoveredServices = new HashSet(); + + for(entry in context.externalToServiceMap.entrySet()) { + def map = new HashMap(); + map.from = entry.getKey(); + map.to = entry.getValue(); + discoveredServices.add(map); + } + response.discoveredServices = discoveredServices; + + return response;`, + }, + }, + }, + }, + }, + }; + + const serviceMapFromTraceIdsScriptResponse = await client.search( + serviceMapParams + ); + + return serviceMapFromTraceIdsScriptResponse as { + aggregations?: { + service_map: { + value: { + paths: ConnectionNode[][]; + discoveredServices: Array<{ + from: ExternalConnectionNode; + to: ServiceConnectionNode; + }>; + }; + }; + }; + }; +} diff --git a/x-pack/plugins/apm/server/lib/service_map/get_service_map_from_trace_ids.test.ts b/x-pack/plugins/apm/server/lib/service_map/get_service_map_from_trace_ids.test.ts new file mode 100644 index 0000000000000..a3a7e5c995bfe --- /dev/null +++ b/x-pack/plugins/apm/server/lib/service_map/get_service_map_from_trace_ids.test.ts @@ -0,0 +1,28 @@ +/* + * 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 { getConnections } from './get_service_map_from_trace_ids'; +import serviceMapFromTraceIdsScriptResponse from './mock_responses/get_service_map_from_trace_ids_script_response.json'; +import { PromiseReturnType } from '../../../typings/common'; +import { fetchServicePathsFromTraceIds } from './fetch_service_paths_from_trace_ids'; + +describe('getConnections', () => { + it('transforms a list of paths into a list of connections filtered by service.name and environment', () => { + const response = serviceMapFromTraceIdsScriptResponse as PromiseReturnType< + typeof fetchServicePathsFromTraceIds + >; + const serviceName = 'opbeans-node'; + const environment = 'production'; + + const connections = getConnections( + response.aggregations?.service_map.value.paths, + serviceName, + environment + ); + + expect(connections).toMatchSnapshot(); + }); +}); diff --git a/x-pack/plugins/apm/server/lib/service_map/get_service_map_from_trace_ids.ts b/x-pack/plugins/apm/server/lib/service_map/get_service_map_from_trace_ids.ts index 01cbc1aa9b989..f6e331a09fa65 100644 --- a/x-pack/plugins/apm/server/lib/service_map/get_service_map_from_trace_ids.ts +++ b/x-pack/plugins/apm/server/lib/service_map/get_service_map_from_trace_ids.ts @@ -3,237 +3,27 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { find, uniq } from 'lodash'; +import { find, uniqBy } from 'lodash'; import { - PROCESSOR_EVENT, SERVICE_ENVIRONMENT, SERVICE_NAME, - TRACE_ID, } from '../../../common/elasticsearch_fieldnames'; import { Connection, ConnectionNode, - ExternalConnectionNode, ServiceConnectionNode, } from '../../../common/service_map'; import { Setup } from '../helpers/setup_request'; - -export async function getServiceMapFromTraceIds({ - setup, - traceIds, - serviceName, - environment, -}: { - setup: Setup; - traceIds: string[]; - serviceName?: string; - environment?: string; -}) { - const { indices, client } = setup; - - const serviceMapParams = { - index: [ - indices['apm_oss.spanIndices'], - indices['apm_oss.transactionIndices'], - ], - body: { - size: 0, - query: { - bool: { - filter: [ - { - terms: { - [PROCESSOR_EVENT]: ['span', 'transaction'], - }, - }, - { - terms: { - [TRACE_ID]: traceIds, - }, - }, - ], - }, - }, - aggs: { - service_map: { - scripted_metric: { - init_script: { - lang: 'painless', - source: `state.eventsById = new HashMap(); - - String[] fieldsToCopy = new String[] { - 'parent.id', - 'service.name', - 'service.environment', - 'span.destination.service.resource', - 'trace.id', - 'processor.event', - 'span.type', - 'span.subtype', - 'agent.name' - }; - state.fieldsToCopy = fieldsToCopy;`, - }, - map_script: { - lang: 'painless', - source: `def id; - if (!doc['span.id'].empty) { - id = doc['span.id'].value; - } else { - id = doc['transaction.id'].value; - } - - def copy = new HashMap(); - copy.id = id; - - for(key in state.fieldsToCopy) { - if (!doc[key].empty) { - copy[key] = doc[key].value; - } - } - - state.eventsById[id] = copy`, - }, - combine_script: { - lang: 'painless', - source: `return state.eventsById;`, - }, - reduce_script: { - lang: 'painless', - source: ` - def getDestination ( def event ) { - def destination = new HashMap(); - destination['span.destination.service.resource'] = event['span.destination.service.resource']; - destination['span.type'] = event['span.type']; - destination['span.subtype'] = event['span.subtype']; - return destination; - } - - def processAndReturnEvent(def context, def eventId) { - if (context.processedEvents[eventId] != null) { - return context.processedEvents[eventId]; - } - - def event = context.eventsById[eventId]; - - if (event == null) { - return null; - } - - def service = new HashMap(); - service['service.name'] = event['service.name']; - service['service.environment'] = event['service.environment']; - service['agent.name'] = event['agent.name']; - - def basePath = new ArrayList(); - - def parentId = event['parent.id']; - def parent; - - if (parentId != null && parentId != event['id']) { - parent = processAndReturnEvent(context, parentId); - if (parent != null) { - /* copy the path from the parent */ - basePath.addAll(parent.path); - /* flag parent path for removal, as it has children */ - context.locationsToRemove.add(parent.path); - - /* if the parent has 'span.destination.service.resource' set, and the service is different, - we've discovered a service */ - - if (parent['span.destination.service.resource'] != null - && parent['span.destination.service.resource'] != "" - && (parent['service.name'] != event['service.name'] - || parent['service.environment'] != event['service.environment'] - ) - ) { - def parentDestination = getDestination(parent); - context.externalToServiceMap.put(parentDestination, service); - } - } - } - - def lastLocation = basePath.size() > 0 ? basePath[basePath.size() - 1] : null; - - def currentLocation = service; - - /* only add the current location to the path if it's different from the last one*/ - if (lastLocation == null || !lastLocation.equals(currentLocation)) { - basePath.add(currentLocation); - } - - /* if there is an outgoing span, create a new path */ - if (event['span.destination.service.resource'] != null - && event['span.destination.service.resource'] != '') { - def outgoingLocation = getDestination(event); - def outgoingPath = new ArrayList(basePath); - outgoingPath.add(outgoingLocation); - context.paths.add(outgoingPath); - } - - event.path = basePath; - - context.processedEvents[eventId] = event; - return event; - } - - def context = new HashMap(); - - context.processedEvents = new HashMap(); - context.eventsById = new HashMap(); - - context.paths = new HashSet(); - context.externalToServiceMap = new HashMap(); - context.locationsToRemove = new HashSet(); - - for (state in states) { - context.eventsById.putAll(state); - } - - for (entry in context.eventsById.entrySet()) { - processAndReturnEvent(context, entry.getKey()); - } - - def paths = new HashSet(); - - for(foundPath in context.paths) { - if (!context.locationsToRemove.contains(foundPath)) { - paths.add(foundPath); - } - } - - def response = new HashMap(); - response.paths = paths; - - def discoveredServices = new HashSet(); - - for(entry in context.externalToServiceMap.entrySet()) { - def map = new HashMap(); - map.from = entry.getKey(); - map.to = entry.getValue(); - discoveredServices.add(map); - } - response.discoveredServices = discoveredServices; - - return response;`, - }, - }, - }, - }, - }, - }; - - const serviceMapResponse = await client.search(serviceMapParams); - - const scriptResponse = serviceMapResponse.aggregations?.service_map.value as { - paths: ConnectionNode[][]; - discoveredServices: Array<{ - from: ExternalConnectionNode; - to: ServiceConnectionNode; - }>; - }; - - let paths = scriptResponse.paths; +import { fetchServicePathsFromTraceIds } from './fetch_service_paths_from_trace_ids'; + +export function getConnections( + paths?: ConnectionNode[][], + serviceName?: string, + environment?: string +) { + if (!paths) { + return []; + } if (serviceName || environment) { paths = paths.filter((path) => { @@ -257,26 +47,51 @@ export async function getServiceMapFromTraceIds({ }); } - const connections = uniq( - paths.flatMap((path) => { - return path.reduce((conns, location, index) => { - const prev = path[index - 1]; - if (prev) { - return conns.concat({ - source: prev, - destination: location, - }); - } - return conns; - }, [] as Connection[]); - }, [] as Connection[]), - (value, _index, array) => { - return find(array, value); - } + const connectionsArr = paths.flatMap((path) => { + return path.reduce((conns, location, index) => { + const prev = path[index - 1]; + if (prev) { + return conns.concat({ + source: prev, + destination: location, + }); + } + return conns; + }, [] as Connection[]); + }, [] as Connection[]); + + const connections = uniqBy(connectionsArr, (value) => + find(connectionsArr, value) ); + return connections; +} + +export async function getServiceMapFromTraceIds({ + setup, + traceIds, + serviceName, + environment, +}: { + setup: Setup; + traceIds: string[]; + serviceName?: string; + environment?: string; +}) { + const serviceMapFromTraceIdsScriptResponse = await fetchServicePathsFromTraceIds( + setup, + traceIds + ); + + const serviceMapScriptedAggValue = + serviceMapFromTraceIdsScriptResponse.aggregations?.service_map.value; + return { - connections, - discoveredServices: scriptResponse.discoveredServices, + connections: getConnections( + serviceMapScriptedAggValue?.paths, + serviceName, + environment + ), + discoveredServices: serviceMapScriptedAggValue?.discoveredServices ?? [], }; } diff --git a/x-pack/plugins/apm/server/lib/service_map/mock_responses/get_service_map_from_trace_ids_script_response.json b/x-pack/plugins/apm/server/lib/service_map/mock_responses/get_service_map_from_trace_ids_script_response.json new file mode 100644 index 0000000000000..49d8efebbf43b --- /dev/null +++ b/x-pack/plugins/apm/server/lib/service_map/mock_responses/get_service_map_from_trace_ids_script_response.json @@ -0,0 +1,1165 @@ +{ + "took": 43, + "timed_out": false, + "_shards": { "total": 6, "successful": 6, "skipped": 0, "failed": 0 }, + "hits": { + "total": { "value": 465, "relation": "eq" }, + "max_score": null, + "hits": [] + }, + "aggregations": { + "service_map": { + "value": { + "paths": [ + [ + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "172.18.0.6:3000", + "span.type": "external" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "http_rb", + "span.destination.service.resource": "opbeans-python:3000", + "span.type": "ext" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "172.18.0.6:3000", + "span.type": "external" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "opbeans-node:3000", + "span.type": "external" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "172.18.0.7:3000", + "span.type": "external" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "opbeans-ruby:3000", + "span.type": "external" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "172.18.0.7:3000", + "span.type": "external" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "opbeans-node:3000", + "span.type": "external" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "opbeans-node:3000", + "span.type": "external" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "http_rb", + "span.destination.service.resource": "opbeans-node:3000", + "span.type": "ext" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "opbeans-ruby:3000", + "span.type": "external" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "172.18.0.7:3000", + "span.type": "external" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "http_rb", + "span.destination.service.resource": "opbeans-python:3000", + "span.type": "ext" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "93.184.216.34:80", + "span.type": "external" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "http_rb", + "span.destination.service.resource": "opbeans-ruby:3000", + "span.type": "ext" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "http_rb", + "span.destination.service.resource": "opbeans-node:3000", + "span.type": "ext" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "http_rb", + "span.destination.service.resource": "opbeans-python:3000", + "span.type": "ext" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "172.18.0.7:3000", + "span.type": "external" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "http_rb", + "span.destination.service.resource": "opbeans-ruby:3000", + "span.type": "ext" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "http_rb", + "span.destination.service.resource": "opbeans-ruby:3000", + "span.type": "ext" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "redis", + "span.destination.service.resource": "redis", + "span.type": "cache" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "http_rb", + "span.destination.service.resource": "opbeans-python:3000", + "span.type": "ext" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "redis", + "span.destination.service.resource": "redis", + "span.type": "cache" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "opbeans-node:3000", + "span.type": "external" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "opbeans-node:3000", + "span.type": "external" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "http_rb", + "span.destination.service.resource": "opbeans-node:3000", + "span.type": "ext" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "opbeans-ruby:3000", + "span.type": "external" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "http_rb", + "span.destination.service.resource": "opbeans-node:3000", + "span.type": "ext" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "postgresql", + "span.destination.service.resource": "postgresql", + "span.type": "db" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "redis", + "span.destination.service.resource": "redis", + "span.type": "cache" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "http_rb", + "span.destination.service.resource": "opbeans-python:3000", + "span.type": "ext" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "172.18.0.6:3000", + "span.type": "external" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "http_rb", + "span.destination.service.resource": "opbeans-ruby:3000", + "span.type": "ext" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "redis", + "span.destination.service.resource": "redis", + "span.type": "cache" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "span.subtype": "http_rb", + "span.destination.service.resource": "opbeans-node:3000", + "span.type": "ext" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "redis", + "span.destination.service.resource": "redis", + "span.type": "cache" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + }, + { + "span.subtype": "redis", + "span.destination.service.resource": "redis", + "span.type": "cache" + } + ], + [ + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + }, + { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + }, + { + "span.subtype": "http", + "span.destination.service.resource": "opbeans-node:3000", + "span.type": "external" + } + ] + ], + "discoveredServices": [ + { + "from": { + "span.subtype": "http", + "span.destination.service.resource": "opbeans-node:3000", + "span.type": "external" + }, + "to": { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + } + }, + { + "from": { + "span.subtype": "http", + "span.destination.service.resource": "172.18.0.7:3000", + "span.type": "external" + }, + "to": { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + } + }, + { + "from": { + "span.subtype": "http", + "span.destination.service.resource": "opbeans-ruby:3000", + "span.type": "external" + }, + "to": { + "service.environment": "production", + "service.name": "opbeans-ruby", + "agent.name": "ruby" + } + }, + { + "from": { + "span.subtype": "http_rb", + "span.destination.service.resource": "opbeans-node:3000", + "span.type": "ext" + }, + "to": { + "service.environment": "production", + "service.name": "opbeans-node", + "agent.name": "nodejs" + } + }, + { + "from": { + "span.subtype": "http_rb", + "span.destination.service.resource": "opbeans-python:3000", + "span.type": "ext" + }, + "to": { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + } + }, + { + "from": { + "span.subtype": "http", + "span.destination.service.resource": "172.18.0.6:3000", + "span.type": "external" + }, + "to": { + "service.environment": "production", + "service.name": "opbeans-python", + "agent.name": "python" + } + } + ] + } + } + } +} diff --git a/x-pack/plugins/apm/server/lib/service_map/transform_service_map_responses.ts b/x-pack/plugins/apm/server/lib/service_map/transform_service_map_responses.ts index 835c00b8df239..2e394f44b25b1 100644 --- a/x-pack/plugins/apm/server/lib/service_map/transform_service_map_responses.ts +++ b/x-pack/plugins/apm/server/lib/service_map/transform_service_map_responses.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { sortBy, pick, identity } from 'lodash'; +import { sortBy, pickBy, identity } from 'lodash'; import { ValuesType } from 'utility-types'; import { SERVICE_NAME, @@ -112,7 +112,7 @@ export function transformServiceMapResponses(response: ServiceMapResponse) { id: matchedServiceNodes[0][SERVICE_NAME], }, ...matchedServiceNodes.map((serviceNode) => - pick(serviceNode, identity) + pickBy(serviceNode, identity) ) ), }; diff --git a/x-pack/plugins/apm/server/lib/transaction_groups/transform.ts b/x-pack/plugins/apm/server/lib/transaction_groups/transform.ts index 81dba39e9d712..b04ff6764675d 100644 --- a/x-pack/plugins/apm/server/lib/transaction_groups/transform.ts +++ b/x-pack/plugins/apm/server/lib/transaction_groups/transform.ts @@ -5,7 +5,7 @@ */ import moment from 'moment'; -import { sortByOrder } from 'lodash'; +import { orderBy } from 'lodash'; import { ESResponse } from './fetcher'; function calculateRelativeImpacts(items: ITransactionGroup[]) { @@ -27,7 +27,7 @@ function calculateRelativeImpacts(items: ITransactionGroup[]) { const getBuckets = (response: ESResponse) => { if (response.aggregations) { - return sortByOrder( + return orderBy( response.aggregations.transaction_groups.buckets, ['sum.value'], ['desc'] diff --git a/x-pack/plugins/apm/server/lib/transactions/breakdown/index.ts b/x-pack/plugins/apm/server/lib/transactions/breakdown/index.ts index 5af8b9f78cec1..3c48c14c2a471 100644 --- a/x-pack/plugins/apm/server/lib/transactions/breakdown/index.ts +++ b/x-pack/plugins/apm/server/lib/transactions/breakdown/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { flatten, sortByOrder, last } from 'lodash'; +import { flatten, orderBy, last } from 'lodash'; import { SERVICE_NAME, SPAN_SUBTYPE, @@ -138,13 +138,13 @@ export async function getTransactionBreakdown({ }; const visibleKpis = resp.aggregations - ? sortByOrder(formatBucket(resp.aggregations), 'percentage', 'desc').slice( + ? orderBy(formatBucket(resp.aggregations), 'percentage', 'desc').slice( 0, MAX_KPIS ) : []; - const kpis = sortByOrder(visibleKpis, 'name').map((kpi, index) => { + const kpis = orderBy(visibleKpis, 'name').map((kpi, index) => { return { ...kpi, color: getVizColorForIndex(index), @@ -186,8 +186,8 @@ export async function getTransactionBreakdown({ // is drawn correctly. // If we set all values to 0, the chart always displays null values as 0, // and the chart looks weird. - const hasAnyValues = lastValues.some((value) => value.y !== null); - const hasNullValues = lastValues.some((value) => value.y === null); + const hasAnyValues = lastValues.some((value) => value?.y !== null); + const hasNullValues = lastValues.some((value) => value?.y === null); if (hasAnyValues && hasNullValues) { Object.values(updatedSeries).forEach((series) => { diff --git a/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/index.ts b/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/index.ts index 31bc0563ec13f..588d5c7896db9 100644 --- a/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/index.ts +++ b/x-pack/plugins/apm/server/lib/ui_filters/local_ui_filters/index.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { cloneDeep, sortByOrder } from 'lodash'; +import { cloneDeep, orderBy } from 'lodash'; import { UIFilters } from '../../../../typings/ui_filters'; import { Projection } from '../../../../common/projections/typings'; import { PromiseReturnType } from '../../../../../observability/typings/common'; @@ -47,7 +47,7 @@ export async function getLocalUIFilters({ return { ...filter, - options: sortByOrder( + options: orderBy( buckets.map((bucket) => { return { name: bucket.key as string, diff --git a/x-pack/plugins/apm/server/routes/create_api/index.ts b/x-pack/plugins/apm/server/routes/create_api/index.ts index b21f0ea8d32db..92f52dd1552d6 100644 --- a/x-pack/plugins/apm/server/routes/create_api/index.ts +++ b/x-pack/plugins/apm/server/routes/create_api/index.ts @@ -140,6 +140,7 @@ export function createApi() { // Only return values for parameters that have runtime types, // but always include query as _debug is always set even if // it's not defined in the route. + // @ts-ignore params: pick(parsedParams, ...Object.keys(params), 'query'), config, logger, diff --git a/x-pack/plugins/apm/server/routes/services.ts b/x-pack/plugins/apm/server/routes/services.ts index 08eba00251e26..74ab717b8de59 100644 --- a/x-pack/plugins/apm/server/routes/services.ts +++ b/x-pack/plugins/apm/server/routes/services.ts @@ -6,7 +6,7 @@ import * as t from 'io-ts'; import Boom from 'boom'; -import { unique } from 'lodash'; +import { uniq } from 'lodash'; import { setupRequest } from '../lib/helpers/setup_request'; import { getServiceAgentName } from '../lib/services/get_service_agent_name'; import { getServices } from '../lib/services/get_services'; @@ -160,7 +160,7 @@ export const serviceAnnotationsCreateRoute = createRoute(() => ({ ...body.service, name: path.serviceName, }, - tags: unique(['apm'].concat(body.tags ?? [])), + tags: uniq(['apm'].concat(body.tags ?? [])), }); }, })); diff --git a/x-pack/plugins/apm/typings/lodash.mean.d.ts b/x-pack/plugins/apm/typings/lodash.mean.d.ts deleted file mode 100644 index 0b9ca3f6914cb..0000000000000 --- a/x-pack/plugins/apm/typings/lodash.mean.d.ts +++ /dev/null @@ -1,10 +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. - */ - -declare module 'lodash.mean' { - function mean(numbers: Array): number; - export = mean; -} diff --git a/x-pack/plugins/beats_management/public/components/enroll_beats.tsx b/x-pack/plugins/beats_management/public/components/enroll_beats.tsx index e609cd83587ce..5bf0f51f48355 100644 --- a/x-pack/plugins/beats_management/public/components/enroll_beats.tsx +++ b/x-pack/plugins/beats_management/public/components/enroll_beats.tsx @@ -18,7 +18,7 @@ import { EuiTitle, } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; -import { capitalize } from 'lodash'; +import { upperFirst } from 'lodash'; import React from 'react'; import { CMBeat } from '../../../../legacy/plugins/beats_management/common/domain_types'; @@ -93,7 +93,7 @@ export class EnrollBeat extends React.Component } const cmdText = `${this.state.command .replace('{{beatType}}', this.state.beatType) - .replace('{{beatTypeInCaps}}', capitalize(this.state.beatType))} enroll ${ + .replace('{{beatTypeInCaps}}', upperFirst(this.state.beatType))} enroll ${ window.location.protocol }//${window.location.host}${this.props.frameworkBasePath} ${this.props.enrollmentToken}`; @@ -183,7 +183,7 @@ export class EnrollBeat extends React.Component id="xpack.beatsManagement.enrollBeat.yourBeatTypeHostTitle" defaultMessage="On the host where your {beatType} is installed, run:" values={{ - beatType: capitalize(this.state.beatType), + beatType: upperFirst(this.state.beatType), }} /> @@ -220,7 +220,7 @@ export class EnrollBeat extends React.Component id="xpack.beatsManagement.enrollBeat.waitingBeatTypeToEnrollTitle" defaultMessage="Waiting for {beatType} to enroll…" values={{ - beatType: capitalize(this.state.beatType), + beatType: upperFirst(this.state.beatType), }} /> diff --git a/x-pack/plugins/beats_management/public/components/navigation/connected_link.tsx b/x-pack/plugins/beats_management/public/components/navigation/connected_link.tsx index 947e22ee29089..ebac34afa016b 100644 --- a/x-pack/plugins/beats_management/public/components/navigation/connected_link.tsx +++ b/x-pack/plugins/beats_management/public/components/navigation/connected_link.tsx @@ -3,6 +3,8 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ + +import _ from 'lodash'; import React from 'react'; import { EuiLink } from '@elastic/eui'; diff --git a/x-pack/plugins/beats_management/public/components/table/table_type_configs.tsx b/x-pack/plugins/beats_management/public/components/table/table_type_configs.tsx index 94e4ca46aec19..6bbf269711fbd 100644 --- a/x-pack/plugins/beats_management/public/components/table/table_type_configs.tsx +++ b/x-pack/plugins/beats_management/public/components/table/table_type_configs.tsx @@ -6,7 +6,7 @@ import { EuiFlexGroup, EuiFlexItem, EuiHealth, EuiToolTip, IconColor } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; -import { sortBy, uniq } from 'lodash'; +import { sortBy, uniqBy } from 'lodash'; import moment from 'moment'; import React from 'react'; import { @@ -226,7 +226,7 @@ export const BeatsTableType: TableType = { // render: (tags?: BeatTag[]) => // tags && tags.length ? ( // - // {moment(first(sortByOrder(tags, ['last_updated'], ['desc'])).last_updated).fromNow()} + // {moment(first(orderBy(tags, ['last_updated'], ['desc'])).last_updated).fromNow()} // // ) : null, // sortable: true, @@ -249,7 +249,7 @@ export const BeatsTableType: TableType = { name: i18n.translate('xpack.beatsManagement.beatsTable.typeLabel', { defaultMessage: 'Type', }), - options: uniq( + options: uniqBy( data.map(({ type }: { type: any }) => ({ value: type })), 'value' ), diff --git a/x-pack/plugins/beats_management/public/lib/adapters/beats/memory_beats_adapter.ts b/x-pack/plugins/beats_management/public/lib/adapters/beats/memory_beats_adapter.ts index 8e3f58b18f391..24a7e5c3af8fa 100644 --- a/x-pack/plugins/beats_management/public/lib/adapters/beats/memory_beats_adapter.ts +++ b/x-pack/plugins/beats_management/public/lib/adapters/beats/memory_beats_adapter.ts @@ -32,14 +32,14 @@ export class MemoryBeatsAdapter implements CMBeatsAdapter { } public async getAll() { - return this.beatsDB.map((beat: any) => omit(beat, ['access_token'])); + return this.beatsDB.map((beat: any) => omit(beat, ['access_token'])) as CMBeat[]; } public async getBeatsWithTag(tagId: string): Promise { - return this.beatsDB.map((beat: any) => omit(beat, ['access_token'])); + return this.beatsDB.map((beat: any) => omit(beat, ['access_token'])) as CMBeat[]; } public async getBeatWithToken(enrollmentToken: string): Promise { - return this.beatsDB.map((beat: any) => omit(beat, ['access_token']))[0]; + return this.beatsDB.map((beat: any) => omit(beat, ['access_token']))[0] as CMBeat | null; } public async removeTagsFromBeats( removals: BeatsTagAssignment[] @@ -66,11 +66,11 @@ export class MemoryBeatsAdapter implements CMBeatsAdapter { return beat; }); - return response.map((item: CMBeat, resultIdx: number) => ({ + return response.map((item: CMBeat, resultIdx: number) => ({ idxInRequest: removals[resultIdx].idxInRequest, result: 'updated', status: 200, - })); + })) as any; } public async assignTagsToBeats( diff --git a/x-pack/plugins/beats_management/public/lib/framework.ts b/x-pack/plugins/beats_management/public/lib/framework.ts index 9e4271c683415..63a81e0895348 100644 --- a/x-pack/plugins/beats_management/public/lib/framework.ts +++ b/x-pack/plugins/beats_management/public/lib/framework.ts @@ -58,6 +58,6 @@ export class FrameworkLib { public currentUserHasOneOfRoles(roles: string[]) { // If the user has at least one of the roles requested, the returnd difference will be less // then the orig array size. difference only compares based on the left side arg - return difference(roles, get(this.currentUser, 'roles', [])).length < roles.length; + return difference(roles, get(this.currentUser, 'roles', []) as string[]).length < roles.length; } } diff --git a/x-pack/plugins/canvas/.storybook/webpack.dll.config.js b/x-pack/plugins/canvas/.storybook/webpack.dll.config.js index 0a648e861b386..5fdc4519f3bd7 100644 --- a/x-pack/plugins/canvas/.storybook/webpack.dll.config.js +++ b/x-pack/plugins/canvas/.storybook/webpack.dll.config.js @@ -39,7 +39,6 @@ module.exports = { 'highlight.js', 'html-entities', 'jquery', - 'lodash.clone', 'lodash', 'markdown-it', 'mocha', diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/pie.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/pie.ts index b568f18924869..c32c553fffc1b 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/pie.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/pie.ts @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { get, map, groupBy } from 'lodash'; -// @ts-expect-error lodash.keyby imports invalid member from @types/lodash -import keyBy from 'lodash.keyby'; +import { get, keyBy, map, groupBy } from 'lodash'; // @ts-expect-error untyped local import { getColorsFromPalette } from '../../../common/lib/get_colors_from_palette'; // @ts-expect-error untyped local diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/plot/get_tick_hash.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/plot/get_tick_hash.ts index 4839db047c871..21166454e478f 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/plot/get_tick_hash.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/plot/get_tick_hash.ts @@ -20,11 +20,13 @@ export const getTickHash = (columns: PointSeriesColumns, rows: DatatableRow[]) = }; if (get(columns, 'x.type') === 'string') { - sortBy(rows, ['x']).forEach((row) => { - if (!ticks.x.hash[row.x]) { - ticks.x.hash[row.x] = ticks.x.counter++; - } - }); + sortBy(rows, ['x']) + .reverse() + .forEach((row) => { + if (!ticks.x.hash[row.x]) { + ticks.x.hash[row.x] = ticks.x.counter++; + } + }); } if (get(columns, 'y.type') === 'string') { diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/plot/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/plot/index.ts index 0b4583f4581ae..4ffd2ff3e0c96 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/plot/index.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/plot/index.ts @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -// @ts-expect-error no @typed def -import keyBy from 'lodash.keyby'; -import { groupBy, get, set, map, sortBy } from 'lodash'; +import { groupBy, get, keyBy, set, map, sortBy } from 'lodash'; import { ExpressionFunctionDefinition, Style } from 'src/plugins/expressions'; // @ts-expect-error untyped local import { getColorsFromPalette } from '../../../../common/lib/get_colors_from_palette'; diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/plot/series_style_to_flot.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/plot/series_style_to_flot.ts index 6fbaee8736a50..e4b710240de19 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/common/plot/series_style_to_flot.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/common/plot/series_style_to_flot.ts @@ -12,12 +12,12 @@ export const seriesStyleToFlot = (seriesStyle: SeriesStyle) => { return {}; } - const lines = get(seriesStyle, 'lines'); - const bars = get(seriesStyle, 'bars'); - const fill = get(seriesStyle, 'fill'); - const color = get(seriesStyle, 'color'); - const stack = get(seriesStyle, 'stack'); - const horizontal = get(seriesStyle, 'horizontalBars', false); + const lines = get(seriesStyle, 'lines'); + const bars = get(seriesStyle, 'bars'); + const fill = get(seriesStyle, 'fill'); + const color = get(seriesStyle, 'color'); + const stack = get(seriesStyle, 'stack'); + const horizontal = get(seriesStyle, 'horizontalBars', false); const flotStyle = { numbers: { diff --git a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts index bae80d3c33510..f79f189f363d4 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts +++ b/x-pack/plugins/canvas/canvas_plugin_src/functions/server/pointseries/index.ts @@ -4,11 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -// @ts-expect-error untyped library -import uniqBy from 'lodash.uniqby'; -// @ts-expect-error untyped Elastic library +// @ts-expect-error Untyped Elastic library import { evaluate } from 'tinymath'; -import { groupBy, zipObject, omit } from 'lodash'; +import { groupBy, zipObject, omit, uniqBy } from 'lodash'; import moment from 'moment'; import { ExpressionFunctionDefinition } from 'src/plugins/expressions/common'; import { diff --git a/x-pack/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/time_filter.tsx b/x-pack/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/time_filter.tsx index 8d28287b32066..487f17fb89d12 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/time_filter.tsx +++ b/x-pack/plugins/canvas/canvas_plugin_src/renderers/time_filter/components/time_filter.tsx @@ -34,9 +34,9 @@ export interface FilterMeta { function getFilterMeta(filter: string): FilterMeta { const ast = fromExpression(filter); - const column = get(ast, 'chain[0].arguments.column[0]'); - const start = get(ast, 'chain[0].arguments.from[0]'); - const end = get(ast, 'chain[0].arguments.to[0]'); + const column = get(ast, 'chain[0].arguments.column[0]') as string; + const start = get(ast, 'chain[0].arguments.from[0]') as string; + const end = get(ast, 'chain[0].arguments.to[0]') as string; return { column, start, end }; } diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/palette.tsx b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/palette.tsx index a33d000a1f656..8ae61f7197ee8 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/palette.tsx +++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/arguments/palette.tsx @@ -40,7 +40,7 @@ export const PaletteArgInput: FC = ({ onValueChange, argId, argValue, ren return astObj; }) as string[]; - const gradient = get(chain[0].arguments.gradient, '[0]'); + const gradient = get(chain[0].arguments.gradient, '[0]') as boolean; const palette = identifyPalette({ colors, gradient }); if (palette) { diff --git a/x-pack/plugins/canvas/canvas_plugin_src/uis/views/plot.js b/x-pack/plugins/canvas/canvas_plugin_src/uis/views/plot.js index 1449bddf322b5..05ecf467a1d35 100644 --- a/x-pack/plugins/canvas/canvas_plugin_src/uis/views/plot.js +++ b/x-pack/plugins/canvas/canvas_plugin_src/uis/views/plot.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { map, uniq } from 'lodash'; +import { map, uniqBy } from 'lodash'; import { getState, getValue } from '../../../public/lib/resolved_arg'; import { legendOptions } from '../../../public/lib/legend_options'; import { ViewStrings } from '../../../i18n'; @@ -72,6 +72,6 @@ export const plot = () => ({ if (getState(context) !== 'ready') { return { labels: [] }; } - return { labels: uniq(map(getValue(context).rows, 'color').filter((v) => v !== undefined)) }; + return { labels: uniqBy(map(getValue(context).rows, 'color').filter((v) => v !== undefined)) }; }, }); diff --git a/x-pack/plugins/canvas/common/lib/pivot_object_array.ts b/x-pack/plugins/canvas/common/lib/pivot_object_array.ts index c098b7772ef11..2bc52fb0eaafc 100644 --- a/x-pack/plugins/canvas/common/lib/pivot_object_array.ts +++ b/x-pack/plugins/canvas/common/lib/pivot_object_array.ts @@ -11,10 +11,7 @@ const isString = (val: any): boolean => typeof val === 'string'; export function pivotObjectArray< RowType extends { [key: string]: any }, ReturnColumns extends string | number | symbol = keyof RowType ->( - rows: RowType[], - columns?: string[] -): { [Column in ReturnColumns]: Column extends keyof RowType ? Array : never } { +>(rows: RowType[], columns?: string[]): Record { const columnNames = columns || Object.keys(rows[0]); if (!columnNames.every(isString)) { throw new Error('Columns should be an array of strings'); diff --git a/x-pack/plugins/canvas/public/components/enhance/error_boundary.tsx b/x-pack/plugins/canvas/public/components/enhance/error_boundary.tsx index 134efe61c9dcb..c0ed14965cbd3 100644 --- a/x-pack/plugins/canvas/public/components/enhance/error_boundary.tsx +++ b/x-pack/plugins/canvas/public/components/enhance/error_boundary.tsx @@ -4,38 +4,27 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { Fragment, FunctionComponent, ReactChildren } from 'react'; +import React, { ErrorInfo, FC, ReactElement } from 'react'; import { withState, withHandlers, lifecycle, mapProps, compose } from 'recompose'; import PropTypes from 'prop-types'; import { omit } from 'lodash'; -type ResetErrorState = ({ - setError, - setErrorInfo, -}: { - setError: Function; - setErrorInfo: Function; -}) => void; - interface Props { - error: Error; - errorInfo: any; - resetErrorState: ResetErrorState; + error?: Error; + errorInfo?: ErrorInfo; + resetErrorState: (state: { error: Error; errorInfo: ErrorInfo }) => void; + setError: (error: Error | null) => void; + setErrorInfo: (info: ErrorInfo | null) => void; + children: (props: ChildrenProps) => ReactElement | null; } -interface ComponentProps extends Props { - children: (props: Props) => ReactChildren; -} +type ComponentProps = Pick; +type ChildrenProps = Omit; -const ErrorBoundaryComponent: FunctionComponent = (props) => ( - - {props.children({ - error: props.error, - errorInfo: props.errorInfo, - resetErrorState: props.resetErrorState, - })} - -); +const ErrorBoundaryComponent: FC = (props) => { + const { children, ...rest } = props; + return <>{children(rest)}; +}; ErrorBoundaryComponent.propTypes = { children: PropTypes.func.isRequired, @@ -44,33 +33,22 @@ ErrorBoundaryComponent.propTypes = { resetErrorState: PropTypes.func.isRequired, }; -interface HOCProps { - setError: Function; - setErrorInfo: Function; -} - -interface HandlerProps { - resetErrorState: ResetErrorState; -} - -export const errorBoundaryHoc = compose( +export const errorBoundaryHoc = compose>( withState('error', 'setError', null), withState('errorInfo', 'setErrorInfo', null), - withHandlers({ + withHandlers, Pick>({ resetErrorState: ({ setError, setErrorInfo }) => () => { setError(null); setErrorInfo(null); }, }), - lifecycle({ + lifecycle({ componentDidCatch(error, errorInfo) { this.props.setError(error); this.props.setErrorInfo(errorInfo); }, }), - mapProps>((props) => - omit(props, ['setError', 'setErrorInfo']) - ) + mapProps((props) => omit(props, ['setError', 'setErrorInfo'])) ); export const ErrorBoundary = errorBoundaryHoc(ErrorBoundaryComponent); diff --git a/x-pack/plugins/canvas/public/components/function_form/function_form.js b/x-pack/plugins/canvas/public/components/function_form/function_form.js index 8c9f8847d8eed..062f782942a82 100644 --- a/x-pack/plugins/canvas/public/components/function_form/function_form.js +++ b/x-pack/plugins/canvas/public/components/function_form/function_form.js @@ -32,7 +32,6 @@ const branches = [ export const FunctionForm = compose(...branches)(FunctionFormComponent); FunctionForm.propTypes = { - expressionType: PropTypes.object, context: PropTypes.object, expressionType: PropTypes.object, }; diff --git a/x-pack/plugins/canvas/public/components/item_grid/item_grid.tsx b/x-pack/plugins/canvas/public/components/item_grid/item_grid.tsx index 234f505071669..b9c879a27fd9c 100644 --- a/x-pack/plugins/canvas/public/components/item_grid/item_grid.tsx +++ b/x-pack/plugins/canvas/public/components/item_grid/item_grid.tsx @@ -19,13 +19,13 @@ export interface Props { */ itemsPerRow?: number; /** A function with which to iterate upon the items collection, producing nodes. */ - children: (item: T) => ReactElement; + children: (item: T) => ReactElement; } // We need this type in order to define propTypes on the object. It's a bit redundant, // but TS needs to know that ItemGrid can have propTypes defined on it. interface ItemGridType { - (props: Props): ReactElement; + (props: Props): ReactElement; propTypes?: ValidationMap>; } @@ -35,16 +35,22 @@ export const ItemGrid: ItemGridType = function ItemGridFunc({ children, }: Props) { const reducedRows = items.reduce( - (rows: Array>>, item: any) => { - if (last(rows).length >= itemsPerRow) { + (rows: ReactElement[][], item: T) => { + let end = last(rows); + + if (end && end.length >= itemsPerRow) { rows.push([]); } - last(rows).push(children(item)); + end = last(rows); + + if (end) { + end.push(children(item)); + } return rows; }, - [[]] as Array>> + [[]] as ReactElement[][] ); return ( diff --git a/x-pack/plugins/canvas/public/components/workpad_config/index.ts b/x-pack/plugins/canvas/public/components/workpad_config/index.ts index e417821fd4f67..c69a1fd9b8137 100644 --- a/x-pack/plugins/canvas/public/components/workpad_config/index.ts +++ b/x-pack/plugins/canvas/public/components/workpad_config/index.ts @@ -17,12 +17,12 @@ const mapStateToProps = (state: State) => { const workpad = getWorkpad(state); return { - name: get(workpad, 'name'), + name: get(workpad, 'name'), size: { - width: get(workpad, 'width'), - height: get(workpad, 'height'), + width: get(workpad, 'width'), + height: get(workpad, 'height'), }, - css: get(workpad, 'css', DEFAULT_WORKPAD_CSS), + css: get(workpad, 'css', DEFAULT_WORKPAD_CSS), }; }; diff --git a/x-pack/plugins/canvas/public/components/workpad_loader/workpad_loader.js b/x-pack/plugins/canvas/public/components/workpad_loader/workpad_loader.js index 28cfac11e76bd..af4e3af6db693 100644 --- a/x-pack/plugins/canvas/public/components/workpad_loader/workpad_loader.js +++ b/x-pack/plugins/canvas/public/components/workpad_loader/workpad_loader.js @@ -19,7 +19,7 @@ import { EuiFilePicker, EuiLink, } from '@elastic/eui'; -import { sortByOrder } from 'lodash'; +import { orderBy } from 'lodash'; import { ConfirmModal } from '../confirm_modal'; import { Link } from '../link'; import { Paginate } from '../paginate'; @@ -369,7 +369,7 @@ export class WorkpadLoader extends React.PureComponent { if (!createPending && !isLoading) { const { workpads } = this.props.workpads; - sortedWorkpads = sortByOrder(workpads, [sortField, '@timestamp'], [sortDirection, 'desc']); + sortedWorkpads = orderBy(workpads, [sortField, '@timestamp'], [sortDirection, 'desc']); } return ( diff --git a/x-pack/plugins/canvas/public/components/workpad_templates/workpad_templates.tsx b/x-pack/plugins/canvas/public/components/workpad_templates/workpad_templates.tsx index 065b84c490d20..43d5d5f939ce0 100644 --- a/x-pack/plugins/canvas/public/components/workpad_templates/workpad_templates.tsx +++ b/x-pack/plugins/canvas/public/components/workpad_templates/workpad_templates.tsx @@ -18,7 +18,7 @@ import { Direction, SortDirection, } from '@elastic/eui'; -import { sortByOrder } from 'lodash'; +import { orderBy } from 'lodash'; // @ts-ignore untyped local import { EuiBasicTableColumn } from '@elastic/eui'; import { Paginate, PaginateChildProps } from '../paginate'; @@ -182,7 +182,7 @@ export class WorkpadTemplates extends React.PureComponent< render() { const { templates } = this.props; const { sortField, sortDirection, searchTerm, filterTags } = this.state; - const sortedTemplates = sortByOrder(templates, [sortField, 'name'], [sortDirection, 'asc']); + const sortedTemplates = orderBy(templates, [sortField, 'name'], [sortDirection, 'asc']); const filteredTemplates = sortedTemplates.filter(({ name = '', help = '', tags = [] }) => { const tagMatch = filterTags.length diff --git a/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/extended_template.tsx b/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/extended_template.tsx index e0fe6e60c1dab..f02407ba2897d 100644 --- a/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/extended_template.tsx +++ b/x-pack/plugins/canvas/public/expression_types/arg_types/series_style/extended_template.tsx @@ -46,7 +46,7 @@ export const ExtendedTemplate: FunctionComponent = (props) => { name = typeInstance.name; } - const fields = get(typeInstance, 'options.include', []); + const fields: string[] = get(typeInstance, 'options.include', []); const hasPropFields = fields.some((field) => ['lines', 'bars', 'points'].indexOf(field) !== -1); const handleChange: (key: T, val: ChangeEvent) => void = ( diff --git a/x-pack/plugins/canvas/public/functions/filters.ts b/x-pack/plugins/canvas/public/functions/filters.ts index 48f4a41c7690a..ecde5d2eb255b 100644 --- a/x-pack/plugins/canvas/public/functions/filters.ts +++ b/x-pack/plugins/canvas/public/functions/filters.ts @@ -36,7 +36,7 @@ function getFiltersByGroup(allFilters: string[], groups?: string[], ungrouped = return allFilters.filter((filter: string) => { const ast = fromExpression(filter); - const expGroups = get(ast, 'chain[0].arguments.filterGroup', []); + const expGroups: string[] = get(ast, 'chain[0].arguments.filterGroup', []); return expGroups.length > 0 && expGroups.every((expGroup) => groups.includes(expGroup)); }); } diff --git a/x-pack/plugins/canvas/public/lib/keymap.ts b/x-pack/plugins/canvas/public/lib/keymap.ts index 7ca93f440087e..f713da5419b3e 100644 --- a/x-pack/plugins/canvas/public/lib/keymap.ts +++ b/x-pack/plugins/canvas/public/lib/keymap.ts @@ -153,10 +153,12 @@ export const keymap: KeyMap = { displayName: namespaceDisplayNames.PRESENTATION, FULLSCREEN: fullscreenShortcut, FULLSCREEN_EXIT: getShortcuts('esc', { help: shortcutHelp.FULLSCREEN_EXIT }), + // @ts-expect-error TODO: figure out why lodash is inferring booleans, rather than ShortcutMap. PREV: mapValues(previousPageShortcut, (osShortcuts: string[], key?: string) => // adds 'backspace' and 'left' to list of shortcuts per OS key === 'help' ? osShortcuts : osShortcuts.concat(['backspace', 'left']) ), + // @ts-expect-error TODO: figure out why lodash is inferring booleans, rather than ShortcutMap. NEXT: mapValues(nextPageShortcut, (osShortcuts: string[], key?: string) => // adds 'space' and 'right' to list of shortcuts per OS key === 'help' ? osShortcuts : osShortcuts.concat(['space', 'right']) diff --git a/x-pack/plugins/canvas/public/lib/modify_path.js b/x-pack/plugins/canvas/public/lib/modify_path.js index b4b2354b4cae0..714a616679bc9 100644 --- a/x-pack/plugins/canvas/public/lib/modify_path.js +++ b/x-pack/plugins/canvas/public/lib/modify_path.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import toPath from 'lodash.topath'; +import { toPath } from 'lodash'; export function prepend(path, value) { return toPath(value).concat(toPath(path)); diff --git a/x-pack/plugins/canvas/public/lib/template_from_react_component.tsx b/x-pack/plugins/canvas/public/lib/template_from_react_component.tsx index 17e2712c44b8d..f4e715b1bbc49 100644 --- a/x-pack/plugins/canvas/public/lib/template_from_react_component.tsx +++ b/x-pack/plugins/canvas/public/lib/template_from_react_component.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import React, { ComponentType, FunctionComponent } from 'react'; +import React, { ComponentType, FC } from 'react'; import { unmountComponentAtNode, render } from 'react-dom'; import PropTypes from 'prop-types'; import { I18nProvider } from '@kbn/i18n/react'; @@ -16,9 +16,9 @@ interface Props { } export const templateFromReactComponent = (Component: ComponentType) => { - const WrappedComponent: FunctionComponent = (props) => ( + const WrappedComponent: FC = (props) => ( - {({ error }: { error: Error }) => { + {({ error }) => { if (error) { props.renderError(); return null; diff --git a/x-pack/plugins/canvas/public/state/selectors/resolved_args.ts b/x-pack/plugins/canvas/public/state/selectors/resolved_args.ts index 766e27d95da9b..770d4403f8587 100644 --- a/x-pack/plugins/canvas/public/state/selectors/resolved_args.ts +++ b/x-pack/plugins/canvas/public/state/selectors/resolved_args.ts @@ -12,7 +12,7 @@ import { prepend } from '../../lib/modify_path'; import { State } from '../../../types'; export function getArgs(state: State) { - return get(state, ['transient', 'resolvedArgs']); + return get(state, ['transient', 'resolvedArgs']); } export function getArg(state: State, path: any[]) { diff --git a/x-pack/plugins/canvas/public/state/selectors/workpad.ts b/x-pack/plugins/canvas/public/state/selectors/workpad.ts index 0f4953ff56d98..83f4984b4a300 100644 --- a/x-pack/plugins/canvas/public/state/selectors/workpad.ts +++ b/x-pack/plugins/canvas/public/state/selectors/workpad.ts @@ -50,7 +50,10 @@ export function getWorkpadPersisted(state: State) { } export function getWorkpadInfo(state: State): WorkpadInfo { - return omit(getWorkpad(state), ['pages']); + return { + ...getWorkpad(state), + pages: undefined, + }; } export function isWriteable(state: State): boolean { @@ -308,7 +311,7 @@ export function getElements( } const page = getPageById(state, id); - const elements = get(page, 'elements'); + const elements = get(page, 'elements'); if (!elements) { return []; @@ -318,6 +321,8 @@ export function getElements( // due to https://github.com/elastic/kibana-canvas/issues/260 // TODO: remove this once it's been in the wild a bit if (!withAst) { + // @ts-expect-error 'ast' is no longer on the CanvasElement type, but since we + // have JS calling into this, we can't be certain this call isn't necessary. return elements.map((el) => omit(el, ['ast'])); } @@ -330,11 +335,13 @@ const augment = (type: string) => (n: T): ...(type === 'group' && { expression: 'shape fill="rgba(255,255,255,0)" | render' }), // fixme unify with mw/aeroelastic }); -const getNodesOfPage = (page: CanvasPage): CanvasElement[] => { - const elements = get(page, 'elements').map(augment('element')); - const groups = get(page, 'groups', []).map(augment('group')); +const getNodesOfPage = (page: CanvasPage): Array => { + const elements: Array = get(page, 'elements').map( + augment('element') + ); + const groups = get(page, 'groups', [] as CanvasGroup[]).map(augment('group')); - return elements.concat(groups as CanvasElement[]); + return elements.concat(groups); }; export function getNodesForPage(page: CanvasPage, withAst: true): PositionedElement[]; @@ -343,7 +350,11 @@ export function getNodesForPage( page: CanvasPage, withAst: boolean ): CanvasElement[] | PositionedElement[]; -export function getNodesForPage(page: CanvasPage, withAst: boolean): CanvasElement[] { + +export function getNodesForPage( + page: CanvasPage, + withAst: boolean +): Array { const elements = getNodesOfPage(page); if (!elements) { @@ -354,9 +365,12 @@ export function getNodesForPage(page: CanvasPage, withAst: boolean): CanvasEleme // due to https://github.com/elastic/kibana-canvas/issues/260 // TODO: remove this once it's been in the wild a bit if (!withAst) { + // @ts-expect-error 'ast' is no longer on the CanvasElement type, but since we + // have JS calling into this, we can't be certain this call isn't necessary. return elements.map((el) => omit(el, ['ast'])); } + // @ts-expect-error All of this AST business needs to be cleaned up. return elements.map(appendAst); } @@ -407,7 +421,7 @@ export function getResolvedArgs(state: State, elementId: string, path: any): any if (!elementId) { return; } - const args = get(state, ['transient', 'resolvedArgs', elementId]); + const args = get(state, ['transient', 'resolvedArgs', elementId]) as any; if (path) { return get(args, path); } diff --git a/x-pack/plugins/canvas/server/collectors/custom_element_collector.ts b/x-pack/plugins/canvas/server/collectors/custom_element_collector.ts index 3ada8e7b4efdc..7b39e8b83b045 100644 --- a/x-pack/plugins/canvas/server/collectors/custom_element_collector.ts +++ b/x-pack/plugins/canvas/server/collectors/custom_element_collector.ts @@ -113,7 +113,7 @@ const customElementCollector: TelemetryCollector = async function customElementC const esResponse = await callCluster('search', customElementParams); - if (get(esResponse, 'hits.hits.length') > 0) { + if (get(esResponse, 'hits.hits.length') > 0) { const customElements = esResponse.hits.hits.map((hit) => hit._source[CUSTOM_ELEMENT_TYPE]); return summarizeCustomElements(customElements); } diff --git a/x-pack/plugins/canvas/server/collectors/workpad_collector.test.ts b/x-pack/plugins/canvas/server/collectors/workpad_collector.test.ts index 420b785771bfe..9f71edcc05bf2 100644 --- a/x-pack/plugins/canvas/server/collectors/workpad_collector.test.ts +++ b/x-pack/plugins/canvas/server/collectors/workpad_collector.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import clonedeep from 'lodash.clonedeep'; +import { cloneDeep } from 'lodash'; import { summarizeWorkpads } from './workpad_collector'; import { workpads } from '../../__tests__/fixtures/workpads'; @@ -53,7 +53,7 @@ describe('usage collector handle es response data', () => { }); it('should collect correctly if an expression has null as an argument (possible sub-expression)', () => { - const workpad = clonedeep(workpads[0]); + const workpad = cloneDeep(workpads[0]); workpad.pages[0].elements[0].expression = 'toast butter=null'; const mockWorkpads = [workpad]; @@ -67,7 +67,7 @@ describe('usage collector handle es response data', () => { }); it('should fail gracefully if workpad has 0 pages (corrupted workpad)', () => { - const workpad = clonedeep(workpads[0]); + const workpad = cloneDeep(workpads[0]); workpad.pages = []; const mockWorkpadsCorrupted = [workpad]; const usage = summarizeWorkpads(mockWorkpadsCorrupted); diff --git a/x-pack/plugins/canvas/server/collectors/workpad_collector.ts b/x-pack/plugins/canvas/server/collectors/workpad_collector.ts index 3d394afaeba50..4b00d061c17ce 100644 --- a/x-pack/plugins/canvas/server/collectors/workpad_collector.ts +++ b/x-pack/plugins/canvas/server/collectors/workpad_collector.ts @@ -133,8 +133,8 @@ export function summarizeWorkpads(workpadDocs: CanvasWorkpad[]): WorkpadTelemetr total: elementsTotal, per_page: { avg: elementsTotal / elementCounts.length, - min: arrayMin(elementCounts), - max: arrayMax(elementCounts), + min: arrayMin(elementCounts) || 0, + max: arrayMax(elementCounts) || 0, }, } : undefined; @@ -145,8 +145,8 @@ export function summarizeWorkpads(workpadDocs: CanvasWorkpad[]): WorkpadTelemetr in_use: Array.from(functionSet), per_element: { avg: functionsTotal / functionCounts.length, - min: arrayMin(functionCounts), - max: arrayMax(functionCounts), + min: arrayMin(functionCounts) || 0, + max: arrayMax(functionCounts) || 0, }, } : undefined; @@ -170,7 +170,7 @@ const workpadCollector: TelemetryCollector = async function (kibanaIndex, callCl const esResponse = await callCluster('search', searchParams); - if (get(esResponse, 'hits.hits.length') > 0) { + if (get(esResponse, 'hits.hits.length') > 0) { const workpads = esResponse.hits.hits.map((hit) => hit._source[CANVAS_TYPE]); return summarizeWorkpads(workpads); } diff --git a/x-pack/plugins/canvas/server/routes/workpad/update.ts b/x-pack/plugins/canvas/server/routes/workpad/update.ts index 021ac41d88d19..9dae2047c30bf 100644 --- a/x-pack/plugins/canvas/server/routes/workpad/update.ts +++ b/x-pack/plugins/canvas/server/routes/workpad/update.ts @@ -7,6 +7,7 @@ import { schema, TypeOf } from '@kbn/config-schema'; import { omit } from 'lodash'; import { KibanaResponseFactory, SavedObjectsClientContract } from 'src/core/server'; +import { CanvasWorkpad } from '../../../types'; import { RouteInitializerDeps } from '../'; import { CANVAS_TYPE, @@ -14,7 +15,6 @@ import { API_ROUTE_WORKPAD_STRUCTURES, API_ROUTE_WORKPAD_ASSETS, } from '../../../common/lib/constants'; -import { WorkpadAttributes } from './workpad_attributes'; import { WorkpadSchema, WorkpadAssetSchema } from './workpad_schema'; import { okResponse } from '../ok_response'; import { catchErrorHandler } from '../catch_error_handler'; @@ -33,8 +33,8 @@ const workpadUpdateHandler = async ( ) => { const now = new Date().toISOString(); - const workpadObject = await savedObjectsClient.get(CANVAS_TYPE, id); - await savedObjectsClient.create( + const workpadObject = await savedObjectsClient.get(CANVAS_TYPE, id); + await savedObjectsClient.create( CANVAS_TYPE, { ...workpadObject.attributes, diff --git a/x-pack/plugins/dashboard_mode/public/plugin.ts b/x-pack/plugins/dashboard_mode/public/plugin.ts index 24273280d9495..d988de5851cf5 100644 --- a/x-pack/plugins/dashboard_mode/public/plugin.ts +++ b/x-pack/plugins/dashboard_mode/public/plugin.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { trimLeft } from 'lodash'; +import { trimStart } from 'lodash'; import { CoreSetup } from 'kibana/public'; import { KibanaLegacyStart } from '../../../../src/plugins/kibana_legacy/public'; import { @@ -19,7 +19,7 @@ function defaultUrl(defaultAppId: string) { } function dashboardAppIdPrefix() { - return trimLeft(createDashboardEditUrl(''), '/'); + return trimStart(createDashboardEditUrl(''), '/'); } function migratePath(currentHash: string, kibanaLegacy: KibanaLegacyStart) { diff --git a/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/index.ts b/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/index.ts index 546dc6361826a..20b3292128a2f 100644 --- a/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/index.ts +++ b/x-pack/plugins/data_enhanced/public/autocomplete/providers/kql_query_suggestion/index.ts @@ -6,7 +6,7 @@ import { CoreSetup } from 'kibana/public'; import { $Keys } from 'utility-types'; -import { flatten, uniq } from 'lodash'; +import { flatten, uniqBy } from 'lodash'; import { setupGetFieldSuggestions } from './field'; import { setupGetValueSuggestions } from './value'; import { setupGetOperatorSuggestions } from './operator'; @@ -21,7 +21,7 @@ import { const cursorSymbol = '@kuery-cursor@'; const dedup = (suggestions: QuerySuggestion[]): QuerySuggestion[] => - uniq(suggestions, ({ type, text, start, end }) => [type, text, start, end].join('|')); + uniqBy(suggestions, ({ type, text, start, end }) => [type, text, start, end].join('|')); export const KUERY_LANGUAGE_NAME = 'kuery'; diff --git a/x-pack/plugins/event_log/server/event_log_service.ts b/x-pack/plugins/event_log/server/event_log_service.ts index 6cfb16d126427..f7f915f1cf0ef 100644 --- a/x-pack/plugins/event_log/server/event_log_service.ts +++ b/x-pack/plugins/event_log/server/event_log_service.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; import { Observable } from 'rxjs'; import { LegacyClusterClient } from 'src/core/server'; diff --git a/x-pack/plugins/event_log/server/event_log_start_service.ts b/x-pack/plugins/event_log/server/event_log_start_service.ts index 36a6bc0a926af..0339d0883dc46 100644 --- a/x-pack/plugins/event_log/server/event_log_start_service.ts +++ b/x-pack/plugins/event_log/server/event_log_start_service.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; import { Observable } from 'rxjs'; import { LegacyClusterClient, diff --git a/x-pack/plugins/features/server/ui_capabilities_for_features.ts b/x-pack/plugins/features/server/ui_capabilities_for_features.ts index e41035e9365ce..2570d4540b6a6 100644 --- a/x-pack/plugins/features/server/ui_capabilities_for_features.ts +++ b/x-pack/plugins/features/server/ui_capabilities_for_features.ts @@ -8,7 +8,7 @@ import _ from 'lodash'; import { Capabilities as UICapabilities } from '../../../../src/core/server'; import { Feature } from '../common/feature'; -const ELIGIBLE_FLAT_MERGE_KEYS = ['catalogue']; +const ELIGIBLE_FLAT_MERGE_KEYS = ['catalogue'] as const; interface FeatureCapabilities { [featureId: string]: Record; @@ -67,7 +67,7 @@ function getCapabilitiesFromFeature(feature: Feature): FeatureCapabilities { function buildCapabilities(...allFeatureCapabilities: FeatureCapabilities[]): UICapabilities { return allFeatureCapabilities.reduce((acc, capabilities) => { - const mergableCapabilities: UICapabilities = _.omit(capabilities, ...ELIGIBLE_FLAT_MERGE_KEYS); + const mergableCapabilities = _.omit(capabilities, ...ELIGIBLE_FLAT_MERGE_KEYS); const mergedFeatureCapabilities = { ...mergableCapabilities, diff --git a/x-pack/plugins/graph/server/routes/explore.ts b/x-pack/plugins/graph/server/routes/explore.ts index 648010eeeafeb..b0b8cf14ff699 100644 --- a/x-pack/plugins/graph/server/routes/explore.ts +++ b/x-pack/plugins/graph/server/routes/explore.ts @@ -59,7 +59,7 @@ export function registerExploreRoute({ error, 'body.error.root_cause', [] as Array<{ type: string; reason: string }> - ).find((cause) => { + ).find((cause: { type: string; reason: string }) => { return ( cause.reason.includes('Fielddata is disabled on text fields') || cause.reason.includes('No support for examining floating point') || diff --git a/x-pack/plugins/index_lifecycle_management/public/extend_index_management/index.js b/x-pack/plugins/index_lifecycle_management/public/extend_index_management/index.js index e7afc8f12859c..a1eac5264bb6a 100644 --- a/x-pack/plugins/index_lifecycle_management/public/extend_index_management/index.js +++ b/x-pack/plugins/index_lifecycle_management/public/extend_index_management/index.js @@ -5,7 +5,7 @@ */ import React from 'react'; -import { get, every, any } from 'lodash'; +import { get, every, some } from 'lodash'; import { i18n } from '@kbn/i18n'; import { EuiSearchBar } from '@elastic/eui'; @@ -129,7 +129,7 @@ export const ilmSummaryExtension = (index, getUrlForApp) => { }; export const ilmFilterExtension = (indices) => { - const hasIlm = any(indices, (index) => index.ilm && index.ilm.managed); + const hasIlm = some(indices, (index) => index.ilm && index.ilm.managed); if (!hasIlm) { return []; } else { diff --git a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js index 1931884cf7306..5c249ee474b00 100644 --- a/x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js +++ b/x-pack/plugins/index_management/public/application/sections/home/index_list/index_actions_context_menu/index_actions_context_menu.js @@ -7,7 +7,7 @@ import React, { Component, Fragment } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import { all } from 'lodash'; +import { every } from 'lodash'; import { EuiBadge, EuiButton, @@ -66,11 +66,11 @@ export class IndexActionsContextMenu extends Component { unfreezeIndices, hasSystemIndex, } = this.props; - const allOpen = all(indexNames, (indexName) => { + const allOpen = every(indexNames, (indexName) => { return indexStatusByName[indexName] === INDEX_OPEN; }); - const allFrozen = all(indices, (index) => index.isFrozen); - const allUnfrozen = all(indices, (index) => !index.isFrozen); + const allFrozen = every(indices, (index) => index.isFrozen); + const allUnfrozen = every(indices, (index) => !index.isFrozen); const selectedIndexCount = indexNames.length; const items = []; if (!detailPanel && selectedIndexCount === 1) { diff --git a/x-pack/plugins/infra/public/alerting/inventory/components/expression.tsx b/x-pack/plugins/infra/public/alerting/inventory/components/expression.tsx index d0b4045949d3e..8d36262b55792 100644 --- a/x-pack/plugins/infra/public/alerting/inventory/components/expression.tsx +++ b/x-pack/plugins/infra/public/alerting/inventory/components/expression.tsx @@ -364,7 +364,7 @@ export const Expressions: React.FC = (props) => { = (props) => { = ({ const dateFormatter = useMemo(() => { const firstSeries = data ? first(data.series) : null; return firstSeries && firstSeries.rows.length > 0 - ? niceTimeFormatter([first(firstSeries.rows).timestamp, last(firstSeries.rows).timestamp]) + ? niceTimeFormatter([ + (first(firstSeries.rows) as any).timestamp, + (last(firstSeries.rows) as any).timestamp, + ]) : (value: number) => `${value}`; }, [data]); @@ -135,8 +138,8 @@ export const ExpressionChart: React.FC = ({ }), }; - const firstTimestamp = first(firstSeries.rows).timestamp; - const lastTimestamp = last(firstSeries.rows).timestamp; + const firstTimestamp = (first(firstSeries.rows) as any).timestamp; + const lastTimestamp = (last(firstSeries.rows) as any).timestamp; const dataDomain = calculateDomain(series, [metric], false); const domain = { max: Math.max(dataDomain.max, last(thresholds) || dataDomain.max) * 1.1, // add 10% headroom. diff --git a/x-pack/plugins/infra/public/alerting/metric_threshold/lib/transform_metrics_explorer_data.ts b/x-pack/plugins/infra/public/alerting/metric_threshold/lib/transform_metrics_explorer_data.ts index 0e631b1e333d7..f46a7f3e5a5e4 100644 --- a/x-pack/plugins/infra/public/alerting/metric_threshold/lib/transform_metrics_explorer_data.ts +++ b/x-pack/plugins/infra/public/alerting/metric_threshold/lib/transform_metrics_explorer_data.ts @@ -14,8 +14,8 @@ export const transformMetricsExplorerData = ( ) => { const { criteria } = params; if (criteria && data) { - const firstSeries = first(data.series); - const series = firstSeries.rows.reduce((acc, row) => { + const firstSeries = first(data.series) as any; + const series = firstSeries.rows.reduce((acc: any, row: any) => { const { timestamp } = row; criteria.forEach((item, index) => { if (!acc[index]) { diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.tsx index cc4b6967d34fb..c2b49c43281a9 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_logs.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { compose } from 'lodash'; +import { flowRight } from 'lodash'; import React from 'react'; import { match as RouteMatch, Redirect, RouteComponentProps } from 'react-router-dom'; @@ -24,7 +24,7 @@ interface RedirectToLogsProps extends RedirectToLogsType { export const RedirectToLogs = ({ location, match }: RedirectToLogsProps) => { const sourceId = match.params.sourceId || 'default'; const filter = getFilterFromLocation(location); - const searchString = compose( + const searchString = flowRight( replaceLogFilterInQueryString(filter), replaceLogPositionInQueryString(getTimeFromLocation(location)), replaceSourceIdInQueryString(sourceId) diff --git a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx index 10320ebbe7609..37203084124f5 100644 --- a/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx +++ b/x-pack/plugins/infra/public/pages/link_to/redirect_to_node_logs.tsx @@ -6,7 +6,7 @@ import { i18n } from '@kbn/i18n'; -import { compose } from 'lodash'; +import { flowRight } from 'lodash'; import React from 'react'; import { Redirect, RouteComponentProps } from 'react-router-dom'; @@ -65,7 +65,7 @@ export const RedirectToNodeLogs = ({ const userFilter = getFilterFromLocation(location); const filter = userFilter ? `(${nodeFilter}) and (${userFilter})` : nodeFilter; - const searchString = compose( + const searchString = flowRight( replaceLogFilterInQueryString(filter), replaceLogPositionInQueryString(getTimeFromLocation(location)), replaceSourceIdInQueryString(sourceId) diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/legend_controls.tsx b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/legend_controls.tsx index 538cd5f7d9525..3997a7eab44e8 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/legend_controls.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/components/waffle/legend_controls.tsx @@ -266,7 +266,7 @@ export const LegendControls = ({ fullWidth label={ { @@ -79,7 +79,7 @@ export const calculateSteppedGradientColor = ( return rule.color; } return color; - }, first(rules).color || defaultColor); + }, (first(rules) as any).color || defaultColor); }; export const calculateStepColor = ( @@ -106,7 +106,7 @@ export const calculateGradientColor = ( return defaultColor; } if (rules.length === 1) { - return last(rules).color; + return (last(rules) as any).color; } const { min, max } = bounds; const sortedRules = sortBy(rules, 'value'); @@ -116,8 +116,10 @@ export const calculateGradientColor = ( return rule; } return acc; - }, first(sortedRules)); - const endRule = sortedRules.filter((r) => r !== startRule).find((r) => r.value >= normValue); + }, first(sortedRules)) as any; + const endRule = sortedRules + .filter((r) => r !== startRule) + .find((r) => r.value >= normValue) as any; if (!endRule) { return startRule.color; } diff --git a/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/nodes_to_wafflemap.ts b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/nodes_to_wafflemap.ts index a5515895a51a0..b56b409717cc6 100644 --- a/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/nodes_to_wafflemap.ts +++ b/x-pack/plugins/infra/public/pages/metrics/inventory_view/lib/nodes_to_wafflemap.ts @@ -30,7 +30,7 @@ function findOrCreateGroupWithNodes( * then look for the group in it's sub groups. */ if (path.length === 2) { - const parentId = first(path).value; + const parentId = (first(path) as any).value; const existingParentGroup = groups.find((g) => g.id === parentId); if (isWaffleMapGroupWithGroups(existingParentGroup)) { const existingSubGroup = existingParentGroup.groups.find((g) => g.id === id); diff --git a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/helpers.ts b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/helpers.ts index 0b8773db2dddf..c2cde7eb15e95 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/helpers.ts +++ b/x-pack/plugins/infra/public/pages/metrics/metric_detail/components/helpers.ts @@ -44,7 +44,7 @@ export const getMaxMinTimestamp = (metric: NodeDetailsMetricData): [number, numb const lastRow = last(item.data); return acc.concat([(firstRow && firstRow.timestamp) || 0, (lastRow && lastRow.timestamp) || 0]); }, [] as number[]); - return [min(values), max(values)]; + return [min(values) as number, max(values) as number]; }; /** diff --git a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart.tsx b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart.tsx index 2a218c1c78aa3..3802366fe2ac5 100644 --- a/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart.tsx +++ b/x-pack/plugins/infra/public/pages/metrics/metrics_explorer/components/chart.tsx @@ -77,7 +77,10 @@ export const MetricsExplorerChart = ({ const dateFormatter = useMemo( () => series.rows.length > 0 - ? niceTimeFormatter([first(series.rows).timestamp, last(series.rows).timestamp]) + ? niceTimeFormatter([ + (first(series.rows) as any).timestamp, + (last(series.rows) as any).timestamp, + ]) : (value: number) => `${value}`, [series.rows] ); diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts index f4dc7de51daee..e3d23d86c9f56 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/evaluate_condition.ts @@ -103,7 +103,7 @@ const getData = async ( const { nodes } = await snapshot.getNodes(esClient, options); return nodes.reduce((acc, n) => { - const nodePathItem = last(n.path); + const nodePathItem = last(n.path) as any; const m = first(n.metrics); if (m && m.value && m.timeseries) { const { timeseries } = m; diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts index 445911878111f..1ef86d9e7eac4 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/inventory_metric_threshold_executor.ts @@ -52,7 +52,7 @@ export const createInventoryMetricThresholdExecutor = ( ) ); - const inventoryItems = Object.keys(first(results)); + const inventoryItems = Object.keys(first(results) as any); for (const item of inventoryItems) { const alertInstance = services.alertInstanceFactory(`${item}::${alertId}`); // AND logic; all criteria must be across the threshold diff --git a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/preview_inventory_metric_threshold_alert.ts b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/preview_inventory_metric_threshold_alert.ts index ba43303bccf0b..b865454951cd2 100644 --- a/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/preview_inventory_metric_threshold_alert.ts +++ b/x-pack/plugins/infra/server/lib/alerting/inventory_metric_threshold/preview_inventory_metric_threshold_alert.ts @@ -53,7 +53,7 @@ export const previewInventoryMetricThresholdAlert = async ({ ) ); - const inventoryItems = Object.keys(first(results)); + const inventoryItems = Object.keys(first(results) as any); const previewResults = inventoryItems.map((item) => { const isNoData = results.some((result) => result[item].isNoData); if (isNoData) { diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts index 5782277e4f469..4c02593dd0095 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/metric_threshold_executor.ts @@ -33,8 +33,8 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs, alertId: s const config = source.configuration; const alertResults = await evaluateAlert(services.callCluster, params, config); - // Because each alert result has the same group definitions, just grab the groups from the first one. - const groups = Object.keys(first(alertResults)); + // Because each alert result has the same group definitions, just grap the groups from the first one. + const groups = Object.keys(first(alertResults) as any); for (const group of groups) { const alertInstance = services.alertInstanceFactory(`${group}::${alertId}`); @@ -58,7 +58,9 @@ export const createMetricThresholdExecutor = (libs: InfraBackendLibs, alertId: s let reason; if (nextState === AlertStates.ALERT) { - reason = alertResults.map((result) => buildFiredAlertReason(result[group])).join('\n'); + reason = alertResults + .map((result) => buildFiredAlertReason(result[group] as any)) + .join('\n'); } if (alertOnNoData) { if (nextState === AlertStates.NO_DATA) { diff --git a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/preview_metric_threshold_alert.ts b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/preview_metric_threshold_alert.ts index 39db24684e8d3..0ecfa27d0f0a8 100644 --- a/x-pack/plugins/infra/server/lib/alerting/metric_threshold/preview_metric_threshold_alert.ts +++ b/x-pack/plugins/infra/server/lib/alerting/metric_threshold/preview_metric_threshold_alert.ts @@ -70,7 +70,7 @@ export const previewMetricThresholdAlert: ( // Get a date histogram using the bucket interval and the lookback interval try { const alertResults = await evaluateAlert(callCluster, params, config, timeframe); - const groups = Object.keys(first(alertResults)); + const groups = Object.keys(first(alertResults) as any); // Now determine how to interpolate this histogram based on the alert interval const alertIntervalInSeconds = getIntervalInSeconds(alertInterval); @@ -90,7 +90,7 @@ export const previewMetricThresholdAlert: ( // buckets would have fired the alert. If the alert interval and bucket interval are the same, // this will be a 1:1 evaluation of the alert results. If these are different, the interpolation // will skip some buckets or read some buckets more than once, depending on the differential - const numberOfResultBuckets = first(alertResults)[group].shouldFire.length; + const numberOfResultBuckets = (first(alertResults) as any)[group].shouldFire.length; const numberOfExecutionBuckets = Math.floor( numberOfResultBuckets / alertResultsPerExecution ); @@ -118,7 +118,8 @@ export const previewMetricThresholdAlert: ( ? await evaluateAlert(callCluster, params, config) : []; const numberOfGroups = - precalculatedNumberOfGroups ?? Math.max(Object.keys(first(currentAlertResults)).length, 1); + precalculatedNumberOfGroups ?? + Math.max(Object.keys(first(currentAlertResults) as any).length, 1); const estimatedTotalBuckets = (lookbackIntervalInSeconds / bucketIntervalInSeconds) * numberOfGroups; // The minimum number of slices is 2. In case we underestimate the total number of buckets @@ -156,7 +157,7 @@ export const previewMetricThresholdAlert: ( return a + b; }) ); - return zippedResult; + return zippedResult as any; } else throw e; } }; diff --git a/x-pack/plugins/infra/server/lib/snapshot/response_helpers.ts b/x-pack/plugins/infra/server/lib/snapshot/response_helpers.ts index bb1c4c6632af0..317a7da95ce6b 100644 --- a/x-pack/plugins/infra/server/lib/snapshot/response_helpers.ts +++ b/x-pack/plugins/infra/server/lib/snapshot/response_helpers.ts @@ -127,7 +127,7 @@ export const getNodeMetrics = ( avg: null, })); } - const lastBucket = findLastFullBucket(nodeBuckets, options); + const lastBucket = findLastFullBucket(nodeBuckets, options) as any; return options.metrics.map((metric, index) => { const metricResult: SnapshotNodeMetric = { name: metric.type, diff --git a/x-pack/plugins/infra/server/routes/ip_to_hostname.ts b/x-pack/plugins/infra/server/routes/ip_to_hostname.ts index 28b7777c1d688..08ad266a22f9b 100644 --- a/x-pack/plugins/infra/server/routes/ip_to_hostname.ts +++ b/x-pack/plugins/infra/server/routes/ip_to_hostname.ts @@ -48,7 +48,7 @@ export const initIpToHostName = ({ framework }: InfraBackendLibs) => { body: { message: 'Host with matching IP address not found.' }, }); } - const hostDoc = first(hits.hits); + const hostDoc = first(hits.hits) as any; return response.ok({ body: { host: hostDoc._source.host.name } }); } catch ({ statusCode = 500, message = 'Unknown error occurred' }) { return response.customError({ diff --git a/x-pack/plugins/infra/server/routes/metadata/index.ts b/x-pack/plugins/infra/server/routes/metadata/index.ts index 7e3a30e1e6918..b2664d5a6d9fe 100644 --- a/x-pack/plugins/infra/server/routes/metadata/index.ts +++ b/x-pack/plugins/infra/server/routes/metadata/index.ts @@ -59,7 +59,7 @@ export const initMetadataRoute = (libs: InfraBackendLibs) => { ); const info = await getNodeInfo(framework, requestContext, configuration, nodeId, nodeType); - const cloudInstanceId = get(info, 'cloud.instance.id'); + const cloudInstanceId = get(info, 'cloud.instance.id'); const cloudMetricsMetadata = cloudInstanceId ? await getCloudMetricsMetadata( diff --git a/x-pack/plugins/infra/server/utils/create_afterkey_handler.ts b/x-pack/plugins/infra/server/utils/create_afterkey_handler.ts index 559fba0799987..2b65c42410723 100644 --- a/x-pack/plugins/infra/server/utils/create_afterkey_handler.ts +++ b/x-pack/plugins/infra/server/utils/create_afterkey_handler.ts @@ -14,7 +14,7 @@ export const createAfterKeyHandler = ( if (!response.aggregations) { return options; } - const newOptions = { ...options }; + const newOptions = { ...options } as any; const afterKey = afterKeySelector(response); set(newOptions, optionsAfterKeyPath, afterKey); return newOptions; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/save.ts b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/save.ts index d62f3dbcf029a..b41e93def966e 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/save.ts +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/save.ts @@ -55,7 +55,7 @@ export function getSavedObjectFormat({ state: { datasourceStates, datasourceMetaData: { - filterableIndexPatterns: _.uniq(filterableIndexPatterns, 'id'), + filterableIndexPatterns: _.uniqBy(filterableIndexPatterns, 'id'), }, visualization: visualization.getPersistableState(state.visualization.state), query: framePublicAPI.query, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/change_indexpattern.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/change_indexpattern.tsx index 851a9f4653fec..94c0f4083dfee 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/change_indexpattern.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/change_indexpattern.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; import { i18n } from '@kbn/i18n'; import React, { useState } from 'react'; import { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx index 0e7cefb58fc28..eb7940634d78e 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.tsx @@ -5,7 +5,7 @@ */ import './datapanel.scss'; -import { uniq, indexBy, groupBy, throttle } from 'lodash'; +import { uniq, keyBy, groupBy, throttle } from 'lodash'; import React, { useState, useEffect, memo, useCallback, useMemo } from 'react'; import { EuiFlexGroup, @@ -256,7 +256,7 @@ export const InnerIndexPatternDataPanel = function InnerIndexPatternDataPanel({ const fieldGroups: FieldsGroup = useMemo(() => { const containsData = (field: IndexPatternField) => { - const fieldByName = indexBy(allFields, 'name'); + const fieldByName = keyBy(allFields, 'name'); const overallField = fieldByName[field.name]; return ( diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.tsx index df49ed828a190..ebb706258cf45 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/bucket_nesting_editor.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; import React from 'react'; import { i18n } from '@kbn/i18n'; import { EuiFormRow, EuiHorizontalRule, EuiRadio, EuiSelect, htmlIdGenerator } from '@elastic/eui'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/popover_editor.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/popover_editor.tsx index 34a4384ec0d40..5b84108b99dd9 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/popover_editor.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/popover_editor.tsx @@ -119,7 +119,7 @@ export function PopoverEditor(props: PopoverEditorProps) { validOperationTypes.push(...operationByField[selectedColumn.sourceField]!); } - return _.uniq( + return _.uniqBy( [ ...asOperationOptions(validOperationTypes, true), ...asOperationOptions(possibleOperationTypes, false), diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts index 89e2c753f4c76..111a113a16be7 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/indexpattern_suggestions.ts @@ -57,14 +57,11 @@ function buildSuggestion({ // two match up. const layers = _.mapValues(updatedState.layers, (layer) => ({ ...layer, - columns: _.pick, Record>( - layer.columns, - layer.columnOrder - ), + columns: _.pick(layer.columns, layer.columnOrder) as Record, })); const columnOrder = layers[layerId].columnOrder; - const columnMap = layers[layerId].columns; + const columnMap = layers[layerId].columns as Record; const isMultiRow = Object.values(columnMap).some((column) => column.isBucketed); return { @@ -108,7 +105,10 @@ export function getDatasourceSuggestionsForField( // The field we're suggesting on matches an existing layer. In this case we find the layer with // the fewest configured columns and try to add the field to this table. If this layer does not // contain any layers yet, behave as if there is no layer. - const mostEmptyLayerId = _.min(layerIds, (layerId) => state.layers[layerId].columnOrder.length); + const mostEmptyLayerId = _.minBy( + layerIds, + (layerId) => state.layers[layerId].columnOrder.length + ) as string; if (state.layers[mostEmptyLayerId].columnOrder.length === 0) { return getEmptyLayerSuggestionsForField(state, mostEmptyLayerId, indexPatternId, field); } else { @@ -491,7 +491,7 @@ function createChangedNestingSuggestion(state: IndexPatternPrivateState, layerId } function getMetricColumn(indexPattern: IndexPattern, layerId: string, field: IndexPatternField) { - const operationDefinitionsMap = _.indexBy(operationDefinitions, 'type'); + const operationDefinitionsMap = _.keyBy(operationDefinitions, 'type'); const [column] = getOperationTypesForField(field) .map((type) => operationDefinitionsMap[type].buildColumn({ diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.tsx index eea00d52a77f9..1ae10e07b0c24 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/layerpanel.tsx @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; import React from 'react'; import { I18nProvider } from '@kbn/i18n/react'; import { DatasourceLayerPanelProps } from '../types'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts b/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts index 101f536993365..e995c7317b5d8 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/loader.ts @@ -96,7 +96,7 @@ export async function loadInitialState({ const indexPatternRefs = await loadIndexPatternRefs(savedObjectsClient); const lastUsedIndexPatternId = getLastUsedIndexPatternId(storage, indexPatternRefs); - const requiredPatterns = _.unique( + const requiredPatterns = _.uniq( state ? Object.values(state.layers) .map((l) => l.indexPatternId) diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.ts b/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.ts index a04f71a9095c5..9e5a0f496357d 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/operations.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; import { DimensionPriority, OperationMetadata } from '../../types'; import { operationDefinitionMap, diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.ts b/x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.ts index 3a1aaaa819dc0..51691ae18a99a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/state_helpers.ts @@ -161,7 +161,7 @@ export function updateLayerIndexPattern( layer: IndexPatternLayer, newIndexPattern: IndexPattern ): IndexPatternLayer { - const keptColumns: IndexPatternLayer['columns'] = _.pick(layer.columns, (column) => + const keptColumns: IndexPatternLayer['columns'] = _.pickBy(layer.columns, (column) => isColumnTransferable(column, newIndexPattern) ); const newColumns: IndexPatternLayer['columns'] = _.mapValues(keptColumns, (column) => { diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts b/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts index e507bee2a898d..9473a1523b8ca 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/to_expression.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; import { Ast, ExpressionFunctionAST } from '@kbn/interpreter/common'; import { IndexPatternColumn } from './indexpattern'; import { operationDefinitionMap } from './operations'; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/utils.ts b/x-pack/plugins/lens/public/indexpattern_datasource/utils.ts index fadee01e695d5..0cd92fd96c952 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/utils.ts +++ b/x-pack/plugins/lens/public/indexpattern_datasource/utils.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; import { DraggedField } from './indexpattern'; import { BaseIndexPatternColumn, diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_visualization.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_visualization.tsx index 474ea5c5b08cd..d38f51cb1621a 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_visualization.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_visualization.tsx @@ -31,7 +31,7 @@ function getVisualizationType(state: State): VisualizationType | 'mixed' { ); } const visualizationType = visualizationTypes.find((t) => t.id === state.layers[0].seriesType); - const seriesTypes = _.unique(state.layers.map((l) => l.seriesType)); + const seriesTypes = _.uniq(state.layers.map((l) => l.seriesType)); return visualizationType && seriesTypes.length === 1 ? visualizationType : 'mixed'; } diff --git a/x-pack/plugins/logstash/public/models/pipeline_list_item/pipeline_list_item.js b/x-pack/plugins/logstash/public/models/pipeline_list_item/pipeline_list_item.js index 3a304e467e0c0..7d541ec192e0f 100755 --- a/x-pack/plugins/logstash/public/models/pipeline_list_item/pipeline_list_item.js +++ b/x-pack/plugins/logstash/public/models/pipeline_list_item/pipeline_list_item.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { pick, capitalize } from 'lodash'; +import { pick, upperFirst } from 'lodash'; import moment from 'moment'; import { getSearchValue } from '../../lib/get_search_value'; @@ -26,7 +26,7 @@ export class PipelineListItem { if (props.lastModified) { this.lastModified = getMomentDate(props.lastModified); - this.lastModifiedHumanized = capitalize(this.lastModified.fromNow()); + this.lastModifiedHumanized = upperFirst(this.lastModified.fromNow()); } } diff --git a/x-pack/plugins/logstash/server/models/cluster/cluster.ts b/x-pack/plugins/logstash/server/models/cluster/cluster.ts index 54f03605e14d6..6bc57eae41b76 100755 --- a/x-pack/plugins/logstash/server/models/cluster/cluster.ts +++ b/x-pack/plugins/logstash/server/models/cluster/cluster.ts @@ -25,7 +25,7 @@ export class Cluster { // generate Pipeline object from elasticsearch response static fromUpstreamJSON(upstreamCluster: Record) { - const uuid = get(upstreamCluster, 'cluster_uuid'); + const uuid = get(upstreamCluster, 'cluster_uuid') as string; return new Cluster({ uuid }); } } diff --git a/x-pack/plugins/logstash/server/models/pipeline/pipeline.ts b/x-pack/plugins/logstash/server/models/pipeline/pipeline.ts index 3f2debeebeb46..8ce04c83afdbf 100755 --- a/x-pack/plugins/logstash/server/models/pipeline/pipeline.ts +++ b/x-pack/plugins/logstash/server/models/pipeline/pipeline.ts @@ -103,11 +103,11 @@ export class Pipeline { ) ); } - const id = get(upstreamPipeline, '_id'); - const description = get(upstreamPipeline, '_source.description'); - const username = get(upstreamPipeline, '_source.username'); - const pipeline = get(upstreamPipeline, '_source.pipeline'); - const settings = get>(upstreamPipeline, '_source.pipeline_settings'); + const id = get(upstreamPipeline, '_id') as string; + const description = get(upstreamPipeline, '_source.description') as string; + const username = get(upstreamPipeline, '_source.username') as string; + const pipeline = get(upstreamPipeline, '_source.pipeline') as string; + const settings = get(upstreamPipeline, '_source.pipeline_settings') as Record; const opts: PipelineOptions = { id, description, username, pipeline, settings }; diff --git a/x-pack/plugins/logstash/server/models/pipeline_list_item/pipeline_list_item.ts b/x-pack/plugins/logstash/server/models/pipeline_list_item/pipeline_list_item.ts index 98c91fca1fcca..eeb197a58f51d 100755 --- a/x-pack/plugins/logstash/server/models/pipeline_list_item/pipeline_list_item.ts +++ b/x-pack/plugins/logstash/server/models/pipeline_list_item/pipeline_list_item.ts @@ -37,9 +37,9 @@ export class PipelineListItem { static fromUpstreamJSON(pipeline: Hit) { const opts = { id: pipeline._id, - description: get(pipeline, '_source.description'), - last_modified: get(pipeline, '_source.last_modified'), - username: get(pipeline, '_source.username'), + description: get(pipeline, '_source.description') as string, + last_modified: get(pipeline, '_source.last_modified') as string, + username: get(pipeline, '_source.username') as string, }; return new PipelineListItem(opts); diff --git a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx index a959912718197..8c2f5e271ff5c 100644 --- a/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx +++ b/x-pack/plugins/maps/public/classes/sources/mvt_single_layer_vector_source/update_source_editor.tsx @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import _ from 'lodash'; import React, { Component, Fragment } from 'react'; import { EuiTitle, EuiPanel, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; diff --git a/x-pack/plugins/maps/public/classes/styles/vector/components/field_meta/categorical_field_meta_popover.tsx b/x-pack/plugins/maps/public/classes/styles/vector/components/field_meta/categorical_field_meta_popover.tsx index 550b3737963d5..fac002d0a877d 100644 --- a/x-pack/plugins/maps/public/classes/styles/vector/components/field_meta/categorical_field_meta_popover.tsx +++ b/x-pack/plugins/maps/public/classes/styles/vector/components/field_meta/categorical_field_meta_popover.tsx @@ -5,7 +5,6 @@ */ /* eslint-disable @typescript-eslint/consistent-type-definitions */ -import _ from 'lodash'; import React from 'react'; import { EuiFormRow, EuiSwitch, EuiSwitchEvent } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; diff --git a/x-pack/plugins/maps/public/classes/util/data_request.ts b/x-pack/plugins/maps/public/classes/util/data_request.ts index 44b7b2ffb6ae7..42c19b8c641e0 100644 --- a/x-pack/plugins/maps/public/classes/util/data_request.ts +++ b/x-pack/plugins/maps/public/classes/util/data_request.ts @@ -5,7 +5,6 @@ */ /* eslint-disable max-classes-per-file */ -import _ from 'lodash'; import { DataRequestDescriptor, DataMeta } from '../../../common/descriptor_types'; export class DataRequest { diff --git a/x-pack/plugins/maps/server/maps_telemetry/maps_telemetry.ts b/x-pack/plugins/maps/server/maps_telemetry/maps_telemetry.ts index 0e29eca244642..5f57d666b9f74 100644 --- a/x-pack/plugins/maps/server/maps_telemetry/maps_telemetry.ts +++ b/x-pack/plugins/maps/server/maps_telemetry/maps_telemetry.ts @@ -45,8 +45,8 @@ function getUniqueLayerCounts(layerCountsList: ILayerTypeCount[], mapsCount: num ); const typeCountsSum = _.sum(typeCounts); accu[type] = { - min: typeCounts.length ? _.min(typeCounts) : 0, - max: typeCounts.length ? _.max(typeCounts) : 0, + min: typeCounts.length ? (_.min(typeCounts) as number) : 0, + max: typeCounts.length ? (_.max(typeCounts) as number) : 0, avg: typeCountsSum ? typeCountsSum / mapsCount : 0, }; return accu; @@ -115,9 +115,9 @@ export function buildMapsTelemetry({ const isEmsFile = _.get(layer, 'sourceDescriptor.type') === SOURCE_TYPES.EMS_FILE; return isEmsFile && _.get(layer, 'sourceDescriptor.id'); }) - .pick((val, key) => key !== 'false') + .pickBy((val, key) => key !== 'false') .value() - ); + ) as ILayerTypeCount[]; const dataSourcesCountSum = _.sum(dataSourcesCount); const layersCountSum = _.sum(layersCount); @@ -174,10 +174,10 @@ export async function getMapsTelemetry(config: MapsConfigType) { const savedObjectsClient = getInternalRepository(); // @ts-ignore const mapSavedObjects: MapSavedObject[] = await getMapSavedObjects(savedObjectsClient); - const indexPatternSavedObjects: IIndexPattern[] = await getIndexPatternSavedObjects( + const indexPatternSavedObjects: IIndexPattern[] = (await getIndexPatternSavedObjects( // @ts-ignore savedObjectsClient - ); + )) as IIndexPattern[]; const settings: SavedObjectAttribute = { showMapVisualizationTypes: config.showMapVisualizationTypes, }; diff --git a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container_service.js b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container_service.js index 8b30dccc25306..898e29a303881 100644 --- a/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container_service.js +++ b/x-pack/plugins/ml/public/application/explorer/explorer_charts/explorer_charts_container_service.js @@ -560,7 +560,7 @@ function calculateChartRange( // Calculate the time range for the charts. // Fit in as many points in the available container width plotted at the job bucket span. const midpointMs = Math.ceil((earliestMs + latestMs) / 2); - const maxBucketSpanMs = Math.max.apply(null, _.pluck(seriesConfigs, 'bucketSpanSeconds')) * 1000; + const maxBucketSpanMs = Math.max.apply(null, _.map(seriesConfigs, 'bucketSpanSeconds')) * 1000; const pointsToPlotFullSelection = Math.ceil((latestMs - earliestMs) / maxBucketSpanMs); diff --git a/x-pack/plugins/ml/public/application/util/string_utils.js b/x-pack/plugins/ml/public/application/util/string_utils.js index 450c166f90300..7411820ba3239 100644 --- a/x-pack/plugins/ml/public/application/util/string_utils.js +++ b/x-pack/plugins/ml/public/application/util/string_utils.js @@ -91,7 +91,7 @@ export function sortByKey(list, reverse, comparator) { keys = keys.reverse(); } - return _.object( + return _.zipObject( keys, _.map(keys, (key) => { return list[key]; diff --git a/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts b/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts index 78cc7901363cd..d58c797b446db 100644 --- a/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts +++ b/x-pack/plugins/ml/server/models/data_visualizer/data_visualizer.ts @@ -143,7 +143,7 @@ export class DataVisualizer { // split the check into multiple batches (max 200 fields per request). const batches: string[][] = [[]]; _.each(aggregatableFields, (field) => { - let lastArray: string[] = _.last(batches); + let lastArray: string[] = _.last(batches) as string[]; if (lastArray.length === AGGREGATABLE_EXISTS_REQUEST_BATCH_SIZE) { lastArray = []; batches.push(lastArray); @@ -229,7 +229,7 @@ export class DataVisualizer { if (batchedFields[fieldType] === undefined) { batchedFields[fieldType] = [[]]; } - let lastArray: Field[] = _.last(batchedFields[fieldType]); + let lastArray: Field[] = _.last(batchedFields[fieldType]) as Field[]; if (lastArray.length === FIELDS_REQUEST_BATCH_SIZE) { lastArray = []; batchedFields[fieldType].push(lastArray); @@ -867,7 +867,7 @@ export class DataVisualizer { [...aggsPath, `${safeFieldName}_values`, 'buckets'], [] ); - _.each(valueBuckets, (bucket) => { + _.forEach(valueBuckets, (bucket) => { stats[`${bucket.key_as_string}Count`] = bucket.doc_count; }); @@ -958,7 +958,7 @@ export class DataVisualizer { // Look ahead to the last percentiles and process these too if // they don't add more than 50% to the value range. - const lastValue = _.last(percentileBuckets).value; + const lastValue = (_.last(percentileBuckets) as any).value; const upperBound = lowerBound + 1.5 * (lastValue - lowerBound); const filteredLength = percentileBuckets.length; for (let i = filteredLength; i < percentiles.length; i++) { @@ -979,7 +979,7 @@ export class DataVisualizer { // Add in 0-5 and 95-100% if they don't add more // than 25% to the value range at either end. - const lastValue: number = _.last(percentileBuckets).value; + const lastValue: number = (_.last(percentileBuckets) as any).value; const maxDiff = 0.25 * (lastValue - lowerBound); if (lowerBound - dataMin < maxDiff) { percentileBuckets.splice(0, 0, percentiles[0]); diff --git a/x-pack/plugins/monitoring/public/angular/app_modules.ts b/x-pack/plugins/monitoring/public/angular/app_modules.ts index 726d4be4924d7..9ebb074ec7c3b 100644 --- a/x-pack/plugins/monitoring/public/angular/app_modules.ts +++ b/x-pack/plugins/monitoring/public/angular/app_modules.ts @@ -10,7 +10,7 @@ import '../views/all'; import 'angular-sanitize'; import 'angular-route'; import '../index.scss'; -import { capitalize } from 'lodash'; +import { upperFirst } from 'lodash'; import { i18nDirective, i18nFilter, I18nProvider } from '@kbn/i18n/angular'; import { AppMountContext } from 'kibana/public'; import { Storage } from '../../../../../src/plugins/kibana_utils/public'; @@ -159,7 +159,7 @@ function createMonitoringAppFilters() { .module('monitoring/filters', []) .filter('capitalize', function () { return function (input: string) { - return capitalize(input?.toLowerCase()); + return upperFirst(input?.toLowerCase()); }; }) .filter('formatNumber', function () { diff --git a/x-pack/plugins/monitoring/public/components/alerts/alerts.js b/x-pack/plugins/monitoring/public/components/alerts/alerts.js index b3fc70e9ffd7d..59e838c449a3b 100644 --- a/x-pack/plugins/monitoring/public/components/alerts/alerts.js +++ b/x-pack/plugins/monitoring/public/components/alerts/alerts.js @@ -6,7 +6,7 @@ import React from 'react'; import { Legacy } from '../../legacy_shims'; -import { capitalize, get } from 'lodash'; +import { upperFirst, get } from 'lodash'; import { formatDateTimeLocal } from '../../../common/formatting'; import { formatTimestampToDuration } from '../../../common'; import { @@ -55,7 +55,7 @@ const getColumns = (timezone) => [ data-test-subj="alertIcon" aria-label={severityIcon.title} > - {capitalize(severityIcon.value)} + {upperFirst(severityIcon.value)} ); diff --git a/x-pack/plugins/monitoring/public/components/alerts/map_severity.js b/x-pack/plugins/monitoring/public/components/alerts/map_severity.js index b76f4eb5b75a7..8232e0a8908d0 100644 --- a/x-pack/plugins/monitoring/public/components/alerts/map_severity.js +++ b/x-pack/plugins/monitoring/public/components/alerts/map_severity.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { capitalize } from 'lodash'; +import { upperFirst } from 'lodash'; /** * Map the {@code severity} value to the associated alert level to be usable within the UI. @@ -68,7 +68,7 @@ export function mapSeverity(severity) { return { title: i18n.translate('xpack.monitoring.alerts.severityTitle', { defaultMessage: '{severity} severity alert', - values: { severity: capitalize(mapped.value) }, + values: { severity: upperFirst(mapped.value) }, }), ...mapped, }; diff --git a/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/lib/decorate_shards.js b/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/lib/decorate_shards.js index 9c5981585a8de..9acfce1e8c0b9 100644 --- a/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/lib/decorate_shards.js +++ b/x-pack/plugins/monitoring/public/components/elasticsearch/shard_allocation/lib/decorate_shards.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { capitalize, find, get, includes } from 'lodash'; +import { upperFirst, find, get, includes } from 'lodash'; import { i18n } from '@kbn/i18n'; export function decorateShards(shards, nodes) { @@ -40,7 +40,7 @@ export function decorateShards(shards, nodes) { ); } } - return capitalize(shard.state.toLowerCase()); + return upperFirst(shard.state.toLowerCase()); } return shards.map((shard) => { diff --git a/x-pack/plugins/monitoring/public/components/logs/logs.js b/x-pack/plugins/monitoring/public/components/logs/logs.js index 0ab3683f4b72f..297ce49f1f148 100644 --- a/x-pack/plugins/monitoring/public/components/logs/logs.js +++ b/x-pack/plugins/monitoring/public/components/logs/logs.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import React, { PureComponent } from 'react'; -import { capitalize } from 'lodash'; +import { upperFirst } from 'lodash'; import { Legacy } from '../../legacy_shims'; import { EuiBasicTable, EuiTitle, EuiSpacer, EuiText, EuiCallOut, EuiLink } from '@elastic/eui'; import { INFRA_SOURCE_ID } from '../../../common/constants'; @@ -59,7 +59,7 @@ const columns = [ field: 'type', name: columnTypeTitle, width: '10%', - render: (type) => capitalize(type), + render: (type) => upperFirst(type), }, { field: 'message', @@ -89,7 +89,7 @@ const clusterColumns = [ field: 'type', name: columnTypeTitle, width: '10%', - render: (type) => capitalize(type), + render: (type) => upperFirst(type), }, { field: 'message', diff --git a/x-pack/plugins/monitoring/public/lib/ajax_error_handler.tsx b/x-pack/plugins/monitoring/public/lib/ajax_error_handler.tsx index 14f838cff7a3c..12bd3a7575cf2 100644 --- a/x-pack/plugins/monitoring/public/lib/ajax_error_handler.tsx +++ b/x-pack/plugins/monitoring/public/lib/ajax_error_handler.tsx @@ -5,7 +5,7 @@ */ import React from 'react'; -import { contains } from 'lodash'; +import { includes } from 'lodash'; import { EuiButton, EuiSpacer, EuiText } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { Legacy } from '../legacy_shims'; @@ -38,7 +38,7 @@ export function ajaxErrorHandlersProvider() { if (err.status === 403) { // redirect to error message view history.replaceState(null, '', '#/access-denied'); - } else if (err.status === 404 && !contains(window.location.hash, 'no-data')) { + } else if (err.status === 404 && !includes(window.location.hash, 'no-data')) { // pass through if this is a 404 and we're already on the no-data page Legacy.shims.toastNotifications.addDanger({ title: toMountPoint( diff --git a/x-pack/plugins/monitoring/public/lib/form_validation.ts b/x-pack/plugins/monitoring/public/lib/form_validation.ts index 98d56f9790be4..2255022dcece0 100644 --- a/x-pack/plugins/monitoring/public/lib/form_validation.ts +++ b/x-pack/plugins/monitoring/public/lib/form_validation.ts @@ -5,13 +5,13 @@ */ import { i18n } from '@kbn/i18n'; -import { isString, isNumber, capitalize } from 'lodash'; +import { isString, isNumber, upperFirst } from 'lodash'; export function getRequiredFieldError(field: string): string { return i18n.translate('xpack.monitoring.alerts.migrate.manageAction.requiredFieldError', { defaultMessage: '{field} is a required field.', values: { - field: capitalize(field), + field: upperFirst(field), }, }); } diff --git a/x-pack/plugins/monitoring/public/lib/route_init.js b/x-pack/plugins/monitoring/public/lib/route_init.js index 9467535d556b0..163688d772022 100644 --- a/x-pack/plugins/monitoring/public/lib/route_init.js +++ b/x-pack/plugins/monitoring/public/lib/route_init.js @@ -13,7 +13,7 @@ export function routeInitProvider(Private, monitoringClusters, globalState, lice const ajaxErrorHandlers = Private(ajaxErrorHandlersProvider); function isOnPage(hash) { - return _.contains(window.location.hash, hash); + return _.includes(window.location.hash, hash); } /* diff --git a/x-pack/plugins/monitoring/public/lib/setup_mode.tsx b/x-pack/plugins/monitoring/public/lib/setup_mode.tsx index 5afb382b7cda8..2a4caf17515e1 100644 --- a/x-pack/plugins/monitoring/public/lib/setup_mode.tsx +++ b/x-pack/plugins/monitoring/public/lib/setup_mode.tsx @@ -6,14 +6,14 @@ import React from 'react'; import { render } from 'react-dom'; -import { get, contains } from 'lodash'; +import { get, includes } from 'lodash'; import { i18n } from '@kbn/i18n'; import { Legacy } from '../legacy_shims'; import { ajaxErrorHandlersProvider } from './ajax_error_handler'; import { SetupModeEnterButton } from '../components/setup_mode/enter_button'; function isOnPage(hash: string) { - return contains(window.location.hash, hash); + return includes(window.location.hash, hash); } interface IAngularState { diff --git a/x-pack/plugins/monitoring/public/services/license.js b/x-pack/plugins/monitoring/public/services/license.js index 341309004b110..caa21cd8ee8d7 100644 --- a/x-pack/plugins/monitoring/public/services/license.js +++ b/x-pack/plugins/monitoring/public/services/license.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { contains } from 'lodash'; +import { includes } from 'lodash'; import { ML_SUPPORTED_LICENSES } from '../../common/constants'; export function licenseProvider() { @@ -27,7 +27,7 @@ export function licenseProvider() { } mlIsSupported() { - return contains(ML_SUPPORTED_LICENSES, this.license.type); + return includes(ML_SUPPORTED_LICENSES, this.license.type); } doesExpire() { diff --git a/x-pack/plugins/monitoring/server/lib/apm/get_apm_info.js b/x-pack/plugins/monitoring/server/lib/apm/get_apm_info.js index c3fbe266be6d6..cc3682ef764c8 100644 --- a/x-pack/plugins/monitoring/server/lib/apm/get_apm_info.js +++ b/x-pack/plugins/monitoring/server/lib/apm/get_apm_info.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { get, capitalize } from 'lodash'; +import { get, upperFirst } from 'lodash'; import { checkParam } from '../error_missing_required'; import { createQuery } from '../create_query'; import { getDiffCalculation } from '../beats/_beats_stats'; @@ -33,8 +33,8 @@ export function handleResponse(response, apmUuid) { transportAddress: get(stats, 'beat.host', null), version: get(stats, 'beat.version', null), name: get(stats, 'beat.name', null), - type: capitalize(get(stats, 'beat.type')) || null, - output: capitalize(get(stats, 'metrics.libbeat.output.type')) || null, + type: upperFirst(get(stats, 'beat.type')) || null, + output: upperFirst(get(stats, 'metrics.libbeat.output.type')) || null, configReloads: get(stats, 'metrics.libbeat.config.reloads', null), uptime: get(stats, 'metrics.beat.info.uptime.ms', null), eventsTotal: getDiffCalculation(eventsTotalLast, eventsTotalFirst), diff --git a/x-pack/plugins/monitoring/server/lib/apm/get_apms.js b/x-pack/plugins/monitoring/server/lib/apm/get_apms.js index 40070a6b0d0f2..19ed8298391d7 100644 --- a/x-pack/plugins/monitoring/server/lib/apm/get_apms.js +++ b/x-pack/plugins/monitoring/server/lib/apm/get_apms.js @@ -5,7 +5,7 @@ */ import moment from 'moment'; -import { capitalize, get } from 'lodash'; +import { upperFirst, get } from 'lodash'; import { checkParam } from '../error_missing_required'; import { createApmQuery } from './create_apm_query'; import { calculateRate } from '../calculate_rate'; @@ -59,8 +59,8 @@ export function handleResponse(response, start, end) { accum.beats.push({ uuid: get(stats, 'beat.uuid'), name: get(stats, 'beat.name'), - type: capitalize(get(stats, 'beat.type')), - output: capitalize(get(stats, 'metrics.libbeat.output.type')), + type: upperFirst(get(stats, 'beat.type')), + output: upperFirst(get(stats, 'metrics.libbeat.output.type')), total_events_rate: totalEventsRate, bytes_sent_rate: bytesSentRate, errors, diff --git a/x-pack/plugins/monitoring/server/lib/beats/_beats_stats.js b/x-pack/plugins/monitoring/server/lib/beats/_beats_stats.js index cf5a99525cc4c..9508260a64139 100644 --- a/x-pack/plugins/monitoring/server/lib/beats/_beats_stats.js +++ b/x-pack/plugins/monitoring/server/lib/beats/_beats_stats.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { capitalize, get } from 'lodash'; +import { upperFirst, get } from 'lodash'; export const getDiffCalculation = (max, min) => { // no need to test max >= 0, but min <= 0 which is normal for a derivative after restart @@ -105,7 +105,7 @@ export const beatsAggResponseHandler = (response) => { return [ ...types, { - type: capitalize(typeBucket.key), + type: upperFirst(typeBucket.key), count: get(typeBucket, 'uuids.buckets.length'), }, ]; diff --git a/x-pack/plugins/monitoring/server/lib/beats/get_beat_summary.js b/x-pack/plugins/monitoring/server/lib/beats/get_beat_summary.js index 06f6cf4f1a5e0..30ec728546ce9 100644 --- a/x-pack/plugins/monitoring/server/lib/beats/get_beat_summary.js +++ b/x-pack/plugins/monitoring/server/lib/beats/get_beat_summary.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { capitalize, get } from 'lodash'; +import { upperFirst, get } from 'lodash'; import { checkParam } from '../error_missing_required'; import { createBeatsQuery } from './create_beats_query.js'; import { getDiffCalculation } from './_beats_stats'; @@ -33,8 +33,8 @@ export function handleResponse(response, beatUuid) { transportAddress: get(stats, 'beat.host', null), version: get(stats, 'beat.version', null), name: get(stats, 'beat.name', null), - type: capitalize(get(stats, 'beat.type')) || null, - output: capitalize(get(stats, 'metrics.libbeat.output.type')) || null, + type: upperFirst(get(stats, 'beat.type')) || null, + output: upperFirst(get(stats, 'metrics.libbeat.output.type')) || null, configReloads: get(stats, 'metrics.libbeat.config.reloads', null), uptime: get(stats, 'metrics.beat.info.uptime.ms', null), eventsTotal: getDiffCalculation(eventsTotalLast, eventsTotalFirst), diff --git a/x-pack/plugins/monitoring/server/lib/beats/get_beats.js b/x-pack/plugins/monitoring/server/lib/beats/get_beats.js index ef878e4892557..a5d43d1da7ebc 100644 --- a/x-pack/plugins/monitoring/server/lib/beats/get_beats.js +++ b/x-pack/plugins/monitoring/server/lib/beats/get_beats.js @@ -5,7 +5,7 @@ */ import moment from 'moment'; -import { capitalize, get } from 'lodash'; +import { upperFirst, get } from 'lodash'; import { checkParam } from '../error_missing_required'; import { createBeatsQuery } from './create_beats_query'; import { calculateRate } from '../calculate_rate'; @@ -59,8 +59,8 @@ export function handleResponse(response, start, end) { accum.beats.push({ uuid: get(stats, 'beat.uuid'), name: get(stats, 'beat.name'), - type: capitalize(get(stats, 'beat.type')), - output: capitalize(get(stats, 'metrics.libbeat.output.type')), + type: upperFirst(get(stats, 'beat.type')), + output: upperFirst(get(stats, 'metrics.libbeat.output.type')), total_events_rate: totalEventsRate, bytes_sent_rate: bytesSentRate, errors, diff --git a/x-pack/plugins/monitoring/server/lib/beats/get_latest_stats.js b/x-pack/plugins/monitoring/server/lib/beats/get_latest_stats.js index f630903d4e29d..10a75b9d1ca85 100644 --- a/x-pack/plugins/monitoring/server/lib/beats/get_latest_stats.js +++ b/x-pack/plugins/monitoring/server/lib/beats/get_latest_stats.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { capitalize, get } from 'lodash'; +import { upperFirst, get } from 'lodash'; import { checkParam } from '../error_missing_required'; import { createBeatsQuery } from './create_beats_query'; @@ -47,7 +47,7 @@ export function handleResponse(response) { return [ ...accum, { - type: capitalize(current.key), + type: upperFirst(current.key), count: get(current, 'uuids.buckets.length'), }, ]; diff --git a/x-pack/plugins/monitoring/server/lib/elasticsearch/get_ml_jobs.js b/x-pack/plugins/monitoring/server/lib/elasticsearch/get_ml_jobs.js index c6575393590f0..74d4bd6d2b5df 100644 --- a/x-pack/plugins/monitoring/server/lib/elasticsearch/get_ml_jobs.js +++ b/x-pack/plugins/monitoring/server/lib/elasticsearch/get_ml_jobs.js @@ -5,7 +5,7 @@ */ import Bluebird from 'bluebird'; -import { contains, get } from 'lodash'; +import { includes, get } from 'lodash'; import { checkParam } from '../error_missing_required'; import { createQuery } from '../create_query'; import { ElasticsearchMetric } from '../metrics'; @@ -59,7 +59,7 @@ export function getMlJobs(req, esIndexPattern) { export function getMlJobsForCluster(req, esIndexPattern, cluster) { const license = get(cluster, 'license', {}); - if (license.status === 'active' && contains(ML_SUPPORTED_LICENSES, license.type)) { + if (license.status === 'active' && includes(ML_SUPPORTED_LICENSES, license.type)) { // ML is supported const start = req.payload.timeRange.min; // no wrapping in moment :) const end = req.payload.timeRange.max; diff --git a/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/map_nodes_metrics.js b/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/map_nodes_metrics.js index 4e5e439ff90d5..d1a7aec2f153f 100644 --- a/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/map_nodes_metrics.js +++ b/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/map_nodes_metrics.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { get, pluck, min, max, last } from 'lodash'; +import { get, map, min, max, last } from 'lodash'; import { filterPartialBuckets } from '../../../filter_partial_buckets'; import { metrics } from '../../../metrics'; @@ -76,14 +76,14 @@ function reduceMetric(metricName, metricBuckets, { min: startTime, max: endTime, /* it's possible that no data exists for the type of metric. For example, * node_cgroup_throttled data could be completely null if there is no cgroup * throttling. */ - const allValues = pluck(mappedData, 'y'); + const allValues = map(mappedData, 'y'); if (allValues.join(',') === '') { return; // no data exists for this type of metric } - const minVal = min(pluck(mappedData, 'y')); - const maxVal = max(pluck(mappedData, 'y')); - const lastVal = last(pluck(mappedData, 'y')); + const minVal = min(map(mappedData, 'y')); + const maxVal = max(map(mappedData, 'y')); + const lastVal = last(map(mappedData, 'y')); const slope = calcSlope(mappedData) > 0 ? 1 : -1; // no need for the entire precision, it's just an up/down arrow return { diff --git a/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/sort_nodes.js b/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/sort_nodes.js index 8782875775530..39855e7f10eaf 100644 --- a/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/sort_nodes.js +++ b/x-pack/plugins/monitoring/server/lib/elasticsearch/nodes/get_nodes/sort_nodes.js @@ -3,12 +3,12 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { sortByOrder } from 'lodash'; +import { orderBy } from 'lodash'; export function sortNodes(nodes, sort) { if (!sort || !sort.field) { return nodes; } - return sortByOrder(nodes, (node) => node[sort.field], sort.direction); + return orderBy(nodes, (node) => node[sort.field], sort.direction); } diff --git a/x-pack/plugins/monitoring/server/lib/logstash/sort_pipelines.js b/x-pack/plugins/monitoring/server/lib/logstash/sort_pipelines.js index 2a5c15ece4b40..e4a36fdf35daf 100644 --- a/x-pack/plugins/monitoring/server/lib/logstash/sort_pipelines.js +++ b/x-pack/plugins/monitoring/server/lib/logstash/sort_pipelines.js @@ -3,12 +3,12 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { sortByOrder } from 'lodash'; +import { orderBy } from 'lodash'; export function sortPipelines(pipelines, sort) { if (!sort) { return pipelines; } - return sortByOrder(pipelines, (pipeline) => pipeline[sort.field], sort.direction); + return orderBy(pipelines, (pipeline) => pipeline[sort.field], sort.direction); } diff --git a/x-pack/plugins/oss_telemetry/server/lib/tasks/visualizations/task_runner.ts b/x-pack/plugins/oss_telemetry/server/lib/tasks/visualizations/task_runner.ts index d7a708173d3ad..27913fafe3257 100644 --- a/x-pack/plugins/oss_telemetry/server/lib/tasks/visualizations/task_runner.ts +++ b/x-pack/plugins/oss_telemetry/server/lib/tasks/visualizations/task_runner.ts @@ -40,7 +40,7 @@ async function getStats(callCluster: LegacyAPICaller, index: string) { }, }; const esResponse = await callCluster('search', searchParams); - const size = _.get(esResponse, 'hits.hits.length'); + const size = _.get(esResponse, 'hits.hits.length') as number; if (size < 1) { return; } diff --git a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx index 37441edce0af8..d0800c7b24fef 100644 --- a/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx +++ b/x-pack/plugins/reporting/public/panel_actions/get_csv_panel_action.tsx @@ -5,6 +5,7 @@ */ import dateMath from '@elastic/datemath'; import { i18n } from '@kbn/i18n'; +import _ from 'lodash'; import moment from 'moment-timezone'; import { CoreSetup } from 'src/core/public'; import { Action, IncompatibleActionError } from '../../../../../src/plugins/ui_actions/public'; diff --git a/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts b/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts index 898b123e976fd..bca9496bc9add 100644 --- a/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts +++ b/x-pack/plugins/reporting/server/browsers/chromium/driver/chromium_driver.ts @@ -5,7 +5,7 @@ */ import { i18n } from '@kbn/i18n'; -import { map, trunc } from 'lodash'; +import { map, truncate } from 'lodash'; import open from 'opn'; import { ElementHandle, EvaluateFn, Page, Response, SerializableOrJSHandle } from 'puppeteer'; import { parse as parseUrl } from 'url'; @@ -70,7 +70,7 @@ export class HeadlessChromiumDriver { } private truncateUrl(url: string) { - return trunc(url, { + return truncate(url, { length: 100, omission: '[truncated]', }); diff --git a/x-pack/plugins/reporting/server/config/create_config.ts b/x-pack/plugins/reporting/server/config/create_config.ts index 5c66bd599dd9a..3c892fe6120af 100644 --- a/x-pack/plugins/reporting/server/config/create_config.ts +++ b/x-pack/plugins/reporting/server/config/create_config.ts @@ -6,7 +6,7 @@ import { i18n } from '@kbn/i18n/'; import crypto from 'crypto'; -import { capitalize } from 'lodash'; +import { upperFirst } from 'lodash'; import { Observable } from 'rxjs'; import { map, mergeMap } from 'rxjs/operators'; import { CoreSetup } from 'src/core/server'; @@ -84,7 +84,7 @@ export function createConfig$( // disableSandbox was not set by user, apply default for OS const { os, disableSandbox } = await getDefaultChromiumSandboxDisabled(); - const osName = [os.os, os.dist, os.release].filter(Boolean).map(capitalize).join(' '); + const osName = [os.os, os.dist, os.release].filter(Boolean).map(upperFirst).join(' '); logger.debug( i18n.translate('xpack.reporting.serverConfig.osDetected', { diff --git a/x-pack/plugins/reporting/server/export_types/common/execute_job/omit_blacklisted_headers.ts b/x-pack/plugins/reporting/server/export_types/common/execute_job/omit_blacklisted_headers.ts index db7137c30513b..305fb6bab5478 100644 --- a/x-pack/plugins/reporting/server/export_types/common/execute_job/omit_blacklisted_headers.ts +++ b/x-pack/plugins/reporting/server/export_types/common/execute_job/omit_blacklisted_headers.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { omit } from 'lodash'; +import { omitBy } from 'lodash'; import { KBN_SCREENSHOT_HEADER_BLACKLIST, KBN_SCREENSHOT_HEADER_BLACKLIST_STARTS_WITH_PATTERN, @@ -16,7 +16,7 @@ export const omitBlacklistedHeaders = ({ job: ScheduledTaskParamsType; decryptedHeaders: Record; }) => { - const filteredHeaders: Record = omit( + const filteredHeaders: Record = omitBy( decryptedHeaders, (_value, header: string) => header && diff --git a/x-pack/plugins/reporting/server/export_types/csv/server/lib/flatten_hit.ts b/x-pack/plugins/reporting/server/export_types/csv/server/lib/flatten_hit.ts index a4c634439ec45..acfae5138154c 100644 --- a/x-pack/plugins/reporting/server/export_types/csv/server/lib/flatten_hit.ts +++ b/x-pack/plugins/reporting/server/export_types/csv/server/lib/flatten_hit.ts @@ -30,7 +30,7 @@ export function createFlattenHit( } else if (_.isArray(flat[key])) { flat[key].push(val); } else { - flat[key] = [flat[key], val]; + flat[key] = [flat[key], val] as any; } return; } @@ -49,7 +49,7 @@ export function createFlattenHit( const flattenFields = (flat: FlatHits, hitFields: string[]) => { _.forOwn(hitFields, (val, key) => { if (key) { - if (key[0] === '_' && !_.contains(metaFields, key)) return; + if (key[0] === '_' && !_.includes(metaFields, key)) return; flat[key] = _.isArray(val) && val.length === 1 ? val[0] : val; } }); diff --git a/x-pack/plugins/reporting/server/usage/get_reporting_usage.ts b/x-pack/plugins/reporting/server/usage/get_reporting_usage.ts index 2a6d08c0740dd..213bea3bc3eec 100644 --- a/x-pack/plugins/reporting/server/usage/get_reporting_usage.ts +++ b/x-pack/plugins/reporting/server/usage/get_reporting_usage.ts @@ -13,11 +13,9 @@ import { decorateRangeStats } from './decorate_range_stats'; import { getExportTypesHandler } from './get_export_type_handler'; import { AggregationResultBuckets, - AppCounts, FeatureAvailabilityMap, JobTypes, KeyCountBucket, - LayoutCounts, RangeStats, ReportingUsageType, SearchResponse, @@ -75,21 +73,21 @@ function getAggStats(aggs: AggregationResultBuckets): Partial { // merge pdf stats into pdf jobtype key const pdfJobs = jobTypes[PRINTABLE_PDF_JOBTYPE]; if (pdfJobs) { - const pdfAppBuckets = get(aggs[OBJECT_TYPES_KEY], '.pdf.buckets', []); - const pdfLayoutBuckets = get(aggs[LAYOUT_TYPES_KEY], '.pdf.buckets', []); - pdfJobs.app = getKeyCount(pdfAppBuckets); - pdfJobs.layout = getKeyCount(pdfLayoutBuckets); + const pdfAppBuckets = get(aggs[OBJECT_TYPES_KEY], 'pdf.buckets', []); + const pdfLayoutBuckets = get(aggs[LAYOUT_TYPES_KEY], 'pdf.buckets', []); + pdfJobs.app = getKeyCount(pdfAppBuckets); + pdfJobs.layout = getKeyCount(pdfLayoutBuckets); } const all = aggs.doc_count; let statusTypes = {}; - const statusBuckets = get(aggs[STATUS_TYPES_KEY], 'buckets', []); + const statusBuckets = get(aggs[STATUS_TYPES_KEY], 'buckets', []); if (statusBuckets) { statusTypes = getKeyCount(statusBuckets); } let statusByApp = {}; - const statusAppBuckets = get(aggs[STATUS_BY_APP_KEY], 'buckets', []); + const statusAppBuckets = get(aggs[STATUS_BY_APP_KEY], 'buckets', []); if (statusAppBuckets) { statusByApp = getAppStatuses(statusAppBuckets); } @@ -97,18 +95,16 @@ function getAggStats(aggs: AggregationResultBuckets): Partial { return { _all: all, status: statusTypes, statuses: statusByApp, ...jobTypes }; } -type SearchAggregation = SearchResponse['aggregations']['ranges']['buckets']; - type RangeStatSets = Partial & { last7Days: Partial; }; async function handleResponse(response: SearchResponse): Promise> { - const buckets = get(response, 'aggregations.ranges.buckets'); + const buckets = get(response, 'aggregations.ranges.buckets'); if (!buckets) { return {}; } - const { last7Days, all } = buckets; + const { last7Days, all } = buckets as any; const last7DaysUsage = last7Days ? getAggStats(last7Days) : {}; const allUsage = all ? getAggStats(all) : {}; diff --git a/x-pack/plugins/rollup/public/crud_app/sections/job_create/job_create.js b/x-pack/plugins/rollup/public/crud_app/sections/job_create/job_create.js index 151eff31f8a01..8c326c3f8a788 100644 --- a/x-pack/plugins/rollup/public/crud_app/sections/job_create/job_create.js +++ b/x-pack/plugins/rollup/public/crud_app/sections/job_create/job_create.js @@ -6,10 +6,7 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; -import mapValues from 'lodash/object/mapValues'; -import cloneDeep from 'lodash/lang/cloneDeep'; -import debounce from 'lodash/function/debounce'; -import first from 'lodash/array/first'; +import { cloneDeep, debounce, first, mapValues } from 'lodash'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; diff --git a/x-pack/plugins/rollup/public/crud_app/sections/job_create/steps/step_metrics.js b/x-pack/plugins/rollup/public/crud_app/sections/job_create/steps/step_metrics.js index d70fbb89c065d..df9b63bc5fa3d 100644 --- a/x-pack/plugins/rollup/public/crud_app/sections/job_create/steps/step_metrics.js +++ b/x-pack/plugins/rollup/public/crud_app/sections/job_create/steps/step_metrics.js @@ -8,7 +8,7 @@ import React, { Component, Fragment } from 'react'; import PropTypes from 'prop-types'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import get from 'lodash/object/get'; +import { get } from 'lodash'; import { EuiButtonEmpty, diff --git a/x-pack/plugins/rollup/public/crud_app/sections/job_create/steps_config/index.js b/x-pack/plugins/rollup/public/crud_app/sections/job_create/steps_config/index.js index 3a61518a850e9..56225639777cd 100644 --- a/x-pack/plugins/rollup/public/crud_app/sections/job_create/steps_config/index.js +++ b/x-pack/plugins/rollup/public/crud_app/sections/job_create/steps_config/index.js @@ -4,9 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import cloneDeep from 'lodash/lang/cloneDeep'; -import get from 'lodash/object/get'; -import pick from 'lodash/object/pick'; +import { cloneDeep, get, pick } from 'lodash'; import { WEEK } from '../../../../../../../../src/plugins/es_ui_shared/public'; diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_create_clone.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_create_clone.test.js index aa95bbbd9cf0d..3ebc7e5c8192c 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_create_clone.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_create_clone.test.js @@ -9,7 +9,10 @@ import { mockHttpRequest, pageHelpers, nextTick } from './helpers'; import { JOB_TO_CLONE, JOB_CLONE_INDEX_PATTERN_CHECK } from './helpers/constants'; import { coreMock } from '../../../../../../src/core/public/mocks'; -jest.mock('lodash/function/debounce', () => (fn) => fn); +jest.mock('lodash', () => ({ + ...jest.requireActual('lodash'), + debounce: (fn) => fn, +})); const { setup } = pageHelpers.jobClone; const { diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_create_date_histogram.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_create_date_histogram.test.js index 8791b5173b893..90f53a91e425a 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_create_date_histogram.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_create_date_histogram.test.js @@ -10,7 +10,10 @@ import { setHttp } from '../../crud_app/services'; import { mockHttpRequest, pageHelpers } from './helpers'; import { coreMock } from '../../../../../../src/core/public/mocks'; -jest.mock('lodash/function/debounce', () => (fn) => fn); +jest.mock('lodash', () => ({ + ...jest.requireActual('lodash'), + debounce: (fn) => fn, +})); const { setup } = pageHelpers.jobCreate; diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_create_histogram.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_create_histogram.test.js index 50898f94586fc..549f6ab063746 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_create_histogram.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_create_histogram.test.js @@ -8,7 +8,10 @@ import { setHttp } from '../../crud_app/services'; import { mockHttpRequest, pageHelpers } from './helpers'; import { coreMock } from '../../../../../../src/core/public/mocks'; -jest.mock('lodash/function/debounce', () => (fn) => fn); +jest.mock('lodash', () => ({ + ...jest.requireActual('lodash'), + debounce: (fn) => fn, +})); const { setup } = pageHelpers.jobCreate; diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_create_logistics.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_create_logistics.test.js index a1edf87c33bad..6cf33334d9281 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_create_logistics.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_create_logistics.test.js @@ -17,7 +17,10 @@ import { setHttp } from '../../crud_app/services'; import { mockHttpRequest, pageHelpers } from './helpers'; import { coreMock } from '../../../../../../src/core/public/mocks'; -jest.mock('lodash/function/debounce', () => (fn) => fn); +jest.mock('lodash', () => ({ + ...jest.requireActual('lodash'), + debounce: (fn) => fn, +})); const { setup } = pageHelpers.jobCreate; diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_create_metrics.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_create_metrics.test.js index 7f58482d35b19..d75c7b585994c 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_create_metrics.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_create_metrics.test.js @@ -8,7 +8,10 @@ import { setHttp } from '../../crud_app/services'; import { mockHttpRequest, pageHelpers } from './helpers'; import { coreMock } from '../../../../../../src/core/public/mocks'; -jest.mock('lodash/function/debounce', () => (fn) => fn); +jest.mock('lodash', () => ({ + ...jest.requireActual('lodash'), + debounce: (fn) => fn, +})); const { setup } = pageHelpers.jobCreate; diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_create_review.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_create_review.test.js index 59118ef6f8ec3..3dbbe70bfc560 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_create_review.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_create_review.test.js @@ -10,7 +10,10 @@ import { setHttp } from '../../crud_app/services'; import { JOBS } from './helpers/constants'; import { coreMock } from '../../../../../../src/core/public/mocks'; -jest.mock('lodash/function/debounce', () => (fn) => fn); +jest.mock('lodash', () => ({ + ...jest.requireActual('lodash'), + debounce: (fn) => fn, +})); jest.mock('../../kibana_services', () => { const services = require.requireActual('../../kibana_services'); diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_create_terms.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_create_terms.test.js index f21fc2c12a007..9434747028e53 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_create_terms.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_create_terms.test.js @@ -8,7 +8,10 @@ import { setHttp } from '../../crud_app/services'; import { pageHelpers, mockHttpRequest } from './helpers'; import { coreMock } from '../../../../../../src/core/public/mocks'; -jest.mock('lodash/function/debounce', () => (fn) => fn); +jest.mock('lodash', () => ({ + ...jest.requireActual('lodash'), + debounce: (fn) => fn, +})); const { setup } = pageHelpers.jobCreate; diff --git a/x-pack/plugins/rollup/public/test/client_integration/job_list_clone.test.js b/x-pack/plugins/rollup/public/test/client_integration/job_list_clone.test.js index 53a3af38f3235..76be39a2c0e09 100644 --- a/x-pack/plugins/rollup/public/test/client_integration/job_list_clone.test.js +++ b/x-pack/plugins/rollup/public/test/client_integration/job_list_clone.test.js @@ -10,7 +10,10 @@ import { getRouter } from '../../crud_app/services/routing'; import { setHttp } from '../../crud_app/services'; import { coreMock } from '../../../../../../src/core/public/mocks'; -jest.mock('lodash/function/debounce', () => (fn) => fn); +jest.mock('lodash', () => ({ + ...jest.requireActual('lodash'), + debounce: (fn) => fn, +})); jest.mock('../../kibana_services', () => { const services = require.requireActual('../../kibana_services'); diff --git a/x-pack/plugins/rollup/server/collectors/register.ts b/x-pack/plugins/rollup/server/collectors/register.ts index c679098bc05be..35c40e42efc19 100644 --- a/x-pack/plugins/rollup/server/collectors/register.ts +++ b/x-pack/plugins/rollup/server/collectors/register.ts @@ -48,7 +48,7 @@ async function fetchRollupIndexPatterns(kibanaIndex: string, callCluster: CallCl const esResponse = await callCluster('search', searchParams); - return get(esResponse, 'hits.hits', []).map((indexPattern) => { + return get(esResponse, 'hits.hits', []).map((indexPattern: any) => { const { _id: savedObjectId } = indexPattern; return getIdFromSavedObjectId(savedObjectId); }); @@ -81,7 +81,7 @@ async function fetchRollupSavedSearches( const savedSearches = get(esResponse, 'hits.hits', []); // Filter for ones with rollup index patterns. - return savedSearches.reduce((rollupSavedSearches, savedSearch) => { + return savedSearches.reduce((rollupSavedSearches: any, savedSearch: any) => { const { _id: savedObjectId, _source: { @@ -136,7 +136,7 @@ async function fetchRollupVisualizations( let rollupVisualizations = 0; let rollupVisualizationsFromSavedSearches = 0; - visualizations.forEach((visualization) => { + visualizations.forEach((visualization: any) => { const { _source: { visualization: { @@ -151,7 +151,7 @@ async function fetchRollupVisualizations( if (savedSearchRefName) { // This visualization depends upon a saved search. - const savedSearch = references.find((ref) => ref.name === savedSearchRefName); + const savedSearch = references.find((ref: any) => ref.name === savedSearchRefName); if (rollupSavedSearchesToFlagMap[savedSearch.id]) { rollupVisualizations++; rollupVisualizationsFromSavedSearches++; diff --git a/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_strategy.ts b/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_strategy.ts index 815fe163411b3..885836780f1a9 100644 --- a/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_strategy.ts +++ b/x-pack/plugins/rollup/server/lib/search_strategies/rollup_search_strategy.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { indexBy, isString } from 'lodash'; +import { keyBy, isString } from 'lodash'; import { KibanaRequest } from 'src/core/server'; import { CallWithRequestFactoryShim } from '../../types'; @@ -74,7 +74,7 @@ export const getRollupSearchStrategy = ( }: { fieldsCapabilities: { [key: string]: any }; rollupIndex: string } ) { const fields = await super.getFieldsForWildcard(req, indexPattern); - const fieldsFromFieldCapsApi = indexBy(fields, 'name'); + const fieldsFromFieldCapsApi = keyBy(fields, 'name'); const rollupIndexCapabilities = fieldsCapabilities[rollupIndex].aggs; return mergeCapabilitiesWithFields(rollupIndexCapabilities, fieldsFromFieldCapsApi); diff --git a/x-pack/plugins/rollup/server/routes/api/index_patterns/register_fields_for_wildcard_route.ts b/x-pack/plugins/rollup/server/routes/api/index_patterns/register_fields_for_wildcard_route.ts index 546d9d628277f..250947d72c5fa 100644 --- a/x-pack/plugins/rollup/server/routes/api/index_patterns/register_fields_for_wildcard_route.ts +++ b/x-pack/plugins/rollup/server/routes/api/index_patterns/register_fields_for_wildcard_route.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { indexBy } from 'lodash'; +import { keyBy } from 'lodash'; import { schema } from '@kbn/config-schema'; import { Field } from '../../../lib/merge_capabilities_with_fields'; import { RouteDependencies } from '../../../types'; @@ -111,7 +111,7 @@ export const registerFieldsForWildcardRoute = ({ const parsedParams = JSON.parse(params); const rollupIndex = parsedParams.rollup_index; const rollupFields: Field[] = []; - const fieldsFromFieldCapsApi: { [key: string]: any } = indexBy(fields, 'name'); + const fieldsFromFieldCapsApi: { [key: string]: any } = keyBy(fields, 'name'); const rollupIndexCapabilities = getCapabilitiesForRollupIndices( await context.rollup!.client.callAsCurrentUser('rollup.rollupIndexCapabilities', { indexPattern: rollupIndex, diff --git a/x-pack/plugins/searchprofiler/public/application/components/profile_tree/init_data.ts b/x-pack/plugins/searchprofiler/public/application/components/profile_tree/init_data.ts index f5daa6b38de48..e4dded600dcf2 100644 --- a/x-pack/plugins/searchprofiler/public/application/components/profile_tree/init_data.ts +++ b/x-pack/plugins/searchprofiler/public/application/components/profile_tree/init_data.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import cloneDeep from 'lodash.clonedeep'; +import { cloneDeep } from 'lodash'; import { flow } from 'fp-ts/lib/function'; import { Targets, Shard, ShardSerialized } from '../../types'; import { calcTimes, initTree, normalizeIndices, sortIndices } from './unsafe_utils'; @@ -108,7 +108,7 @@ export const normalize = (target: Targets) => (data: IndexMap) => { export const initDataFor = (target: Targets) => flow( - cloneDeep, + cloneDeep as any, initShards, calculateShardValues(target), initIndices, diff --git a/x-pack/plugins/searchprofiler/public/application/components/profile_tree/unsafe_utils.ts b/x-pack/plugins/searchprofiler/public/application/components/profile_tree/unsafe_utils.ts index b023f1b365c06..0fb0522d449bd 100644 --- a/x-pack/plugins/searchprofiler/public/application/components/profile_tree/unsafe_utils.ts +++ b/x-pack/plugins/searchprofiler/public/application/components/profile_tree/unsafe_utils.ts @@ -122,10 +122,10 @@ export function normalizeIndices(indices: IndexMap, target: Targets) { let sortQueryComponents; if (target === 'searches') { sortQueryComponents = (a: Shard, b: Shard) => { - const aTime = _.sum(a.searches!, (search) => { + const aTime = _.sumBy(a.searches!, (search: any) => { return search.treeRoot!.time; }); - const bTime = _.sum(b.searches!, (search) => { + const bTime = _.sumBy(b.searches!, (search: any) => { return search.treeRoot!.time; }); @@ -133,10 +133,10 @@ export function normalizeIndices(indices: IndexMap, target: Targets) { }; } else if (target === 'aggregations') { sortQueryComponents = (a: Shard, b: Shard) => { - const aTime = _.sum(a.aggregations!, (agg) => { + const aTime = _.sumBy(a.aggregations!, (agg: any) => { return agg.treeRoot!.time; }); - const bTime = _.sum(b.aggregations!, (agg) => { + const bTime = _.sumBy(b.aggregations!, (agg: any) => { return agg.treeRoot!.time; }); diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/change_all_privileges.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/change_all_privileges.tsx index 10aa59083dff6..14375587c8497 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/change_all_privileges.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/change_all_privileges.tsx @@ -51,7 +51,7 @@ export class ChangeAllPrivilegesControl extends Component { }} disabled={this.props.disabled} > - {_.capitalize(privilege.id)} + {_.upperFirst(privilege.id)} ); }); @@ -65,7 +65,7 @@ export class ChangeAllPrivilegesControl extends Component { }} disabled={this.props.disabled} > - {_.capitalize(NO_PRIVILEGE_VALUE)} + {_.upperFirst(NO_PRIVILEGE_VALUE)} ); diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.tsx index 38e4390a2856a..a371a9ec9ba1e 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/feature_table/feature_table.tsx @@ -15,7 +15,6 @@ import { } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { i18n } from '@kbn/i18n'; -import _ from 'lodash'; import React, { Component } from 'react'; import { Role } from '../../../../../../../common/model'; import { ChangeAllPrivilegesControl } from './change_all_privileges'; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_display.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_display.tsx index 7b5d8d8c1ed27..204fb512abcff 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_display.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_display.tsx @@ -40,7 +40,7 @@ function getDisplayValue(privilege: string | string[] | undefined) { if (isPrivilegeMissing) { displayValue = ; } else { - displayValue = privileges.map((p) => _.capitalize(p)).join(', '); + displayValue = privileges.map((p) => _.upperFirst(p)).join(', '); } return displayValue; diff --git a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_space_table.tsx b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_space_table.tsx index 585c07c2e834f..64b7fe3e2e3a9 100644 --- a/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_space_table.tsx +++ b/x-pack/plugins/security/public/management/roles/edit_role/privileges/kibana/space_aware_privilege_section/privilege_space_table.tsx @@ -20,7 +20,6 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import _ from 'lodash'; import React, { Component } from 'react'; import { Space, getSpaceColor } from '../../../../../../../../spaces/public'; import { FeaturesPrivileges, Role, copyRole } from '../../../../../../../common/model'; diff --git a/x-pack/plugins/security/public/management/roles/model/kibana_privilege.ts b/x-pack/plugins/security/public/management/roles/model/kibana_privilege.ts index f5c85d3d92be2..cc9e74805040c 100644 --- a/x-pack/plugins/security/public/management/roles/model/kibana_privilege.ts +++ b/x-pack/plugins/security/public/management/roles/model/kibana_privilege.ts @@ -10,7 +10,7 @@ export class KibanaPrivilege { constructor(public readonly id: string, public readonly actions: string[] = []) {} public get name() { - return _.capitalize(this.id); + return _.upperFirst(this.id); } public grantsPrivilege(candidatePrivilege: KibanaPrivilege) { diff --git a/x-pack/plugins/security/public/management/users/components/change_password_form/change_password_form.tsx b/x-pack/plugins/security/public/management/users/components/change_password_form/change_password_form.tsx index 7a97794303558..296a8f6c8693f 100644 --- a/x-pack/plugins/security/public/management/users/components/change_password_form/change_password_form.tsx +++ b/x-pack/plugins/security/public/management/users/components/change_password_form/change_password_form.tsx @@ -12,6 +12,7 @@ import { EuiForm, EuiFormRow, } from '@elastic/eui'; +import _ from 'lodash'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import React, { ChangeEvent, Component } from 'react'; diff --git a/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.ts b/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.ts index 448b7b7e7ef48..8b5c119d59494 100644 --- a/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.ts +++ b/x-pack/plugins/security/server/authorization/register_privileges_with_cluster.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { isEqual, difference } from 'lodash'; +import { isEqual, isEqualWith, difference } from 'lodash'; import { ILegacyClusterClient, Logger } from '../../../../../src/core/server'; import { serializePrivileges } from './privileges_serializer'; @@ -22,7 +22,7 @@ export async function registerPrivilegesWithCluster( ) => { // when comparing privileges, the order of the actions doesn't matter, lodash's isEqual // doesn't know how to compare Sets - return isEqual(existingPrivileges, expectedPrivileges, (value, other, key) => { + return isEqualWith(existingPrivileges, expectedPrivileges, (value, other, key) => { if (key === 'actions' && Array.isArray(value) && Array.isArray(other)) { // Array.sort() is in-place, and we don't want to be modifying the actual order // of the arrays permanently, and there's potential they're frozen, so we're copying diff --git a/x-pack/plugins/security_solution/package.json b/x-pack/plugins/security_solution/package.json index 1ce5243bf7950..703ef6584f164 100644 --- a/x-pack/plugins/security_solution/package.json +++ b/x-pack/plugins/security_solution/package.json @@ -13,13 +13,11 @@ "test:generate": "ts-node --project scripts/endpoint/cli_tsconfig.json scripts/endpoint/resolver_generator.ts" }, "devDependencies": { - "@types/lodash": "^4.14.110", "@types/md5": "^2.2.0" }, "dependencies": { "@types/rbush": "^3.0.0", "@types/seedrandom": ">=2.0.0 <4.0.0", - "lodash": "^4.17.15", "querystring": "^0.2.0", "rbush": "^3.0.1", "redux-devtools-extension": "^2.13.8" diff --git a/x-pack/plugins/security_solution/scripts/extract_tactics_techniques_mitre.js b/x-pack/plugins/security_solution/scripts/extract_tactics_techniques_mitre.js index 344d0f0e5131a..5c31b3fad685a 100644 --- a/x-pack/plugins/security_solution/scripts/extract_tactics_techniques_mitre.js +++ b/x-pack/plugins/security_solution/scripts/extract_tactics_techniques_mitre.js @@ -9,6 +9,7 @@ require('../../../../src/setup_node_env'); const fs = require('fs'); // eslint-disable-next-line import/no-extraneous-dependencies const fetch = require('node-fetch'); +// eslint-disable-next-line import/no-extraneous-dependencies const { camelCase } = require('lodash'); const { resolve } = require('path'); diff --git a/x-pack/plugins/snapshot_restore/public/application/sections/home/restore_list/restore_table/restore_table.tsx b/x-pack/plugins/snapshot_restore/public/application/sections/home/restore_list/restore_table/restore_table.tsx index 739c72fe03a6f..3b18af7cebbf3 100644 --- a/x-pack/plugins/snapshot_restore/public/application/sections/home/restore_list/restore_table/restore_table.tsx +++ b/x-pack/plugins/snapshot_restore/public/application/sections/home/restore_list/restore_table/restore_table.tsx @@ -6,7 +6,7 @@ import React, { useState, useMemo } from 'react'; import { FormattedMessage } from '@kbn/i18n/react'; -import { sortByOrder } from 'lodash'; +import { orderBy } from 'lodash'; import { EuiBasicTable, EuiButtonIcon, EuiHealth } from '@elastic/eui'; import { RIGHT_ALIGNMENT } from '@elastic/eui/lib/services'; @@ -58,7 +58,7 @@ export const RestoreTable: React.FunctionComponent = React.memo(({ restor } = getSorting(); const { pageIndex, pageSize } = getPagination(); - const sortedRestores = sortByOrder(newRestoresList, [field], [direction]); + const sortedRestores = orderBy(newRestoresList, [field], [direction]); return sortedRestores.slice(pageIndex * pageSize, (pageIndex + 1) * pageSize); }; diff --git a/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.ts b/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.ts index 4c9f62503a21b..87c2fee4ea9bf 100644 --- a/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.ts +++ b/x-pack/plugins/spaces/server/routes/api/external/copy_to_space.ts @@ -18,7 +18,7 @@ import { createLicensedRouteHandler } from '../../lib'; type SavedObjectIdentifier = Pick; const areObjectsUnique = (objects: SavedObjectIdentifier[]) => - _.uniq(objects, (o: SavedObjectIdentifier) => `${o.type}:${o.id}`).length === objects.length; + _.uniqBy(objects, (o: SavedObjectIdentifier) => `${o.type}:${o.id}`).length === objects.length; export function initCopyToSpacesApi(deps: ExternalRouteDeps) { const { externalRouter, spacesService, getImportExportObjectLimit, getStartServices } = deps; diff --git a/x-pack/plugins/task_manager/server/lib/get_template_version.ts b/x-pack/plugins/task_manager/server/lib/get_template_version.ts index eac9d09685a42..07a9076359f0c 100644 --- a/x-pack/plugins/task_manager/server/lib/get_template_version.ts +++ b/x-pack/plugins/task_manager/server/lib/get_template_version.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { padLeft } from 'lodash'; +import { padStart } from 'lodash'; /* * The logic for ID is: XXYYZZAA, where XX is major version, YY is minor @@ -27,7 +27,7 @@ export function getTemplateVersion(versionStr: string): number { const padded = splitted.map((v: string) => { const vMatches = v.match(/\d+/); if (vMatches) { - return padLeft(vMatches[0], 2, '0'); + return padStart(vMatches[0], 2, '0'); } return '00'; }); @@ -39,13 +39,13 @@ export function getTemplateVersion(versionStr: string): number { const matches = minorStr.match(/alpha(?\d+)/); if (matches != null && matches.groups != null) { const alphaVerInt = parseInt(matches.groups.alpha, 10); // alpha build indicator - buildV = padLeft(`${alphaVerInt}`, 2, '0'); + buildV = padStart(`${alphaVerInt}`, 2, '0'); } } else if (minorStr.match('beta')) { const matches = minorStr.match(/beta(?\d+)/); if (matches != null && matches.groups != null) { const alphaVerInt = parseInt(matches.groups.beta, 10) + 25; // beta build indicator - buildV = padLeft(`${alphaVerInt}`, 2, '0'); + buildV = padStart(`${alphaVerInt}`, 2, '0'); } } else { buildV = '99'; // release build indicator diff --git a/x-pack/plugins/task_manager/server/task_pool.ts b/x-pack/plugins/task_manager/server/task_pool.ts index 17292adad3eb4..92374908c60f7 100644 --- a/x-pack/plugins/task_manager/server/task_pool.ts +++ b/x-pack/plugins/task_manager/server/task_pool.ts @@ -10,7 +10,7 @@ */ import moment, { Duration } from 'moment'; import { performance } from 'perf_hooks'; -import { padLeft } from 'lodash'; +import { padStart } from 'lodash'; import { Logger } from './types'; import { TaskRunner } from './task_runner'; import { isTaskSavedObjectNotFoundError } from './lib/is_task_not_found_error'; @@ -182,7 +182,7 @@ function partitionListByCount(list: T[], count: number): [T[], T[]] { function durationAsString(duration: Duration): string { const [m, s] = [duration.minutes(), duration.seconds()].map((value) => - padLeft(`${value}`, 2, '0') + padStart(`${value}`, 2, '0') ); return `${m}m ${s}s`; } diff --git a/x-pack/plugins/task_manager/server/task_runner.ts b/x-pack/plugins/task_manager/server/task_runner.ts index 7a9fa0c45e15f..4c690a5675f61 100644 --- a/x-pack/plugins/task_manager/server/task_runner.ts +++ b/x-pack/plugins/task_manager/server/task_runner.ts @@ -359,7 +359,7 @@ export class TaskManagerRunner implements TaskRunner { await this.bufferedTaskStore.update( defaults( { - ...fieldUpdates, + ...(fieldUpdates as Partial), // reset fields that track the lifecycle of the concluded `task run` startedAt: null, retryAt: null, diff --git a/x-pack/plugins/task_manager/server/task_store.test.ts b/x-pack/plugins/task_manager/server/task_store.test.ts index fec72c317225b..771b4e2d7d9cb 100644 --- a/x-pack/plugins/task_manager/server/task_store.test.ts +++ b/x-pack/plugins/task_manager/server/task_store.test.ts @@ -853,7 +853,7 @@ if (doc['task.runAt'].size()!=0) { type, attributes: { ..._.omit(task, 'id'), - ..._.mapValues(_.pick(task, 'params', 'state'), (value) => JSON.stringify(value)), + ..._.mapValues(_.pick(task, ['params', 'state']), (value) => JSON.stringify(value)), }, references: [], version: '123', @@ -904,7 +904,7 @@ if (doc['task.runAt'].size()!=0) { type, attributes: { ..._.omit(task, 'id'), - ..._.mapValues(_.pick(task, 'params', 'state'), (value) => JSON.stringify(value)), + ..._.mapValues(_.pick(task, ['params', 'state']), (value) => JSON.stringify(value)), }, references: [], version: '123', diff --git a/x-pack/plugins/task_manager/server/task_store.ts b/x-pack/plugins/task_manager/server/task_store.ts index c63f4ac72ed20..4a691e17011e8 100644 --- a/x-pack/plugins/task_manager/server/task_store.ts +++ b/x-pack/plugins/task_manager/server/task_store.ts @@ -429,7 +429,7 @@ function taskInstanceToAttributes(doc: TaskInstance): SerializedConcreteTaskInst retryAt: (doc.retryAt && doc.retryAt.toISOString()) || null, runAt: (doc.runAt || new Date()).toISOString(), status: (doc as ConcreteTaskInstance).status || 'idle', - }; + } as SerializedConcreteTaskInstance; } export function savedObjectToConcreteTaskInstance( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.tsx b/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.tsx index 463d170df2296..838b684cc10e8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.tsx @@ -5,7 +5,7 @@ */ import React from 'react'; -import { capitalize } from 'lodash'; +import { upperFirst } from 'lodash'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; import { EuiCard, EuiLink } from '@elastic/eui'; @@ -30,7 +30,7 @@ const getLicenseCheckResult = (actionType: ActionType) => { { defaultMessage: 'This connector requires a {minimumLicenseRequired} license.', values: { - minimumLicenseRequired: capitalize(actionType.minimumLicenseRequired), + minimumLicenseRequired: upperFirst(actionType.minimumLicenseRequired), }, } ), @@ -42,7 +42,7 @@ const getLicenseCheckResult = (actionType: ActionType) => { { defaultMessage: 'This feature requires a {minimumLicenseRequired} license.', values: { - minimumLicenseRequired: capitalize(actionType.minimumLicenseRequired), + minimumLicenseRequired: upperFirst(actionType.minimumLicenseRequired), }, } )} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx index 3a25417f7db4c..66a7ac25d4a70 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_details.tsx @@ -5,7 +5,7 @@ */ import React, { useState, Fragment } from 'react'; -import { indexBy } from 'lodash'; +import { keyBy } from 'lodash'; import { useHistory } from 'react-router-dom'; import { EuiPageBody, @@ -72,7 +72,7 @@ export const AlertDetails: React.FunctionComponent = ({ } = useAppDependencies(); const canSave = hasSaveAlertsCapability(capabilities); - const actionTypesByTypeId = indexBy(actionTypes, 'id'); + const actionTypesByTypeId = keyBy(actionTypes, 'id'); const hasEditButton = canSave && alertTypeRegistry.has(alert.alertTypeId) ? !alertTypeRegistry.get(alert.alertTypeId).requiresAppContext diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_instances.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_instances.tsx index 9deeeb96124c8..799886d264547 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_instances.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_details/components/alert_instances.tsx @@ -10,7 +10,7 @@ import { i18n } from '@kbn/i18n'; import { EuiBasicTable, EuiHealth, EuiSpacer, EuiSwitch } from '@elastic/eui'; // @ts-ignore import { RIGHT_ALIGNMENT, CENTER_ALIGNMENT } from '@elastic/eui/lib/services'; -import { padLeft, difference, chunk } from 'lodash'; +import { padStart, difference, chunk } from 'lodash'; import { Alert, AlertTaskState, RawAlertInstance, Pagination } from '../../../../types'; import { ComponentOpts as AlertApis, @@ -103,7 +103,7 @@ export const alertInstancesTableColumns = ( function durationAsString(duration: Duration): string { return [duration.hours(), duration.minutes(), duration.seconds()] - .map((value) => padLeft(`${value}`, 2, '0')) + .map((value) => padStart(`${value}`, 2, '0')) .join(':'); } diff --git a/x-pack/plugins/triggers_actions_ui/public/common/index_controls/index.ts b/x-pack/plugins/triggers_actions_ui/public/common/index_controls/index.ts index 0bec188f63640..da332aa326ccf 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/index_controls/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/common/index_controls/index.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { uniq } from 'lodash'; import { HttpSetup } from 'kibana/public'; import { i18n } from '@kbn/i18n'; import { @@ -47,7 +48,7 @@ export const getIndexOptions = async ( }) as string[]; if (matchingIndices.length || matchingIndexPatterns.length) { - const matchingOptions = _.uniq([...matchingIndices, ...matchingIndexPatterns]); + const matchingOptions = uniq([...matchingIndices, ...matchingIndexPatterns]); options.push({ label: i18n.translate( diff --git a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/constants.tsx b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/constants.tsx index aeb5801c9f6b5..b7eafb7bf5c88 100644 --- a/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/constants.tsx +++ b/x-pack/plugins/upgrade_assistant/public/application/components/tabs/checkup/constants.tsx @@ -14,7 +14,9 @@ export const LEVEL_MAP: { [level: string]: number } = { critical: 1, }; -export const REVERSE_LEVEL_MAP: { [idx: number]: DeprecationInfo['level'] } = invert(LEVEL_MAP); +export const REVERSE_LEVEL_MAP: { [idx: number]: DeprecationInfo['level'] } = invert( + LEVEL_MAP +) as any; export const COLOR_MAP: { [level: string]: IconColor } = { warning: 'default', diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_group.test.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_group.test.tsx index 25cf400bcd0fd..1c587568fe61d 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_group.test.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/__tests__/integration_group.test.tsx @@ -7,7 +7,7 @@ import React from 'react'; import { MonitorSummary } from '../../../../../../common/runtime_types'; import { shallowWithIntl } from 'test_utils/enzyme_helpers'; -import { IntegrationGroup } from '../actions_popover/integration_group'; +import { IntegrationGroup, extractSummaryValues } from '../actions_popover/integration_group'; describe('IntegrationGroup', () => { let summary: MonitorSummary; @@ -38,4 +38,97 @@ describe('IntegrationGroup', () => { const component = shallowWithIntl(); expect(component).toMatchSnapshot(); }); + + describe('extractSummaryValues', () => { + let mockSummary: Pick; + + beforeEach(() => { + mockSummary = { + state: { + timestamp: 'foo', + url: {}, + }, + }; + }); + + it('provides defaults when values are not present', () => { + expect(extractSummaryValues(mockSummary)).toMatchInlineSnapshot(` + Object { + "containerId": undefined, + "domain": "", + "ip": undefined, + "podUid": undefined, + } + `); + }); + + it('finds url domain', () => { + mockSummary.state.url.domain = 'mydomain'; + + expect(extractSummaryValues(mockSummary)).toMatchInlineSnapshot(` + Object { + "containerId": undefined, + "domain": "mydomain", + "ip": undefined, + "podUid": undefined, + } + `); + }); + + it('finds pod uid', () => { + mockSummary.state.checks = [ + { kubernetes: { pod: { uid: 'myuid' } }, monitor: { status: 'up' }, timestamp: 123 }, + ]; + + expect(extractSummaryValues(mockSummary)).toMatchInlineSnapshot(` + Object { + "containerId": undefined, + "domain": "", + "ip": undefined, + "podUid": "myuid", + } + `); + }); + + it('does not throw for missing kubernetes fields', () => { + mockSummary.state.checks = []; + + expect(extractSummaryValues(mockSummary)).toMatchInlineSnapshot(` + Object { + "containerId": undefined, + "domain": "", + "ip": undefined, + "podUid": undefined, + } + `); + }); + + it('finds container id', () => { + mockSummary.state.checks = [ + { container: { id: 'mycontainer' }, monitor: { status: 'up' }, timestamp: 123 }, + ]; + + expect(extractSummaryValues(mockSummary)).toMatchInlineSnapshot(` + Object { + "containerId": "mycontainer", + "domain": "", + "ip": undefined, + "podUid": undefined, + } + `); + }); + + it('finds ip field', () => { + mockSummary.state.checks = [{ monitor: { ip: '127.0.0.1', status: 'up' }, timestamp: 123 }]; + + expect(extractSummaryValues(mockSummary)).toMatchInlineSnapshot(` + Object { + "containerId": undefined, + "domain": "", + "ip": "127.0.0.1", + "podUid": undefined, + } + `); + }); + }); }); diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_group.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_group.tsx index bbcba7238748d..55a99ab8541f8 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_group.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/actions_popover/integration_group.tsx @@ -7,7 +7,6 @@ import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui'; import React, { useContext } from 'react'; import { i18n } from '@kbn/i18n'; -import { get } from 'lodash'; import { FormattedMessage } from '@kbn/i18n/react'; import { IntegrationLink } from './integration_link'; import { @@ -26,6 +25,20 @@ interface IntegrationGroupProps { summary: MonitorSummary; } +export const extractSummaryValues = (summary: Pick) => { + const domain = summary.state.url?.domain ?? ''; + const podUid = summary.state.checks?.[0]?.kubernetes?.pod.uid ?? undefined; + const containerId = summary.state.checks?.[0]?.container?.id ?? undefined; + const ip = summary.state.checks?.[0]?.monitor.ip ?? undefined; + + return { + domain, + podUid, + containerId, + ip, + }; +}; + export const IntegrationGroup = ({ summary }: IntegrationGroupProps) => { const { basePath, @@ -36,10 +49,7 @@ export const IntegrationGroup = ({ summary }: IntegrationGroupProps) => { isLogsAvailable, } = useContext(UptimeSettingsContext); - const domain = get(summary, 'state.url.domain', ''); - const podUid = get(summary, 'state.checks[0].kubernetes.pod.uid', undefined); - const containerId = get(summary, 'state.checks[0].container.id', undefined); - const ip = get(summary, 'state.checks[0].monitor.ip', undefined); + const { domain, podUid, containerId, ip } = extractSummaryValues(summary); return isApmAvailable || isInfraAvailable || isLogsAvailable ? ( @@ -97,7 +107,7 @@ export const IntegrationGroup = ({ summary }: IntegrationGroupProps) => { { defaultMessage: 'Check Infrastructure UI for the IP "{ip}"', values: { - ip, + ip: Array.isArray(ip) ? ip[0] : ip, }, } )} @@ -184,7 +194,12 @@ export const IntegrationGroup = ({ summary }: IntegrationGroupProps) => { )} tooltipContent={i18n.translate( 'xpack.uptime.monitorList.loggingIntegrationAction.ip.tooltip', - { defaultMessage: 'Check Logging UI for the IP "{ip}"', values: { ip } } + { + defaultMessage: 'Check Logging UI for the IP "{ip}"', + values: { + ip: Array.isArray(ip) ? ip[0] : ip, + }, + } )} /> diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_list.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_list.tsx index 12fff376a1a3c..26d0093446461 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_list.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_drawer/monitor_status_list.tsx @@ -5,7 +5,7 @@ */ import React from 'react'; -import { get, capitalize } from 'lodash'; +import { get, upperFirst } from 'lodash'; import { EuiCallOut, EuiSpacer } from '@elastic/eui'; import { FormattedMessage } from '@kbn/i18n/react'; import { LocationLink } from '../../../common/location_link'; @@ -26,12 +26,12 @@ export const MonitorStatusList = ({ checks }: MonitorStatusListProps) => { checks.forEach((check: Check) => { // Doing this way because name is either string or null, get() default value only works on undefined value - const location = get(check, 'observer.geo.name', null) || UNNAMED_LOCATION; + const location = get(check, 'observer.geo.name', null) || UNNAMED_LOCATION; if (check.monitor.status === STATUS.UP) { - upChecks.add(capitalize(location)); + upChecks.add(upperFirst(location)); } else if (check.monitor.status === STATUS.DOWN) { - downChecks.add(capitalize(location)); + downChecks.add(upperFirst(location)); } }); diff --git a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_status_column.tsx b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_status_column.tsx index a9d04e68b8929..f80c73dcf5bb0 100644 --- a/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_status_column.tsx +++ b/x-pack/plugins/uptime/public/components/overview/monitor_list/monitor_list_status_column.tsx @@ -7,7 +7,7 @@ import React from 'react'; import moment from 'moment'; import { i18n } from '@kbn/i18n'; -import { capitalize } from 'lodash'; +import { upperFirst } from 'lodash'; import styled from 'styled-components'; import { EuiHealth, EuiFlexGroup, EuiFlexItem, EuiText, EuiToolTip } from '@elastic/eui'; import { parseTimestamp } from './parse_timestamp'; @@ -83,9 +83,9 @@ export const getLocationStatus = (checks: Check[], status: string) => { const location = check?.observer?.geo?.name ?? UNNAMED_LOCATION; if (check.monitor.status === STATUS.UP) { - upChecks.add(capitalize(location)); + upChecks.add(upperFirst(location)); } else if (check.monitor.status === STATUS.DOWN) { - downChecks.add(capitalize(location)); + downChecks.add(upperFirst(location)); } }); diff --git a/x-pack/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx b/x-pack/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx index 3a940b4655b19..d6185f2c2589a 100644 --- a/x-pack/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx +++ b/x-pack/plugins/uptime/public/lib/adapters/framework/new_platform_adapter.tsx @@ -7,7 +7,6 @@ import { CoreStart } from 'src/core/public'; import React from 'react'; import ReactDOM from 'react-dom'; -import { get } from 'lodash'; import { i18n as i18nFormatter } from '@kbn/i18n'; import { UptimeApp, UptimeAppProps } from '../../../uptime_app'; import { getIntegratedAppAvailability } from './capabilities_adapter'; @@ -38,7 +37,7 @@ export const getKibanaFrameworkAdapter = ( INTEGRATED_SOLUTIONS ); - const canSave = get(capabilities, 'uptime.save', false); + const canSave = (capabilities.uptime.save ?? false) as boolean; const props: UptimeAppProps = { basePath: basePath.get(), diff --git a/x-pack/plugins/uptime/public/lib/helper/observability_integration/build_href.ts b/x-pack/plugins/uptime/public/lib/helper/observability_integration/build_href.ts index 414b37939b381..397d23a18332c 100644 --- a/x-pack/plugins/uptime/public/lib/helper/observability_integration/build_href.ts +++ b/x-pack/plugins/uptime/public/lib/helper/observability_integration/build_href.ts @@ -21,7 +21,7 @@ export const buildHref = ( getHref: (value: string | string[] | undefined) => string | undefined ): string | undefined => { const queryValue = checks - .map((check) => get(check, path, undefined)) + .map((check) => get(check, path, undefined)) .filter((value: string | undefined) => value !== undefined); if (queryValue.length === 0) { return getHref(undefined); diff --git a/x-pack/plugins/uptime/server/lib/requests/search/__tests__/enrich_monitor_groups.test.ts b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/enrich_monitor_groups.test.ts new file mode 100644 index 0000000000000..dd7996b68c41f --- /dev/null +++ b/x-pack/plugins/uptime/server/lib/requests/search/__tests__/enrich_monitor_groups.test.ts @@ -0,0 +1,98 @@ +/* + * 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 { sortChecksBy } from '../enrich_monitor_groups'; + +describe('enrich monitor groups', () => { + describe('sortChecksBy', () => { + it('identifies lesser geo name', () => { + expect( + sortChecksBy( + { observer: { geo: { name: 'less' } }, monitor: { status: 'up' } }, + { observer: { geo: { name: 'more' } }, monitor: { status: 'up' } } + ) + ).toBe(-1); + }); + + it('identifies greater geo name', () => { + expect( + sortChecksBy( + { observer: { geo: { name: 'more' } }, monitor: { status: 'up' } }, + { observer: { geo: { name: 'less' } }, monitor: { status: 'up' } } + ) + ).toBe(1); + }); + + it('identifies equivalent geo name and sorts by lesser ip', () => { + expect( + sortChecksBy( + { observer: { geo: { name: 'same' } }, monitor: { ip: '127.0.0.1', status: 'up' } }, + { observer: { geo: { name: 'same' } }, monitor: { ip: '127.0.0.2', status: 'up' } } + ) + ).toBe(-1); + }); + + it('identifies equivalent geo name and sorts by greater ip', () => { + expect( + sortChecksBy( + { observer: { geo: { name: 'same' } }, monitor: { ip: '127.0.0.2', status: 'up' } }, + { observer: { geo: { name: 'same' } }, monitor: { ip: '127.0.0.1', status: 'up' } } + ) + ).toBe(1); + }); + + it('identifies equivalent geo name and sorts by equivalent ip', () => { + expect( + sortChecksBy( + { observer: { geo: { name: 'same' } }, monitor: { ip: '127.0.0.1', status: 'up' } }, + { observer: { geo: { name: 'same' } }, monitor: { ip: '127.0.0.1', status: 'up' } } + ) + ).toBe(0); + }); + + it('handles equivalent ip arrays', () => { + expect( + sortChecksBy( + { observer: { geo: { name: 'same' } }, monitor: { ip: ['127.0.0.1'], status: 'up' } }, + { observer: { geo: { name: 'same' } }, monitor: { ip: ['127.0.0.1'], status: 'up' } } + ) + ).toBe(0); + }); + + it('handles non-equal ip arrays', () => { + expect( + sortChecksBy( + { + observer: { geo: { name: 'same' } }, + monitor: { ip: ['127.0.0.2', '127.0.0.9'], status: 'up' }, + }, + { + observer: { geo: { name: 'same' } }, + monitor: { ip: ['127.0.0.3', '127.0.0.1'], status: 'up' }, + } + ) + ).toBe(1); + }); + + it('handles undefined observer fields', () => { + expect( + sortChecksBy( + { observer: undefined, monitor: { ip: ['127.0.0.1'], status: 'up' } }, + { observer: { geo: { name: 'same' } }, monitor: { ip: ['127.0.0.1'], status: 'up' } } + ) + ).toBe(-1); + }); + + it('handles undefined ip fields', () => { + expect( + sortChecksBy( + { observer: { geo: { name: 'same' } }, monitor: { ip: undefined, status: 'up' } }, + { observer: { geo: { name: 'same' } }, monitor: { ip: ['127.0.0.1'], status: 'up' } } + ) + ).toBe(-1); + }); + }); +}); diff --git a/x-pack/plugins/uptime/server/lib/requests/search/enrich_monitor_groups.ts b/x-pack/plugins/uptime/server/lib/requests/search/enrich_monitor_groups.ts index 6e52b3a11f25f..f5c4c55a4e300 100644 --- a/x-pack/plugins/uptime/server/lib/requests/search/enrich_monitor_groups.ts +++ b/x-pack/plugins/uptime/server/lib/requests/search/enrich_monitor_groups.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import { get, sortBy } from 'lodash'; import { QueryContext } from './query_context'; import { Check, @@ -245,17 +244,17 @@ export const enrichMonitorGroups: MonitorEnricher = async ( const items = await queryContext.search(params); - const monitorBuckets = get(items, 'aggregations.monitors.buckets', []); + const monitorBuckets = items?.aggregations?.monitors?.buckets ?? []; const monitorIds: string[] = []; const summaries: MonitorSummary[] = monitorBuckets.map((monitor: any) => { - const monitorId = get(monitor, 'key.monitor_id'); + const monitorId = monitor.key.monitor_id; monitorIds.push(monitorId); const state: any = monitor.state?.value; state.timestamp = state['@timestamp']; const { checks } = state; - if (checks) { - state.checks = sortBy(checks, checksSortBy); + if (Array.isArray(checks)) { + checks.sort(sortChecksBy); state.checks = state.checks.map((check: any) => ({ ...check, timestamp: check['@timestamp'], @@ -276,7 +275,11 @@ export const enrichMonitorGroups: MonitorEnricher = async ( histogram: histogramMap[summary.monitor_id], })); - const sortedResItems: any = sortBy(resItems, 'monitor_id'); + const sortedResItems: any = resItems.sort((a, b) => { + if (a.monitor_id === b.monitor_id) return 0; + return a.monitor_id > b.monitor_id ? 1 : -1; + }); + if (queryContext.pagination.sortOrder === SortOrder.DESC) { sortedResItems.reverse(); } @@ -378,8 +381,29 @@ const cursorDirectionToOrder = (cd: CursorDirection): 'asc' | 'desc' => { return CursorDirection[cd] === CursorDirection.AFTER ? 'asc' : 'desc'; }; -type SortChecks = (check: Check) => string[]; -const checksSortBy = (check: Check) => [ - get(check, 'observer.geo.name'), - get(check, 'monitor.ip'), -]; +const getStringValue = (value: string | Array | null | undefined): string => { + if (Array.isArray(value)) { + value.sort(); + return value[0] ?? ''; + } + return value ?? ''; +}; + +export const sortChecksBy = ( + a: Pick, + b: Pick +) => { + const nameA: string = a.observer?.geo?.name ?? ''; + const nameB: string = b.observer?.geo?.name ?? ''; + + if (nameA === nameB) { + const ipA = getStringValue(a.monitor.ip); + const ipB = getStringValue(b.monitor.ip); + + if (ipA === ipB) { + return 0; + } + return ipA > ipB ? 1 : -1; + } + return nameA > nameB ? 1 : -1; +}; diff --git a/x-pack/plugins/watcher/public/application/sections/watch_edit/components/threshold_watch_edit/threshold_watch_edit.tsx b/x-pack/plugins/watcher/public/application/sections/watch_edit/components/threshold_watch_edit/threshold_watch_edit.tsx index b82f631a30fe7..01702a033d585 100644 --- a/x-pack/plugins/watcher/public/application/sections/watch_edit/components/threshold_watch_edit/threshold_watch_edit.tsx +++ b/x-pack/plugins/watcher/public/application/sections/watch_edit/components/threshold_watch_edit/threshold_watch_edit.tsx @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import _ from 'lodash'; import React, { Fragment, useContext, useEffect, useState } from 'react'; import { EuiButton, diff --git a/x-pack/plugins/watcher/server/models/execute_details/execute_details.js b/x-pack/plugins/watcher/server/models/execute_details/execute_details.js index 9dc162e06fba0..189da025e7142 100644 --- a/x-pack/plugins/watcher/server/models/execute_details/execute_details.js +++ b/x-pack/plugins/watcher/server/models/execute_details/execute_details.js @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { omit, isUndefined } from 'lodash'; +import { omitBy, isUndefined } from 'lodash'; export class ExecuteDetails { constructor(props) { @@ -22,14 +22,14 @@ export class ExecuteDetails { }; const result = { - trigger_data: omit(triggerData, isUndefined), + trigger_data: omitBy(triggerData, isUndefined), ignore_condition: this.ignoreCondition, alternative_input: this.alternativeInput, action_modes: this.actionModes, record_execution: this.recordExecution, }; - return omit(result, isUndefined); + return omitBy(result, isUndefined); } // generate ExecuteDetails object from kibana response diff --git a/x-pack/plugins/watcher/server/models/watch/lib/get_watch_type/get_watch_type.js b/x-pack/plugins/watcher/server/models/watch/lib/get_watch_type/get_watch_type.js index 2bdd03e23c6dc..90cb65a77e9ae 100644 --- a/x-pack/plugins/watcher/server/models/watch/lib/get_watch_type/get_watch_type.js +++ b/x-pack/plugins/watcher/server/models/watch/lib/get_watch_type/get_watch_type.js @@ -4,12 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { get, contains, values } from 'lodash'; +import { get, includes, values } from 'lodash'; import { WATCH_TYPES } from '../../../../../common/constants'; export function getWatchType(watchJson) { const type = get(watchJson, 'metadata.xpack.type'); - if (contains(values(WATCH_TYPES), type)) { + if (includes(values(WATCH_TYPES), type)) { return type; } diff --git a/x-pack/test/api_integration/apis/metrics_ui/metrics.ts b/x-pack/test/api_integration/apis/metrics_ui/metrics.ts index 673ee3c3f8475..23b0a96ecd401 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/metrics.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/metrics.ts @@ -61,13 +61,13 @@ export default function ({ getService }: FtrProviderContext) { return; } expect(resp.metrics.length).to.equal(1); - const metric = first(resp.metrics); + const metric = first(resp.metrics) as any; expect(metric).to.have.property('id', 'hostCpuUsage'); expect(metric).to.have.property('series'); - const series = first(metric.series); + const series = first(metric.series) as any; expect(series).to.have.property('id', 'user'); expect(series).to.have.property('data'); - const datapoint = last(series.data); + const datapoint = last(series.data) as any; expect(datapoint).to.have.property('timestamp', 1547571720000); expect(datapoint).to.have.property('value', 0.0018333333333333333); }); diff --git a/x-pack/test/api_integration/apis/metrics_ui/metrics_explorer.ts b/x-pack/test/api_integration/apis/metrics_ui/metrics_explorer.ts index 554b17d505c5e..d372496d2d1d9 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/metrics_explorer.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/metrics_explorer.ts @@ -49,7 +49,7 @@ export default function ({ getService }: FtrProviderContext) { .expect(200); const body = decodeOrThrow(metricsExplorerResponseRT)(response.body); expect(body.series).length(1); - const firstSeries = first(body.series); + const firstSeries = first(body.series) as any; expect(firstSeries).to.have.property('id', 'Everything'); expect(firstSeries.columns).to.eql([ { name: 'timestamp', type: 'date' }, @@ -89,7 +89,7 @@ export default function ({ getService }: FtrProviderContext) { .expect(200); const body = decodeOrThrow(metricsExplorerResponseRT)(response.body); expect(body.series).length(1); - const firstSeries = first(body.series); + const firstSeries = first(body.series) as any; expect(firstSeries).to.have.property('id', 'Everything'); expect(firstSeries.columns).to.eql([ { name: 'timestamp', type: 'date' }, @@ -120,7 +120,7 @@ export default function ({ getService }: FtrProviderContext) { .expect(200); const body = decodeOrThrow(metricsExplorerResponseRT)(response.body); expect(body.series).length(1); - const firstSeries = first(body.series); + const firstSeries = first(body.series) as any; expect(firstSeries).to.have.property('id', 'Everything'); expect(firstSeries.columns).to.eql([]); expect(firstSeries.rows).to.have.length(0); @@ -151,7 +151,7 @@ export default function ({ getService }: FtrProviderContext) { .expect(200); const body = decodeOrThrow(metricsExplorerResponseRT)(response.body); expect(body.series).length(3); - const firstSeries = first(body.series); + const firstSeries = first(body.series) as any; expect(firstSeries).to.have.property('id', 'system.diskio'); expect(firstSeries.columns).to.eql([ { name: 'timestamp', type: 'date' }, @@ -196,7 +196,7 @@ export default function ({ getService }: FtrProviderContext) { .expect(200); const body = decodeOrThrow(metricsExplorerResponseRT)(response.body); expect(body.series).length(3); - const firstSeries = first(body.series); + const firstSeries = first(body.series) as any; expect(firstSeries).to.have.property('id', 'demo-stack-mysql-01 / eth0'); expect(firstSeries.columns).to.eql([ { name: 'timestamp', type: 'date' }, diff --git a/x-pack/test/api_integration/apis/metrics_ui/snapshot.ts b/x-pack/test/api_integration/apis/metrics_ui/snapshot.ts index 1f4da602b108a..bb0934b73a4c7 100644 --- a/x-pack/test/api_integration/apis/metrics_ui/snapshot.ts +++ b/x-pack/test/api_integration/apis/metrics_ui/snapshot.ts @@ -60,7 +60,7 @@ export default function ({ getService }: FtrProviderContext) { if (snapshot) { const { nodes } = snapshot; expect(nodes.length).to.equal(5); - const firstNode = first(nodes); + const firstNode = first(nodes) as any; expect(firstNode).to.have.property('path'); expect(firstNode.path.length).to.equal(1); expect(first(firstNode.path)).to.have.property( @@ -105,7 +105,7 @@ export default function ({ getService }: FtrProviderContext) { if (snapshot) { const { nodes } = snapshot; expect(nodes.length).to.equal(65); - const firstNode = first(nodes); + const firstNode = first(nodes) as any; expect(firstNode).to.have.property('path'); expect(firstNode.path.length).to.equal(1); expect(first(firstNode.path)).to.have.property( @@ -137,7 +137,7 @@ export default function ({ getService }: FtrProviderContext) { if (snapshot) { const { nodes } = snapshot; expect(nodes.length).to.equal(136); - const firstNode = first(nodes); + const firstNode = first(nodes) as any; expect(firstNode).to.have.property('path'); expect(firstNode.path.length).to.equal(1); expect(first(firstNode.path)).to.have.property( @@ -176,7 +176,7 @@ export default function ({ getService }: FtrProviderContext) { if (snapshot) { const { nodes } = snapshot; expect(nodes.length).to.equal(1); - const firstNode = first(nodes); + const firstNode = first(nodes) as any; expect(firstNode).to.have.property('path'); expect(firstNode.path.length).to.equal(1); expect(first(firstNode.path)).to.have.property('value', 'demo-stack-mysql-01'); @@ -187,7 +187,7 @@ export default function ({ getService }: FtrProviderContext) { name: 'cpu', value: 0.0032, max: 0.0038333333333333336, - avg: 0.0027944444444444444, + avg: 0.002794444444444445, }, ]); } @@ -215,7 +215,7 @@ export default function ({ getService }: FtrProviderContext) { if (snapshot) { const { nodes } = snapshot; expect(nodes.length).to.equal(1); - const firstNode = first(nodes); + const firstNode = first(nodes) as any; expect(firstNode).to.have.property('path'); expect(firstNode.path.length).to.equal(1); expect(first(firstNode.path)).to.have.property('value', 'demo-stack-mysql-01'); @@ -250,7 +250,7 @@ export default function ({ getService }: FtrProviderContext) { if (snapshot) { const { nodes } = snapshot; expect(nodes.length).to.equal(1); - const firstNode = first(nodes); + const firstNode = first(nodes) as any; expect(firstNode).to.have.property('path'); expect(firstNode.path.length).to.equal(1); expect(first(firstNode.path)).to.have.property('value', 'demo-stack-mysql-01'); @@ -287,7 +287,7 @@ export default function ({ getService }: FtrProviderContext) { if (snapshot) { const { nodes } = snapshot; expect(nodes.length).to.equal(1); - const firstNode = first(nodes); + const firstNode = first(nodes) as any; expect(firstNode).to.have.property('path'); expect(firstNode.path.length).to.equal(1); expect(first(firstNode.path)).to.have.property('value', 'demo-stack-mysql-01'); @@ -322,7 +322,7 @@ export default function ({ getService }: FtrProviderContext) { if (snapshot) { const { nodes } = snapshot; expect(nodes.length).to.equal(1); - const firstNode = first(nodes); + const firstNode = first(nodes) as any; expect(firstNode).to.have.property('path'); expect(firstNode.path.length).to.equal(2); expect(first(firstNode.path)).to.have.property('value', 'virtualbox'); @@ -350,7 +350,7 @@ export default function ({ getService }: FtrProviderContext) { if (snapshot) { const { nodes } = snapshot; expect(nodes.length).to.equal(1); - const firstNode = first(nodes); + const firstNode = first(nodes) as any; expect(firstNode).to.have.property('path'); expect(firstNode.path.length).to.equal(3); expect(first(firstNode.path)).to.have.property('value', 'vagrant'); @@ -378,7 +378,7 @@ export default function ({ getService }: FtrProviderContext) { if (snapshot) { const { nodes } = snapshot; expect(nodes.length).to.equal(2); - const firstNode = nodes[0]; + const firstNode = nodes[0] as any; expect(firstNode).to.have.property('path'); expect(firstNode.path.length).to.equal(2); expect(firstNode.path[0]).to.have.property('value', 'mysql'); @@ -389,10 +389,10 @@ export default function ({ getService }: FtrProviderContext) { name: 'cpu', value: 0.0032, max: 0.0038333333333333336, - avg: 0.0027944444444444444, + avg: 0.002794444444444445, }, ]); - const secondNode = nodes[1]; + const secondNode = nodes[1] as any; expect(secondNode).to.have.property('path'); expect(secondNode.path.length).to.equal(2); expect(secondNode.path[0]).to.have.property('value', 'system'); @@ -403,7 +403,7 @@ export default function ({ getService }: FtrProviderContext) { name: 'cpu', value: 0.0032, max: 0.0038333333333333336, - avg: 0.0027944444444444444, + avg: 0.002794444444444445, }, ]); } diff --git a/x-pack/test/api_integration/apis/security/privileges.ts b/x-pack/test/api_integration/apis/security/privileges.ts index de0abe2350eb5..78915f6580299 100644 --- a/x-pack/test/api_integration/apis/security/privileges.ts +++ b/x-pack/test/api_integration/apis/security/privileges.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import util from 'util'; -import { isEqual } from 'lodash'; +import { isEqual, isEqualWith } from 'lodash'; import expect from '@kbn/expect/expect.js'; import { RawKibanaPrivileges } from '../../../../plugins/security/common/model'; import { FtrProviderContext } from '../../ftr_provider_context'; @@ -53,7 +53,7 @@ export default function ({ getService }: FtrProviderContext) { // supertest uses assert.deepStrictEqual. // expect.js doesn't help us here. // and lodash's isEqual doesn't know how to compare Sets. - const success = isEqual(res.body, expected, (value, other, key) => { + const success = isEqualWith(res.body, expected, (value, other, key) => { if (Array.isArray(value) && Array.isArray(other)) { if (key === 'reserved') { // order does not matter for the reserved privilege set. diff --git a/x-pack/test/api_integration/apis/security/privileges_basic.ts b/x-pack/test/api_integration/apis/security/privileges_basic.ts index 00bfcdc119e47..d2bfdbe4dc967 100644 --- a/x-pack/test/api_integration/apis/security/privileges_basic.ts +++ b/x-pack/test/api_integration/apis/security/privileges_basic.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ import util from 'util'; -import { isEqual } from 'lodash'; +import { isEqual, isEqualWith } from 'lodash'; import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { @@ -51,7 +51,7 @@ export default function ({ getService }: FtrProviderContext) { // supertest uses assert.deepStrictEqual. // expect.js doesn't help us here. // and lodash's isEqual doesn't know how to compare Sets. - const success = isEqual(res.body, expected, (value, other, key) => { + const success = isEqualWith(res.body, expected, (value, other, key) => { if (Array.isArray(value) && Array.isArray(other)) { return isEqual(value.sort(), other.sort()); } diff --git a/x-pack/test/apm_api_integration/trial/tests/annotations.ts b/x-pack/test/apm_api_integration/trial/tests/annotations.ts index cd78f0ff7b88d..662879c495230 100644 --- a/x-pack/test/apm_api_integration/trial/tests/annotations.ts +++ b/x-pack/test/apm_api_integration/trial/tests/annotations.ts @@ -18,7 +18,7 @@ export default function annotationApiTests({ getService }: FtrProviderContext) { function expectContainsObj(source: JsonObject, expected: JsonObject) { expect(source).to.eql( - merge(cloneDeep(source), expected, (a, b) => { + merge(cloneDeep(source), expected, (a: any, b: any) => { if (isPlainObject(a) && isPlainObject(b)) { return undefined; } diff --git a/x-pack/test/functional/apps/lens/persistent_context.ts b/x-pack/test/functional/apps/lens/persistent_context.ts index b980116c581da..9146ec7334625 100644 --- a/x-pack/test/functional/apps/lens/persistent_context.ts +++ b/x-pack/test/functional/apps/lens/persistent_context.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; diff --git a/x-pack/test/functional/apps/lens/smokescreen.ts b/x-pack/test/functional/apps/lens/smokescreen.ts index b399c9e915e27..97cdd081705a4 100644 --- a/x-pack/test/functional/apps/lens/smokescreen.ts +++ b/x-pack/test/functional/apps/lens/smokescreen.ts @@ -4,7 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import _ from 'lodash'; import expect from '@kbn/expect'; import { FtrProviderContext } from '../../ftr_provider_context'; diff --git a/x-pack/test/functional/apps/security/doc_level_security_roles.js b/x-pack/test/functional/apps/security/doc_level_security_roles.js index c0a1ff34db96b..72f463be48fd5 100644 --- a/x-pack/test/functional/apps/security/doc_level_security_roles.js +++ b/x-pack/test/functional/apps/security/doc_level_security_roles.js @@ -5,7 +5,7 @@ */ import expect from '@kbn/expect'; -import { indexBy } from 'lodash'; +import { keyBy } from 'lodash'; export default function ({ getService, getPageObjects }) { const esArchiver = getService('esArchiver'); @@ -43,7 +43,7 @@ export default function ({ getService, getPageObjects }) { global: ['all'], }, }); - const roles = indexBy(await PageObjects.security.getElasticsearchRoles(), 'rolename'); + const roles = keyBy(await PageObjects.security.getElasticsearchRoles(), 'rolename'); log.debug('actualRoles = %j', roles); expect(roles).to.have.key('myroleEast'); expect(roles.myroleEast.reserved).to.be(false); @@ -61,7 +61,7 @@ export default function ({ getService, getPageObjects }) { save: true, roles: ['kibana_admin', 'myroleEast'], }); - const users = indexBy(await PageObjects.security.getElasticsearchUsers(), 'username'); + const users = keyBy(await PageObjects.security.getElasticsearchUsers(), 'username'); log.debug('actualUsers = %j', users); expect(users.userEast.roles).to.eql(['kibana_admin', 'myroleEast']); expect(users.userEast.reserved).to.be(false); diff --git a/x-pack/test/functional/apps/security/field_level_security.js b/x-pack/test/functional/apps/security/field_level_security.js index ec6b91219b7c4..7b22d72885c9d 100644 --- a/x-pack/test/functional/apps/security/field_level_security.js +++ b/x-pack/test/functional/apps/security/field_level_security.js @@ -5,7 +5,7 @@ */ import expect from '@kbn/expect'; -import { indexBy } from 'lodash'; +import { keyBy } from 'lodash'; export default function ({ getService, getPageObjects }) { const esArchiver = getService('esArchiver'); @@ -42,7 +42,7 @@ export default function ({ getService, getPageObjects }) { }); await PageObjects.common.sleep(1000); - const roles = indexBy(await PageObjects.security.getElasticsearchRoles(), 'rolename'); + const roles = keyBy(await PageObjects.security.getElasticsearchRoles(), 'rolename'); log.debug('actualRoles = %j', roles); expect(roles).to.have.key('a_viewssnrole'); expect(roles.a_viewssnrole.reserved).to.be(false); @@ -64,7 +64,7 @@ export default function ({ getService, getPageObjects }) { }, }); await PageObjects.common.sleep(1000); - const roles = indexBy(await PageObjects.security.getElasticsearchRoles(), 'rolename'); + const roles = keyBy(await PageObjects.security.getElasticsearchRoles(), 'rolename'); log.debug('actualRoles = %j', roles); expect(roles).to.have.key('a_view_no_ssn_role'); expect(roles.a_view_no_ssn_role.reserved).to.be(false); @@ -81,7 +81,7 @@ export default function ({ getService, getPageObjects }) { save: true, roles: ['kibana_admin', 'a_viewssnrole'], }); - const users = indexBy(await PageObjects.security.getElasticsearchUsers(), 'username'); + const users = keyBy(await PageObjects.security.getElasticsearchUsers(), 'username'); log.debug('actualUsers = %j', users); expect(users.customer1.roles).to.eql(['kibana_admin', 'a_viewssnrole']); }); @@ -97,7 +97,7 @@ export default function ({ getService, getPageObjects }) { save: true, roles: ['kibana_admin', 'a_view_no_ssn_role'], }); - const users = indexBy(await PageObjects.security.getElasticsearchUsers(), 'username'); + const users = keyBy(await PageObjects.security.getElasticsearchUsers(), 'username'); log.debug('actualUsers = %j', users); expect(users.customer2.roles).to.eql(['kibana_admin', 'a_view_no_ssn_role']); }); diff --git a/x-pack/test/functional/apps/security/rbac_phase1.js b/x-pack/test/functional/apps/security/rbac_phase1.js index e9c09d1af6ea6..b138859d01361 100644 --- a/x-pack/test/functional/apps/security/rbac_phase1.js +++ b/x-pack/test/functional/apps/security/rbac_phase1.js @@ -5,7 +5,7 @@ */ import expect from '@kbn/expect'; -import { indexBy } from 'lodash'; +import { keyBy } from 'lodash'; export default function ({ getService, getPageObjects }) { const PageObjects = getPageObjects([ 'security', @@ -70,7 +70,7 @@ export default function ({ getService, getPageObjects }) { roles: ['rbac_all'], }); log.debug('After Add user: , userObj.userName'); - const users = indexBy(await PageObjects.security.getElasticsearchUsers(), 'username'); + const users = keyBy(await PageObjects.security.getElasticsearchUsers(), 'username'); log.debug('actualUsers = %j', users); log.debug('roles: ', users.kibanauser.roles); expect(users.kibanauser.roles).to.eql(['rbac_all']); @@ -88,7 +88,7 @@ export default function ({ getService, getPageObjects }) { roles: ['rbac_read'], }); log.debug('After Add user: , userObj.userName'); - const users1 = indexBy(await PageObjects.security.getElasticsearchUsers(), 'username'); + const users1 = keyBy(await PageObjects.security.getElasticsearchUsers(), 'username'); const user = users1.kibanareadonly; log.debug('actualUsers = %j', users1); log.debug('roles: ', user.roles); diff --git a/x-pack/test/functional/apps/security/secure_roles_perm.js b/x-pack/test/functional/apps/security/secure_roles_perm.js index 94b4306819052..2054a7b0b0038 100644 --- a/x-pack/test/functional/apps/security/secure_roles_perm.js +++ b/x-pack/test/functional/apps/security/secure_roles_perm.js @@ -5,7 +5,7 @@ */ import expect from '@kbn/expect'; -import { indexBy } from 'lodash'; +import { keyBy } from 'lodash'; export default function ({ getService, getPageObjects }) { const PageObjects = getPageObjects([ 'security', @@ -64,7 +64,7 @@ export default function ({ getService, getPageObjects }) { roles: ['logstash_reader', 'kibana_admin'], }); log.debug('After Add user: , userObj.userName'); - const users = indexBy(await PageObjects.security.getElasticsearchUsers(), 'username'); + const users = keyBy(await PageObjects.security.getElasticsearchUsers(), 'username'); log.debug('actualUsers = %j', users); log.debug('roles: ', users.Rashmi.roles); expect(users.Rashmi.roles).to.eql(['logstash_reader', 'kibana_admin']); diff --git a/x-pack/test/functional/apps/security/user_email.js b/x-pack/test/functional/apps/security/user_email.js index b6e3a84d6f7c0..a2a2b705172d7 100644 --- a/x-pack/test/functional/apps/security/user_email.js +++ b/x-pack/test/functional/apps/security/user_email.js @@ -5,7 +5,7 @@ */ import expect from '@kbn/expect'; -import { indexBy } from 'lodash'; +import { keyBy } from 'lodash'; export default function ({ getService, getPageObjects }) { const PageObjects = getPageObjects(['security', 'settings', 'common', 'accountSetting']); const log = getService('log'); @@ -28,7 +28,7 @@ export default function ({ getService, getPageObjects }) { save: true, roles: ['kibana_admin', 'superuser'], }); - const users = indexBy(await PageObjects.security.getElasticsearchUsers(), 'username'); + const users = keyBy(await PageObjects.security.getElasticsearchUsers(), 'username'); log.debug('actualUsers = %j', users); expect(users.newuser.roles).to.eql(['kibana_admin', 'superuser']); expect(users.newuser.fullname).to.eql('newuserFirst newuserLast'); diff --git a/x-pack/test/functional/apps/security/users.js b/x-pack/test/functional/apps/security/users.js index 4c8c04c0356b0..4fd4384a93c59 100644 --- a/x-pack/test/functional/apps/security/users.js +++ b/x-pack/test/functional/apps/security/users.js @@ -5,7 +5,7 @@ */ import expect from '@kbn/expect'; -import { indexBy } from 'lodash'; +import { keyBy } from 'lodash'; export default function ({ getService, getPageObjects }) { const PageObjects = getPageObjects(['security', 'settings']); const config = getService('config'); @@ -19,7 +19,7 @@ export default function ({ getService, getPageObjects }) { }); it('should show the default elastic and kibana_system users', async function () { - const users = indexBy(await PageObjects.security.getElasticsearchUsers(), 'username'); + const users = keyBy(await PageObjects.security.getElasticsearchUsers(), 'username'); log.info('actualUsers = %j', users); log.info('config = %j', config.get('servers.elasticsearch.hostname')); if (config.get('servers.elasticsearch.hostname') === 'localhost') { @@ -50,7 +50,7 @@ export default function ({ getService, getPageObjects }) { save: true, roles: ['kibana_admin'], }); - const users = indexBy(await PageObjects.security.getElasticsearchUsers(), 'username'); + const users = keyBy(await PageObjects.security.getElasticsearchUsers(), 'username'); log.debug('actualUsers = %j', users); expect(users.Lee.roles).to.eql(['kibana_admin']); expect(users.Lee.fullname).to.eql('LeeFirst LeeLast'); @@ -66,7 +66,7 @@ export default function ({ getService, getPageObjects }) { save: true, roles: [], }); - const users = indexBy(await PageObjects.security.getElasticsearchUsers(), 'username'); + const users = keyBy(await PageObjects.security.getElasticsearchUsers(), 'username'); log.debug('actualUsers = %j', users); expect(users.OptionalUser.roles).to.eql(['']); expect(users.OptionalUser.fullname).to.eql(''); @@ -77,14 +77,14 @@ export default function ({ getService, getPageObjects }) { it('should delete user', async function () { const alertMsg = await PageObjects.security.deleteUser('Lee'); log.debug('alertMsg = %s', alertMsg); - const users = indexBy(await PageObjects.security.getElasticsearchUsers(), 'username'); + const users = keyBy(await PageObjects.security.getElasticsearchUsers(), 'username'); log.debug('actualUsers = %j', users); expect(users).to.not.have.key('Lee'); }); it('should show the default roles', async function () { await PageObjects.security.clickElasticsearchRoles(); - const roles = indexBy(await PageObjects.security.getElasticsearchRoles(), 'rolename'); + const roles = keyBy(await PageObjects.security.getElasticsearchRoles(), 'rolename'); log.debug('actualRoles = %j', roles); // This only contains the first page of alphabetically sorted results, so the assertions are only for the first handful of expected roles. expect(roles.apm_system.reserved).to.be(true); diff --git a/x-pack/test/functional/apps/watcher/watcher_test.js b/x-pack/test/functional/apps/watcher/watcher_test.js index 7a2eebc118ab3..1dd3fb6bbcc3d 100644 --- a/x-pack/test/functional/apps/watcher/watcher_test.js +++ b/x-pack/test/functional/apps/watcher/watcher_test.js @@ -5,7 +5,7 @@ */ import expect from '@kbn/expect'; -import { indexBy } from 'lodash'; +import { keyBy } from 'lodash'; const watchID = 'watchID'; const watchName = 'watch Name'; @@ -74,7 +74,7 @@ export default function ({ getService, getPageObjects }) { it('should delete the watch', async () => { // Navigate to the main list page await PageObjects.common.navigateToApp('watcher'); - const watchList = indexBy(await PageObjects.watcher.getWatches(), 'id'); + const watchList = keyBy(await PageObjects.watcher.getWatches(), 'id'); log.debug(watchList); expect(watchList.watchID.name).to.eql([watchName]); await PageObjects.watcher.deleteWatch(watchID); diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts index e22b098e6ee0c..d86d272c1da8c 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts @@ -375,7 +375,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { const { alertInstances } = await alerting.alerts.getAlertState(alert.id); - const dateOnAllInstancesFromApiResponse = mapValues>( + const dateOnAllInstancesFromApiResponse = mapValues( alertInstances, ({ meta: { diff --git a/x-pack/test/plugin_api_perf/plugins/task_manager_performance/package.json b/x-pack/test/plugin_api_perf/plugins/task_manager_performance/package.json index 35a420561731a..2b174a8cae076 100644 --- a/x-pack/test/plugin_api_perf/plugins/task_manager_performance/package.json +++ b/x-pack/test/plugin_api_perf/plugins/task_manager_performance/package.json @@ -11,7 +11,6 @@ "build": "rm -rf './target' && tsc" }, "dependencies": { - "lodash": "^4.17.15", "uuid": "3.3.2", "stats-lite": "2.2.0", "pretty-ms": "5.0.0" diff --git a/x-pack/test/plugin_api_perf/plugins/task_manager_performance/server/plugin.ts b/x-pack/test/plugin_api_perf/plugins/task_manager_performance/server/plugin.ts index 9fbe9f26944ca..ba6d7ced3c591 100644 --- a/x-pack/test/plugin_api_perf/plugins/task_manager_performance/server/plugin.ts +++ b/x-pack/test/plugin_api_perf/plugins/task_manager_performance/server/plugin.ts @@ -265,8 +265,8 @@ function avg(items: number[]) { return { mean: Math.round(stats.mean(items)), range: { - min: Math.round(isNumericArray(mode) ? _.min([...mode]) : mode), - max: Math.round(isNumericArray(mode) ? _.max([...mode]) : mode), + min: Math.round(isNumericArray(mode) ? (_.min([...mode]) as number) : (mode as number)), + max: Math.round(isNumericArray(mode) ? (_.max([...mode]) as number) : (mode as number)), }, }; } diff --git a/x-pack/typings/index.d.ts b/x-pack/typings/index.d.ts index 1bf1370ad467f..73efee0dab2eb 100644 --- a/x-pack/typings/index.d.ts +++ b/x-pack/typings/index.d.ts @@ -22,11 +22,6 @@ declare module '*.svg' { export default content; } -declare module 'lodash/internal/toPath' { - function toPath(value: string | string[]): string[]; - export = toPath; -} - type MethodKeysOf = { [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never; }[keyof T]; diff --git a/yarn.lock b/yarn.lock index ace6181797246..02f7e90ab7d24 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5325,35 +5325,21 @@ "@types/node" "*" "@types/webpack" "*" -"@types/lodash.clonedeep@^4.5.4": - version "4.5.4" - resolved "https://registry.yarnpkg.com/@types/lodash.clonedeep/-/lodash.clonedeep-4.5.4.tgz#2515c5f08bc95afebfb597711871b0497f5d7da7" - integrity sha512-+rCVPIZOJaub++wU/lmyp/SxiKlqXQaXI5LryzjuHBKFj51ApVt38Xxk9psLWNGMuR/obEQNTH0l/yDfG4ANNQ== - dependencies: - "@types/lodash" "*" +"@types/lodash@4.14.149", "@types/lodash@^4.14.155": + version "4.14.156" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.156.tgz#cbe30909c89a1feeb7c60803e785344ea0ec82d1" + integrity sha512-l2AgHXcKUwx2DsvP19wtRPqZ4NkONjmorOdq4sMcxIjqdIuuV/ULo2ftuv4NUpevwfW7Ju/UKLqo0ZXuEt/8lQ== -"@types/lodash.clonedeepwith@^4.5.3": - version "4.5.3" - resolved "https://registry.yarnpkg.com/@types/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.3.tgz#8057f074de743bdcff59fdbf26cd04c674a186cc" - integrity sha512-DNOO/Vec+yrzxxYwRXhVxTE4cOE1Xkf1xUzHhz3atoQ2URYKjvO5m9S7UxUcpn48rXkt9PxOT6cOyJCMIfjLNg== - dependencies: - "@types/lodash" "*" +"@types/lodash@^3.10.1": + version "3.10.3" + resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-3.10.3.tgz#aaddec6a3c93bf03b402db3acf5d4c77bce8bdff" + integrity sha512-b9zScBKmB/RJqETbxu3YRya61vJOik89/lR+NdxjZAFMDcMSjwX6IhQoP4terJkhsa9TE1C+l6XwxCkhhsaZXg== -"@types/lodash@*", "@types/lodash@^4.14.110", "@types/lodash@^4.14.116": +"@types/lodash@^4.14.116": version "4.14.150" resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.150.tgz#649fe44684c3f1fcb6164d943c5a61977e8cf0bd" integrity sha512-kMNLM5JBcasgYscD9x/Gvr6lTAv2NVgsKtet/hm93qMyf/D1pt+7jeEZklKJKxMVmXjxbRVQQGfqDSfipYCO6w== -"@types/lodash@4.14.149": - version "4.14.149" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-4.14.149.tgz#1342d63d948c6062838fbf961012f74d4e638440" - integrity sha512-ijGqzZt/b7BfzcK9vTrS6MFljQRPn5BFWOx8oE0GYxribu6uV+aA9zZuXI1zc/etK9E8nrgdoF2+LgUw7+9tJQ== - -"@types/lodash@^3.10.1": - version "3.10.2" - resolved "https://registry.yarnpkg.com/@types/lodash/-/lodash-3.10.2.tgz#c1fbda1562ef5603c8192fe1fe65b017849d5873" - integrity sha512-TmlYodTNhMzVzv3CK/9sXGzh31jWsRKHE3faczhVgYFCdXIRQRCOPD+0NDlR+SvJlCj914yP3q3aAupt53p2Ug== - "@types/log-symbols@^2.0.0": version "2.0.0" resolved "https://registry.yarnpkg.com/@types/log-symbols/-/log-symbols-2.0.0.tgz#7919e2ec3c8d13879bfdcab310dd7a3f7fc9466d" @@ -20672,16 +20658,6 @@ lodash.clone@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6" integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y= -lodash.clonedeep@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef" - integrity sha1-4j8/nE+Pvd6HJSnBBxhXoIblzO8= - -lodash.clonedeepwith@^4.5.0: - version "4.5.0" - resolved "https://registry.yarnpkg.com/lodash.clonedeepwith/-/lodash.clonedeepwith-4.5.0.tgz#6ee30573a03a1a60d670a62ef33c10cf1afdbdd4" - integrity sha1-buMFc6A6GmDWcKYu8zwQzxr9vdQ= - lodash.debounce@^4.0.8: version "4.0.8" resolved "https://registry.yarnpkg.com/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af" @@ -20792,26 +20768,16 @@ lodash.isstring@^4.0.1: resolved "https://registry.yarnpkg.com/lodash.isstring/-/lodash.isstring-4.0.1.tgz#d527dfb5456eca7cc9bb95d5daeaf88ba54a5451" integrity sha1-1SfftUVuynzJu5XV2ur4i6VKVFE= -lodash.kebabcase@^4.0.0, lodash.kebabcase@^4.1.1: +lodash.kebabcase@^4.0.0: version "4.1.1" resolved "https://registry.yarnpkg.com/lodash.kebabcase/-/lodash.kebabcase-4.1.1.tgz#8489b1cb0d29ff88195cceca448ff6d6cc295c36" integrity sha1-hImxyw0p/4gZXM7KRI/21swpXDY= -lodash.keyby@^4.6.0: - version "4.6.0" - resolved "https://registry.yarnpkg.com/lodash.keyby/-/lodash.keyby-4.6.0.tgz#7f6a1abda93fd24e22728a4d361ed8bcba5a4354" - integrity sha1-f2oavak/0k4icopNNh7YvLpaQ1Q= - lodash.map@^4.4.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.map/-/lodash.map-4.6.0.tgz#771ec7839e3473d9c4cde28b19394c3562f4f6d3" integrity sha1-dx7Hg540c9nEzeKLGTlMNWL09tM= -lodash.mean@^4.1.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/lodash.mean/-/lodash.mean-4.1.0.tgz#bb985349628c0b9d7fe0f5fcc0011a2ee2c0dd7a" - integrity sha1-u5hTSWKMC51/4PX8wAEaLuLA3Xo= - lodash.memoize@^4.1.2: version "4.1.2" resolved "https://registry.yarnpkg.com/lodash.memoize/-/lodash.memoize-4.1.2.tgz#bcc6c49a42a2840ed997f323eada5ecd182e0bfe" @@ -20872,11 +20838,6 @@ lodash.set@^4.3.2: resolved "https://registry.yarnpkg.com/lodash.set/-/lodash.set-4.3.2.tgz#d8757b1da807dde24816b0d6a84bea1a76230b23" integrity sha1-2HV7HagH3eJIFrDWqEvqGnYjCyM= -lodash.snakecase@^4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/lodash.snakecase/-/lodash.snakecase-4.1.1.tgz#39d714a35357147837aefd64b5dcbb16becd8f8d" - integrity sha1-OdcUo1NXFHg3rv1ktdy7Fr7Nj40= - lodash.some@^4.4.0, lodash.some@^4.6.0: version "4.6.0" resolved "https://registry.yarnpkg.com/lodash.some/-/lodash.some-4.6.0.tgz#1bb9f314ef6b8baded13b549169b2a945eb68e4d" @@ -20887,11 +20848,6 @@ lodash.sortby@^4.7.0: resolved "https://registry.yarnpkg.com/lodash.sortby/-/lodash.sortby-4.7.0.tgz#edd14c824e2cc9c1e0b0a1b42bb5210516a42438" integrity sha1-7dFMgk4sycHgsKG0K7UhBRakJDg= -lodash.startcase@^4.4.0: - version "4.4.0" - resolved "https://registry.yarnpkg.com/lodash.startcase/-/lodash.startcase-4.4.0.tgz#9436e34ed26093ed7ffae1936144350915d9add8" - integrity sha1-lDbjTtJgk+1/+uGTYUQ1CRXZrdg= - lodash.template@^4.4.0: version "4.5.0" resolved "https://registry.yarnpkg.com/lodash.template/-/lodash.template-4.5.0.tgz#f976195cf3f347d0d5f52483569fe8031ccce8ab" @@ -20912,11 +20868,6 @@ lodash.throttle@^4.1.1: resolved "https://registry.yarnpkg.com/lodash.throttle/-/lodash.throttle-4.1.1.tgz#c23e91b710242ac70c37f1e1cda9274cc39bf2f4" integrity sha1-wj6RtxAkKscMN/HhzaknTMOb8vQ= -lodash.topath@^4.5.2: - version "4.5.2" - resolved "https://registry.yarnpkg.com/lodash.topath/-/lodash.topath-4.5.2.tgz#3616351f3bba61994a0931989660bd03254fd009" - integrity sha1-NhY1Hzu6YZlKCTGYlmC9AyVP0Ak= - lodash.unescape@4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/lodash.unescape/-/lodash.unescape-4.0.1.tgz#bf2249886ce514cda112fae9218cdc065211fc9c" @@ -20932,11 +20883,6 @@ lodash.uniq@^4.5.0: resolved "https://registry.yarnpkg.com/lodash.uniq/-/lodash.uniq-4.5.0.tgz#d0225373aeb652adc1bc82e4945339a842754773" integrity sha1-0CJTc662Uq3BvILklFM5qEJ1R3M= -lodash.uniqby@^4.7.0: - version "4.7.0" - resolved "https://registry.yarnpkg.com/lodash.uniqby/-/lodash.uniqby-4.7.0.tgz#d99c07a669e9e6d24e1362dfe266c67616af1302" - integrity sha1-2ZwHpmnp5tJOE2Lf4mbGdhavEwI= - lodash@4.17.11, lodash@4.17.15, lodash@>4.17.4, lodash@^4, lodash@^4.0.0, lodash@^4.0.1, lodash@^4.10.0, lodash@^4.11.1, lodash@^4.14.0, lodash@^4.15.0, lodash@^4.17.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.2, lodash@^4.17.4, lodash@^4.2.0, lodash@^4.2.1, lodash@^4.3.0, lodash@^4.6.1, lodash@~4.17.10, lodash@~4.17.15, lodash@~4.17.5: version "4.17.15" resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"