diff --git a/.buildkite/pipelines/es_snapshots/verify.yml b/.buildkite/pipelines/es_snapshots/verify.yml index 9af2e938db49d..61212e1fcf0a8 100755 --- a/.buildkite/pipelines/es_snapshots/verify.yml +++ b/.buildkite/pipelines/es_snapshots/verify.yml @@ -91,13 +91,5 @@ steps: - wait: ~ continue_on_failure: true - - plugins: - - junit-annotate#v1.9.0: - artifacts: target/junit/**/*.xml - job-uuid-file-pattern: '-bk__(.*).xml' - - - wait: ~ - continue_on_failure: true - - command: .buildkite/scripts/lifecycle/post_build.sh label: Post-Build diff --git a/.buildkite/pipelines/hourly.yml b/.buildkite/pipelines/hourly.yml index 89541023be8e2..279c8cf96bfe3 100644 --- a/.buildkite/pipelines/hourly.yml +++ b/.buildkite/pipelines/hourly.yml @@ -159,13 +159,5 @@ steps: - wait: ~ continue_on_failure: true - - plugins: - - junit-annotate#v1.9.0: - artifacts: target/junit/**/*.xml - job-uuid-file-pattern: '-bk__(.*).xml' - - - wait: ~ - continue_on_failure: true - - command: .buildkite/scripts/lifecycle/post_build.sh label: Post-Build diff --git a/.buildkite/scripts/lifecycle/annotate_test_failures.js b/.buildkite/scripts/lifecycle/annotate_test_failures.js new file mode 100644 index 0000000000000..caf1e08c2bb4d --- /dev/null +++ b/.buildkite/scripts/lifecycle/annotate_test_failures.js @@ -0,0 +1,14 @@ +const { TestFailures } = require('kibana-buildkite-library'); + +(async () => { + try { + await TestFailures.annotateTestFailures(); + } catch (ex) { + console.error('Annotate test failures error', ex.message); + if (ex.response) { + console.error('HTTP Error Response Status', ex.response.status); + console.error('HTTP Error Response Body', ex.response.data); + } + process.exit(1); + } +})(); diff --git a/.buildkite/scripts/lifecycle/post_command.sh b/.buildkite/scripts/lifecycle/post_command.sh index 23f44a586e978..0f98035f9f828 100755 --- a/.buildkite/scripts/lifecycle/post_command.sh +++ b/.buildkite/scripts/lifecycle/post_command.sh @@ -23,4 +23,9 @@ if [[ "$IS_TEST_EXECUTION_STEP" == "true" ]]; then buildkite-agent artifact upload '.es/**/*.hprof' node scripts/report_failed_tests --build-url="${BUILDKITE_BUILD_URL}#${BUILDKITE_JOB_ID}" 'target/junit/**/*.xml' + + if [[ -d 'target/test_failures' ]]; then + buildkite-agent artifact upload 'target/test_failures/**/*' + node .buildkite/scripts/lifecycle/annotate_test_failures.js + fi fi diff --git a/dev_docs/contributing/standards.mdx b/dev_docs/contributing/standards.mdx new file mode 100644 index 0000000000000..3d41de8f229cc --- /dev/null +++ b/dev_docs/contributing/standards.mdx @@ -0,0 +1,74 @@ +--- +id: kibStandards +slug: /kibana-dev-docs/standards +title: Standards and guidelines +summary: Standards and guidelines we expect every Kibana developer to abide by +date: 2021-09-28 +tags: ['contributor', 'dev', 'github', 'getting started', 'onboarding', 'kibana'] +--- + +## Developer principles + +We expect all developers to read and abide by our overarching . + +## Style guide + +Please read and abide by our . The majority of these items are linted against but some are not. + +## RESTful HTTP APIs + +### Terminology + +**REST APIs** +Technically, REST does not specify a protocol, but for readability, we’ll be calling RESTful HTTP APIs as REST APIs for short for the remainder of the section. HTTP APIs that serve HTML, CSS and images are not REST APIs. + +**End user** +Anywhere we refer to “end user” in this section, we are referring to someone who is using the REST APIs. The distinction between Product breaking changes and plugin breaking changes can also be found in this [Make it Minor strawman proposal doc](https://docs.google.com/document/d/12R0w75dSNR-VDQLGl2vxFyEHhzxNT38iamYhven9uvw/edit). This can be a tricky distinction, as some folks may consider end user to only be folks that use the Kibana UI. + +### Privacy + +| Type | Description | Guarantees | +| -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- | +| Internal | An API with “internal” in the route. Specifically it should be `/internal/{pluginname}/{...}`. It should only be used by the plugin that created it. | None | +| Public | Any API that is not internal based on above definition | Based on | + +### Do not access directly from plugins + +Plugins should not attempt to directly access the REST APIs created by another plugin. The plugin author who registered the public REST API should provide access to it via functionality on the plugin lifecycle contract. Accessing functionality through a client side plugin contract provides more type-safety compared to calling the REST API directly. Never attempt to call a server-side REST API if you are already on the server-side. It will not work. This should also be avoided in any code provided within a common folder. + +### Path names + +All public API path names should start with `/api/`. +All internal APIs should start with `/internal/{pluginname}/{...}`. + +### Backward compatibility and breaking changes + +Every public API should have a release tag specified at the top of it’s documentation page. Release tags are not applicable to internal APIs, as we make no guarantees on those. + +#### Release tags + +| Type | Description | Documentation | Asciidoc Tag | +| Undocumented | Every public API should be documented, but if it isn’t, we make no guarantees about it. These need to be eliminated and should become internal or documented. | +| Experimental | A public API that may break or be removed at any time. | experimental[] | +| Beta | A public API that we make a best effort not to break or remove. However, there are no guarantees. | beta[] | +| Stable | No breaking changes outside of a Major\* | stable[] | +| Deprecated | Do not use, will be removed. | deprecated[] | + +\*This is likely to change with Make it Minor as we move towards a calendar based rolling deprecation and removal policy. + +#### What constitutes a breaking change? + +- A path change +- A request payload change that adds a new required variable, or changes an existing one (new optional parameters are not breaking). +- A response payload change that removes data or changes existing data (returning additional data is not breaking). +- Status code changes + +### Telemetry + +Every team should be collecting telemetry metrics on it’s public API usage. This will be important for knowing when it’s safe to make breaking changes. The Core team will be looking into ways to make this easier and an automatic part of registration (see [#112291](https://github.com/elastic/kibana/issues/112291)). + +### Documentation + +Every public API should be documented inside the [docs/api](https://github.com/elastic/kibana/tree/master/docs/api) folder in asciidoc (this content will eventually be migrated to mdx to support the new docs system). If a public REST API is undocumented, you should either document it, or make it internal. + +Every public API should have a release tag specified using the appropriate documentation release tag above. If you do this, the docs system will provide a pop up explaining the conditions. If an API is not marked, it should be considered experimental. diff --git a/docs/setup/install/deb.asciidoc b/docs/setup/install/deb.asciidoc index 1ec73e8c3c7f5..a229426185200 100644 --- a/docs/setup/install/deb.asciidoc +++ b/docs/setup/install/deb.asciidoc @@ -157,7 +157,6 @@ locations for a Debian-based system: | Configuration files including `kibana.yml` | /etc/kibana | <> - d| | data | The location of the data files written to disk by Kibana and its plugins diff --git a/package.json b/package.json index 3da4475e2cd01..28ed283aab2a5 100644 --- a/package.json +++ b/package.json @@ -771,6 +771,7 @@ "multimatch": "^4.0.0", "mutation-observer": "^1.0.3", "ncp": "^2.0.0", + "node-jq": "2.0.0", "node-sass": "^6.0.1", "null-loader": "^3.0.0", "nyc": "^15.0.1", diff --git a/packages/kbn-cli-dev-mode/src/get_server_watch_paths.test.ts b/packages/kbn-cli-dev-mode/src/get_server_watch_paths.test.ts index 2208c122bf250..9cb902882ffd7 100644 --- a/packages/kbn-cli-dev-mode/src/get_server_watch_paths.test.ts +++ b/packages/kbn-cli-dev-mode/src/get_server_watch_paths.test.ts @@ -38,7 +38,7 @@ it('produces the right watch and ignore list', () => { expect(ignorePaths).toMatchInlineSnapshot(` Array [ /\\[\\\\\\\\\\\\/\\]\\(\\\\\\.\\.\\*\\|node_modules\\|bower_components\\|target\\|public\\|__\\[a-z0-9_\\]\\+__\\|coverage\\)\\(\\[\\\\\\\\\\\\/\\]\\|\\$\\)/, - /\\\\\\.test\\\\\\.\\(js\\|tsx\\?\\)\\$/, + /\\\\\\.\\(test\\|spec\\)\\\\\\.\\(js\\|ts\\|tsx\\)\\$/, /\\\\\\.\\(md\\|sh\\|txt\\)\\$/, /debug\\\\\\.log\\$/, /src/plugins/*/test/**, diff --git a/packages/kbn-cli-dev-mode/src/get_server_watch_paths.ts b/packages/kbn-cli-dev-mode/src/get_server_watch_paths.ts index ce614d33c735c..53f52279c8be8 100644 --- a/packages/kbn-cli-dev-mode/src/get_server_watch_paths.ts +++ b/packages/kbn-cli-dev-mode/src/get_server_watch_paths.ts @@ -52,7 +52,7 @@ export function getServerWatchPaths({ pluginPaths, pluginScanDirs }: Options) { const ignorePaths = [ /[\\\/](\..*|node_modules|bower_components|target|public|__[a-z0-9_]+__|coverage)([\\\/]|$)/, - /\.test\.(js|tsx?)$/, + /\.(test|spec)\.(js|ts|tsx)$/, /\.(md|sh|txt)$/, /debug\.log$/, ...pluginInternalDirsIgnore, diff --git a/packages/kbn-dev-utils/src/vscode_config/managed_config_keys.ts b/packages/kbn-dev-utils/src/vscode_config/managed_config_keys.ts index 8b941e9e4f71f..07156ca9257fb 100644 --- a/packages/kbn-dev-utils/src/vscode_config/managed_config_keys.ts +++ b/packages/kbn-dev-utils/src/vscode_config/managed_config_keys.ts @@ -8,7 +8,7 @@ export interface ManagedConfigKey { key: string; - value: string | Record; + value: string | Record | boolean; } /** @@ -42,4 +42,8 @@ export const MANAGED_CONFIG_KEYS: ManagedConfigKey[] = [ // we use a relative path here so that it works with remote vscode connections value: './node_modules/typescript/lib', }, + { + key: 'typescript.enablePromptUseWorkspaceTsdk', + value: true, + }, ]; diff --git a/packages/kbn-dev-utils/src/vscode_config/update_vscode_config.ts b/packages/kbn-dev-utils/src/vscode_config/update_vscode_config.ts index 42a642ef1b6c4..b337c8baa5e32 100644 --- a/packages/kbn-dev-utils/src/vscode_config/update_vscode_config.ts +++ b/packages/kbn-dev-utils/src/vscode_config/update_vscode_config.ts @@ -69,10 +69,10 @@ const createObjectPropOfManagedValues = (key: string, value: Record const addManagedProp = ( ast: t.ObjectExpression, key: string, - value: string | Record + value: string | Record | boolean ) => { ast.properties.push( - typeof value === 'string' + typeof value === 'string' || typeof value === 'boolean' ? createManagedProp(key, value) : createObjectPropOfManagedValues(key, value) ); @@ -89,7 +89,7 @@ const addManagedProp = ( const replaceManagedProp = ( ast: t.ObjectExpression, existing: BasicObjectProp, - value: string | Record + value: string | Record | boolean ) => { remove(ast.properties, existing); addManagedProp(ast, existing.key.value, value); diff --git a/packages/kbn-logging/src/ecs/agent.ts b/packages/kbn-logging/src/ecs/agent.ts index 0c2e7f7bbe44f..fc01fc649d266 100644 --- a/packages/kbn-logging/src/ecs/agent.ts +++ b/packages/kbn-logging/src/ecs/agent.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-agent.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-agent.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/autonomous_system.ts b/packages/kbn-logging/src/ecs/autonomous_system.ts index 85569b7dbabe1..5e59cb84e198b 100644 --- a/packages/kbn-logging/src/ecs/autonomous_system.ts +++ b/packages/kbn-logging/src/ecs/autonomous_system.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-as.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-as.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/base.ts b/packages/kbn-logging/src/ecs/base.ts index cf12cf0ea6e53..95c67623869f5 100644 --- a/packages/kbn-logging/src/ecs/base.ts +++ b/packages/kbn-logging/src/ecs/base.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-base.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-base.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/client.ts b/packages/kbn-logging/src/ecs/client.ts index ebee7826104a5..ef4b227593e62 100644 --- a/packages/kbn-logging/src/ecs/client.ts +++ b/packages/kbn-logging/src/ecs/client.ts @@ -17,7 +17,7 @@ interface NestedFields { } /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-client.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-client.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/cloud.ts b/packages/kbn-logging/src/ecs/cloud.ts index 8ef15d40f5529..803fc63bef216 100644 --- a/packages/kbn-logging/src/ecs/cloud.ts +++ b/packages/kbn-logging/src/ecs/cloud.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-cloud.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-cloud.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/code_signature.ts b/packages/kbn-logging/src/ecs/code_signature.ts index 277c3901a4f8b..e2e5eaf5c89af 100644 --- a/packages/kbn-logging/src/ecs/code_signature.ts +++ b/packages/kbn-logging/src/ecs/code_signature.ts @@ -7,15 +7,17 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-code_signature.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-code_signature.html * * @internal */ export interface EcsCodeSignature { + digest_algorithm?: string; exists?: boolean; signing_id?: string; status?: string; subject_name?: string; + timestamp?: string; team_id?: string; trusted?: boolean; valid?: boolean; diff --git a/packages/kbn-logging/src/ecs/container.ts b/packages/kbn-logging/src/ecs/container.ts index 6c5c85e7107e3..746b5b917a745 100644 --- a/packages/kbn-logging/src/ecs/container.ts +++ b/packages/kbn-logging/src/ecs/container.ts @@ -7,14 +7,21 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-container.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-container.html * * @internal */ export interface EcsContainer { + cpu?: { usage?: number }; + disk?: Disk; id?: string; image?: { name?: string; tag?: string[] }; labels?: Record; name?: string; runtime?: string; } + +interface Disk { + read?: { bytes?: number }; + write?: { bytes?: number }; +} diff --git a/packages/kbn-logging/src/ecs/data_stream.ts b/packages/kbn-logging/src/ecs/data_stream.ts new file mode 100644 index 0000000000000..fae0a30f69cc4 --- /dev/null +++ b/packages/kbn-logging/src/ecs/data_stream.ts @@ -0,0 +1,18 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** + * https://www.elastic.co/guide/en/ecs/1.12/ecs-data_stream.html + * + * @internal + */ +export interface EcsDataStream { + dataset?: string; + namespace?: string; + type?: 'logs' | 'metrics'; +} diff --git a/packages/kbn-logging/src/ecs/destination.ts b/packages/kbn-logging/src/ecs/destination.ts index 6d2dbc8f431c9..00473da4a1e78 100644 --- a/packages/kbn-logging/src/ecs/destination.ts +++ b/packages/kbn-logging/src/ecs/destination.ts @@ -17,7 +17,7 @@ interface NestedFields { } /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-destination.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-destination.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/dll.ts b/packages/kbn-logging/src/ecs/dll.ts index d9ffa68b3f1a5..2983361f753e7 100644 --- a/packages/kbn-logging/src/ecs/dll.ts +++ b/packages/kbn-logging/src/ecs/dll.ts @@ -17,7 +17,7 @@ interface NestedFields { } /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-dll.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-dll.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/dns.ts b/packages/kbn-logging/src/ecs/dns.ts index c7a0e7983376c..c45f8f6b91fc5 100644 --- a/packages/kbn-logging/src/ecs/dns.ts +++ b/packages/kbn-logging/src/ecs/dns.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-dns.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-dns.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/elf.ts b/packages/kbn-logging/src/ecs/elf.ts new file mode 100644 index 0000000000000..a1cb2a85038e6 --- /dev/null +++ b/packages/kbn-logging/src/ecs/elf.ts @@ -0,0 +1,71 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** + * https://www.elastic.co/guide/en/ecs/1.12/ecs-elf.html + * + * @internal + */ +export interface EcsElf { + architecture?: string; + byte_order?: string; + cpu_type?: string; + creation_date?: string; + exports?: Export[]; + imports?: Import[]; + header?: Header; + sections?: Section[]; + segments?: Segment[]; + shared_libraries?: string[]; + telfhash?: string; +} + +interface Export { + binding?: string; + name?: string; + section?: string; + size?: string; + type?: string; + version?: string; + visibility?: string; +} + +interface Import { + library?: string; + name?: string; + type?: string; + version?: string; +} + +interface Header { + abi_version?: string; + class?: string; + data?: string; + entrypoint?: number; + object_version?: string; + os_abi?: string; + type?: string; + version?: string; +} + +interface Section { + chi2?: number; + entropy?: number; + flags?: string; + name?: string; + physical_offset?: string; + physical_size?: number; + type?: string; + virtual_address?: number; + virtual_size?: number; +} + +interface Segment { + sections?: string; + type?: string; +} diff --git a/packages/kbn-logging/src/ecs/email.ts b/packages/kbn-logging/src/ecs/email.ts new file mode 100644 index 0000000000000..fcc3295fd71b5 --- /dev/null +++ b/packages/kbn-logging/src/ecs/email.ts @@ -0,0 +1,48 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { EcsFile } from './file'; +import { EcsHash } from './hash'; + +interface NestedFields { + // Not all hash types are explicitly supported, see + // https://github.com/elastic/ecs/pull/1569 + hash?: Pick; +} + +interface AttachmentNestedFields { + file?: Pick; +} + +/** + * No docs yet, see https://github.com/elastic/ecs/pull/1569 + * + * @internal + */ +export interface EcsEmail extends NestedFields { + attachments?: Attachment[]; + bcc?: string[]; + cc?: string[]; + content_type?: string; + delivery_timestamp?: string; + direction?: string; + from?: string; + local_id?: string; + message_id?: string; + origination_timestamp?: string; + reply_to?: string; + subject?: string; + 'subject.text'?: string; + to?: string[]; + x_mailer?: string; +} + +// eslint-disable-next-line @typescript-eslint/no-empty-interface +interface Attachment extends AttachmentNestedFields { + // intentionally empty +} diff --git a/packages/kbn-logging/src/ecs/error.ts b/packages/kbn-logging/src/ecs/error.ts index aee010748ddf2..a48b03075d469 100644 --- a/packages/kbn-logging/src/ecs/error.ts +++ b/packages/kbn-logging/src/ecs/error.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-error.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-error.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/event.ts b/packages/kbn-logging/src/ecs/event.ts index bf711410a9dd7..2baf320de8db4 100644 --- a/packages/kbn-logging/src/ecs/event.ts +++ b/packages/kbn-logging/src/ecs/event.ts @@ -7,12 +7,13 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-event.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-event.html * * @internal */ export interface EcsEvent { action?: string; + agent_id_status?: 'verified' | 'mismatch' | 'missing' | 'auth_metadata_missing'; category?: EcsEventCategory[]; code?: string; created?: string; diff --git a/packages/kbn-logging/src/ecs/file.ts b/packages/kbn-logging/src/ecs/file.ts index c09121607e0a4..dbd1653e21190 100644 --- a/packages/kbn-logging/src/ecs/file.ts +++ b/packages/kbn-logging/src/ecs/file.ts @@ -7,19 +7,21 @@ */ import { EcsCodeSignature } from './code_signature'; +import { EcsElf } from './elf'; import { EcsHash } from './hash'; import { EcsPe } from './pe'; import { EcsX509 } from './x509'; interface NestedFields { code_signature?: EcsCodeSignature; + elf?: EcsElf; hash?: EcsHash; pe?: EcsPe; x509?: EcsX509; } /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-file.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-file.html * * @internal */ @@ -32,6 +34,7 @@ export interface EcsFile extends NestedFields { directory?: string; drive_letter?: string; extension?: string; + fork_name?: string; gid?: string; group?: string; inode?: string; diff --git a/packages/kbn-logging/src/ecs/geo.ts b/packages/kbn-logging/src/ecs/geo.ts index 85d45ca803aee..2373f4f119dfc 100644 --- a/packages/kbn-logging/src/ecs/geo.ts +++ b/packages/kbn-logging/src/ecs/geo.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-geo.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-geo.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/group.ts b/packages/kbn-logging/src/ecs/group.ts index e1bc339964fc0..c0d007d3bea0a 100644 --- a/packages/kbn-logging/src/ecs/group.ts +++ b/packages/kbn-logging/src/ecs/group.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-group.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-group.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/hash.ts b/packages/kbn-logging/src/ecs/hash.ts index 2ecd49f1ca092..fcf134349d7a4 100644 --- a/packages/kbn-logging/src/ecs/hash.ts +++ b/packages/kbn-logging/src/ecs/hash.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-hash.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-hash.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/host.ts b/packages/kbn-logging/src/ecs/host.ts index 085db30e13e7e..6c5046ef458e2 100644 --- a/packages/kbn-logging/src/ecs/host.ts +++ b/packages/kbn-logging/src/ecs/host.ts @@ -18,7 +18,7 @@ interface NestedFields { } /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-host.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-host.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/http.ts b/packages/kbn-logging/src/ecs/http.ts index c734c93318f5c..914e35c0f1fd7 100644 --- a/packages/kbn-logging/src/ecs/http.ts +++ b/packages/kbn-logging/src/ecs/http.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-http.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-http.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/index.ts b/packages/kbn-logging/src/ecs/index.ts index 30da3baa43b72..613945d22ad80 100644 --- a/packages/kbn-logging/src/ecs/index.ts +++ b/packages/kbn-logging/src/ecs/index.ts @@ -13,8 +13,10 @@ import { EcsAutonomousSystem } from './autonomous_system'; import { EcsClient } from './client'; import { EcsCloud } from './cloud'; import { EcsContainer } from './container'; +import { EcsDataStream } from './data_stream'; import { EcsDestination } from './destination'; import { EcsDns } from './dns'; +import { EcsEmail } from './email'; import { EcsError } from './error'; import { EcsEvent } from './event'; import { EcsFile } from './file'; @@ -24,6 +26,7 @@ import { EcsHttp } from './http'; import { EcsLog } from './log'; import { EcsNetwork } from './network'; import { EcsObserver } from './observer'; +import { EcsOrchestrator } from './orchestrator'; import { EcsOrganization } from './organization'; import { EcsPackage } from './package'; import { EcsProcess } from './process'; @@ -45,13 +48,13 @@ export { EcsEventCategory, EcsEventKind, EcsEventOutcome, EcsEventType } from '. interface EcsField { /** - * These typings were written as of ECS 1.9.0. + * These typings were written as of ECS 1.12.0. * Don't change this value without checking the rest * of the types to conform to that ECS version. * - * https://www.elastic.co/guide/en/ecs/1.9/index.html + * https://www.elastic.co/guide/en/ecs/1.12/index.html */ - version: '1.9.0'; + version: '1.12.0'; } /** @@ -68,8 +71,10 @@ export type Ecs = EcsBase & client?: EcsClient; cloud?: EcsCloud; container?: EcsContainer; + data_stream?: EcsDataStream; destination?: EcsDestination; dns?: EcsDns; + email?: EcsEmail; error?: EcsError; event?: EcsEvent; file?: EcsFile; @@ -79,6 +84,7 @@ export type Ecs = EcsBase & log?: EcsLog; network?: EcsNetwork; observer?: EcsObserver; + orchestrator?: EcsOrchestrator; organization?: EcsOrganization; package?: EcsPackage; process?: EcsProcess; diff --git a/packages/kbn-logging/src/ecs/interface.ts b/packages/kbn-logging/src/ecs/interface.ts index 49b33e8338184..80c00fe8d8a12 100644 --- a/packages/kbn-logging/src/ecs/interface.ts +++ b/packages/kbn-logging/src/ecs/interface.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-interface.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-interface.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/log.ts b/packages/kbn-logging/src/ecs/log.ts index 8bc2e4982e96c..e55915094e528 100644 --- a/packages/kbn-logging/src/ecs/log.ts +++ b/packages/kbn-logging/src/ecs/log.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-log.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-log.html * * @internal */ @@ -16,6 +16,7 @@ export interface EcsLog { level?: string; logger?: string; origin?: Origin; + /** @deprecated - use `event.original` instead */ original?: string; syslog?: Syslog; } diff --git a/packages/kbn-logging/src/ecs/network.ts b/packages/kbn-logging/src/ecs/network.ts index 912427b6cdb7e..6d00aa10a9968 100644 --- a/packages/kbn-logging/src/ecs/network.ts +++ b/packages/kbn-logging/src/ecs/network.ts @@ -14,7 +14,7 @@ interface NestedFields { } /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-network.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-network.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/observer.ts b/packages/kbn-logging/src/ecs/observer.ts index be2636d15dcdf..89e1cbb59880c 100644 --- a/packages/kbn-logging/src/ecs/observer.ts +++ b/packages/kbn-logging/src/ecs/observer.ts @@ -29,7 +29,7 @@ interface NestedIngressFields { } /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-observer.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-observer.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/orchestrator.ts b/packages/kbn-logging/src/ecs/orchestrator.ts new file mode 100644 index 0000000000000..ac92006091a93 --- /dev/null +++ b/packages/kbn-logging/src/ecs/orchestrator.ts @@ -0,0 +1,32 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +/** + * https://www.elastic.co/guide/en/ecs/1.12/ecs-orchestrator.html + * + * @internal + */ +export interface EcsOrchestrator { + api_version?: string; + cluster?: Cluster; + namespace?: string; + organization?: string; + resource?: Resource; + type?: string; +} + +interface Cluster { + name?: string; + url?: string; + version?: string; +} + +interface Resource { + name?: string; + type?: string; +} diff --git a/packages/kbn-logging/src/ecs/organization.ts b/packages/kbn-logging/src/ecs/organization.ts index 370e6b2646a2f..e9274f864b7d2 100644 --- a/packages/kbn-logging/src/ecs/organization.ts +++ b/packages/kbn-logging/src/ecs/organization.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-organization.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-organization.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/os.ts b/packages/kbn-logging/src/ecs/os.ts index 342eb14264fd3..76690bffaf69f 100644 --- a/packages/kbn-logging/src/ecs/os.ts +++ b/packages/kbn-logging/src/ecs/os.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-os.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-os.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/package.ts b/packages/kbn-logging/src/ecs/package.ts index 10528066f3f29..f0e75b3cd2753 100644 --- a/packages/kbn-logging/src/ecs/package.ts +++ b/packages/kbn-logging/src/ecs/package.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-package.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-package.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/pe.ts b/packages/kbn-logging/src/ecs/pe.ts index bd53b7048a50d..c017dfa87fb23 100644 --- a/packages/kbn-logging/src/ecs/pe.ts +++ b/packages/kbn-logging/src/ecs/pe.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-pe.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-pe.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/process.ts b/packages/kbn-logging/src/ecs/process.ts index 9a034c30fd531..4e527d0b21d4c 100644 --- a/packages/kbn-logging/src/ecs/process.ts +++ b/packages/kbn-logging/src/ecs/process.ts @@ -7,18 +7,21 @@ */ import { EcsCodeSignature } from './code_signature'; +import { EcsElf } from './elf'; import { EcsHash } from './hash'; import { EcsPe } from './pe'; interface NestedFields { code_signature?: EcsCodeSignature; + elf?: EcsElf; hash?: EcsHash; parent?: EcsProcess; pe?: EcsPe; + target?: EcsProcess; } /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-process.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-process.html * * @internal */ @@ -26,6 +29,7 @@ export interface EcsProcess extends NestedFields { args?: string[]; args_count?: number; command_line?: string; + end?: string; entity_id?: string; executable?: string; exit_code?: number; @@ -34,7 +38,6 @@ export interface EcsProcess extends NestedFields { pid?: number; ppid?: number; start?: string; - thread?: { id?: number; name?: string }; title?: string; uptime?: number; working_directory?: string; diff --git a/packages/kbn-logging/src/ecs/registry.ts b/packages/kbn-logging/src/ecs/registry.ts index ba7ef699e2cdb..8cc12de6c136e 100644 --- a/packages/kbn-logging/src/ecs/registry.ts +++ b/packages/kbn-logging/src/ecs/registry.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-registry.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-registry.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/related.ts b/packages/kbn-logging/src/ecs/related.ts index 33c3ff50540ce..6616780177d16 100644 --- a/packages/kbn-logging/src/ecs/related.ts +++ b/packages/kbn-logging/src/ecs/related.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-related.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-related.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/rule.ts b/packages/kbn-logging/src/ecs/rule.ts index c6bf1ce96552a..5a961302de918 100644 --- a/packages/kbn-logging/src/ecs/rule.ts +++ b/packages/kbn-logging/src/ecs/rule.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-rule.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-rule.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/server.ts b/packages/kbn-logging/src/ecs/server.ts index 9b2a9b1a11b42..01b2394c6bccc 100644 --- a/packages/kbn-logging/src/ecs/server.ts +++ b/packages/kbn-logging/src/ecs/server.ts @@ -17,7 +17,7 @@ interface NestedFields { } /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-server.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-server.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/service.ts b/packages/kbn-logging/src/ecs/service.ts index 4cd79e928c076..04cff203da961 100644 --- a/packages/kbn-logging/src/ecs/service.ts +++ b/packages/kbn-logging/src/ecs/service.ts @@ -7,11 +7,13 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-service.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-service.html * * @internal */ export interface EcsService { + address?: string; + environment?: string; ephemeral_id?: string; id?: string; name?: string; diff --git a/packages/kbn-logging/src/ecs/source.ts b/packages/kbn-logging/src/ecs/source.ts index 9ec7e2521d0b9..2879adb0d996e 100644 --- a/packages/kbn-logging/src/ecs/source.ts +++ b/packages/kbn-logging/src/ecs/source.ts @@ -17,7 +17,7 @@ interface NestedFields { } /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-source.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-source.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/threat.ts b/packages/kbn-logging/src/ecs/threat.ts index ac6033949fccd..78adf583b0ee2 100644 --- a/packages/kbn-logging/src/ecs/threat.ts +++ b/packages/kbn-logging/src/ecs/threat.ts @@ -6,17 +6,82 @@ * Side Public License, v 1. */ +import { EcsAutonomousSystem } from './autonomous_system'; +import { EcsFile } from './file'; +import { EcsGeo } from './geo'; +import { EcsRegistry } from './registry'; +import { EcsUrl } from './url'; +import { EcsX509 } from './x509'; + +interface IndicatorNestedFields { + as?: EcsAutonomousSystem; + file?: EcsFile; + geo?: EcsGeo; + registry?: EcsRegistry; + url?: EcsUrl; + x509?: EcsX509; +} + /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-threat.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-threat.html * * @internal */ export interface EcsThreat { + enrichments?: Enrichment[]; + indicator?: Indicator; framework?: string; + group?: Group; + software?: Software; tactic?: Tactic; technique?: Technique; } +interface Enrichment { + indicator?: Indicator; + matched?: Matched; +} + +interface Indicator extends IndicatorNestedFields { + confidence?: string; + description?: string; + email?: { address?: string }; + first_seen?: string; + ip?: string; + last_seen?: string; + marking?: { tlp?: string }; + modified_at?: string; + port?: number; + provider?: string; + reference?: string; + scanner_stats?: number; + sightings?: number; + type?: string; +} + +interface Matched { + atomic?: string; + field?: string; + id?: string; + index?: string; + type?: string; +} + +interface Group { + alias?: string[]; + id?: string; + name?: string; + reference?: string; +} + +interface Software { + id?: string; + name?: string; + platforms?: string[]; + reference?: string; + type?: string; +} + interface Tactic { id?: string[]; name?: string[]; diff --git a/packages/kbn-logging/src/ecs/tls.ts b/packages/kbn-logging/src/ecs/tls.ts index b04d03d650908..75667170f6059 100644 --- a/packages/kbn-logging/src/ecs/tls.ts +++ b/packages/kbn-logging/src/ecs/tls.ts @@ -17,7 +17,7 @@ interface NestedServerFields { } /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-tls.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-tls.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/tracing.ts b/packages/kbn-logging/src/ecs/tracing.ts index 1abbbd4b4c8a2..ea1ff300e4c3f 100644 --- a/packages/kbn-logging/src/ecs/tracing.ts +++ b/packages/kbn-logging/src/ecs/tracing.ts @@ -12,7 +12,7 @@ * the base fields, we will need to do an intersection with these types at * the root level. * - * https://www.elastic.co/guide/en/ecs/1.9/ecs-tracing.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-tracing.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/url.ts b/packages/kbn-logging/src/ecs/url.ts index 5985b28a4f6c3..069ff6b09aec5 100644 --- a/packages/kbn-logging/src/ecs/url.ts +++ b/packages/kbn-logging/src/ecs/url.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-url.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-url.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/user.ts b/packages/kbn-logging/src/ecs/user.ts index 3ab0c946b49b7..6bce3552e23ec 100644 --- a/packages/kbn-logging/src/ecs/user.ts +++ b/packages/kbn-logging/src/ecs/user.ts @@ -20,7 +20,7 @@ interface NestedFields { * placed at the root level, but not if it is nested inside another field like * `destination`. A more detailed explanation of these nuances can be found at: * - * https://www.elastic.co/guide/en/ecs/1.9/ecs-user-usage.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-user-usage.html * * As a result, we need to export a separate `NestedUser` type to import into * other interfaces internally. This contains the reusable subset of properties diff --git a/packages/kbn-logging/src/ecs/user_agent.ts b/packages/kbn-logging/src/ecs/user_agent.ts index f77b3ba9e1f0f..0ff8aa681d964 100644 --- a/packages/kbn-logging/src/ecs/user_agent.ts +++ b/packages/kbn-logging/src/ecs/user_agent.ts @@ -13,7 +13,7 @@ interface NestedFields { } /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-user_agent.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-user_agent.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/vlan.ts b/packages/kbn-logging/src/ecs/vlan.ts index 646f8ee17fd03..a2939380ea57f 100644 --- a/packages/kbn-logging/src/ecs/vlan.ts +++ b/packages/kbn-logging/src/ecs/vlan.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-vlan.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-vlan.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/vulnerability.ts b/packages/kbn-logging/src/ecs/vulnerability.ts index 2c26d557d2ba9..a3648a9c5df17 100644 --- a/packages/kbn-logging/src/ecs/vulnerability.ts +++ b/packages/kbn-logging/src/ecs/vulnerability.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-vulnerability.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-vulnerability.html * * @internal */ diff --git a/packages/kbn-logging/src/ecs/x509.ts b/packages/kbn-logging/src/ecs/x509.ts index 35bc1b458579a..a38fb93585c83 100644 --- a/packages/kbn-logging/src/ecs/x509.ts +++ b/packages/kbn-logging/src/ecs/x509.ts @@ -7,7 +7,7 @@ */ /** - * https://www.elastic.co/guide/en/ecs/1.9/ecs-x509.html + * https://www.elastic.co/guide/en/ecs/1.12/ecs-x509.html * * @internal */ diff --git a/packages/kbn-test/BUILD.bazel b/packages/kbn-test/BUILD.bazel index 36e81df6d8c3c..efaf01f7137d9 100644 --- a/packages/kbn-test/BUILD.bazel +++ b/packages/kbn-test/BUILD.bazel @@ -50,6 +50,7 @@ RUNTIME_DEPS = [ "@npm//exit-hook", "@npm//form-data", "@npm//globby", + "@npm//he", "@npm//history", "@npm//jest", "@npm//jest-cli", @@ -85,6 +86,7 @@ TYPES_DEPS = [ "@npm//xmlbuilder", "@npm//@types/chance", "@npm//@types/enzyme", + "@npm//@types/he", "@npm//@types/history", "@npm//@types/jest", "@npm//@types/joi", diff --git a/packages/kbn-test/src/failed_tests_reporter/report_failures_to_file.ts b/packages/kbn-test/src/failed_tests_reporter/report_failures_to_file.ts new file mode 100644 index 0000000000000..aca2e6838faec --- /dev/null +++ b/packages/kbn-test/src/failed_tests_reporter/report_failures_to_file.ts @@ -0,0 +1,138 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { createHash } from 'crypto'; +import { mkdirSync, readdirSync, readFileSync, statSync, writeFileSync } from 'fs'; +import { join, basename, resolve } from 'path'; + +import { ToolingLog } from '@kbn/dev-utils'; +import { REPO_ROOT } from '@kbn/utils'; +import { escape } from 'he'; + +import { TestFailure } from './get_failures'; + +const findScreenshots = (dirPath: string, allScreenshots: string[] = []) => { + const files = readdirSync(dirPath); + + for (const file of files) { + if (statSync(join(dirPath, file)).isDirectory()) { + if (file.match(/node_modules/)) { + continue; + } + + allScreenshots = findScreenshots(join(dirPath, file), allScreenshots); + } else { + const fullPath = join(dirPath, file); + if (fullPath.match(/screenshots\/failure\/.+\.png$/)) { + allScreenshots.push(fullPath); + } + } + } + + return allScreenshots; +}; + +export function reportFailuresToFile(log: ToolingLog, failures: TestFailure[]) { + if (!failures?.length) { + return; + } + + let screenshots: string[]; + try { + screenshots = [ + ...findScreenshots(join(REPO_ROOT, 'test', 'functional')), + ...findScreenshots(join(REPO_ROOT, 'x-pack', 'test', 'functional')), + ]; + } catch (e) { + log.error(e as Error); + screenshots = []; + } + + const screenshotsByName: Record = {}; + for (const screenshot of screenshots) { + const [name] = basename(screenshot).split('.'); + screenshotsByName[name] = screenshot; + } + + // Jest could, in theory, fail 1000s of tests and write 1000s of failures + // So let's just write files for the first 20 + for (const failure of failures.slice(0, 20)) { + const hash = createHash('md5').update(failure.name).digest('hex'); + const filenameBase = `${ + process.env.BUILDKITE_JOB_ID ? process.env.BUILDKITE_JOB_ID + '_' : '' + }${hash}`; + const dir = join('target', 'test_failures'); + + const failureLog = [ + ['Test:', '-----', failure.classname, failure.name, ''], + ['Failure:', '--------', failure.failure], + failure['system-out'] ? ['', 'Standard Out:', '-------------', failure['system-out']] : [], + ] + .flat() + .join('\n'); + + const failureJSON = JSON.stringify( + { + ...failure, + hash, + buildId: process.env.BUJILDKITE_BUILD_ID || '', + jobId: process.env.BUILDKITE_JOB_ID || '', + url: process.env.BUILDKITE_BUILD_URL || '', + jobName: process.env.BUILDKITE_LABEL + ? `${process.env.BUILDKITE_LABEL}${ + process.env.BUILDKITE_PARALLEL_JOB ? ` #${process.env.BUILDKITE_PARALLEL_JOB}` : '' + }` + : '', + }, + null, + 2 + ); + + let screenshot = ''; + const screenshotName = `${failure.name.replace(/([^ a-zA-Z0-9-]+)/g, '_')}`; + if (screenshotsByName[screenshotName]) { + try { + screenshot = readFileSync(screenshotsByName[screenshotName]).toString('base64'); + } catch (e) { + log.error(e as Error); + } + } + + const screenshotHtml = screenshot + ? `` + : ''; + + const failureHTML = readFileSync( + resolve( + REPO_ROOT, + 'packages/kbn-test/src/failed_tests_reporter/report_failures_to_file_html_template.html' + ) + ) + .toString() + .replace('$TITLE', escape(failure.name)) + .replace( + '$MAIN', + ` + ${failure.classname + .split('.') + .map((part) => `
${escape(part.replace('·', '.'))}
`) + .join('')} +
+

${escape(failure.name)}

+
${escape(failure.failure)}
+ ${screenshotHtml} +
${escape(failure['system-out'] || '')}
+ ` + ); + + mkdirSync(dir, { recursive: true }); + writeFileSync(join(dir, `${filenameBase}.log`), failureLog, 'utf8'); + writeFileSync(join(dir, `${filenameBase}.html`), failureHTML, 'utf8'); + writeFileSync(join(dir, `${filenameBase}.json`), failureJSON, 'utf8'); + } +} diff --git a/packages/kbn-test/src/failed_tests_reporter/report_failures_to_file_html_template.html b/packages/kbn-test/src/failed_tests_reporter/report_failures_to_file_html_template.html new file mode 100644 index 0000000000000..485a2c2d4eb3f --- /dev/null +++ b/packages/kbn-test/src/failed_tests_reporter/report_failures_to_file_html_template.html @@ -0,0 +1,41 @@ + + + + + + + + $TITLE + + +
+
$MAIN
+
+ + + diff --git a/packages/kbn-test/src/failed_tests_reporter/run_failed_tests_reporter_cli.ts b/packages/kbn-test/src/failed_tests_reporter/run_failed_tests_reporter_cli.ts index 0129614fe658d..6c88b7408b628 100644 --- a/packages/kbn-test/src/failed_tests_reporter/run_failed_tests_reporter_cli.ts +++ b/packages/kbn-test/src/failed_tests_reporter/run_failed_tests_reporter_cli.ts @@ -21,6 +21,7 @@ import { readTestReport } from './test_report'; import { addMessagesToReport } from './add_messages_to_report'; import { getReportMessageIter } from './report_metadata'; import { reportFailuresToEs } from './report_failures_to_es'; +import { reportFailuresToFile } from './report_failures_to_file'; const DEFAULT_PATTERNS = [Path.resolve(REPO_ROOT, 'target/junit/**/*.xml')]; @@ -98,6 +99,8 @@ export function runFailedTestsReporterCli() { const messages = Array.from(getReportMessageIter(report)); const failures = await getFailures(report); + reportFailuresToFile(log, failures); + if (indexInEs) { await reportFailuresToEs(log, failures); } diff --git a/src/cli/serve/serve.js b/src/cli/serve/serve.js index be949350f7229..705acfe4fdf54 100644 --- a/src/cli/serve/serve.js +++ b/src/cli/serve/serve.js @@ -52,7 +52,6 @@ const pathCollector = function () { }; const configPathCollector = pathCollector(); -const pluginDirCollector = pathCollector(); const pluginPathCollector = pathCollector(); function applyConfigOverrides(rawConfig, opts, extraCliOptions) { @@ -138,7 +137,6 @@ function applyConfigOverrides(rawConfig, opts, extraCliOptions) { } } - set('plugins.scanDirs', _.compact([].concat(get('plugins.scanDirs'), opts.pluginDir))); set('plugins.paths', _.compact([].concat(get('plugins.paths'), opts.pluginPath))); merge(extraCliOptions); @@ -169,13 +167,6 @@ export default function (program) { '-l, --log-file ', 'Deprecated, set logging file destination in your configuration' ) - .option( - '--plugin-dir ', - 'A path to scan for plugins, this can be specified multiple ' + - 'times to specify multiple directories', - pluginDirCollector, - [fromRoot('plugins')] - ) .option( '--plugin-path ', 'A path to a plugin which should be included by the server, ' + @@ -183,7 +174,6 @@ export default function (program) { pluginPathCollector, [] ) - .option('--plugins ', 'an alias for --plugin-dir', pluginDirCollector) .option('--optimize', 'Deprecated, running the optimizer is no longer required'); if (!isKibanaDistributable()) { diff --git a/src/core/server/i18n/get_kibana_translation_files.test.ts b/src/core/server/i18n/get_kibana_translation_files.test.ts index 45e1a8dfec9cb..89a03c35d66ae 100644 --- a/src/core/server/i18n/get_kibana_translation_files.test.ts +++ b/src/core/server/i18n/get_kibana_translation_files.test.ts @@ -41,7 +41,7 @@ describe('getKibanaTranslationPaths', () => { }); }); - it('calls getTranslationPaths for each config returned in plugin.paths and plugins.scanDirs', async () => { + it('calls getTranslationPaths for each config returned in plugin.paths', async () => { const pluginPaths = ['/path/to/pluginA', '/path/to/pluginB']; await getKibanaTranslationFiles(locale, pluginPaths); diff --git a/src/core/server/logging/__snapshots__/logging_system.test.ts.snap b/src/core/server/logging/__snapshots__/logging_system.test.ts.snap index d74317203d78e..851cfd6cf3bcc 100644 --- a/src/core/server/logging/__snapshots__/logging_system.test.ts.snap +++ b/src/core/server/logging/__snapshots__/logging_system.test.ts.snap @@ -16,7 +16,7 @@ exports[`asLoggerFactory() only allows to create new loggers. 1`] = ` Object { "@timestamp": "2012-01-30T22:33:22.011-05:00", "ecs": Object { - "version": "1.9.0", + "version": "1.12.0", }, "log": Object { "level": "TRACE", @@ -33,7 +33,7 @@ exports[`asLoggerFactory() only allows to create new loggers. 2`] = ` Object { "@timestamp": "2012-01-30T17:33:22.011-05:00", "ecs": Object { - "version": "1.9.0", + "version": "1.12.0", }, "log": Object { "level": "INFO", @@ -51,7 +51,7 @@ exports[`asLoggerFactory() only allows to create new loggers. 3`] = ` Object { "@timestamp": "2012-01-30T12:33:22.011-05:00", "ecs": Object { - "version": "1.9.0", + "version": "1.12.0", }, "log": Object { "level": "FATAL", @@ -68,7 +68,7 @@ exports[`flushes memory buffer logger and switches to real logger once config is Object { "@timestamp": "2012-02-01T09:33:22.011-05:00", "ecs": Object { - "version": "1.9.0", + "version": "1.12.0", }, "log": Object { "level": "INFO", @@ -86,7 +86,7 @@ exports[`flushes memory buffer logger and switches to real logger once config is Object { "@timestamp": "2012-01-31T23:33:22.011-05:00", "ecs": Object { - "version": "1.9.0", + "version": "1.12.0", }, "log": Object { "level": "INFO", diff --git a/src/core/server/logging/layouts/__snapshots__/json_layout.test.ts.snap b/src/core/server/logging/layouts/__snapshots__/json_layout.test.ts.snap index a131d5c8a9248..e128651e61b40 100644 --- a/src/core/server/logging/layouts/__snapshots__/json_layout.test.ts.snap +++ b/src/core/server/logging/layouts/__snapshots__/json_layout.test.ts.snap @@ -1,13 +1,13 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP -exports[`\`format()\` correctly formats record. 1`] = `"{\\"ecs\\":{\\"version\\":\\"1.9.0\\"},\\"@timestamp\\":\\"2012-02-01T09:30:22.011-05:00\\",\\"message\\":\\"message-1\\",\\"error\\":{\\"message\\":\\"Some error message\\",\\"type\\":\\"Some error name\\",\\"stack_trace\\":\\"Some error stack\\"},\\"log\\":{\\"level\\":\\"FATAL\\",\\"logger\\":\\"context-1\\"},\\"process\\":{\\"pid\\":5355}}"`; +exports[`\`format()\` correctly formats record. 1`] = `"{\\"ecs\\":{\\"version\\":\\"1.12.0\\"},\\"@timestamp\\":\\"2012-02-01T09:30:22.011-05:00\\",\\"message\\":\\"message-1\\",\\"error\\":{\\"message\\":\\"Some error message\\",\\"type\\":\\"Some error name\\",\\"stack_trace\\":\\"Some error stack\\"},\\"log\\":{\\"level\\":\\"FATAL\\",\\"logger\\":\\"context-1\\"},\\"process\\":{\\"pid\\":5355}}"`; -exports[`\`format()\` correctly formats record. 2`] = `"{\\"ecs\\":{\\"version\\":\\"1.9.0\\"},\\"@timestamp\\":\\"2012-02-01T09:30:22.011-05:00\\",\\"message\\":\\"message-2\\",\\"log\\":{\\"level\\":\\"ERROR\\",\\"logger\\":\\"context-2\\"},\\"process\\":{\\"pid\\":5355}}"`; +exports[`\`format()\` correctly formats record. 2`] = `"{\\"ecs\\":{\\"version\\":\\"1.12.0\\"},\\"@timestamp\\":\\"2012-02-01T09:30:22.011-05:00\\",\\"message\\":\\"message-2\\",\\"log\\":{\\"level\\":\\"ERROR\\",\\"logger\\":\\"context-2\\"},\\"process\\":{\\"pid\\":5355}}"`; -exports[`\`format()\` correctly formats record. 3`] = `"{\\"ecs\\":{\\"version\\":\\"1.9.0\\"},\\"@timestamp\\":\\"2012-02-01T09:30:22.011-05:00\\",\\"message\\":\\"message-3\\",\\"log\\":{\\"level\\":\\"WARN\\",\\"logger\\":\\"context-3\\"},\\"process\\":{\\"pid\\":5355}}"`; +exports[`\`format()\` correctly formats record. 3`] = `"{\\"ecs\\":{\\"version\\":\\"1.12.0\\"},\\"@timestamp\\":\\"2012-02-01T09:30:22.011-05:00\\",\\"message\\":\\"message-3\\",\\"log\\":{\\"level\\":\\"WARN\\",\\"logger\\":\\"context-3\\"},\\"process\\":{\\"pid\\":5355}}"`; -exports[`\`format()\` correctly formats record. 4`] = `"{\\"ecs\\":{\\"version\\":\\"1.9.0\\"},\\"@timestamp\\":\\"2012-02-01T09:30:22.011-05:00\\",\\"message\\":\\"message-4\\",\\"log\\":{\\"level\\":\\"DEBUG\\",\\"logger\\":\\"context-4\\"},\\"process\\":{\\"pid\\":5355}}"`; +exports[`\`format()\` correctly formats record. 4`] = `"{\\"ecs\\":{\\"version\\":\\"1.12.0\\"},\\"@timestamp\\":\\"2012-02-01T09:30:22.011-05:00\\",\\"message\\":\\"message-4\\",\\"log\\":{\\"level\\":\\"DEBUG\\",\\"logger\\":\\"context-4\\"},\\"process\\":{\\"pid\\":5355}}"`; -exports[`\`format()\` correctly formats record. 5`] = `"{\\"ecs\\":{\\"version\\":\\"1.9.0\\"},\\"@timestamp\\":\\"2012-02-01T09:30:22.011-05:00\\",\\"message\\":\\"message-5\\",\\"log\\":{\\"level\\":\\"INFO\\",\\"logger\\":\\"context-5\\"},\\"process\\":{\\"pid\\":5355}}"`; +exports[`\`format()\` correctly formats record. 5`] = `"{\\"ecs\\":{\\"version\\":\\"1.12.0\\"},\\"@timestamp\\":\\"2012-02-01T09:30:22.011-05:00\\",\\"message\\":\\"message-5\\",\\"log\\":{\\"level\\":\\"INFO\\",\\"logger\\":\\"context-5\\"},\\"process\\":{\\"pid\\":5355}}"`; -exports[`\`format()\` correctly formats record. 6`] = `"{\\"ecs\\":{\\"version\\":\\"1.9.0\\"},\\"@timestamp\\":\\"2012-02-01T09:30:22.011-05:00\\",\\"message\\":\\"message-6\\",\\"log\\":{\\"level\\":\\"TRACE\\",\\"logger\\":\\"context-6\\"},\\"process\\":{\\"pid\\":5355}}"`; +exports[`\`format()\` correctly formats record. 6`] = `"{\\"ecs\\":{\\"version\\":\\"1.12.0\\"},\\"@timestamp\\":\\"2012-02-01T09:30:22.011-05:00\\",\\"message\\":\\"message-6\\",\\"log\\":{\\"level\\":\\"TRACE\\",\\"logger\\":\\"context-6\\"},\\"process\\":{\\"pid\\":5355}}"`; diff --git a/src/core/server/logging/layouts/json_layout.test.ts b/src/core/server/logging/layouts/json_layout.test.ts index e76e3fb4402bb..034e2abf46461 100644 --- a/src/core/server/logging/layouts/json_layout.test.ts +++ b/src/core/server/logging/layouts/json_layout.test.ts @@ -74,7 +74,7 @@ test('`format()` correctly formats record.', () => { } }); -test('`format()` correctly formats record with meta-data', () => { +test('`format()` correctly formats record with meta-data and correct ECS version', () => { const layout = new JsonLayout(); expect( @@ -94,7 +94,7 @@ test('`format()` correctly formats record with meta-data', () => { }) ) ).toStrictEqual({ - ecs: { version: '1.9.0' }, + ecs: { version: '1.12.0' }, '@timestamp': '2012-02-01T09:30:22.011-05:00', log: { level: 'DEBUG', @@ -136,7 +136,7 @@ test('`format()` correctly formats error record with meta-data', () => { }) ) ).toStrictEqual({ - ecs: { version: '1.9.0' }, + ecs: { version: expect.any(String) }, '@timestamp': '2012-02-01T09:30:22.011-05:00', log: { level: 'DEBUG', @@ -176,7 +176,7 @@ test('format() meta can merge override logs', () => { }) ) ).toStrictEqual({ - ecs: { version: '1.9.0' }, + ecs: { version: expect.any(String) }, '@timestamp': '2012-02-01T09:30:22.011-05:00', message: 'foo', log: { @@ -206,7 +206,7 @@ test('format() meta can not override message', () => { }) ) ).toStrictEqual({ - ecs: { version: '1.9.0' }, + ecs: { version: expect.any(String) }, '@timestamp': '2012-02-01T09:30:22.011-05:00', message: 'foo', log: { @@ -235,7 +235,7 @@ test('format() meta can not override ecs version', () => { }) ) ).toStrictEqual({ - ecs: { version: '1.9.0' }, + ecs: { version: expect.any(String) }, '@timestamp': '2012-02-01T09:30:22.011-05:00', message: 'foo', log: { @@ -267,7 +267,7 @@ test('format() meta can not override logger or level', () => { }) ) ).toStrictEqual({ - ecs: { version: '1.9.0' }, + ecs: { version: expect.any(String) }, '@timestamp': '2012-02-01T09:30:22.011-05:00', message: 'foo', log: { @@ -296,7 +296,7 @@ test('format() meta can not override timestamp', () => { }) ) ).toStrictEqual({ - ecs: { version: '1.9.0' }, + ecs: { version: expect.any(String) }, '@timestamp': '2012-02-01T09:30:22.011-05:00', message: 'foo', log: { diff --git a/src/core/server/logging/layouts/json_layout.ts b/src/core/server/logging/layouts/json_layout.ts index add88cc01b6d2..820ed32045f15 100644 --- a/src/core/server/logging/layouts/json_layout.ts +++ b/src/core/server/logging/layouts/json_layout.ts @@ -43,7 +43,7 @@ export class JsonLayout implements Layout { public format(record: LogRecord): string { const log: Ecs = { - ecs: { version: '1.9.0' }, + ecs: { version: '1.12.0' }, '@timestamp': moment(record.timestamp).format('YYYY-MM-DDTHH:mm:ss.SSSZ'), message: record.message, error: JsonLayout.errorToSerializableObject(record.error), diff --git a/src/core/server/plugins/plugins_config.ts b/src/core/server/plugins/plugins_config.ts index 45d80445f376e..6624fc40d2c0a 100644 --- a/src/core/server/plugins/plugins_config.ts +++ b/src/core/server/plugins/plugins_config.ts @@ -24,7 +24,6 @@ export type PluginsConfigType = TypeOf; export const config: ServiceConfigDescriptor = { path: 'plugins', schema: configSchema, - deprecations: ({ unusedFromRoot }) => [unusedFromRoot('plugins.scanDirs')], }; /** @internal */ diff --git a/src/core/test_helpers/kbn_server.ts b/src/core/test_helpers/kbn_server.ts index a2aa453cf55e7..67bd6c7455d6d 100644 --- a/src/core/test_helpers/kbn_server.ts +++ b/src/core/test_helpers/kbn_server.ts @@ -15,7 +15,6 @@ import { kibanaTestUser, } from '@kbn/test'; import { defaultsDeep } from 'lodash'; -import { resolve } from 'path'; import { BehaviorSubject } from 'rxjs'; import supertest from 'supertest'; @@ -99,7 +98,6 @@ export function createRoot(settings = {}, cliArgs: Partial = {}) { */ export function createRootWithCorePlugins(settings = {}, cliArgs: Partial = {}) { const DEFAULT_SETTINGS_WITH_CORE_PLUGINS = { - plugins: { scanDirs: [resolve(__dirname, '../../legacy/core_plugins')] }, elasticsearch: { hosts: [esTestConfig.getUrl()], username: kibanaServerTestUser.username, diff --git a/src/dev/build/tasks/os_packages/service_templates/systemd/usr/lib/systemd/system/kibana.service b/src/dev/build/tasks/os_packages/service_templates/systemd/usr/lib/systemd/system/kibana.service index df33b82f1f967..21f1a011f2397 100644 --- a/src/dev/build/tasks/os_packages/service_templates/systemd/usr/lib/systemd/system/kibana.service +++ b/src/dev/build/tasks/os_packages/service_templates/systemd/usr/lib/systemd/system/kibana.service @@ -8,6 +8,7 @@ After=network-online.target Type=simple User=kibana Group=kibana +PrivateTmp=true Environment=KBN_HOME=/usr/share/kibana Environment=KBN_PATH_CONF=/etc/kibana diff --git a/src/dev/eslint/lint_files.ts b/src/dev/eslint/lint_files.ts index 5c6118edeb2ec..b5849c0f8485f 100644 --- a/src/dev/eslint/lint_files.ts +++ b/src/dev/eslint/lint_files.ts @@ -12,6 +12,45 @@ import { REPO_ROOT } from '@kbn/utils'; import { createFailError, ToolingLog } from '@kbn/dev-utils'; import { File } from '../file'; +// For files living on the filesystem +function lintFilesOnFS(cli: CLIEngine, files: File[]) { + const paths = files.map((file) => file.getRelativePath()); + return cli.executeOnFiles(paths); +} + +// For files living somewhere else (ie. git object) +async function lintFilesOnContent(cli: CLIEngine, files: File[]) { + const report: { + results: any[]; + errorCount: number; + warningCount: number; + fixableErrorCount: number; + fixableWarningCount: number; + } = { + results: [], + errorCount: 0, + warningCount: 0, + fixableErrorCount: 0, + fixableWarningCount: 0, + }; + + for (let i = 0; i < files.length; i++) { + const r = cli.executeOnText(await files[i].getContent(), files[i].getRelativePath()); + // Despite a relative path was given, the result would contain an absolute one. Work around it. + r.results[0].filePath = r.results[0].filePath.replace( + files[i].getAbsolutePath(), + files[i].getRelativePath() + ); + report.results.push(...r.results); + report.errorCount += r.errorCount; + report.warningCount += r.warningCount; + report.fixableErrorCount += r.fixableErrorCount; + report.fixableWarningCount += r.fixableWarningCount; + } + + return report; +} + /** * Lints a list of files with eslint. eslint reports are written to the log * and a FailError is thrown when linting errors occur. @@ -20,15 +59,16 @@ import { File } from '../file'; * @param {Array} files * @return {undefined} */ -export function lintFiles(log: ToolingLog, files: File[], { fix }: { fix?: boolean } = {}) { +export async function lintFiles(log: ToolingLog, files: File[], { fix }: { fix?: boolean } = {}) { const cli = new CLIEngine({ cache: true, cwd: REPO_ROOT, fix, }); - const paths = files.map((file) => file.getRelativePath()); - const report = cli.executeOnFiles(paths); + const virtualFilesCount = files.filter((file) => file.isVirtual()).length; + const report = + virtualFilesCount && !fix ? await lintFilesOnContent(cli, files) : lintFilesOnFS(cli, files); if (fix) { CLIEngine.outputFixes(report); diff --git a/src/dev/file.ts b/src/dev/file.ts index b532a7bb70602..01005b257a403 100644 --- a/src/dev/file.ts +++ b/src/dev/file.ts @@ -7,11 +7,13 @@ */ import { dirname, extname, join, relative, resolve, sep, basename } from 'path'; +import { createFailError } from '@kbn/dev-utils'; export class File { private path: string; private relativePath: string; private ext: string; + private fileReader: undefined | (() => Promise); constructor(path: string) { this.path = resolve(path); @@ -55,6 +57,11 @@ export class File { ); } + // Virtual files cannot be read as usual, an helper is needed + public isVirtual() { + return this.fileReader !== undefined; + } + public getRelativeParentDirs() { const parents: string[] = []; @@ -81,4 +88,15 @@ export class File { public toJSON() { return this.relativePath; } + + public setFileReader(fileReader: () => Promise) { + this.fileReader = fileReader; + } + + public getContent() { + if (this.fileReader) { + return this.fileReader(); + } + throw createFailError('getContent() was invoked on a non-virtual File'); + } } diff --git a/src/dev/precommit_hook/get_files_for_commit.js b/src/dev/precommit_hook/get_files_for_commit.js index 44c8c9d5e6bc0..52dfab49c5c64 100644 --- a/src/dev/precommit_hook/get_files_for_commit.js +++ b/src/dev/precommit_hook/get_files_for_commit.js @@ -6,12 +6,65 @@ * Side Public License, v 1. */ +import { format } from 'util'; import SimpleGit from 'simple-git'; import { fromNode as fcb } from 'bluebird'; import { REPO_ROOT } from '@kbn/utils'; import { File } from '../file'; +/** + * Return the `git diff` argument used for building the list of files + * + * @param {String} gitRef + * @return {String} + * + * gitRef return + * '' '--cached' + * '' '~1..' + * '..' '..' + * '...' '...' + * '..' '..' + * '...' '...' + * '..' '..' + * '...' '...' + */ +function getRefForDiff(gitRef) { + if (!gitRef) { + return '--cached'; + } else if (gitRef.includes('..')) { + return gitRef; + } else { + return format('%s~1..%s', gitRef, gitRef); + } +} + +/** + * Return the used for reading files content + * + * @param {String} gitRef + * @return {String} + * + * gitRef return + * '' '' + * '' '' + * '..' 'HEAD' + * '...' 'HEAD' + * '..' '' + * '...' '' + * '..' '' + * '...' '' + */ +function getRefForCat(gitRef) { + if (!gitRef) { + return ''; + } else if (gitRef.includes('..')) { + return gitRef.endsWith('..') ? 'HEAD' : gitRef.slice(gitRef.lastIndexOf('..') + 2); + } else { + return gitRef; + } +} + /** * Get the files that are staged for commit (excluding deleted files) * as `File` objects that are aware of their commit status. @@ -21,29 +74,23 @@ import { File } from '../file'; */ export async function getFilesForCommit(gitRef) { const simpleGit = new SimpleGit(REPO_ROOT); - const gitRefForDiff = gitRef ? gitRef : '--cached'; - const output = await fcb((cb) => simpleGit.diff(['--name-status', gitRefForDiff], cb)); + const gitRefForDiff = getRefForDiff(gitRef); + const gitRefForCat = getRefForCat(gitRef); + + const output = await fcb((cb) => { + simpleGit.diff(['--diff-filter=d', '--name-only', gitRefForDiff], cb); + }); return ( output .split('\n') // Ignore blank lines .filter((line) => line.trim().length > 0) - // git diff --name-status outputs lines with two OR three parts - // separated by a tab character - .map((line) => line.trim().split('\t')) - .map(([status, ...paths]) => { - // ignore deleted files - if (status === 'D') { - return undefined; - } - - // the status is always in the first column - // .. If the file is edited the line will only have two columns - // .. If the file is renamed it will have three columns - // .. In any case, the last column is the CURRENT path to the file - return new File(paths[paths.length - 1]); + .map((path) => { + const file = new File(path); + const object = format('%s:%s', gitRefForCat, path); + file.setFileReader(() => fcb((cb) => simpleGit.catFile(['-p', object], cb))); + return file; }) - .filter(Boolean) ); } diff --git a/src/dev/run_precommit_hook.js b/src/dev/run_precommit_hook.js index 73394a62e3396..e1eafaf28d95d 100644 --- a/src/dev/run_precommit_hook.js +++ b/src/dev/run_precommit_hook.js @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { run, combineErrors, createFlagError } from '@kbn/dev-utils'; +import { run, combineErrors, createFlagError, createFailError } from '@kbn/dev-utils'; import * as Eslint from './eslint'; import * as Stylelint from './stylelint'; import { getFilesForCommit, checkFileCasing } from './precommit_hook'; @@ -23,6 +23,11 @@ run( throw createFlagError('expected --max-files to be a number greater than 0'); } + const virtualFilesCount = files.filter((file) => file.isVirtual()).length; + if (virtualFilesCount > 0 && virtualFilesCount < files.length) { + throw createFailError('Mixing of virtual and on-filesystem files is unsupported'); + } + if (maxFilesCount && files.length > maxFilesCount) { log.warning( `--max-files is set to ${maxFilesCount} and ${files.length} were discovered. The current script execution will be skipped.` @@ -66,7 +71,11 @@ run( help: ` --fix Execute eslint in --fix mode --max-files Max files number to check against. If exceeded the script will skip the execution - --ref Run checks against any git ref files (example HEAD or ) instead of running against staged ones + --ref Run checks against git ref files instead of running against staged ones + Examples: + HEAD~1..HEAD files changed in the commit at HEAD + HEAD equivalent to HEAD~1..HEAD + main... files changed in current branch since the common ancestor with main `, }, } diff --git a/src/dev/stylelint/lint_files.js b/src/dev/stylelint/lint_files.js index 6e62c85d44ae8..1ebc981728814 100644 --- a/src/dev/stylelint/lint_files.js +++ b/src/dev/stylelint/lint_files.js @@ -16,6 +16,51 @@ import { createFailError } from '@kbn/dev-utils'; const stylelintPath = path.resolve(__dirname, '..', '..', '..', '.stylelintrc'); const styleLintConfig = safeLoad(fs.readFileSync(stylelintPath)); +// For files living on the filesystem +function lintFilesOnFS(files) { + const paths = files.map((file) => file.getRelativePath()); + + const options = { + files: paths, + config: styleLintConfig, + formatter: 'string', + ignorePath: path.resolve(__dirname, '..', '..', '..', '.stylelintignore'), + }; + + return stylelint.lint(options); +} + +// For files living somewhere else (ie. git object) +async function lintFilesOnContent(files) { + const report = { + errored: false, + output: '', + postcssResults: [], + results: [], + maxWarningsExceeded: { + maxWarnings: 0, + foundWarnings: 0, + }, + }; + + for (let i = 0; i < files.length; i++) { + const options = { + code: await files[i].getContent(), + config: styleLintConfig, + formatter: 'string', + ignorePath: path.resolve(__dirname, '..', '..', '..', '.stylelintignore'), + }; + const r = await stylelint.lint(options); + report.errored = report.errored || r.errored; + report.output += r.output.replace(//, files[i].getRelativePath()).slice(0, -1); + report.postcssResults.push(...(r.postcssResults || [])); + report.maxWarnings = r.maxWarnings; + report.foundWarnings += r.foundWarnings; + } + + return report; +} + /** * Lints a list of files with eslint. eslint reports are written to the log * and a FailError is thrown when linting errors occur. @@ -25,16 +70,9 @@ const styleLintConfig = safeLoad(fs.readFileSync(stylelintPath)); * @return {undefined} */ export async function lintFiles(log, files) { - const paths = files.map((file) => file.getRelativePath()); - - const options = { - files: paths, - config: styleLintConfig, - formatter: 'string', - ignorePath: path.resolve(__dirname, '..', '..', '..', '.stylelintignore'), - }; + const virtualFilesCount = files.filter((file) => file.isVirtual()).length; + const report = virtualFilesCount ? await lintFilesOnContent(files) : await lintFilesOnFS(files); - const report = await stylelint.lint(options); if (report.errored) { log.error(report.output); throw createFailError('[stylelint] errors'); diff --git a/src/plugins/custom_integrations/common/index.ts b/src/plugins/custom_integrations/common/index.ts index 48f31cb0bcb0c..73e15c91ce4bf 100755 --- a/src/plugins/custom_integrations/common/index.ts +++ b/src/plugins/custom_integrations/common/index.ts @@ -9,12 +9,12 @@ export const PLUGIN_ID = 'customIntegrations'; export const PLUGIN_NAME = 'customIntegrations'; -export interface CategoryCount { +export interface IntegrationCategoryCount { count: number; - id: Category; + id: IntegrationCategory; } -export const CATEGORY_DISPLAY = { +export const INTEGRATION_CATEGORY_DISPLAY = { aws: 'AWS', azure: 'Azure', cloud: 'Cloud', @@ -44,7 +44,7 @@ export const CATEGORY_DISPLAY = { updates_available: 'Updates available', }; -export type Category = keyof typeof CATEGORY_DISPLAY; +export type IntegrationCategory = keyof typeof INTEGRATION_CATEGORY_DISPLAY; export interface CustomIntegrationIcon { src: string; @@ -59,8 +59,10 @@ export interface CustomIntegration { uiInternalPath: string; isBeta: boolean; icons: CustomIntegrationIcon[]; - categories: Category[]; + categories: IntegrationCategory[]; shipper: string; + eprOverlap?: string; // name of the equivalent Elastic Agent integration in EPR. e.g. a beat module can correspond to an EPR-package, or an APM-tutorial. When completed, Integrations-UX can preferentially show the EPR-package, rather than the custom-integration } -export const ROUTES_ADDABLECUSTOMINTEGRATIONS = `/api/${PLUGIN_ID}/appendCustomIntegrations`; +export const ROUTES_APPEND_CUSTOM_INTEGRATIONS = `/internal/${PLUGIN_ID}/appendCustomIntegrations`; +export const ROUTES_REPLACEMENT_CUSTOM_INTEGRATIONS = `/internal/${PLUGIN_ID}/replacementCustomIntegrations`; diff --git a/src/plugins/custom_integrations/public/mocks.ts b/src/plugins/custom_integrations/public/mocks.ts index e6462751368a3..2e6bc491c2c5c 100644 --- a/src/plugins/custom_integrations/public/mocks.ts +++ b/src/plugins/custom_integrations/public/mocks.ts @@ -9,10 +9,10 @@ import { CustomIntegrationsSetup } from './types'; function createCustomIntegrationsSetup(): jest.Mocked { - const mock = { + const mock: jest.Mocked = { getAppendCustomIntegrations: jest.fn(), + getReplacementCustomIntegrations: jest.fn(), }; - return mock; } diff --git a/src/plugins/custom_integrations/public/plugin.ts b/src/plugins/custom_integrations/public/plugin.ts index 821c08ce84e31..7ea7a829e8072 100755 --- a/src/plugins/custom_integrations/public/plugin.ts +++ b/src/plugins/custom_integrations/public/plugin.ts @@ -8,7 +8,11 @@ import { CoreSetup, CoreStart, Plugin } from 'src/core/public'; import { CustomIntegrationsSetup, CustomIntegrationsStart } from './types'; -import { CustomIntegration, ROUTES_ADDABLECUSTOMINTEGRATIONS } from '../common'; +import { + CustomIntegration, + ROUTES_APPEND_CUSTOM_INTEGRATIONS, + ROUTES_REPLACEMENT_CUSTOM_INTEGRATIONS, +} from '../common'; export class CustomIntegrationsPlugin implements Plugin @@ -16,10 +20,14 @@ export class CustomIntegrationsPlugin public setup(core: CoreSetup): CustomIntegrationsSetup { // Return methods that should be available to other plugins return { + async getReplacementCustomIntegrations(): Promise { + return core.http.get(ROUTES_REPLACEMENT_CUSTOM_INTEGRATIONS); + }, + async getAppendCustomIntegrations(): Promise { - return core.http.get(ROUTES_ADDABLECUSTOMINTEGRATIONS); + return core.http.get(ROUTES_APPEND_CUSTOM_INTEGRATIONS); }, - } as CustomIntegrationsSetup; + }; } public start(core: CoreStart): CustomIntegrationsStart { diff --git a/src/plugins/custom_integrations/public/types.ts b/src/plugins/custom_integrations/public/types.ts index 911194171b4c4..9a12af767ecbc 100755 --- a/src/plugins/custom_integrations/public/types.ts +++ b/src/plugins/custom_integrations/public/types.ts @@ -10,6 +10,7 @@ import { CustomIntegration } from '../common'; export interface CustomIntegrationsSetup { getAppendCustomIntegrations: () => Promise; + getReplacementCustomIntegrations: () => Promise; } // eslint-disable-next-line @typescript-eslint/no-empty-interface export interface CustomIntegrationsStart {} diff --git a/src/plugins/custom_integrations/server/custom_integration_registry.test.ts b/src/plugins/custom_integrations/server/custom_integration_registry.test.ts index 2e211cfb4c93d..8904aa8a257f6 100644 --- a/src/plugins/custom_integrations/server/custom_integration_registry.test.ts +++ b/src/plugins/custom_integrations/server/custom_integration_registry.test.ts @@ -8,7 +8,7 @@ import { CustomIntegrationRegistry } from './custom_integration_registry'; import { loggerMock, MockedLogger } from '@kbn/logging/mocks'; -import { CustomIntegration } from '../common'; +import { IntegrationCategory, CustomIntegration } from '../common'; describe('CustomIntegrationsRegistry', () => { let mockLogger: MockedLogger; @@ -44,6 +44,27 @@ describe('CustomIntegrationsRegistry', () => { expect(mockLogger.debug.mock.calls.length).toBe(1); }); }); + + test('should strip unsupported categories', () => { + const registry = new CustomIntegrationRegistry(mockLogger, true); + registry.registerCustomIntegration({ + ...integration, + categories: ['upload_file', 'foobar'] as IntegrationCategory[], + }); + expect(registry.getAppendCustomIntegrations()).toEqual([ + { + categories: ['upload_file'], + description: 'test integration', + icons: [], + id: 'foo', + isBeta: false, + shipper: 'tests', + title: 'Foo', + type: 'ui_link', + uiInternalPath: '/path/to/foo', + }, + ]); + }); }); describe('getAppendCustomCategories', () => { @@ -76,7 +97,7 @@ describe('CustomIntegrationsRegistry', () => { }, ]); }); - test('should ignore duplicate ids', () => { + test('should filter duplicate ids', () => { const registry = new CustomIntegrationRegistry(mockLogger, true); registry.registerCustomIntegration(integration); registry.registerCustomIntegration(integration); @@ -94,7 +115,7 @@ describe('CustomIntegrationsRegistry', () => { }, ]); }); - test('should ignore integrations without category', () => { + test('should filter integrations without category', () => { const registry = new CustomIntegrationRegistry(mockLogger, true); registry.registerCustomIntegration(integration); registry.registerCustomIntegration({ ...integration, id: 'bar', categories: [] }); @@ -113,5 +134,44 @@ describe('CustomIntegrationsRegistry', () => { }, ]); }); + + test('should filter integrations that need to replace EPR packages', () => { + const registry = new CustomIntegrationRegistry(mockLogger, true); + registry.registerCustomIntegration({ ...integration, id: 'bar', eprOverlap: 'aws' }); + expect(registry.getAppendCustomIntegrations()).toEqual([]); + }); + }); + + describe('getReplacementCustomIntegrations', () => { + test('should only return integrations with corresponding epr package ', () => { + const registry = new CustomIntegrationRegistry(mockLogger, true); + registry.registerCustomIntegration(integration); + registry.registerCustomIntegration({ ...integration, id: 'bar', eprOverlap: 'aws' }); + expect(registry.getReplacementCustomIntegrations()).toEqual([ + { + categories: ['upload_file'], + description: 'test integration', + icons: [], + id: 'bar', + isBeta: false, + shipper: 'tests', + title: 'Foo', + type: 'ui_link', + uiInternalPath: '/path/to/foo', + eprOverlap: 'aws', + }, + ]); + }); + + test('should filter registrations without valid categories', () => { + const registry = new CustomIntegrationRegistry(mockLogger, true); + registry.registerCustomIntegration({ + ...integration, + id: 'bar', + eprOverlap: 'aws', + categories: ['foobar'] as unknown as IntegrationCategory[], + }); + expect(registry.getReplacementCustomIntegrations()).toEqual([]); + }); }); }); diff --git a/src/plugins/custom_integrations/server/custom_integration_registry.ts b/src/plugins/custom_integrations/server/custom_integration_registry.ts index fa216ced5bd92..ba1b901b3fb29 100644 --- a/src/plugins/custom_integrations/server/custom_integration_registry.ts +++ b/src/plugins/custom_integrations/server/custom_integration_registry.ts @@ -7,10 +7,14 @@ */ import { Logger } from 'kibana/server'; -import { CustomIntegration } from '../common'; +import { IntegrationCategory, INTEGRATION_CATEGORY_DISPLAY, CustomIntegration } from '../common'; -function isAddable(integration: CustomIntegration) { - return integration.categories.length; +function isAddable(integration: CustomIntegration): boolean { + return !!integration.categories.length && !integration.eprOverlap; +} + +function isReplacement(integration: CustomIntegration): boolean { + return !!integration.categories.length && !!integration.eprOverlap; } export class CustomIntegrationRegistry { @@ -39,10 +43,20 @@ export class CustomIntegrationRegistry { return; } - this._integrations.push(customIntegration); + const allowedCategories: IntegrationCategory[] = (customIntegration.categories ?? []).filter( + (category) => { + return INTEGRATION_CATEGORY_DISPLAY.hasOwnProperty(category); + } + ) as IntegrationCategory[]; + + this._integrations.push({ ...customIntegration, categories: allowedCategories }); } getAppendCustomIntegrations(): CustomIntegration[] { return this._integrations.filter(isAddable); } + + getReplacementCustomIntegrations(): CustomIntegration[] { + return this._integrations.filter(isReplacement); + } } diff --git a/src/plugins/custom_integrations/server/index.ts b/src/plugins/custom_integrations/server/index.ts index 423a06009ac4b..490627ef90f8d 100755 --- a/src/plugins/custom_integrations/server/index.ts +++ b/src/plugins/custom_integrations/server/index.ts @@ -19,7 +19,7 @@ export function plugin(initializerContext: PluginInitializerContext) { export { CustomIntegrationsPluginSetup, CustomIntegrationsPluginStart } from './types'; -export type { Category, CategoryCount, CustomIntegration } from '../common'; +export type { IntegrationCategory, IntegrationCategoryCount, CustomIntegration } from '../common'; export const config = { schema: schema.object({}), diff --git a/src/plugins/custom_integrations/server/plugin.test.ts b/src/plugins/custom_integrations/server/plugin.test.ts index 08f68a70a3c70..424eedf0603cd 100644 --- a/src/plugins/custom_integrations/server/plugin.test.ts +++ b/src/plugins/custom_integrations/server/plugin.test.ts @@ -25,7 +25,6 @@ describe('CustomIntegrationsPlugin', () => { test('wires up tutorials provider service and returns registerTutorial and addScopedTutorialContextFactory', () => { const setup = new CustomIntegrationsPlugin(initContext).setup(mockCoreSetup); expect(setup).toHaveProperty('registerCustomIntegration'); - expect(setup).toHaveProperty('getAppendCustomIntegrations'); }); }); }); diff --git a/src/plugins/custom_integrations/server/plugin.ts b/src/plugins/custom_integrations/server/plugin.ts index f1ddd70b6945a..099650ee15a05 100755 --- a/src/plugins/custom_integrations/server/plugin.ts +++ b/src/plugins/custom_integrations/server/plugin.ts @@ -40,9 +40,6 @@ export class CustomIntegrationsPlugin ...integration, }); }, - getAppendCustomIntegrations: (): CustomIntegration[] => { - return this.customIngegrationRegistry.getAppendCustomIntegrations(); - }, } as CustomIntegrationsPluginSetup; } diff --git a/src/plugins/custom_integrations/server/routes/define_routes.ts b/src/plugins/custom_integrations/server/routes/define_routes.ts index f5e952a0c1ebd..77ec49363dc8f 100644 --- a/src/plugins/custom_integrations/server/routes/define_routes.ts +++ b/src/plugins/custom_integrations/server/routes/define_routes.ts @@ -8,7 +8,10 @@ import { IRouter } from 'src/core/server'; import { CustomIntegrationRegistry } from '../custom_integration_registry'; -import { ROUTES_ADDABLECUSTOMINTEGRATIONS } from '../../common'; +import { + ROUTES_APPEND_CUSTOM_INTEGRATIONS, + ROUTES_REPLACEMENT_CUSTOM_INTEGRATIONS, +} from '../../common'; export function defineRoutes( router: IRouter, @@ -16,7 +19,7 @@ export function defineRoutes( ) { router.get( { - path: ROUTES_ADDABLECUSTOMINTEGRATIONS, + path: ROUTES_APPEND_CUSTOM_INTEGRATIONS, validate: false, }, async (context, request, response) => { @@ -26,4 +29,17 @@ export function defineRoutes( }); } ); + + router.get( + { + path: ROUTES_REPLACEMENT_CUSTOM_INTEGRATIONS, + validate: false, + }, + async (context, request, response) => { + const integrations = customIntegrationsRegistry.getReplacementCustomIntegrations(); + return response.ok({ + body: integrations, + }); + } + ); } diff --git a/src/plugins/discover/public/__mocks__/services.ts b/src/plugins/discover/public/__mocks__/services.ts index d24aefb6c8192..30d66b113e528 100644 --- a/src/plugins/discover/public/__mocks__/services.ts +++ b/src/plugins/discover/public/__mocks__/services.ts @@ -89,4 +89,7 @@ export const discoverServiceMock = { useChartsTheme: jest.fn(() => EUI_CHARTS_THEME_LIGHT.theme), useChartsBaseTheme: jest.fn(() => EUI_CHARTS_THEME_LIGHT.theme), }, + storage: { + get: jest.fn(), + }, } as unknown as DiscoverServices; diff --git a/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.test.tsx b/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.test.tsx index 7b2825907ba29..6ebed3185e2f1 100644 --- a/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.test.tsx +++ b/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.test.tsx @@ -10,7 +10,7 @@ import React from 'react'; import { Subject, BehaviorSubject } from 'rxjs'; import { mountWithIntl } from '@kbn/test/jest'; import { setHeaderActionMenuMounter } from '../../../../../kibana_services'; -import { DiscoverLayout } from './discover_layout'; +import { DiscoverLayout, SIDEBAR_CLOSED_KEY } from './discover_layout'; import { esHits } from '../../../../../__mocks__/es_hits'; import { indexPatternMock } from '../../../../../__mocks__/index_pattern'; import { savedSearchMock } from '../../../../../__mocks__/saved_search'; @@ -31,15 +31,21 @@ import { FetchStatus } from '../../../../types'; import { ElasticSearchHit } from '../../../../doc_views/doc_views_types'; import { RequestAdapter } from '../../../../../../../inspector'; import { Chart } from '../chart/point_series'; +import { DiscoverSidebar } from '../sidebar/discover_sidebar'; setHeaderActionMenuMounter(jest.fn()); -function getProps(indexPattern: IndexPattern): DiscoverLayoutProps { +function getProps(indexPattern: IndexPattern, wasSidebarClosed?: boolean): DiscoverLayoutProps { const searchSourceMock = createSearchSourceMock({}); const services = discoverServiceMock; services.data.query.timefilter.timefilter.getAbsoluteTime = () => { return { from: '2020-05-14T11:05:13.590', to: '2020-05-14T11:20:13.590' }; }; + services.storage.get = (key: string) => { + if (key === SIDEBAR_CLOSED_KEY) { + return wasSidebarClosed; + } + }; const indexPatternList = [indexPattern].map((ip) => { return { ...ip, ...{ attributes: { title: ip.title } } }; @@ -139,10 +145,34 @@ describe('Discover component', () => { const component = mountWithIntl(); expect(component.find('[data-test-subj="discoverChartOptionsToggle"]').exists()).toBeFalsy(); }); + test('selected index pattern with time field displays chart toggle', () => { const component = mountWithIntl( ); expect(component.find('[data-test-subj="discoverChartOptionsToggle"]').exists()).toBeTruthy(); }); + + describe('sidebar', () => { + test('should be opened if discover:sidebarClosed was not set', () => { + const component = mountWithIntl( + + ); + expect(component.find(DiscoverSidebar).length).toBe(1); + }); + + test('should be opened if discover:sidebarClosed is false', () => { + const component = mountWithIntl( + + ); + expect(component.find(DiscoverSidebar).length).toBe(1); + }); + + test('should be closed if discover:sidebarClosed is true', () => { + const component = mountWithIntl( + + ); + expect(component.find(DiscoverSidebar).length).toBe(0); + }); + }); }); diff --git a/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx b/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx index c2d09f31e3e0a..4bbef32dcbadd 100644 --- a/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx +++ b/src/plugins/discover/public/application/apps/main/components/layout/discover_layout.tsx @@ -40,6 +40,11 @@ import { DiscoverDocuments } from './discover_documents'; import { FetchStatus } from '../../../../types'; import { useDataState } from '../../utils/use_data_state'; +/** + * Local storage key for sidebar persistence state + */ +export const SIDEBAR_CLOSED_KEY = 'discover:sidebarClosed'; + const SidebarMemoized = React.memo(DiscoverSidebarResponsive); const TopNavMemoized = React.memo(DiscoverTopNav); const DiscoverChartMemoized = React.memo(DiscoverChart); @@ -60,7 +65,8 @@ export function DiscoverLayout({ state, stateContainer, }: DiscoverLayoutProps) { - const { trackUiMetric, capabilities, indexPatterns, data, uiSettings, filterManager } = services; + const { trackUiMetric, capabilities, indexPatterns, data, uiSettings, filterManager, storage } = + services; const { main$, charts$, totalHits$ } = savedSearchData$; const [expandedDoc, setExpandedDoc] = useState(undefined); @@ -78,7 +84,8 @@ export function DiscoverLayout({ return indexPattern.type !== 'rollup' ? indexPattern.timeFieldName : undefined; }, [indexPattern]); - const [isSidebarClosed, setIsSidebarClosed] = useState(false); + const initialSidebarClosed = Boolean(storage.get(SIDEBAR_CLOSED_KEY)); + const [isSidebarClosed, setIsSidebarClosed] = useState(initialSidebarClosed); const useNewFieldsApi = useMemo(() => !uiSettings.get(SEARCH_FIELDS_FROM_SOURCE), [uiSettings]); const resultState = useMemo( @@ -144,6 +151,11 @@ export function DiscoverLayout({ filterManager.setFilters(disabledFilters); }, [filterManager]); + const toggleSidebarCollapse = useCallback(() => { + storage.set(SIDEBAR_CLOSED_KEY, !isSidebarClosed); + setIsSidebarClosed(!isSidebarClosed); + }, [isSidebarClosed, storage]); + const contentCentered = resultState === 'uninitialized' || resultState === 'none'; return ( @@ -192,7 +204,7 @@ export function DiscoverLayout({ iconType={isSidebarClosed ? 'menuRight' : 'menuLeft'} iconSize="m" size="xs" - onClick={() => setIsSidebarClosed(!isSidebarClosed)} + onClick={toggleSidebarCollapse} data-test-subj="collapseSideBarButton" aria-controls="discover-sidebar" aria-expanded={isSidebarClosed ? 'false' : 'true'} diff --git a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx b/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx index ade9c3aae4b28..90357b73c6881 100644 --- a/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx +++ b/src/plugins/discover/public/application/apps/main/components/sidebar/discover_sidebar_responsive.tsx @@ -217,7 +217,7 @@ export function DiscoverSidebarResponsive(props: DiscoverSidebarResponsiveProps) return ( <> - {props.isClosed ? null : ( + {!props.isClosed && ( void; indexPatternFieldEditor: IndexPatternFieldEditorStart; http: HttpStart; + storage: Storage; } export function buildServices( @@ -75,6 +77,7 @@ export function buildServices( }; const savedObjectService = createSavedSearchesLoader(services); const { usageCollection } = plugins; + const storage = new Storage(localStorage); return { addBasePath: core.http.basePath.prepend, @@ -100,6 +103,7 @@ export function buildServices( timefilter: plugins.data.query.timefilter.timefilter, toastNotifications: core.notifications.toasts, uiSettings: core.uiSettings, + storage, trackUiMetric: usageCollection?.reportUiCounter.bind(usageCollection, 'discover'), indexPatternFieldEditor: plugins.indexPatternFieldEditor, http: core.http, diff --git a/src/plugins/home/server/plugin.test.ts b/src/plugins/home/server/plugin.test.ts index 2dc8a8e6484aa..5af0c4a578eeb 100644 --- a/src/plugins/home/server/plugin.test.ts +++ b/src/plugins/home/server/plugin.test.ts @@ -77,7 +77,7 @@ describe('HomeServerPlugin', () => { test('is defined', () => { const plugin = new HomeServerPlugin(initContext); plugin.setup(mockCoreSetup, homeServerPluginSetupDependenciesMock); // setup() must always be called before start() - const start = plugin.start(); + const start = plugin.start(coreMock.createStart()); expect(start).toBeDefined(); expect(start).toHaveProperty('tutorials'); expect(start).toHaveProperty('sampleData'); diff --git a/src/plugins/home/server/plugin.ts b/src/plugins/home/server/plugin.ts index 5902544d9867f..98f7611655e55 100644 --- a/src/plugins/home/server/plugin.ts +++ b/src/plugins/home/server/plugin.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { CoreSetup, Plugin, PluginInitializerContext } from 'kibana/server'; +import { CoreSetup, CoreStart, Plugin, PluginInitializerContext } from 'kibana/server'; import { TutorialsRegistry, TutorialsRegistrySetup, @@ -30,8 +30,11 @@ export class HomeServerPlugin implements Plugin; diff --git a/src/plugins/home/server/services/tutorials/tutorials_registry.test.ts b/src/plugins/home/server/services/tutorials/tutorials_registry.test.ts index 15372949b1653..ee73c8e13f62b 100644 --- a/src/plugins/home/server/services/tutorials/tutorials_registry.test.ts +++ b/src/plugins/home/server/services/tutorials/tutorials_registry.test.ts @@ -149,7 +149,10 @@ describe('TutorialsRegistry', () => { describe('start', () => { test('exposes proper contract', () => { - const start = new TutorialsRegistry().start(); + const start = new TutorialsRegistry().start( + coreMock.createStart(), + mockCustomIntegrationsPluginSetup + ); expect(start).toBeDefined(); }); }); diff --git a/src/plugins/home/server/services/tutorials/tutorials_registry.ts b/src/plugins/home/server/services/tutorials/tutorials_registry.ts index 8f7ecd7d7ccf5..723c92e6dfaf4 100644 --- a/src/plugins/home/server/services/tutorials/tutorials_registry.ts +++ b/src/plugins/home/server/services/tutorials/tutorials_registry.ts @@ -6,7 +6,7 @@ * Side Public License, v 1. */ -import { CoreSetup } from 'src/core/server'; +import { CoreSetup, CoreStart } from 'src/core/server'; import { TutorialProvider, TutorialContextFactory, @@ -15,23 +15,17 @@ import { import { TutorialSchema, tutorialSchema } from './lib/tutorial_schema'; import { builtInTutorials } from '../../tutorials/register'; import { CustomIntegrationsPluginSetup } from '../../../../custom_integrations/server'; -import { Category, CATEGORY_DISPLAY } from '../../../../custom_integrations/common'; +import { IntegrationCategory } from '../../../../custom_integrations/common'; import { HOME_APP_BASE_PATH } from '../../../common/constants'; function registerTutorialWithCustomIntegrations( customIntegrations: CustomIntegrationsPluginSetup, tutorial: TutorialSchema ) { - const allowedCategories: Category[] = (tutorial.integrationBrowserCategories ?? []).filter( - (category) => { - return CATEGORY_DISPLAY.hasOwnProperty(category); - } - ) as Category[]; - customIntegrations.registerCustomIntegration({ id: tutorial.id, title: tutorial.name, - categories: allowedCategories, + categories: (tutorial.integrationBrowserCategories ?? []) as IntegrationCategory[], uiInternalPath: `${HOME_APP_BASE_PATH}#/tutorial/${tutorial.id}`, description: tutorial.shortDescription, icons: tutorial.euiIconType @@ -44,6 +38,32 @@ function registerTutorialWithCustomIntegrations( : [], shipper: 'tutorial', isBeta: false, + eprOverlap: tutorial.eprPackageOverlap, + }); +} + +function registerBeatsTutorialsWithCustomIntegrations( + core: CoreStart, + customIntegrations: CustomIntegrationsPluginSetup, + tutorial: TutorialSchema +) { + customIntegrations.registerCustomIntegration({ + id: tutorial.name, + title: tutorial.name, + categories: tutorial.integrationBrowserCategories as IntegrationCategory[], + uiInternalPath: `${HOME_APP_BASE_PATH}#/tutorial/${tutorial.id}`, + description: tutorial.shortDescription, + icons: tutorial.euiIconType + ? [ + { + type: tutorial.euiIconType.endsWith('svg') ? 'svg' : 'eui', + src: core.http.basePath.prepend(tutorial.euiIconType), + }, + ] + : [], + shipper: 'beats', + eprOverlap: tutorial.moduleName, + isBeta: false, }); } @@ -106,9 +126,16 @@ export class TutorialsRegistry { }; } - public start() { + public start(core: CoreStart, customIntegrations?: CustomIntegrationsPluginSetup) { // pre-populate with built in tutorials this.tutorialProviders.push(...builtInTutorials); + + if (customIntegrations) { + builtInTutorials.forEach((provider) => { + const tutorial = provider({}); + registerBeatsTutorialsWithCustomIntegrations(core, customIntegrations, tutorial); + }); + } return {}; } } diff --git a/src/plugins/home/server/tutorials/activemq_logs/index.ts b/src/plugins/home/server/tutorials/activemq_logs/index.ts index b1f9ee429473d..64a6fa575f5b6 100644 --- a/src/plugins/home/server/tutorials/activemq_logs/index.ts +++ b/src/plugins/home/server/tutorials/activemq_logs/index.ts @@ -58,5 +58,6 @@ export function activemqLogsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['web'], }; } diff --git a/src/plugins/home/server/tutorials/activemq_metrics/index.ts b/src/plugins/home/server/tutorials/activemq_metrics/index.ts index 49e27b7ce981c..7a59d6d4b70d1 100644 --- a/src/plugins/home/server/tutorials/activemq_metrics/index.ts +++ b/src/plugins/home/server/tutorials/activemq_metrics/index.ts @@ -56,5 +56,7 @@ export function activemqMetricsSpecProvider(context: TutorialContext): TutorialS onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + + integrationBrowserCategories: ['web'], }; } diff --git a/src/plugins/home/server/tutorials/aerospike_metrics/index.ts b/src/plugins/home/server/tutorials/aerospike_metrics/index.ts index 27246b78b1d6b..75dd45272db69 100644 --- a/src/plugins/home/server/tutorials/aerospike_metrics/index.ts +++ b/src/plugins/home/server/tutorials/aerospike_metrics/index.ts @@ -56,5 +56,6 @@ export function aerospikeMetricsSpecProvider(context: TutorialContext): Tutorial onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['web'], }; } diff --git a/src/plugins/home/server/tutorials/apache_logs/index.ts b/src/plugins/home/server/tutorials/apache_logs/index.ts index 06d2035ee4713..8606a40fe0a23 100644 --- a/src/plugins/home/server/tutorials/apache_logs/index.ts +++ b/src/plugins/home/server/tutorials/apache_logs/index.ts @@ -59,5 +59,6 @@ export function apacheLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['web'], }; } diff --git a/src/plugins/home/server/tutorials/apache_metrics/index.ts b/src/plugins/home/server/tutorials/apache_metrics/index.ts index e94f64ce1f058..f013f3da737f0 100644 --- a/src/plugins/home/server/tutorials/apache_metrics/index.ts +++ b/src/plugins/home/server/tutorials/apache_metrics/index.ts @@ -58,5 +58,6 @@ export function apacheMetricsSpecProvider(context: TutorialContext): TutorialSch onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['web'], }; } diff --git a/src/plugins/home/server/tutorials/auditbeat/index.ts b/src/plugins/home/server/tutorials/auditbeat/index.ts index dd51f0e512a5b..8bd6450b1daa4 100644 --- a/src/plugins/home/server/tutorials/auditbeat/index.ts +++ b/src/plugins/home/server/tutorials/auditbeat/index.ts @@ -58,5 +58,6 @@ processes, users, logins, sockets information, file accesses, and more. \ onPrem: onPremInstructions(platforms, context), elasticCloud: cloudInstructions(platforms), onPremElasticCloud: onPremCloudInstructions(platforms), + integrationBrowserCategories: ['web'], }; } diff --git a/src/plugins/home/server/tutorials/auditd_logs/index.ts b/src/plugins/home/server/tutorials/auditd_logs/index.ts index 5e1cea86ccfa7..a0d6f5f683e2c 100644 --- a/src/plugins/home/server/tutorials/auditd_logs/index.ts +++ b/src/plugins/home/server/tutorials/auditd_logs/index.ts @@ -59,5 +59,6 @@ export function auditdLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['os_system'], }; } diff --git a/src/plugins/home/server/tutorials/aws_logs/index.ts b/src/plugins/home/server/tutorials/aws_logs/index.ts index 12eac20d5e4dc..3458800b33f0a 100644 --- a/src/plugins/home/server/tutorials/aws_logs/index.ts +++ b/src/plugins/home/server/tutorials/aws_logs/index.ts @@ -59,5 +59,6 @@ export function awsLogsSpecProvider(context: TutorialContext): TutorialSchema { onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['aws', 'cloud', 'datastore', 'security', 'network'], }; } diff --git a/src/plugins/home/server/tutorials/aws_metrics/index.ts b/src/plugins/home/server/tutorials/aws_metrics/index.ts index 2d4e10290affd..7c3a15a47d784 100644 --- a/src/plugins/home/server/tutorials/aws_metrics/index.ts +++ b/src/plugins/home/server/tutorials/aws_metrics/index.ts @@ -60,5 +60,6 @@ export function awsMetricsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['aws', 'cloud', 'datastore', 'security', 'network'], }; } diff --git a/src/plugins/home/server/tutorials/azure_logs/index.ts b/src/plugins/home/server/tutorials/azure_logs/index.ts index 8d8b1f2813c6a..2bf1527a79c40 100644 --- a/src/plugins/home/server/tutorials/azure_logs/index.ts +++ b/src/plugins/home/server/tutorials/azure_logs/index.ts @@ -60,5 +60,6 @@ export function azureLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['azure', 'cloud', 'network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/azure_metrics/index.ts b/src/plugins/home/server/tutorials/azure_metrics/index.ts index 9dff3956b745f..4a6112510b333 100644 --- a/src/plugins/home/server/tutorials/azure_metrics/index.ts +++ b/src/plugins/home/server/tutorials/azure_metrics/index.ts @@ -59,5 +59,6 @@ export function azureMetricsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['azure', 'cloud', 'network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/barracuda_logs/index.ts b/src/plugins/home/server/tutorials/barracuda_logs/index.ts index c85e92d884f93..35ce10e00892e 100644 --- a/src/plugins/home/server/tutorials/barracuda_logs/index.ts +++ b/src/plugins/home/server/tutorials/barracuda_logs/index.ts @@ -56,5 +56,6 @@ export function barracudaLogsSpecProvider(context: TutorialContext): TutorialSch onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/bluecoat_logs/index.ts b/src/plugins/home/server/tutorials/bluecoat_logs/index.ts index b9a0eb6459b99..85c7dff85d3e6 100644 --- a/src/plugins/home/server/tutorials/bluecoat_logs/index.ts +++ b/src/plugins/home/server/tutorials/bluecoat_logs/index.ts @@ -56,5 +56,6 @@ export function bluecoatLogsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/cef_logs/index.ts b/src/plugins/home/server/tutorials/cef_logs/index.ts index 4204614fadc58..cfd267f661d2a 100644 --- a/src/plugins/home/server/tutorials/cef_logs/index.ts +++ b/src/plugins/home/server/tutorials/cef_logs/index.ts @@ -63,5 +63,6 @@ export function cefLogsSpecProvider(context: TutorialContext): TutorialSchema { onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/ceph_metrics/index.ts b/src/plugins/home/server/tutorials/ceph_metrics/index.ts index 41e47655656ac..821067d87c905 100644 --- a/src/plugins/home/server/tutorials/ceph_metrics/index.ts +++ b/src/plugins/home/server/tutorials/ceph_metrics/index.ts @@ -56,5 +56,6 @@ export function cephMetricsSpecProvider(context: TutorialContext): TutorialSchem onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/checkpoint_logs/index.ts b/src/plugins/home/server/tutorials/checkpoint_logs/index.ts index 7171b09b02492..9c0d5591ae35b 100644 --- a/src/plugins/home/server/tutorials/checkpoint_logs/index.ts +++ b/src/plugins/home/server/tutorials/checkpoint_logs/index.ts @@ -56,5 +56,6 @@ export function checkpointLogsSpecProvider(context: TutorialContext): TutorialSc onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/cisco_logs/index.ts b/src/plugins/home/server/tutorials/cisco_logs/index.ts index f2b21013037bb..50b79f448b316 100644 --- a/src/plugins/home/server/tutorials/cisco_logs/index.ts +++ b/src/plugins/home/server/tutorials/cisco_logs/index.ts @@ -59,5 +59,6 @@ export function ciscoLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/cloudwatch_logs/index.ts b/src/plugins/home/server/tutorials/cloudwatch_logs/index.ts index 41928a072aa6e..dd035a66c5ced 100644 --- a/src/plugins/home/server/tutorials/cloudwatch_logs/index.ts +++ b/src/plugins/home/server/tutorials/cloudwatch_logs/index.ts @@ -53,5 +53,6 @@ export function cloudwatchLogsSpecProvider(context: TutorialContext): TutorialSc onPrem: onPremInstructions([], context), elasticCloud: cloudInstructions(), onPremElasticCloud: onPremCloudInstructions(), + integrationBrowserCategories: ['security', 'network', 'web'], }; } diff --git a/src/plugins/home/server/tutorials/cockroachdb_metrics/index.ts b/src/plugins/home/server/tutorials/cockroachdb_metrics/index.ts index a6ed3ad22ff7f..e43d05a0a098f 100644 --- a/src/plugins/home/server/tutorials/cockroachdb_metrics/index.ts +++ b/src/plugins/home/server/tutorials/cockroachdb_metrics/index.ts @@ -61,5 +61,6 @@ export function cockroachdbMetricsSpecProvider(context: TutorialContext): Tutori onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['security', 'network', 'web'], }; } diff --git a/src/plugins/home/server/tutorials/consul_metrics/index.ts b/src/plugins/home/server/tutorials/consul_metrics/index.ts index fd82227f01fcb..915920db5882c 100644 --- a/src/plugins/home/server/tutorials/consul_metrics/index.ts +++ b/src/plugins/home/server/tutorials/consul_metrics/index.ts @@ -58,5 +58,6 @@ export function consulMetricsSpecProvider(context: TutorialContext): TutorialSch onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['security', 'network', 'web'], }; } diff --git a/src/plugins/home/server/tutorials/coredns_logs/index.ts b/src/plugins/home/server/tutorials/coredns_logs/index.ts index 48b9154b81f4b..298464651f7fc 100644 --- a/src/plugins/home/server/tutorials/coredns_logs/index.ts +++ b/src/plugins/home/server/tutorials/coredns_logs/index.ts @@ -59,5 +59,6 @@ export function corednsLogsSpecProvider(context: TutorialContext): TutorialSchem onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security', 'network', 'web'], }; } diff --git a/src/plugins/home/server/tutorials/coredns_metrics/index.ts b/src/plugins/home/server/tutorials/coredns_metrics/index.ts index 50c0e5d46f86a..34912efb31a81 100644 --- a/src/plugins/home/server/tutorials/coredns_metrics/index.ts +++ b/src/plugins/home/server/tutorials/coredns_metrics/index.ts @@ -56,5 +56,6 @@ export function corednsMetricsSpecProvider(context: TutorialContext): TutorialSc onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['security', 'network', 'web'], }; } diff --git a/src/plugins/home/server/tutorials/couchbase_metrics/index.ts b/src/plugins/home/server/tutorials/couchbase_metrics/index.ts index de8c306480774..1860991fd17b2 100644 --- a/src/plugins/home/server/tutorials/couchbase_metrics/index.ts +++ b/src/plugins/home/server/tutorials/couchbase_metrics/index.ts @@ -56,5 +56,6 @@ export function couchbaseMetricsSpecProvider(context: TutorialContext): Tutorial onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['security', 'network', 'web'], }; } diff --git a/src/plugins/home/server/tutorials/couchdb_metrics/index.ts b/src/plugins/home/server/tutorials/couchdb_metrics/index.ts index d4f4f2c5bc04c..a6c57f56cf2e1 100644 --- a/src/plugins/home/server/tutorials/couchdb_metrics/index.ts +++ b/src/plugins/home/server/tutorials/couchdb_metrics/index.ts @@ -61,5 +61,6 @@ export function couchdbMetricsSpecProvider(context: TutorialContext): TutorialSc onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['security', 'network', 'web'], }; } diff --git a/src/plugins/home/server/tutorials/crowdstrike_logs/index.ts b/src/plugins/home/server/tutorials/crowdstrike_logs/index.ts index a61ad14f9793a..baaaef50a641f 100644 --- a/src/plugins/home/server/tutorials/crowdstrike_logs/index.ts +++ b/src/plugins/home/server/tutorials/crowdstrike_logs/index.ts @@ -59,5 +59,6 @@ export function crowdstrikeLogsSpecProvider(context: TutorialContext): TutorialS onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/cylance_logs/index.ts b/src/plugins/home/server/tutorials/cylance_logs/index.ts index 489e2c49d765e..9766f417b8870 100644 --- a/src/plugins/home/server/tutorials/cylance_logs/index.ts +++ b/src/plugins/home/server/tutorials/cylance_logs/index.ts @@ -56,5 +56,6 @@ export function cylanceLogsSpecProvider(context: TutorialContext): TutorialSchem onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/docker_metrics/index.ts b/src/plugins/home/server/tutorials/docker_metrics/index.ts index 9b4dd919b338b..6a8687ef5d66e 100644 --- a/src/plugins/home/server/tutorials/docker_metrics/index.ts +++ b/src/plugins/home/server/tutorials/docker_metrics/index.ts @@ -58,5 +58,6 @@ export function dockerMetricsSpecProvider(context: TutorialContext): TutorialSch onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['containers', 'os_system'], }; } diff --git a/src/plugins/home/server/tutorials/dropwizard_metrics/index.ts b/src/plugins/home/server/tutorials/dropwizard_metrics/index.ts index 6283147bc3bac..86be26dd12ca7 100644 --- a/src/plugins/home/server/tutorials/dropwizard_metrics/index.ts +++ b/src/plugins/home/server/tutorials/dropwizard_metrics/index.ts @@ -56,5 +56,6 @@ export function dropwizardMetricsSpecProvider(context: TutorialContext): Tutoria onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['elastic_stack', 'datastore'], }; } diff --git a/src/plugins/home/server/tutorials/elasticsearch_logs/index.ts b/src/plugins/home/server/tutorials/elasticsearch_logs/index.ts index 94e904eb33247..1886a912fdcd2 100644 --- a/src/plugins/home/server/tutorials/elasticsearch_logs/index.ts +++ b/src/plugins/home/server/tutorials/elasticsearch_logs/index.ts @@ -58,5 +58,6 @@ export function elasticsearchLogsSpecProvider(context: TutorialContext): Tutoria onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['containers', 'os_system'], }; } diff --git a/src/plugins/home/server/tutorials/elasticsearch_metrics/index.ts b/src/plugins/home/server/tutorials/elasticsearch_metrics/index.ts index 48fa3491e43b6..2adc2fd90fa70 100644 --- a/src/plugins/home/server/tutorials/elasticsearch_metrics/index.ts +++ b/src/plugins/home/server/tutorials/elasticsearch_metrics/index.ts @@ -56,5 +56,6 @@ export function elasticsearchMetricsSpecProvider(context: TutorialContext): Tuto onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['elastic_stack', 'datastore'], }; } diff --git a/src/plugins/home/server/tutorials/envoyproxy_logs/index.ts b/src/plugins/home/server/tutorials/envoyproxy_logs/index.ts index 74add28c1ae74..fda69a2467b25 100644 --- a/src/plugins/home/server/tutorials/envoyproxy_logs/index.ts +++ b/src/plugins/home/server/tutorials/envoyproxy_logs/index.ts @@ -62,5 +62,6 @@ export function envoyproxyLogsSpecProvider(context: TutorialContext): TutorialSc onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['elastic_stack', 'datastore'], }; } diff --git a/src/plugins/home/server/tutorials/envoyproxy_metrics/index.ts b/src/plugins/home/server/tutorials/envoyproxy_metrics/index.ts index 18d3dfae392e7..263d1a2036fd0 100644 --- a/src/plugins/home/server/tutorials/envoyproxy_metrics/index.ts +++ b/src/plugins/home/server/tutorials/envoyproxy_metrics/index.ts @@ -49,5 +49,6 @@ export function envoyproxyMetricsSpecProvider(context: TutorialContext): Tutoria onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['elastic_stack', 'datastore'], }; } diff --git a/src/plugins/home/server/tutorials/etcd_metrics/index.ts b/src/plugins/home/server/tutorials/etcd_metrics/index.ts index 288124c1efbe9..cda16ecf68e34 100644 --- a/src/plugins/home/server/tutorials/etcd_metrics/index.ts +++ b/src/plugins/home/server/tutorials/etcd_metrics/index.ts @@ -56,5 +56,6 @@ export function etcdMetricsSpecProvider(context: TutorialContext): TutorialSchem onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['elastic_stack', 'datastore'], }; } diff --git a/src/plugins/home/server/tutorials/f5_logs/index.ts b/src/plugins/home/server/tutorials/f5_logs/index.ts index 976c207305376..ebcdd4ece7f45 100644 --- a/src/plugins/home/server/tutorials/f5_logs/index.ts +++ b/src/plugins/home/server/tutorials/f5_logs/index.ts @@ -57,5 +57,6 @@ export function f5LogsSpecProvider(context: TutorialContext): TutorialSchema { onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/fortinet_logs/index.ts b/src/plugins/home/server/tutorials/fortinet_logs/index.ts index 250e873d037b5..3e7923b680c6e 100644 --- a/src/plugins/home/server/tutorials/fortinet_logs/index.ts +++ b/src/plugins/home/server/tutorials/fortinet_logs/index.ts @@ -56,5 +56,6 @@ export function fortinetLogsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/gcp_logs/index.ts b/src/plugins/home/server/tutorials/gcp_logs/index.ts index 6aa6adb183418..feef7d673c5d9 100644 --- a/src/plugins/home/server/tutorials/gcp_logs/index.ts +++ b/src/plugins/home/server/tutorials/gcp_logs/index.ts @@ -61,5 +61,6 @@ export function gcpLogsSpecProvider(context: TutorialContext): TutorialSchema { onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['google_cloud', 'cloud', 'network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/gcp_metrics/index.ts b/src/plugins/home/server/tutorials/gcp_metrics/index.ts index 8416ab105de96..5f198ed5f3cf2 100644 --- a/src/plugins/home/server/tutorials/gcp_metrics/index.ts +++ b/src/plugins/home/server/tutorials/gcp_metrics/index.ts @@ -60,5 +60,6 @@ export function gcpMetricsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['google_cloud', 'cloud', 'network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/golang_metrics/index.ts b/src/plugins/home/server/tutorials/golang_metrics/index.ts index 1d298fd294a3e..85937e0dda0e0 100644 --- a/src/plugins/home/server/tutorials/golang_metrics/index.ts +++ b/src/plugins/home/server/tutorials/golang_metrics/index.ts @@ -59,5 +59,6 @@ export function golangMetricsSpecProvider(context: TutorialContext): TutorialSch onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['google_cloud', 'cloud', 'network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/gsuite_logs/index.ts b/src/plugins/home/server/tutorials/gsuite_logs/index.ts index 2973af4b969c7..4d23c6b1cfdce 100644 --- a/src/plugins/home/server/tutorials/gsuite_logs/index.ts +++ b/src/plugins/home/server/tutorials/gsuite_logs/index.ts @@ -56,5 +56,6 @@ export function gsuiteLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/haproxy_logs/index.ts b/src/plugins/home/server/tutorials/haproxy_logs/index.ts index 9aa853af7819e..0b0fd35f07058 100644 --- a/src/plugins/home/server/tutorials/haproxy_logs/index.ts +++ b/src/plugins/home/server/tutorials/haproxy_logs/index.ts @@ -59,5 +59,6 @@ export function haproxyLogsSpecProvider(context: TutorialContext): TutorialSchem onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network', 'web'], }; } diff --git a/src/plugins/home/server/tutorials/haproxy_metrics/index.ts b/src/plugins/home/server/tutorials/haproxy_metrics/index.ts index a6953808871fa..e37f0ffc4b916 100644 --- a/src/plugins/home/server/tutorials/haproxy_metrics/index.ts +++ b/src/plugins/home/server/tutorials/haproxy_metrics/index.ts @@ -56,5 +56,6 @@ export function haproxyMetricsSpecProvider(context: TutorialContext): TutorialSc onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['network', 'web'], }; } diff --git a/src/plugins/home/server/tutorials/ibmmq_logs/index.ts b/src/plugins/home/server/tutorials/ibmmq_logs/index.ts index a777443c5f9b8..646747d1a49f8 100644 --- a/src/plugins/home/server/tutorials/ibmmq_logs/index.ts +++ b/src/plugins/home/server/tutorials/ibmmq_logs/index.ts @@ -58,5 +58,6 @@ export function ibmmqLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/ibmmq_metrics/index.ts b/src/plugins/home/server/tutorials/ibmmq_metrics/index.ts index 2501aa81f0e30..3862bd9ca85eb 100644 --- a/src/plugins/home/server/tutorials/ibmmq_metrics/index.ts +++ b/src/plugins/home/server/tutorials/ibmmq_metrics/index.ts @@ -57,5 +57,6 @@ export function ibmmqMetricsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/icinga_logs/index.ts b/src/plugins/home/server/tutorials/icinga_logs/index.ts index b55023a77332f..0dae93b70343b 100644 --- a/src/plugins/home/server/tutorials/icinga_logs/index.ts +++ b/src/plugins/home/server/tutorials/icinga_logs/index.ts @@ -59,5 +59,6 @@ export function icingaLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/iis_logs/index.ts b/src/plugins/home/server/tutorials/iis_logs/index.ts index f87e87a6aa427..5393edf6ab148 100644 --- a/src/plugins/home/server/tutorials/iis_logs/index.ts +++ b/src/plugins/home/server/tutorials/iis_logs/index.ts @@ -59,5 +59,6 @@ export function iisLogsSpecProvider(context: TutorialContext): TutorialSchema { onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['web'], }; } diff --git a/src/plugins/home/server/tutorials/iis_metrics/index.ts b/src/plugins/home/server/tutorials/iis_metrics/index.ts index 56408beb2071f..dbfa474dc9c89 100644 --- a/src/plugins/home/server/tutorials/iis_metrics/index.ts +++ b/src/plugins/home/server/tutorials/iis_metrics/index.ts @@ -59,5 +59,6 @@ export function iisMetricsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['web'], }; } diff --git a/src/plugins/home/server/tutorials/imperva_logs/index.ts b/src/plugins/home/server/tutorials/imperva_logs/index.ts index 09ea5cf21ec21..71c3af3809e2e 100644 --- a/src/plugins/home/server/tutorials/imperva_logs/index.ts +++ b/src/plugins/home/server/tutorials/imperva_logs/index.ts @@ -56,5 +56,6 @@ export function impervaLogsSpecProvider(context: TutorialContext): TutorialSchem onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/infoblox_logs/index.ts b/src/plugins/home/server/tutorials/infoblox_logs/index.ts index 62769946067e5..5329444dfa85f 100644 --- a/src/plugins/home/server/tutorials/infoblox_logs/index.ts +++ b/src/plugins/home/server/tutorials/infoblox_logs/index.ts @@ -56,5 +56,6 @@ export function infobloxLogsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network'], }; } diff --git a/src/plugins/home/server/tutorials/iptables_logs/index.ts b/src/plugins/home/server/tutorials/iptables_logs/index.ts index b25604db39c0d..85faf169f8714 100644 --- a/src/plugins/home/server/tutorials/iptables_logs/index.ts +++ b/src/plugins/home/server/tutorials/iptables_logs/index.ts @@ -62,5 +62,6 @@ export function iptablesLogsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/juniper_logs/index.ts b/src/plugins/home/server/tutorials/juniper_logs/index.ts index f13f62d0d92e3..f9174d8a089e0 100644 --- a/src/plugins/home/server/tutorials/juniper_logs/index.ts +++ b/src/plugins/home/server/tutorials/juniper_logs/index.ts @@ -56,5 +56,6 @@ export function juniperLogsSpecProvider(context: TutorialContext): TutorialSchem onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/kafka_logs/index.ts b/src/plugins/home/server/tutorials/kafka_logs/index.ts index 13a4317761a86..5b877cadcbec6 100644 --- a/src/plugins/home/server/tutorials/kafka_logs/index.ts +++ b/src/plugins/home/server/tutorials/kafka_logs/index.ts @@ -59,5 +59,6 @@ export function kafkaLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['message_queue'], }; } diff --git a/src/plugins/home/server/tutorials/kafka_metrics/index.ts b/src/plugins/home/server/tutorials/kafka_metrics/index.ts index b6840cb69ec57..92f6744b91cbe 100644 --- a/src/plugins/home/server/tutorials/kafka_metrics/index.ts +++ b/src/plugins/home/server/tutorials/kafka_metrics/index.ts @@ -56,5 +56,6 @@ export function kafkaMetricsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['message_queue'], }; } diff --git a/src/plugins/home/server/tutorials/kibana_logs/index.ts b/src/plugins/home/server/tutorials/kibana_logs/index.ts index 27207de013dbd..988af821ef9e3 100644 --- a/src/plugins/home/server/tutorials/kibana_logs/index.ts +++ b/src/plugins/home/server/tutorials/kibana_logs/index.ts @@ -55,5 +55,6 @@ export function kibanaLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['message_queue'], }; } diff --git a/src/plugins/home/server/tutorials/kibana_metrics/index.ts b/src/plugins/home/server/tutorials/kibana_metrics/index.ts index 0e5e0c92e77e9..dfe4efe4f7337 100644 --- a/src/plugins/home/server/tutorials/kibana_metrics/index.ts +++ b/src/plugins/home/server/tutorials/kibana_metrics/index.ts @@ -56,5 +56,6 @@ export function kibanaMetricsSpecProvider(context: TutorialContext): TutorialSch onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['message_queue'], }; } diff --git a/src/plugins/home/server/tutorials/kubernetes_metrics/index.ts b/src/plugins/home/server/tutorials/kubernetes_metrics/index.ts index 48bc3c4b69e39..4a694560f5c28 100644 --- a/src/plugins/home/server/tutorials/kubernetes_metrics/index.ts +++ b/src/plugins/home/server/tutorials/kubernetes_metrics/index.ts @@ -61,5 +61,6 @@ export function kubernetesMetricsSpecProvider(context: TutorialContext): Tutoria onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['containers', 'kubernetes'], }; } diff --git a/src/plugins/home/server/tutorials/logstash_logs/index.ts b/src/plugins/home/server/tutorials/logstash_logs/index.ts index e41796b4b57bf..55491d45df28c 100644 --- a/src/plugins/home/server/tutorials/logstash_logs/index.ts +++ b/src/plugins/home/server/tutorials/logstash_logs/index.ts @@ -58,5 +58,6 @@ export function logstashLogsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['custom'], }; } diff --git a/src/plugins/home/server/tutorials/logstash_metrics/index.ts b/src/plugins/home/server/tutorials/logstash_metrics/index.ts index 0aa85745b0fa3..e7d3fae011bd2 100644 --- a/src/plugins/home/server/tutorials/logstash_metrics/index.ts +++ b/src/plugins/home/server/tutorials/logstash_metrics/index.ts @@ -57,5 +57,6 @@ export function logstashMetricsSpecProvider(context: TutorialContext): TutorialS onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['custom'], }; } diff --git a/src/plugins/home/server/tutorials/memcached_metrics/index.ts b/src/plugins/home/server/tutorials/memcached_metrics/index.ts index 5032130eed0b6..15df179b44a9e 100644 --- a/src/plugins/home/server/tutorials/memcached_metrics/index.ts +++ b/src/plugins/home/server/tutorials/memcached_metrics/index.ts @@ -56,5 +56,6 @@ export function memcachedMetricsSpecProvider(context: TutorialContext): Tutorial onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['custom'], }; } diff --git a/src/plugins/home/server/tutorials/microsoft_logs/index.ts b/src/plugins/home/server/tutorials/microsoft_logs/index.ts index ee860845c04b6..52401df1f9eb7 100644 --- a/src/plugins/home/server/tutorials/microsoft_logs/index.ts +++ b/src/plugins/home/server/tutorials/microsoft_logs/index.ts @@ -59,5 +59,6 @@ export function microsoftLogsSpecProvider(context: TutorialContext): TutorialSch onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network', 'security', 'azure'], }; } diff --git a/src/plugins/home/server/tutorials/misp_logs/index.ts b/src/plugins/home/server/tutorials/misp_logs/index.ts index 3c341f5ad1e93..b7611b543bab1 100644 --- a/src/plugins/home/server/tutorials/misp_logs/index.ts +++ b/src/plugins/home/server/tutorials/misp_logs/index.ts @@ -59,5 +59,6 @@ export function mispLogsSpecProvider(context: TutorialContext): TutorialSchema { onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network', 'security', 'azure'], }; } diff --git a/src/plugins/home/server/tutorials/mongodb_logs/index.ts b/src/plugins/home/server/tutorials/mongodb_logs/index.ts index 7b5ee10c1d5e0..3c189c04da43b 100644 --- a/src/plugins/home/server/tutorials/mongodb_logs/index.ts +++ b/src/plugins/home/server/tutorials/mongodb_logs/index.ts @@ -59,5 +59,6 @@ export function mongodbLogsSpecProvider(context: TutorialContext): TutorialSchem onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['datastore'], }; } diff --git a/src/plugins/home/server/tutorials/mongodb_metrics/index.ts b/src/plugins/home/server/tutorials/mongodb_metrics/index.ts index c7946309cb2d8..121310fba6f3a 100644 --- a/src/plugins/home/server/tutorials/mongodb_metrics/index.ts +++ b/src/plugins/home/server/tutorials/mongodb_metrics/index.ts @@ -61,5 +61,6 @@ export function mongodbMetricsSpecProvider(context: TutorialContext): TutorialSc onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['datastore'], }; } diff --git a/src/plugins/home/server/tutorials/mssql_logs/index.ts b/src/plugins/home/server/tutorials/mssql_logs/index.ts index 1b605d2c17dbb..567080910b7fe 100644 --- a/src/plugins/home/server/tutorials/mssql_logs/index.ts +++ b/src/plugins/home/server/tutorials/mssql_logs/index.ts @@ -56,5 +56,6 @@ export function mssqlLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['datastore'], }; } diff --git a/src/plugins/home/server/tutorials/mssql_metrics/index.ts b/src/plugins/home/server/tutorials/mssql_metrics/index.ts index 767612e3a1c2e..998cefe2de004 100644 --- a/src/plugins/home/server/tutorials/mssql_metrics/index.ts +++ b/src/plugins/home/server/tutorials/mssql_metrics/index.ts @@ -59,5 +59,6 @@ export function mssqlMetricsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['datastore'], }; } diff --git a/src/plugins/home/server/tutorials/munin_metrics/index.ts b/src/plugins/home/server/tutorials/munin_metrics/index.ts index 063770e43e6d1..1abd321e4c738 100644 --- a/src/plugins/home/server/tutorials/munin_metrics/index.ts +++ b/src/plugins/home/server/tutorials/munin_metrics/index.ts @@ -56,5 +56,6 @@ export function muninMetricsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['datastore'], }; } diff --git a/src/plugins/home/server/tutorials/mysql_logs/index.ts b/src/plugins/home/server/tutorials/mysql_logs/index.ts index 79eaeb3826162..a788e736d2964 100644 --- a/src/plugins/home/server/tutorials/mysql_logs/index.ts +++ b/src/plugins/home/server/tutorials/mysql_logs/index.ts @@ -59,5 +59,6 @@ export function mysqlLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['datastore'], }; } diff --git a/src/plugins/home/server/tutorials/mysql_metrics/index.ts b/src/plugins/home/server/tutorials/mysql_metrics/index.ts index 66da2d8e0a5ff..078a96f8110df 100644 --- a/src/plugins/home/server/tutorials/mysql_metrics/index.ts +++ b/src/plugins/home/server/tutorials/mysql_metrics/index.ts @@ -58,5 +58,6 @@ export function mysqlMetricsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['datastore'], }; } diff --git a/src/plugins/home/server/tutorials/nats_logs/index.ts b/src/plugins/home/server/tutorials/nats_logs/index.ts index c5c7028e19163..a1dc24080bc0d 100644 --- a/src/plugins/home/server/tutorials/nats_logs/index.ts +++ b/src/plugins/home/server/tutorials/nats_logs/index.ts @@ -60,5 +60,6 @@ export function natsLogsSpecProvider(context: TutorialContext): TutorialSchema { onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['message_queue'], }; } diff --git a/src/plugins/home/server/tutorials/nats_metrics/index.ts b/src/plugins/home/server/tutorials/nats_metrics/index.ts index bf25ab9f8d33e..11494e5dc57d0 100644 --- a/src/plugins/home/server/tutorials/nats_metrics/index.ts +++ b/src/plugins/home/server/tutorials/nats_metrics/index.ts @@ -58,5 +58,6 @@ export function natsMetricsSpecProvider(context: TutorialContext): TutorialSchem onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['message_queue'], }; } diff --git a/src/plugins/home/server/tutorials/netflow_logs/index.ts b/src/plugins/home/server/tutorials/netflow_logs/index.ts index 1a85c3feb1173..e8404e93ae355 100644 --- a/src/plugins/home/server/tutorials/netflow_logs/index.ts +++ b/src/plugins/home/server/tutorials/netflow_logs/index.ts @@ -58,5 +58,6 @@ export function netflowLogsSpecProvider(context: TutorialContext): TutorialSchem onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/netscout_logs/index.ts b/src/plugins/home/server/tutorials/netscout_logs/index.ts index 57429e9acddfe..395fbb8b49d39 100644 --- a/src/plugins/home/server/tutorials/netscout_logs/index.ts +++ b/src/plugins/home/server/tutorials/netscout_logs/index.ts @@ -56,5 +56,6 @@ export function netscoutLogsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/nginx_logs/index.ts b/src/plugins/home/server/tutorials/nginx_logs/index.ts index a1419fbb42d5a..90ec6737c2461 100644 --- a/src/plugins/home/server/tutorials/nginx_logs/index.ts +++ b/src/plugins/home/server/tutorials/nginx_logs/index.ts @@ -59,5 +59,6 @@ export function nginxLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['web', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/nginx_metrics/index.ts b/src/plugins/home/server/tutorials/nginx_metrics/index.ts index 32b20844ef813..12f67a26dcf29 100644 --- a/src/plugins/home/server/tutorials/nginx_metrics/index.ts +++ b/src/plugins/home/server/tutorials/nginx_metrics/index.ts @@ -63,5 +63,6 @@ which must be enabled in your Nginx installation. \ onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['web', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/o365_logs/index.ts b/src/plugins/home/server/tutorials/o365_logs/index.ts index 50cd13298a879..e3663e2c3cd78 100644 --- a/src/plugins/home/server/tutorials/o365_logs/index.ts +++ b/src/plugins/home/server/tutorials/o365_logs/index.ts @@ -62,5 +62,6 @@ export function o365LogsSpecProvider(context: TutorialContext): TutorialSchema { onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/okta_logs/index.ts b/src/plugins/home/server/tutorials/okta_logs/index.ts index ac173c79db605..62cde4b5128c3 100644 --- a/src/plugins/home/server/tutorials/okta_logs/index.ts +++ b/src/plugins/home/server/tutorials/okta_logs/index.ts @@ -60,5 +60,6 @@ export function oktaLogsSpecProvider(context: TutorialContext): TutorialSchema { onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/openmetrics_metrics/index.ts b/src/plugins/home/server/tutorials/openmetrics_metrics/index.ts index 6885c1ccea86d..acbddf5169881 100644 --- a/src/plugins/home/server/tutorials/openmetrics_metrics/index.ts +++ b/src/plugins/home/server/tutorials/openmetrics_metrics/index.ts @@ -49,5 +49,6 @@ export function openmetricsMetricsSpecProvider(context: TutorialContext): Tutori onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/oracle_metrics/index.ts b/src/plugins/home/server/tutorials/oracle_metrics/index.ts index f0e3967344b5e..9b63e82c21ccd 100644 --- a/src/plugins/home/server/tutorials/oracle_metrics/index.ts +++ b/src/plugins/home/server/tutorials/oracle_metrics/index.ts @@ -57,5 +57,6 @@ export function oracleMetricsSpecProvider(context: TutorialContext): TutorialSch onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/osquery_logs/index.ts b/src/plugins/home/server/tutorials/osquery_logs/index.ts index 40ed13d767319..6bacbed57792c 100644 --- a/src/plugins/home/server/tutorials/osquery_logs/index.ts +++ b/src/plugins/home/server/tutorials/osquery_logs/index.ts @@ -62,5 +62,6 @@ export function osqueryLogsSpecProvider(context: TutorialContext): TutorialSchem onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security', 'os_system'], }; } diff --git a/src/plugins/home/server/tutorials/panw_logs/index.ts b/src/plugins/home/server/tutorials/panw_logs/index.ts index a46b2deb29826..3ca839556d756 100644 --- a/src/plugins/home/server/tutorials/panw_logs/index.ts +++ b/src/plugins/home/server/tutorials/panw_logs/index.ts @@ -62,5 +62,6 @@ export function panwLogsSpecProvider(context: TutorialContext): TutorialSchema { onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/php_fpm_metrics/index.ts b/src/plugins/home/server/tutorials/php_fpm_metrics/index.ts index 229a167bb137e..ed67960ab5a1c 100644 --- a/src/plugins/home/server/tutorials/php_fpm_metrics/index.ts +++ b/src/plugins/home/server/tutorials/php_fpm_metrics/index.ts @@ -56,5 +56,6 @@ export function phpfpmMetricsSpecProvider(context: TutorialContext): TutorialSch onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/postgresql_logs/index.ts b/src/plugins/home/server/tutorials/postgresql_logs/index.ts index da7b8927a610d..c5f5d879ac35d 100644 --- a/src/plugins/home/server/tutorials/postgresql_logs/index.ts +++ b/src/plugins/home/server/tutorials/postgresql_logs/index.ts @@ -62,5 +62,6 @@ export function postgresqlLogsSpecProvider(context: TutorialContext): TutorialSc onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['datastore'], }; } diff --git a/src/plugins/home/server/tutorials/postgresql_metrics/index.ts b/src/plugins/home/server/tutorials/postgresql_metrics/index.ts index eb5ed17021d1a..ca20efb44bca7 100644 --- a/src/plugins/home/server/tutorials/postgresql_metrics/index.ts +++ b/src/plugins/home/server/tutorials/postgresql_metrics/index.ts @@ -58,5 +58,6 @@ export function postgresqlMetricsSpecProvider(context: TutorialContext): Tutoria onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['datastore'], }; } diff --git a/src/plugins/home/server/tutorials/prometheus_metrics/index.ts b/src/plugins/home/server/tutorials/prometheus_metrics/index.ts index b0179fbc82614..ee05770d65108 100644 --- a/src/plugins/home/server/tutorials/prometheus_metrics/index.ts +++ b/src/plugins/home/server/tutorials/prometheus_metrics/index.ts @@ -57,5 +57,6 @@ export function prometheusMetricsSpecProvider(context: TutorialContext): Tutoria onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['monitoring', 'datastore'], }; } diff --git a/src/plugins/home/server/tutorials/rabbitmq_logs/index.ts b/src/plugins/home/server/tutorials/rabbitmq_logs/index.ts index 92e6623da6f53..0fbdb48236832 100644 --- a/src/plugins/home/server/tutorials/rabbitmq_logs/index.ts +++ b/src/plugins/home/server/tutorials/rabbitmq_logs/index.ts @@ -56,5 +56,6 @@ export function rabbitmqLogsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['message_queue'], }; } diff --git a/src/plugins/home/server/tutorials/rabbitmq_metrics/index.ts b/src/plugins/home/server/tutorials/rabbitmq_metrics/index.ts index 56b7a8c8c2109..b58f936f205b2 100644 --- a/src/plugins/home/server/tutorials/rabbitmq_metrics/index.ts +++ b/src/plugins/home/server/tutorials/rabbitmq_metrics/index.ts @@ -62,5 +62,6 @@ export function rabbitmqMetricsSpecProvider(context: TutorialContext): TutorialS onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['message_queue'], }; } diff --git a/src/plugins/home/server/tutorials/radware_logs/index.ts b/src/plugins/home/server/tutorials/radware_logs/index.ts index 3d91514c2c13e..28392cf9c4362 100644 --- a/src/plugins/home/server/tutorials/radware_logs/index.ts +++ b/src/plugins/home/server/tutorials/radware_logs/index.ts @@ -56,5 +56,6 @@ export function radwareLogsSpecProvider(context: TutorialContext): TutorialSchem onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/redis_logs/index.ts b/src/plugins/home/server/tutorials/redis_logs/index.ts index 116099e809832..0f3a5aa812f49 100644 --- a/src/plugins/home/server/tutorials/redis_logs/index.ts +++ b/src/plugins/home/server/tutorials/redis_logs/index.ts @@ -65,5 +65,6 @@ Note that the `slowlog` fileset is experimental. \ onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['datastore', 'message_queue'], }; } diff --git a/src/plugins/home/server/tutorials/redis_metrics/index.ts b/src/plugins/home/server/tutorials/redis_metrics/index.ts index bce77a2b18cc3..1b4ee7290a6d0 100644 --- a/src/plugins/home/server/tutorials/redis_metrics/index.ts +++ b/src/plugins/home/server/tutorials/redis_metrics/index.ts @@ -58,5 +58,6 @@ export function redisMetricsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['datastore', 'message_queue'], }; } diff --git a/src/plugins/home/server/tutorials/redisenterprise_metrics/index.ts b/src/plugins/home/server/tutorials/redisenterprise_metrics/index.ts index 257440ec69987..be8de9c3eab4d 100644 --- a/src/plugins/home/server/tutorials/redisenterprise_metrics/index.ts +++ b/src/plugins/home/server/tutorials/redisenterprise_metrics/index.ts @@ -57,5 +57,6 @@ export function redisenterpriseMetricsSpecProvider(context: TutorialContext): Tu onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['datastore', 'message_queue'], }; } diff --git a/src/plugins/home/server/tutorials/santa_logs/index.ts b/src/plugins/home/server/tutorials/santa_logs/index.ts index fb5ba7ede4171..10d1506438b62 100644 --- a/src/plugins/home/server/tutorials/santa_logs/index.ts +++ b/src/plugins/home/server/tutorials/santa_logs/index.ts @@ -60,5 +60,6 @@ export function santaLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security', 'os_system'], }; } diff --git a/src/plugins/home/server/tutorials/sonicwall_logs/index.ts b/src/plugins/home/server/tutorials/sonicwall_logs/index.ts index fa33f81728db7..1fa711327a07d 100644 --- a/src/plugins/home/server/tutorials/sonicwall_logs/index.ts +++ b/src/plugins/home/server/tutorials/sonicwall_logs/index.ts @@ -56,5 +56,6 @@ export function sonicwallLogsSpecProvider(context: TutorialContext): TutorialSch onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/sophos_logs/index.ts b/src/plugins/home/server/tutorials/sophos_logs/index.ts index 19b6b3033c9f1..35b27973a55ec 100644 --- a/src/plugins/home/server/tutorials/sophos_logs/index.ts +++ b/src/plugins/home/server/tutorials/sophos_logs/index.ts @@ -56,5 +56,6 @@ export function sophosLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/squid_logs/index.ts b/src/plugins/home/server/tutorials/squid_logs/index.ts index ef6ea4aef3e17..d8d0bb6c0829b 100644 --- a/src/plugins/home/server/tutorials/squid_logs/index.ts +++ b/src/plugins/home/server/tutorials/squid_logs/index.ts @@ -56,5 +56,6 @@ export function squidLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['security'], }; } diff --git a/src/plugins/home/server/tutorials/stan_metrics/index.ts b/src/plugins/home/server/tutorials/stan_metrics/index.ts index 10b7fc08bbf19..ceb6084b539e6 100644 --- a/src/plugins/home/server/tutorials/stan_metrics/index.ts +++ b/src/plugins/home/server/tutorials/stan_metrics/index.ts @@ -58,5 +58,6 @@ export function stanMetricsSpecProvider(context: TutorialContext): TutorialSchem onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['message_queue', 'kubernetes'], }; } diff --git a/src/plugins/home/server/tutorials/statsd_metrics/index.ts b/src/plugins/home/server/tutorials/statsd_metrics/index.ts index 70a35d3f6f648..472c1406db386 100644 --- a/src/plugins/home/server/tutorials/statsd_metrics/index.ts +++ b/src/plugins/home/server/tutorials/statsd_metrics/index.ts @@ -47,5 +47,6 @@ export function statsdMetricsSpecProvider(context: TutorialContext): TutorialSch onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['message_queue', 'kubernetes'], }; } diff --git a/src/plugins/home/server/tutorials/suricata_logs/index.ts b/src/plugins/home/server/tutorials/suricata_logs/index.ts index c06c7c05c5583..3bb2b93b6301a 100644 --- a/src/plugins/home/server/tutorials/suricata_logs/index.ts +++ b/src/plugins/home/server/tutorials/suricata_logs/index.ts @@ -60,5 +60,6 @@ export function suricataLogsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/system_logs/index.ts b/src/plugins/home/server/tutorials/system_logs/index.ts index 087f8e04e250d..6f403a6d0a71a 100644 --- a/src/plugins/home/server/tutorials/system_logs/index.ts +++ b/src/plugins/home/server/tutorials/system_logs/index.ts @@ -58,5 +58,6 @@ export function systemLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['os_system', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/system_metrics/index.ts b/src/plugins/home/server/tutorials/system_metrics/index.ts index 91e0b74a05d68..08979a3d3b003 100644 --- a/src/plugins/home/server/tutorials/system_metrics/index.ts +++ b/src/plugins/home/server/tutorials/system_metrics/index.ts @@ -59,5 +59,6 @@ It collects system wide statistics and statistics per process and filesystem. \ onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['os_system', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/tomcat_logs/index.ts b/src/plugins/home/server/tutorials/tomcat_logs/index.ts index 4632f5d64eec8..5ce4096ad4628 100644 --- a/src/plugins/home/server/tutorials/tomcat_logs/index.ts +++ b/src/plugins/home/server/tutorials/tomcat_logs/index.ts @@ -56,5 +56,6 @@ export function tomcatLogsSpecProvider(context: TutorialContext): TutorialSchema onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['web', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/traefik_logs/index.ts b/src/plugins/home/server/tutorials/traefik_logs/index.ts index 139a158d77b81..6bbc905bbd6aa 100644 --- a/src/plugins/home/server/tutorials/traefik_logs/index.ts +++ b/src/plugins/home/server/tutorials/traefik_logs/index.ts @@ -58,5 +58,6 @@ export function traefikLogsSpecProvider(context: TutorialContext): TutorialSchem onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['web', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/traefik_metrics/index.ts b/src/plugins/home/server/tutorials/traefik_metrics/index.ts index a036de3546ba8..35d54317c8ede 100644 --- a/src/plugins/home/server/tutorials/traefik_metrics/index.ts +++ b/src/plugins/home/server/tutorials/traefik_metrics/index.ts @@ -46,5 +46,6 @@ export function traefikMetricsSpecProvider(context: TutorialContext): TutorialSc onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['web', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/uptime_monitors/index.ts b/src/plugins/home/server/tutorials/uptime_monitors/index.ts index f04e0e1e797ef..6e949d5410115 100644 --- a/src/plugins/home/server/tutorials/uptime_monitors/index.ts +++ b/src/plugins/home/server/tutorials/uptime_monitors/index.ts @@ -57,5 +57,6 @@ export function uptimeMonitorsSpecProvider(context: TutorialContext): TutorialSc onPrem: onPremInstructions([], context), elasticCloud: cloudInstructions(), onPremElasticCloud: onPremCloudInstructions(), + integrationBrowserCategories: ['web', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/uwsgi_metrics/index.ts b/src/plugins/home/server/tutorials/uwsgi_metrics/index.ts index d41bdad6a90d9..d9cfcc9f7fb75 100644 --- a/src/plugins/home/server/tutorials/uwsgi_metrics/index.ts +++ b/src/plugins/home/server/tutorials/uwsgi_metrics/index.ts @@ -59,5 +59,6 @@ export function uwsgiMetricsSpecProvider(context: TutorialContext): TutorialSche onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['web', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/vsphere_metrics/index.ts b/src/plugins/home/server/tutorials/vsphere_metrics/index.ts index b4786d060ecd1..bcbcec59c36e4 100644 --- a/src/plugins/home/server/tutorials/vsphere_metrics/index.ts +++ b/src/plugins/home/server/tutorials/vsphere_metrics/index.ts @@ -56,5 +56,6 @@ export function vSphereMetricsSpecProvider(context: TutorialContext): TutorialSc onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['web', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/windows_event_logs/index.ts b/src/plugins/home/server/tutorials/windows_event_logs/index.ts index 5b073e7a0fcde..0df7fa906e085 100644 --- a/src/plugins/home/server/tutorials/windows_event_logs/index.ts +++ b/src/plugins/home/server/tutorials/windows_event_logs/index.ts @@ -56,5 +56,6 @@ export function windowsEventLogsSpecProvider(context: TutorialContext): Tutorial onPrem: onPremInstructions(context), elasticCloud: cloudInstructions(), onPremElasticCloud: onPremCloudInstructions(), + integrationBrowserCategories: ['os_system', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/windows_metrics/index.ts b/src/plugins/home/server/tutorials/windows_metrics/index.ts index e937a962f1bd5..6c663fbb13d4d 100644 --- a/src/plugins/home/server/tutorials/windows_metrics/index.ts +++ b/src/plugins/home/server/tutorials/windows_metrics/index.ts @@ -56,5 +56,6 @@ export function windowsMetricsSpecProvider(context: TutorialContext): TutorialSc onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['os_system', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/zeek_logs/index.ts b/src/plugins/home/server/tutorials/zeek_logs/index.ts index 9c5baa8368a7c..5434dcc8527ff 100644 --- a/src/plugins/home/server/tutorials/zeek_logs/index.ts +++ b/src/plugins/home/server/tutorials/zeek_logs/index.ts @@ -60,5 +60,6 @@ export function zeekLogsSpecProvider(context: TutorialContext): TutorialSchema { onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network', 'monitoring', 'security'], }; } diff --git a/src/plugins/home/server/tutorials/zookeeper_metrics/index.ts b/src/plugins/home/server/tutorials/zookeeper_metrics/index.ts index 29038269b0825..85ca03acacfd4 100644 --- a/src/plugins/home/server/tutorials/zookeeper_metrics/index.ts +++ b/src/plugins/home/server/tutorials/zookeeper_metrics/index.ts @@ -57,5 +57,6 @@ export function zookeeperMetricsSpecProvider(context: TutorialContext): Tutorial onPrem: onPremInstructions(moduleName, context), elasticCloud: cloudInstructions(moduleName), onPremElasticCloud: onPremCloudInstructions(moduleName), + integrationBrowserCategories: ['datastore', 'config_management'], }; } diff --git a/src/plugins/home/server/tutorials/zscaler_logs/index.ts b/src/plugins/home/server/tutorials/zscaler_logs/index.ts index fcfcccf2c50bf..a2eb41a257a92 100644 --- a/src/plugins/home/server/tutorials/zscaler_logs/index.ts +++ b/src/plugins/home/server/tutorials/zscaler_logs/index.ts @@ -56,5 +56,6 @@ export function zscalerLogsSpecProvider(context: TutorialContext): TutorialSchem onPrem: onPremInstructions(moduleName, platforms, context), elasticCloud: cloudInstructions(moduleName, platforms), onPremElasticCloud: onPremCloudInstructions(moduleName, platforms), + integrationBrowserCategories: ['network', 'security'], }; } diff --git a/test/api_integration/apis/custom_integration/integrations.ts b/test/api_integration/apis/custom_integration/integrations.ts index 2d1d085198bb4..4b1344ee8e84c 100644 --- a/test/api_integration/apis/custom_integration/integrations.ts +++ b/test/api_integration/apis/custom_integration/integrations.ts @@ -12,18 +12,32 @@ import { FtrProviderContext } from '../../ftr_provider_context'; export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); - describe('get list of append integrations', () => { - it('should return list of custom integrations that can be appended', async () => { - const resp = await supertest - .get(`/api/customIntegrations/appendCustomIntegrations`) - .set('kbn-xsrf', 'kibana') - .expect(200); + describe('customIntegrations', () => { + describe('get list of append integrations', () => { + it('should return list of custom integrations that can be appended', async () => { + const resp = await supertest + .get(`/internal/customIntegrations/appendCustomIntegrations`) + .set('kbn-xsrf', 'kibana') + .expect(200); - expect(resp.body).to.be.an('array'); - expect(resp.body.length).to.be.above(2); // Should at least have registered the three sample data-sets + expect(resp.body).to.be.an('array'); + expect(resp.body.length).to.be.above(2); // Should at least have registered the three sample data-sets - ['flights', 'logs', 'ecommerce'].forEach((sampleData) => { - expect(resp.body.findIndex((c: { id: string }) => c.id === sampleData)).to.be.above(-1); + ['flights', 'logs', 'ecommerce'].forEach((sampleData) => { + expect(resp.body.findIndex((c: { id: string }) => c.id === sampleData)).to.be.above(-1); + }); + }); + }); + + describe('get list of replacement integrations', () => { + it('should return list of custom integrations that can be used to replace EPR packages', async () => { + const resp = await supertest + .get(`/internal/customIntegrations/replacementCustomIntegrations`) + .set('kbn-xsrf', 'kibana') + .expect(200); + + expect(resp.body).to.be.an('array'); + expect(resp.body.length).to.be.above(2); // Should have at least a few beats registered }); }); }); diff --git a/test/common/services/saved_object_info/README.md b/test/common/services/saved_object_info/README.md index 5f081e48e2639..c5e36f2596ddc 100644 --- a/test/common/services/saved_object_info/README.md +++ b/test/common/services/saved_object_info/README.md @@ -1,6 +1,70 @@ -# Tips for using the SO INFO SVC CLI with JQ +# Tips for using the SO INFO SVC -## Myriad ways to use jq to discern discrete info from the svc +## From an FTR test +``` + ... + const soInfo = getService('savedObjectInfo'); + const log = getService('log'); + + describe('some test suite', function () { + ... + + after(async () => { + // "Normal" logging, without JQ + await soInfo.logSoTypes(log); + // Without a title, using JQ + await soInfo.filterSoTypes(log, '.[] | .key'); + // With a title, using JQ + await soInfo.filterSoTypes( + log, + 'reduce .[].doc_count as $item (0; . + $item)', + 'TOTAL count of ALL Saved Object types' + ); + // With a title, using JQ + await soInfo.filterSoTypes( + log, + '.[] | select(.key =="canvas-workpad-template") | .doc_count', + 'TOTAL count of canvas-workpad-template' + ); + }); +``` + +## From the CLI + +Run the cli +> the **--esUrl** arg is required; tells the svc which elastic search endpoint to use + +```shell + λ node scripts/saved_objs_info.js --esUrl http://elastic:changeme@localhost:9220 --soTypes +``` + +Result + +```shell + ### types: + + [ + { + doc_count: 5, + key: 'canvas-workpad-template' + }, + { + doc_count: 1, + key: 'apm-telemetry' + }, + { + doc_count: 1, + key: 'config' + }, + { + doc_count: 1, + key: 'space' + } + ] +``` + + +### Myriad ways to use JQ to discern discrete info from the svc Below, I will leave out the so types call, which is: `node scripts/saved_objs_info.js --esUrl http://elastic:changeme@localhost:9220 --soTypes --json` diff --git a/test/common/services/saved_object_info/index.ts b/test/common/services/saved_object_info/index.ts index 41367694373f3..799c9964fde7f 100644 --- a/test/common/services/saved_object_info/index.ts +++ b/test/common/services/saved_object_info/index.ts @@ -33,7 +33,7 @@ Show information pertaining to the saved objects in the .kibana index Examples: -See 'saved_objects_info_svc.md' +See 'README.md' `, flags: expectedFlags(), diff --git a/test/common/services/saved_object_info/saved_object_info.ts b/test/common/services/saved_object_info/saved_object_info.ts index 61472ea98d879..a75dfd8f3b5aa 100644 --- a/test/common/services/saved_object_info/saved_object_info.ts +++ b/test/common/services/saved_object_info/saved_object_info.ts @@ -13,6 +13,7 @@ import { flow, pipe } from 'fp-ts/function'; import * as TE from 'fp-ts/lib/TaskEither'; import * as T from 'fp-ts/lib/Task'; import { ToolingLog } from '@kbn/dev-utils'; +import { run as jq } from 'node-jq'; import { FtrService } from '../../ftr_provider_context'; import { print } from './utils'; @@ -60,8 +61,22 @@ export const types = export class SavedObjectInfoService extends FtrService { private readonly config = this.ctx.getService('config'); + private readonly typesF = async () => + await types(url.format(this.config.get('servers.elasticsearch')))(); + public async logSoTypes(log: ToolingLog, msg: string | null = null) { // @ts-ignore - pipe(await types(url.format(this.config.get('servers.elasticsearch'))), print(log)(msg)); + pipe(await this.typesF(), print(log)(msg)); + } + + /** + * See test/common/services/saved_object_info/README.md for "jq filtering" ideas. + */ + public async filterSoTypes(log: ToolingLog, jqFilter: string, title: string | null = null) { + pipe(await this.typesF(), filterAndLog); + + async function filterAndLog(payload: any) { + log.info(`${title ? title + '\n' : ''}${await jq(jqFilter, payload, { input: 'json' })}`); + } } } diff --git a/test/common/services/saved_object_info/saved_objects_info_svc.md b/test/common/services/saved_object_info/saved_objects_info_svc.md deleted file mode 100644 index 2d623129e2906..0000000000000 --- a/test/common/services/saved_object_info/saved_objects_info_svc.md +++ /dev/null @@ -1,35 +0,0 @@ -# Saved Objects Info Svc w/ CLI - -## Used via the cli - -Run the cli -> the **--esUrl** arg is required; tells the svc which elastic search endpoint to use - -```shell - λ node scripts/saved_objs_info.js --esUrl http://elastic:changeme@localhost:9220 --soTypes -``` - -Result - -```shell - ### types: - - [ - { - doc_count: 5, - key: 'canvas-workpad-template' - }, - { - doc_count: 1, - key: 'apm-telemetry' - }, - { - doc_count: 1, - key: 'config' - }, - { - doc_count: 1, - key: 'space' - } - ] -``` diff --git a/vars/tasks.groovy b/vars/tasks.groovy index 1842e278282b1..5c8f133331e55 100644 --- a/vars/tasks.groovy +++ b/vars/tasks.groovy @@ -146,13 +146,14 @@ def functionalXpack(Map params = [:]) { } } - whenChanged([ - 'x-pack/plugins/apm/', - ]) { - if (githubPr.isPr()) { - task(kibanaPipeline.functionalTestProcess('xpack-APMCypress', './test/scripts/jenkins_apm_cypress.sh')) - } - } + //temporarily disable apm e2e test since it's breaking due to a version upgrade. + // whenChanged([ + // 'x-pack/plugins/apm/', + // ]) { + // if (githubPr.isPr()) { + // task(kibanaPipeline.functionalTestProcess('xpack-APMCypress', './test/scripts/jenkins_apm_cypress.sh')) + // } + // } whenChanged([ 'x-pack/plugins/uptime/', diff --git a/x-pack/plugins/apm/server/tutorial/envs/elastic_cloud.ts b/x-pack/plugins/apm/server/tutorial/envs/elastic_cloud.ts index a7efaa3b00f34..c62e42f222194 100644 --- a/x-pack/plugins/apm/server/tutorial/envs/elastic_cloud.ts +++ b/x-pack/plugins/apm/server/tutorial/envs/elastic_cloud.ts @@ -57,10 +57,10 @@ function getApmServerInstructionSet( id: INSTRUCTION_VARIANT.ESC, instructions: [ { - title: 'Enable the APM Server in the ESS console', + title: 'Enable the APM Server in the Elastic Cloud user console', textPre: i18n.translate('xpack.apm.tutorial.elasticCloud.textPre', { defaultMessage: - 'To enable the APM Server go to [the Elastic Cloud console](https://cloud.elastic.co/deployments/{deploymentId}/edit) and enable APM in the deployment settings. Once enabled, refresh this page.', + 'To enable the APM Server go to [the Elastic Cloud console](https://cloud.elastic.co/deployments/{deploymentId}/edit) and enable APM and Fleet in the deployment edit page by clicking on add capacity, and then click on save. Once enabled, refresh this page.', values: { deploymentId }, }), }, diff --git a/x-pack/plugins/enterprise_search/jest.config.js b/x-pack/plugins/enterprise_search/jest.config.js index 263713697b7e0..b5e6105ff41f2 100644 --- a/x-pack/plugins/enterprise_search/jest.config.js +++ b/x-pack/plugins/enterprise_search/jest.config.js @@ -18,4 +18,8 @@ module.exports = { '!/x-pack/plugins/enterprise_search/public/applications/test_helpers/**/*.{ts,tsx}', ], coverageDirectory: '/target/kibana-coverage/jest/x-pack/plugins/enterprise_search', + modulePathIgnorePatterns: [ + '/x-pack/plugins/enterprise_search/public/applications/app_search/cypress', + '/x-pack/plugins/enterprise_search/public/applications/workplace_search/cypress', + ], }; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.test.tsx index a241edb8020a4..9598212d3e0c9 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.test.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.test.tsx @@ -19,6 +19,6 @@ describe('CurationsRouter', () => { const wrapper = shallow(); expect(wrapper.find(Switch)).toHaveLength(1); - expect(wrapper.find(Route)).toHaveLength(3); + expect(wrapper.find(Route)).toHaveLength(4); }); }); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.tsx index 40f2d07ab61ab..693e5406b714b 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.tsx +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/curations_router.tsx @@ -12,10 +12,11 @@ import { ENGINE_CURATIONS_PATH, ENGINE_CURATIONS_NEW_PATH, ENGINE_CURATION_PATH, + ENGINE_CURATION_SUGGESTION_PATH, } from '../../routes'; import { Curation } from './curation'; -import { Curations, CurationCreation } from './views'; +import { Curations, CurationCreation, CurationSuggestion } from './views'; export const CurationsRouter: React.FC = () => { return ( @@ -26,6 +27,9 @@ export const CurationsRouter: React.FC = () => { + + + diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_action_bar.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_action_bar.test.tsx new file mode 100644 index 0000000000000..4bd586d9d2e91 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_action_bar.test.tsx @@ -0,0 +1,29 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { shallow } from 'enzyme'; + +import { CurationActionBar } from './curation_action_bar'; + +describe('CurationActionBar', () => { + const handleAcceptClick = jest.fn(); + const handleRejectClick = jest.fn(); + + it('renders', () => { + const wrapper = shallow( + + ); + + wrapper.find('[data-test-subj="rejectButton"]').simulate('click'); + expect(handleRejectClick).toHaveBeenCalled(); + + wrapper.find('[data-test-subj="acceptButton"]').simulate('click'); + expect(handleAcceptClick).toHaveBeenCalled(); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_action_bar.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_action_bar.tsx new file mode 100644 index 0000000000000..42f4cbbb7d7a9 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_action_bar.tsx @@ -0,0 +1,81 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiPanel, EuiTitle } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { CurationActionsPopover } from './curation_actions_popover'; + +interface Props { + onAcceptClick: (event: React.MouseEvent) => void; + onRejectClick: (event: React.MouseEvent) => void; +} + +export const CurationActionBar: React.FC = ({ onAcceptClick, onRejectClick }) => { + return ( + + + + + + +

+ {i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.curations.suggestedCuration.title', + { defaultMessage: 'Manage suggestion' } + )} +

+
+
+ + + + + {i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.curations.suggestedCuration.rejectButtonLabel', + { defaultMessage: 'Reject' } + )} + + + + + {i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.curations.suggestedCuration.acceptButtonLabel', + { defaultMessage: 'Accept' } + )} + + + + {}} + onAutomate={() => {}} + onReject={() => {}} + onTurnOff={() => {}} + /> + + + +
+
+
+
+ ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_actions_popover.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_actions_popover.test.tsx new file mode 100644 index 0000000000000..33d00ca2b7899 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_actions_popover.test.tsx @@ -0,0 +1,69 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { shallow } from 'enzyme'; + +import { CurationActionsPopover } from './curation_actions_popover'; + +describe('CurationActionsPopover', () => { + const handleAccept = jest.fn(); + const handleAutomate = jest.fn(); + const handleReject = jest.fn(); + const handleTurnOff = jest.fn(); + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders', () => { + const wrapper = shallow( + + ); + expect(wrapper.isEmptyRender()).toBe(false); + + wrapper.find('[data-test-subj="acceptButton"]').simulate('click'); + expect(handleAccept).toHaveBeenCalled(); + + wrapper.find('[data-test-subj="automateButton"]').simulate('click'); + expect(handleAutomate).toHaveBeenCalled(); + + wrapper.find('[data-test-subj="rejectButton"]').simulate('click'); + expect(handleReject).toHaveBeenCalled(); + + wrapper.find('[data-test-subj="turnoffButton"]').simulate('click'); + expect(handleTurnOff).toHaveBeenCalled(); + }); + + it('can open and close', () => { + const wrapper = shallow( + + ); + + expect(wrapper.prop('isOpen')).toBe(false); + + const button = shallow(wrapper.prop('button')); + button.simulate('click'); + + expect(wrapper.prop('isOpen')).toBe(true); + + wrapper.prop('closePopover')(); + + expect(wrapper.prop('isOpen')).toBe(false); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_actions_popover.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_actions_popover.tsx new file mode 100644 index 0000000000000..ef7b42fb705f1 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_actions_popover.tsx @@ -0,0 +1,102 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState } from 'react'; + +import { + EuiButtonIcon, + EuiListGroup, + EuiListGroupItem, + EuiPopover, + EuiPopoverTitle, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +interface Props { + onAccept: () => void; + onAutomate: () => void; + onReject: () => void; + onTurnOff: () => void; +} + +export const CurationActionsPopover: React.FC = ({ + onAccept, + onAutomate, + onReject, + onTurnOff, +}) => { + const [isPopoverOpen, setIsPopoverOpen] = useState(false); + + const onButtonClick = () => setIsPopoverOpen(!isPopoverOpen); + const closePopover = () => setIsPopoverOpen(false); + + const button = ( + + ); + return ( + + + {i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.curations.suggestedCuration.actionsPopoverTitle', + { + defaultMessage: 'Manage suggestion', + } + )} + + + + + + + + + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.scss b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.scss new file mode 100644 index 0000000000000..1fa988014edb7 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.scss @@ -0,0 +1,24 @@ +.curationResultPanel { + border-radius: $euiSizeM; + margin-top: $euiSizeS; + padding: $euiSizeXS; +} + +.curationResultPanel--current, .curationResultPanel--promoted { + border: $euiBorderWidthThick solid $euiColorPrimary; + background-color: tintOrShade($euiColorPrimary, 90%, 70%); // Copied from @elastit/eui/src/global_styling/variables/_panels.scss +} + +.curationResultPanel--suggested { + border: $euiBorderWidthThick solid $euiColorSecondary; + background-color: tintOrShade($euiColorSuccess, 90%, 70%); // Copied from @elastit/eui/src/global_styling/variables/_panels.scss +} + +.curationResultPanel--hidden { + border: $euiBorderWidthThick solid $euiColorAccent; + background-color: tintOrShade($euiColorAccent, 90%, 70%); // Copied from @elastit/eui/src/global_styling/variables/_panels.scss +} + +.curationResultPanel__header { + flex-grow: 0; +} \ No newline at end of file diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.test.tsx new file mode 100644 index 0000000000000..fad4e54721bb3 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.test.tsx @@ -0,0 +1,53 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { shallow } from 'enzyme'; + +import { Result } from '../../../result'; + +import { CurationResultPanel } from './curation_result_panel'; + +describe('CurationResultPanel', () => { + const results = [ + { + id: { raw: 'foo' }, + _meta: { engine: 'some-engine', id: 'foo' }, + }, + { + id: { raw: 'bar' }, + _meta: { engine: 'some-engine', id: 'bar' }, + }, + ]; + + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('renders results', () => { + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="suggestedText"]').exists()).toBe(false); + expect(wrapper.find(Result).length).toBe(2); + }); + + it('renders a no results message when there are no results', () => { + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="noResults"]').exists()).toBe(true); + expect(wrapper.find(Result).length).toBe(0); + }); + + it('shows text about automation when variant is "suggested"', () => { + const wrapper = shallow(); + expect(wrapper.find('[data-test-subj="suggestedText"]').exists()).toBe(true); + }); + + it('renders the right class name for the provided variant', () => { + const wrapper = shallow(); + expect(wrapper.find('.curationResultPanel--promoted').exists()).toBe(true); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.tsx new file mode 100644 index 0000000000000..12bbf07f97bb3 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_result_panel.tsx @@ -0,0 +1,91 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React from 'react'; + +import { + EuiFlexGroup, + EuiFlexItem, + EuiNotificationBadge, + EuiSpacer, + EuiText, + EuiTitle, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { Result } from '../../../result'; +import { Result as ResultType } from '../../../result/types'; +import './curation_result_panel.scss'; + +interface Props { + variant: 'current' | 'promoted' | 'suggested' | 'hidden'; + results: ResultType[]; +} + +export const CurationResultPanel: React.FC = ({ variant, results }) => { + // TODO wire up + const count = 3; + + return ( + <> + + + {count} + + + +
+ {i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.curations.suggestedCuration.resultPanelTitle', + { defaultMessage: 'Promoted results' } + )} +
+
+
+ {variant === 'suggested' && ( + + +

+ {i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.curations.suggestedCuration.resultPanelDescription', + { defaultMessage: 'This curation can be automated by App Search' } + )} +

+
+
+ )} +
+ + 0 ? 'flexStart' : 'center'} + gutterSize="s" + direction="column" + className={`curationResultPanel curationResultPanel--${variant}`} + > + {results.length > 0 ? ( + results.map((result) => ( + + + + )) + ) : ( + +

+ + {i18n.translate( + 'xpack.enterpriseSearch.appSearch.engine.curations.suggestedCuration.noResultsMessage', + { defaultMessage: 'There are currently no promoted documents for this query' } + )} + +

+
+ )} +
+ + ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.test.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.test.tsx new file mode 100644 index 0000000000000..9bfc12dfe7cc2 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.test.tsx @@ -0,0 +1,55 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { mockUseParams } from '../../../../../__mocks__/react_router'; +import '../../../../__mocks__/engine_logic.mock'; + +import React from 'react'; + +import { shallow } from 'enzyme'; + +import { AppSearchPageTemplate } from '../../../layout'; + +import { CurationSuggestion } from './curation_suggestion'; + +describe('CurationSuggestion', () => { + beforeEach(() => { + jest.clearAllMocks(); + mockUseParams.mockReturnValue({ query: 'some%20query' }); + }); + + it('renders', () => { + const wrapper = shallow(); + + expect(wrapper.is(AppSearchPageTemplate)).toBe(true); + }); + + it('displays the decoded query in the title', () => { + const wrapper = shallow(); + + expect(wrapper.prop('pageHeader').pageTitle).toEqual('some query'); + }); + + // TODO This will need to come from somewhere else when wired up + it('displays an empty query if "" is encoded in as the qery', () => { + mockUseParams.mockReturnValue({ query: '%22%22' }); + + const wrapper = shallow(); + + expect(wrapper.prop('pageHeader').pageTitle).toEqual('""'); + }); + + it('displays has a button to display organic results', () => { + const wrapper = shallow(); + + expect(wrapper.find('[data-test-subj="organicResults"]').exists()).toBe(false); + wrapper.find('[data-test-subj="showOrganicResults"]').simulate('click'); + expect(wrapper.find('[data-test-subj="organicResults"]').exists()).toBe(true); + wrapper.find('[data-test-subj="showOrganicResults"]').simulate('click'); + expect(wrapper.find('[data-test-subj="organicResults"]').exists()).toBe(false); + }); +}); diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.tsx b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.tsx new file mode 100644 index 0000000000000..4fab9db47af90 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/curation_suggestion.tsx @@ -0,0 +1,120 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import React, { useState } from 'react'; + +import { + EuiButtonEmpty, + EuiFlexGroup, + EuiFlexItem, + EuiHorizontalRule, + EuiPanel, + EuiSpacer, + EuiTitle, +} from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; + +import { useDecodedParams } from '../../../../utils/encode_path_params'; +import { AppSearchPageTemplate } from '../../../layout'; +import { Result } from '../../../result'; +import { Result as ResultType } from '../../../result/types'; +import { getCurationsBreadcrumbs } from '../../utils'; + +import { CurationActionBar } from './curation_action_bar'; +import { CurationResultPanel } from './curation_result_panel'; + +import { DATA } from './temp_data'; + +export const CurationSuggestion: React.FC = () => { + const { query } = useDecodedParams(); + const [showOrganicResults, setShowOrganicResults] = useState(false); + const currentOrganicResults = [...DATA].splice(5, 4); + const proposedOrganicResults = [...DATA].splice(2, 4); + + const queryTitle = query === '""' ? query : `${query}`; + + return ( + + alert('Accepted')} + onRejectClick={() => alert('Rejected')} + /> + + + + +

Current

+
+ + +
+ + +

Suggested

+
+ + +
+
+ + + setShowOrganicResults(!showOrganicResults)} + data-test-subj="showOrganicResults" + > + {showOrganicResults ? 'Collapse' : 'Expand'} organic search results + + {showOrganicResults && ( + <> + + + + + {currentOrganicResults.length > 0 && ( + + {currentOrganicResults.map((result: ResultType) => ( + + + + ))} + + )} + + + {proposedOrganicResults.length > 0 && ( + + {proposedOrganicResults.map((result: ResultType) => ( + + + + ))} + + )} + + + + + )} + +
+ ); +}; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/index.ts new file mode 100644 index 0000000000000..9cb1809e20442 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/index.ts @@ -0,0 +1,8 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +export { CurationSuggestion } from './curation_suggestion'; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/temp_data.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/temp_data.ts new file mode 100644 index 0000000000000..83bbc977427a9 --- /dev/null +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/curation_suggestion/temp_data.ts @@ -0,0 +1,470 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import { Result } from '../../../result/types'; + +export const DATA: Result[] = [ + { + visitors: { + raw: 5028868.0, + }, + square_km: { + raw: 3082.7, + }, + world_heritage_site: { + raw: 'true', + snippet: 'true', + }, + date_established: { + raw: '1890-10-01T05:00:00+00:00', + }, + description: { + raw: "Yosemite features sheer granite cliffs, exceptionally tall waterfalls, and old-growth forests at a unique intersection of geology and hydrology. Half Dome and El Capitan rise from the park's centerpiece, the glacier-carved Yosemite Valley, and from its vertical walls drop Yosemite Falls, one of North America's tallest waterfalls at 2,425 feet (739 m) high. Three giant sequoia groves, along with a pristine wilderness in the heart of the Sierra Nevada, are home to a wide variety of rare plant and animal species.", + snippet: + 'Yosemite features sheer granite cliffs, exceptionally tall waterfalls, and old-growth forests', + }, + location: { + raw: '37.83,-119.5', + }, + acres: { + raw: 761747.5, + }, + title: { + raw: 'Yosemite', + snippet: 'Yosemite', + }, + nps_link: { + raw: 'https://www.nps.gov/yose/index.htm', + snippet: 'https://www.nps.gov/yose/index.htm', + }, + states: { + raw: ['California'], + snippet: 'California', + }, + _meta: { + engine: 'national-parks-demo', + score: 7543305.0, + id: 'park_yosemite', + }, + id: { + raw: 'park_yosemite', + }, + }, + { + visitors: { + raw: 4517585.0, + }, + square_km: { + raw: 1075.6, + }, + world_heritage_site: { + raw: 'false', + snippet: 'false', + }, + date_established: { + raw: '1915-01-26T06:00:00+00:00', + }, + description: { + raw: 'Bisected north to south by the Continental Divide, this portion of the Rockies has ecosystems varying from over 150 riparian lakes to montane and subalpine forests to treeless alpine tundra. Wildlife including mule deer, bighorn sheep, black bears, and cougars inhabit its igneous mountains and glacial valleys. Longs Peak, a classic Colorado fourteener, and the scenic Bear Lake are popular destinations, as well as the historic Trail Ridge Road, which reaches an elevation of more than 12,000 feet (3,700 m).', + snippet: + ' varying from over 150 riparian lakes to montane and subalpine forests to treeless alpine tundra. Wildlife', + }, + location: { + raw: '40.4,-105.58', + }, + acres: { + raw: 265795.2, + }, + title: { + raw: 'Rocky Mountain', + snippet: 'Rocky Mountain', + }, + nps_link: { + raw: 'https://www.nps.gov/romo/index.htm', + snippet: 'https://www.nps.gov/romo/index.htm', + }, + states: { + raw: ['Colorado'], + snippet: 'Colorado', + }, + _meta: { + engine: 'national-parks-demo', + score: 6776380.0, + id: 'park_rocky-mountain', + }, + id: { + raw: 'park_rocky-mountain', + }, + }, + { + visitors: { + raw: 4295127.0, + }, + square_km: { + raw: 595.8, + }, + world_heritage_site: { + raw: 'false', + snippet: 'false', + }, + date_established: { + raw: '1919-11-19T06:00:00+00:00', + }, + description: { + raw: 'Located at the junction of the Colorado Plateau, Great Basin, and Mojave Desert, this park contains sandstone features such as mesas, rock towers, and canyons, including the Virgin River Narrows. The various sandstone formations and the forks of the Virgin River create a wilderness divided into four ecosystems: desert, riparian, woodland, and coniferous forest.', + snippet: ' into four ecosystems: desert, riparian, woodland, and coniferous forest.', + }, + location: { + raw: '37.3,-113.05', + }, + acres: { + raw: 147237.02, + }, + title: { + raw: 'Zion', + snippet: 'Zion', + }, + nps_link: { + raw: 'https://www.nps.gov/zion/index.htm', + snippet: 'https://www.nps.gov/zion/index.htm', + }, + states: { + raw: ['Utah'], + snippet: 'Utah', + }, + _meta: { + engine: 'national-parks-demo', + score: 6442695.0, + id: 'park_zion', + }, + id: { + raw: 'park_zion', + }, + }, + { + visitors: { + raw: 3303393.0, + }, + square_km: { + raw: 198.5, + }, + world_heritage_site: { + raw: 'false', + snippet: 'false', + }, + date_established: { + raw: '1919-02-26T06:00:00+00:00', + }, + description: { + raw: 'Covering most of Mount Desert Island and other coastal islands, Acadia features the tallest mountain on the Atlantic coast of the United States, granite peaks, ocean shoreline, woodlands, and lakes. There are freshwater, estuary, forest, and intertidal habitats.', + snippet: + ' mountain on the Atlantic coast of the United States, granite peaks, ocean shoreline, woodlands, and lakes. There are freshwater, estuary, forest, and intertidal habitats.', + }, + location: { + raw: '44.35,-68.21', + }, + acres: { + raw: 49057.36, + }, + title: { + raw: 'Acadia', + snippet: 'Acadia', + }, + nps_link: { + raw: 'https://www.nps.gov/acad/index.htm', + snippet: 'https://www.nps.gov/acad/index.htm', + }, + states: { + raw: ['Maine'], + snippet: 'Maine', + }, + _meta: { + engine: 'national-parks-demo', + score: 4955094.5, + id: 'park_acadia', + }, + id: { + raw: 'park_acadia', + }, + }, + { + visitors: { + raw: 1887580.0, + }, + square_km: { + raw: 1308.9, + }, + world_heritage_site: { + raw: 'true', + snippet: 'true', + }, + date_established: { + raw: '1916-08-01T05:00:00+00:00', + }, + description: { + raw: "This park on the Big Island protects the Kīlauea and Mauna Loa volcanoes, two of the world's most active geological features. Diverse ecosystems range from tropical forests at sea level to barren lava beds at more than 13,000 feet (4,000 m).", + snippet: + ' active geological features. Diverse ecosystems range from tropical forests at sea level to barren lava beds at more than 13,000 feet (4,000 m).', + }, + location: { + raw: '19.38,-155.2', + }, + acres: { + raw: 323431.38, + }, + title: { + raw: 'Hawaii Volcanoes', + snippet: 'Hawaii Volcanoes', + }, + nps_link: { + raw: 'https://www.nps.gov/havo/index.htm', + snippet: 'https://www.nps.gov/havo/index.htm', + }, + states: { + raw: ['Hawaii'], + snippet: 'Hawaii', + }, + _meta: { + engine: 'national-parks-demo', + score: 2831373.2, + id: 'park_hawaii-volcanoes', + }, + id: { + raw: 'park_hawaii-volcanoes', + }, + }, + { + visitors: { + raw: 1437341.0, + }, + square_km: { + raw: 806.1, + }, + world_heritage_site: { + raw: 'false', + snippet: 'false', + }, + date_established: { + raw: '1935-12-26T06:00:00+00:00', + }, + description: { + raw: "Shenandoah's Blue Ridge Mountains are covered by hardwood forests that teem with a wide variety of wildlife. The Skyline Drive and Appalachian Trail run the entire length of this narrow park, along with more than 500 miles (800 km) of hiking trails passing scenic overlooks and cataracts of the Shenandoah River.", + snippet: + 'Shenandoah's Blue Ridge Mountains are covered by hardwood forests that teem with a wide variety', + }, + location: { + raw: '38.53,-78.35', + }, + acres: { + raw: 199195.27, + }, + title: { + raw: 'Shenandoah', + snippet: 'Shenandoah', + }, + nps_link: { + raw: 'https://www.nps.gov/shen/index.htm', + snippet: 'https://www.nps.gov/shen/index.htm', + }, + states: { + raw: ['Virginia'], + snippet: 'Virginia', + }, + _meta: { + engine: 'national-parks-demo', + score: 2156015.5, + id: 'park_shenandoah', + }, + id: { + raw: 'park_shenandoah', + }, + }, + { + visitors: { + raw: 1356913.0, + }, + square_km: { + raw: 956.6, + }, + world_heritage_site: { + raw: 'false', + snippet: 'false', + }, + date_established: { + raw: '1899-03-02T06:00:00+00:00', + }, + description: { + raw: 'Mount Rainier, an active stratovolcano, is the most prominent peak in the Cascades and is covered by 26 named glaciers including Carbon Glacier and Emmons Glacier, the largest in the contiguous United States. The mountain is popular for climbing, and more than half of the park is covered by subalpine and alpine forests and meadows seasonally in bloom with wildflowers. Paradise on the south slope is the snowiest place on Earth where snowfall is measured regularly. The Longmire visitor center is the start of the Wonderland Trail, which encircles the mountain.', + snippet: + ' by subalpine and alpine forests and meadows seasonally in bloom with wildflowers. Paradise on the south slope', + }, + location: { + raw: '46.85,-121.75', + }, + acres: { + raw: 236381.64, + }, + title: { + raw: 'Mount Rainier', + snippet: 'Mount Rainier', + }, + nps_link: { + raw: 'https://www.nps.gov/mora/index.htm', + snippet: 'https://www.nps.gov/mora/index.htm', + }, + states: { + raw: ['Washington'], + snippet: 'Washington', + }, + _meta: { + engine: 'national-parks-demo', + score: 2035372.0, + id: 'park_mount-rainier', + }, + id: { + raw: 'park_mount-rainier', + }, + }, + { + visitors: { + raw: 1254688.0, + }, + square_km: { + raw: 1635.2, + }, + world_heritage_site: { + raw: 'false', + snippet: 'false', + }, + date_established: { + raw: '1890-09-25T05:00:00+00:00', + }, + description: { + raw: "This park protects the Giant Forest, which boasts some of the world's largest trees, the General Sherman being the largest measured tree in the park. Other features include over 240 caves, a long segment of the Sierra Nevada including the tallest mountain in the contiguous United States, and Moro Rock, a large granite dome.", + snippet: + 'This park protects the Giant Forest, which boasts some of the world's largest trees, the General', + }, + location: { + raw: '36.43,-118.68', + }, + acres: { + raw: 404062.63, + }, + title: { + raw: 'Sequoia', + snippet: 'Sequoia', + }, + nps_link: { + raw: 'https://www.nps.gov/seki/index.htm', + snippet: 'https://www.nps.gov/seki/index.htm', + }, + states: { + raw: ['California'], + snippet: 'California', + }, + _meta: { + engine: 'national-parks-demo', + score: 1882038.0, + id: 'park_sequoia', + }, + id: { + raw: 'park_sequoia', + }, + }, + { + visitors: { + raw: 643274.0, + }, + square_km: { + raw: 896.0, + }, + world_heritage_site: { + raw: 'false', + snippet: 'false', + }, + date_established: { + raw: '1962-12-09T06:00:00+00:00', + }, + description: { + raw: 'This portion of the Chinle Formation has a large concentration of 225-million-year-old petrified wood. The surrounding Painted Desert features eroded cliffs of red-hued volcanic rock called bentonite. Dinosaur fossils and over 350 Native American sites are also protected in this park.', + snippet: + 'This portion of the Chinle Formation has a large concentration of 225-million-year-old petrified', + }, + location: { + raw: '35.07,-109.78', + }, + acres: { + raw: 221415.77, + }, + title: { + raw: 'Petrified Forest', + snippet: 'Petrified Forest', + }, + nps_link: { + raw: 'https://www.nps.gov/pefo/index.htm', + snippet: 'https://www.nps.gov/pefo/index.htm', + }, + states: { + raw: ['Arizona'], + snippet: 'Arizona', + }, + _meta: { + engine: 'national-parks-demo', + score: 964919.94, + id: 'park_petrified-forest', + }, + id: { + raw: 'park_petrified-forest', + }, + }, + { + visitors: { + raw: 617377.0, + }, + square_km: { + raw: 137.5, + }, + world_heritage_site: { + raw: 'false', + snippet: 'false', + }, + date_established: { + raw: '1903-01-09T06:00:00+00:00', + }, + description: { + raw: "Wind Cave is distinctive for its calcite fin formations called boxwork, a unique formation rarely found elsewhere, and needle-like growths called frostwork. The cave is one of the longest and most complex caves in the world. Above ground is a mixed-grass prairie with animals such as bison, black-footed ferrets, and prairie dogs, and ponderosa pine forests that are home to cougars and elk. The cave is culturally significant to the Lakota people as the site 'from which Wakan Tanka, the Great Mystery, sent the buffalo out into their hunting grounds.'", + snippet: + '-footed ferrets, and prairie dogs, and ponderosa pine forests that are home to cougars and elk', + }, + location: { + raw: '43.57,-103.48', + }, + acres: { + raw: 33970.84, + }, + title: { + raw: 'Wind Cave', + snippet: 'Wind Cave', + }, + nps_link: { + raw: 'https://www.nps.gov/wica/index.htm', + snippet: 'https://www.nps.gov/wica/index.htm', + }, + states: { + raw: ['South Dakota'], + snippet: 'South Dakota', + }, + _meta: { + engine: 'national-parks-demo', + score: 926068.7, + id: 'park_wind-cave', + }, + id: { + raw: 'park_wind-cave', + }, + }, +]; diff --git a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/index.ts b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/index.ts index ca6924879324a..7268c0fdbc4dc 100644 --- a/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/index.ts +++ b/x-pack/plugins/enterprise_search/public/applications/app_search/components/curations/views/index.ts @@ -7,3 +7,4 @@ export { Curations } from './curations'; export { CurationCreation } from './curation_creation'; +export { CurationSuggestion } from './curation_suggestion'; diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/category_facets.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/category_facets.tsx index daa0520ebc041..d60ccd93b8db1 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/category_facets.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/category_facets.tsx @@ -11,22 +11,24 @@ import React from 'react'; import { i18n } from '@kbn/i18n'; import { Loading } from '../../../../components'; -import type { CategoryCount } from '../../../../../../../../../../src/plugins/custom_integrations/common'; -import { CATEGORY_DISPLAY } from '../../../../../../../../../../src/plugins/custom_integrations/common'; +import type { IntegrationCategoryCount } from '../../../../../../../../../../src/plugins/custom_integrations/common'; +import { INTEGRATION_CATEGORY_DISPLAY } from '../../../../../../../../../../src/plugins/custom_integrations/common'; interface ALL_CATEGORY { id: ''; count: number; } -export type CategoryFacet = CategoryCount | ALL_CATEGORY; +export type CategoryFacet = IntegrationCategoryCount | ALL_CATEGORY; export function CategoryFacets({ + showCounts, isLoading, categories, selectedCategory, onCategoryChange, }: { + showCounts: boolean; isLoading?: boolean; categories: CategoryFacet[]; selectedCategory: string; @@ -49,14 +51,14 @@ export function CategoryFacets({ defaultMessage: 'All', }); } else { - title = CATEGORY_DISPLAY[category.id]; + title = INTEGRATION_CATEGORY_DISPLAY[category.id]; } return ( onCategoryChange(category)} > {title} diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/index.tsx b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/index.tsx index 48a9dc0f6b63c..27e2d11769ef8 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/index.tsx +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/index.tsx @@ -21,7 +21,8 @@ import { useGetCategories, useGetPackages, useBreadcrumbs, - useGetAddableCustomIntegrations, + useGetAppendCustomIntegrations, + useGetReplacementCustomIntegrations, useLink, } from '../../../../hooks'; import { doesPackageHaveIntegrations } from '../../../../services'; @@ -35,7 +36,9 @@ import type { PackageListItem } from '../../../../types'; import type { IntegrationCardItem } from '../../../../../../../common/types/models'; -import type { Category } from '../../../../../../../../../../src/plugins/custom_integrations/common'; +import type { IntegrationCategory } from '../../../../../../../../../../src/plugins/custom_integrations/common'; + +import { useMergeEprPackagesWithReplacements } from '../../../../../../hooks/use_merge_epr_with_replacements'; import { mergeAndReplaceCategoryCounts } from './util'; import { CategoryFacets } from './category_facets'; @@ -209,6 +212,7 @@ const InstalledPackages: React.FC = memo(() => { const controls = ( setSelectedCategory(id)} @@ -266,6 +270,7 @@ const AvailablePackages: React.FC = memo(() => { const { data: categoriesRes, isLoading: isLoadingCategories } = useGetCategories({ include_policy_templates: true, }); + const eprPackages = useMemo( () => packageListToIntegrationsList(categoryPackagesRes?.response || []), [categoryPackagesRes] @@ -276,14 +281,23 @@ const AvailablePackages: React.FC = memo(() => { [allCategoryPackagesRes] ); - const { loading: isLoadingAddableCustomIntegrations, value: addableCustomIntegrations } = - useGetAddableCustomIntegrations(); - const filteredAddableIntegrations = addableCustomIntegrations - ? addableCustomIntegrations.filter((integration: CustomIntegration) => { + const { value: replacementCustomIntegrations } = useGetReplacementCustomIntegrations(); + + const mergedEprPackages: Array = + useMergeEprPackagesWithReplacements( + eprPackages || [], + replacementCustomIntegrations || [], + selectedCategory as IntegrationCategory + ); + + const { loading: isLoadingAppendCustomIntegrations, value: appendCustomIntegrations } = + useGetAppendCustomIntegrations(); + const filteredAddableIntegrations = appendCustomIntegrations + ? appendCustomIntegrations.filter((integration: CustomIntegration) => { if (!selectedCategory) { return true; } - return integration.categories.indexOf(selectedCategory as Category) >= 0; + return integration.categories.indexOf(selectedCategory as IntegrationCategory) >= 0; }) : []; @@ -296,7 +310,7 @@ const AvailablePackages: React.FC = memo(() => { ); const eprAndCustomPackages: Array = [ - ...eprPackages, + ...mergedEprPackages, ...filteredAddableIntegrations, ]; eprAndCustomPackages.sort((a, b) => { @@ -306,26 +320,26 @@ const AvailablePackages: React.FC = memo(() => { const categories = useMemo(() => { const eprAndCustomCategories: CategoryFacet[] = isLoadingCategories || - isLoadingAddableCustomIntegrations || - !addableCustomIntegrations || + isLoadingAppendCustomIntegrations || + !appendCustomIntegrations || !categoriesRes ? [] : mergeAndReplaceCategoryCounts( categoriesRes.response as CategoryFacet[], - addableCustomIntegrations + appendCustomIntegrations ); return [ { id: '', - count: (allEprPackages?.length || 0) + (addableCustomIntegrations?.length || 0), + count: (allEprPackages?.length || 0) + (appendCustomIntegrations?.length || 0), }, ...(eprAndCustomCategories ? eprAndCustomCategories : []), ] as CategoryFacet[]; }, [ allEprPackages?.length, - addableCustomIntegrations, + appendCustomIntegrations, categoriesRes, - isLoadingAddableCustomIntegrations, + isLoadingAppendCustomIntegrations, isLoadingCategories, ]); @@ -336,7 +350,8 @@ const AvailablePackages: React.FC = memo(() => { const controls = categories ? ( { diff --git a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/util.ts b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/util.ts index 2f0e4f71ea59d..53a62555650ab 100644 --- a/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/util.ts +++ b/x-pack/plugins/fleet/public/applications/integrations/sections/epm/screens/home/util.ts @@ -7,7 +7,7 @@ import type { CustomIntegration, - Category, + IntegrationCategory, } from '../../../../../../../../../../src/plugins/custom_integrations/common'; import type { CategoryFacet } from './category_facets'; @@ -27,7 +27,7 @@ export function mergeAndReplaceCategoryCounts( match.count += count; } else { merged.push({ - id: category as Category, + id: category as IntegrationCategory, count, }); } diff --git a/x-pack/plugins/fleet/public/hooks/use_merge_epr_with_replacements.test.ts b/x-pack/plugins/fleet/public/hooks/use_merge_epr_with_replacements.test.ts new file mode 100644 index 0000000000000..687fb01b04546 --- /dev/null +++ b/x-pack/plugins/fleet/public/hooks/use_merge_epr_with_replacements.test.ts @@ -0,0 +1,220 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { PackageListItem } from '../../common/types/models'; +import type { CustomIntegration } from '../../../../../src/plugins/custom_integrations/common'; + +import type { IntegrationCategory } from '../../../../../src/plugins/custom_integrations/common'; + +import { useMergeEprPackagesWithReplacements } from './use_merge_epr_with_replacements'; + +function mockEprPackages( + items: Array<{ name: string; release: 'ga' | 'beta' | 'experimental'; integration?: string }> +): PackageListItem[] { + return items as unknown as PackageListItem[]; +} + +function mockIntegrations( + items: Array<{ eprOverlap?: string; id: string; categories: IntegrationCategory[] }> +): CustomIntegration[] { + return items as unknown as CustomIntegration[]; +} + +describe('useMergeEprWithReplacements', () => { + test('should not replace ga packages', () => { + const eprPackages: PackageListItem[] = mockEprPackages([ + { + name: 'aws', + release: 'ga', + integration: 'cloudwatch', + }, + { + name: 'aws', + release: 'ga', + integration: 's3', + }, + ]); + const replacements: CustomIntegration[] = mockIntegrations([ + { + eprOverlap: 'aws', + id: 'awsLogs', + categories: ['cloud', 'datastore'], + }, + ]); + + expect(useMergeEprPackagesWithReplacements(eprPackages, replacements, '')).toEqual([ + { + name: 'aws', + release: 'ga', + integration: 'cloudwatch', + }, + { + name: 'aws', + release: 'ga', + integration: 's3', + }, + ]); + }); + + test('should replace non-ga packages', () => { + const eprPackages: PackageListItem[] = mockEprPackages([ + { + name: 'activemq', + release: 'beta', + }, + ]); + const replacements: CustomIntegration[] = mockIntegrations([ + { + eprOverlap: 'activemq', + id: 'activemq-logs', + categories: ['web'], + }, + { + eprOverlap: 'activemq', + id: 'activemq-metrics', + categories: ['web'], + }, + ]); + + expect(useMergeEprPackagesWithReplacements(eprPackages, replacements, '')).toEqual([ + { + eprOverlap: 'activemq', + id: 'activemq-logs', + categories: ['web'], + }, + { + eprOverlap: 'activemq', + id: 'activemq-metrics', + categories: ['web'], + }, + ]); + }); + + test('should merge if no equivalent package', () => { + const eprPackages: PackageListItem[] = mockEprPackages([ + { + name: 'activemq', + release: 'beta', + }, + ]); + const replacements: CustomIntegration[] = mockIntegrations([ + { + id: 'prometheus', + categories: ['monitoring', 'datastore'], + }, + ]); + + expect(useMergeEprPackagesWithReplacements(eprPackages, replacements, '')).toEqual([ + { + name: 'activemq', + release: 'beta', + }, + { + id: 'prometheus', + categories: ['monitoring', 'datastore'], + }, + ]); + }); + + test('should respect category assignment', () => { + const eprPackages: PackageListItem[] = mockEprPackages([ + { + name: 'activemq', + release: 'beta', + }, + ]); + const replacements: CustomIntegration[] = mockIntegrations([ + { + id: 'prometheus', + categories: ['monitoring', 'datastore'], + }, + { + id: 'oracle', + categories: ['datastore'], + }, + ]); + + expect(useMergeEprPackagesWithReplacements(eprPackages, replacements, 'web')).toEqual([ + { + name: 'activemq', + release: 'beta', + }, + ]); + }); + + test('should consists of all 3 types (ga eprs, replacements for non-ga eprs, replacements without epr equivalent', () => { + const eprPackages: PackageListItem[] = mockEprPackages([ + { + name: 'aws', + release: 'ga', + integration: 'cloudwatch', + }, + { + name: 'aws', + release: 'ga', + integration: 's3', + }, + { + name: 'activemq', + release: 'beta', + }, + ]); + const replacements: CustomIntegration[] = mockIntegrations([ + { + id: 'prometheus', + categories: ['monitoring', 'datastore'], + }, + { + eprOverlap: 'activemq', + id: 'activemq-logs', + categories: ['web'], + }, + { + eprOverlap: 'activemq', + id: 'activemq-metrics', + categories: ['web'], + }, + { + eprOverlap: 'aws', + id: 'awsLogs', + categories: ['cloud', 'datastore'], + }, + { + eprOverlap: 'aws', + id: 'awsMetrics', + categories: ['cloud', 'datastore'], + }, + ]); + + expect(useMergeEprPackagesWithReplacements(eprPackages, replacements, '')).toEqual([ + { + name: 'aws', + release: 'ga', + integration: 'cloudwatch', + }, + { + name: 'aws', + release: 'ga', + integration: 's3', + }, + { + eprOverlap: 'activemq', + id: 'activemq-logs', + categories: ['web'], + }, + { + eprOverlap: 'activemq', + id: 'activemq-metrics', + categories: ['web'], + }, + { + id: 'prometheus', + categories: ['monitoring', 'datastore'], + }, + ]); + }); +}); diff --git a/x-pack/plugins/fleet/public/hooks/use_merge_epr_with_replacements.ts b/x-pack/plugins/fleet/public/hooks/use_merge_epr_with_replacements.ts new file mode 100644 index 0000000000000..a3c1fea5e744f --- /dev/null +++ b/x-pack/plugins/fleet/public/hooks/use_merge_epr_with_replacements.ts @@ -0,0 +1,71 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License + * 2.0; you may not use this file except in compliance with the Elastic License + * 2.0. + */ + +import type { PackageListItem } from '../../common/types/models'; +import type { + CustomIntegration, + IntegrationCategory, +} from '../../../../../src/plugins/custom_integrations/common'; + +// Export this as a utility to find replacements for a package (e.g. in the overview-page for an EPR package) +function findReplacementsForEprPackage( + replacements: CustomIntegration[], + packageName: string, + release: 'beta' | 'experimental' | 'ga' +): CustomIntegration[] { + if (release === 'ga') { + return []; + } + return replacements.filter((customIntegration: CustomIntegration) => { + return customIntegration.eprOverlap === packageName; + }); +} + +export function useMergeEprPackagesWithReplacements( + eprPackages: PackageListItem[], + replacements: CustomIntegration[], + category: IntegrationCategory | '' +): Array { + const merged: Array = []; + + const filteredReplacements = replacements.filter((customIntegration) => { + return !category || customIntegration.categories.includes(category); + }); + + // Either select replacement or select beat + eprPackages.forEach((eprPackage) => { + const hits = findReplacementsForEprPackage( + filteredReplacements, + eprPackage.name, + eprPackage.release + ); + if (hits.length) { + hits.forEach((hit) => { + const match = merged.find(({ id }) => { + return id === hit.id; + }); + if (!match) { + merged.push(hit); + } + }); + } else { + merged.push(eprPackage); + } + }); + + // Add unused replacements + // This is an edge-case. E.g. the Oracle-beat did not have an Epr-equivalent at the time of writing + const unusedReplacements = filteredReplacements.filter((integration) => { + return !eprPackages.find((eprPackage) => { + return eprPackage.name === integration.eprOverlap; + }); + }); + + merged.push(...unusedReplacements); + + return merged; +} diff --git a/x-pack/plugins/fleet/public/hooks/use_request/epm.ts b/x-pack/plugins/fleet/public/hooks/use_request/epm.ts index 650667000409a..d6764aac7de00 100644 --- a/x-pack/plugins/fleet/public/hooks/use_request/epm.ts +++ b/x-pack/plugins/fleet/public/hooks/use_request/epm.ts @@ -24,11 +24,16 @@ import { getCustomIntegrations } from '../../services/custom_integrations'; import { useRequest, sendRequest } from './use_request'; -export function useGetAddableCustomIntegrations() { +export function useGetAppendCustomIntegrations() { const customIntegrations = getCustomIntegrations(); return useAsync(customIntegrations.getAppendCustomIntegrations, []); } +export function useGetReplacementCustomIntegrations() { + const customIntegrations = getCustomIntegrations(); + return useAsync(customIntegrations.getReplacementCustomIntegrations, []); +} + export const useGetCategories = (query: GetCategoriesRequest['query'] = {}) => { return useRequest({ path: epmRouteService.getCategoriesPath(), diff --git a/x-pack/plugins/fleet/server/integration_tests/router.test.ts b/x-pack/plugins/fleet/server/integration_tests/router.test.ts index d5f40e4db2cfe..55518923e65f2 100644 --- a/x-pack/plugins/fleet/server/integration_tests/router.test.ts +++ b/x-pack/plugins/fleet/server/integration_tests/router.test.ts @@ -19,7 +19,6 @@ import * as kbnTestServer from '../../../../../src/test_utils/kbn_server'; function createXPackRoot(config: {} = {}) { return kbnTestServer.createRoot({ plugins: { - scanDirs: [], paths: [ resolve(__dirname, '../../../../../x-pack/plugins/encrypted_saved_objects'), resolve(__dirname, '../../../../../x-pack/plugins/fleet'), diff --git a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx index b1a37caf149d9..6a5019d4683c8 100644 --- a/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx +++ b/x-pack/plugins/infra/public/alerting/metric_threshold/components/expression.tsx @@ -260,6 +260,28 @@ export const Expressions: React.FC = (props) => { [alertParams.groupBy] ); + const groupByFilterTestPatterns = useMemo(() => { + if (!alertParams.groupBy) return null; + const groups = !Array.isArray(alertParams.groupBy) + ? [alertParams.groupBy] + : alertParams.groupBy; + return groups.map((group: string) => ({ + groupName: group, + pattern: new RegExp(`{"match(_phrase)?":{"${group}":"(.*?)"}}`), + })); + }, [alertParams.groupBy]); + + const redundantFilterGroupBy = useMemo(() => { + if (!alertParams.filterQuery || !groupByFilterTestPatterns) return []; + return groupByFilterTestPatterns + .map(({ groupName, pattern }) => { + if (pattern.test(alertParams.filterQuery!)) { + return groupName; + } + }) + .filter((g) => typeof g === 'string') as string[]; + }, [alertParams.filterQuery, groupByFilterTestPatterns]); + return ( <> @@ -425,8 +447,24 @@ export const Expressions: React.FC = (props) => { ...options, groupBy: alertParams.groupBy || undefined, }} + errorOptions={redundantFilterGroupBy} /> + {redundantFilterGroupBy.length > 0 && ( + <> + + + {redundantFilterGroupBy.join(', ')}, + groupCount: redundantFilterGroupBy.length, + }} + /> + + + )} void; fields: IFieldType[]; + errorOptions?: string[]; } -export const MetricsExplorerGroupBy = ({ options, onChange, fields }: Props) => { +export const MetricsExplorerGroupBy = ({ options, onChange, fields, errorOptions }: Props) => { const handleChange = useCallback( (selectedOptions: Array<{ label: string }>) => { const groupBy = selectedOptions.map((option) => option.label); @@ -28,9 +29,17 @@ export const MetricsExplorerGroupBy = ({ options, onChange, fields }: Props) => ); const selectedOptions = Array.isArray(options.groupBy) - ? options.groupBy.map((field) => ({ label: field })) + ? options.groupBy.map((field) => ({ + label: field, + color: errorOptions?.includes(field) ? 'danger' : undefined, + })) : options.groupBy - ? [{ label: options.groupBy }] + ? [ + { + label: options.groupBy, + color: errorOptions?.includes(options.groupBy) ? 'danger' : undefined, + }, + ] : []; return ( diff --git a/x-pack/plugins/lens/public/_mixins.scss b/x-pack/plugins/lens/public/_mixins.scss index 5a798bcc6c23b..7282de214636c 100644 --- a/x-pack/plugins/lens/public/_mixins.scss +++ b/x-pack/plugins/lens/public/_mixins.scss @@ -15,7 +15,7 @@ // Static styles for a draggable item @mixin lnsDraggable { @include euiSlightShadow; - background: lightOrDarkTheme($euiColorEmptyShade, $euiColorLightestShade); + background: $euiColorEmptyShade; border: $euiBorderWidthThin dashed transparent; cursor: grab; } diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/add_layer.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/add_layer.tsx index 69e4aa629cec6..e052e06f1b2f1 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/add_layer.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/add_layer.tsx @@ -64,7 +64,6 @@ export function AddLayerButton({ diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.scss deleted file mode 100644 index 0d51108fb2dcb..0000000000000 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.scss +++ /dev/null @@ -1,10 +0,0 @@ -.lnsConfigPanel__addLayerBtn { - @include kbnThemeStyle('v7') { - // sass-lint:disable-block no-important - background-color: transparent !important; - color: transparentize($euiColorMediumShade, .3) !important; - border-color: $euiColorLightShade !important; - box-shadow: none !important; - } - -} diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx index 57e4cf5b8dffd..0b6223ac87ce2 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/config_panel.tsx @@ -5,8 +5,6 @@ * 2.0. */ -import './config_panel.scss'; - import React, { useMemo, memo } from 'react'; import { EuiForm } from '@elastic/eui'; import { mapValues } from 'lodash'; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_container.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_container.scss index 135286fc2172b..692db8171d124 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_container.scss +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_container.scss @@ -24,48 +24,24 @@ } } -.lnsDimensionContainer__footer { - padding: $euiSizeS; - - .lnsFrameLayout__sidebar-isFullscreen & { - display: none; - } -} - .lnsDimensionContainer__header { - padding: $euiSizeS $euiSizeXS; + padding: $euiSize; .lnsFrameLayout__sidebar-isFullscreen & { display: none; } } -.lnsDimensionContainer__headerTitle { - padding: $euiSizeS $euiSizeXS; - cursor: pointer; - - &:hover { - text-decoration: underline; - } +.lnsDimensionContainer__content { + @include euiYScroll; + flex: 1; } -.lnsDimensionContainer__headerLink { - &:focus-within { - background-color: transparentize($euiColorVis1, .9); - - .lnsDimensionContainer__headerTitle { - text-decoration: underline; - } - } -} - -.lnsDimensionContainer__backIcon { - &:hover { - transform: none !important; // sass-lint:disable-line no-important - } +.lnsDimensionContainer__footer { + padding: $euiSize; - &:focus { - background-color: transparent; + .lnsFrameLayout__sidebar-isFullscreen & { + display: none; } } diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_container.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_container.tsx index c62b10093e6e5..f7402e78ebd96 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_container.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/dimension_container.tsx @@ -98,13 +98,7 @@ export function DimensionContainer({ }} > - +

+ - - {panel} - + +
{panel}
+ {i18n.translate('xpack.lens.dimensionContainer.close', { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.scss b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.scss index 7a1cbb8237f50..781a08d0f60bb 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.scss +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.scss @@ -36,32 +36,32 @@ background: $euiColorLightestShade; padding: $euiSize; + &:last-child { + border-radius: 0 0 $euiBorderRadius $euiBorderRadius; + } + // Add border to the top of the next same panel & + & { border-top: $euiBorderThin; margin-top: 0; } - &:last-child { - border-bottom-right-radius: $euiBorderRadius; - border-bottom-left-radius: $euiBorderRadius; + + & > * { + margin-bottom: 0; } -} -.lnsLayerPanel__row--notSupportsMoreColumns { - padding-bottom: 0; + // Targeting EUI class as we are unable to apply a class to this element in component + &, + .euiFormRow__fieldWrapper { + & > * + * { + margin-top: $euiSize; + } + } } .lnsLayerPanel__group { - padding: $euiSizeS 0; - margin-bottom: $euiSizeS; -} - -.lnsLayerPanel__group:empty { - padding: 0; -} - -.lnsLayerPanel__error { - padding: 0 $euiSizeS; + margin: (-$euiSizeS) (-$euiSize); + padding: $euiSizeS $euiSize; } .lnsLayerPanel__dimension { @@ -87,11 +87,10 @@ } .lnsLayerPanel__dimensionContainer { - margin: 0 0 $euiSizeS; position: relative; - &:last-child { - margin-bottom: 0; + & + & { + margin-top: $euiSizeS; } } @@ -105,6 +104,10 @@ min-height: $euiSizeXXL - 2; word-break: break-word; font-weight: $euiFontWeightRegular; + + @include kbnThemeStyle('v7') { + font-size: $euiFontSizeS; + } } .lnsLayerPanel__triggerTextLabel { @@ -119,7 +122,8 @@ } .lnsLayerPanel__styleEditor { - padding: 0 $euiSizeS $euiSizeS; + margin-top: -$euiSizeS; + padding: 0 $euiSize $euiSize; } .lnsLayerPanel__colorIndicator { diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx index f777fd0976dfd..5b432f85efde2 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.test.tsx @@ -222,7 +222,7 @@ describe('LayerPanel', () => { const group = instance .find(EuiFormRow) - .findWhere((e) => e.prop('error')?.props?.children === 'Required dimension'); + .findWhere((e) => e.prop('error') === 'Required dimension'); expect(group).toHaveLength(1); }); diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx index 6e2e77af4f3b0..8d19620cebbdc 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/config_panel/layer_panel.tsx @@ -326,12 +326,7 @@ export function LayerPanel( className="lnsLayerPanel" style={{ visibility: isDimensionPanelOpen ? 'hidden' : 'visible' }} > - +
@@ -394,16 +389,13 @@ export function LayerPanel( {groups.map((group, groupIndex) => { const isMissing = !isEmptyLayer && group.required && group.accessors.length === 0; + return ( + <> {group.groupLabel} {group.groupTooltip && ( <> @@ -420,92 +412,91 @@ export function LayerPanel( /> )} - + } labelType="legend" key={group.groupId} isInvalid={isMissing} error={ - isMissing ? ( -
- {i18n.translate('xpack.lens.editorFrame.requiredDimensionWarningLabel', { + isMissing + ? i18n.translate('xpack.lens.editorFrame.requiredDimensionWarningLabel', { defaultMessage: 'Required dimension', - })} -
- ) : ( - [] - ) + }) + : [] } > <> - - {group.accessors.map((accessorConfig, accessorIndex) => { - const { columnId } = accessorConfig; - - return ( - -
- { - setActiveDimension({ - isNew: false, - activeGroup: group, - activeId: id, - }); - }} - onRemoveClick={(id: string) => { - trackUiEvent('indexpattern_dimension_removed'); - props.updateAll( - datasourceId, - layerDatasource.removeColumn({ - layerId, - columnId: id, - prevState: layerDatasourceState, - }), - activeVisualization.removeDimension({ - layerId, - columnId: id, - prevState: props.visualizationState, - frame: framePublicAPI, - }) - ); - removeButtonRef(id); - }} - > - + {group.accessors.map((accessorConfig, accessorIndex) => { + const { columnId } = accessorConfig; + + return ( + +
+ { + setActiveDimension({ + isNew: false, + activeGroup: group, + activeId: id, + }); }} - /> - -
-
- ); - })} - + onRemoveClick={(id: string) => { + trackUiEvent('indexpattern_dimension_removed'); + props.updateAll( + datasourceId, + layerDatasource.removeColumn({ + layerId, + columnId: id, + prevState: layerDatasourceState, + }), + activeVisualization.removeDimension({ + layerId, + columnId: id, + prevState: props.visualizationState, + frame: framePublicAPI, + }) + ); + removeButtonRef(id); + }} + > + +
+
+
+ ); + })} +
+ ) : null} + {group.supportsMoreColumns ? ( * { flex: 1 1 100%; @@ -38,10 +42,13 @@ } .lnsWorkspacePanel__dragDrop { - width: 100%; - height: 100%; - border: $euiBorderThin; - border-radius: $euiBorderRadiusSmall; + @include kbnThemeStyle('v7') { + border: $euiBorderThin; + } + + @include kbnThemeStyle('v8') { + border: $euiBorderWidthThin solid transparent; + } &.lnsDragDrop-isDropTarget { @include lnsDroppable; diff --git a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx index e1cb1aeb9f825..d8959e714d16e 100644 --- a/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx +++ b/x-pack/plugins/lens/public/editor_frame_service/editor_frame/workspace_panel/workspace_panel_wrapper.tsx @@ -125,10 +125,15 @@ export function WorkspacePanelWrapper({
+ {children} diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.scss b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.scss index 0303e6549d8df..c93f05c6eb19a 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.scss +++ b/x-pack/plugins/lens/public/indexpattern_datasource/datapanel.scss @@ -54,6 +54,5 @@ .lnsLayerPanelChartSwitch_title { font-weight: 600; display: inline; - vertical-align: middle; padding-left: 8px; } \ No newline at end of file diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.scss b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.scss index 874291ae25e34..30e2e00c7c85d 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.scss +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.scss @@ -6,8 +6,8 @@ position: sticky; top: 0; background: $euiColorEmptyShade; - // Raise it above the elements that are after it in DOM order - z-index: $euiZLevel1; + z-index: $euiZLevel1; // Raise it above the elements that are after it in DOM order + padding: 0 $euiSize; } .lnsIndexPatternDimensionEditor-isFullscreen { @@ -23,21 +23,14 @@ } .lnsIndexPatternDimensionEditor__section--padded { - padding: $euiSizeS; + padding: $euiSize; } .lnsIndexPatternDimensionEditor__section--shaded { background-color: $euiColorLightestShade; -} - -.lnsIndexPatternDimensionEditor__section--top { border-bottom: $euiBorderThin; } -.lnsIndexPatternDimensionEditor__section--bottom { - border-top: $euiBorderThin; -} - .lnsIndexPatternDimensionEditor__columns { column-count: 2; column-gap: $euiSizeXL; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx index 333e76f5a4f57..29bbe6a96b9e1 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/dimension_panel/dimension_editor.tsx @@ -422,7 +422,7 @@ export function DimensionEditor(props: DimensionEditorProps) { maxWidth={false} /> - +
{!incompleteInfo && selectedColumn && @@ -636,8 +636,6 @@ export function DimensionEditor(props: DimensionEditorProps) { /> )}
- - ); diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula.scss b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula.scss index d66e19bec8a1c..92a778ebfb803 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula.scss +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula.scss @@ -17,8 +17,6 @@ } .lnsFormula__editor { - border-bottom: $euiBorderThin; - .lnsIndexPatternDimensionEditor-isFullscreen & { border-bottom: none; display: flex; @@ -32,7 +30,7 @@ .lnsFormula__editorHeader, .lnsFormula__editorFooter { - padding: $euiSizeS; + padding: $euiSizeS $euiSize; } .lnsFormula__editorFooter { @@ -130,7 +128,7 @@ } .lnsFormula__docsSearch { - padding: $euiSizeS; + padding: $euiSize; } .lnsFormula__docsNav { @@ -138,7 +136,7 @@ } .lnsFormula__docsNavGroup { - padding: $euiSizeS; + padding: $euiSize; & + & { border-top: $euiBorderThin; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_editor.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_editor.tsx index 4f6f13ea843ef..7abe80003ea0e 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_editor.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_editor.tsx @@ -549,6 +549,8 @@ export function FormulaEditor({ dimension: { width: 320, height: 200 }, fixedOverflowWidgets: true, matchBrackets: 'always', + // Undocumented Monaco option to force left margin width + lineDecorationsWidth: 16, }, }; diff --git a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_help.tsx b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_help.tsx index 3c3068a595bc0..47dd8fbc9c569 100644 --- a/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_help.tsx +++ b/x-pack/plugins/lens/public/indexpattern_datasource/operations/definitions/formula/editor/formula_help.tsx @@ -18,6 +18,7 @@ import { EuiTitle, EuiFieldSearch, EuiHighlight, + EuiSpacer, } from '@elastic/eui'; import { Markdown } from '../../../../../../../../../src/plugins/kibana_react/public'; import { IndexPattern } from '../../../../types'; @@ -298,7 +299,7 @@ sum(products.base_price) / overall_sum(sum(products.base_price)) return ( <> - + {i18n.translate('xpack.lens.formulaDocumentation.header', { defaultMessage: 'Formula reference', })} @@ -347,22 +348,28 @@ sum(products.base_price) / overall_sum(sum(products.base_price))

- - {helpGroup.items.map((helpItem) => { - return ( - {helpItem.label} - } - size="s" - onClick={() => { - setSelectedFunction(helpItem.label); - }} - /> - ); - })} - + {helpGroup.items.length ? ( + <> + + + + {helpGroup.items.map((helpItem) => { + return ( + {helpItem.label} + } + size="s" + onClick={() => { + setSelectedFunction(helpItem.label); + }} + /> + ); + })} + + + ) : null} ); })} diff --git a/x-pack/plugins/lens/public/shared_components/coloring/palette_configuration.scss b/x-pack/plugins/lens/public/shared_components/coloring/palette_configuration.scss index c6b14c5c5f9a3..82165b172eab9 100644 --- a/x-pack/plugins/lens/public/shared_components/coloring/palette_configuration.scss +++ b/x-pack/plugins/lens/public/shared_components/coloring/palette_configuration.scss @@ -1,7 +1,8 @@ -.lnsPalettePanel__section--shaded { - background-color: $euiColorLightestShade; +.lnsPalettePanel__section { + padding: $euiSize; } -.lnsPalettePanel__section { - padding: $euiSizeS; +.lnsPalettePanel__section--shaded { + background-color: $euiColorLightestShade; + border-bottom: $euiBorderThin; } \ No newline at end of file diff --git a/x-pack/plugins/lens/public/shared_components/coloring/palette_panel_container.scss b/x-pack/plugins/lens/public/shared_components/coloring/palette_panel_container.scss index db14d064d1881..edf6c472321bf 100644 --- a/x-pack/plugins/lens/public/shared_components/coloring/palette_panel_container.scss +++ b/x-pack/plugins/lens/public/shared_components/coloring/palette_panel_container.scss @@ -15,39 +15,15 @@ z-index: $euiZLevel3 + 1 } -.lnsPalettePanelContainer__footer { - padding: $euiSizeS; -} - .lnsPalettePanelContainer__header { - padding: $euiSizeS $euiSizeXS; -} - -.lnsPalettePanelContainer__headerTitle { - padding: $euiSizeS $euiSizeXS; - cursor: pointer; - - &:hover { - text-decoration: underline; - } + padding: $euiSize; } -.lnsPalettePanelContainer__headerLink { - &:focus-within { - background-color: transparentize($euiColorVis1, .9); - - .lnsPalettePanelContainer__headerTitle { - text-decoration: underline; - } - } +.lnsPalettePanelContainer__content { + @include euiYScroll; + flex: 1; } -.lnsPalettePanelContainer__backIcon { - &:hover { - transform: none !important; // sass-lint:disable-line no-important - } - - &:focus { - background-color: transparent; - } -} +.lnsPalettePanelContainer__footer { + padding: $euiSize; +} \ No newline at end of file diff --git a/x-pack/plugins/lens/public/shared_components/coloring/palette_panel_container.tsx b/x-pack/plugins/lens/public/shared_components/coloring/palette_panel_container.tsx index 583d6e25ed4e2..b546ffe5fb6fb 100644 --- a/x-pack/plugins/lens/public/shared_components/coloring/palette_panel_container.tsx +++ b/x-pack/plugins/lens/public/shared_components/coloring/palette_panel_container.tsx @@ -59,12 +59,7 @@ export function PalettePanelContainer({ className="lnsPalettePanelContainer" > - + +

- - {children} - + +
{children}
+ {i18n.translate('xpack.lens.table.palettePanelContainer.back', { diff --git a/x-pack/plugins/lens/public/xy_visualization/color_assignment.ts b/x-pack/plugins/lens/public/xy_visualization/color_assignment.ts index 1e00d821d9b30..30238507c3566 100644 --- a/x-pack/plugins/lens/public/xy_visualization/color_assignment.ts +++ b/x-pack/plugins/lens/public/xy_visualization/color_assignment.ts @@ -8,9 +8,10 @@ import { uniq, mapValues } from 'lodash'; import type { PaletteOutput, PaletteRegistry } from 'src/plugins/charts/public'; import type { Datatable } from 'src/plugins/expressions'; +import { euiLightVars } from '@kbn/ui-shared-deps-src/theme'; import type { AccessorConfig, FramePublicAPI } from '../types'; import { getColumnToLabelMap } from './state_helpers'; -import type { FormatFactory } from '../../common'; +import { FormatFactory, LayerType, layerTypes } from '../../common'; import type { XYLayerConfig } from '../../common/expressions'; const isPrimitive = (value: unknown): boolean => value != null && typeof value !== 'object'; @@ -20,8 +21,11 @@ interface LayerColorConfig { splitAccessor?: string; accessors: string[]; layerId: string; + layerType: LayerType; } +export const defaultThresholdColor = euiLightVars.euiColorDarkShade; + export type ColorAssignments = Record< string, { @@ -37,13 +41,15 @@ export function getColorAssignments( ): ColorAssignments { const layersPerPalette: Record = {}; - layers.forEach((layer) => { - const palette = layer.palette?.name || 'default'; - if (!layersPerPalette[palette]) { - layersPerPalette[palette] = []; - } - layersPerPalette[palette].push(layer); - }); + layers + .filter(({ layerType }) => layerType === layerTypes.DATA) + .forEach((layer) => { + const palette = layer.palette?.name || 'default'; + if (!layersPerPalette[palette]) { + layersPerPalette[palette] = []; + } + layersPerPalette[palette].push(layer); + }); return mapValues(layersPerPalette, (paletteLayers) => { const seriesPerLayer = paletteLayers.map((layer, layerIndex) => { @@ -111,6 +117,13 @@ export function getAccessorColorConfig( triggerIcon: 'disabled', }; } + if (layer.layerType === layerTypes.THRESHOLD) { + return { + columnId: accessor as string, + triggerIcon: 'color', + color: currentYConfig?.color || defaultThresholdColor, + }; + } const columnToLabel = getColumnToLabelMap(layer, frame.datasourceLayers[layer.layerId]); const rank = colorAssignments[currentPalette.name].getRank( layer, @@ -133,7 +146,7 @@ export function getAccessorColorConfig( return { columnId: accessor as string, triggerIcon: customColor ? 'color' : 'disabled', - color: customColor ? customColor : undefined, + color: customColor ?? undefined, }; }); } diff --git a/x-pack/plugins/lens/public/xy_visualization/expression.tsx b/x-pack/plugins/lens/public/xy_visualization/expression.tsx index bc80b4569977c..c4315b7ccea85 100644 --- a/x-pack/plugins/lens/public/xy_visualization/expression.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/expression.tsx @@ -836,7 +836,6 @@ export function XYChart({ ; paletteService: PaletteRegistry; syncColors: boolean; @@ -36,12 +34,11 @@ export const ThresholdAnnotations = ({ if (!thresholdLayer.yConfig) { return []; } - const { columnToLabel, palette, yConfig: yConfigs, layerId } = thresholdLayer; + const { columnToLabel, yConfig: yConfigs, layerId } = thresholdLayer; const columnToLabelMap: Record = columnToLabel ? JSON.parse(columnToLabel) : {}; const table = data.tables[layerId]; - const colorAssignment = colorAssignments[palette.name]; const row = table.rows[0]; @@ -62,27 +59,7 @@ export const ThresholdAnnotations = ({ const formatter = formatters[groupId || 'bottom']; - const seriesLayers: SeriesLayer[] = [ - { - name: columnToLabelMap[yConfig.forAccessor], - totalSeriesAtDepth: colorAssignment.totalSeriesCount, - rankAtDepth: colorAssignment.getRank( - thresholdLayer, - String(yConfig.forAccessor), - String(yConfig.forAccessor) - ), - }, - ]; - const defaultColor = paletteService.get(palette.name).getCategoricalColor( - seriesLayers, - { - maxDepth: 1, - behindText: false, - totalSeries: colorAssignment.totalSeriesCount, - syncColors, - }, - palette.params - ); + const defaultColor = euiLightVars.euiColorDarkShade; const props = { groupId, @@ -99,7 +76,7 @@ export const ThresholdAnnotations = ({ const sharedStyle = { strokeWidth: yConfig.lineWidth || 1, - stroke: (yConfig.color || defaultColor) ?? '#f00', + stroke: yConfig.color || defaultColor, dash: dashStyle, }; @@ -179,7 +156,7 @@ export const ThresholdAnnotations = ({ })} style={{ ...sharedStyle, - fill: (yConfig.color || defaultColor) ?? '#f00', + fill: yConfig.color || defaultColor, opacity: 0.1, }} /> diff --git a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts index 1996f918b675e..b66f0ca4687b8 100644 --- a/x-pack/plugins/lens/public/xy_visualization/to_expression.ts +++ b/x-pack/plugins/lens/public/xy_visualization/to_expression.ts @@ -13,6 +13,7 @@ import { OperationMetadata, DatasourcePublicAPI } from '../types'; import { getColumnToLabelMap } from './state_helpers'; import type { ValidLayer, XYLayerConfig } from '../../common/expressions'; import { layerTypes } from '../../common'; +import { defaultThresholdColor } from './color_assignment'; export const getSortedAccessors = (datasource: DatasourcePublicAPI, layer: XYLayerConfig) => { const originalOrder = datasource @@ -334,9 +335,9 @@ export const buildExpression = ( arguments: { forAccessor: [yConfig.forAccessor], axisMode: yConfig.axisMode ? [yConfig.axisMode] : [], - color: yConfig.color ? [yConfig.color] : [], - lineStyle: yConfig.lineStyle ? [yConfig.lineStyle] : [], - lineWidth: yConfig.lineWidth ? [yConfig.lineWidth] : [], + color: [yConfig.color || defaultThresholdColor], + lineStyle: [yConfig.lineStyle || 'solid'], + lineWidth: [yConfig.lineWidth || 1], fill: [yConfig.fill || 'none'], icon: yConfig.icon ? [yConfig.icon] : [], }, diff --git a/x-pack/plugins/lens/public/xy_visualization/visualization.test.ts b/x-pack/plugins/lens/public/xy_visualization/visualization.test.ts index 8907db4954f99..8052b0d593215 100644 --- a/x-pack/plugins/lens/public/xy_visualization/visualization.test.ts +++ b/x-pack/plugins/lens/public/xy_visualization/visualization.test.ts @@ -347,9 +347,6 @@ describe('xy_visualization', () => { { axisMode: 'bottom', forAccessor: 'newCol', - icon: undefined, - lineStyle: 'solid', - lineWidth: 1, }, ], }); diff --git a/x-pack/plugins/lens/public/xy_visualization/visualization.tsx b/x-pack/plugins/lens/public/xy_visualization/visualization.tsx index 33cd01c8fda7a..4e279d2e0026d 100644 --- a/x-pack/plugins/lens/public/xy_visualization/visualization.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/visualization.tsx @@ -448,12 +448,7 @@ export const getXyVisualization = ({ if (!hasYConfig) { newLayer.yConfig = [ ...(newLayer.yConfig || []), - // TODO: move this - // add a default config if none is available { - icon: undefined, - lineStyle: 'solid', - lineWidth: 1, // override with previous styling, ...previousYConfig, // but keep the new group & id config diff --git a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/color_picker.tsx b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/color_picker.tsx index 5a6458a4654d0..516adbf585b9f 100644 --- a/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/color_picker.tsx +++ b/x-pack/plugins/lens/public/xy_visualization/xy_config_panel/color_picker.tsx @@ -13,9 +13,13 @@ import { EuiFormRow, EuiColorPicker, EuiColorPickerProps, EuiToolTip, EuiIcon } import type { PaletteRegistry } from 'src/plugins/charts/public'; import type { VisualizationDimensionEditorProps } from '../../types'; import { State } from '../types'; -import { FormatFactory } from '../../../common'; +import { FormatFactory, layerTypes } from '../../../common'; import { getSeriesColor } from '../state_helpers'; -import { getAccessorColorConfig, getColorAssignments } from '../color_assignment'; +import { + defaultThresholdColor, + getAccessorColorConfig, + getColorAssignments, +} from '../color_assignment'; import { getSortedAccessors } from '../to_expression'; import { updateLayer } from '.'; import { TooltipWrapper } from '../../shared_components'; @@ -56,6 +60,9 @@ export const ColorPicker = ({ const overwriteColor = getSeriesColor(layer, accessor); const currentColor = useMemo(() => { if (overwriteColor || !frame.activeData) return overwriteColor; + if (layer.layerType === layerTypes.THRESHOLD) { + return defaultThresholdColor; + } const datasource = frame.datasourceLayers[layer.layerId]; const sortedAccessors: string[] = getSortedAccessors(datasource, layer); diff --git a/x-pack/plugins/monitoring/public/application/hooks/use_table.ts b/x-pack/plugins/monitoring/public/application/hooks/use_table.ts index 8c27a826564ee..2e6018ec89809 100644 --- a/x-pack/plugins/monitoring/public/application/hooks/use_table.ts +++ b/x-pack/plugins/monitoring/public/application/hooks/use_table.ts @@ -6,7 +6,6 @@ */ import { useState, useCallback } from 'react'; -import { EUI_SORT_ASCENDING } from '../../../common/constants'; import { euiTableStorageGetter, euiTableStorageSetter } from '../../components/table'; import { Storage } from '../../../../../../src/plugins/kibana_utils/public'; @@ -83,22 +82,18 @@ export function useTable(storageKey: string) { // get initial state from localStorage const [sorting, setSorting] = useState(storageData.sort || { sort: {} }); - const cleanSortingData = (sortData: Sorting) => { - const sort = sortData || { sort: {} }; - - if (!sort.sort.field) { - sort.sort.field = 'name'; - } - if (!sort.sort.direction) { - sort.sort.direction = EUI_SORT_ASCENDING; - } - - return sort; - }; const [query, setQuery] = useState(''); - const onTableChange = ({ page, sort }: { page: Page; sort: Sorting['sort'] }) => { + const onTableChange = ({ + page, + sort, + queryText, + }: { + page: Page; + sort: Sorting['sort']; + queryText: string; + }) => { setPagination({ ...pagination, ...{ @@ -109,11 +104,14 @@ export function useTable(storageKey: string) { pageSizeOptions: PAGE_SIZE_OPTIONS, }, }); - setSorting(cleanSortingData({ sort })); + setSorting({ sort }); setLocalStorageData(storage, { page, - sort: { sort }, + sort: { + sort, + }, }); + setQuery(queryText); }; const getPaginationRouteOptions = useCallback(() => { @@ -136,33 +134,6 @@ export function useTable(storageKey: string) { sorting, pagination, onTableChange, - fetchMoreData: ({ - page, - sort, - queryText, - }: { - page: Page; - sort: Sorting; - queryText: string; - }) => { - setPagination({ - ...pagination, - ...{ - initialPageSize: page.size, - pageSize: page.size, - initialPageIndex: page.index, - pageIndex: page.index, - pageSizeOptions: PAGE_SIZE_OPTIONS, - }, - }); - setSorting(cleanSortingData(sort)); - setQuery(queryText); - - setLocalStorageData(storage, { - page, - sort, - }); - }, }; }; diff --git a/x-pack/plugins/monitoring/public/application/pages/beats/instances.tsx b/x-pack/plugins/monitoring/public/application/pages/beats/instances.tsx index 873cc7e939269..7a65022d8ff53 100644 --- a/x-pack/plugins/monitoring/public/application/pages/beats/instances.tsx +++ b/x-pack/plugins/monitoring/public/application/pages/beats/instances.tsx @@ -84,6 +84,7 @@ export const BeatsInstancesPage: React.FC = ({ clusters }) => { >
( {flyoutComponent} diff --git a/x-pack/plugins/monitoring/public/components/elasticsearch/nodes/nodes.js b/x-pack/plugins/monitoring/public/components/elasticsearch/nodes/nodes.js index 8a4a8a3c63d9d..987422c2e8bb3 100644 --- a/x-pack/plugins/monitoring/public/components/elasticsearch/nodes/nodes.js +++ b/x-pack/plugins/monitoring/public/components/elasticsearch/nodes/nodes.js @@ -298,8 +298,7 @@ const getColumns = (showCgroupMetricsElasticsearch, setupMode, clusterUuid, aler }; export function ElasticsearchNodes({ clusterStatus, showCgroupMetricsElasticsearch, ...props }) { - const { sorting, pagination, onTableChange, clusterUuid, setupMode, fetchMoreData, alerts } = - props; + const { sorting, pagination, onTableChange, clusterUuid, setupMode, alerts } = props; const columns = getColumns(showCgroupMetricsElasticsearch, setupMode, clusterUuid, alerts); @@ -474,7 +473,7 @@ export function ElasticsearchNodes({ clusterStatus, showCgroupMetricsElasticsear }, }} onTableChange={onTableChange} - fetchMoreData={fetchMoreData} + {...props} /> diff --git a/x-pack/plugins/monitoring/public/components/logstash/pipeline_listing/pipeline_listing.js b/x-pack/plugins/monitoring/public/components/logstash/pipeline_listing/pipeline_listing.js index 50a4d3f8cf32b..067f2b56937f8 100644 --- a/x-pack/plugins/monitoring/public/components/logstash/pipeline_listing/pipeline_listing.js +++ b/x-pack/plugins/monitoring/public/components/logstash/pipeline_listing/pipeline_listing.js @@ -129,7 +129,7 @@ export class PipelineListing extends Component { } render() { - const { data, sorting, pagination, onTableChange, fetchMoreData, upgradeMessage, className } = + const { data, sorting, pagination, onTableChange, upgradeMessage, className, ...props } = this.props; const sortingOptions = sorting || { field: 'id', direction: 'asc' }; @@ -159,7 +159,6 @@ export class PipelineListing extends Component { sorting={sortingOptions} message={upgradeMessage} pagination={pagination} - fetchMoreData={fetchMoreData} search={{ box: { placeholder: i18n.translate( @@ -171,6 +170,7 @@ export class PipelineListing extends Component { }, }} onTableChange={onTableChange} + {...props} /> diff --git a/x-pack/plugins/monitoring/public/components/table/eui_table_ssp.js b/x-pack/plugins/monitoring/public/components/table/eui_table_ssp.js index 5042c3c938fb7..cbf589d5de2a0 100644 --- a/x-pack/plugins/monitoring/public/components/table/eui_table_ssp.js +++ b/x-pack/plugins/monitoring/public/components/table/eui_table_ssp.js @@ -20,10 +20,8 @@ export function EuiMonitoringSSPTable({ onTableChange, setupMode, productName, - fetchMoreData, ...props }) { - const [isLoading, setIsLoading] = React.useState(false); const [queryText, setQueryText] = React.useState(''); const [page, setPage] = React.useState({ index: pagination.pageIndex, @@ -72,19 +70,28 @@ export function EuiMonitoringSSPTable({ const onChange = async ({ page, sort }) => { setPage(page); setSort({ sort }); - setIsLoading(true); - await fetchMoreData({ page, sort: { sort }, queryText }); - setIsLoading(false); - onTableChange({ page, sort }); + // angular version + if (props.fetchMoreData) { + await props.fetchMoreData({ page, sort: { sort }, queryText }); + onTableChange({ page, sort }); + } + // react version + else { + onTableChange({ page, sort, queryText }); + } }; const onQueryChange = async ({ queryText }) => { const newPage = { ...page, index: 0 }; setPage(newPage); setQueryText(queryText); - setIsLoading(true); - await fetchMoreData({ page: newPage, sort, queryText }); - setIsLoading(false); + // angular version + if (props.fetchMoreData) { + await props.fetchMoreData({ page: newPage, sort, queryText }); + } else { + // react version + onTableChange({ page, sort: sort.sort, queryText }); + } }; return ( @@ -97,7 +104,6 @@ export function EuiMonitoringSSPTable({ items={items} pagination={pagination} onChange={onChange} - loading={isLoading} columns={columns} /> {footerContent} diff --git a/x-pack/plugins/security/server/audit/audit_events.ts b/x-pack/plugins/security/server/audit/audit_events.ts index 611e7bd456da3..a4025b619365f 100644 --- a/x-pack/plugins/security/server/audit/audit_events.ts +++ b/x-pack/plugins/security/server/audit/audit_events.ts @@ -10,7 +10,7 @@ import type { EcsEventOutcome, EcsEventType, KibanaRequest, LogMeta } from 'src/ import type { AuthenticationResult } from '../authentication/authentication_result'; /** - * Audit event schema using ECS format: https://www.elastic.co/guide/en/ecs/1.9/index.html + * Audit event schema using ECS format: https://www.elastic.co/guide/en/ecs/1.12/index.html * * If you add additional fields to the schema ensure you update the Kibana Filebeat module: * https://github.com/elastic/beats/tree/master/filebeat/module/kibana diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index d77a555991df8..4316b1c033ec6 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -10,6 +10,7 @@ import { ENABLE_CASE_CONNECTOR } from '../../cases/common'; import { metadataTransformPattern } from './endpoint/constants'; export const APP_ID = 'securitySolution'; +export const CASES_FEATURE_ID = 'securitySolutionCases'; export const SERVER_APP_ID = 'siem'; export const APP_NAME = 'Security'; export const APP_ICON = 'securityAnalyticsApp'; diff --git a/x-pack/plugins/security_solution/cypress/integration/cases/privileges.spec.ts b/x-pack/plugins/security_solution/cypress/integration/cases/privileges.spec.ts index 4d6c60e93ee20..23016ecc512b1 100644 --- a/x-pack/plugins/security_solution/cypress/integration/cases/privileges.spec.ts +++ b/x-pack/plugins/security_solution/cypress/integration/cases/privileges.spec.ts @@ -81,6 +81,7 @@ const secAll: Role = { { feature: { siem: ['all'], + securitySolutionCases: ['all'], actions: ['all'], actionsSimulators: ['all'], }, @@ -110,7 +111,8 @@ const secReadCasesAll: Role = { kibana: [ { feature: { - siem: ['minimal_read', 'cases_all'], + siem: ['read'], + securitySolutionCases: ['all'], actions: ['all'], actionsSimulators: ['all'], }, diff --git a/x-pack/plugins/security_solution/public/app/deep_links/index.test.ts b/x-pack/plugins/security_solution/public/app/deep_links/index.test.ts index 5bcc598c7be5e..a3dc6565b19c6 100644 --- a/x-pack/plugins/security_solution/public/app/deep_links/index.test.ts +++ b/x-pack/plugins/security_solution/public/app/deep_links/index.test.ts @@ -8,6 +8,7 @@ import { getDeepLinks, PREMIUM_DEEP_LINK_IDS } from '.'; import { AppDeepLink, Capabilities } from '../../../../../../src/core/public'; import { SecurityPageName } from '../types'; import { mockGlobalState } from '../../common/mock'; +import { CASES_FEATURE_ID } from '../../../common/constants'; const findDeepLink = (id: string, deepLinks: AppDeepLink[]): AppDeepLink | null => deepLinks.reduce((deepLinkFound: AppDeepLink | null, deepLink) => { @@ -58,7 +59,7 @@ describe('deepLinks', () => { it('should return case links for basic license with only read_cases capabilities', () => { const basicLicense = 'basic'; const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, { - siem: { read_cases: true, crud_cases: false }, + [CASES_FEATURE_ID]: { read_cases: true, crud_cases: false }, } as unknown as Capabilities); expect(findDeepLink(SecurityPageName.case, basicLinks)).toBeTruthy(); @@ -67,7 +68,7 @@ describe('deepLinks', () => { it('should return case links with NO deepLinks for basic license with only read_cases capabilities', () => { const basicLicense = 'basic'; const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, { - siem: { read_cases: true, crud_cases: false }, + [CASES_FEATURE_ID]: { read_cases: true, crud_cases: false }, } as unknown as Capabilities); expect(findDeepLink(SecurityPageName.case, basicLinks)?.deepLinks?.length === 0).toBeTruthy(); }); @@ -75,7 +76,7 @@ describe('deepLinks', () => { it('should return case links with deepLinks for basic license with crud_cases capabilities', () => { const basicLicense = 'basic'; const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, { - siem: { read_cases: true, crud_cases: true }, + [CASES_FEATURE_ID]: { read_cases: true, crud_cases: true }, } as unknown as Capabilities); expect( @@ -86,7 +87,7 @@ describe('deepLinks', () => { it('should return NO case links for basic license with NO read_cases capabilities', () => { const basicLicense = 'basic'; const basicLinks = getDeepLinks(mockGlobalState.app.enableExperimental, basicLicense, { - siem: { read_cases: false, crud_cases: false }, + [CASES_FEATURE_ID]: { read_cases: false, crud_cases: false }, } as unknown as Capabilities); expect(findDeepLink(SecurityPageName.case, basicLinks)).toBeFalsy(); diff --git a/x-pack/plugins/security_solution/public/app/deep_links/index.ts b/x-pack/plugins/security_solution/public/app/deep_links/index.ts index e8d4f5d09e5f7..aaa8ce789591f 100644 --- a/x-pack/plugins/security_solution/public/app/deep_links/index.ts +++ b/x-pack/plugins/security_solution/public/app/deep_links/index.ts @@ -48,6 +48,7 @@ import { TRUSTED_APPS_PATH, EVENT_FILTERS_PATH, UEBA_PATH, + CASES_FEATURE_ID, HOST_ISOLATION_EXCEPTIONS_PATH, } from '../../../common/constants'; import { ExperimentalFeatures } from '../../../common/experimental_features'; @@ -362,7 +363,7 @@ export function getDeepLinks( return false; } if (deepLink.id === SecurityPageName.case) { - return capabilities == null || capabilities.siem.read_cases === true; + return capabilities == null || capabilities[CASES_FEATURE_ID].read_cases === true; } if (deepLink.id === SecurityPageName.ueba) { return enableExperimental.uebaEnabled; @@ -373,7 +374,7 @@ export function getDeepLinks( if ( deepLink.id === SecurityPageName.case && capabilities != null && - capabilities.siem.crud_cases === false + capabilities[CASES_FEATURE_ID].crud_cases === false ) { return { ...deepLink, diff --git a/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_secuirty_packages.test.tsx b/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_secuirty_packages.test.tsx index f1d1b09f45f60..968bd8679b23b 100644 --- a/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_secuirty_packages.test.tsx +++ b/x-pack/plugins/security_solution/public/common/hooks/use_upgrade_secuirty_packages.test.tsx @@ -21,7 +21,8 @@ jest.mock('../components/user_privileges', () => { }); jest.mock('../lib/kibana'); -describe('When using the `useUpgradeSecurityPackages()` hook', () => { +// FLAKY: https://github.com/elastic/kibana/issues/112910 +describe.skip('When using the `useUpgradeSecurityPackages()` hook', () => { let renderResult: RenderHookResult; let renderHook: () => RenderHookResult; let kibana: ReturnType; diff --git a/x-pack/plugins/security_solution/public/common/lib/kibana/hooks.ts b/x-pack/plugins/security_solution/public/common/lib/kibana/hooks.ts index adc06468d9a02..fdaed64ba91d7 100644 --- a/x-pack/plugins/security_solution/public/common/lib/kibana/hooks.ts +++ b/x-pack/plugins/security_solution/public/common/lib/kibana/hooks.ts @@ -12,7 +12,12 @@ import { i18n } from '@kbn/i18n'; import { camelCase, isArray, isObject } from 'lodash'; import { set } from '@elastic/safer-lodash-set'; -import { APP_ID, DEFAULT_DATE_FORMAT, DEFAULT_DATE_FORMAT_TZ } from '../../../../common/constants'; +import { + APP_ID, + CASES_FEATURE_ID, + DEFAULT_DATE_FORMAT, + DEFAULT_DATE_FORMAT_TZ, +} from '../../../../common/constants'; import { errorToToaster, useStateToaster } from '../../components/toasters'; import { AuthenticatedUser } from '../../../../../security/common/model'; import { NavigateToAppOptions } from '../../../../../../../src/core/public'; @@ -151,13 +156,9 @@ export const useGetUserCasesPermissions = () => { const uiCapabilities = useKibana().services.application.capabilities; useEffect(() => { - const capabilitiesCanUserCRUD: boolean = - typeof uiCapabilities.siem.crud_cases === 'boolean' ? uiCapabilities.siem.crud_cases : false; - const capabilitiesCanUserRead: boolean = - typeof uiCapabilities.siem.read_cases === 'boolean' ? uiCapabilities.siem.read_cases : false; setCasesPermissions({ - crud: capabilitiesCanUserCRUD, - read: capabilitiesCanUserRead, + crud: !!uiCapabilities[CASES_FEATURE_ID].crud_cases, + read: !!uiCapabilities[CASES_FEATURE_ID].read_cases, }); }, [uiCapabilities]); diff --git a/x-pack/plugins/security_solution/server/features.ts b/x-pack/plugins/security_solution/server/features.ts index cff1e2482a1ee..185bf43a3da37 100644 --- a/x-pack/plugins/security_solution/server/features.ts +++ b/x-pack/plugins/security_solution/server/features.ts @@ -9,49 +9,48 @@ import { i18n } from '@kbn/i18n'; import { KibanaFeatureConfig, SubFeatureConfig } from '../../features/common'; import { DEFAULT_APP_CATEGORIES } from '../../../../src/core/server'; -import { APP_ID, SERVER_APP_ID } from '../common/constants'; +import { APP_ID, CASES_FEATURE_ID, SERVER_APP_ID } from '../common/constants'; import { savedObjectTypes } from './saved_objects'; -const CASES_SUB_FEATURE: SubFeatureConfig = { - name: 'Cases', - privilegeGroups: [ - { - groupType: 'mutually_exclusive', - privileges: [ - { - id: 'cases_all', - includeIn: 'all', - name: 'All', - savedObject: { - all: [], - read: [], - }, - // using variables with underscores here otherwise when we retrieve them from the kibana - // capabilities in a hook I get type errors regarding boolean | ReadOnly<{[x: string]: boolean}> - ui: ['crud_cases', 'read_cases'], // uiCapabilities.siem.crud_cases - cases: { - all: [APP_ID], - }, - }, - { - id: 'cases_read', - includeIn: 'read', - name: 'Read', - savedObject: { - all: [], - read: [], - }, - // using variables with underscores here otherwise when we retrieve them from the kibana - // capabilities in a hook I get type errors regarding boolean | ReadOnly<{[x: string]: boolean}> - ui: ['read_cases'], // uiCapabilities.siem.read_cases - cases: { - read: [APP_ID], - }, - }, - ], +export const getCasesKibanaFeature = (): KibanaFeatureConfig => ({ + id: CASES_FEATURE_ID, + name: i18n.translate('xpack.securitySolution.featureRegistry.linkSecuritySolutionCaseTitle', { + defaultMessage: 'Cases', + }), + order: 1100, + category: DEFAULT_APP_CATEGORIES.security, + app: [CASES_FEATURE_ID, 'kibana'], + catalogue: [APP_ID], + cases: [APP_ID], + privileges: { + all: { + app: [CASES_FEATURE_ID, 'kibana'], + catalogue: [APP_ID], + cases: { + all: [APP_ID], + }, + api: [], + savedObject: { + all: [], + read: [], + }, + ui: ['crud_cases', 'read_cases'], // uiCapabilities[CASES_FEATURE_ID].crud_cases or read_cases }, - ], -}; + read: { + app: [CASES_FEATURE_ID, 'kibana'], + catalogue: [APP_ID], + cases: { + read: [APP_ID], + }, + api: [], + savedObject: { + all: [], + read: [], + }, + ui: ['read_cases'], // uiCapabilities[CASES_FEATURE_ID].read_cases + }, + }, +}); export const getAlertsSubFeature = (ruleTypes: string[]): SubFeatureConfig => ({ name: i18n.translate('xpack.securitySolution.featureRegistry.manageAlertsName', { @@ -108,18 +107,17 @@ export const getKibanaPrivilegesFeaturePrivileges = (ruleTypes: string[]): Kiban order: 1100, category: DEFAULT_APP_CATEGORIES.security, app: [APP_ID, 'kibana'], - catalogue: ['securitySolution'], + catalogue: [APP_ID], management: { insightsAndAlerting: ['triggersActions'], }, alerting: ruleTypes, - cases: [APP_ID], - subFeatures: [{ ...CASES_SUB_FEATURE } /* , { ...getAlertsSubFeature(ruleTypes) } */], + subFeatures: [], privileges: { all: { app: [APP_ID, 'kibana'], - catalogue: ['securitySolution'], - api: ['securitySolution', 'lists-all', 'lists-read', 'rac'], + catalogue: [APP_ID], + api: [APP_ID, 'lists-all', 'lists-read', 'rac'], savedObject: { all: ['alert', 'exception-list', 'exception-list-agnostic', ...savedObjectTypes], read: [], @@ -136,8 +134,8 @@ export const getKibanaPrivilegesFeaturePrivileges = (ruleTypes: string[]): Kiban }, read: { app: [APP_ID, 'kibana'], - catalogue: ['securitySolution'], - api: ['securitySolution', 'lists-read', 'rac'], + catalogue: [APP_ID], + api: [APP_ID, 'lists-read', 'rac'], savedObject: { all: [], read: ['exception-list', 'exception-list-agnostic', ...savedObjectTypes], diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/detections_admin/detections_role.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/detections_admin/detections_role.json index ef3a3bef324f9..7d81897708422 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/detections_admin/detections_role.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/detections_admin/detections_role.json @@ -33,6 +33,7 @@ "feature": { "ml": ["all"], "siem": ["all", "read_alerts", "crud_alerts"], + "securitySolutionCases": ["all"], "actions": ["read"], "builtInAlerts": ["all"], "dev_tools": ["all"] diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/hunter/detections_role.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/hunter/detections_role.json index f9d2c68e6878a..34d8b7b4d4446 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/hunter/detections_role.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/hunter/detections_role.json @@ -38,6 +38,7 @@ "feature": { "ml": ["read"], "siem": ["all", "read_alerts", "crud_alerts"], + "securitySolutionCases": ["all"], "actions": ["read"], "builtInAlerts": ["all"] }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/platform_engineer/detections_role.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/platform_engineer/detections_role.json index 5c6188b053d20..f6b31d4b3ed81 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/platform_engineer/detections_role.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/platform_engineer/detections_role.json @@ -33,6 +33,7 @@ "feature": { "ml": ["all"], "siem": ["all", "read_alerts", "crud_alerts"], + "securitySolutionCases": ["all"], "actions": ["all"], "builtInAlerts": ["all"] }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/reader/detections_role.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/reader/detections_role.json index d04251542d11b..4cfc6a3ec80ed 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/reader/detections_role.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/reader/detections_role.json @@ -26,6 +26,7 @@ "feature": { "ml": ["read"], "siem": ["read", "read_alerts"], + "securitySolutionCases": ["read"], "actions": ["read"], "builtInAlerts": ["read"] }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/rule_author/detections_role.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/rule_author/detections_role.json index f7b8818d6c004..a23aec6d6e403 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/rule_author/detections_role.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/rule_author/detections_role.json @@ -36,6 +36,7 @@ "feature": { "ml": ["read"], "siem": ["all", "read_alerts", "crud_alerts"], + "securitySolutionCases": ["all"], "actions": ["read"], "builtInAlerts": ["all"] }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/soc_manager/detections_role.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/soc_manager/detections_role.json index 324fb2737f24f..da855c6926438 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/soc_manager/detections_role.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/soc_manager/detections_role.json @@ -36,6 +36,7 @@ "feature": { "ml": ["read"], "siem": ["all", "read_alerts", "crud_alerts"], + "securitySolutionCases": ["all"], "actions": ["all"], "builtInAlerts": ["all"] }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t1_analyst/detections_role.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t1_analyst/detections_role.json index 90232bdb53fed..a63d0186a2a91 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t1_analyst/detections_role.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t1_analyst/detections_role.json @@ -26,6 +26,7 @@ "feature": { "ml": ["read"], "siem": ["read", "read_alerts"], + "securitySolutionCases": ["read"], "actions": ["read"], "builtInAlerts": ["read"] }, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t2_analyst/detections_role.json b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t2_analyst/detections_role.json index 9885ba0ee610b..de1ff5af99c1b 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t2_analyst/detections_role.json +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/scripts/roles_users/t2_analyst/detections_role.json @@ -28,6 +28,7 @@ "feature": { "ml": ["read"], "siem": ["read", "read_alerts"], + "securitySolutionCases": ["read"], "actions": ["read"], "builtInAlerts": ["read"] }, diff --git a/x-pack/plugins/security_solution/server/plugin.ts b/x-pack/plugins/security_solution/server/plugin.ts index 59bf5057f2796..391beb3c40121 100644 --- a/x-pack/plugins/security_solution/server/plugin.ts +++ b/x-pack/plugins/security_solution/server/plugin.ts @@ -100,7 +100,7 @@ import aadFieldConversion from './lib/detection_engine/routes/index/signal_aad_m import { alertsFieldMap } from './lib/detection_engine/rule_types/field_maps/alerts'; import { rulesFieldMap } from './lib/detection_engine/rule_types/field_maps/rules'; import { RuleExecutionLogClient } from './lib/detection_engine/rule_execution_log/rule_execution_log_client'; -import { getKibanaPrivilegesFeaturePrivileges } from './features'; +import { getKibanaPrivilegesFeaturePrivileges, getCasesKibanaFeature } from './features'; import { EndpointMetadataService } from './endpoint/services/metadata'; import { CreateRuleOptions } from './lib/detection_engine/rule_types/types'; import { ctiFieldMap } from './lib/detection_engine/rule_types/field_maps/cti'; @@ -305,6 +305,7 @@ export class Plugin implements IPlugin { const esArchiver = getService('esArchiver'); const pageObjects = getPageObjects(['common', 'infraHome', 'infraSavedViews']); - // FLAKY: See https://github.com/elastic/kibana/issues/106650 - describe.skip('Home page', function () { + describe('Home page', function () { this.tags('includeFirefox'); before(async () => { await esArchiver.load('x-pack/test/functional/es_archives/empty_kibana'); diff --git a/x-pack/test/functional/apps/saved_objects_management/spaces_integration.ts b/x-pack/test/functional/apps/saved_objects_management/spaces_integration.ts index e4da0b341dce9..62c742e39d02b 100644 --- a/x-pack/test/functional/apps/saved_objects_management/spaces_integration.ts +++ b/x-pack/test/functional/apps/saved_objects_management/spaces_integration.ts @@ -13,7 +13,6 @@ const getSpacePrefix = (spaceId: string) => { }; export default function ({ getPageObjects, getService }: FtrProviderContext) { - const esArchiver = getService('esArchiver'); const PageObjects = getPageObjects([ 'common', 'security', @@ -22,6 +21,8 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { 'settings', ]); const find = getService('find'); + const kibanaServer = getService('kibanaServer'); + const spacesService = getService('spaces'); const spaceId = 'space_1'; @@ -32,15 +33,15 @@ export default function ({ getPageObjects, getService }: FtrProviderContext) { describe('spaces integration', () => { before(async () => { - await esArchiver.load( - 'x-pack/test/functional/es_archives/saved_objects_management/spaces_integration' + await spacesService.create({ id: spaceId, name: spaceId }); + await kibanaServer.importExport.load( + 'x-pack/test/functional/fixtures/kbn_archiver/saved_objects_management/spaces_integration', + { space: spaceId } ); }); after(async () => { - await esArchiver.unload( - 'x-pack/test/functional/es_archives/saved_objects_management/spaces_integration' - ); + await spacesService.delete(spaceId); }); beforeEach(async () => { diff --git a/x-pack/test/functional/es_archives/saved_objects_management/spaces_integration/data.json b/x-pack/test/functional/es_archives/saved_objects_management/spaces_integration/data.json deleted file mode 100644 index e6f4a0d00e198..0000000000000 --- a/x-pack/test/functional/es_archives/saved_objects_management/spaces_integration/data.json +++ /dev/null @@ -1,96 +0,0 @@ -{ - "type": "doc", - "value": { - "id": "space:default", - "index": ".kibana", - "source": { - "space": { - "_reserved": true, - "description": "This is the default space", - "name": "Default Space" - }, - "type": "space", - "updated_at": "2017-09-21T18:49:16.270Z" - }, - "type": "doc" - } -} - -{ - "type": "doc", - "value": { - "id": "space:space_1", - "index": ".kibana", - "source": { - "space": { - "description": "This is the first test space", - "name": "Space 1" - }, - "type": "space", - "updated_at": "2017-09-21T18:49:16.270Z" - }, - "type": "doc" - } -} - -{ - "type": "doc", - "value": { - "index": ".kibana", - "type": "doc", - "id": "index-pattern:logstash-*", - "source": { - "index-pattern": { - "title": "logstash-*", - "timeFieldName": "@timestamp", - "fields": "[{\"name\":\"@message\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"@message.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"@tags\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"@tags.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"@timestamp\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"_id\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_score\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_source\",\"type\":\"_source\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"agent\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"agent.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"bytes\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"clientip\",\"type\":\"ip\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"extension\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"extension.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geo.coordinates\",\"type\":\"geo_point\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geo.dest\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geo.src\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geo.srcdest\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"headings\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"headings.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"host\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"host.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"id\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"index.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"ip\",\"type\":\"ip\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"links\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"links.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"machine.os\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"machine.os.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"machine.ram\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"memory\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"meta.char\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"meta.related\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"meta.user.firstname\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"meta.user.lastname\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"phpmemory\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"referer\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.article:modified_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.article:published_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.article:section\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.article:section.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.article:tag\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.article:tag.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:description\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:description.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:image\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:image.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:image:height\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:image:height.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:image:width\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:image:width.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:site_name\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:site_name.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:title\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:title.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:type.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:url.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.twitter:card\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.twitter:card.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.twitter:description\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.twitter:description.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.twitter:image\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.twitter:image.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.twitter:site\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.twitter:site.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.twitter:title\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.twitter:title.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.url.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"request\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"request.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"response\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"response.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"spaces\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"spaces.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"url.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"utc_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"xss\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"xss.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true}]" - }, - "type": "index-pattern", - "migrationVersion": { - "index-pattern": "6.5.0" - }, - "updated_at": "2018-12-21T00:43:07.096Z" - } - } -} - -{ - "type": "doc", - "value": { - "index": ".kibana", - "type": "doc", - "id": "space_1:visualization:75c3e060-1e7c-11e9-8488-65449e65d0ed", - "source": { - "visualization": { - "title": "A Pie", - "visState": "{\"title\":\"A Pie\",\"type\":\"pie\",\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true,\"labels\":{\"show\":false,\"values\":true,\"last_level\":true,\"truncate\":100},\"dimensions\":{\"metric\":{\"accessor\":0,\"format\":{\"id\":\"number\"},\"params\":{},\"aggType\":\"count\"}}},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"geo.src\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\"}}]}", - "uiStateJSON": "{}", - "description": "", - "version": 1, - "kibanaSavedObjectMeta": { - "searchSourceJSON": "{\"index\":\"logstash-*\",\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[]}" - } - }, - "type": "visualization", - "namespace": "space_1", - "updated_at": "2019-01-22T19:32:31.206Z" - } - } -} - -{ - "type": "doc", - "value": { - "index": ".kibana", - "type": "doc", - "id": "config:6.0.0", - "source": { - "config": { - "buildNum": 9007199254740991, - "defaultIndex": "logstash-*" - }, - "type": "config", - "updated_at": "2019-01-22T19:32:02.235Z" - } - } -} diff --git a/x-pack/test/functional/es_archives/saved_objects_management/spaces_integration/mappings.json b/x-pack/test/functional/es_archives/saved_objects_management/spaces_integration/mappings.json deleted file mode 100644 index 036dd7fad63f8..0000000000000 --- a/x-pack/test/functional/es_archives/saved_objects_management/spaces_integration/mappings.json +++ /dev/null @@ -1,27 +0,0 @@ -{ - "type": "index", - "value": { - "aliases": { - ".kibana_$KIBANA_PACKAGE_VERSION": {}, - ".kibana": {} - }, - "index": ".kibana_$KIBANA_PACKAGE_VERSION_001", - "mappings": { - "dynamic": "false", - "properties": { - "type": { "type": "keyword" }, - "migrationVersion": { - "dynamic": "true", - "type": "object" - } - } - }, - "settings": { - "index": { - "auto_expand_replicas": "0-1", - "number_of_replicas": "0", - "number_of_shards": "1" - } - } - } -} diff --git a/x-pack/test/functional/fixtures/kbn_archiver/saved_objects_management/spaces_integration.json b/x-pack/test/functional/fixtures/kbn_archiver/saved_objects_management/spaces_integration.json new file mode 100644 index 0000000000000..4a7ab6d406736 --- /dev/null +++ b/x-pack/test/functional/fixtures/kbn_archiver/saved_objects_management/spaces_integration.json @@ -0,0 +1,44 @@ +{ + "attributes": { + "fields": "[{\"name\":\"@message\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"@message.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"@tags\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"@tags.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"@timestamp\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"_id\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"_score\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_source\",\"type\":\"_source\",\"count\":0,\"scripted\":false,\"searchable\":false,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"_type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":false},{\"name\":\"agent\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"agent.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"bytes\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"clientip\",\"type\":\"ip\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"extension\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"extension.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geo.coordinates\",\"type\":\"geo_point\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geo.dest\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geo.src\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"geo.srcdest\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"headings\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"headings.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"host\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"host.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"id\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"index\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"index.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"ip\",\"type\":\"ip\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"links\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"links.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"machine.os\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"machine.os.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"machine.ram\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"memory\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"meta.char\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"meta.related\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"meta.user.firstname\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"meta.user.lastname\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"phpmemory\",\"type\":\"number\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"referer\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.article:modified_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.article:published_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.article:section\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.article:section.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.article:tag\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.article:tag.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:description\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:description.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:image\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:image.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:image:height\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:image:height.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:image:width\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:image:width.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:site_name\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:site_name.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:title\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:title.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:type.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.og:url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.og:url.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.twitter:card\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.twitter:card.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.twitter:description\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.twitter:description.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.twitter:image\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.twitter:image.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.twitter:site\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.twitter:site.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.twitter:title\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.twitter:title.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"relatedContent.url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"relatedContent.url.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"request\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"request.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"response\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"response.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"spaces\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"spaces.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"type\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"url\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"url.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"utc_time\",\"type\":\"date\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true},{\"name\":\"xss\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":false,\"readFromDocValues\":false},{\"name\":\"xss.raw\",\"type\":\"string\",\"count\":0,\"scripted\":false,\"searchable\":true,\"aggregatable\":true,\"readFromDocValues\":true}]", + "timeFieldName": "@timestamp", + "title": "logstash-*" + }, + "coreMigrationVersion": "7.16.0", + "id": "logstash-*", + "migrationVersion": { + "index-pattern": "7.11.0" + }, + "references": [], + "type": "index-pattern", + "updated_at": "2021-09-29T14:44:14.268Z", + "version": "WzExLDFd" +} + +{ + "attributes": { + "description": "", + "kibanaSavedObjectMeta": { + "searchSourceJSON": "{\"query\":{\"query\":\"\",\"language\":\"lucene\"},\"filter\":[],\"indexRefName\":\"kibanaSavedObjectMeta.searchSourceJSON.index\"}" + }, + "title": "A Pie", + "uiStateJSON": "{}", + "version": 1, + "visState": "{\"title\":\"A Pie\",\"type\":\"pie\",\"params\":{\"type\":\"pie\",\"addTooltip\":true,\"addLegend\":true,\"legendPosition\":\"right\",\"isDonut\":true,\"labels\":{\"show\":false,\"values\":true,\"last_level\":true,\"truncate\":100},\"dimensions\":{\"metric\":{\"accessor\":0,\"format\":{\"id\":\"number\"},\"params\":{},\"aggType\":\"count\"}},\"palette\":{\"type\":\"palette\",\"name\":\"kibana_palette\"},\"distinctColors\":true},\"aggs\":[{\"id\":\"1\",\"enabled\":true,\"type\":\"count\",\"schema\":\"metric\",\"params\":{}},{\"id\":\"2\",\"enabled\":true,\"type\":\"terms\",\"schema\":\"segment\",\"params\":{\"field\":\"geo.src\",\"size\":5,\"order\":\"desc\",\"orderBy\":\"1\",\"otherBucket\":false,\"otherBucketLabel\":\"Other\",\"missingBucket\":false,\"missingBucketLabel\":\"Missing\"}}]}" + }, + "coreMigrationVersion": "7.16.0", + "id": "75c3e060-1e7c-11e9-8488-65449e65d0ed", + "migrationVersion": { + "visualization": "7.14.0" + }, + "references": [ + { + "id": "logstash-*", + "name": "kibanaSavedObjectMeta.searchSourceJSON.index", + "type": "index-pattern" + } + ], + "type": "visualization", + "updated_at": "2021-09-29T14:45:14.428Z", + "version": "WzEzLDFd" +} \ No newline at end of file diff --git a/x-pack/test/functional/page_objects/infra_home_page.ts b/x-pack/test/functional/page_objects/infra_home_page.ts index 09941c129c819..0790c694e772c 100644 --- a/x-pack/test/functional/page_objects/infra_home_page.ts +++ b/x-pack/test/functional/page_objects/infra_home_page.ts @@ -24,6 +24,7 @@ export function InfraHomePageProvider({ getService, getPageObjects }: FtrProvide ); await datePickerInput.clearValueWithKeyboard({ charByChar: true }); await datePickerInput.type([time, browser.keys.RETURN]); + await this.waitForLoading(); }, async getWaffleMap() { diff --git a/yarn.lock b/yarn.lock index 2813a39fa47a4..4eceb4a18162e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3804,6 +3804,11 @@ resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.14.0.tgz#9fb3a3cf3132328151f353de4632e01e52102bea" integrity sha512-9NET910DNaIPngYnLLPeg+Ogzqsi9uM4mSboU5y6p8S5DzMTVEsJZrawi+BoDNUVBa2DhJqQYUFvMDfgU062LQ== +"@sindresorhus/is@^0.7.0": + version "0.7.0" + resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-0.7.0.tgz#9a06f4f137ee84d7df0460c1fdb1135ffa6c50fd" + integrity sha512-ONhaKPIufzzrlNbqtWFFd+jlnemX6lJAgq9ZeiZtS7I1PIf/la7CW4m83rTXRnVnsMbW2k56pGYu7AUFJD9Pow== + "@sindresorhus/is@^4.0.0": version "4.0.0" resolved "https://registry.yarnpkg.com/@sindresorhus/is/-/is-4.0.0.tgz#2ff674e9611b45b528896d820d3d7a812de2f0e4" @@ -7254,6 +7259,13 @@ arch@^2.2.0: resolved "https://registry.yarnpkg.com/arch/-/arch-2.2.0.tgz#1bc47818f305764f23ab3306b0bfc086c5a29d11" integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== +archive-type@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/archive-type/-/archive-type-4.0.0.tgz#f92e72233056dfc6969472749c267bdb046b1d70" + integrity sha1-+S5yIzBW38aWlHJ0nCZ72wRrHXA= + dependencies: + file-type "^4.2.0" + archiver-utils@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/archiver-utils/-/archiver-utils-2.1.0.tgz#e8a460e94b693c3e3da182a098ca6285ba9249e2" @@ -8461,6 +8473,17 @@ big.js@^5.2.2: resolved "https://registry.yarnpkg.com/big.js/-/big.js-5.2.2.tgz#65f0af382f578bcdc742bd9c281e9cb2d7768328" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== +bin-build@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/bin-build/-/bin-build-3.0.0.tgz#c5780a25a8a9f966d8244217e6c1f5082a143861" + integrity sha512-jcUOof71/TNAI2uM5uoUaDq2ePcVBQ3R/qhxAz1rX7UfvduAL/RXD3jXzvn8cVcDJdGVkiR1shal3OH0ImpuhA== + dependencies: + decompress "^4.0.0" + download "^6.2.2" + execa "^0.7.0" + p-map-series "^1.0.0" + tempfile "^2.0.0" + binary-extensions@^1.0.0: version "1.13.1" resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" @@ -8476,6 +8499,14 @@ binary-search@^1.3.3: resolved "https://registry.yarnpkg.com/binary-search/-/binary-search-1.3.6.tgz#e32426016a0c5092f0f3598836a1c7da3560565c" integrity sha512-nbE1WxOTTrUWIfsfZ4aHGYu5DOuNkbxGokjV6Z2kxfJK3uaAb8zNK1muzOeipoLHZjInT4Br88BHpzevc681xA== +bl@^1.0.0: + version "1.2.2" + resolved "https://registry.yarnpkg.com/bl/-/bl-1.2.2.tgz#a160911717103c07410cef63ef51b397c025af9c" + integrity sha512-e8tQYnZodmebYDWGH7KMRvtzKXaJHx3BbilrgZCfvyLUYdKpK1t5PSPmpkny/SgiTSCnjfLW7v5rlONXVFkQEA== + dependencies: + readable-stream "^2.3.5" + safe-buffer "^5.1.1" + bl@^4.0.1, bl@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/bl/-/bl-4.0.3.tgz#12d6287adc29080e22a705e5764b2a9522cdc489" @@ -8934,6 +8965,19 @@ btoa-lite@^1.0.0: resolved "https://registry.yarnpkg.com/btoa-lite/-/btoa-lite-1.0.0.tgz#337766da15801210fdd956c22e9c6891ab9d0337" integrity sha1-M3dm2hWAEhD92VbCLpxokaudAzc= +buffer-alloc-unsafe@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/buffer-alloc-unsafe/-/buffer-alloc-unsafe-1.1.0.tgz#bd7dc26ae2972d0eda253be061dba992349c19f0" + integrity sha512-TEM2iMIEQdJ2yjPJoSIsldnleVaAk1oW3DBVUykyOLsEsFmEc9kn+SFFPz+gl54KQNxlDnAwCXosOS9Okx2xAg== + +buffer-alloc@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/buffer-alloc/-/buffer-alloc-1.2.0.tgz#890dd90d923a873e08e10e5fd51a57e5b7cce0ec" + integrity sha512-CFsHQgjtW1UChdXgbyJGtnm+O/uLQeZdtbDo8mfUgYXCHSM1wgrVxXm6bSyrUuErEb+4sYVGCzASBRot7zyrow== + dependencies: + buffer-alloc-unsafe "^1.1.0" + buffer-fill "^1.0.0" + buffer-crc32@^0.2.1, buffer-crc32@^0.2.13, buffer-crc32@~0.2.3: version "0.2.13" resolved "https://registry.yarnpkg.com/buffer-crc32/-/buffer-crc32-0.2.13.tgz#0d333e3f00eac50aa1454abd30ef8c2a5d9a7242" @@ -8954,6 +8998,11 @@ buffer-equal@^1.0.0: resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-1.0.0.tgz#59616b498304d556abd466966b22eeda3eca5fbe" integrity sha1-WWFrSYME1Var1GaWayLu2j7KX74= +buffer-fill@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-fill/-/buffer-fill-1.0.0.tgz#f8f78b76789888ef39f205cd637f68e702122b2c" + integrity sha1-+PeLdniYiO858gXNY39o5wISKyw= + buffer-from@^1.0.0: version "1.1.1" resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.1.tgz#32713bc028f75c02fdb710d7c7bcec1f2c6070ef" @@ -9091,6 +9140,19 @@ cacheable-lookup@^5.0.3: resolved "https://registry.yarnpkg.com/cacheable-lookup/-/cacheable-lookup-5.0.3.tgz#049fdc59dffdd4fc285e8f4f82936591bd59fec3" integrity sha512-W+JBqF9SWe18A72XFzN/V/CULFzPm7sBXzzR6ekkE+3tLG72wFZrBiBZhrZuDoYexop4PHJVdFAKb/Nj9+tm9w== +cacheable-request@^2.1.1: + version "2.1.4" + resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-2.1.4.tgz#0d808801b6342ad33c91df9d0b44dc09b91e5c3d" + integrity sha1-DYCIAbY0KtM8kd+dC0TcCbkeXD0= + dependencies: + clone-response "1.0.2" + get-stream "3.0.0" + http-cache-semantics "3.8.1" + keyv "3.0.0" + lowercase-keys "1.0.0" + normalize-url "2.0.1" + responselike "1.0.2" + cacheable-request@^6.0.0: version "6.1.0" resolved "https://registry.yarnpkg.com/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912" @@ -9284,6 +9346,16 @@ caseless@~0.12.0: resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" integrity sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw= +caw@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/caw/-/caw-2.0.1.tgz#6c3ca071fc194720883c2dc5da9b074bfc7e9e95" + integrity sha512-Cg8/ZSBEa8ZVY9HspcGUYaK63d/bN7rqS3CYCzEGUxuYv6UlmcjzDUz2fCFFHyTvUW5Pk0I+3hkA3iXlIj6guA== + dependencies: + get-proxy "^2.0.0" + isurl "^1.0.0-alpha5" + tunnel-agent "^0.6.0" + url-to-options "^1.0.1" + ccount@^1.0.0: version "1.0.5" resolved "https://registry.yarnpkg.com/ccount/-/ccount-1.0.5.tgz#ac82a944905a65ce204eb03023157edf29425c17" @@ -9728,7 +9800,7 @@ clone-regexp@^2.1.0: dependencies: is-regexp "^2.0.0" -clone-response@^1.0.2: +clone-response@1.0.2, clone-response@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/clone-response/-/clone-response-1.0.2.tgz#d1dc973920314df67fbeb94223b4ee350239e96b" integrity sha1-0dyXOSAxTfZ/vrlCI7TuNQI56Ws= @@ -10013,6 +10085,13 @@ commander@^7.0.0: resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7" integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== +commander@~2.8.1: + version "2.8.1" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.8.1.tgz#06be367febfda0c330aa1e2a072d3dc9762425d4" + integrity sha1-Br42f+v9oMMwqh4qBy09yXYkJdQ= + dependencies: + graceful-readlink ">= 1.0.0" + common-tags@^1.8.0: version "1.8.0" resolved "https://registry.yarnpkg.com/common-tags/-/common-tags-1.8.0.tgz#8e3153e542d4a39e9b10554434afaaf98956a937" @@ -10123,7 +10202,7 @@ concaveman@*: robust-predicates "^2.0.4" tinyqueue "^2.0.3" -config-chain@^1.1.12: +config-chain@^1.1.11, config-chain@^1.1.12: version "1.1.12" resolved "https://registry.yarnpkg.com/config-chain/-/config-chain-1.1.12.tgz#0fde8d091200eb5e808caf25fe618c02f48e4efa" integrity sha512-a1eOIcu8+7lUInge4Rpf/n4Krkf3Dd9lqhljRzII1/Zno/kRtUWnznPO3jOKBmTEktkt3fkxisUcivoj0ebzoA== @@ -10209,7 +10288,7 @@ contains-path@^0.1.0: resolved "https://registry.yarnpkg.com/contains-path/-/contains-path-0.1.0.tgz#fe8cf184ff6670b6baef01a9d4861a5cbec4120a" integrity sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo= -content-disposition@0.5.3: +content-disposition@0.5.3, content-disposition@^0.5.2: version "0.5.3" resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.3.tgz#e130caf7e7279087c5616c2007d0485698984fbd" integrity sha512-ExO0774ikEObIAEV9kDo50o+79VCUdEB6n6lzKgGwupcVeRlhrj3qGAfwq8G6uBJjkqLrhT0qEYFcWng8z1z0g== @@ -10532,6 +10611,15 @@ cross-spawn@7.0.3, cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: shebang-command "^2.0.0" which "^2.0.1" +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" + integrity sha1-6L0O/uWPz/b4+UUQoKVUu/ojVEk= + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + cross-spawn@^6.0.0, cross-spawn@^6.0.5: version "6.0.5" resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4" @@ -11497,7 +11585,7 @@ decode-uri-component@^0.2.0: resolved "https://registry.yarnpkg.com/decode-uri-component/-/decode-uri-component-0.2.0.tgz#eb3913333458775cb84cd1a1fae062106bb87545" integrity sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU= -decompress-response@^3.3.0: +decompress-response@^3.2.0, decompress-response@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/decompress-response/-/decompress-response-3.3.0.tgz#80a4dd323748384bfa248083622aedec982adff3" integrity sha1-gKTdMjdIOEv6JICDYirt7Jgq3/M= @@ -11518,6 +11606,59 @@ decompress-response@^6.0.0: dependencies: mimic-response "^3.1.0" +decompress-tar@^4.0.0, decompress-tar@^4.1.0, decompress-tar@^4.1.1: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tar/-/decompress-tar-4.1.1.tgz#718cbd3fcb16209716e70a26b84e7ba4592e5af1" + integrity sha512-JdJMaCrGpB5fESVyxwpCx4Jdj2AagLmv3y58Qy4GE6HMVjWz1FeVQk1Ct4Kye7PftcdOo/7U7UKzYBJgqnGeUQ== + dependencies: + file-type "^5.2.0" + is-stream "^1.1.0" + tar-stream "^1.5.2" + +decompress-tarbz2@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-tarbz2/-/decompress-tarbz2-4.1.1.tgz#3082a5b880ea4043816349f378b56c516be1a39b" + integrity sha512-s88xLzf1r81ICXLAVQVzaN6ZmX4A6U4z2nMbOwobxkLoIIfjVMBg7TeguTUXkKeXni795B6y5rnvDw7rxhAq9A== + dependencies: + decompress-tar "^4.1.0" + file-type "^6.1.0" + is-stream "^1.1.0" + seek-bzip "^1.0.5" + unbzip2-stream "^1.0.9" + +decompress-targz@^4.0.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/decompress-targz/-/decompress-targz-4.1.1.tgz#c09bc35c4d11f3de09f2d2da53e9de23e7ce1eee" + integrity sha512-4z81Znfr6chWnRDNfFNqLwPvm4db3WuZkqV+UgXQzSngG3CEKdBkw5jrv3axjjL96glyiiKjsxJG3X6WBZwX3w== + dependencies: + decompress-tar "^4.1.1" + file-type "^5.2.0" + is-stream "^1.1.0" + +decompress-unzip@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/decompress-unzip/-/decompress-unzip-4.0.1.tgz#deaaccdfd14aeaf85578f733ae8210f9b4848f69" + integrity sha1-3qrM39FK6vhVePczroIQ+bSEj2k= + dependencies: + file-type "^3.8.0" + get-stream "^2.2.0" + pify "^2.3.0" + yauzl "^2.4.2" + +decompress@^4.0.0, decompress@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/decompress/-/decompress-4.2.1.tgz#007f55cc6a62c055afa37c07eb6a4ee1b773f118" + integrity sha512-e48kc2IjU+2Zw8cTb6VZcJQ3lgVbS4uuB1TfCHbiZIP/haNXm+SVyhu+87jts5/3ROpd82GSVCoNs/z8l4ZOaQ== + dependencies: + decompress-tar "^4.0.0" + decompress-tarbz2 "^4.0.0" + decompress-targz "^4.0.0" + decompress-unzip "^4.0.1" + graceful-fs "^4.1.10" + make-dir "^1.0.0" + pify "^2.3.0" + strip-dirs "^2.0.0" + dedent@^0.7.0: version "0.7.0" resolved "https://registry.yarnpkg.com/dedent/-/dedent-0.7.0.tgz#2495ddbaf6eb874abb0e1be9df22d2e5a544326c" @@ -12202,6 +12343,40 @@ dotignore@^0.1.2: dependencies: minimatch "^3.0.4" +download@^6.2.2: + version "6.2.5" + resolved "https://registry.yarnpkg.com/download/-/download-6.2.5.tgz#acd6a542e4cd0bb42ca70cfc98c9e43b07039714" + integrity sha512-DpO9K1sXAST8Cpzb7kmEhogJxymyVUd5qz/vCOSyvwtp2Klj2XcDt5YUuasgxka44SxF0q5RriKIwJmQHG2AuA== + dependencies: + caw "^2.0.0" + content-disposition "^0.5.2" + decompress "^4.0.0" + ext-name "^5.0.0" + file-type "5.2.0" + filenamify "^2.0.0" + get-stream "^3.0.0" + got "^7.0.0" + make-dir "^1.0.0" + p-event "^1.0.0" + pify "^3.0.0" + +download@^8.0.0: + version "8.0.0" + resolved "https://registry.yarnpkg.com/download/-/download-8.0.0.tgz#afc0b309730811731aae9f5371c9f46be73e51b1" + integrity sha512-ASRY5QhDk7FK+XrQtQyvhpDKanLluEEQtWl/J7Lxuf/b+i8RYh997QeXvL85xitrmRKVlx9c7eTrcRdq2GS4eA== + dependencies: + archive-type "^4.0.0" + content-disposition "^0.5.2" + decompress "^4.2.1" + ext-name "^5.0.0" + file-type "^11.1.0" + filenamify "^3.0.0" + get-stream "^4.1.0" + got "^8.3.1" + make-dir "^2.1.0" + p-event "^2.1.0" + pify "^4.0.1" + downshift@^3.2.10: version "3.4.8" resolved "https://registry.yarnpkg.com/downshift/-/downshift-3.4.8.tgz#06b7ad9e9c423a58e8a9049b2a00a5d19c7ef954" @@ -13319,6 +13494,19 @@ execa@4.1.0: signal-exit "^3.0.2" strip-final-newline "^2.0.0" +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777" + integrity sha1-lEvs00zEHuMqY6n68nrVpl/Fl3c= + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + execa@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/execa/-/execa-1.0.0.tgz#c6236a5bb4df6d6f15e88e7f017798216749ddd8" @@ -13488,6 +13676,21 @@ express@^4.16.3, express@^4.17.0, express@^4.17.1: utils-merge "1.0.1" vary "~1.1.2" +ext-list@^2.0.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/ext-list/-/ext-list-2.2.2.tgz#0b98e64ed82f5acf0f2931babf69212ef52ddd37" + integrity sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA== + dependencies: + mime-db "^1.28.0" + +ext-name@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ext-name/-/ext-name-5.0.0.tgz#70781981d183ee15d13993c8822045c506c8f0a6" + integrity sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ== + dependencies: + ext-list "^2.0.0" + sort-keys-length "^1.0.0" + extend-shallow@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/extend-shallow/-/extend-shallow-2.0.1.tgz#51af7d614ad9a9f610ea1bafbb989d6b1c56890f" @@ -13833,11 +14036,36 @@ file-system-cache@^1.0.5: fs-extra "^0.30.0" ramda "^0.21.0" +file-type@5.2.0, file-type@^5.2.0: + version "5.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-5.2.0.tgz#2ddbea7c73ffe36368dfae49dc338c058c2b8ad6" + integrity sha1-LdvqfHP/42No365J3DOMBYwritY= + file-type@^10.9.0: version "10.9.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-10.9.0.tgz#f6c12c7cb9e6b8aeefd6917555fd4f9eadf31891" integrity sha512-9C5qtGR/fNibHC5gzuMmmgnjH3QDDLKMa8lYe9CiZVmAnI4aUaoMh40QyUPzzs0RYo837SOBKh7TYwle4G8E4w== +file-type@^11.1.0: + version "11.1.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-11.1.0.tgz#93780f3fed98b599755d846b99a1617a2ad063b8" + integrity sha512-rM0UO7Qm9K7TWTtA6AShI/t7H5BPjDeGVDaNyg9BjHAj3PysKy7+8C8D137R88jnR3rFJZQB/tFgydl5sN5m7g== + +file-type@^3.8.0: + version "3.9.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-3.9.0.tgz#257a078384d1db8087bc449d107d52a52672b9e9" + integrity sha1-JXoHg4TR24CHvESdEH1SpSZyuek= + +file-type@^4.2.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-4.4.0.tgz#1b600e5fca1fbdc6e80c0a70c71c8dba5f7906c5" + integrity sha1-G2AOX8ofvcboDApwxxyNul95BsU= + +file-type@^6.1.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-6.2.0.tgz#e50cd75d356ffed4e306dc4f5bcf52a79903a919" + integrity sha512-YPcTBDV+2Tm0VqjybVd32MHdlEGAtuxS3VAYsumFokDSMG+ROT5wawGlnHDoz7bfMcMDt9hxuXvXwoKUx2fkOg== + file-type@^9.0.0: version "9.0.0" resolved "https://registry.yarnpkg.com/file-type/-/file-type-9.0.0.tgz#a68d5ad07f486414dfb2c8866f73161946714a18" @@ -13850,6 +14078,29 @@ filelist@^1.0.1: dependencies: minimatch "^3.0.4" +filename-reserved-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-reserved-regex/-/filename-reserved-regex-2.0.0.tgz#abf73dfab735d045440abfea2d91f389ebbfa229" + integrity sha1-q/c9+rc10EVECr/qLZHzieu/oik= + +filenamify@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-2.0.0.tgz#bd162262c0b6e94bfbcdcf19a3bbb3764f785695" + integrity sha1-vRYiYsC26Uv7zc8Zo7uzdk94VpU= + dependencies: + filename-reserved-regex "^2.0.0" + strip-outer "^1.0.0" + trim-repeated "^1.0.0" + +filenamify@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/filenamify/-/filenamify-3.0.0.tgz#9603eb688179f8c5d40d828626dcbb92c3a4672c" + integrity sha512-5EFZ//MsvJgXjBAFJ+Bh2YaCTRF/VP1YOmGrgt+KJ4SFRLjI87EIdwLLuT6wQX0I4F9W41xutobzczjsOKlI/g== + dependencies: + filename-reserved-regex "^2.0.0" + strip-outer "^1.0.0" + trim-repeated "^1.0.0" + filesize@6.1.0: version "6.1.0" resolved "https://registry.yarnpkg.com/filesize/-/filesize-6.1.0.tgz#e81bdaa780e2451d714d71c0d7a4f3238d37ad00" @@ -14242,7 +14493,7 @@ fresh@0.5.2: resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.2.tgz#3d8cadd90d976569fa835ab1f8e4b23a105605a7" integrity sha1-PYyt2Q2XZWn6g1qx+OSyOhBWBac= -from2@^2.1.0: +from2@^2.1.0, from2@^2.1.1: version "2.3.0" resolved "https://registry.yarnpkg.com/from2/-/from2-2.3.0.tgz#8bfb5502bde4a4d36cfdeea007fcca21d7e382af" integrity sha1-i/tVAr3kpNNs/e6gB/zKIdfjgq8= @@ -14505,6 +14756,13 @@ get-port@^5.0.0: resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== +get-proxy@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/get-proxy/-/get-proxy-2.1.0.tgz#349f2b4d91d44c4d4d4e9cba2ad90143fac5ef93" + integrity sha512-zmZIaQTWnNQb4R4fJUEp/FC51eZsc6EkErspy3xtIYStaq8EB/hDIWipxsal+E8rz0qD7f2sL/NA9Xee4RInJw== + dependencies: + npm-conf "^1.1.0" + get-stdin@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-4.0.1.tgz#b968c6b0a04384324902e8bf1a5df32579a450fe" @@ -14525,6 +14783,19 @@ get-stdin@^8.0.0: resolved "https://registry.yarnpkg.com/get-stdin/-/get-stdin-8.0.0.tgz#cbad6a73feb75f6eeb22ba9e01f89aa28aa97a53" integrity sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg== +get-stream@3.0.0, get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-3.0.0.tgz#8e943d1358dc37555054ecbe2edb05aa174ede14" + integrity sha1-jpQ9E1jcN1VQVOy+LtsFqhdO3hQ= + +get-stream@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-2.3.1.tgz#5f38f93f346009666ee0150a054167f91bdd95de" + integrity sha1-Xzj5PzRgCWZu4BUKBUFn+Rvdld4= + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + get-stream@^4.0.0, get-stream@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-4.1.0.tgz#c1b255575f3dc21d59bfc79cd3d2b46b1c3a54b5" @@ -14920,6 +15191,49 @@ got@^3.2.0: read-all-stream "^3.0.0" timed-out "^2.0.0" +got@^7.0.0: + version "7.1.0" + resolved "https://registry.yarnpkg.com/got/-/got-7.1.0.tgz#05450fd84094e6bbea56f451a43a9c289166385a" + integrity sha512-Y5WMo7xKKq1muPsxD+KmrR8DH5auG7fBdDVueZwETwV6VytKyU9OX/ddpq2/1hp1vIPvVb4T81dKQz3BivkNLw== + dependencies: + decompress-response "^3.2.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + is-plain-obj "^1.1.0" + is-retry-allowed "^1.0.0" + is-stream "^1.0.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + p-cancelable "^0.3.0" + p-timeout "^1.1.1" + safe-buffer "^5.0.1" + timed-out "^4.0.0" + url-parse-lax "^1.0.0" + url-to-options "^1.0.1" + +got@^8.3.1: + version "8.3.2" + resolved "https://registry.yarnpkg.com/got/-/got-8.3.2.tgz#1d23f64390e97f776cac52e5b936e5f514d2e937" + integrity sha512-qjUJ5U/hawxosMryILofZCkm3C84PLJS/0grRIpjAwu+Lkxxj5cxeCU25BG0/3mDSpXKTyZr8oh8wIgLaH0QCw== + dependencies: + "@sindresorhus/is" "^0.7.0" + cacheable-request "^2.1.1" + decompress-response "^3.3.0" + duplexer3 "^0.1.4" + get-stream "^3.0.0" + into-stream "^3.1.0" + is-retry-allowed "^1.1.0" + isurl "^1.0.0-alpha5" + lowercase-keys "^1.0.0" + mimic-response "^1.0.0" + p-cancelable "^0.4.0" + p-timeout "^2.0.1" + pify "^3.0.0" + safe-buffer "^5.1.1" + timed-out "^4.0.1" + url-parse-lax "^3.0.0" + url-to-options "^1.0.1" + got@^9.6.0: version "9.6.0" resolved "https://registry.yarnpkg.com/got/-/got-9.6.0.tgz#edf45e7d67f99545705de1f7bbeeeb121765ed85" @@ -14942,11 +15256,16 @@ graceful-fs@4.X, graceful-fs@^4.0.0, graceful-fs@^4.1.11, graceful-fs@^4.1.15, g resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.4.tgz#2256bde14d3632958c465ebc96dc467ca07a29fb" integrity sha512-WjKPNJF79dtJAVniUlGGWHYGz2jWxT6VhN/4m1NdkbZ2nOsEF+cI1Edgql5zCRhs/VsQYRvrXctxktVXZUkixw== -graceful-fs@^4.2.3, graceful-fs@^4.2.6: +graceful-fs@^4.1.10, graceful-fs@^4.2.3, graceful-fs@^4.2.6: version "4.2.6" resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee" integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ== +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU= + graphlib@^2.1.8: version "2.1.8" resolved "https://registry.yarnpkg.com/graphlib/-/graphlib-2.1.8.tgz#5761d414737870084c92ec7b5dbcb0592c9d35da" @@ -15198,11 +15517,23 @@ has-glob@^1.0.0: dependencies: is-glob "^3.0.0" +has-symbol-support-x@^1.4.1: + version "1.4.2" + resolved "https://registry.yarnpkg.com/has-symbol-support-x/-/has-symbol-support-x-1.4.2.tgz#1409f98bc00247da45da67cee0a36f282ff26455" + integrity sha512-3ToOva++HaW+eCpgqZrCfN51IPB+7bJNVT6CUATzueB5Heb8o6Nam0V3HG5dlDvZU1Gn5QLcbahiKw/XVk5JJw== + has-symbols@^1.0.0, has-symbols@^1.0.1, has-symbols@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/has-symbols/-/has-symbols-1.0.2.tgz#165d3070c00309752a1236a479331e3ac56f1423" integrity sha512-chXa79rL/UC2KlX17jo3vRGz0azaWEx5tGqZg5pO3NUyEJVB17dMruQlzCCOfUvElghKcm5194+BCRvi2Rv/Gw== +has-to-string-tag-x@^1.2.0: + version "1.4.1" + resolved "https://registry.yarnpkg.com/has-to-string-tag-x/-/has-to-string-tag-x-1.4.1.tgz#a045ab383d7b4b2012a00148ab0aa5f290044d4d" + integrity sha512-vdbKfmw+3LoOYVr+mtxHaX5a96+0f3DljYd8JOqvOLsf5mw2Otda2qCDT9qRqLAhrjyQ0h7ual5nOiASpsGNFw== + dependencies: + has-symbol-support-x "^1.4.1" + has-unicode@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" @@ -15669,6 +16000,11 @@ htmlparser2@~3.3.0: domutils "1.1" readable-stream "1.0" +http-cache-semantics@3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-3.8.1.tgz#39b0e16add9b605bf0a9ef3d9daaf4843b4cacd2" + integrity sha512-5ai2iksyV8ZXmnZhHH4rWPoxxistEexSi5936zIQ1bnNTW5VnA85B6P/VpXiRM017IgRvb2kKo1a//y+0wSp3w== + http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz#49e91c5cbf36c9b94bcfcd71c23d5249ec74e390" @@ -16166,6 +16502,14 @@ intl@^1.2.5: resolved "https://registry.yarnpkg.com/intl/-/intl-1.2.5.tgz#82244a2190c4e419f8371f5aa34daa3420e2abde" integrity sha1-giRKIZDE5Bn4Nx9ao02qNCDiq94= +into-stream@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/into-stream/-/into-stream-3.1.0.tgz#96fb0a936c12babd6ff1752a17d05616abd094c6" + integrity sha1-lvsKk2wSur1v8XUqF9BWFqvQlMY= + dependencies: + from2 "^2.1.1" + p-is-promise "^1.1.0" + invariant@2.2.4, invariant@^2.1.0, invariant@^2.1.1, invariant@^2.2.2, invariant@^2.2.3, invariant@^2.2.4: version "2.2.4" resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.4.tgz#610f3c92c9359ce1db616e538008d23ff35158e6" @@ -16522,6 +16866,13 @@ is-interactive@^1.0.0: resolved "https://registry.yarnpkg.com/is-interactive/-/is-interactive-1.0.0.tgz#cea6e6ae5c870a7b0a0004070b7b587e0252912e" integrity sha512-2HvIEKRoqS62guEC+qBjpvRubdX910WCMuJTZ+I9yvqKU2/12eSL549HMwtabb4oupdj2sMP50k+XJfB/8JE6w== +is-invalid-path@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/is-invalid-path/-/is-invalid-path-0.1.0.tgz#307a855b3cf1a938b44ea70d2c61106053714f34" + integrity sha1-MHqFWzzxqTi0TqcNLGEQYFNxTzQ= + dependencies: + is-glob "^2.0.0" + is-lambda@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/is-lambda/-/is-lambda-1.0.1.tgz#3d9877899e6a53efc0160504cde15f82e6f061d5" @@ -16540,6 +16891,11 @@ is-native@^1.0.1: is-nil "^1.0.0" to-source-code "^1.0.0" +is-natural-number@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-natural-number/-/is-natural-number-4.0.1.tgz#ab9d76e1db4ced51e35de0c72ebecf09f734cde8" + integrity sha1-q5124dtM7VHjXeDHLr7PCfc0zeg= + is-negated-glob@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-negated-glob/-/is-negated-glob-1.0.0.tgz#6910bca5da8c95e784b5751b976cf5a10fee36d2" @@ -16714,6 +17070,11 @@ is-resolvable@^1.0.0: resolved "https://registry.yarnpkg.com/is-resolvable/-/is-resolvable-1.1.0.tgz#fb18f87ce1feb925169c9a407c19318a3206ed88" integrity sha512-qgDYXFSR5WvEfuS5dMj6oTMEbrrSaM0CrFk2Yiq/gXnBvD9pMa2jGXxyhGLfvhZpuMZe18CJpFxAt3CRs42NMg== +is-retry-allowed@^1.0.0, is-retry-allowed@^1.1.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/is-retry-allowed/-/is-retry-allowed-1.2.0.tgz#d778488bd0a4666a3be8a1482b9f2baafedea8b4" + integrity sha512-RUbUeKwvm3XG2VYamhJL1xFktgjvPzL0Hq8C+6yrWIswDy3BIXGqCxhxkc30N9jqK311gVU137K8Ei55/zVJRg== + is-root@2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/is-root/-/is-root-2.1.0.tgz#809e18129cf1129644302a4f8544035d51984a9c" @@ -16788,6 +17149,13 @@ is-valid-glob@^1.0.0: resolved "https://registry.yarnpkg.com/is-valid-glob/-/is-valid-glob-1.0.0.tgz#29bf3eff701be2d4d315dbacc39bc39fe8f601aa" integrity sha1-Kb8+/3Ab4tTTFdusw5vDn+j2Aao= +is-valid-path@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-valid-path/-/is-valid-path-0.1.1.tgz#110f9ff74c37f663e1ec7915eb451f2db93ac9df" + integrity sha1-EQ+f90w39mPh7HkV60UfLbk6yd8= + dependencies: + is-invalid-path "^0.1.0" + is-weakmap@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/is-weakmap/-/is-weakmap-2.0.1.tgz#5008b59bdc43b698201d18f62b37b2ca243e8cf2" @@ -16993,6 +17361,14 @@ istanbul-reports@^3.0.2: html-escaper "^2.0.0" istanbul-lib-report "^3.0.0" +isurl@^1.0.0-alpha5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isurl/-/isurl-1.0.0.tgz#b27f4f49f3cdaa3ea44a0a5b7f3462e6edc39d67" + integrity sha512-1P/yWsxPlDtn7QeRD+ULKQPaIaN6yF368GZ2vDfv0AL0NwpStafjWCDDdn0k8wgFMWpVAqG7oJhxHnlud42i9w== + dependencies: + has-to-string-tag-x "^1.2.0" + is-object "^1.0.1" + iterate-iterator@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/iterate-iterator/-/iterate-iterator-1.0.1.tgz#1693a768c1ddd79c969051459453f082fe82e9f6" @@ -18084,7 +18460,7 @@ kea@^2.4.2: resolved "https://registry.yarnpkg.com/kea/-/kea-2.4.2.tgz#53af42702f2c8962422e456e5dd943391bad26e9" integrity sha512-cdGds/gsJsbo/KbVAMk5/tTr229eDibVT1wmPPxPO/10zYb8GFoP3udBIQb+Hop5qGEu2wIHVdXwJvXqSS8JAg== -keyv@^3.0.0: +keyv@3.0.0, keyv@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/keyv/-/keyv-3.0.0.tgz#44923ba39e68b12a7cec7df6c3268c031f2ef373" integrity sha512-eguHnq22OE3uVoSYG0LVWNP+4ppamWr9+zWBe1bsNcovIMy6huUJFPgy4mGwCd/rnl3vOLGW1MTlu4c57CT1xA== @@ -18844,6 +19220,11 @@ lower-case@^2.0.1: dependencies: tslib "^1.10.0" +lowercase-keys@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.0.tgz#4e3366b39e7f5457e35f1324bdf6f88d0bfc7306" + integrity sha1-TjNms55/VFfjXxMkvfb4jQv8cwY= + lowercase-keys@^1.0.0, lowercase-keys@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/lowercase-keys/-/lowercase-keys-1.0.1.tgz#6f9e30b47084d971a7c820ff15a6c5167b74c26f" @@ -18862,7 +19243,7 @@ lowlight@^1.14.0: fault "^1.0.0" highlight.js "~10.4.0" -lru-cache@^4.0.0, lru-cache@^4.1.5: +lru-cache@^4.0.0, lru-cache@^4.0.1, lru-cache@^4.1.5: version "4.1.5" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== @@ -18908,6 +19289,13 @@ magic-string@0.25.1: dependencies: sourcemap-codec "^1.4.1" +make-dir@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-1.3.0.tgz#79c1033b80515bd6d24ec9933e860ca75ee27f0c" + integrity sha512-2w31R7SJtieJJnQtGc7RVL2StM2vGYVfqUOvUDxH6bC6aJTxPxTF0GnIgCyu7tjockiUWAYQRbxa7vKn34s5sQ== + dependencies: + pify "^3.0.0" + make-dir@^2.0.0, make-dir@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/make-dir/-/make-dir-2.1.0.tgz#5f0310e18b8be898cc07009295a30ae41e91e6f5" @@ -19433,6 +19821,11 @@ mime-db@1.45.0: resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.45.0.tgz#cceeda21ccd7c3a745eba2decd55d4b73e7879ea" integrity sha512-CkqLUxUk15hofLoLyljJSrukZi8mAtgd+yE5uO4tqRZsdsAJKv0O+rFMhVDRJgozy+yG6md5KwuXhD4ocIoP+w== +mime-db@^1.28.0: + version "1.49.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.49.0.tgz#f3dfde60c99e9cf3bc9701d687778f537001cbed" + integrity sha512-CIc8j9URtOVApSFCQIF+VBkX1RwXp/oMMOrqdyXSBXq5RWNEsRfyj1kiRnQgmNXmHxPoFIxOroKA3zcU9P+nAA== + mime-types@^2.0.1, mime-types@^2.1.12, mime-types@^2.1.26, mime-types@^2.1.27, mime-types@~2.1.17, mime-types@~2.1.19, mime-types@~2.1.24: version "2.1.27" resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.27.tgz#47949f98e279ea53119f5722e0f34e529bec009f" @@ -20276,6 +20669,19 @@ node-jose@1.1.0: node-forge "^0.7.6" uuid "^3.3.2" +node-jq@2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/node-jq/-/node-jq-2.0.0.tgz#f0777ee2be6f6bfcf0ef58cc44689c422def6d97" + integrity sha512-gp8Xkr5RlZrXVK+VuUaF0JKtsGrElHb1hOjugdJFiCMHUup1OqsSBXZyeuwPkpty3P9taFHJmw4uzjQFIMFv4g== + dependencies: + bin-build "^3.0.0" + download "^8.0.0" + is-valid-path "^0.1.1" + joi "^17.4.0" + strip-eof "^2.0.0" + strip-final-newline "^2.0.0" + tempfile "^3.0.0" + "node-libs-browser@^1.0.0 || ^2.0.0", node-libs-browser@^2.2.1: version "2.2.1" resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.2.1.tgz#b64f513d18338625f90346d27b0d235e631f6425" @@ -20452,6 +20858,15 @@ normalize-selector@^0.2.0: resolved "https://registry.yarnpkg.com/normalize-selector/-/normalize-selector-0.2.0.tgz#d0b145eb691189c63a78d201dc4fdb1293ef0c03" integrity sha1-0LFF62kRicY6eNIB3E/bEpPvDAM= +normalize-url@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-2.0.1.tgz#835a9da1551fa26f70e92329069a23aa6574d7e6" + integrity sha512-D6MUW4K/VzoJ4rJ01JFKxDrtY1v9wrgzCX5f2qj/lzH1m/lW6MhUZFKerVsnyjOhOsYzI9Kqqak+10l4LvLpMw== + dependencies: + prepend-http "^2.0.0" + query-string "^5.0.1" + sort-keys "^2.0.0" + normalize-url@^3.0.0: version "3.3.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" @@ -20469,6 +20884,14 @@ now-and-later@^2.0.0: dependencies: once "^1.3.2" +npm-conf@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/npm-conf/-/npm-conf-1.1.3.tgz#256cc47bd0e218c259c4e9550bf413bc2192aff9" + integrity sha512-Yic4bZHJOt9RCFbRP3GgpqhScOY4HH3V2P8yBj6CeYq118Qr+BLXqT2JvpJ00mryLESpgOxf5XlFv4ZjXxLScw== + dependencies: + config-chain "^1.1.11" + pify "^3.0.0" + npm-normalize-package-bin@^1.0.0: version "1.0.1" resolved "https://registry.yarnpkg.com/npm-normalize-package-bin/-/npm-normalize-package-bin-1.0.1.tgz#6e79a41f23fd235c0623218228da7d9c23b8f6e2" @@ -20970,6 +21393,16 @@ p-all@^2.1.0: dependencies: p-map "^2.0.0" +p-cancelable@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.3.0.tgz#b9e123800bcebb7ac13a479be195b507b98d30fa" + integrity sha512-RVbZPLso8+jFeq1MfNvgXtCRED2raz/dKpacfTNxsx6pLEpEomM7gah6VeHSYV3+vo0OAi4MkArtQcWWXuQoyw== + +p-cancelable@^0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-0.4.1.tgz#35f363d67d52081c8d9585e37bcceb7e0bbcb2a0" + integrity sha512-HNa1A8LvB1kie7cERyy21VNeHb2CWJJYqyyC2o3klWFfMGlFmWv2Z7sFgZH8ZiaYL95ydToKTFVXgMV/Os0bBQ== + p-cancelable@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/p-cancelable/-/p-cancelable-1.1.0.tgz#d078d15a3af409220c886f1d9a0ca2e441ab26cc" @@ -20985,6 +21418,20 @@ p-each-series@^2.1.0: resolved "https://registry.yarnpkg.com/p-each-series/-/p-each-series-2.1.0.tgz#961c8dd3f195ea96c747e636b262b800a6b1af48" integrity sha512-ZuRs1miPT4HrjFa+9fRfOFXxGJfORgelKV9f9nNOWw2gl6gVsRaVDOQP0+MI0G0wGKns1Yacsu0GjOFbTK0JFQ== +p-event@^1.0.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-1.3.0.tgz#8e6b4f4f65c72bc5b6fe28b75eda874f96a4a085" + integrity sha1-jmtPT2XHK8W2/ii3XtqHT5akoIU= + dependencies: + p-timeout "^1.1.1" + +p-event@^2.1.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/p-event/-/p-event-2.3.1.tgz#596279ef169ab2c3e0cae88c1cfbb08079993ef6" + integrity sha512-NQCqOFhbpVTMX4qMe8PF8lbGtzZ+LCiN7pcNrb/413Na7+TRoe1xkKUzuWa/YEJdGQ0FvKtj35EEbDoVPO2kbA== + dependencies: + p-timeout "^2.0.1" + p-event@^4.1.0: version "4.1.0" resolved "https://registry.yarnpkg.com/p-event/-/p-event-4.1.0.tgz#e92bb866d7e8e5b732293b1c8269d38e9982bf8e" @@ -21004,6 +21451,11 @@ p-finally@^1.0.0: resolved "https://registry.yarnpkg.com/p-finally/-/p-finally-1.0.0.tgz#3fbcfb15b899a44123b34b6dcc18b724336a2cae" integrity sha1-P7z7FbiZpEEjs0ttzBi3JDNqLK4= +p-is-promise@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/p-is-promise/-/p-is-promise-1.1.0.tgz#9c9456989e9f6588017b0434d56097675c3da05e" + integrity sha1-nJRWmJ6fZYgBewQ01WCXZ1w9oF4= + p-limit@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/p-limit/-/p-limit-1.3.0.tgz#b86bd5f0c25690911c7590fcbfc2010d54b3ccb8" @@ -21053,6 +21505,13 @@ p-locate@^5.0.0: dependencies: p-limit "^3.0.2" +p-map-series@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-map-series/-/p-map-series-1.0.0.tgz#bf98fe575705658a9e1351befb85ae4c1f07bdca" + integrity sha1-v5j+V1cFZYqeE1G++4WuTB8Hvco= + dependencies: + p-reduce "^1.0.0" + p-map@^2.0.0: version "2.1.0" resolved "https://registry.yarnpkg.com/p-map/-/p-map-2.1.0.tgz#310928feef9c9ecc65b68b17693018a665cea175" @@ -21072,6 +21531,11 @@ p-map@^4.0.0: dependencies: aggregate-error "^3.0.0" +p-reduce@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/p-reduce/-/p-reduce-1.0.0.tgz#18c2b0dd936a4690a529f8231f58a0fdb6a47dfa" + integrity sha1-GMKw3ZNqRpClKfgjH1ig/bakffo= + p-retry@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/p-retry/-/p-retry-3.0.1.tgz#316b4c8893e2c8dc1cfa891f406c4b422bebf328" @@ -21087,6 +21551,13 @@ p-retry@^4.2.0: "@types/retry" "^0.12.0" retry "^0.12.0" +p-timeout@^1.1.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-1.2.1.tgz#5eb3b353b7fce99f101a1038880bb054ebbea386" + integrity sha1-XrOzU7f86Z8QGhA4iAuwVOu+o4Y= + dependencies: + p-finally "^1.0.0" + p-timeout@^2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/p-timeout/-/p-timeout-2.0.1.tgz#d8dd1979595d2dc0139e1fe46b8b646cb3cdf038" @@ -21579,7 +22050,7 @@ picomatch@^2.2.3: resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== -pify@^2.0.0, pify@^2.2.0: +pify@^2.0.0, pify@^2.2.0, pify@^2.3.0: version "2.3.0" resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" integrity sha1-7RQaasBDqEnqWISY59yosVMw6Qw= @@ -22236,7 +22707,7 @@ prelude-ls@~1.1.2: resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" integrity sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ= -prepend-http@^1.0.0: +prepend-http@^1.0.0, prepend-http@^1.0.1: version "1.0.4" resolved "https://registry.yarnpkg.com/prepend-http/-/prepend-http-1.0.4.tgz#d4f4562b0ce3696e41ac52d0e002e57a635dc6dc" integrity sha1-1PRWKwzjaW5BrFLQ4ALlemNdxtw= @@ -22684,6 +23155,15 @@ qs@~6.5.2: resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.2.tgz#cb3ae806e8740444584ef154ce8ee98d403f3e36" integrity sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA== +query-string@^5.0.1: + version "5.1.1" + resolved "https://registry.yarnpkg.com/query-string/-/query-string-5.1.1.tgz#a78c012b71c17e05f2e3fa2319dd330682efb3cb" + integrity sha512-gjWOsm2SoGlgLEdAGt7a6slVOk9mGiXmPFMqrEhLQ68rhQuBnpfs3+EmlvqKyxnCo9/PPlF+9MtY02S1aFg+Jw== + dependencies: + decode-uri-component "^0.2.0" + object-assign "^4.1.0" + strict-uri-encode "^1.0.0" + query-string@^6.13.2: version "6.13.2" resolved "https://registry.yarnpkg.com/query-string/-/query-string-6.13.2.tgz#3585aa9412c957cbd358fd5eaca7466f05586dda" @@ -23696,7 +24176,7 @@ read-pkg@^5.2.0: parse-json "^5.0.0" type-fest "^0.6.0" -"readable-stream@1 || 2", "readable-stream@2 || 3", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@^2.3.7, readable-stream@~2.3.3, readable-stream@~2.3.6: +"readable-stream@1 || 2", "readable-stream@2 || 3", readable-stream@^2.0.0, readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.4, readable-stream@^2.0.5, readable-stream@^2.0.6, readable-stream@^2.1.5, readable-stream@^2.2.2, readable-stream@^2.3.0, readable-stream@^2.3.3, readable-stream@^2.3.5, readable-stream@^2.3.6, readable-stream@^2.3.7, readable-stream@~2.3.3, readable-stream@~2.3.6: version "2.3.7" resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.7.tgz#1eca1cf711aef814c04f62252a36a62f6cb23b57" integrity sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw== @@ -24528,7 +25008,7 @@ resolve@~1.10.1: dependencies: path-parse "^1.0.6" -responselike@^1.0.2: +responselike@1.0.2, responselike@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/responselike/-/responselike-1.0.2.tgz#918720ef3b631c5642be068f15ade5a46f4ba1e7" integrity sha1-kYcg7ztjHFZCvgaPFa3lpG9Loec= @@ -24935,6 +25415,13 @@ seedrandom@^3.0.5: resolved "https://registry.yarnpkg.com/seedrandom/-/seedrandom-3.0.5.tgz#54edc85c95222525b0c7a6f6b3543d8e0b3aa0a7" integrity sha512-8OwmbklUNzwezjGInmZ+2clQmExQPvomqjL7LFqOYqtmuxRgQYqOD3mHaU+MvZn5FLUeVxVfQjwLZW/n/JFuqg== +seek-bzip@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/seek-bzip/-/seek-bzip-1.0.5.tgz#cfe917cb3d274bcffac792758af53173eb1fabdc" + integrity sha1-z+kXyz0nS8/6x5J1ivUxc+sfq9w= + dependencies: + commander "~2.8.1" + select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" @@ -25503,6 +25990,20 @@ sonic-boom@^2.1.0: dependencies: atomic-sleep "^1.0.0" +sort-keys-length@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/sort-keys-length/-/sort-keys-length-1.0.1.tgz#9cb6f4f4e9e48155a6aa0671edd336ff1479a188" + integrity sha1-nLb09OnkgVWmqgZx7dM2/xR5oYg= + dependencies: + sort-keys "^1.0.0" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-1.1.2.tgz#441b6d4d346798f1b4e49e8920adfba0e543f9ad" + integrity sha1-RBttTTRnmPG05J6JIK37oOVD+a0= + dependencies: + is-plain-obj "^1.0.0" + sort-keys@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/sort-keys/-/sort-keys-2.0.0.tgz#658535584861ec97d730d6cf41822e1f56684128" @@ -26051,6 +26552,11 @@ stream-to-async-iterator@^0.2.0: resolved "https://registry.yarnpkg.com/stream-to-async-iterator/-/stream-to-async-iterator-0.2.0.tgz#bef5c885e9524f98b2fa5effecc357bd58483780" integrity sha1-vvXIhelST5iy+l7/7MNXvVhIN4A= +strict-uri-encode@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-1.1.0.tgz#279b225df1d582b1f54e65addd4352e18faa0713" + integrity sha1-J5siXfHVgrH1TmWt3UNS4Y+qBxM= + strict-uri-encode@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz#b9c7330c7042862f6b142dc274bbcc5866ce3546" @@ -26273,11 +26779,23 @@ strip-bom@^4.0.0: resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-4.0.0.tgz#9c3505c1db45bcedca3d9cf7a16f5c5aa3901878" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== +strip-dirs@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/strip-dirs/-/strip-dirs-2.1.0.tgz#4987736264fc344cf20f6c34aca9d13d1d4ed6c5" + integrity sha512-JOCxOeKLm2CAS73y/U4ZeZPTkE+gNVCzKt7Eox84Iej1LT/2pTWYpZKJuxwQpvX1LiZb1xokNR7RLfuBAa7T3g== + dependencies: + is-natural-number "^4.0.1" + strip-eof@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-1.0.0.tgz#bb43ff5598a6eb05d89b59fcd129c983313606bf" integrity sha1-u0P/VZim6wXYm1n80SnJgzE2Br8= +strip-eof@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-eof/-/strip-eof-2.0.0.tgz#2e3f3c5145d02de826eafb23e65b2faf675448b4" + integrity sha512-zLsJC+5P5hGu4Zmoq6I4uo6bTf1Nx6Z/vnZedxwnrcfkc38Vz6UiuqGOtS9bewFaoTCDErpqkV7v02htp9KEow== + strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/strip-final-newline/-/strip-final-newline-2.0.0.tgz#89b852fb2fcbe936f6f4b3187afb0a12c1ab58ad" @@ -26300,6 +26818,13 @@ strip-json-comments@~2.0.1: resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" integrity sha1-PFMZQukIwml8DsNEhYwobHygpgo= +strip-outer@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/strip-outer/-/strip-outer-1.0.0.tgz#aac0ba60d2e90c5d4f275fd8869fd9a2d310ffb8" + integrity sha1-qsC6YNLpDF1PJ1/Yhp/ZotMQ/7g= + dependencies: + escape-string-regexp "^1.0.2" + strong-log-transformer@^2.1.0: version "2.1.0" resolved "https://registry.yarnpkg.com/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz#0f5ed78d325e0421ac6f90f7f10e691d6ae3ae10" @@ -26745,6 +27270,19 @@ tar-fs@^2.1.0: pump "^3.0.0" tar-stream "^2.0.0" +tar-stream@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-1.6.2.tgz#8ea55dab37972253d9a9af90fdcd559ae435c555" + integrity sha512-rzS0heiNf8Xn7/mpdSVVSMAWAoy9bfb1WOTYC78Z0UQKeKa/CWS8FOq0lKGNa8DWKAn9gxjCvMLYc5PGXYlK2A== + dependencies: + bl "^1.0.0" + buffer-alloc "^1.2.0" + end-of-stream "^1.0.0" + fs-constants "^1.0.0" + readable-stream "^2.3.0" + to-buffer "^1.1.1" + xtend "^4.0.0" + tar-stream@^2.0.0: version "2.1.3" resolved "https://registry.yarnpkg.com/tar-stream/-/tar-stream-2.1.3.tgz#1e2022559221b7866161660f118255e20fa79e41" @@ -26844,6 +27382,27 @@ temp-dir@^1.0.0: resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-1.0.0.tgz#0a7c0ea26d3a39afa7e0ebea9c1fc0bc4daa011d" integrity sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0= +temp-dir@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/temp-dir/-/temp-dir-2.0.0.tgz#bde92b05bdfeb1516e804c9c00ad45177f31321e" + integrity sha512-aoBAniQmmwtcKp/7BzsH8Cxzv8OL736p7v1ihGb5e9DJ9kTwGWHrQrVB5+lfVDzfGrdRzXch+ig7LHaY1JTOrg== + +tempfile@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-2.0.0.tgz#6b0446856a9b1114d1856ffcbe509cccb0977265" + integrity sha1-awRGhWqbERTRhW/8vlCczLCXcmU= + dependencies: + temp-dir "^1.0.0" + uuid "^3.0.1" + +tempfile@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/tempfile/-/tempfile-3.0.0.tgz#5376a3492de7c54150d0cc0612c3f00e2cdaf76c" + integrity sha512-uNFCg478XovRi85iD42egu+eSFUmmka750Jy7L5tfHI5hQKKtbPnxaSaXAbBqCDYrw3wx4tXjKwci4/QmsZJxw== + dependencies: + temp-dir "^2.0.0" + uuid "^3.3.2" + tempy@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/tempy/-/tempy-0.3.0.tgz#6f6c5b295695a16130996ad5ab01a8bd726e8bf8" @@ -27049,6 +27608,11 @@ timed-out@^2.0.0: resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-2.0.0.tgz#f38b0ae81d3747d628001f41dafc652ace671c0a" integrity sha1-84sK6B03R9YoAB9B2vxlKs5nHAo= +timed-out@^4.0.0, timed-out@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/timed-out/-/timed-out-4.0.1.tgz#f32eacac5a175bea25d7fab565ab3ed8741ef56f" + integrity sha1-8y6srFoXW+ol1/q1Zas+2HQe9W8= + timers-browserify@^1.0.1: version "1.4.2" resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-1.4.2.tgz#c9c58b575be8407375cb5e2462dacee74359f41d" @@ -27161,6 +27725,11 @@ to-arraybuffer@^1.0.0: resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" integrity sha1-fSKbH8xjfkZsoIEYCDanqr/4P0M= +to-buffer@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/to-buffer/-/to-buffer-1.1.1.tgz#493bd48f62d7c43fcded313a03dcadb2e1213a80" + integrity sha512-lx9B5iv7msuFYE3dytT+KE5tap+rNYw+K4jVkb9R/asAb+pbBSM17jtunHplhBe6RRJdZx3Pn2Jph24O32mOVg== + to-camel-case@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/to-camel-case/-/to-camel-case-1.0.0.tgz#1a56054b2f9d696298ce66a60897322b6f423e46" @@ -27353,6 +27922,13 @@ trim-newlines@^3.0.0: resolved "https://registry.yarnpkg.com/trim-newlines/-/trim-newlines-3.0.0.tgz#79726304a6a898aa8373427298d54c2ee8b1cb30" integrity sha512-C4+gOpvmxaSMKuEf9Qc134F1ZuOHVXKRbtEflf4NTtuuJDEIJ9p5PXsalL8SkeRw+qit1Mo+yuvMPAKwWg/1hA== +trim-repeated@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/trim-repeated/-/trim-repeated-1.0.0.tgz#e3646a2ea4e891312bf7eace6cfb05380bc01c21" + integrity sha1-42RqLqTokTEr9+rObPsFOAvAHCE= + dependencies: + escape-string-regexp "^1.0.2" + trim-right@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" @@ -27704,7 +28280,7 @@ unbox-primitive@^1.0.0: has-symbols "^1.0.2" which-boxed-primitive "^1.0.2" -unbzip2-stream@^1.3.3: +unbzip2-stream@^1.0.9, unbzip2-stream@^1.3.3: version "1.4.3" resolved "https://registry.yarnpkg.com/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz#b0da04c4371311df771cdc215e87f2130991ace7" integrity sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg== @@ -28199,6 +28775,13 @@ url-loader@^4.0.0: mime-types "^2.1.26" schema-utils "^2.6.5" +url-parse-lax@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-1.0.0.tgz#7af8f303645e9bd79a272e7a14ac68bc0609da73" + integrity sha1-evjzA2Rem9eaJy56FKxovAYJ2nM= + dependencies: + prepend-http "^1.0.1" + url-parse-lax@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/url-parse-lax/-/url-parse-lax-3.0.0.tgz#16b5cafc07dbe3676c1b1999177823d6503acb0c" @@ -28219,6 +28802,11 @@ url-template@^2.0.8: resolved "https://registry.yarnpkg.com/url-template/-/url-template-2.0.8.tgz#fc565a3cccbff7730c775f5641f9555791439f21" integrity sha1-/FZaPMy/93MMd19WQflVV5FDnyE= +url-to-options@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/url-to-options/-/url-to-options-1.0.1.tgz#1505a03a289a48cbd7a434efbaeec5055f5633a9" + integrity sha1-FQWgOiiaSMvXpDTvuu7FBV9WM6k= + url@^0.11.0, url@~0.11.0: version "0.11.0" resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" @@ -28371,7 +28959,7 @@ uuid@^2.0.1: resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" integrity sha1-Z+LoY3lyFVMN/zGOW/nc6/1Hsho= -uuid@^3.0.0, uuid@^3.3.2, uuid@^3.3.3, uuid@^3.4.0: +uuid@^3.0.0, uuid@^3.0.1, uuid@^3.3.2, uuid@^3.3.3, uuid@^3.4.0: version "3.4.0" resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee" integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== @@ -29850,7 +30438,7 @@ yargs@~3.10.0: decamelize "^1.0.0" window-size "0.1.0" -yauzl@^2.10.0: +yauzl@^2.10.0, yauzl@^2.4.2: version "2.10.0" resolved "https://registry.yarnpkg.com/yauzl/-/yauzl-2.10.0.tgz#c7eb17c93e112cb1086fa6d8e51fb0667b79a5f9" integrity sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=